AttachmentsToChat #145
25
backend/docker-compose.target-db.yml
Normal file
25
backend/docker-compose.target-db.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
services:
|
||||
db-target:
|
||||
image: mysql:8.0
|
||||
container_name: petshop-db-target
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: Petstoredb_target
|
||||
MYSQL_USER: petshop
|
||||
MYSQL_PASSWORD: petshop
|
||||
ports:
|
||||
- "3307:3306"
|
||||
volumes:
|
||||
- db_target_data:/var/lib/mysql
|
||||
- ./src/main/resources/dev/final-target/final_target_schema.sql:/docker-entrypoint-initdb.d/01_final_target_schema.sql:ro
|
||||
- ./src/main/resources/dev/final-target/final_target_seed.sql:/docker-entrypoint-initdb.d/02_final_target_seed.sql:ro
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-proot"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
start_period: 40s
|
||||
|
||||
volumes:
|
||||
db_target_data:
|
||||
@@ -197,6 +197,57 @@
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>docker-up-target-db</id>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>docker</executable>
|
||||
<arguments>
|
||||
<argument>compose</argument>
|
||||
<argument>-f</argument>
|
||||
<argument>docker-compose.target-db.yml</argument>
|
||||
<argument>up</argument>
|
||||
<argument>-d</argument>
|
||||
<argument>--wait</argument>
|
||||
<argument>db-target</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>docker-down-target-db</id>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>docker</executable>
|
||||
<arguments>
|
||||
<argument>compose</argument>
|
||||
<argument>-f</argument>
|
||||
<argument>docker-compose.target-db.yml</argument>
|
||||
<argument>down</argument>
|
||||
<argument>-v</argument>
|
||||
<argument>--remove-orphans</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>docker-logs-target-db</id>
|
||||
<goals>
|
||||
<goal>exec</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<executable>docker</executable>
|
||||
<arguments>
|
||||
<argument>compose</argument>
|
||||
<argument>-f</argument>
|
||||
<argument>docker-compose.target-db.yml</argument>
|
||||
<argument>logs</argument>
|
||||
<argument>db-target</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
@@ -11,7 +11,7 @@ final class RuntimeClasspathValidator {
|
||||
if (!resourceExists("application.yml")) {
|
||||
throw new IllegalStateException("Backend resources are missing from the runtime classpath. Reimport the Maven project in IntelliJ and run the shared Maven run configuration.");
|
||||
}
|
||||
if (!resourceExists("db/migration/V1__baseline_schema.sql")) {
|
||||
if (!resourceExists("db/migration/V1__target_baseline.sql")) {
|
||||
throw new IllegalStateException("Flyway migration files are missing from the runtime classpath. Reimport the Maven project in IntelliJ and run the shared Maven run configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ====");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -29,6 +25,7 @@ import org.springframework.security.authentication.InternalAuthenticationService
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@@ -44,22 +41,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 +83,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(
|
||||
@@ -145,25 +131,11 @@ public class AuthController {
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@GetMapping("/me")
|
||||
public ResponseEntity<UserInfoResponse> 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 +190,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) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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<Page<CustomerResponse>> getAllCustomers(
|
||||
public ResponseEntity<Page<UserResponse>> 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<CustomerResponse> getCustomerById(@PathVariable Long id) {
|
||||
return ResponseEntity.ok(customerService.getCustomerById(id));
|
||||
public ResponseEntity<UserResponse> getCustomerById(@PathVariable Long id) {
|
||||
return ResponseEntity.ok(userService.getUserById(id));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<CustomerResponse> createCustomer(@Valid @RequestBody CustomerRequest request) {
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(customerService.createCustomer(request));
|
||||
public ResponseEntity<UserResponse> createCustomer(@Valid @RequestBody UserRequest request) {
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(userService.createUser(request));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<CustomerResponse> updateCustomer(
|
||||
public ResponseEntity<UserResponse> 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<Void> deleteCustomer(@PathVariable Long id) {
|
||||
customerService.deleteCustomer(id);
|
||||
userService.deleteUser(id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@PostMapping("/bulk-delete")
|
||||
public ResponseEntity<Void> bulkDeleteCustomers(@Valid @RequestBody BulkDeleteRequest request) {
|
||||
customerService.bulkDeleteCustomers(request);
|
||||
userService.bulkDeleteUsers(request);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<List<CustomerPetResponse>> getMyPets() {
|
||||
|
||||
return ResponseEntity.ok(customerPetService.getMyPets());
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<CustomerPetResponse> createPet(@Valid @RequestBody CustomerPetRequest request) {
|
||||
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(customerPetService.createPet(request));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<CustomerPetResponse> updatePet(@PathVariable Long id, @Valid @RequestBody CustomerPetRequest request) {
|
||||
|
||||
return ResponseEntity.ok(customerPetService.updatePet(id, request));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> 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<String, String> error = new HashMap<>();
|
||||
error.put("message", ex.getMessage());
|
||||
|
||||
return ResponseEntity.badRequest().body(error);
|
||||
}
|
||||
|
||||
catch (IOException ex) {
|
||||
Map<String, String> 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<Resource> 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<CustomerPetResponse> deleteImage(@PathVariable Long id) {
|
||||
|
||||
return ResponseEntity.ok(customerPetService.deleteImage(id));
|
||||
}
|
||||
}
|
||||
@@ -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<List<DropdownOption>> 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<List<DropdownOption>> 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<List<DropdownOption>> 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<List<DropdownOption>> getStoreEmployees(@PathVariable(required = false) Long storeId) {
|
||||
List<EmployeeStore> employees;
|
||||
List<User> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Page<EmployeeResponse>> getAllEmployees(@RequestParam(required = false) String q, Pageable pageable) {
|
||||
return ResponseEntity.ok(employeeService.getAllEmployees(q, pageable));
|
||||
public ResponseEntity<Page<UserResponse>> getAllEmployees(
|
||||
@RequestParam(required = false) String q,
|
||||
Pageable pageable) {
|
||||
return ResponseEntity.ok(userService.getAllUsers(q, "STAFF", pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<EmployeeResponse> getEmployeeById(@PathVariable Long id) {
|
||||
return ResponseEntity.ok(employeeService.getEmployeeById(id));
|
||||
public ResponseEntity<UserResponse> getEmployeeById(@PathVariable Long id) {
|
||||
return ResponseEntity.ok(userService.getUserById(id));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<EmployeeResponse> createEmployee(@Valid @RequestBody EmployeeRequest request) {
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(employeeService.createEmployee(request));
|
||||
public ResponseEntity<UserResponse> createEmployee(@Valid @RequestBody UserRequest request) {
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(userService.createUser(request));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<EmployeeResponse> updateEmployee(@PathVariable Long id, @Valid @RequestBody EmployeeRequest request) {
|
||||
return ResponseEntity.ok(employeeService.updateEmployee(id, request));
|
||||
public ResponseEntity<UserResponse> updateEmployee(
|
||||
@PathVariable Long id,
|
||||
@Valid @RequestBody UserRequest request) {
|
||||
return ResponseEntity.ok(userService.updateUser(id, request));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> deleteEmployee(@PathVariable Long id) {
|
||||
employeeService.deleteEmployee(id);
|
||||
userService.deleteUser(id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<RefundResponse> 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);
|
||||
|
||||
@@ -20,6 +20,8 @@ public class AdoptionRequest {
|
||||
|
||||
private Long employeeId;
|
||||
|
||||
private Long sourceStoreId;
|
||||
|
||||
public Long getPetId() {
|
||||
return petId;
|
||||
}
|
||||
@@ -60,6 +62,14 @@ public class AdoptionRequest {
|
||||
this.employeeId = employeeId;
|
||||
}
|
||||
|
||||
public Long getSourceStoreId() {
|
||||
return sourceStoreId;
|
||||
}
|
||||
|
||||
public void setSourceStoreId(Long sourceStoreId) {
|
||||
this.sourceStoreId = sourceStoreId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -69,12 +79,13 @@ public class AdoptionRequest {
|
||||
Objects.equals(customerId, that.customerId) &&
|
||||
Objects.equals(adoptionDate, that.adoptionDate) &&
|
||||
Objects.equals(adoptionStatus, that.adoptionStatus) &&
|
||||
Objects.equals(employeeId, that.employeeId);
|
||||
Objects.equals(employeeId, that.employeeId) &&
|
||||
Objects.equals(sourceStoreId, that.sourceStoreId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(petId, customerId, adoptionDate, adoptionStatus, employeeId);
|
||||
return Objects.hash(petId, customerId, adoptionDate, adoptionStatus, employeeId, sourceStoreId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,6 +96,7 @@ public class AdoptionRequest {
|
||||
", adoptionDate=" + adoptionDate +
|
||||
", adoptionStatus='" + adoptionStatus + '\'' +
|
||||
", employeeId=" + employeeId +
|
||||
", sourceStoreId=" + sourceStoreId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ public class AdoptionResponse {
|
||||
private String customerName;
|
||||
private Long employeeId;
|
||||
private String employeeName;
|
||||
private Long sourceStoreId;
|
||||
private String sourceStoreName;
|
||||
private LocalDate adoptionDate;
|
||||
private String adoptionStatus;
|
||||
private BigDecimal adoptionFee;
|
||||
@@ -22,7 +24,7 @@ public class AdoptionResponse {
|
||||
public AdoptionResponse() {
|
||||
}
|
||||
|
||||
public AdoptionResponse(Long adoptionId, Long petId, String petName, Long customerId, String customerName, Long employeeId, String employeeName, LocalDate adoptionDate, String adoptionStatus, BigDecimal adoptionFee, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public AdoptionResponse(Long adoptionId, Long petId, String petName, Long customerId, String customerName, Long employeeId, String employeeName, Long sourceStoreId, String sourceStoreName, LocalDate adoptionDate, String adoptionStatus, BigDecimal adoptionFee, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.adoptionId = adoptionId;
|
||||
this.petId = petId;
|
||||
this.petName = petName;
|
||||
@@ -30,6 +32,8 @@ public class AdoptionResponse {
|
||||
this.customerName = customerName;
|
||||
this.employeeId = employeeId;
|
||||
this.employeeName = employeeName;
|
||||
this.sourceStoreId = sourceStoreId;
|
||||
this.sourceStoreName = sourceStoreName;
|
||||
this.adoptionDate = adoptionDate;
|
||||
this.adoptionStatus = adoptionStatus;
|
||||
this.adoptionFee = adoptionFee;
|
||||
@@ -93,6 +97,22 @@ public class AdoptionResponse {
|
||||
this.employeeName = employeeName;
|
||||
}
|
||||
|
||||
public Long getSourceStoreId() {
|
||||
return sourceStoreId;
|
||||
}
|
||||
|
||||
public void setSourceStoreId(Long sourceStoreId) {
|
||||
this.sourceStoreId = sourceStoreId;
|
||||
}
|
||||
|
||||
public String getSourceStoreName() {
|
||||
return sourceStoreName;
|
||||
}
|
||||
|
||||
public void setSourceStoreName(String sourceStoreName) {
|
||||
this.sourceStoreName = sourceStoreName;
|
||||
}
|
||||
|
||||
public LocalDate getAdoptionDate() {
|
||||
return adoptionDate;
|
||||
}
|
||||
@@ -138,12 +158,12 @@ public class AdoptionResponse {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AdoptionResponse that = (AdoptionResponse) o;
|
||||
return Objects.equals(adoptionId, that.adoptionId) && Objects.equals(petId, that.petId) && Objects.equals(petName, that.petName) && Objects.equals(customerId, that.customerId) && Objects.equals(customerName, that.customerName) && Objects.equals(adoptionDate, that.adoptionDate) && Objects.equals(adoptionStatus, that.adoptionStatus) && Objects.equals(adoptionFee, that.adoptionFee) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
return Objects.equals(adoptionId, that.adoptionId) && Objects.equals(petId, that.petId) && Objects.equals(petName, that.petName) && Objects.equals(customerId, that.customerId) && Objects.equals(customerName, that.customerName) && Objects.equals(sourceStoreId, that.sourceStoreId) && Objects.equals(sourceStoreName, that.sourceStoreName) && Objects.equals(adoptionDate, that.adoptionDate) && Objects.equals(adoptionStatus, that.adoptionStatus) && Objects.equals(adoptionFee, that.adoptionFee) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(adoptionId, petId, petName, customerId, customerName, adoptionDate, adoptionStatus, adoptionFee, createdAt, updatedAt);
|
||||
return Objects.hash(adoptionId, petId, petName, customerId, customerName, sourceStoreId, sourceStoreName, adoptionDate, adoptionStatus, adoptionFee, createdAt, updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,6 +174,8 @@ public class AdoptionResponse {
|
||||
", petName='" + petName + '\'' +
|
||||
", customerId=" + customerId +
|
||||
", customerName='" + customerName + '\'' +
|
||||
", sourceStoreId=" + sourceStoreId +
|
||||
", sourceStoreName='" + sourceStoreName + '\'' +
|
||||
", adoptionDate=" + adoptionDate +
|
||||
", adoptionStatus='" + adoptionStatus + '\'' +
|
||||
", adoptionFee=" + adoptionFee +
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.petshop.backend.dto.appointment;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class AppointmentRequest {
|
||||
@@ -25,9 +24,7 @@ public class AppointmentRequest {
|
||||
@NotNull(message = "Appointment status is required")
|
||||
private String appointmentStatus;
|
||||
|
||||
private List<Long> petIds;
|
||||
|
||||
private List<Long> customerPetIds;
|
||||
private Long petId;
|
||||
|
||||
private Long employeeId;
|
||||
|
||||
@@ -79,20 +76,12 @@ public class AppointmentRequest {
|
||||
this.appointmentStatus = appointmentStatus;
|
||||
}
|
||||
|
||||
public List<Long> getPetIds() {
|
||||
return petIds;
|
||||
public Long getPetId() {
|
||||
return petId;
|
||||
}
|
||||
|
||||
public void setPetIds(List<Long> petIds) {
|
||||
this.petIds = petIds;
|
||||
}
|
||||
|
||||
public List<Long> getCustomerPetIds() {
|
||||
return customerPetIds;
|
||||
}
|
||||
|
||||
public void setCustomerPetIds(List<Long> customerPetIds) {
|
||||
this.customerPetIds = customerPetIds;
|
||||
public void setPetId(Long petId) {
|
||||
this.petId = petId;
|
||||
}
|
||||
|
||||
public Long getEmployeeId() {
|
||||
@@ -114,14 +103,13 @@ public class AppointmentRequest {
|
||||
Objects.equals(appointmentDate, that.appointmentDate) &&
|
||||
Objects.equals(appointmentTime, that.appointmentTime) &&
|
||||
Objects.equals(appointmentStatus, that.appointmentStatus) &&
|
||||
Objects.equals(petIds, that.petIds) &&
|
||||
Objects.equals(customerPetIds, that.customerPetIds) &&
|
||||
Objects.equals(petId, that.petId) &&
|
||||
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, petId, employeeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,8 +121,7 @@ public class AppointmentRequest {
|
||||
", appointmentDate=" + appointmentDate +
|
||||
", appointmentTime=" + appointmentTime +
|
||||
", appointmentStatus='" + appointmentStatus + '\'' +
|
||||
", petIds=" + petIds +
|
||||
", customerPetIds=" + customerPetIds +
|
||||
", petId=" + petId +
|
||||
", employeeId=" + employeeId +
|
||||
'}';
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.petshop.backend.dto.appointment;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class AppointmentResponse {
|
||||
@@ -19,17 +18,15 @@ public class AppointmentResponse {
|
||||
private String appointmentStatus;
|
||||
private Long employeeId;
|
||||
private String employeeName;
|
||||
private List<String> petNames;
|
||||
private List<Long> petIds;
|
||||
private List<String> customerPetNames;
|
||||
private List<Long> customerPetIds;
|
||||
private String petName;
|
||||
private Long petId;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public AppointmentResponse() {
|
||||
}
|
||||
|
||||
public AppointmentResponse(Long appointmentId, Long customerId, String customerName, Long storeId, String storeName, Long serviceId, String serviceName, LocalDate appointmentDate, LocalTime appointmentTime, String appointmentStatus, List<String> petNames, List<Long> petIds, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public AppointmentResponse(Long appointmentId, Long customerId, String customerName, Long storeId, String storeName, Long serviceId, String serviceName, LocalDate appointmentDate, LocalTime appointmentTime, String appointmentStatus, String petName, Long petId, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.appointmentId = appointmentId;
|
||||
this.customerId = customerId;
|
||||
this.customerName = customerName;
|
||||
@@ -40,8 +37,8 @@ public class AppointmentResponse {
|
||||
this.appointmentDate = appointmentDate;
|
||||
this.appointmentTime = appointmentTime;
|
||||
this.appointmentStatus = appointmentStatus;
|
||||
this.petNames = petNames;
|
||||
this.petIds = petIds;
|
||||
this.petName = petName;
|
||||
this.petId = petId;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
@@ -142,38 +139,20 @@ public class AppointmentResponse {
|
||||
this.employeeName = employeeName;
|
||||
}
|
||||
|
||||
public List<String> getPetNames() {
|
||||
return petNames;
|
||||
public String getPetName() {
|
||||
return petName;
|
||||
}
|
||||
|
||||
public void setPetNames(List<String> petNames) {
|
||||
this.petNames = petNames;
|
||||
public void setPetName(String petName) {
|
||||
this.petName = petName;
|
||||
}
|
||||
|
||||
public List<Long> getPetIds() {
|
||||
return petIds;
|
||||
public Long getPetId() {
|
||||
return petId;
|
||||
}
|
||||
|
||||
public void setPetIds(List<Long> petIds) {
|
||||
this.petIds = petIds;
|
||||
}
|
||||
|
||||
public List<String> getCustomerPetNames() {
|
||||
|
||||
return customerPetNames;
|
||||
}
|
||||
|
||||
public void setCustomerPetNames(List<String> customerPetNames) {
|
||||
this.customerPetNames = customerPetNames;
|
||||
}
|
||||
|
||||
public List<Long> getCustomerPetIds() {
|
||||
|
||||
return customerPetIds;
|
||||
}
|
||||
|
||||
public void setCustomerPetIds(List<Long> customerPetIds) {
|
||||
this.customerPetIds = customerPetIds;
|
||||
public void setPetId(Long petId) {
|
||||
this.petId = petId;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
@@ -197,12 +176,12 @@ public class AppointmentResponse {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AppointmentResponse that = (AppointmentResponse) o;
|
||||
return Objects.equals(appointmentId, that.appointmentId) && Objects.equals(customerId, that.customerId) && Objects.equals(customerName, that.customerName) && Objects.equals(storeId, that.storeId) && Objects.equals(storeName, that.storeName) && Objects.equals(serviceId, that.serviceId) && Objects.equals(serviceName, that.serviceName) && Objects.equals(appointmentDate, that.appointmentDate) && Objects.equals(appointmentTime, that.appointmentTime) && Objects.equals(appointmentStatus, that.appointmentStatus) && Objects.equals(petNames, that.petNames) && Objects.equals(petIds, that.petIds) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
return Objects.equals(appointmentId, that.appointmentId) && Objects.equals(customerId, that.customerId) && Objects.equals(customerName, that.customerName) && Objects.equals(storeId, that.storeId) && Objects.equals(storeName, that.storeName) && Objects.equals(serviceId, that.serviceId) && Objects.equals(serviceName, that.serviceName) && Objects.equals(appointmentDate, that.appointmentDate) && Objects.equals(appointmentTime, that.appointmentTime) && Objects.equals(appointmentStatus, that.appointmentStatus) && Objects.equals(petName, that.petName) && Objects.equals(petId, that.petId) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(appointmentId, customerId, customerName, storeId, storeName, serviceId, serviceName, appointmentDate, appointmentTime, appointmentStatus, petNames, petIds, createdAt, updatedAt);
|
||||
return Objects.hash(appointmentId, customerId, customerName, storeId, storeName, serviceId, serviceName, appointmentDate, appointmentTime, appointmentStatus, petName, petId, createdAt, updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -218,8 +197,8 @@ public class AppointmentResponse {
|
||||
", appointmentDate=" + appointmentDate +
|
||||
", appointmentTime=" + appointmentTime +
|
||||
", appointmentStatus='" + appointmentStatus + '\'' +
|
||||
", petNames=" + petNames +
|
||||
", petIds=" + petIds +
|
||||
", petName='" + petName + '\'' +
|
||||
", petId=" + petId +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
'}';
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
package com.petshop.backend.dto.chat;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
|
||||
public class MessageRequest {
|
||||
@NotBlank(message = "Message content is required")
|
||||
private String content;
|
||||
private String attachmentUrl;
|
||||
private String attachmentName;
|
||||
private String attachmentMimeType;
|
||||
private Long attachmentSizeBytes;
|
||||
|
||||
public MessageRequest() {
|
||||
}
|
||||
|
||||
public MessageRequest(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
@@ -20,4 +17,36 @@ public class MessageRequest {
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getAttachmentUrl() {
|
||||
return attachmentUrl;
|
||||
}
|
||||
|
||||
public void setAttachmentUrl(String attachmentUrl) {
|
||||
this.attachmentUrl = attachmentUrl;
|
||||
}
|
||||
|
||||
public String getAttachmentName() {
|
||||
return attachmentName;
|
||||
}
|
||||
|
||||
public void setAttachmentName(String attachmentName) {
|
||||
this.attachmentName = attachmentName;
|
||||
}
|
||||
|
||||
public String getAttachmentMimeType() {
|
||||
return attachmentMimeType;
|
||||
}
|
||||
|
||||
public void setAttachmentMimeType(String attachmentMimeType) {
|
||||
this.attachmentMimeType = attachmentMimeType;
|
||||
}
|
||||
|
||||
public Long getAttachmentSizeBytes() {
|
||||
return attachmentSizeBytes;
|
||||
}
|
||||
|
||||
public void setAttachmentSizeBytes(Long attachmentSizeBytes) {
|
||||
this.attachmentSizeBytes = attachmentSizeBytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ public class MessageResponse {
|
||||
private String content;
|
||||
private LocalDateTime timestamp;
|
||||
private Boolean isRead;
|
||||
private String attachmentUrl;
|
||||
private String attachmentName;
|
||||
private String attachmentMimeType;
|
||||
private Long attachmentSizeBytes;
|
||||
|
||||
public MessageResponse() {
|
||||
}
|
||||
@@ -32,6 +36,10 @@ public class MessageResponse {
|
||||
response.setContent(message.getContent());
|
||||
response.setTimestamp(message.getTimestamp());
|
||||
response.setIsRead(message.getIsRead());
|
||||
response.setAttachmentUrl(message.getAttachmentUrl());
|
||||
response.setAttachmentName(message.getAttachmentName());
|
||||
response.setAttachmentMimeType(message.getAttachmentMimeType());
|
||||
response.setAttachmentSizeBytes(message.getAttachmentSizeBytes());
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -82,4 +90,36 @@ public class MessageResponse {
|
||||
public void setIsRead(Boolean isRead) {
|
||||
this.isRead = isRead;
|
||||
}
|
||||
|
||||
public String getAttachmentUrl() {
|
||||
return attachmentUrl;
|
||||
}
|
||||
|
||||
public void setAttachmentUrl(String attachmentUrl) {
|
||||
this.attachmentUrl = attachmentUrl;
|
||||
}
|
||||
|
||||
public String getAttachmentName() {
|
||||
return attachmentName;
|
||||
}
|
||||
|
||||
public void setAttachmentName(String attachmentName) {
|
||||
this.attachmentName = attachmentName;
|
||||
}
|
||||
|
||||
public String getAttachmentMimeType() {
|
||||
return attachmentMimeType;
|
||||
}
|
||||
|
||||
public void setAttachmentMimeType(String attachmentMimeType) {
|
||||
this.attachmentMimeType = attachmentMimeType;
|
||||
}
|
||||
|
||||
public Long getAttachmentSizeBytes() {
|
||||
return attachmentSizeBytes;
|
||||
}
|
||||
|
||||
public void setAttachmentSizeBytes(Long attachmentSizeBytes) {
|
||||
this.attachmentSizeBytes = attachmentSizeBytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -12,6 +12,8 @@ public class InventoryRequest {
|
||||
@PositiveOrZero(message = "Quantity must be zero or positive")
|
||||
private Integer quantity;
|
||||
|
||||
private Long storeId;
|
||||
|
||||
public Long getProdId() {
|
||||
return prodId;
|
||||
}
|
||||
@@ -28,18 +30,27 @@ public class InventoryRequest {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
InventoryRequest that = (InventoryRequest) o;
|
||||
return Objects.equals(prodId, that.prodId) &&
|
||||
Objects.equals(quantity, that.quantity);
|
||||
Objects.equals(quantity, that.quantity) &&
|
||||
Objects.equals(storeId, that.storeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(prodId, quantity);
|
||||
return Objects.hash(prodId, quantity, storeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,6 +58,7 @@ public class InventoryRequest {
|
||||
return "InventoryRequest{" +
|
||||
"prodId=" + prodId +
|
||||
", quantity=" + quantity +
|
||||
", storeId=" + storeId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ public class InventoryResponse {
|
||||
private Long prodId;
|
||||
private String productName;
|
||||
private String categoryName;
|
||||
private Long storeId;
|
||||
private String storeName;
|
||||
private Integer quantity;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
@@ -15,11 +17,13 @@ public class InventoryResponse {
|
||||
public InventoryResponse() {
|
||||
}
|
||||
|
||||
public InventoryResponse(Long inventoryId, Long prodId, String productName, String categoryName, Integer quantity, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public InventoryResponse(Long inventoryId, Long prodId, String productName, String categoryName, Long storeId, String storeName, Integer quantity, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.inventoryId = inventoryId;
|
||||
this.prodId = prodId;
|
||||
this.productName = productName;
|
||||
this.categoryName = categoryName;
|
||||
this.storeId = storeId;
|
||||
this.storeName = storeName;
|
||||
this.quantity = quantity;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
@@ -57,6 +61,22 @@ public class InventoryResponse {
|
||||
this.categoryName = categoryName;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
public String getStoreName() {
|
||||
return storeName;
|
||||
}
|
||||
|
||||
public void setStoreName(String storeName) {
|
||||
this.storeName = storeName;
|
||||
}
|
||||
|
||||
public Integer getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
@@ -86,12 +106,12 @@ public class InventoryResponse {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
InventoryResponse that = (InventoryResponse) o;
|
||||
return Objects.equals(inventoryId, that.inventoryId) && Objects.equals(prodId, that.prodId) && Objects.equals(productName, that.productName) && Objects.equals(categoryName, that.categoryName) && Objects.equals(quantity, that.quantity) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
return Objects.equals(inventoryId, that.inventoryId) && Objects.equals(prodId, that.prodId) && Objects.equals(productName, that.productName) && Objects.equals(categoryName, that.categoryName) && Objects.equals(storeId, that.storeId) && Objects.equals(storeName, that.storeName) && Objects.equals(quantity, that.quantity) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(inventoryId, prodId, productName, categoryName, quantity, createdAt, updatedAt);
|
||||
return Objects.hash(inventoryId, prodId, productName, categoryName, storeId, storeName, quantity, createdAt, updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,6 +121,8 @@ public class InventoryResponse {
|
||||
", prodId=" + prodId +
|
||||
", productName='" + productName + '\'' +
|
||||
", categoryName='" + categoryName + '\'' +
|
||||
", storeId=" + storeId +
|
||||
", storeName='" + storeName + '\'' +
|
||||
", quantity=" + quantity +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
|
||||
@@ -8,6 +8,8 @@ public class PurchaseOrderResponse {
|
||||
private Long purchaseOrderId;
|
||||
private Long supId;
|
||||
private String supplierName;
|
||||
private Long storeId;
|
||||
private String storeName;
|
||||
private LocalDate orderDate;
|
||||
private String status;
|
||||
private LocalDateTime createdAt;
|
||||
@@ -16,10 +18,12 @@ public class PurchaseOrderResponse {
|
||||
public PurchaseOrderResponse() {
|
||||
}
|
||||
|
||||
public PurchaseOrderResponse(Long purchaseOrderId, Long supId, String supplierName, LocalDate orderDate, String status, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public PurchaseOrderResponse(Long purchaseOrderId, Long supId, String supplierName, Long storeId, String storeName, LocalDate orderDate, String status, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.purchaseOrderId = purchaseOrderId;
|
||||
this.supId = supId;
|
||||
this.supplierName = supplierName;
|
||||
this.storeId = storeId;
|
||||
this.storeName = storeName;
|
||||
this.orderDate = orderDate;
|
||||
this.status = status;
|
||||
this.createdAt = createdAt;
|
||||
@@ -50,6 +54,22 @@ public class PurchaseOrderResponse {
|
||||
this.supplierName = supplierName;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
public String getStoreName() {
|
||||
return storeName;
|
||||
}
|
||||
|
||||
public void setStoreName(String storeName) {
|
||||
this.storeName = storeName;
|
||||
}
|
||||
|
||||
public LocalDate getOrderDate() {
|
||||
return orderDate;
|
||||
}
|
||||
@@ -87,12 +107,12 @@ public class PurchaseOrderResponse {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
PurchaseOrderResponse that = (PurchaseOrderResponse) o;
|
||||
return Objects.equals(purchaseOrderId, that.purchaseOrderId) && Objects.equals(supId, that.supId) && Objects.equals(supplierName, that.supplierName) && Objects.equals(orderDate, that.orderDate) && Objects.equals(status, that.status) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
return Objects.equals(purchaseOrderId, that.purchaseOrderId) && Objects.equals(supId, that.supId) && Objects.equals(supplierName, that.supplierName) && Objects.equals(storeId, that.storeId) && Objects.equals(storeName, that.storeName) && Objects.equals(orderDate, that.orderDate) && Objects.equals(status, that.status) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(purchaseOrderId, supId, supplierName, orderDate, status, createdAt, updatedAt);
|
||||
return Objects.hash(purchaseOrderId, supId, supplierName, storeId, storeName, orderDate, status, createdAt, updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,6 +121,8 @@ public class PurchaseOrderResponse {
|
||||
"purchaseOrderId=" + purchaseOrderId +
|
||||
", supId=" + supId +
|
||||
", supplierName='" + supplierName + '\'' +
|
||||
", storeId=" + storeId +
|
||||
", storeName='" + storeName + '\'' +
|
||||
", orderDate=" + orderDate +
|
||||
", status='" + status + '\'' +
|
||||
", createdAt=" + createdAt +
|
||||
|
||||
@@ -22,6 +22,12 @@ public class SaleRequest {
|
||||
|
||||
private Long customerId;
|
||||
|
||||
private String channel;
|
||||
|
||||
private Long couponId;
|
||||
|
||||
private Long cartId;
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
@@ -70,6 +76,30 @@ public class SaleRequest {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public String getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public void setChannel(String channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public Long getCouponId() {
|
||||
return couponId;
|
||||
}
|
||||
|
||||
public void setCouponId(Long couponId) {
|
||||
this.couponId = couponId;
|
||||
}
|
||||
|
||||
public Long getCartId() {
|
||||
return cartId;
|
||||
}
|
||||
|
||||
public void setCartId(Long cartId) {
|
||||
this.cartId = cartId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -80,12 +110,15 @@ public class SaleRequest {
|
||||
Objects.equals(items, that.items) &&
|
||||
Objects.equals(isRefund, that.isRefund) &&
|
||||
Objects.equals(originalSaleId, that.originalSaleId) &&
|
||||
Objects.equals(customerId, that.customerId);
|
||||
Objects.equals(customerId, that.customerId) &&
|
||||
Objects.equals(channel, that.channel) &&
|
||||
Objects.equals(couponId, that.couponId) &&
|
||||
Objects.equals(cartId, that.cartId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(storeId, paymentMethod, items, isRefund, originalSaleId, customerId);
|
||||
return Objects.hash(storeId, paymentMethod, items, isRefund, originalSaleId, customerId, channel, couponId, cartId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,6 +130,9 @@ public class SaleRequest {
|
||||
", isRefund=" + isRefund +
|
||||
", originalSaleId=" + originalSaleId +
|
||||
", customerId=" + customerId +
|
||||
", channel='" + channel + '\'' +
|
||||
", couponId=" + couponId +
|
||||
", cartId=" + cartId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,13 @@ public class SaleResponse {
|
||||
private Long storeId;
|
||||
private String storeName;
|
||||
private BigDecimal totalAmount;
|
||||
private BigDecimal subtotalAmount;
|
||||
private BigDecimal couponDiscountAmount;
|
||||
private BigDecimal employeeDiscountAmount;
|
||||
private Integer pointsEarned;
|
||||
private String channel;
|
||||
private Long couponId;
|
||||
private Long cartId;
|
||||
private String paymentMethod;
|
||||
private Boolean isRefund;
|
||||
private Long originalSaleId;
|
||||
@@ -22,21 +29,6 @@ public class SaleResponse {
|
||||
public SaleResponse() {
|
||||
}
|
||||
|
||||
public SaleResponse(Long saleId, LocalDateTime saleDate, Long employeeId, String employeeName, Long storeId, String storeName, BigDecimal totalAmount, String paymentMethod, Boolean isRefund, Long originalSaleId, List<SaleItemResponse> items, LocalDateTime createdAt) {
|
||||
this.saleId = saleId;
|
||||
this.saleDate = saleDate;
|
||||
this.employeeId = employeeId;
|
||||
this.employeeName = employeeName;
|
||||
this.storeId = storeId;
|
||||
this.storeName = storeName;
|
||||
this.totalAmount = totalAmount;
|
||||
this.paymentMethod = paymentMethod;
|
||||
this.isRefund = isRefund;
|
||||
this.originalSaleId = originalSaleId;
|
||||
this.items = items;
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
public Long getSaleId() {
|
||||
return saleId;
|
||||
}
|
||||
@@ -93,6 +85,62 @@ public class SaleResponse {
|
||||
this.totalAmount = totalAmount;
|
||||
}
|
||||
|
||||
public BigDecimal getSubtotalAmount() {
|
||||
return subtotalAmount;
|
||||
}
|
||||
|
||||
public void setSubtotalAmount(BigDecimal subtotalAmount) {
|
||||
this.subtotalAmount = subtotalAmount;
|
||||
}
|
||||
|
||||
public BigDecimal getCouponDiscountAmount() {
|
||||
return couponDiscountAmount;
|
||||
}
|
||||
|
||||
public void setCouponDiscountAmount(BigDecimal couponDiscountAmount) {
|
||||
this.couponDiscountAmount = couponDiscountAmount;
|
||||
}
|
||||
|
||||
public BigDecimal getEmployeeDiscountAmount() {
|
||||
return employeeDiscountAmount;
|
||||
}
|
||||
|
||||
public void setEmployeeDiscountAmount(BigDecimal employeeDiscountAmount) {
|
||||
this.employeeDiscountAmount = employeeDiscountAmount;
|
||||
}
|
||||
|
||||
public Integer getPointsEarned() {
|
||||
return pointsEarned;
|
||||
}
|
||||
|
||||
public void setPointsEarned(Integer pointsEarned) {
|
||||
this.pointsEarned = pointsEarned;
|
||||
}
|
||||
|
||||
public String getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public void setChannel(String channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public Long getCouponId() {
|
||||
return couponId;
|
||||
}
|
||||
|
||||
public void setCouponId(Long couponId) {
|
||||
this.couponId = couponId;
|
||||
}
|
||||
|
||||
public Long getCartId() {
|
||||
return cartId;
|
||||
}
|
||||
|
||||
public void setCartId(Long cartId) {
|
||||
this.cartId = cartId;
|
||||
}
|
||||
|
||||
public String getPaymentMethod() {
|
||||
return paymentMethod;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,9 @@ import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class ServiceRequest {
|
||||
@NotBlank(message = "Service name is required")
|
||||
@@ -19,6 +21,8 @@ public class ServiceRequest {
|
||||
@Positive(message = "Duration must be positive")
|
||||
private Integer serviceDuration;
|
||||
|
||||
private Set<String> species = new HashSet<>();
|
||||
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
@@ -51,6 +55,14 @@ public class ServiceRequest {
|
||||
this.serviceDuration = serviceDuration;
|
||||
}
|
||||
|
||||
public Set<String> getSpecies() {
|
||||
return species;
|
||||
}
|
||||
|
||||
public void setSpecies(Set<String> species) {
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -59,12 +71,13 @@ public class ServiceRequest {
|
||||
return Objects.equals(serviceName, that.serviceName) &&
|
||||
Objects.equals(serviceDesc, that.serviceDesc) &&
|
||||
Objects.equals(servicePrice, that.servicePrice) &&
|
||||
Objects.equals(serviceDuration, that.serviceDuration);
|
||||
Objects.equals(serviceDuration, that.serviceDuration) &&
|
||||
Objects.equals(species, that.species);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(serviceName, serviceDesc, servicePrice, serviceDuration);
|
||||
return Objects.hash(serviceName, serviceDesc, servicePrice, serviceDuration, species);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,6 +87,7 @@ public class ServiceRequest {
|
||||
", serviceDesc='" + serviceDesc + '\'' +
|
||||
", servicePrice=" + servicePrice +
|
||||
", serviceDuration=" + serviceDuration +
|
||||
", species=" + species +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.petshop.backend.dto.service;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public class ServiceResponse {
|
||||
private Long serviceId;
|
||||
@@ -10,18 +11,20 @@ public class ServiceResponse {
|
||||
private String serviceDesc;
|
||||
private BigDecimal servicePrice;
|
||||
private Integer serviceDuration;
|
||||
private Set<String> species;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public ServiceResponse() {
|
||||
}
|
||||
|
||||
public ServiceResponse(Long serviceId, String serviceName, String serviceDesc, BigDecimal servicePrice, Integer serviceDuration, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public ServiceResponse(Long serviceId, String serviceName, String serviceDesc, BigDecimal servicePrice, Integer serviceDuration, Set<String> species, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.serviceId = serviceId;
|
||||
this.serviceName = serviceName;
|
||||
this.serviceDesc = serviceDesc;
|
||||
this.servicePrice = servicePrice;
|
||||
this.serviceDuration = serviceDuration;
|
||||
this.species = species;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
@@ -66,6 +69,14 @@ public class ServiceResponse {
|
||||
this.serviceDuration = serviceDuration;
|
||||
}
|
||||
|
||||
public Set<String> getSpecies() {
|
||||
return species;
|
||||
}
|
||||
|
||||
public void setSpecies(Set<String> species) {
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
@@ -87,12 +98,12 @@ public class ServiceResponse {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ServiceResponse that = (ServiceResponse) o;
|
||||
return Objects.equals(serviceId, that.serviceId) && Objects.equals(serviceName, that.serviceName) && Objects.equals(serviceDesc, that.serviceDesc) && Objects.equals(servicePrice, that.servicePrice) && Objects.equals(serviceDuration, that.serviceDuration) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
return Objects.equals(serviceId, that.serviceId) && Objects.equals(serviceName, that.serviceName) && Objects.equals(serviceDesc, that.serviceDesc) && Objects.equals(servicePrice, that.servicePrice) && Objects.equals(serviceDuration, that.serviceDuration) && Objects.equals(species, that.species) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(serviceId, serviceName, serviceDesc, servicePrice, serviceDuration, createdAt, updatedAt);
|
||||
return Objects.hash(serviceId, serviceName, serviceDesc, servicePrice, serviceDuration, species, createdAt, updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,6 +114,7 @@ public class ServiceResponse {
|
||||
", serviceDesc='" + serviceDesc + '\'' +
|
||||
", servicePrice=" + servicePrice +
|
||||
", serviceDuration=" + serviceDuration +
|
||||
", species=" + species +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
'}';
|
||||
|
||||
@@ -18,6 +18,8 @@ public class StoreRequest {
|
||||
@Email(message = "Email must be valid")
|
||||
private String email;
|
||||
|
||||
private String imageUrl;
|
||||
|
||||
public String getStoreName() {
|
||||
return storeName;
|
||||
}
|
||||
@@ -50,6 +52,14 @@ public class StoreRequest {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -58,12 +68,13 @@ public class StoreRequest {
|
||||
return Objects.equals(storeName, that.storeName) &&
|
||||
Objects.equals(address, that.address) &&
|
||||
Objects.equals(phone, that.phone) &&
|
||||
Objects.equals(email, that.email);
|
||||
Objects.equals(email, that.email) &&
|
||||
Objects.equals(imageUrl, that.imageUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(storeName, address, phone, email);
|
||||
return Objects.hash(storeName, address, phone, email, imageUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,6 +84,7 @@ public class StoreRequest {
|
||||
", address='" + address + '\'' +
|
||||
", phone='" + phone + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", imageUrl='" + imageUrl + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,17 +9,19 @@ public class StoreResponse {
|
||||
private String address;
|
||||
private String phone;
|
||||
private String email;
|
||||
private String imageUrl;
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
public StoreResponse() {
|
||||
}
|
||||
|
||||
public StoreResponse(Long storeId, String storeName, String address, String phone, String email, LocalDateTime createdAt) {
|
||||
public StoreResponse(Long storeId, String storeName, String address, String phone, String email, String imageUrl, LocalDateTime createdAt) {
|
||||
this.storeId = storeId;
|
||||
this.storeName = storeName;
|
||||
this.address = address;
|
||||
this.phone = phone;
|
||||
this.email = email;
|
||||
this.imageUrl = imageUrl;
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
|
||||
@@ -63,6 +65,14 @@ public class StoreResponse {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
@@ -8,14 +8,20 @@ import jakarta.validation.constraints.Size;
|
||||
import java.util.Objects;
|
||||
|
||||
public class UserRequest {
|
||||
@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 = "Full name is required")
|
||||
@NotBlank(message = "First name is required")
|
||||
@Size(max = 50)
|
||||
private String firstName;
|
||||
|
||||
@NotBlank(message = "Last name is required")
|
||||
@Size(max = 50)
|
||||
private String lastName;
|
||||
|
||||
private String fullName;
|
||||
|
||||
@Email(message = "Invalid email format")
|
||||
@@ -27,6 +33,10 @@ public class UserRequest {
|
||||
@NotNull(message = "Role is required")
|
||||
private User.Role role;
|
||||
|
||||
private String staffRole;
|
||||
|
||||
private Long primaryStoreId;
|
||||
|
||||
private Boolean active = true;
|
||||
|
||||
public String getUsername() {
|
||||
@@ -45,6 +55,22 @@ public class UserRequest {
|
||||
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 getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
@@ -77,6 +103,22 @@ public class UserRequest {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getStaffRole() {
|
||||
return staffRole;
|
||||
}
|
||||
|
||||
public void setStaffRole(String staffRole) {
|
||||
this.staffRole = staffRole;
|
||||
}
|
||||
|
||||
public Long getPrimaryStoreId() {
|
||||
return primaryStoreId;
|
||||
}
|
||||
|
||||
public void setPrimaryStoreId(Long primaryStoreId) {
|
||||
this.primaryStoreId = primaryStoreId;
|
||||
}
|
||||
|
||||
public Boolean getActive() {
|
||||
return active;
|
||||
}
|
||||
@@ -91,29 +133,20 @@ public class UserRequest {
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
UserRequest that = (UserRequest) o;
|
||||
return Objects.equals(username, that.username) &&
|
||||
Objects.equals(password, that.password) &&
|
||||
Objects.equals(fullName, that.fullName) &&
|
||||
Objects.equals(firstName, that.firstName) &&
|
||||
Objects.equals(lastName, that.lastName) &&
|
||||
Objects.equals(email, that.email) &&
|
||||
Objects.equals(phone, that.phone) &&
|
||||
role == that.role &&
|
||||
Objects.equals(active, that.active);
|
||||
role == that.role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(username, password, fullName, email, phone, role, active);
|
||||
return Objects.hash(username, firstName, lastName, email, role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserRequest{" +
|
||||
"username='" + username + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", fullName='" + fullName + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", phone='" + phone + '\'' +
|
||||
", role=" + role +
|
||||
", active=" + active +
|
||||
'}';
|
||||
return "UserRequest{username='" + username + "', firstName='" + firstName +
|
||||
"', lastName='" + lastName + "', role=" + role + '}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,15 @@ import java.util.Objects;
|
||||
public class UserResponse {
|
||||
private Long id;
|
||||
private String username;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String fullName;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String role;
|
||||
private String staffRole;
|
||||
private Long primaryStoreId;
|
||||
private Integer loyaltyPoints;
|
||||
private Boolean active;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
@@ -17,18 +22,6 @@ public class UserResponse {
|
||||
public UserResponse() {
|
||||
}
|
||||
|
||||
public UserResponse(Long id, String username, String fullName, String email, String phone, String role, Boolean active, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.fullName = fullName;
|
||||
this.email = email;
|
||||
this.phone = phone;
|
||||
this.role = role;
|
||||
this.active = active;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -45,6 +38,22 @@ public class UserResponse {
|
||||
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;
|
||||
}
|
||||
@@ -77,6 +86,30 @@ public class UserResponse {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getStaffRole() {
|
||||
return staffRole;
|
||||
}
|
||||
|
||||
public void setStaffRole(String staffRole) {
|
||||
this.staffRole = staffRole;
|
||||
}
|
||||
|
||||
public Long getPrimaryStoreId() {
|
||||
return primaryStoreId;
|
||||
}
|
||||
|
||||
public void setPrimaryStoreId(Long primaryStoreId) {
|
||||
this.primaryStoreId = primaryStoreId;
|
||||
}
|
||||
|
||||
public Integer getLoyaltyPoints() {
|
||||
return loyaltyPoints;
|
||||
}
|
||||
|
||||
public void setLoyaltyPoints(Integer loyaltyPoints) {
|
||||
this.loyaltyPoints = loyaltyPoints;
|
||||
}
|
||||
|
||||
public Boolean getActive() {
|
||||
return active;
|
||||
}
|
||||
@@ -106,26 +139,17 @@ public class UserResponse {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
UserResponse that = (UserResponse) o;
|
||||
return Objects.equals(id, that.id) && Objects.equals(username, that.username) && Objects.equals(fullName, that.fullName) && Objects.equals(email, that.email) && Objects.equals(phone, that.phone) && Objects.equals(role, that.role) && Objects.equals(active, that.active) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
return Objects.equals(id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, username, fullName, email, phone, role, active, createdAt, updatedAt);
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserResponse{" +
|
||||
"id=" + id +
|
||||
", username='" + username + '\'' +
|
||||
", fullName='" + fullName + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", phone='" + phone + '\'' +
|
||||
", role='" + role + '\'' +
|
||||
", active=" + active +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
'}';
|
||||
return "UserResponse{id=" + id + ", username='" + username + "', firstName='" + firstName +
|
||||
"', lastName='" + lastName + "', role='" + role + "', active=" + active + '}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,12 @@ public class ActivityLog {
|
||||
private Long logId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "employeeId", nullable = false)
|
||||
private Employee employee;
|
||||
@JoinColumn(name = "userId", nullable = false)
|
||||
private User user;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "storeId")
|
||||
private StoreLocation store;
|
||||
|
||||
@Column(nullable = false, columnDefinition = "TEXT")
|
||||
private String activity;
|
||||
@@ -26,9 +30,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 +45,20 @@ 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 StoreLocation getStore() {
|
||||
return store;
|
||||
}
|
||||
|
||||
public void setStore(StoreLocation store) {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public String getActivity() {
|
||||
@@ -82,7 +94,7 @@ public class ActivityLog {
|
||||
public String toString() {
|
||||
return "ActivityLog{" +
|
||||
"logId=" + logId +
|
||||
", employee=" + employee +
|
||||
", user=" + user +
|
||||
", activity='" + activity + '\'' +
|
||||
", logTimestamp=" + logTimestamp +
|
||||
'}';
|
||||
|
||||
@@ -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,15 @@ 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;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "sourceStoreId")
|
||||
private StoreLocation sourceStore;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDate adoptionDate;
|
||||
@@ -46,17 +49,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,22 +65,30 @@ 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;
|
||||
}
|
||||
|
||||
public StoreLocation getSourceStore() {
|
||||
return sourceStore;
|
||||
}
|
||||
|
||||
public void setSourceStore(StoreLocation sourceStore) {
|
||||
this.sourceStore = sourceStore;
|
||||
}
|
||||
|
||||
public LocalDate getAdoptionDate() {
|
||||
return adoptionDate;
|
||||
}
|
||||
@@ -138,13 +138,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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,7 @@ import org.hibernate.annotations.UpdateTimestamp;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
@Table(name = "appointment")
|
||||
@@ -21,7 +19,7 @@ public class Appointment {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "customerId", nullable = false)
|
||||
private Customer customer;
|
||||
private User customer;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "storeId", nullable = false)
|
||||
@@ -33,7 +31,7 @@ public class Appointment {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "employeeId", nullable = false)
|
||||
private Employee employee;
|
||||
private User employee;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDate appointmentDate;
|
||||
@@ -44,21 +42,9 @@ public class Appointment {
|
||||
@Column(nullable = false, length = 20)
|
||||
private String appointmentStatus;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(
|
||||
name = "appointmentPet",
|
||||
joinColumns = @JoinColumn(name = "appointmentId"),
|
||||
inverseJoinColumns = @JoinColumn(name = "petId")
|
||||
)
|
||||
private Set<Pet> pets = new HashSet<>();
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(
|
||||
name = "appointment_customer_pet",
|
||||
joinColumns = @JoinColumn(name = "appointment_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "customer_pet_id")
|
||||
)
|
||||
private Set<CustomerPet> customerPets = new HashSet<>();
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "petId")
|
||||
private Pet pet;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
@@ -71,20 +57,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<Pet> 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 +65,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 +89,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;
|
||||
}
|
||||
|
||||
@@ -149,21 +121,12 @@ public class Appointment {
|
||||
this.appointmentStatus = appointmentStatus;
|
||||
}
|
||||
|
||||
public Set<Pet> getPets() {
|
||||
return pets;
|
||||
public Pet getPet() {
|
||||
return pet;
|
||||
}
|
||||
|
||||
public void setPets(Set<Pet> pets) {
|
||||
this.pets = pets;
|
||||
}
|
||||
|
||||
public Set<CustomerPet> getCustomerPets() {
|
||||
|
||||
return customerPets;
|
||||
}
|
||||
|
||||
public void setCustomerPets(Set<CustomerPet> customerPets) {
|
||||
this.customerPets = customerPets;
|
||||
public void setPet(Pet pet) {
|
||||
this.pet = pet;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
@@ -206,7 +169,7 @@ public class Appointment {
|
||||
", appointmentDate=" + appointmentDate +
|
||||
", appointmentTime=" + appointmentTime +
|
||||
", appointmentStatus='" + appointmentStatus + '\'' +
|
||||
", pets=" + pets +
|
||||
", pet=" + pet +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
'}';
|
||||
|
||||
155
backend/src/main/java/com/petshop/backend/entity/Cart.java
Normal file
155
backend/src/main/java/com/petshop/backend/entity/Cart.java
Normal file
@@ -0,0 +1,155 @@
|
||||
package com.petshop.backend.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "cart")
|
||||
public class Cart {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long cartId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "userId", nullable = false)
|
||||
private User user;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "storeId")
|
||||
private StoreLocation store;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "couponId")
|
||||
private Coupon coupon;
|
||||
|
||||
@Column(nullable = false, length = 20)
|
||||
private String cartStatus = "ACTIVE";
|
||||
|
||||
@Column(nullable = false, precision = 10, scale = 2)
|
||||
private BigDecimal subtotalAmount = BigDecimal.ZERO;
|
||||
|
||||
@Column(nullable = false, precision = 10, scale = 2)
|
||||
private BigDecimal discountAmount = BigDecimal.ZERO;
|
||||
|
||||
@Column(nullable = false, precision = 10, scale = 2)
|
||||
private BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@UpdateTimestamp
|
||||
@Column(name = "updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public Cart() {
|
||||
}
|
||||
|
||||
public Long getCartId() {
|
||||
return cartId;
|
||||
}
|
||||
|
||||
public void setCartId(Long cartId) {
|
||||
this.cartId = cartId;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public StoreLocation getStore() {
|
||||
return store;
|
||||
}
|
||||
|
||||
public void setStore(StoreLocation store) {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public Coupon getCoupon() {
|
||||
return coupon;
|
||||
}
|
||||
|
||||
public void setCoupon(Coupon coupon) {
|
||||
this.coupon = coupon;
|
||||
}
|
||||
|
||||
public String getCartStatus() {
|
||||
return cartStatus;
|
||||
}
|
||||
|
||||
public void setCartStatus(String cartStatus) {
|
||||
this.cartStatus = cartStatus;
|
||||
}
|
||||
|
||||
public BigDecimal getSubtotalAmount() {
|
||||
return subtotalAmount;
|
||||
}
|
||||
|
||||
public void setSubtotalAmount(BigDecimal subtotalAmount) {
|
||||
this.subtotalAmount = subtotalAmount;
|
||||
}
|
||||
|
||||
public BigDecimal getDiscountAmount() {
|
||||
return discountAmount;
|
||||
}
|
||||
|
||||
public void setDiscountAmount(BigDecimal discountAmount) {
|
||||
this.discountAmount = discountAmount;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalAmount() {
|
||||
return totalAmount;
|
||||
}
|
||||
|
||||
public void setTotalAmount(BigDecimal totalAmount) {
|
||||
this.totalAmount = totalAmount;
|
||||
}
|
||||
|
||||
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;
|
||||
Cart cart = (Cart) o;
|
||||
return Objects.equals(cartId, cart.cartId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(cartId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Cart{" +
|
||||
"cartId=" + cartId +
|
||||
", cartStatus='" + cartStatus + '\'' +
|
||||
", totalAmount=" + totalAmount +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
121
backend/src/main/java/com/petshop/backend/entity/CartItem.java
Normal file
121
backend/src/main/java/com/petshop/backend/entity/CartItem.java
Normal file
@@ -0,0 +1,121 @@
|
||||
package com.petshop.backend.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "cart_item")
|
||||
public class CartItem {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long cartItemId;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "cartId", nullable = false)
|
||||
private Cart cart;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "prodId", nullable = false)
|
||||
private Product product;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Integer quantity;
|
||||
|
||||
@Column(nullable = false, precision = 10, scale = 2)
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@UpdateTimestamp
|
||||
@Column(name = "updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public CartItem() {
|
||||
}
|
||||
|
||||
public Long getCartItemId() {
|
||||
return cartItemId;
|
||||
}
|
||||
|
||||
public void setCartItemId(Long cartItemId) {
|
||||
this.cartItemId = cartItemId;
|
||||
}
|
||||
|
||||
public Cart getCart() {
|
||||
return cart;
|
||||
}
|
||||
|
||||
public void setCart(Cart cart) {
|
||||
this.cart = cart;
|
||||
}
|
||||
|
||||
public Product getProduct() {
|
||||
return product;
|
||||
}
|
||||
|
||||
public void setProduct(Product product) {
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public Integer getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(Integer quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public BigDecimal getUnitPrice() {
|
||||
return unitPrice;
|
||||
}
|
||||
|
||||
public void setUnitPrice(BigDecimal unitPrice) {
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
|
||||
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;
|
||||
CartItem cartItem = (CartItem) o;
|
||||
return Objects.equals(cartItemId, cartItem.cartItemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(cartItemId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CartItem{" +
|
||||
"cartItemId=" + cartItemId +
|
||||
", quantity=" + quantity +
|
||||
", unitPrice=" + unitPrice +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
162
backend/src/main/java/com/petshop/backend/entity/Coupon.java
Normal file
162
backend/src/main/java/com/petshop/backend/entity/Coupon.java
Normal file
@@ -0,0 +1,162 @@
|
||||
package com.petshop.backend.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "coupon")
|
||||
public class Coupon {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long couponId;
|
||||
|
||||
@Column(nullable = false, length = 50, unique = true)
|
||||
private String couponCode;
|
||||
|
||||
@Column(nullable = false, length = 20)
|
||||
private String discountType;
|
||||
|
||||
@Column(nullable = false, precision = 10, scale = 2)
|
||||
private BigDecimal discountValue;
|
||||
|
||||
@Column(precision = 10, scale = 2)
|
||||
private BigDecimal minOrderAmount;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Boolean active = true;
|
||||
|
||||
private LocalDateTime startsAt;
|
||||
|
||||
private LocalDateTime endsAt;
|
||||
|
||||
private Integer usageLimit;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@UpdateTimestamp
|
||||
@Column(name = "updated_at")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public Coupon() {
|
||||
}
|
||||
|
||||
public Long getCouponId() {
|
||||
return couponId;
|
||||
}
|
||||
|
||||
public void setCouponId(Long couponId) {
|
||||
this.couponId = couponId;
|
||||
}
|
||||
|
||||
public String getCouponCode() {
|
||||
return couponCode;
|
||||
}
|
||||
|
||||
public void setCouponCode(String couponCode) {
|
||||
this.couponCode = couponCode;
|
||||
}
|
||||
|
||||
public String getDiscountType() {
|
||||
return discountType;
|
||||
}
|
||||
|
||||
public void setDiscountType(String discountType) {
|
||||
this.discountType = discountType;
|
||||
}
|
||||
|
||||
public BigDecimal getDiscountValue() {
|
||||
return discountValue;
|
||||
}
|
||||
|
||||
public void setDiscountValue(BigDecimal discountValue) {
|
||||
this.discountValue = discountValue;
|
||||
}
|
||||
|
||||
public BigDecimal getMinOrderAmount() {
|
||||
return minOrderAmount;
|
||||
}
|
||||
|
||||
public void setMinOrderAmount(BigDecimal minOrderAmount) {
|
||||
this.minOrderAmount = minOrderAmount;
|
||||
}
|
||||
|
||||
public Boolean getActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActive(Boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public LocalDateTime getStartsAt() {
|
||||
return startsAt;
|
||||
}
|
||||
|
||||
public void setStartsAt(LocalDateTime startsAt) {
|
||||
this.startsAt = startsAt;
|
||||
}
|
||||
|
||||
public LocalDateTime getEndsAt() {
|
||||
return endsAt;
|
||||
}
|
||||
|
||||
public void setEndsAt(LocalDateTime endsAt) {
|
||||
this.endsAt = endsAt;
|
||||
}
|
||||
|
||||
public Integer getUsageLimit() {
|
||||
return usageLimit;
|
||||
}
|
||||
|
||||
public void setUsageLimit(Integer usageLimit) {
|
||||
this.usageLimit = usageLimit;
|
||||
}
|
||||
|
||||
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;
|
||||
Coupon coupon = (Coupon) o;
|
||||
return Objects.equals(couponId, coupon.couponId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(couponId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Coupon{" +
|
||||
"couponId=" + couponId +
|
||||
", couponCode='" + couponCode + '\'' +
|
||||
", discountType='" + discountType + '\'' +
|
||||
", discountValue=" + discountValue +
|
||||
", active=" + active +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,10 @@ public class Inventory {
|
||||
@JoinColumn(name = "prodId", nullable = false)
|
||||
private Product product;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "storeId")
|
||||
private StoreLocation store;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Integer quantity = 0;
|
||||
|
||||
@@ -57,6 +61,14 @@ public class Inventory {
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public StoreLocation getStore() {
|
||||
return store;
|
||||
}
|
||||
|
||||
public void setStore(StoreLocation store) {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public Integer getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
@@ -99,6 +111,7 @@ public class Inventory {
|
||||
return "Inventory{" +
|
||||
"inventoryId=" + inventoryId +
|
||||
", product=" + product +
|
||||
", store=" + store +
|
||||
", quantity=" + quantity +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
|
||||
@@ -19,9 +19,20 @@ public class Message {
|
||||
@Column(nullable = false)
|
||||
private Long senderId;
|
||||
|
||||
@Column(nullable = false, columnDefinition = "TEXT")
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private String content;
|
||||
|
||||
@Column(length = 255)
|
||||
private String attachmentUrl;
|
||||
|
||||
@Column(length = 255)
|
||||
private String attachmentName;
|
||||
|
||||
@Column(length = 100)
|
||||
private String attachmentMimeType;
|
||||
|
||||
private Long attachmentSizeBytes;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(nullable = false, updatable = false)
|
||||
private LocalDateTime timestamp;
|
||||
@@ -88,4 +99,36 @@ public class Message {
|
||||
public void setIsRead(Boolean isRead) {
|
||||
this.isRead = isRead;
|
||||
}
|
||||
|
||||
public String getAttachmentUrl() {
|
||||
return attachmentUrl;
|
||||
}
|
||||
|
||||
public void setAttachmentUrl(String attachmentUrl) {
|
||||
this.attachmentUrl = attachmentUrl;
|
||||
}
|
||||
|
||||
public String getAttachmentName() {
|
||||
return attachmentName;
|
||||
}
|
||||
|
||||
public void setAttachmentName(String attachmentName) {
|
||||
this.attachmentName = attachmentName;
|
||||
}
|
||||
|
||||
public String getAttachmentMimeType() {
|
||||
return attachmentMimeType;
|
||||
}
|
||||
|
||||
public void setAttachmentMimeType(String attachmentMimeType) {
|
||||
this.attachmentMimeType = attachmentMimeType;
|
||||
}
|
||||
|
||||
public Long getAttachmentSizeBytes() {
|
||||
return attachmentSizeBytes;
|
||||
}
|
||||
|
||||
public void setAttachmentSizeBytes(Long attachmentSizeBytes) {
|
||||
this.attachmentSizeBytes = attachmentSizeBytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,8 @@ 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.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@@ -23,6 +20,10 @@ public class PurchaseOrder {
|
||||
@JoinColumn(name = "supId", nullable = false)
|
||||
private Supplier supplier;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "storeId")
|
||||
private StoreLocation store;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDate orderDate;
|
||||
|
||||
@@ -65,6 +66,14 @@ public class PurchaseOrder {
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
public StoreLocation getStore() {
|
||||
return store;
|
||||
}
|
||||
|
||||
public void setStore(StoreLocation store) {
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public LocalDate getOrderDate() {
|
||||
return orderDate;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -46,6 +46,29 @@ public class Sale {
|
||||
@JoinColumn(name = "originalSaleId")
|
||||
private Sale originalSale;
|
||||
|
||||
@Column(nullable = false, length = 20)
|
||||
private String channel = "IN_STORE";
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "cartId")
|
||||
private Cart cart;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "couponId")
|
||||
private Coupon coupon;
|
||||
|
||||
@Column(precision = 10, scale = 2)
|
||||
private BigDecimal subtotalAmount;
|
||||
|
||||
@Column(nullable = false, precision = 10, scale = 2)
|
||||
private BigDecimal couponDiscountAmount = BigDecimal.ZERO;
|
||||
|
||||
@Column(nullable = false, precision = 10, scale = 2)
|
||||
private BigDecimal employeeDiscountAmount = BigDecimal.ZERO;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Integer pointsEarned = 0;
|
||||
|
||||
@OneToMany(mappedBy = "sale", cascade = CascadeType.ALL)
|
||||
private List<SaleItem> items = new ArrayList<>();
|
||||
|
||||
@@ -60,21 +83,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<SaleItem> 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 +99,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 +115,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;
|
||||
}
|
||||
|
||||
@@ -147,6 +155,62 @@ public class Sale {
|
||||
this.originalSale = originalSale;
|
||||
}
|
||||
|
||||
public String getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public void setChannel(String channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public Cart getCart() {
|
||||
return cart;
|
||||
}
|
||||
|
||||
public void setCart(Cart cart) {
|
||||
this.cart = cart;
|
||||
}
|
||||
|
||||
public Coupon getCoupon() {
|
||||
return coupon;
|
||||
}
|
||||
|
||||
public void setCoupon(Coupon coupon) {
|
||||
this.coupon = coupon;
|
||||
}
|
||||
|
||||
public BigDecimal getSubtotalAmount() {
|
||||
return subtotalAmount;
|
||||
}
|
||||
|
||||
public void setSubtotalAmount(BigDecimal subtotalAmount) {
|
||||
this.subtotalAmount = subtotalAmount;
|
||||
}
|
||||
|
||||
public BigDecimal getCouponDiscountAmount() {
|
||||
return couponDiscountAmount;
|
||||
}
|
||||
|
||||
public void setCouponDiscountAmount(BigDecimal couponDiscountAmount) {
|
||||
this.couponDiscountAmount = couponDiscountAmount;
|
||||
}
|
||||
|
||||
public BigDecimal getEmployeeDiscountAmount() {
|
||||
return employeeDiscountAmount;
|
||||
}
|
||||
|
||||
public void setEmployeeDiscountAmount(BigDecimal employeeDiscountAmount) {
|
||||
this.employeeDiscountAmount = employeeDiscountAmount;
|
||||
}
|
||||
|
||||
public Integer getPointsEarned() {
|
||||
return pointsEarned;
|
||||
}
|
||||
|
||||
public void setPointsEarned(Integer pointsEarned) {
|
||||
this.pointsEarned = pointsEarned;
|
||||
}
|
||||
|
||||
public List<SaleItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
@@ -189,16 +253,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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@ import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
@Table(name = "service")
|
||||
@@ -28,6 +30,11 @@ public class Service {
|
||||
@Column(nullable = false)
|
||||
private Integer serviceDuration;
|
||||
|
||||
@ElementCollection(fetch = FetchType.EAGER)
|
||||
@CollectionTable(name = "service_species", joinColumns = @JoinColumn(name = "serviceId"))
|
||||
@Column(name = "species", length = 50)
|
||||
private Set<String> species = new HashSet<>();
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
@@ -89,6 +96,14 @@ public class Service {
|
||||
this.serviceDuration = serviceDuration;
|
||||
}
|
||||
|
||||
public Set<String> getSpecies() {
|
||||
return species;
|
||||
}
|
||||
|
||||
public void setSpecies(Set<String> species) {
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ public class StoreLocation {
|
||||
@Column(nullable = false, length = 100)
|
||||
private String email;
|
||||
|
||||
@Column(length = 500)
|
||||
private String imageUrl;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
@@ -89,6 +92,14 @@ public class StoreLocation {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
@@ -16,15 +16,21 @@ public class User {
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true, length = 50)
|
||||
@Column(unique = true, length = 50)
|
||||
private String username;
|
||||
|
||||
@Column(nullable = false)
|
||||
@Column
|
||||
private String password;
|
||||
|
||||
@Column(unique = true, length = 100)
|
||||
private String email;
|
||||
|
||||
@Column(nullable = false, length = 50)
|
||||
private String firstName;
|
||||
|
||||
@Column(nullable = false, length = 50)
|
||||
private String lastName;
|
||||
|
||||
@Column(length = 100)
|
||||
private String fullName;
|
||||
|
||||
@@ -38,6 +44,16 @@ public class User {
|
||||
@Column(nullable = false, length = 20, columnDefinition = "VARCHAR(20)")
|
||||
private Role role;
|
||||
|
||||
@Column(length = 50)
|
||||
private String staffRole;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "primaryStoreId")
|
||||
private StoreLocation primaryStore;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Integer loyaltyPoints = 0;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Boolean active = true;
|
||||
|
||||
@@ -59,21 +75,6 @@ public class User {
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(Long id, String username, String password, String email, String fullName, String phone, String avatarUrl, Role role, Boolean active, Integer tokenVersion, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.email = email;
|
||||
this.fullName = fullName;
|
||||
this.phone = phone;
|
||||
this.avatarUrl = avatarUrl;
|
||||
this.role = role;
|
||||
this.active = active;
|
||||
this.tokenVersion = tokenVersion;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -106,6 +107,22 @@ public class User {
|
||||
this.email = 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 getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
@@ -138,6 +155,30 @@ public class User {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getStaffRole() {
|
||||
return staffRole;
|
||||
}
|
||||
|
||||
public void setStaffRole(String staffRole) {
|
||||
this.staffRole = staffRole;
|
||||
}
|
||||
|
||||
public StoreLocation getPrimaryStore() {
|
||||
return primaryStore;
|
||||
}
|
||||
|
||||
public void setPrimaryStore(StoreLocation primaryStore) {
|
||||
this.primaryStore = primaryStore;
|
||||
}
|
||||
|
||||
public Integer getLoyaltyPoints() {
|
||||
return loyaltyPoints;
|
||||
}
|
||||
|
||||
public void setLoyaltyPoints(Integer loyaltyPoints) {
|
||||
this.loyaltyPoints = loyaltyPoints;
|
||||
}
|
||||
|
||||
public Boolean getActive() {
|
||||
return active;
|
||||
}
|
||||
@@ -188,16 +229,12 @@ public class User {
|
||||
return "User{" +
|
||||
"id=" + id +
|
||||
", username='" + username + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", firstName='" + firstName + '\'' +
|
||||
", lastName='" + lastName + '\'' +
|
||||
", fullName='" + fullName + '\'' +
|
||||
", phone='" + phone + '\'' +
|
||||
", avatarUrl='" + avatarUrl + '\'' +
|
||||
", role=" + role +
|
||||
", active=" + active +
|
||||
", tokenVersion=" + tokenVersion +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ public interface AdoptionRepository extends JpaRepository<Adoption, Long> {
|
||||
"LOWER(a.pet.petName) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
Page<Adoption> searchAdoptions(@Param("q") String query, Pageable pageable);
|
||||
|
||||
Page<Adoption> findByCustomerCustomerId(Long customerId, Pageable pageable);
|
||||
Page<Adoption> 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, '%')))")
|
||||
|
||||
@@ -21,25 +21,25 @@ public interface AppointmentRepository extends JpaRepository<Appointment, Long>
|
||||
@Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.store.storeId = :storeId AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) NOT IN ('cancelled', 'missed')")
|
||||
List<Appointment> findByStoreAndDate(@Param("storeId") Long storeId, @Param("date") LocalDate date);
|
||||
|
||||
@Query("SELECT DISTINCT a FROM Appointment a LEFT JOIN a.pets p WHERE " +
|
||||
@Query("SELECT a FROM Appointment a LEFT JOIN a.pet p WHERE " +
|
||||
"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<Appointment> searchAppointments(@Param("q") String query, Pageable pageable);
|
||||
|
||||
Page<Appointment> findByCustomerCustomerId(Long customerId, Pageable pageable);
|
||||
Page<Appointment> 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 a FROM Appointment a LEFT JOIN a.pet 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<Appointment> 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<Appointment> 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<Appointment> 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<Appointment> findByEmployeeEmployeeIdInAndAppointmentDate(@Param("employeeIds") List<Long> 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<Appointment> findByEmployeeIdInAndAppointmentDate(@Param("employeeIds") List<Long> employeeIds, @Param("date") LocalDate date);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.petshop.backend.repository;
|
||||
|
||||
import com.petshop.backend.entity.CartItem;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface CartItemRepository extends JpaRepository<CartItem, Long> {
|
||||
|
||||
List<CartItem> findByCartCartId(Long cartId);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.petshop.backend.repository;
|
||||
|
||||
import com.petshop.backend.entity.Cart;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface CartRepository extends JpaRepository<Cart, Long> {
|
||||
|
||||
List<Cart> findByUserId(Long userId);
|
||||
|
||||
Optional<Cart> findByUserIdAndCartStatus(Long userId, String cartStatus);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.petshop.backend.repository;
|
||||
|
||||
import com.petshop.backend.entity.Coupon;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface CouponRepository extends JpaRepository<Coupon, Long> {
|
||||
|
||||
Optional<Coupon> findByCouponCode(String couponCode);
|
||||
}
|
||||
@@ -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<CustomerPet, Long> {
|
||||
|
||||
List<CustomerPet> findByCustomerCustomerIdOrderByCreatedAtDesc(Long customerId);
|
||||
|
||||
List<CustomerPet> findByCustomerCustomerIdOrderByPetNameAsc(Long customerId);
|
||||
|
||||
Optional<CustomerPet> findByCustomerPetIdAndCustomerCustomerId(Long customerPetId, Long customerId);
|
||||
}
|
||||
@@ -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<Customer, Long> {
|
||||
|
||||
Optional<Customer> findByUserId(Long userId);
|
||||
List<Customer> 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<Customer> 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<Customer> searchCustomers(@Param("q") String query, Pageable pageable);
|
||||
}
|
||||
@@ -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<Employee, Long> {
|
||||
Optional<Employee> findByUserId(Long userId);
|
||||
List<Employee> findAllByEmail(String email);
|
||||
Optional<Employee> findFirstByIsActiveTrueOrderByEmployeeIdAsc();
|
||||
List<Employee> 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<Employee> searchEmployees(@Param("q") String query, Pageable pageable);
|
||||
}
|
||||
@@ -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<EmployeeStore, EmployeeStore.EmployeeStoreId> {
|
||||
Optional<EmployeeStore> 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<EmployeeStore> findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(@Param("storeId") Long storeId);
|
||||
|
||||
@Query("SELECT es FROM EmployeeStore es WHERE es.employee.isActive = true ORDER BY es.employee.employeeId ASC")
|
||||
List<EmployeeStore> findActiveAllOrderByEmployeeEmployeeIdAsc();
|
||||
}
|
||||
@@ -16,8 +16,12 @@ public interface InventoryRepository extends JpaRepository<Inventory, Long> {
|
||||
@Query("SELECT i FROM Inventory i WHERE i.product.prodId = :productId")
|
||||
Optional<Inventory> findByProductId(@Param("productId") Long productId);
|
||||
|
||||
@Query("SELECT i FROM Inventory i WHERE " +
|
||||
@Query("SELECT i FROM Inventory i WHERE i.product.prodId = :productId AND i.store.storeId = :storeId")
|
||||
Optional<Inventory> findByProductIdAndStoreId(@Param("productId") Long productId, @Param("storeId") Long storeId);
|
||||
|
||||
@Query("SELECT i FROM Inventory i LEFT JOIN i.store s WHERE " +
|
||||
"LOWER(i.product.prodName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(i.product.category.categoryName) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
"LOWER(i.product.category.categoryName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(s.storeName) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
Page<Inventory> searchInventory(@Param("q") String query, Pageable pageable);
|
||||
}
|
||||
|
||||
@@ -16,21 +16,21 @@ public interface PetRepository extends JpaRepository<Pet, Long> {
|
||||
List<Pet> 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<Pet> 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<Pet> 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<Pet> searchCustomerVisiblePets(@Param("userId") Long userId, @Param("q") String query, @Param("species") String species, @Param("status") String status, Pageable pageable);
|
||||
|
||||
@@ -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<User, Long> {
|
||||
Optional<User> findByPhone(String phone);
|
||||
boolean existsByUsername(String username);
|
||||
Page<User> findByRole(User.Role role, Pageable pageable);
|
||||
List<User> findByRoleAndActiveTrue(User.Role role);
|
||||
List<User> findByPrimaryStoreStoreIdAndRoleAndActiveTrue(Long storeId, User.Role role);
|
||||
Optional<User> findFirstByPrimaryStoreStoreIdAndRoleAndActiveTrueOrderByIdAsc(Long storeId, User.Role role);
|
||||
Optional<User> 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<User> 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, '%')))")
|
||||
|
||||
@@ -4,15 +4,13 @@ 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.StoreLocation;
|
||||
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.StoreRepository;
|
||||
import com.petshop.backend.repository.UserRepository;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -30,16 +28,14 @@ public class AdoptionService {
|
||||
|
||||
private final AdoptionRepository adoptionRepository;
|
||||
private final PetRepository petRepository;
|
||||
private final CustomerRepository customerRepository;
|
||||
private final EmployeeRepository employeeRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final StoreRepository storeRepository;
|
||||
|
||||
public AdoptionService(AdoptionRepository adoptionRepository, PetRepository petRepository, CustomerRepository customerRepository, EmployeeRepository employeeRepository, UserRepository userRepository) {
|
||||
public AdoptionService(AdoptionRepository adoptionRepository, PetRepository petRepository, UserRepository userRepository, StoreRepository storeRepository) {
|
||||
this.adoptionRepository = adoptionRepository;
|
||||
this.petRepository = petRepository;
|
||||
this.customerRepository = customerRepository;
|
||||
this.employeeRepository = employeeRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.storeRepository = storeRepository;
|
||||
}
|
||||
|
||||
public Page<AdoptionResponse> getAllAdoptions(String query, Pageable pageable, Long customerId) {
|
||||
@@ -49,7 +45,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 +62,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 +74,13 @@ 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());
|
||||
StoreLocation sourceStore = request.getSourceStoreId() != null
|
||||
? storeRepository.findById(request.getSourceStoreId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getSourceStoreId()))
|
||||
: null;
|
||||
String adoptionStatus = normalizeAdoptionStatus(request.getAdoptionStatus());
|
||||
validatePetAvailability(pet, null);
|
||||
|
||||
@@ -88,6 +88,7 @@ public class AdoptionService {
|
||||
adoption.setPet(pet);
|
||||
adoption.setCustomer(customer);
|
||||
adoption.setEmployee(employee);
|
||||
adoption.setSourceStore(sourceStore);
|
||||
adoption.setAdoptionDate(request.getAdoptionDate());
|
||||
adoption.setAdoptionStatus(adoptionStatus);
|
||||
|
||||
@@ -104,15 +105,20 @@ 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());
|
||||
StoreLocation sourceStore = request.getSourceStoreId() != null
|
||||
? storeRepository.findById(request.getSourceStoreId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getSourceStoreId()))
|
||||
: null;
|
||||
String adoptionStatus = normalizeAdoptionStatus(request.getAdoptionStatus());
|
||||
validatePetAvailability(pet, adoption.getAdoptionId());
|
||||
|
||||
adoption.setPet(pet);
|
||||
adoption.setCustomer(customer);
|
||||
adoption.setEmployee(employee);
|
||||
adoption.setSourceStore(sourceStore);
|
||||
adoption.setAdoptionDate(request.getAdoptionDate());
|
||||
adoption.setAdoptionStatus(adoptionStatus);
|
||||
|
||||
@@ -135,14 +141,17 @@ public class AdoptionService {
|
||||
}
|
||||
|
||||
private AdoptionResponse mapToResponse(Adoption adoption) {
|
||||
StoreLocation sourceStore = adoption.getSourceStore();
|
||||
return new AdoptionResponse(
|
||||
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(),
|
||||
sourceStore != null ? sourceStore.getStoreId() : null,
|
||||
sourceStore != null ? sourceStore.getStoreName() : null,
|
||||
adoption.getAdoptionDate(),
|
||||
adoption.getAdoptionStatus(),
|
||||
adoption.getPet().getPetPrice(),
|
||||
@@ -151,31 +160,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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -32,34 +24,24 @@ import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
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 +52,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 +70,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 +83,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())
|
||||
@@ -110,16 +92,8 @@ public class AppointmentService {
|
||||
com.petshop.backend.entity.Service service = serviceRepository.findById(request.getServiceId())
|
||||
.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) {
|
||||
throw new IllegalArgumentException("Please specify at least one pet.");
|
||||
}
|
||||
|
||||
Set<Pet> pets = hasPetIds ? fetchPets(request.getPetIds()) : new HashSet<>();
|
||||
Set<CustomerPet> customerPets = hasCustomerPetIds ? fetchCustomerPets(request.getCustomerPetIds(), customer.getCustomerId()) : new HashSet<>();
|
||||
Employee employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId());
|
||||
Pet pet = request.getPetId() != null ? fetchPet(request.getPetId()) : null;
|
||||
User employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId());
|
||||
|
||||
validateStoreAccess(store.getStoreId(), authenticatedUser);
|
||||
validateAvailability(employee, service, request.getAppointmentDate(), request.getAppointmentTime(), null);
|
||||
@@ -131,8 +105,7 @@ public class AppointmentService {
|
||||
appointment.setAppointmentDate(request.getAppointmentDate());
|
||||
appointment.setAppointmentTime(request.getAppointmentTime());
|
||||
appointment.setAppointmentStatus(request.getAppointmentStatus());
|
||||
appointment.setPets(pets);
|
||||
appointment.setCustomerPets(customerPets);
|
||||
appointment.setPet(pet);
|
||||
appointment.setEmployee(employee);
|
||||
|
||||
appointment = appointmentRepository.save(appointment);
|
||||
@@ -148,7 +121,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())
|
||||
@@ -157,16 +130,8 @@ public class AppointmentService {
|
||||
com.petshop.backend.entity.Service service = serviceRepository.findById(request.getServiceId())
|
||||
.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) {
|
||||
throw new IllegalArgumentException("Please specify at least one pet.");
|
||||
}
|
||||
|
||||
Set<Pet> pets = hasPetIds ? fetchPets(request.getPetIds()) : new HashSet<>();
|
||||
Set<CustomerPet> customerPets = hasCustomerPetIds ? fetchCustomerPets(request.getCustomerPetIds(), customer.getCustomerId()) : new HashSet<>();
|
||||
Employee employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId());
|
||||
Pet pet = request.getPetId() != null ? fetchPet(request.getPetId()) : null;
|
||||
User employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId());
|
||||
|
||||
validateStoreAccess(store.getStoreId(), authenticatedUser);
|
||||
validateAvailability(employee, service, request.getAppointmentDate(), request.getAppointmentTime(), id);
|
||||
@@ -177,8 +142,7 @@ public class AppointmentService {
|
||||
appointment.setAppointmentDate(request.getAppointmentDate());
|
||||
appointment.setAppointmentTime(request.getAppointmentTime());
|
||||
appointment.setAppointmentStatus(request.getAppointmentStatus());
|
||||
appointment.setPets(pets);
|
||||
appointment.setCustomerPets(customerPets);
|
||||
appointment.setPet(pet);
|
||||
appointment.setEmployee(employee);
|
||||
|
||||
appointment = appointmentRepository.save(appointment);
|
||||
@@ -206,20 +170,17 @@ public class AppointmentService {
|
||||
com.petshop.backend.entity.Service service = serviceRepository.findById(serviceId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Service not found with id: " + serviceId));
|
||||
|
||||
List<Employee> assignableEmployees = employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(storeId).stream()
|
||||
.filter(es -> isAssignableEmployee(es.getEmployee()))
|
||||
.map(EmployeeStore::getEmployee)
|
||||
.collect(Collectors.toList());
|
||||
List<User> assignableUsers = userRepository.findByPrimaryStoreStoreIdAndRoleAndActiveTrue(storeId, User.Role.STAFF);
|
||||
|
||||
if (assignableEmployees.isEmpty()) {
|
||||
if (assignableUsers.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
List<Long> employeeIds = assignableEmployees.stream().map(Employee::getEmployeeId).collect(Collectors.toList());
|
||||
List<Appointment> allAppointments = appointmentRepository.findByEmployeeEmployeeIdInAndAppointmentDate(employeeIds, date);
|
||||
|
||||
List<Long> employeeIds = assignableUsers.stream().map(User::getId).collect(Collectors.toList());
|
||||
List<Appointment> allAppointments = appointmentRepository.findByEmployeeIdInAndAppointmentDate(employeeIds, date);
|
||||
|
||||
java.util.Map<Long, List<Appointment>> appointmentsByEmployee = allAppointments.stream()
|
||||
.collect(Collectors.groupingBy(a -> a.getEmployee().getEmployeeId()));
|
||||
.collect(Collectors.groupingBy(a -> a.getEmployee().getId()));
|
||||
|
||||
List<String> availableSlots = new ArrayList<>();
|
||||
LocalTime startTime = LocalTime.of(9, 0);
|
||||
@@ -229,8 +190,8 @@ public class AppointmentService {
|
||||
LocalTime currentTime = startTime;
|
||||
while (!currentTime.isAfter(latestStart)) {
|
||||
final LocalTime slotTime = currentTime;
|
||||
boolean anyEmployeeAvailable = assignableEmployees.stream().anyMatch(emp -> {
|
||||
List<Appointment> empAppointments = appointmentsByEmployee.getOrDefault(emp.getEmployeeId(), List.of());
|
||||
boolean anyEmployeeAvailable = assignableUsers.stream().anyMatch(emp -> {
|
||||
List<Appointment> empAppointments = appointmentsByEmployee.getOrDefault(emp.getId(), List.of());
|
||||
return isSlotAvailable(empAppointments, service, slotTime, null);
|
||||
});
|
||||
|
||||
@@ -252,50 +213,17 @@ public class AppointmentService {
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Pet> fetchPets(List<Long> petIds) {
|
||||
Set<Pet> pets = new HashSet<>();
|
||||
for (Long petId : petIds) {
|
||||
Pet pet = petRepository.findById(petId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + petId));
|
||||
pets.add(pet);
|
||||
}
|
||||
return pets;
|
||||
}
|
||||
|
||||
private Set<CustomerPet> fetchCustomerPets(List<Long> customerPetIds, Long customerId) {
|
||||
Set<CustomerPet> 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 Pet fetchPet(Long petId) {
|
||||
return petRepository.findById(petId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Pet not found with id: " + petId));
|
||||
}
|
||||
|
||||
private AppointmentResponse mapToResponse(Appointment appointment) {
|
||||
List<String> petNames = appointment.getPets().stream()
|
||||
.map(Pet::getPetName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Long> petIds = appointment.getPets().stream()
|
||||
.map(Pet::getPetId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<String> customerPetNames = appointment.getCustomerPets().stream()
|
||||
.map(CustomerPet::getPetName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Long> customerPetIds = appointment.getCustomerPets().stream()
|
||||
.map(CustomerPet::getCustomerPetId)
|
||||
.collect(Collectors.toList());
|
||||
Pet pet = appointment.getPet();
|
||||
|
||||
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 +232,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.setPetName(pet != null ? pet.getPetName() : null);
|
||||
response.setPetId(pet != null ? pet.getPetId() : null);
|
||||
response.setCreatedAt(appointment.getCreatedAt());
|
||||
response.setUpdatedAt(appointment.getUpdatedAt());
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
private Employee resolveAppointmentEmployee(Long requestedEmployeeId, Long storeId) {
|
||||
List<EmployeeStore> assignableEmployees = employeeStoreRepository.findActiveByStoreStoreIdOrderByEmployeeEmployeeIdAsc(storeId).stream()
|
||||
.filter(es -> isAssignableEmployee(es.getEmployee()))
|
||||
.collect(Collectors.toList());
|
||||
private User resolveAppointmentEmployee(Long requestedEmployeeId, Long storeId) {
|
||||
List<User> 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<Appointment> 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 +289,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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Conversation> 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<Conversation> assignedToMe = conversationRepository.findByStaffId(userId);
|
||||
List<Conversation> unassigned = conversationRepository.findByStaffIdIsNull();
|
||||
@@ -87,7 +77,8 @@ public class ChatService {
|
||||
return conversations.stream()
|
||||
.map(conv -> {
|
||||
List<Message> messages = messageRepository.findByConversationIdOrderByTimestampAsc(conv.getId());
|
||||
String lastMessage = messages.isEmpty() ? "" : messages.get(messages.size() - 1).getContent();
|
||||
Message last = messages.isEmpty() ? null : messages.get(messages.size() - 1);
|
||||
String lastMessage = last != null && last.getContent() != null ? last.getContent() : "";
|
||||
return ConversationResponse.fromEntity(conv, lastMessage);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
@@ -107,7 +98,8 @@ public class ChatService {
|
||||
}
|
||||
|
||||
List<Message> messages = messageRepository.findByConversationIdOrderByTimestampAsc(conversationId);
|
||||
String lastMessage = messages.isEmpty() ? "" : messages.get(messages.size() - 1).getContent();
|
||||
Message last = messages.isEmpty() ? null : messages.get(messages.size() - 1);
|
||||
String lastMessage = last != null && last.getContent() != null ? last.getContent() : "";
|
||||
|
||||
return ConversationResponse.fromEntity(conversation, lastMessage);
|
||||
}
|
||||
@@ -134,6 +126,10 @@ public class ChatService {
|
||||
message.setConversationId(conversationId);
|
||||
message.setSenderId(userId);
|
||||
message.setContent(request.getContent());
|
||||
message.setAttachmentUrl(request.getAttachmentUrl());
|
||||
message.setAttachmentName(request.getAttachmentName());
|
||||
message.setAttachmentMimeType(request.getAttachmentMimeType());
|
||||
message.setAttachmentSizeBytes(request.getAttachmentSizeBytes());
|
||||
message.setIsRead(false);
|
||||
message = messageRepository.save(message);
|
||||
|
||||
@@ -168,7 +164,8 @@ public class ChatService {
|
||||
conversationRepository.save(conversation);
|
||||
|
||||
List<Message> messages = messageRepository.findByConversationIdOrderByTimestampAsc(conversationId);
|
||||
String lastMessage = messages.isEmpty() ? "" : messages.get(messages.size() - 1).getContent();
|
||||
Message last = messages.isEmpty() ? null : messages.get(messages.size() - 1);
|
||||
String lastMessage = last != null && last.getContent() != null ? last.getContent() : "";
|
||||
return ConversationResponse.fromEntity(conversation, lastMessage);
|
||||
}
|
||||
|
||||
@@ -190,7 +187,8 @@ public class ChatService {
|
||||
conversation = conversationRepository.save(conversation);
|
||||
|
||||
List<Message> messages = messageRepository.findByConversationIdOrderByTimestampAsc(conversationId);
|
||||
String lastMessage = messages.isEmpty() ? "" : messages.get(messages.size() - 1).getContent();
|
||||
Message last = messages.isEmpty() ? null : messages.get(messages.size() - 1);
|
||||
String lastMessage = last != null && last.getContent() != null ? last.getContent() : "";
|
||||
return ConversationResponse.fromEntity(conversation, lastMessage);
|
||||
}
|
||||
|
||||
@@ -225,9 +223,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) {
|
||||
|
||||
@@ -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<CustomerPetResponse> 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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<CustomerResponse> getAllCustomers(String query, Pageable pageable) {
|
||||
Page<Customer> 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");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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<EmployeeResponse> getAllEmployees(String query, Pageable pageable) {
|
||||
Page<Employee> 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;
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,11 @@ import com.petshop.backend.dto.inventory.InventoryRequest;
|
||||
import com.petshop.backend.dto.inventory.InventoryResponse;
|
||||
import com.petshop.backend.entity.Inventory;
|
||||
import com.petshop.backend.entity.Product;
|
||||
import com.petshop.backend.entity.StoreLocation;
|
||||
import com.petshop.backend.exception.ResourceNotFoundException;
|
||||
import com.petshop.backend.repository.InventoryRepository;
|
||||
import com.petshop.backend.repository.ProductRepository;
|
||||
import com.petshop.backend.repository.StoreRepository;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -18,10 +20,12 @@ public class InventoryService {
|
||||
|
||||
private final InventoryRepository inventoryRepository;
|
||||
private final ProductRepository productRepository;
|
||||
private final StoreRepository storeRepository;
|
||||
|
||||
public InventoryService(InventoryRepository inventoryRepository, ProductRepository productRepository) {
|
||||
public InventoryService(InventoryRepository inventoryRepository, ProductRepository productRepository, StoreRepository storeRepository) {
|
||||
this.inventoryRepository = inventoryRepository;
|
||||
this.productRepository = productRepository;
|
||||
this.storeRepository = storeRepository;
|
||||
}
|
||||
|
||||
public Page<InventoryResponse> getAllInventory(String query, Pageable pageable) {
|
||||
@@ -45,8 +49,14 @@ public class InventoryService {
|
||||
Product product = productRepository.findById(request.getProdId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Product not found with id: " + request.getProdId()));
|
||||
|
||||
StoreLocation store = request.getStoreId() != null
|
||||
? storeRepository.findById(request.getStoreId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getStoreId()))
|
||||
: null;
|
||||
|
||||
Inventory inventory = new Inventory();
|
||||
inventory.setProduct(product);
|
||||
inventory.setStore(store);
|
||||
inventory.setQuantity(request.getQuantity());
|
||||
|
||||
inventory = inventoryRepository.save(inventory);
|
||||
@@ -61,7 +71,13 @@ public class InventoryService {
|
||||
Product product = productRepository.findById(request.getProdId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Product not found with id: " + request.getProdId()));
|
||||
|
||||
StoreLocation store = request.getStoreId() != null
|
||||
? storeRepository.findById(request.getStoreId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getStoreId()))
|
||||
: null;
|
||||
|
||||
inventory.setProduct(product);
|
||||
inventory.setStore(store);
|
||||
inventory.setQuantity(request.getQuantity());
|
||||
|
||||
inventory = inventoryRepository.save(inventory);
|
||||
@@ -82,11 +98,14 @@ public class InventoryService {
|
||||
}
|
||||
|
||||
private InventoryResponse mapToResponse(Inventory inventory) {
|
||||
StoreLocation store = inventory.getStore();
|
||||
return new InventoryResponse(
|
||||
inventory.getInventoryId(),
|
||||
inventory.getProduct().getProdId(),
|
||||
inventory.getProduct().getProdName(),
|
||||
inventory.getProduct().getCategory().getCategoryName(),
|
||||
store != null ? store.getStoreId() : null,
|
||||
store != null ? store.getStoreName() : null,
|
||||
inventory.getQuantity(),
|
||||
inventory.getCreatedAt(),
|
||||
inventory.getUpdatedAt()
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.petshop.backend.service;
|
||||
|
||||
import com.petshop.backend.dto.purchaseorder.PurchaseOrderResponse;
|
||||
import com.petshop.backend.entity.PurchaseOrder;
|
||||
import com.petshop.backend.entity.StoreLocation;
|
||||
import com.petshop.backend.exception.ResourceNotFoundException;
|
||||
import com.petshop.backend.repository.PurchaseOrderRepository;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -34,10 +35,13 @@ public class PurchaseOrderService {
|
||||
}
|
||||
|
||||
private PurchaseOrderResponse mapToResponse(PurchaseOrder purchaseOrder) {
|
||||
StoreLocation store = purchaseOrder.getStore();
|
||||
return new PurchaseOrderResponse(
|
||||
purchaseOrder.getPurchaseOrderId(),
|
||||
purchaseOrder.getSupplier().getSupId(),
|
||||
purchaseOrder.getSupplier().getSupCompany(),
|
||||
store != null ? store.getStoreId() : null,
|
||||
store != null ? store.getStoreName() : null,
|
||||
purchaseOrder.getOrderDate(),
|
||||
purchaseOrder.getStatus(),
|
||||
purchaseOrder.getCreatedAt(),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -81,6 +81,7 @@ public class RefundService {
|
||||
return toResponse(savedRefund);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public RefundResponse getRefundById(Long id, Long customerId) {
|
||||
Refund refund = refundRepository.findById(id)
|
||||
.orElseThrow(() -> new RuntimeException("Refund not found"));
|
||||
@@ -92,6 +93,7 @@ public class RefundService {
|
||||
return toResponse(refund);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<RefundResponse> getAllRefunds(Long customerId) {
|
||||
List<Refund> refunds;
|
||||
|
||||
|
||||
@@ -24,20 +24,18 @@ 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;
|
||||
private final CouponRepository couponRepository;
|
||||
private final CartRepository cartRepository;
|
||||
|
||||
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, CouponRepository couponRepository, CartRepository cartRepository) {
|
||||
this.saleRepository = saleRepository;
|
||||
this.productRepository = productRepository;
|
||||
this.storeRepository = storeRepository;
|
||||
this.inventoryRepository = inventoryRepository;
|
||||
this.employeeRepository = employeeRepository;
|
||||
this.employeeStoreRepository = employeeStoreRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.customerRepository = customerRepository;
|
||||
this.couponRepository = couponRepository;
|
||||
this.cartRepository = cartRepository;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@@ -60,18 +58,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();
|
||||
@@ -80,9 +76,22 @@ public class SaleService {
|
||||
sale.setStore(store);
|
||||
sale.setPaymentMethod(normalizePaymentMethod(request.getPaymentMethod()));
|
||||
sale.setIsRefund(request.getIsRefund() != null ? request.getIsRefund() : false);
|
||||
sale.setChannel(request.getChannel() != null ? request.getChannel() : "IN_STORE");
|
||||
|
||||
if (request.getCouponId() != null) {
|
||||
Coupon coupon = couponRepository.findById(request.getCouponId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Coupon not found with id: " + request.getCouponId()));
|
||||
sale.setCoupon(coupon);
|
||||
}
|
||||
|
||||
if (request.getCartId() != null) {
|
||||
Cart cart = cartRepository.findById(request.getCartId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Cart not found with id: " + request.getCartId()));
|
||||
sale.setCart(cart);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -125,8 +134,8 @@ public class SaleService {
|
||||
" for product: " + product.getProdName());
|
||||
}
|
||||
|
||||
Inventory inventory = inventoryRepository.findByProductId(itemRequest.getProdId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Inventory not found for product " + itemRequest.getProdId()));
|
||||
Inventory inventory = inventoryRepository.findByProductIdAndStoreId(itemRequest.getProdId(), store.getStoreId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Inventory not found for product " + itemRequest.getProdId() + " at store " + store.getStoreId()));
|
||||
|
||||
inventory.setQuantity(inventory.getQuantity() + itemRequest.getQuantity());
|
||||
inventoryRepository.save(inventory);
|
||||
@@ -149,8 +158,8 @@ public class SaleService {
|
||||
Product product = productRepository.findById(itemRequest.getProdId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Product not found with id: " + itemRequest.getProdId()));
|
||||
|
||||
Inventory inventory = inventoryRepository.findByProductId(itemRequest.getProdId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Inventory not found for product " + itemRequest.getProdId()));
|
||||
Inventory inventory = inventoryRepository.findByProductIdAndStoreId(itemRequest.getProdId(), store.getStoreId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Inventory not found for product " + itemRequest.getProdId() + " at store " + store.getStoreId()));
|
||||
|
||||
if (inventory.getQuantity() < itemRequest.getQuantity()) {
|
||||
throw new BusinessException("Insufficient stock for product: " + product.getProdName() +
|
||||
@@ -185,7 +194,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) {
|
||||
@@ -194,6 +203,17 @@ public class SaleService {
|
||||
}
|
||||
|
||||
response.setTotalAmount(sale.getTotalAmount());
|
||||
response.setSubtotalAmount(sale.getSubtotalAmount());
|
||||
response.setCouponDiscountAmount(sale.getCouponDiscountAmount());
|
||||
response.setEmployeeDiscountAmount(sale.getEmployeeDiscountAmount());
|
||||
response.setPointsEarned(sale.getPointsEarned());
|
||||
response.setChannel(sale.getChannel());
|
||||
if (sale.getCoupon() != null) {
|
||||
response.setCouponId(sale.getCoupon().getCouponId());
|
||||
}
|
||||
if (sale.getCart() != null) {
|
||||
response.setCartId(sale.getCart().getCartId());
|
||||
}
|
||||
response.setPaymentMethod(sale.getPaymentMethod());
|
||||
response.setIsRefund(sale.getIsRefund());
|
||||
if (sale.getOriginalSale() != null) {
|
||||
|
||||
@@ -19,6 +19,7 @@ public class ServiceService {
|
||||
this.serviceRepository = serviceRepository;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<ServiceResponse> getAllServices(String query, Pageable pageable) {
|
||||
Page<com.petshop.backend.entity.Service> services;
|
||||
if (query != null && !query.trim().isEmpty()) {
|
||||
@@ -29,6 +30,7 @@ public class ServiceService {
|
||||
return services.map(this::mapToResponse);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public ServiceResponse getServiceById(Long id) {
|
||||
com.petshop.backend.entity.Service service = serviceRepository.findById(id)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Service not found with id: " + id));
|
||||
@@ -42,6 +44,9 @@ public class ServiceService {
|
||||
service.setServiceDesc(request.getServiceDesc());
|
||||
service.setServicePrice(request.getServicePrice());
|
||||
service.setServiceDuration(request.getServiceDuration());
|
||||
if (request.getSpecies() != null) {
|
||||
service.setSpecies(request.getSpecies());
|
||||
}
|
||||
|
||||
service = serviceRepository.save(service);
|
||||
return mapToResponse(service);
|
||||
@@ -56,6 +61,9 @@ public class ServiceService {
|
||||
service.setServiceDesc(request.getServiceDesc());
|
||||
service.setServicePrice(request.getServicePrice());
|
||||
service.setServiceDuration(request.getServiceDuration());
|
||||
if (request.getSpecies() != null) {
|
||||
service.setSpecies(request.getSpecies());
|
||||
}
|
||||
|
||||
service = serviceRepository.save(service);
|
||||
return mapToResponse(service);
|
||||
@@ -81,6 +89,7 @@ public class ServiceService {
|
||||
service.getServiceDesc(),
|
||||
service.getServicePrice(),
|
||||
service.getServiceDuration(),
|
||||
service.getSpecies(),
|
||||
service.getCreatedAt(),
|
||||
service.getUpdatedAt()
|
||||
);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ public class StoreService {
|
||||
store.setAddress(request.getAddress());
|
||||
store.setPhone(request.getPhone());
|
||||
store.setEmail(request.getEmail());
|
||||
store.setImageUrl(request.getImageUrl());
|
||||
|
||||
store = storeRepository.save(store);
|
||||
return mapToResponse(store);
|
||||
@@ -57,6 +58,7 @@ public class StoreService {
|
||||
store.setAddress(request.getAddress());
|
||||
store.setPhone(request.getPhone());
|
||||
store.setEmail(request.getEmail());
|
||||
store.setImageUrl(request.getImageUrl());
|
||||
|
||||
store = storeRepository.save(store);
|
||||
return mapToResponse(store);
|
||||
@@ -82,6 +84,7 @@ public class StoreService {
|
||||
store.getAddress(),
|
||||
store.getPhone(),
|
||||
store.getEmail(),
|
||||
store.getImageUrl(),
|
||||
store.getCreatedAt()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<Employee> 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<Customer> 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};
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,10 @@ package com.petshop.backend.service;
|
||||
import com.petshop.backend.dto.common.BulkDeleteRequest;
|
||||
import com.petshop.backend.dto.user.UserRequest;
|
||||
import com.petshop.backend.dto.user.UserResponse;
|
||||
import com.petshop.backend.entity.StoreLocation;
|
||||
import com.petshop.backend.entity.User;
|
||||
import com.petshop.backend.exception.ResourceNotFoundException;
|
||||
import com.petshop.backend.repository.StoreRepository;
|
||||
import com.petshop.backend.repository.UserRepository;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
@@ -14,6 +16,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||
import static org.springframework.http.HttpStatus.CONFLICT;
|
||||
@@ -23,12 +26,12 @@ 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) {
|
||||
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, StoreRepository storeRepository) {
|
||||
this.userRepository = userRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.userBusinessLinkageService = userBusinessLinkageService;
|
||||
this.storeRepository = storeRepository;
|
||||
}
|
||||
|
||||
public Page<UserResponse> getAllUsers(String query, String role, Pageable pageable) {
|
||||
@@ -56,20 +59,24 @@ public class UserService {
|
||||
@Transactional
|
||||
public UserResponse createUser(UserRequest request) {
|
||||
User user = new User();
|
||||
user.setUsername(request.getUsername());
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
user.setUsername(trimToNull(request.getUsername()));
|
||||
if (request.getPassword() != null && !request.getPassword().trim().isEmpty()) {
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
}
|
||||
user.setFirstName(request.getFirstName());
|
||||
user.setLastName(request.getLastName());
|
||||
user.setFullName(request.getFullName());
|
||||
user.setEmail(request.getEmail());
|
||||
user.setPhone(trimToNull(request.getPhone()));
|
||||
user.setRole(request.getRole());
|
||||
user.setStaffRole(trimToNull(request.getStaffRole()));
|
||||
user.setPrimaryStore(resolveStore(request.getPrimaryStoreId()));
|
||||
user.setActive(request.getActive() != null ? request.getActive() : true);
|
||||
|
||||
validateUniquePhone(user.getPhone(), null);
|
||||
|
||||
user = userRepository.save(user);
|
||||
|
||||
userBusinessLinkageService.syncLinkedRecords(user);
|
||||
|
||||
return mapToResponse(user);
|
||||
}
|
||||
|
||||
@@ -79,30 +86,33 @@ public class UserService {
|
||||
.orElseThrow(() -> new ResourceNotFoundException("User not found with id: " + id));
|
||||
|
||||
boolean invalidateToken =
|
||||
!user.getUsername().equals(request.getUsername())
|
||||
!Objects.equals(user.getUsername(), request.getUsername())
|
||||
|| user.getRole() != request.getRole()
|
||||
|| !user.getActive().equals(request.getActive() != null ? request.getActive() : true);
|
||||
|
||||
user.setUsername(request.getUsername());
|
||||
user.setUsername(trimToNull(request.getUsername()));
|
||||
if (request.getPassword() != null && !request.getPassword().trim().isEmpty()) {
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
invalidateToken = true;
|
||||
}
|
||||
user.setFirstName(request.getFirstName());
|
||||
user.setLastName(request.getLastName());
|
||||
user.setFullName(request.getFullName());
|
||||
user.setEmail(request.getEmail());
|
||||
String phone = trimToNull(request.getPhone());
|
||||
if (!java.util.Objects.equals(user.getPhone(), phone)) {
|
||||
if (!Objects.equals(user.getPhone(), phone)) {
|
||||
validateUniquePhone(phone, user.getId());
|
||||
}
|
||||
user.setPhone(phone);
|
||||
user.setRole(request.getRole());
|
||||
user.setStaffRole(trimToNull(request.getStaffRole()));
|
||||
user.setPrimaryStore(resolveStore(request.getPrimaryStoreId()));
|
||||
user.setActive(request.getActive() != null ? request.getActive() : true);
|
||||
if (invalidateToken) {
|
||||
user.setTokenVersion(user.getTokenVersion() + 1);
|
||||
}
|
||||
|
||||
user = userRepository.save(user);
|
||||
userBusinessLinkageService.syncLinkedRecords(user);
|
||||
return mapToResponse(user);
|
||||
}
|
||||
|
||||
@@ -123,16 +133,27 @@ public class UserService {
|
||||
UserResponse response = new UserResponse();
|
||||
response.setId(user.getId());
|
||||
response.setUsername(user.getUsername());
|
||||
response.setFirstName(user.getFirstName());
|
||||
response.setLastName(user.getLastName());
|
||||
response.setFullName(user.getFullName());
|
||||
response.setEmail(user.getEmail());
|
||||
response.setPhone(user.getPhone());
|
||||
response.setRole(user.getRole().toString());
|
||||
response.setStaffRole(user.getStaffRole());
|
||||
response.setPrimaryStoreId(user.getPrimaryStore() != null ? user.getPrimaryStore().getStoreId() : null);
|
||||
response.setLoyaltyPoints(user.getLoyaltyPoints());
|
||||
response.setActive(user.getActive());
|
||||
response.setCreatedAt(user.getCreatedAt());
|
||||
response.setUpdatedAt(user.getUpdatedAt());
|
||||
return response;
|
||||
}
|
||||
|
||||
private StoreLocation resolveStore(Long storeId) {
|
||||
if (storeId == null) return null;
|
||||
return storeRepository.findById(storeId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + storeId));
|
||||
}
|
||||
|
||||
private void validateUniquePhone(String phone, Long currentUserId) {
|
||||
if (phone == null || phone.isBlank()) {
|
||||
return;
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ spring:
|
||||
flyway:
|
||||
enabled: true
|
||||
baseline-on-migrate: true
|
||||
baseline-version: 0
|
||||
baseline-version: 1
|
||||
|
||||
server:
|
||||
port: ${SERVER_PORT:8080}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
INSERT INTO service (serviceName, serviceDesc, serviceDuration, servicePrice)
|
||||
VALUES ('Pet Adoption', 'Schedule a visit to meet and adopt an available pet', 30, 0.00);
|
||||
@@ -1,7 +0,0 @@
|
||||
CREATE TABLE IF NOT EXISTS appointment_customer_pet (
|
||||
appointment_id BIGINT NOT NULL,
|
||||
customer_pet_id BIGINT NOT NULL,
|
||||
PRIMARY KEY (appointment_id, customer_pet_id),
|
||||
FOREIGN KEY (appointment_id) REFERENCES appointment(appointmentId),
|
||||
FOREIGN KEY (customer_pet_id) REFERENCES customer_pet(customer_pet_id)
|
||||
);
|
||||
@@ -1,91 +0,0 @@
|
||||
INSERT INTO users (username, password, email, fullName, phone, role, active, tokenVersion)
|
||||
SELECT
|
||||
CONCAT('customer_', c.customerId) AS username,
|
||||
'$2a$10$mE0D/HrnCuqFeEqMy0NJwuy2jkoRYjQ7GrKcc/7QQ0r2AqnZTvyGq' AS password,
|
||||
CASE
|
||||
WHEN c.email IS NOT NULL
|
||||
AND c.email <> ''
|
||||
AND (SELECT COUNT(*) FROM customer c2 WHERE c2.email = c.email) = 1
|
||||
AND NOT EXISTS (SELECT 1 FROM employee e2 WHERE e2.email = c.email)
|
||||
AND NOT EXISTS (SELECT 1 FROM users u WHERE u.email = c.email)
|
||||
THEN c.email
|
||||
ELSE CONCAT('customer_', c.customerId, '@petshop.local')
|
||||
END AS email,
|
||||
CONCAT(c.firstName, ' ', c.lastName) AS fullName,
|
||||
CONCAT('200-000-', LPAD(c.customerId, 4, '0')) AS phone,
|
||||
'CUSTOMER' AS role,
|
||||
FALSE AS active,
|
||||
0 AS tokenVersion
|
||||
FROM customer c
|
||||
WHERE c.user_id IS NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM users u
|
||||
WHERE u.username = CONCAT('customer_', c.customerId)
|
||||
);
|
||||
|
||||
INSERT INTO users (username, password, email, fullName, phone, role, active, tokenVersion)
|
||||
SELECT
|
||||
CONCAT('employee_', e.employeeId) AS username,
|
||||
'$2a$10$mE0D/HrnCuqFeEqMy0NJwuy2jkoRYjQ7GrKcc/7QQ0r2AqnZTvyGq' AS password,
|
||||
CASE
|
||||
WHEN e.email IS NOT NULL
|
||||
AND e.email <> ''
|
||||
AND (SELECT COUNT(*) FROM employee e2 WHERE e2.email = e.email) = 1
|
||||
AND NOT EXISTS (SELECT 1 FROM customer c2 WHERE c2.email = e.email)
|
||||
AND NOT EXISTS (SELECT 1 FROM users u WHERE u.email = e.email)
|
||||
THEN e.email
|
||||
ELSE CONCAT('employee_', e.employeeId, '@petshop.local')
|
||||
END AS email,
|
||||
CONCAT(e.firstName, ' ', e.lastName) AS fullName,
|
||||
CONCAT('300-000-', LPAD(e.employeeId, 4, '0')) AS phone,
|
||||
CASE
|
||||
WHEN UPPER(e.role) = 'MANAGER' THEN 'ADMIN'
|
||||
ELSE 'STAFF'
|
||||
END AS role,
|
||||
FALSE AS active,
|
||||
0 AS tokenVersion
|
||||
FROM employee e
|
||||
WHERE e.user_id IS NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM users u
|
||||
WHERE u.username = CONCAT('employee_', e.employeeId)
|
||||
);
|
||||
|
||||
UPDATE customer c
|
||||
JOIN users u ON u.username = CONCAT('customer_', c.customerId)
|
||||
AND u.role = 'CUSTOMER'
|
||||
SET c.user_id = u.id
|
||||
WHERE c.user_id IS NULL;
|
||||
|
||||
UPDATE employee e
|
||||
JOIN users u ON u.username = CONCAT('employee_', e.employeeId)
|
||||
AND u.role IN ('STAFF', 'ADMIN')
|
||||
SET e.user_id = u.id
|
||||
WHERE e.user_id IS NULL;
|
||||
|
||||
UPDATE users
|
||||
SET
|
||||
fullName = CASE
|
||||
WHEN fullName IS NULL OR fullName = '' THEN username
|
||||
ELSE fullName
|
||||
END,
|
||||
email = CASE
|
||||
WHEN email IS NULL OR email = '' THEN CONCAT(username, '@petshop.local')
|
||||
ELSE email
|
||||
END,
|
||||
phone = CASE
|
||||
WHEN phone IS NULL OR phone = '' THEN CONCAT('000-000-', LPAD(id, 4, '0'))
|
||||
ELSE phone
|
||||
END,
|
||||
active = COALESCE(active, TRUE),
|
||||
tokenVersion = COALESCE(tokenVersion, 0)
|
||||
WHERE fullName IS NULL
|
||||
OR fullName = ''
|
||||
OR email IS NULL
|
||||
OR email = ''
|
||||
OR phone IS NULL
|
||||
OR phone = ''
|
||||
OR active IS NULL
|
||||
OR tokenVersion IS NULL;
|
||||
@@ -1,3 +0,0 @@
|
||||
UPDATE sale
|
||||
SET paymentMethod = 'Card'
|
||||
WHERE LOWER(paymentMethod) = 'debit';
|
||||
@@ -1,33 +0,0 @@
|
||||
-- Consolidated Updates: Phone Normalization and Refund Items
|
||||
|
||||
-- 1. Create refund_item table
|
||||
CREATE TABLE IF NOT EXISTS refund_item (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
refund_id BIGINT NOT NULL,
|
||||
prod_id BIGINT NOT NULL,
|
||||
quantity INT NOT NULL,
|
||||
unit_price DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (refund_id) REFERENCES refund(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (prod_id) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
-- 2. Normalize existing phone numbers (MySQL Set-based)
|
||||
UPDATE users
|
||||
SET phone = CONCAT('(', SUBSTRING(REGEXP_REPLACE(phone, '[^0-9]', ''), -10, 3), ') ',
|
||||
SUBSTRING(REGEXP_REPLACE(phone, '[^0-9]', ''), -7, 3), '-',
|
||||
SUBSTRING(REGEXP_REPLACE(phone, '[^0-9]', ''), -4))
|
||||
WHERE phone REGEXP '[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9]';
|
||||
|
||||
UPDATE supplier
|
||||
SET supPhone = CONCAT('(', SUBSTRING(REGEXP_REPLACE(supPhone, '[^0-9]', ''), -10, 3), ') ',
|
||||
SUBSTRING(REGEXP_REPLACE(supPhone, '[^0-9]', ''), -7, 3), '-',
|
||||
SUBSTRING(REGEXP_REPLACE(supPhone, '[^0-9]', ''), -4))
|
||||
WHERE supPhone REGEXP '[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9]';
|
||||
|
||||
UPDATE storeLocation
|
||||
SET phone = CONCAT('(', SUBSTRING(REGEXP_REPLACE(phone, '[^0-9]', ''), -10, 3), ') ',
|
||||
SUBSTRING(REGEXP_REPLACE(phone, '[^0-9]', ''), -7, 3), '-',
|
||||
SUBSTRING(REGEXP_REPLACE(phone, '[^0-9]', ''), -4))
|
||||
WHERE phone REGEXP '[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9].*[0-9]';
|
||||
@@ -1,61 +0,0 @@
|
||||
ALTER TABLE appointment
|
||||
ADD COLUMN employeeId BIGINT NULL;
|
||||
|
||||
UPDATE appointment a
|
||||
SET a.employeeId = (
|
||||
SELECT es.employeeId
|
||||
FROM employeeStore es
|
||||
JOIN employee e ON e.employeeId = es.employeeId
|
||||
JOIN users u ON u.id = e.user_id
|
||||
WHERE es.storeId = a.storeId
|
||||
AND e.isActive = TRUE
|
||||
AND u.role = 'STAFF'
|
||||
ORDER BY es.employeeId ASC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE a.employeeId IS NULL;
|
||||
|
||||
UPDATE appointment a
|
||||
SET a.employeeId = (
|
||||
SELECT e.employeeId
|
||||
FROM employee e
|
||||
JOIN users u ON u.id = e.user_id
|
||||
WHERE e.isActive = TRUE
|
||||
AND u.role = 'STAFF'
|
||||
ORDER BY e.employeeId ASC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE a.employeeId IS NULL;
|
||||
|
||||
ALTER TABLE appointment
|
||||
ADD CONSTRAINT fk_appointment_employee
|
||||
FOREIGN KEY (employeeId) REFERENCES employee(employeeId);
|
||||
|
||||
CREATE INDEX idx_appointment_employeeId ON appointment(employeeId);
|
||||
|
||||
ALTER TABLE appointment
|
||||
MODIFY employeeId BIGINT NOT NULL;
|
||||
|
||||
ALTER TABLE adoption
|
||||
ADD COLUMN employeeId BIGINT NULL;
|
||||
|
||||
UPDATE adoption a
|
||||
SET a.employeeId = (
|
||||
SELECT e.employeeId
|
||||
FROM employee e
|
||||
JOIN users u ON u.id = e.user_id
|
||||
WHERE e.isActive = TRUE
|
||||
AND u.role = 'STAFF'
|
||||
ORDER BY e.employeeId ASC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE a.employeeId IS NULL;
|
||||
|
||||
ALTER TABLE adoption
|
||||
ADD CONSTRAINT fk_adoption_employee
|
||||
FOREIGN KEY (employeeId) REFERENCES employee(employeeId);
|
||||
|
||||
CREATE INDEX idx_adoption_employeeId ON adoption(employeeId);
|
||||
|
||||
ALTER TABLE adoption
|
||||
MODIFY employeeId BIGINT NOT NULL;
|
||||
@@ -1,4 +0,0 @@
|
||||
UPDATE users u
|
||||
SET u.active = TRUE
|
||||
WHERE u.role IN ('STAFF', 'ADMIN')
|
||||
AND EXISTS (SELECT 1 FROM employee e WHERE e.user_id = u.id);
|
||||
@@ -1,22 +0,0 @@
|
||||
INSERT INTO customer_pet (customer_id, pet_name, species, breed)
|
||||
SELECT DISTINCT a.customerId, p.petName, p.petSpecies, p.petBreed
|
||||
FROM appointmentPet ap
|
||||
JOIN appointment a ON a.appointmentId = ap.appointmentId
|
||||
JOIN pet p ON p.petId = ap.petId
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM customer_pet cp
|
||||
WHERE cp.customer_id = a.customerId AND cp.pet_name = p.petName
|
||||
);
|
||||
|
||||
INSERT INTO appointment_customer_pet (appointment_id, customer_pet_id)
|
||||
SELECT ap.appointmentId, cp.customer_pet_id
|
||||
FROM appointmentPet ap
|
||||
JOIN appointment a ON a.appointmentId = ap.appointmentId
|
||||
JOIN pet p ON p.petId = ap.petId
|
||||
JOIN customer_pet cp ON cp.customer_id = a.customerId AND cp.pet_name = p.petName
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM appointment_customer_pet acp
|
||||
WHERE acp.appointment_id = ap.appointmentId AND acp.customer_pet_id = cp.customer_pet_id
|
||||
);
|
||||
|
||||
DELETE FROM appointmentPet;
|
||||
@@ -1,40 +0,0 @@
|
||||
UPDATE appointment
|
||||
SET appointmentStatus = 'Missed'
|
||||
WHERE LOWER(appointmentStatus) = 'booked'
|
||||
AND (
|
||||
appointmentDate < CURRENT_DATE
|
||||
OR (appointmentDate = CURRENT_DATE AND appointmentTime < CURRENT_TIME)
|
||||
);
|
||||
|
||||
UPDATE appointment a1
|
||||
JOIN (
|
||||
SELECT a3.appointmentId
|
||||
FROM appointment a3
|
||||
INNER JOIN appointment a4
|
||||
ON a4.employeeId = a3.employeeId
|
||||
AND a4.appointmentDate = a3.appointmentDate
|
||||
AND a4.appointmentTime = a3.appointmentTime
|
||||
AND a4.appointmentId < a3.appointmentId
|
||||
WHERE LOWER(a3.appointmentStatus) NOT IN ('cancelled', 'missed')
|
||||
) conflicting ON conflicting.appointmentId = a1.appointmentId
|
||||
SET a1.employeeId = (
|
||||
SELECT es.employeeId
|
||||
FROM employeeStore es
|
||||
JOIN employee e ON e.employeeId = es.employeeId
|
||||
JOIN users u ON u.id = e.user_id
|
||||
WHERE es.storeId = a1.storeId
|
||||
AND e.isActive = TRUE
|
||||
AND u.role = 'STAFF'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM (
|
||||
SELECT employeeId, appointmentDate, appointmentTime, appointmentId
|
||||
FROM appointment
|
||||
) snap
|
||||
WHERE snap.employeeId = es.employeeId
|
||||
AND snap.appointmentDate = a1.appointmentDate
|
||||
AND snap.appointmentTime = a1.appointmentTime
|
||||
AND snap.appointmentId <> a1.appointmentId
|
||||
)
|
||||
ORDER BY es.employeeId ASC
|
||||
LIMIT 1
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
ALTER TABLE pet ADD COLUMN customerId BIGINT NULL;
|
||||
ALTER TABLE pet ADD COLUMN storeId BIGINT NULL;
|
||||
|
||||
ALTER TABLE pet ADD CONSTRAINT fk_pet_customer
|
||||
FOREIGN KEY (customerId) REFERENCES customer(customerId);
|
||||
ALTER TABLE pet ADD CONSTRAINT fk_pet_store
|
||||
FOREIGN KEY (storeId) REFERENCES storeLocation(storeId);
|
||||
|
||||
CREATE INDEX idx_pet_customerId ON pet(customerId);
|
||||
CREATE INDEX idx_pet_storeId ON pet(storeId);
|
||||
|
||||
UPDATE pet
|
||||
SET storeId = (SELECT storeId FROM storeLocation ORDER BY storeId ASC LIMIT 1)
|
||||
WHERE LOWER(petStatus) IN ('available', 'unadopted');
|
||||
|
||||
UPDATE pet p
|
||||
JOIN (
|
||||
SELECT a.petId, a.customerId
|
||||
FROM adoption a
|
||||
WHERE LOWER(a.adoptionStatus) = 'completed'
|
||||
) latest ON latest.petId = p.petId
|
||||
SET p.customerId = latest.customerId
|
||||
WHERE LOWER(p.petStatus) = 'adopted';
|
||||
@@ -1,250 +0,0 @@
|
||||
-- Create Tables
|
||||
|
||||
CREATE TABLE IF NOT EXISTS storeLocation (
|
||||
storeId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
storeName VARCHAR(100) NOT NULL,
|
||||
address VARCHAR(255) NOT NULL,
|
||||
phone VARCHAR(20) NOT NULL,
|
||||
email VARCHAR(100) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS employee (
|
||||
employeeId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT NULL,
|
||||
firstName VARCHAR(50) NOT NULL,
|
||||
lastName VARCHAR(50) NOT NULL,
|
||||
email VARCHAR(100) NOT NULL,
|
||||
phone VARCHAR(20) NOT NULL,
|
||||
role VARCHAR(50) NOT NULL,
|
||||
isActive BOOLEAN DEFAULT TRUE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT uk_employee_user_id UNIQUE (user_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS employeeStore (
|
||||
employeeId BIGINT NOT NULL,
|
||||
storeId BIGINT NOT NULL,
|
||||
PRIMARY KEY (employeeId, storeId),
|
||||
FOREIGN KEY (employeeId) REFERENCES employee(employeeId),
|
||||
FOREIGN KEY (storeId) REFERENCES storeLocation(storeId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS customer (
|
||||
customerId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT NULL,
|
||||
firstName VARCHAR(50) NOT NULL,
|
||||
lastName VARCHAR(50) NOT NULL,
|
||||
email VARCHAR(100) NOT NULL,
|
||||
phone VARCHAR(20) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT uk_customer_user_id UNIQUE (user_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pet (
|
||||
petId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
petName VARCHAR(50) NOT NULL,
|
||||
petSpecies VARCHAR(50) NOT NULL,
|
||||
petBreed VARCHAR(50) NOT NULL,
|
||||
petAge INT NOT NULL,
|
||||
petStatus VARCHAR(20) NOT NULL,
|
||||
petPrice DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS adoption (
|
||||
adoptionId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
petId BIGINT NOT NULL,
|
||||
customerId BIGINT NOT NULL,
|
||||
adoptionDate DATE NOT NULL,
|
||||
adoptionStatus VARCHAR(20) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (petId) REFERENCES pet(petId),
|
||||
FOREIGN KEY (customerId) REFERENCES customer(customerId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS supplier (
|
||||
supId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
supCompany VARCHAR(100) NOT NULL,
|
||||
supContactFirstName VARCHAR(50) NOT NULL,
|
||||
supContactLastName VARCHAR(50) NOT NULL,
|
||||
supEmail VARCHAR(100) NOT NULL,
|
||||
supPhone VARCHAR(20) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS category (
|
||||
categoryId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
categoryName VARCHAR(100) NOT NULL,
|
||||
categoryType VARCHAR(50) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS product (
|
||||
prodId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
prodName VARCHAR(100) NOT NULL,
|
||||
prodPrice DECIMAL(10, 2) NOT NULL,
|
||||
categoryId BIGINT NOT NULL,
|
||||
prodDesc TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (categoryId) REFERENCES category(categoryId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS productSupplier (
|
||||
supId BIGINT NOT NULL,
|
||||
prodId BIGINT NOT NULL,
|
||||
cost DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (supId, prodId),
|
||||
FOREIGN KEY (supId) REFERENCES supplier(supId),
|
||||
FOREIGN KEY (prodId) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS inventory (
|
||||
inventoryId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
prodId BIGINT NOT NULL,
|
||||
quantity INT DEFAULT 0 NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (prodId) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS service (
|
||||
serviceId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
serviceName VARCHAR(100) NOT NULL,
|
||||
serviceDesc TEXT,
|
||||
serviceDuration INT NOT NULL,
|
||||
servicePrice DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS appointment (
|
||||
appointmentId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
serviceId BIGINT NOT NULL,
|
||||
customerId BIGINT NOT NULL,
|
||||
appointmentDate DATE NOT NULL,
|
||||
appointmentTime TIME NOT NULL,
|
||||
appointmentStatus VARCHAR(20) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (serviceId) REFERENCES service(serviceId),
|
||||
FOREIGN KEY (customerId) REFERENCES customer(customerId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS appointmentPet (
|
||||
appointmentId BIGINT NOT NULL,
|
||||
petId BIGINT NOT NULL,
|
||||
PRIMARY KEY (appointmentId, petId),
|
||||
FOREIGN KEY (appointmentId) REFERENCES appointment(appointmentId),
|
||||
FOREIGN KEY (petId) REFERENCES pet(petId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sale (
|
||||
saleId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
saleDate DATETIME NOT NULL,
|
||||
totalAmount DECIMAL(10, 2) NOT NULL,
|
||||
paymentMethod VARCHAR(50) NOT NULL,
|
||||
employeeId BIGINT NOT NULL,
|
||||
storeId BIGINT NOT NULL,
|
||||
customerId BIGINT NULL,
|
||||
isRefund BOOLEAN DEFAULT FALSE NOT NULL,
|
||||
originalSaleId BIGINT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (employeeId) REFERENCES employee(employeeId),
|
||||
FOREIGN KEY (storeId) REFERENCES storeLocation(storeId),
|
||||
FOREIGN KEY (customerId) REFERENCES customer(customerId),
|
||||
FOREIGN KEY (originalSaleId) REFERENCES sale(saleId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS saleItem (
|
||||
saleItemId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
saleId BIGINT NOT NULL,
|
||||
prodId BIGINT NOT NULL,
|
||||
quantity INT NOT NULL,
|
||||
unitPrice DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (saleId) REFERENCES sale(saleId),
|
||||
FOREIGN KEY (prodId) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS purchaseOrder (
|
||||
purchaseOrderId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
supId BIGINT NOT NULL,
|
||||
orderDate DATE NOT NULL,
|
||||
status VARCHAR(50) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (supId) REFERENCES supplier(supId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS activityLog (
|
||||
logId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
employeeId BIGINT NOT NULL,
|
||||
activity TEXT NOT NULL,
|
||||
logTimestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
FOREIGN KEY (employeeId) REFERENCES employee(employeeId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(50) UNIQUE NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(100) UNIQUE,
|
||||
fullName VARCHAR(100),
|
||||
avatarUrl VARCHAR(255),
|
||||
role VARCHAR(20) NOT NULL,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS refund (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
saleId BIGINT NOT NULL,
|
||||
customerId BIGINT NOT NULL,
|
||||
amount DECIMAL(10, 2) NOT NULL,
|
||||
reason VARCHAR(500) NOT NULL,
|
||||
status VARCHAR(20) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (saleId) REFERENCES sale(saleId),
|
||||
FOREIGN KEY (customerId) REFERENCES customer(customerId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS conversation (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
customerId BIGINT NOT NULL,
|
||||
staffId BIGINT,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'OPEN',
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (customerId) REFERENCES customer(customerId),
|
||||
FOREIGN KEY (staffId) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS message (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
conversationId BIGINT NOT NULL,
|
||||
senderId BIGINT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
isRead BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
FOREIGN KEY (conversationId) REFERENCES conversation(id),
|
||||
FOREIGN KEY (senderId) REFERENCES users(id)
|
||||
);
|
||||
|
||||
-- Add foreign keys for user_id linkage
|
||||
ALTER TABLE employee ADD CONSTRAINT fk_employee_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
|
||||
ALTER TABLE customer ADD CONSTRAINT fk_customer_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
|
||||
341
backend/src/main/resources/db/migration/V1__target_baseline.sql
Normal file
341
backend/src/main/resources/db/migration/V1__target_baseline.sql
Normal file
@@ -0,0 +1,341 @@
|
||||
|
||||
CREATE TABLE IF NOT EXISTS storeLocation (
|
||||
storeId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
storeName VARCHAR(100) NOT NULL,
|
||||
address VARCHAR(255) NOT NULL,
|
||||
phone VARCHAR(20) NOT NULL,
|
||||
email VARCHAR(100) NOT NULL,
|
||||
imageUrl VARCHAR(255) NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(50) NULL UNIQUE,
|
||||
password VARCHAR(255) NULL,
|
||||
email VARCHAR(100) NULL UNIQUE,
|
||||
firstName VARCHAR(50) NOT NULL,
|
||||
lastName VARCHAR(50) NOT NULL,
|
||||
fullName VARCHAR(100) NULL,
|
||||
phone VARCHAR(20) NULL,
|
||||
avatarUrl VARCHAR(255) NULL,
|
||||
role VARCHAR(20) NOT NULL,
|
||||
staffRole VARCHAR(50) NULL,
|
||||
primaryStoreId BIGINT NULL,
|
||||
loyaltyPoints INT NOT NULL DEFAULT 0,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
tokenVersion INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_users_primary_store FOREIGN KEY (primaryStoreId) REFERENCES storeLocation(storeId) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS supplier (
|
||||
supId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
supCompany VARCHAR(100) NOT NULL,
|
||||
supContactFirstName VARCHAR(50) NOT NULL,
|
||||
supContactLastName VARCHAR(50) NOT NULL,
|
||||
supEmail VARCHAR(100) NOT NULL,
|
||||
supPhone VARCHAR(20) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS category (
|
||||
categoryId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
categoryName VARCHAR(100) NOT NULL,
|
||||
categoryType VARCHAR(50) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT uq_category_name_type UNIQUE (categoryName, categoryType)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS service (
|
||||
serviceId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
serviceName VARCHAR(100) NOT NULL,
|
||||
serviceDesc TEXT NULL,
|
||||
serviceDuration INT NOT NULL,
|
||||
servicePrice DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS service_species (
|
||||
serviceId BIGINT NOT NULL,
|
||||
species VARCHAR(50) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (serviceId, species),
|
||||
CONSTRAINT fk_service_species_service FOREIGN KEY (serviceId) REFERENCES service(serviceId) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS product (
|
||||
prodId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
prodName VARCHAR(100) NOT NULL,
|
||||
prodPrice DECIMAL(10, 2) NOT NULL,
|
||||
categoryId BIGINT NOT NULL,
|
||||
prodDesc TEXT NULL,
|
||||
imageUrl VARCHAR(255) NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_product_category FOREIGN KEY (categoryId) REFERENCES category(categoryId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS inventory (
|
||||
inventoryId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
storeId BIGINT NOT NULL,
|
||||
prodId BIGINT NOT NULL,
|
||||
quantity INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT uq_inventory_store_product UNIQUE (storeId, prodId),
|
||||
CONSTRAINT fk_inventory_store FOREIGN KEY (storeId) REFERENCES storeLocation(storeId),
|
||||
CONSTRAINT fk_inventory_product FOREIGN KEY (prodId) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS productSupplier (
|
||||
supId BIGINT NOT NULL,
|
||||
prodId BIGINT NOT NULL,
|
||||
cost DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (supId, prodId),
|
||||
CONSTRAINT fk_product_supplier_supplier FOREIGN KEY (supId) REFERENCES supplier(supId),
|
||||
CONSTRAINT fk_product_supplier_product FOREIGN KEY (prodId) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS purchaseOrder (
|
||||
purchaseOrderId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
supId BIGINT NOT NULL,
|
||||
storeId BIGINT NOT NULL,
|
||||
orderDate DATE NOT NULL,
|
||||
status VARCHAR(50) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_purchase_order_supplier FOREIGN KEY (supId) REFERENCES supplier(supId),
|
||||
CONSTRAINT fk_purchase_order_store FOREIGN KEY (storeId) REFERENCES storeLocation(storeId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS coupon (
|
||||
couponId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
couponCode VARCHAR(50) NOT NULL,
|
||||
discountType VARCHAR(20) NOT NULL,
|
||||
discountValue DECIMAL(10, 2) NOT NULL,
|
||||
minOrderAmount DECIMAL(10, 2) NULL,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
startsAt DATETIME NULL,
|
||||
endsAt DATETIME NULL,
|
||||
usageLimit INT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT uq_coupon_code UNIQUE (couponCode)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pet (
|
||||
petId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
petName VARCHAR(50) NOT NULL,
|
||||
petSpecies VARCHAR(50) NOT NULL,
|
||||
petBreed VARCHAR(50) NULL,
|
||||
petAge INT NULL,
|
||||
petStatus VARCHAR(20) NOT NULL,
|
||||
petPrice DECIMAL(10, 2) NULL,
|
||||
imageUrl VARCHAR(255) NULL,
|
||||
ownerUserId BIGINT NULL,
|
||||
storeId BIGINT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_pet_owner_user FOREIGN KEY (ownerUserId) REFERENCES users(id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_pet_store FOREIGN KEY (storeId) REFERENCES storeLocation(storeId) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS appointment (
|
||||
appointmentId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
serviceId BIGINT NOT NULL,
|
||||
petId BIGINT NOT NULL,
|
||||
customerId BIGINT NOT NULL,
|
||||
storeId BIGINT NOT NULL,
|
||||
employeeId BIGINT NOT NULL,
|
||||
appointmentDate DATE NOT NULL,
|
||||
appointmentTime TIME NOT NULL,
|
||||
appointmentStatus VARCHAR(20) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_appointment_service FOREIGN KEY (serviceId) REFERENCES service(serviceId),
|
||||
CONSTRAINT fk_appointment_pet FOREIGN KEY (petId) REFERENCES pet(petId),
|
||||
CONSTRAINT fk_appointment_customer FOREIGN KEY (customerId) REFERENCES users(id),
|
||||
CONSTRAINT fk_appointment_store FOREIGN KEY (storeId) REFERENCES storeLocation(storeId),
|
||||
CONSTRAINT fk_appointment_employee FOREIGN KEY (employeeId) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS adoption (
|
||||
adoptionId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
petId BIGINT NOT NULL,
|
||||
customerId BIGINT NOT NULL,
|
||||
employeeId BIGINT NOT NULL,
|
||||
sourceStoreId BIGINT NOT NULL,
|
||||
adoptionDate DATE NOT NULL,
|
||||
adoptionStatus VARCHAR(20) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_adoption_pet FOREIGN KEY (petId) REFERENCES pet(petId),
|
||||
CONSTRAINT fk_adoption_customer FOREIGN KEY (customerId) REFERENCES users(id),
|
||||
CONSTRAINT fk_adoption_employee FOREIGN KEY (employeeId) REFERENCES users(id),
|
||||
CONSTRAINT fk_adoption_source_store FOREIGN KEY (sourceStoreId) REFERENCES storeLocation(storeId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cart (
|
||||
cartId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
userId BIGINT NOT NULL,
|
||||
storeId BIGINT NULL,
|
||||
couponId BIGINT NULL,
|
||||
cartStatus VARCHAR(20) NOT NULL DEFAULT 'ACTIVE',
|
||||
subtotalAmount DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
|
||||
discountAmount DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
|
||||
totalAmount DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_cart_user FOREIGN KEY (userId) REFERENCES users(id),
|
||||
CONSTRAINT fk_cart_store FOREIGN KEY (storeId) REFERENCES storeLocation(storeId) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_cart_coupon FOREIGN KEY (couponId) REFERENCES coupon(couponId) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cart_item (
|
||||
cartItemId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
cartId BIGINT NOT NULL,
|
||||
prodId BIGINT NOT NULL,
|
||||
quantity INT NOT NULL,
|
||||
unitPrice DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_cart_item_cart FOREIGN KEY (cartId) REFERENCES cart(cartId) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_cart_item_product FOREIGN KEY (prodId) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sale (
|
||||
saleId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
saleDate DATETIME NOT NULL,
|
||||
totalAmount DECIMAL(10, 2) NOT NULL,
|
||||
paymentMethod VARCHAR(50) NOT NULL,
|
||||
employeeId BIGINT NOT NULL,
|
||||
storeId BIGINT NOT NULL,
|
||||
customerId BIGINT NULL,
|
||||
isRefund BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
originalSaleId BIGINT NULL,
|
||||
channel VARCHAR(20) NOT NULL DEFAULT 'IN_STORE',
|
||||
cartId BIGINT NULL,
|
||||
couponId BIGINT NULL,
|
||||
subtotalAmount DECIMAL(10, 2) NULL,
|
||||
couponDiscountAmount DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
|
||||
employeeDiscountAmount DECIMAL(10, 2) NOT NULL DEFAULT 0.00,
|
||||
pointsEarned INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_sale_employee FOREIGN KEY (employeeId) REFERENCES users(id),
|
||||
CONSTRAINT fk_sale_store FOREIGN KEY (storeId) REFERENCES storeLocation(storeId),
|
||||
CONSTRAINT fk_sale_customer FOREIGN KEY (customerId) REFERENCES users(id) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_sale_original_sale FOREIGN KEY (originalSaleId) REFERENCES sale(saleId),
|
||||
CONSTRAINT fk_sale_cart FOREIGN KEY (cartId) REFERENCES cart(cartId) ON DELETE SET NULL,
|
||||
CONSTRAINT fk_sale_coupon FOREIGN KEY (couponId) REFERENCES coupon(couponId) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS saleItem (
|
||||
saleItemId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
saleId BIGINT NOT NULL,
|
||||
prodId BIGINT NOT NULL,
|
||||
quantity INT NOT NULL,
|
||||
unitPrice DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_sale_item_sale FOREIGN KEY (saleId) REFERENCES sale(saleId) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_sale_item_product FOREIGN KEY (prodId) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS refund (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
saleId BIGINT NOT NULL,
|
||||
customerId BIGINT NOT NULL,
|
||||
amount DECIMAL(10, 2) NOT NULL,
|
||||
reason VARCHAR(500) NOT NULL,
|
||||
status VARCHAR(20) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_refund_sale FOREIGN KEY (saleId) REFERENCES sale(saleId),
|
||||
CONSTRAINT fk_refund_customer FOREIGN KEY (customerId) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS refund_item (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
refund_id BIGINT NOT NULL,
|
||||
prod_id BIGINT NOT NULL,
|
||||
quantity INT NOT NULL,
|
||||
unit_price DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_refund_item_refund FOREIGN KEY (refund_id) REFERENCES refund(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_refund_item_product FOREIGN KEY (prod_id) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS conversation (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
customerId BIGINT NOT NULL,
|
||||
staffId BIGINT NULL,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'OPEN',
|
||||
mode VARCHAR(20) NOT NULL DEFAULT 'AUTOMATED',
|
||||
humanRequestedAt TIMESTAMP NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_conversation_customer FOREIGN KEY (customerId) REFERENCES users(id),
|
||||
CONSTRAINT fk_conversation_staff FOREIGN KEY (staffId) REFERENCES users(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS message (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
conversationId BIGINT NOT NULL,
|
||||
senderId BIGINT NOT NULL,
|
||||
content TEXT NULL,
|
||||
attachmentUrl VARCHAR(255) NULL,
|
||||
attachmentName VARCHAR(255) NULL,
|
||||
attachmentMimeType VARCHAR(100) NULL,
|
||||
attachmentSizeBytes BIGINT NULL,
|
||||
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
isRead BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
CONSTRAINT fk_message_conversation FOREIGN KEY (conversationId) REFERENCES conversation(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_message_sender FOREIGN KEY (senderId) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS activityLog (
|
||||
logId BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
userId BIGINT NOT NULL,
|
||||
storeId BIGINT NULL,
|
||||
activity TEXT NOT NULL,
|
||||
logTimestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_activity_log_user FOREIGN KEY (userId) REFERENCES users(id),
|
||||
CONSTRAINT fk_activity_log_store FOREIGN KEY (storeId) REFERENCES storeLocation(storeId) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_users_primary_store ON users(primaryStoreId);
|
||||
CREATE INDEX idx_users_role ON users(role);
|
||||
CREATE INDEX idx_users_name ON users(lastName, firstName);
|
||||
CREATE INDEX idx_service_species_species ON service_species(species);
|
||||
CREATE INDEX idx_inventory_store ON inventory(storeId);
|
||||
CREATE INDEX idx_inventory_product ON inventory(prodId);
|
||||
CREATE INDEX idx_purchase_order_store ON purchaseOrder(storeId);
|
||||
CREATE INDEX idx_pet_owner_user ON pet(ownerUserId);
|
||||
CREATE INDEX idx_pet_store ON pet(storeId);
|
||||
CREATE INDEX idx_pet_species ON pet(petSpecies);
|
||||
CREATE INDEX idx_pet_name ON pet(petName);
|
||||
CREATE INDEX idx_appointment_store ON appointment(storeId);
|
||||
CREATE INDEX idx_appointment_employee ON appointment(employeeId);
|
||||
CREATE INDEX idx_appointment_customer ON appointment(customerId);
|
||||
CREATE INDEX idx_appointment_pet ON appointment(petId);
|
||||
CREATE INDEX idx_appointment_date_status ON appointment(appointmentDate, appointmentStatus);
|
||||
CREATE INDEX idx_adoption_store ON adoption(sourceStoreId);
|
||||
CREATE INDEX idx_adoption_employee ON adoption(employeeId);
|
||||
CREATE INDEX idx_sale_store ON sale(storeId);
|
||||
CREATE INDEX idx_sale_employee ON sale(employeeId);
|
||||
CREATE INDEX idx_sale_customer ON sale(customerId);
|
||||
CREATE INDEX idx_sale_date ON sale(saleDate);
|
||||
CREATE INDEX idx_cart_user ON cart(userId);
|
||||
CREATE INDEX idx_conversation_customer ON conversation(customerId);
|
||||
CREATE INDEX idx_conversation_staff ON conversation(staffId);
|
||||
CREATE INDEX idx_activity_log_store ON activityLog(storeId);
|
||||
@@ -1,6 +0,0 @@
|
||||
INSERT INTO pet (petName, petSpecies, petBreed, petAge, petStatus, petPrice, customerId)
|
||||
SELECT 'Pepper', 'Cat', 'Tabby', 3, 'Owned', 0.00, customerId FROM customer WHERE email = 'alex@gmail.com'
|
||||
UNION ALL
|
||||
SELECT 'Coco', 'Dog', 'Pomeranian', 2, 'Owned', 0.00, customerId FROM customer WHERE email = 'olivia@gmail.com'
|
||||
UNION ALL
|
||||
SELECT 'Finn', 'Dog', 'Border Collie', 5, 'Owned', 0.00, customerId FROM customer WHERE email = 'sophia@gmail.com';
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user