merge origin/main into morefiles, resolve all conflicts
This commit is contained in:
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:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -155,6 +155,11 @@
|
||||
<configuration>
|
||||
<mainClass>com.petshop.backend.ResetDatabaseApplication</mainClass>
|
||||
<classpathScope>runtime</classpathScope>
|
||||
<arguments>
|
||||
<argument>clean</argument>
|
||||
<argument>install</argument>
|
||||
<argument>-DskipTests</argument>
|
||||
</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
@@ -192,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>
|
||||
|
||||
@@ -33,6 +33,7 @@ public class DevStackApplication {
|
||||
docker.ensureDockerAvailable();
|
||||
docker.startDatabase();
|
||||
context = new SpringApplicationBuilder(BackendApplication.class)
|
||||
.profiles("local")
|
||||
.initializers(new FlywayContextInitializer())
|
||||
.run(args);
|
||||
context.addApplicationListener(event -> {
|
||||
|
||||
@@ -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 ====");
|
||||
}
|
||||
|
||||
@@ -35,13 +35,14 @@ public class FlywayContextInitializer implements ApplicationContextInitializer<C
|
||||
RuntimeException lastFailure = null;
|
||||
for (int attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
||||
try {
|
||||
Flyway.configure()
|
||||
Flyway flyway = Flyway.configure()
|
||||
.dataSource(url, username, password)
|
||||
.locations(locations)
|
||||
.baselineOnMigrate(environment.getProperty("spring.flyway.baseline-on-migrate", Boolean.class, false))
|
||||
.baselineVersion(MigrationVersion.fromVersion(environment.getProperty("spring.flyway.baseline-version", "1")))
|
||||
.load()
|
||||
.migrate();
|
||||
.load();
|
||||
flyway.repair();
|
||||
flyway.migrate();
|
||||
return;
|
||||
} catch (RuntimeException ex) {
|
||||
lastFailure = ex;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.petshop.backend.config;
|
||||
|
||||
import com.petshop.backend.repository.PetRepository;
|
||||
import com.petshop.backend.repository.ProductRepository;
|
||||
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 LocalCatalogSeedInitializer implements CommandLineRunner {
|
||||
|
||||
private final DataSource dataSource;
|
||||
private final PetRepository petRepository;
|
||||
private final ProductRepository productRepository;
|
||||
|
||||
public LocalCatalogSeedInitializer(DataSource dataSource, PetRepository petRepository, ProductRepository productRepository) {
|
||||
this.dataSource = dataSource;
|
||||
this.petRepository = petRepository;
|
||||
this.productRepository = productRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
if (petRepository.count() > 6 || productRepository.count() > 6) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceDatabasePopulator populator = new ResourceDatabasePopulator(false, false, "UTF-8",
|
||||
new ClassPathResource("dev/expand_pet_product_seed.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;
|
||||
@@ -18,24 +17,28 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/adoptions")
|
||||
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
|
||||
@PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
|
||||
public ResponseEntity<Page<AdoptionResponse>> getAllAdoptions(
|
||||
@RequestParam(required = false) String q,
|
||||
@RequestParam(required = false) Long customerId,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) Long storeId,
|
||||
@RequestParam(required = false) String date,
|
||||
Pageable pageable) {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String role = authentication.getAuthorities().stream()
|
||||
@@ -43,13 +46,15 @@ public class AdoptionController {
|
||||
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
|
||||
.orElse(null);
|
||||
|
||||
Long customerId = null;
|
||||
Long effectiveCustomerId = customerId;
|
||||
if (role != null && role.equals("CUSTOMER")) {
|
||||
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
|
||||
customerId = customer.getCustomerId();
|
||||
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
effectiveCustomerId = user.getId();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(adoptionService.getAllAdoptions(q, pageable, customerId));
|
||||
LocalDate adoptionDate = (date != null && !date.isBlank()) ? LocalDate.parse(date) : null;
|
||||
|
||||
return ResponseEntity.ok(adoptionService.getAllAdoptions(q, effectiveCustomerId, status, storeId, adoptionDate, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@@ -63,29 +68,16 @@ 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));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
|
||||
@PreAuthorize("hasAnyRole('STAFF', 'ADMIN')")
|
||||
public ResponseEntity<AdoptionResponse> createAdoption(@Valid @RequestBody AdoptionRequest request) {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String role = authentication.getAuthorities().stream()
|
||||
.findFirst()
|
||||
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
|
||||
.orElse(null);
|
||||
|
||||
if (role != null && role.equals("CUSTOMER")) {
|
||||
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
|
||||
if (!request.getCustomerId().equals(customer.getCustomerId())) {
|
||||
throw new org.springframework.security.access.AccessDeniedException("You can only create adoptions for yourself");
|
||||
}
|
||||
}
|
||||
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(adoptionService.createAdoption(request));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,40 @@
|
||||
package com.petshop.backend.controller;
|
||||
|
||||
import com.petshop.backend.dto.analytics.DashboardResponse;
|
||||
import com.petshop.backend.entity.User;
|
||||
import com.petshop.backend.repository.UserRepository;
|
||||
import com.petshop.backend.service.AnalyticsService;
|
||||
import com.petshop.backend.util.AuthenticationHelper;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/analytics")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
@PreAuthorize("hasAnyRole('ADMIN', 'STAFF')")
|
||||
public class AnalyticsController {
|
||||
|
||||
private final AnalyticsService analyticsService;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public AnalyticsController(AnalyticsService analyticsService) {
|
||||
public AnalyticsController(AnalyticsService analyticsService, UserRepository userRepository) {
|
||||
this.analyticsService = analyticsService;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@GetMapping("/dashboard")
|
||||
public ResponseEntity<DashboardResponse> getDashboard(
|
||||
@RequestParam(defaultValue = "30") int days,
|
||||
@RequestParam(defaultValue = "10") int top) {
|
||||
return ResponseEntity.ok(analyticsService.getDashboardData(days, top));
|
||||
if (days < 1 || days > 365) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "days must be between 1 and 365");
|
||||
}
|
||||
if (top < 1 || top > 50) {
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "top must be between 1 and 50");
|
||||
}
|
||||
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
return ResponseEntity.ok(analyticsService.getDashboardData(days, top, user));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,32 +26,39 @@ 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
|
||||
@PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
|
||||
public ResponseEntity<Page<AppointmentResponse>> getAllAppointments(
|
||||
@RequestParam(required = false) String q,
|
||||
@RequestParam(required = false) Long storeId,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) String date,
|
||||
@RequestParam(required = false) Long customerId,
|
||||
@RequestParam(required = false) Long employeeId,
|
||||
Pageable pageable) {
|
||||
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String role = authentication.getAuthorities().stream()
|
||||
.findFirst()
|
||||
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
|
||||
.orElse(null);
|
||||
|
||||
Long customerId = null;
|
||||
Long effectiveCustomerId = customerId;
|
||||
if (role != null && role.equals("CUSTOMER")) {
|
||||
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
|
||||
customerId = customer.getCustomerId();
|
||||
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
effectiveCustomerId = user.getId();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(appointmentService.getAllAppointments(q, pageable, customerId));
|
||||
LocalDate appointmentDate = (date != null && !date.isBlank()) ? LocalDate.parse(date) : null;
|
||||
|
||||
return ResponseEntity.ok(appointmentService.getAllAppointments(
|
||||
q, effectiveCustomerId, employeeId, storeId, status, appointmentDate, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@@ -66,8 +72,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 +89,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,13 @@ 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.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 com.petshop.backend.util.PhoneUtils;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -28,6 +26,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;
|
||||
|
||||
@@ -43,37 +42,35 @@ 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;
|
||||
|
||||
public AuthController(AuthenticationManager authenticationManager, UserRepository userRepository, JwtUtil jwtUtil, PasswordEncoder passwordEncoder, UserBusinessLinkageService userBusinessLinkageService, EmployeeRepository employeeRepository, EmployeeStoreRepository employeeStoreRepository, AvatarStorageService avatarStorageService) {
|
||||
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;
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
public ResponseEntity<?> register(@Valid @RequestBody RegisterRequest request) {
|
||||
if (userRepository.findByUsername(request.getUsername()).isPresent()) {
|
||||
String username = trimToNull(request.getUsername());
|
||||
String email = trimToNull(request.getEmail());
|
||||
NameParts nameParts = splitFullName(request.getFullName());
|
||||
String phone = normalizePhone(request.getPhone());
|
||||
|
||||
if (userRepository.findByUsername(username).isPresent()) {
|
||||
Map<String, String> error = new HashMap<>();
|
||||
error.put("message", "Username already exists");
|
||||
return ResponseEntity.status(HttpStatus.CONFLICT).body(error);
|
||||
}
|
||||
|
||||
if (userRepository.findByEmail(request.getEmail()).isPresent()) {
|
||||
if (userRepository.findByEmail(email).isPresent()) {
|
||||
Map<String, String> error = new HashMap<>();
|
||||
error.put("message", "Email already exists");
|
||||
return ResponseEntity.status(HttpStatus.CONFLICT).body(error);
|
||||
}
|
||||
|
||||
String phone = trimToNull(request.getPhone());
|
||||
if (phone != null && userRepository.findByPhone(phone).isPresent()) {
|
||||
Map<String, String> error = new HashMap<>();
|
||||
error.put("message", "Phone already exists");
|
||||
@@ -81,19 +78,18 @@ public class AuthController {
|
||||
}
|
||||
|
||||
User user = new User();
|
||||
user.setUsername(request.getUsername());
|
||||
user.setUsername(username);
|
||||
user.setPassword(passwordEncoder.encode(request.getPassword()));
|
||||
user.setEmail(request.getEmail());
|
||||
user.setFullName(request.getFullName());
|
||||
user.setEmail(email);
|
||||
user.setFirstName(nameParts.firstName());
|
||||
user.setLastName(nameParts.lastName());
|
||||
user.setFullName(nameParts.fullName());
|
||||
user.setPhone(phone);
|
||||
user.setRole(User.Role.CUSTOMER);
|
||||
user.setActive(true);
|
||||
|
||||
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(
|
||||
@@ -142,23 +138,11 @@ public class AuthController {
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@GetMapping("/me")
|
||||
public ResponseEntity<UserInfoResponse> getCurrentUser() {
|
||||
User user = getAuthenticatedUser();
|
||||
|
||||
EmployeeStore employeeStore = resolveEmployeeStore(user);
|
||||
|
||||
return ResponseEntity.ok(new UserInfoResponse(
|
||||
user.getId(),
|
||||
user.getUsername(),
|
||||
user.getEmail(),
|
||||
user.getFullName(),
|
||||
user.getPhone(),
|
||||
avatarStorageService.toOwnerAvatarUrl(user),
|
||||
user.getRole().name(),
|
||||
employeeStore != null ? employeeStore.getStore().getStoreId() : null,
|
||||
employeeStore != null ? employeeStore.getStore().getStoreName() : null
|
||||
));
|
||||
return ResponseEntity.ok(toUserInfoResponse(user));
|
||||
}
|
||||
|
||||
@PutMapping("/me")
|
||||
@@ -166,31 +150,36 @@ public class AuthController {
|
||||
User user = getAuthenticatedUser();
|
||||
boolean invalidateToken = false;
|
||||
|
||||
if (request.getUsername() != null && !request.getUsername().equals(user.getUsername())) {
|
||||
if (userRepository.findByUsername(request.getUsername()).isPresent()) {
|
||||
String username = trimToNull(request.getUsername());
|
||||
if (username != null && !username.equals(user.getUsername())) {
|
||||
if (userRepository.findByUsername(username).isPresent()) {
|
||||
Map<String, String> error = new HashMap<>();
|
||||
error.put("message", "Username already exists");
|
||||
return ResponseEntity.status(HttpStatus.CONFLICT).body(error);
|
||||
}
|
||||
user.setUsername(request.getUsername());
|
||||
user.setUsername(username);
|
||||
invalidateToken = true;
|
||||
}
|
||||
|
||||
if (request.getEmail() != null && !request.getEmail().equals(user.getEmail())) {
|
||||
if (userRepository.findByEmail(request.getEmail()).isPresent()) {
|
||||
String email = trimToNull(request.getEmail());
|
||||
if (email != null && !email.equals(user.getEmail())) {
|
||||
if (userRepository.findByEmail(email).isPresent()) {
|
||||
Map<String, String> error = new HashMap<>();
|
||||
error.put("message", "Email already exists");
|
||||
return ResponseEntity.status(HttpStatus.CONFLICT).body(error);
|
||||
}
|
||||
user.setEmail(request.getEmail());
|
||||
user.setEmail(email);
|
||||
}
|
||||
|
||||
if (request.getFullName() != null) {
|
||||
user.setFullName(request.getFullName());
|
||||
NameParts nameParts = splitFullName(request.getFullName());
|
||||
user.setFirstName(nameParts.firstName());
|
||||
user.setLastName(nameParts.lastName());
|
||||
user.setFullName(nameParts.fullName());
|
||||
}
|
||||
|
||||
if (request.getPhone() != null) {
|
||||
String phone = trimToNull(request.getPhone());
|
||||
String phone = normalizePhone(request.getPhone());
|
||||
if (!java.util.Objects.equals(phone, user.getPhone())) {
|
||||
if (phone != null && userRepository.findByPhone(phone)
|
||||
.filter(existing -> !existing.getId().equals(user.getId()))
|
||||
@@ -213,31 +202,28 @@ public class AuthController {
|
||||
}
|
||||
|
||||
User updatedUser = userRepository.save(user);
|
||||
userBusinessLinkageService.syncLinkedRecords(updatedUser);
|
||||
|
||||
EmployeeStore employeeStore = resolveEmployeeStore(updatedUser);
|
||||
|
||||
return ResponseEntity.ok(new UserInfoResponse(
|
||||
updatedUser.getId(),
|
||||
updatedUser.getUsername(),
|
||||
updatedUser.getEmail(),
|
||||
updatedUser.getFullName(),
|
||||
updatedUser.getPhone(),
|
||||
avatarStorageService.toOwnerAvatarUrl(updatedUser),
|
||||
updatedUser.getRole().name(),
|
||||
employeeStore != null ? employeeStore.getStore().getStoreId() : null,
|
||||
employeeStore != null ? employeeStore.getStore().getStoreName() : null
|
||||
));
|
||||
return ResponseEntity.ok(toUserInfoResponse(updatedUser));
|
||||
}
|
||||
|
||||
private EmployeeStore resolveEmployeeStore(User user) {
|
||||
if (user.getRole() == User.Role.CUSTOMER) {
|
||||
return null;
|
||||
private UserInfoResponse toUserInfoResponse(User user) {
|
||||
StoreLocation primaryStore = user.getPrimaryStore();
|
||||
Long customerId = user.getRole() == User.Role.CUSTOMER ? user.getId() : null;
|
||||
String fullName = user.getFullName();
|
||||
if (fullName == null || fullName.isBlank()) {
|
||||
fullName = joinFullName(user.getFirstName(), user.getLastName());
|
||||
}
|
||||
|
||||
return employeeRepository.findByUserId(user.getId())
|
||||
.flatMap(employee -> employeeStoreRepository.findByEmployeeEmployeeId(employee.getEmployeeId()))
|
||||
.orElse(null);
|
||||
return new UserInfoResponse(
|
||||
user.getId(),
|
||||
user.getUsername(),
|
||||
user.getEmail(),
|
||||
fullName,
|
||||
user.getPhone(),
|
||||
avatarStorageService.toOwnerAvatarUrl(user),
|
||||
user.getRole().name(),
|
||||
customerId,
|
||||
primaryStore != null ? primaryStore.getStoreId() : null,
|
||||
primaryStore != null ? primaryStore.getStoreName() : null
|
||||
);
|
||||
}
|
||||
|
||||
private String trimToNull(String value) {
|
||||
@@ -248,6 +234,36 @@ public class AuthController {
|
||||
return trimmed.isEmpty() ? null : trimmed;
|
||||
}
|
||||
|
||||
private String normalizePhone(String value) {
|
||||
return trimToNull(PhoneUtils.normalize(trimToNull(value)));
|
||||
}
|
||||
|
||||
private NameParts splitFullName(String value) {
|
||||
String normalized = trimToNull(value);
|
||||
if (normalized == null) {
|
||||
throw new IllegalArgumentException("Full name is required");
|
||||
}
|
||||
String[] parts = normalized.split("\\s+", 2);
|
||||
String firstName = parts[0];
|
||||
String lastName = parts.length > 1 ? parts[1] : "";
|
||||
return new NameParts(firstName, lastName, joinFullName(firstName, lastName));
|
||||
}
|
||||
|
||||
private String joinFullName(String firstName, String lastName) {
|
||||
String first = trimToNull(firstName);
|
||||
String last = trimToNull(lastName);
|
||||
if (first == null) {
|
||||
return last == null ? null : last;
|
||||
}
|
||||
if (last == null) {
|
||||
return first;
|
||||
}
|
||||
return first + " " + last;
|
||||
}
|
||||
|
||||
private record NameParts(String firstName, String lastName, String fullName) {
|
||||
}
|
||||
|
||||
@PostMapping("/me/avatar")
|
||||
public ResponseEntity<?> uploadAvatar(@RequestParam("avatar") MultipartFile file) {
|
||||
User user = getAuthenticatedUser();
|
||||
|
||||
@@ -25,8 +25,9 @@ public class CategoryController {
|
||||
@GetMapping
|
||||
public ResponseEntity<Page<CategoryResponse>> getAllCategories(
|
||||
@RequestParam(required = false) String q,
|
||||
@RequestParam(required = false) String type,
|
||||
Pageable pageable) {
|
||||
return ResponseEntity.ok(categoryService.getAllCategories(q, pageable));
|
||||
return ResponseEntity.ok(categoryService.getAllCategories(q, type, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
|
||||
@@ -4,8 +4,8 @@ import com.petshop.backend.dto.chat.ConversationRequest;
|
||||
import com.petshop.backend.dto.chat.ConversationResponse;
|
||||
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;
|
||||
@@ -26,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() {
|
||||
@@ -96,4 +94,13 @@ public class ChatController {
|
||||
chatRealtimeService.publishConversationUpdate(id);
|
||||
return ResponseEntity.ok(conversation);
|
||||
}
|
||||
|
||||
@PutMapping("/conversations/{id}")
|
||||
@PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
|
||||
public ResponseEntity<ConversationResponse> updateConversation(@PathVariable Long id, @Valid @RequestBody UpdateConversationRequest request) {
|
||||
User user = getCurrentUser();
|
||||
ConversationResponse conversation = chatService.updateConversation(id, user.getId(), user.getRole(), request);
|
||||
chatRealtimeService.publishConversationUpdate(id);
|
||||
return ResponseEntity.ok(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,10 +1,12 @@
|
||||
package com.petshop.backend.controller;
|
||||
|
||||
import com.petshop.backend.dto.common.DropdownOption;
|
||||
import com.petshop.backend.entity.User;
|
||||
import com.petshop.backend.repository.*;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@@ -16,24 +18,25 @@ import java.util.stream.Collectors;
|
||||
public class DropdownController {
|
||||
|
||||
private final PetRepository petRepository;
|
||||
private final CustomerRepository customerRepository;
|
||||
private final ServiceRepository serviceRepository;
|
||||
private final ProductRepository productRepository;
|
||||
private final CategoryRepository categoryRepository;
|
||||
private final StoreRepository storeRepository;
|
||||
private final SupplierRepository supplierRepository;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public DropdownController(PetRepository petRepository, CustomerRepository customerRepository,
|
||||
ServiceRepository serviceRepository, ProductRepository productRepository,
|
||||
CategoryRepository categoryRepository, StoreRepository storeRepository,
|
||||
SupplierRepository supplierRepository) {
|
||||
public DropdownController(PetRepository petRepository,
|
||||
ServiceRepository serviceRepository, ProductRepository productRepository,
|
||||
CategoryRepository categoryRepository, StoreRepository storeRepository,
|
||||
SupplierRepository supplierRepository,
|
||||
UserRepository userRepository) {
|
||||
this.petRepository = petRepository;
|
||||
this.customerRepository = customerRepository;
|
||||
this.serviceRepository = serviceRepository;
|
||||
this.productRepository = productRepository;
|
||||
this.categoryRepository = categoryRepository;
|
||||
this.storeRepository = storeRepository;
|
||||
this.supplierRepository = supplierRepository;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@GetMapping("/pets")
|
||||
@@ -45,16 +48,36 @@ public class DropdownController {
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/adoption-pets")
|
||||
@PreAuthorize("hasAnyRole('STAFF', 'ADMIN')")
|
||||
public ResponseEntity<List<DropdownOption>> getAdoptionPets() {
|
||||
return ResponseEntity.ok(
|
||||
petRepository.findAllByPetStatusIgnoreCaseOrderByPetNameAsc("Available").stream()
|
||||
.map(p -> new DropdownOption(p.getPetId(), p.getPetName()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/customers")
|
||||
@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())
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/appointment-customers")
|
||||
@PreAuthorize("hasAnyRole('STAFF', 'ADMIN')")
|
||||
public ResponseEntity<List<DropdownOption>> getAppointmentCustomers() {
|
||||
return ResponseEntity.ok(
|
||||
userRepository.findByRoleAndActiveTrue(User.Role.CUSTOMER).stream()
|
||||
.map(u -> new DropdownOption(u.getId(), u.getFirstName() + " " + u.getLastName()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/services")
|
||||
public ResponseEntity<List<DropdownOption>> getServices() {
|
||||
return ResponseEntity.ok(
|
||||
@@ -82,6 +105,29 @@ public class DropdownController {
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/product-categories")
|
||||
public ResponseEntity<List<DropdownOption>> getProductCategories() {
|
||||
return ResponseEntity.ok(
|
||||
categoryRepository.findAll().stream()
|
||||
.filter(c -> "product".equalsIgnoreCase(c.getCategoryType()))
|
||||
.map(c -> new DropdownOption(c.getCategoryId(), c.getCategoryName()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/pet-species")
|
||||
public ResponseEntity<List<DropdownOption>> getPetSpecies() {
|
||||
return ResponseEntity.ok(
|
||||
petRepository.findAll().stream()
|
||||
.map(p -> p.getPetSpecies())
|
||||
.filter(species -> species != null && !species.isBlank())
|
||||
.distinct()
|
||||
.sorted(String.CASE_INSENSITIVE_ORDER)
|
||||
.map(species -> new DropdownOption(null, species))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/stores")
|
||||
public ResponseEntity<List<DropdownOption>> getStores() {
|
||||
return ResponseEntity.ok(
|
||||
@@ -91,6 +137,32 @@ public class DropdownController {
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping({"/stores/{storeId}/employees", "/employees"})
|
||||
@PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
|
||||
public ResponseEntity<List<DropdownOption>> getStoreEmployees(@PathVariable(required = false) Long storeId) {
|
||||
List<User> employees;
|
||||
if (storeId == null || storeId == 0) {
|
||||
employees = userRepository.findByRoleAndActiveTrue(User.Role.STAFF);
|
||||
} else {
|
||||
employees = userRepository.findByPrimaryStoreStoreIdAndRoleAndActiveTrue(storeId, User.Role.STAFF);
|
||||
}
|
||||
return ResponseEntity.ok(
|
||||
employees.stream()
|
||||
.map(u -> new DropdownOption(u.getId(), u.getFirstName() + " " + u.getLastName()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/customers/{customerId}/pets")
|
||||
@PreAuthorize("hasAnyRole('STAFF', 'ADMIN')")
|
||||
public ResponseEntity<List<DropdownOption>> getCustomerPets(@PathVariable Long customerId) {
|
||||
return ResponseEntity.ok(
|
||||
petRepository.findAllByOwner_IdOrderByPetNameAsc(customerId).stream()
|
||||
.map(p -> new DropdownOption(p.getPetId(), p.getPetName()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
@GetMapping("/suppliers")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<List<DropdownOption>> getSuppliers() {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,9 @@ public class InventoryController {
|
||||
@GetMapping
|
||||
public ResponseEntity<Page<InventoryResponse>> getAllInventory(
|
||||
@RequestParam(required = false) String q,
|
||||
@RequestParam(required = false) Long storeId,
|
||||
Pageable pageable) {
|
||||
return ResponseEntity.ok(inventoryService.getAllInventory(q, pageable));
|
||||
return ResponseEntity.ok(inventoryService.getAllInventory(q, storeId, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.petshop.backend.controller;
|
||||
|
||||
import com.petshop.backend.dto.pet.MyPetRequest;
|
||||
import com.petshop.backend.dto.pet.MyPetResponse;
|
||||
import com.petshop.backend.entity.User;
|
||||
import com.petshop.backend.repository.UserRepository;
|
||||
import com.petshop.backend.service.PetService;
|
||||
import com.petshop.backend.util.AuthenticationHelper;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/my-pets")
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
public class MyPetController {
|
||||
|
||||
private final PetService petService;
|
||||
private final UserRepository userRepository;
|
||||
|
||||
public MyPetController(PetService petService, UserRepository userRepository) {
|
||||
this.petService = petService;
|
||||
this.userRepository = userRepository;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<List<MyPetResponse>> getMyPets() {
|
||||
return ResponseEntity.ok(petService.getMyPets(currentUserId()));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<MyPetResponse> createMyPet(@Valid @RequestBody MyPetRequest request) {
|
||||
return ResponseEntity.ok(petService.createMyPet(currentUserId(), request));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<MyPetResponse> updateMyPet(@PathVariable Long id, @Valid @RequestBody MyPetRequest request) {
|
||||
return ResponseEntity.ok(petService.updateMyPet(currentUserId(), id, request));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> deleteMyPet(@PathVariable Long id) {
|
||||
petService.deleteMyPet(currentUserId(), id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/image")
|
||||
public ResponseEntity<?> uploadMyPetImage(@PathVariable Long id, @RequestParam("image") MultipartFile image) {
|
||||
try {
|
||||
return ResponseEntity.ok(petService.uploadMyPetImage(currentUserId(), id, image));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
return ResponseEntity.badRequest().body(Map.of("message", ex.getMessage()));
|
||||
} catch (IOException ex) {
|
||||
return ResponseEntity.badRequest().body(Map.of("message", "Failed to upload pet image: " + ex.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
private Long currentUserId() {
|
||||
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
return user.getId();
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,11 @@ public class PetController {
|
||||
@GetMapping
|
||||
public ResponseEntity<Page<PetResponse>> getAllPets(
|
||||
@RequestParam(required = false) String q,
|
||||
@RequestParam(required = false) String species,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) Long storeId,
|
||||
Pageable pageable) {
|
||||
return ResponseEntity.ok(petService.getAllPets(q, pageable));
|
||||
return ResponseEntity.ok(petService.getAllPets(q, species, status, storeId, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
|
||||
@@ -48,12 +48,8 @@ public class PetImageController {
|
||||
|
||||
@GetMapping("/{id}/image")
|
||||
public ResponseEntity<Resource> getPetImage(@PathVariable Long id) {
|
||||
try {
|
||||
PetService.ImagePayload payload = petService.loadPetImage(id, currentUserId(), currentUserRole());
|
||||
return ResponseEntity.ok().contentType(payload.mediaType()).body(payload.resource());
|
||||
} catch (PetService.ForbiddenImageAccessException ex) {
|
||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
|
||||
}
|
||||
PetService.ImagePayload payload = petService.loadPetImage(id, currentUserId(), currentUserRole());
|
||||
return ResponseEntity.ok().contentType(payload.mediaType()).body(payload.resource());
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}/image")
|
||||
|
||||
@@ -25,8 +25,9 @@ public class ProductController {
|
||||
@GetMapping
|
||||
public ResponseEntity<Page<ProductResponse>> getAllProducts(
|
||||
@RequestParam(required = false) String q,
|
||||
@RequestParam(required = false) Long categoryId,
|
||||
Pageable pageable) {
|
||||
return ResponseEntity.ok(productService.getAllProducts(q, pageable));
|
||||
return ResponseEntity.ok(productService.getAllProducts(q, categoryId, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
|
||||
@@ -26,8 +26,10 @@ public class ProductSupplierController {
|
||||
@GetMapping
|
||||
public ResponseEntity<Page<ProductSupplierResponse>> getAllProductSuppliers(
|
||||
@RequestParam(required = false) String q,
|
||||
@RequestParam(required = false) Long productId,
|
||||
@RequestParam(required = false) Long supplierId,
|
||||
Pageable pageable) {
|
||||
return ResponseEntity.ok(productSupplierService.getAllProductSuppliers(q, pageable));
|
||||
return ResponseEntity.ok(productSupplierService.getAllProductSuppliers(q, productId, supplierId, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{productId}/{supplierId}")
|
||||
|
||||
@@ -22,8 +22,9 @@ public class PurchaseOrderController {
|
||||
@GetMapping
|
||||
public ResponseEntity<Page<PurchaseOrderResponse>> getAllPurchaseOrders(
|
||||
@RequestParam(required = false) String q,
|
||||
@RequestParam(required = false) Long storeId,
|
||||
Pageable pageable) {
|
||||
return ResponseEntity.ok(purchaseOrderService.getAllPurchaseOrders(q, pageable));
|
||||
return ResponseEntity.ok(purchaseOrderService.getAllPurchaseOrders(q, storeId, pageable));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
|
||||
@@ -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;
|
||||
@@ -16,9 +15,7 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/refunds")
|
||||
@@ -26,37 +23,28 @@ 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
|
||||
@PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
|
||||
public ResponseEntity<?> createRefund(@Valid @RequestBody RefundRequest request) {
|
||||
try {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String role = authentication.getAuthorities().stream()
|
||||
.findFirst()
|
||||
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
|
||||
.orElse(null);
|
||||
public ResponseEntity<RefundResponse> createRefund(@Valid @RequestBody RefundRequest request) {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String role = authentication.getAuthorities().stream()
|
||||
.findFirst()
|
||||
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
|
||||
.orElse(null);
|
||||
|
||||
Long customerId = null;
|
||||
if (role != null && role.equals("CUSTOMER")) {
|
||||
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
|
||||
customerId = customer.getCustomerId();
|
||||
}
|
||||
|
||||
RefundResponse refund = refundService.createRefund(request, customerId);
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(refund);
|
||||
} catch (RuntimeException e) {
|
||||
Map<String, String> error = new HashMap<>();
|
||||
error.put("message", e.getMessage());
|
||||
return ResponseEntity.badRequest().body(error);
|
||||
Long customerId = null;
|
||||
if (role != null && role.equals("CUSTOMER")) {
|
||||
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
customerId = user.getId();
|
||||
}
|
||||
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(refundService.createRefund(request, customerId));
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@@ -70,8 +58,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);
|
||||
@@ -80,54 +68,32 @@ public class RefundController {
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@PreAuthorize("hasAnyRole('CUSTOMER', 'STAFF', 'ADMIN')")
|
||||
public ResponseEntity<?> getRefundById(@PathVariable Long id) {
|
||||
try {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String role = authentication.getAuthorities().stream()
|
||||
.findFirst()
|
||||
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
|
||||
.orElse(null);
|
||||
public ResponseEntity<RefundResponse> getRefundById(@PathVariable Long id) {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String role = authentication.getAuthorities().stream()
|
||||
.findFirst()
|
||||
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
|
||||
.orElse(null);
|
||||
|
||||
Long customerId = null;
|
||||
if (role != null && role.equals("CUSTOMER")) {
|
||||
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
|
||||
customerId = customer.getCustomerId();
|
||||
}
|
||||
|
||||
RefundResponse refund = refundService.getRefundById(id, customerId);
|
||||
return ResponseEntity.ok(refund);
|
||||
} catch (RuntimeException e) {
|
||||
Map<String, String> error = new HashMap<>();
|
||||
error.put("message", e.getMessage());
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
|
||||
Long customerId = null;
|
||||
if (role != null && role.equals("CUSTOMER")) {
|
||||
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
customerId = user.getId();
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(refundService.getRefundById(id, customerId));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("hasAnyRole('STAFF', 'ADMIN')")
|
||||
public ResponseEntity<?> updateRefund(@PathVariable Long id, @Valid @RequestBody RefundUpdateRequest request) {
|
||||
try {
|
||||
RefundResponse refund = refundService.updateRefundStatus(id, request.getStatus());
|
||||
return ResponseEntity.ok(refund);
|
||||
} catch (RuntimeException e) {
|
||||
Map<String, String> error = new HashMap<>();
|
||||
error.put("message", e.getMessage());
|
||||
return ResponseEntity.badRequest().body(error);
|
||||
}
|
||||
public ResponseEntity<RefundResponse> updateRefund(@PathVariable Long id, @Valid @RequestBody RefundUpdateRequest request) {
|
||||
return ResponseEntity.ok(refundService.updateRefundStatus(id, request.getStatus()));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseEntity<?> deleteRefund(@PathVariable Long id) {
|
||||
try {
|
||||
refundService.deleteRefund(id);
|
||||
Map<String, String> response = new HashMap<>();
|
||||
response.put("message", "Refund deleted successfully");
|
||||
return ResponseEntity.ok(response);
|
||||
} catch (RuntimeException e) {
|
||||
Map<String, String> error = new HashMap<>();
|
||||
error.put("message", e.getMessage());
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
|
||||
}
|
||||
public ResponseEntity<Void> deleteRefund(@PathVariable Long id) {
|
||||
refundService.deleteRefund(id);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ public class AdoptionRequest {
|
||||
@NotBlank(message = "Adoption status is required")
|
||||
private String adoptionStatus;
|
||||
|
||||
private Long employeeId;
|
||||
|
||||
private Long sourceStoreId;
|
||||
|
||||
public Long getPetId() {
|
||||
return petId;
|
||||
}
|
||||
@@ -56,6 +60,22 @@ public class AdoptionRequest {
|
||||
this.adoptionStatus = adoptionStatus;
|
||||
}
|
||||
|
||||
public Long getEmployeeId() {
|
||||
return employeeId;
|
||||
}
|
||||
|
||||
public void setEmployeeId(Long employeeId) {
|
||||
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;
|
||||
@@ -64,12 +84,14 @@ public class AdoptionRequest {
|
||||
return Objects.equals(petId, that.petId) &&
|
||||
Objects.equals(customerId, that.customerId) &&
|
||||
Objects.equals(adoptionDate, that.adoptionDate) &&
|
||||
Objects.equals(adoptionStatus, that.adoptionStatus);
|
||||
Objects.equals(adoptionStatus, that.adoptionStatus) &&
|
||||
Objects.equals(employeeId, that.employeeId) &&
|
||||
Objects.equals(sourceStoreId, that.sourceStoreId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(petId, customerId, adoptionDate, adoptionStatus);
|
||||
return Objects.hash(petId, customerId, adoptionDate, adoptionStatus, employeeId, sourceStoreId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,6 +101,8 @@ public class AdoptionRequest {
|
||||
", customerId=" + customerId +
|
||||
", adoptionDate=" + adoptionDate +
|
||||
", adoptionStatus='" + adoptionStatus + '\'' +
|
||||
", employeeId=" + employeeId +
|
||||
", sourceStoreId=" + sourceStoreId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,152 +11,75 @@ public class AdoptionResponse {
|
||||
private String petName;
|
||||
private Long customerId;
|
||||
private String customerName;
|
||||
private Long employeeId;
|
||||
private String employeeName;
|
||||
private Long sourceStoreId;
|
||||
private String sourceStoreName;
|
||||
private LocalDate adoptionDate;
|
||||
private String adoptionStatus;
|
||||
private BigDecimal adoptionFee;
|
||||
private Long employeeId;
|
||||
private String employeeName;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public AdoptionResponse() {
|
||||
}
|
||||
|
||||
public AdoptionResponse(Long adoptionId, Long petId, String petName, Long customerId, String customerName, 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;
|
||||
this.customerId = customerId;
|
||||
this.customerName = customerName;
|
||||
this.adoptionDate = adoptionDate;
|
||||
this.adoptionStatus = adoptionStatus;
|
||||
this.adoptionFee = adoptionFee;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Long getAdoptionId() {
|
||||
return adoptionId;
|
||||
}
|
||||
|
||||
public void setAdoptionId(Long adoptionId) {
|
||||
this.adoptionId = adoptionId;
|
||||
}
|
||||
|
||||
public Long getPetId() {
|
||||
return petId;
|
||||
}
|
||||
|
||||
public void setPetId(Long petId) {
|
||||
this.petId = petId;
|
||||
}
|
||||
|
||||
public String getPetName() {
|
||||
return petName;
|
||||
}
|
||||
|
||||
public void setPetName(String petName) {
|
||||
this.petName = petName;
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public String getCustomerName() {
|
||||
return customerName;
|
||||
}
|
||||
|
||||
public void setCustomerName(String customerName) {
|
||||
this.customerName = customerName;
|
||||
}
|
||||
|
||||
public Long getEmployeeId() {
|
||||
return employeeId;
|
||||
}
|
||||
|
||||
public void setEmployeeId(Long employeeId) {
|
||||
this.employeeId = employeeId;
|
||||
}
|
||||
|
||||
public String getEmployeeName() {
|
||||
return employeeName;
|
||||
}
|
||||
|
||||
public void setEmployeeName(String employeeName) {
|
||||
this.employeeName = employeeName;
|
||||
}
|
||||
|
||||
public LocalDate getAdoptionDate() {
|
||||
return adoptionDate;
|
||||
}
|
||||
|
||||
public void setAdoptionDate(LocalDate adoptionDate) {
|
||||
this.sourceStoreId = sourceStoreId;
|
||||
this.sourceStoreName = sourceStoreName;
|
||||
this.adoptionDate = adoptionDate;
|
||||
}
|
||||
|
||||
public String getAdoptionStatus() {
|
||||
return adoptionStatus;
|
||||
}
|
||||
|
||||
public void setAdoptionStatus(String adoptionStatus) {
|
||||
this.adoptionStatus = adoptionStatus;
|
||||
}
|
||||
|
||||
public BigDecimal getAdoptionFee() {
|
||||
return adoptionFee;
|
||||
}
|
||||
|
||||
public void setAdoptionFee(BigDecimal adoptionFee) {
|
||||
this.adoptionFee = adoptionFee;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
public Long getAdoptionId() { return adoptionId; }
|
||||
public void setAdoptionId(Long adoptionId) { this.adoptionId = adoptionId; }
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(adoptionId, petId, petName, customerId, customerName, adoptionDate, adoptionStatus, adoptionFee, createdAt, updatedAt);
|
||||
}
|
||||
public Long getPetId() { return petId; }
|
||||
public void setPetId(Long petId) { this.petId = petId; }
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdoptionResponse{" +
|
||||
"adoptionId=" + adoptionId +
|
||||
", petId=" + petId +
|
||||
", petName='" + petName + '\'' +
|
||||
", customerId=" + customerId +
|
||||
", customerName='" + customerName + '\'' +
|
||||
", adoptionDate=" + adoptionDate +
|
||||
", adoptionStatus='" + adoptionStatus + '\'' +
|
||||
", adoptionFee=" + adoptionFee +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
'}';
|
||||
}
|
||||
public String getPetName() { return petName; }
|
||||
public void setPetName(String petName) { this.petName = petName; }
|
||||
|
||||
public Long getCustomerId() { return customerId; }
|
||||
public void setCustomerId(Long customerId) { this.customerId = customerId; }
|
||||
|
||||
public String getCustomerName() { return customerName; }
|
||||
public void setCustomerName(String customerName) { this.customerName = customerName; }
|
||||
|
||||
public Long getEmployeeId() { return employeeId; }
|
||||
public void setEmployeeId(Long employeeId) { this.employeeId = employeeId; }
|
||||
|
||||
public String getEmployeeName() { return employeeName; }
|
||||
public void setEmployeeName(String employeeName) { 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; }
|
||||
public void setAdoptionDate(LocalDate adoptionDate) { this.adoptionDate = adoptionDate; }
|
||||
|
||||
public String getAdoptionStatus() { return adoptionStatus; }
|
||||
public void setAdoptionStatus(String adoptionStatus) { this.adoptionStatus = adoptionStatus; }
|
||||
|
||||
public BigDecimal getAdoptionFee() { return adoptionFee; }
|
||||
public void setAdoptionFee(BigDecimal adoptionFee) { this.adoptionFee = adoptionFee; }
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
@@ -9,15 +9,19 @@ public class DashboardResponse {
|
||||
private InventorySummary inventorySummary;
|
||||
private List<TopProduct> topProducts;
|
||||
private List<DailySales> dailySales;
|
||||
private List<PaymentMethodData> paymentMethods;
|
||||
private List<EmployeePerformanceData> employeePerformance;
|
||||
|
||||
public DashboardResponse() {
|
||||
}
|
||||
|
||||
public DashboardResponse(SalesSummary salesSummary, InventorySummary inventorySummary, List<TopProduct> topProducts, List<DailySales> dailySales) {
|
||||
public DashboardResponse(SalesSummary salesSummary, InventorySummary inventorySummary, List<TopProduct> topProducts, List<DailySales> dailySales, List<PaymentMethodData> paymentMethods, List<EmployeePerformanceData> employeePerformance) {
|
||||
this.salesSummary = salesSummary;
|
||||
this.inventorySummary = inventorySummary;
|
||||
this.topProducts = topProducts;
|
||||
this.dailySales = dailySales;
|
||||
this.paymentMethods = paymentMethods;
|
||||
this.employeePerformance = employeePerformance;
|
||||
}
|
||||
|
||||
public SalesSummary getSalesSummary() {
|
||||
@@ -52,17 +56,33 @@ public class DashboardResponse {
|
||||
this.dailySales = dailySales;
|
||||
}
|
||||
|
||||
public List<PaymentMethodData> getPaymentMethods() {
|
||||
return paymentMethods;
|
||||
}
|
||||
|
||||
public void setPaymentMethods(List<PaymentMethodData> paymentMethods) {
|
||||
this.paymentMethods = paymentMethods;
|
||||
}
|
||||
|
||||
public List<EmployeePerformanceData> getEmployeePerformance() {
|
||||
return employeePerformance;
|
||||
}
|
||||
|
||||
public void setEmployeePerformance(List<EmployeePerformanceData> employeePerformance) {
|
||||
this.employeePerformance = employeePerformance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DashboardResponse that = (DashboardResponse) o;
|
||||
return Objects.equals(salesSummary, that.salesSummary) && Objects.equals(inventorySummary, that.inventorySummary) && Objects.equals(topProducts, that.topProducts) && Objects.equals(dailySales, that.dailySales);
|
||||
return Objects.equals(salesSummary, that.salesSummary) && Objects.equals(inventorySummary, that.inventorySummary) && Objects.equals(topProducts, that.topProducts) && Objects.equals(dailySales, that.dailySales) && Objects.equals(paymentMethods, that.paymentMethods) && Objects.equals(employeePerformance, that.employeePerformance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(salesSummary, inventorySummary, topProducts, dailySales);
|
||||
return Objects.hash(salesSummary, inventorySummary, topProducts, dailySales, paymentMethods, employeePerformance);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,6 +92,8 @@ public class DashboardResponse {
|
||||
", inventorySummary=" + inventorySummary +
|
||||
", topProducts=" + topProducts +
|
||||
", dailySales=" + dailySales +
|
||||
", paymentMethods=" + paymentMethods +
|
||||
", employeePerformance=" + employeePerformance +
|
||||
'}';
|
||||
}
|
||||
|
||||
@@ -80,15 +102,17 @@ public class DashboardResponse {
|
||||
private Long totalSales;
|
||||
private BigDecimal totalRefunds;
|
||||
private Long totalRefundCount;
|
||||
private Long totalItemsSold;
|
||||
|
||||
public SalesSummary() {
|
||||
}
|
||||
|
||||
public SalesSummary(BigDecimal totalRevenue, Long totalSales, BigDecimal totalRefunds, Long totalRefundCount) {
|
||||
public SalesSummary(BigDecimal totalRevenue, Long totalSales, BigDecimal totalRefunds, Long totalRefundCount, Long totalItemsSold) {
|
||||
this.totalRevenue = totalRevenue;
|
||||
this.totalSales = totalSales;
|
||||
this.totalRefunds = totalRefunds;
|
||||
this.totalRefundCount = totalRefundCount;
|
||||
this.totalItemsSold = totalItemsSold;
|
||||
}
|
||||
|
||||
public BigDecimal getTotalRevenue() {
|
||||
@@ -123,17 +147,25 @@ public class DashboardResponse {
|
||||
this.totalRefundCount = totalRefundCount;
|
||||
}
|
||||
|
||||
public Long getTotalItemsSold() {
|
||||
return totalItemsSold;
|
||||
}
|
||||
|
||||
public void setTotalItemsSold(Long totalItemsSold) {
|
||||
this.totalItemsSold = totalItemsSold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
SalesSummary that = (SalesSummary) o;
|
||||
return Objects.equals(totalRevenue, that.totalRevenue) && Objects.equals(totalSales, that.totalSales) && Objects.equals(totalRefunds, that.totalRefunds) && Objects.equals(totalRefundCount, that.totalRefundCount);
|
||||
return Objects.equals(totalRevenue, that.totalRevenue) && Objects.equals(totalSales, that.totalSales) && Objects.equals(totalRefunds, that.totalRefunds) && Objects.equals(totalRefundCount, that.totalRefundCount) && Objects.equals(totalItemsSold, that.totalItemsSold);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(totalRevenue, totalSales, totalRefunds, totalRefundCount);
|
||||
return Objects.hash(totalRevenue, totalSales, totalRefunds, totalRefundCount, totalItemsSold);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -143,10 +175,69 @@ public class DashboardResponse {
|
||||
", totalSales=" + totalSales +
|
||||
", totalRefunds=" + totalRefunds +
|
||||
", totalRefundCount=" + totalRefundCount +
|
||||
", totalItemsSold=" + totalItemsSold +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public static class PaymentMethodData {
|
||||
private String paymentMethod;
|
||||
private Long count;
|
||||
|
||||
public PaymentMethodData() {
|
||||
}
|
||||
|
||||
public PaymentMethodData(String paymentMethod, Long count) {
|
||||
this.paymentMethod = paymentMethod;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public String getPaymentMethod() {
|
||||
return paymentMethod;
|
||||
}
|
||||
|
||||
public void setPaymentMethod(String paymentMethod) {
|
||||
this.paymentMethod = paymentMethod;
|
||||
}
|
||||
|
||||
public Long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Long count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EmployeePerformanceData {
|
||||
private String employeeName;
|
||||
private BigDecimal revenue;
|
||||
|
||||
public EmployeePerformanceData() {
|
||||
}
|
||||
|
||||
public EmployeePerformanceData(String employeeName, BigDecimal revenue) {
|
||||
this.employeeName = employeeName;
|
||||
this.revenue = revenue;
|
||||
}
|
||||
|
||||
public String getEmployeeName() {
|
||||
return employeeName;
|
||||
}
|
||||
|
||||
public void setEmployeeName(String employeeName) {
|
||||
this.employeeName = employeeName;
|
||||
}
|
||||
|
||||
public BigDecimal getRevenue() {
|
||||
return revenue;
|
||||
}
|
||||
|
||||
public void setRevenue(BigDecimal revenue) {
|
||||
this.revenue = revenue;
|
||||
}
|
||||
}
|
||||
|
||||
public static class InventorySummary {
|
||||
private Long totalProducts;
|
||||
private Long lowStockProducts;
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.petshop.backend.dto.appointment;
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class AppointmentRequest {
|
||||
@@ -26,8 +24,9 @@ public class AppointmentRequest {
|
||||
@NotNull(message = "Appointment status is required")
|
||||
private String appointmentStatus;
|
||||
|
||||
@NotEmpty(message = "At least one pet must be specified")
|
||||
private List<Long> petIds;
|
||||
private Long petId;
|
||||
|
||||
private Long employeeId;
|
||||
|
||||
// @NotNull(message = "Employee ID is required")
|
||||
private Long employeeId;
|
||||
@@ -80,12 +79,20 @@ 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 void setPetId(Long petId) {
|
||||
this.petId = petId;
|
||||
}
|
||||
|
||||
public Long getEmployeeId() {
|
||||
return employeeId;
|
||||
}
|
||||
|
||||
public void setEmployeeId(Long employeeId) {
|
||||
this.employeeId = employeeId;
|
||||
}
|
||||
|
||||
public Long getEmployeeId() {
|
||||
@@ -107,12 +114,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(petId, that.petId) &&
|
||||
Objects.equals(employeeId, that.employeeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(customerId, storeId, serviceId, appointmentDate, appointmentTime, appointmentStatus, petIds);
|
||||
return Objects.hash(customerId, storeId, serviceId, appointmentDate, appointmentTime, appointmentStatus, petId, employeeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -124,7 +132,8 @@ public class AppointmentRequest {
|
||||
", appointmentDate=" + appointmentDate +
|
||||
", appointmentTime=" + appointmentTime +
|
||||
", appointmentStatus='" + appointmentStatus + '\'' +
|
||||
", petIds=" + petIds +
|
||||
", petId=" + petId +
|
||||
", employeeId=" + employeeId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +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 {
|
||||
private Long appointmentId;
|
||||
@@ -19,8 +17,8 @@ public class AppointmentResponse {
|
||||
private LocalDate appointmentDate;
|
||||
private LocalTime appointmentTime;
|
||||
private String appointmentStatus;
|
||||
private List<String> petNames;
|
||||
private List<Long> petIds;
|
||||
private String petName;
|
||||
private Long petId;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@@ -30,8 +28,8 @@ public class 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, Long employeeId, String employeeName) {
|
||||
String petName, Long petId, LocalDateTime createdAt, LocalDateTime updatedAt,
|
||||
Long employeeId, String employeeName) {
|
||||
this.appointmentId = appointmentId;
|
||||
this.customerId = customerId;
|
||||
this.customerName = customerName;
|
||||
@@ -42,170 +40,59 @@ 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;
|
||||
this.employeeId = employeeId;
|
||||
this.employeeName = employeeName;
|
||||
}
|
||||
public Long getAppointmentId() {
|
||||
return appointmentId;
|
||||
}
|
||||
|
||||
public void setAppointmentId(Long appointmentId) {
|
||||
this.appointmentId = appointmentId;
|
||||
}
|
||||
public Long getAppointmentId() { return appointmentId; }
|
||||
public void setAppointmentId(Long appointmentId) { this.appointmentId = appointmentId; }
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
public Long getCustomerId() { return customerId; }
|
||||
public void setCustomerId(Long customerId) { this.customerId = customerId; }
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
public String getCustomerName() { return customerName; }
|
||||
public void setCustomerName(String customerName) { this.customerName = customerName; }
|
||||
|
||||
public String getCustomerName() {
|
||||
return customerName;
|
||||
}
|
||||
public Long getStoreId() { return storeId; }
|
||||
public void setStoreId(Long storeId) { this.storeId = storeId; }
|
||||
|
||||
public void setCustomerName(String customerName) {
|
||||
this.customerName = customerName;
|
||||
}
|
||||
public String getStoreName() { return storeName; }
|
||||
public void setStoreName(String storeName) { this.storeName = storeName; }
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
public Long getServiceId() { return serviceId; }
|
||||
public void setServiceId(Long serviceId) { this.serviceId = serviceId; }
|
||||
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
public String getServiceName() { return serviceName; }
|
||||
public void setServiceName(String serviceName) { this.serviceName = serviceName; }
|
||||
|
||||
public String getStoreName() {
|
||||
return storeName;
|
||||
}
|
||||
public Long getEmployeeId() { return employeeId; }
|
||||
public void setEmployeeId(Long employeeId) { this.employeeId = employeeId; }
|
||||
|
||||
public void setStoreName(String storeName) {
|
||||
this.storeName = storeName;
|
||||
}
|
||||
public String getEmployeeName() { return employeeName; }
|
||||
public void setEmployeeName(String employeeName) { this.employeeName = employeeName; }
|
||||
|
||||
public Long getServiceId() {
|
||||
return serviceId;
|
||||
}
|
||||
public LocalDate getAppointmentDate() { return appointmentDate; }
|
||||
public void setAppointmentDate(LocalDate appointmentDate) { this.appointmentDate = appointmentDate; }
|
||||
|
||||
public void setServiceId(Long serviceId) {
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
public LocalTime getAppointmentTime() { return appointmentTime; }
|
||||
public void setAppointmentTime(LocalTime appointmentTime) { this.appointmentTime = appointmentTime; }
|
||||
|
||||
public String getServiceName() {
|
||||
return serviceName;
|
||||
}
|
||||
public String getAppointmentStatus() { return appointmentStatus; }
|
||||
public void setAppointmentStatus(String appointmentStatus) { this.appointmentStatus = appointmentStatus; }
|
||||
|
||||
public void setServiceName(String serviceName) {
|
||||
this.serviceName = serviceName;
|
||||
}
|
||||
public String getPetName() { return petName; }
|
||||
public void setPetName(String petName) { this.petName = petName; }
|
||||
|
||||
public Long getPetId() { return petId; }
|
||||
public void setPetId(Long petId) { this.petId = petId; }
|
||||
|
||||
public String getEmployeeName() {
|
||||
return employeeName;
|
||||
}
|
||||
public void setEmployeeName(String employeeName) {
|
||||
this.employeeName = employeeName;
|
||||
}
|
||||
public LocalDateTime getCreatedAt() { return createdAt; }
|
||||
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
|
||||
|
||||
public LocalDate getAppointmentDate() {
|
||||
return appointmentDate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void setAppointmentDate(LocalDate appointmentDate) {
|
||||
this.appointmentDate = appointmentDate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public LocalTime getAppointmentTime() {
|
||||
return appointmentTime;
|
||||
}
|
||||
|
||||
public void setAppointmentTime(LocalTime appointmentTime) {
|
||||
this.appointmentTime = appointmentTime;
|
||||
}
|
||||
|
||||
public String getAppointmentStatus() {
|
||||
return appointmentStatus;
|
||||
}
|
||||
|
||||
public void setAppointmentStatus(String appointmentStatus) {
|
||||
this.appointmentStatus = appointmentStatus;
|
||||
}
|
||||
|
||||
public List<String> getPetNames() {
|
||||
return petNames;
|
||||
}
|
||||
|
||||
public void setPetNames(List<String> petNames) {
|
||||
this.petNames = petNames;
|
||||
}
|
||||
|
||||
public List<Long> getPetIds() {
|
||||
return petIds;
|
||||
}
|
||||
|
||||
public void setPetIds(List<Long> petIds) {
|
||||
this.petIds = petIds;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(appointmentId, customerId, customerName, storeId, storeName, serviceId, serviceName, appointmentDate, appointmentTime, appointmentStatus, petNames, petIds, createdAt, updatedAt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AppointmentResponse{" +
|
||||
"appointmentId=" + appointmentId +
|
||||
", customerId=" + customerId +
|
||||
", customerName='" + customerName + '\'' +
|
||||
", storeId=" + storeId +
|
||||
", storeName='" + storeName + '\'' +
|
||||
", serviceId=" + serviceId +
|
||||
", serviceName='" + serviceName + '\'' +
|
||||
", appointmentDate=" + appointmentDate +
|
||||
", appointmentTime=" + appointmentTime +
|
||||
", appointmentStatus='" + appointmentStatus + '\'' +
|
||||
", petNames=" + petNames +
|
||||
", petIds=" + petIds +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
'}';
|
||||
}
|
||||
public LocalDateTime getUpdatedAt() { return updatedAt; }
|
||||
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
|
||||
}
|
||||
|
||||
@@ -10,13 +10,14 @@ public class UserInfoResponse {
|
||||
private String phone;
|
||||
private String avatarUrl;
|
||||
private String role;
|
||||
private Long customerId;
|
||||
private Long storeId;
|
||||
private String storeName;
|
||||
|
||||
public UserInfoResponse() {
|
||||
}
|
||||
|
||||
public UserInfoResponse(Long id, String username, String email, String fullName, String phone, String avatarUrl, String role, Long storeId, String storeName) {
|
||||
public UserInfoResponse(Long id, String username, String email, String fullName, String phone, String avatarUrl, String role, Long customerId, Long storeId, String storeName) {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.email = email;
|
||||
@@ -24,6 +25,7 @@ public class UserInfoResponse {
|
||||
this.phone = phone;
|
||||
this.avatarUrl = avatarUrl;
|
||||
this.role = role;
|
||||
this.customerId = customerId;
|
||||
this.storeId = storeId;
|
||||
this.storeName = storeName;
|
||||
}
|
||||
@@ -84,6 +86,15 @@ public class UserInfoResponse {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
@@ -112,13 +123,14 @@ public class UserInfoResponse {
|
||||
Objects.equals(phone, that.phone) &&
|
||||
Objects.equals(avatarUrl, that.avatarUrl) &&
|
||||
Objects.equals(role, that.role) &&
|
||||
Objects.equals(customerId, that.customerId) &&
|
||||
Objects.equals(storeId, that.storeId) &&
|
||||
Objects.equals(storeName, that.storeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, username, email, fullName, phone, avatarUrl, role, storeId, storeName);
|
||||
return Objects.hash(id, username, email, fullName, phone, avatarUrl, role, customerId, storeId, storeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,6 +143,7 @@ public class UserInfoResponse {
|
||||
", phone='" + phone + '\'' +
|
||||
", avatarUrl='" + avatarUrl + '\'' +
|
||||
", role='" + role + '\'' +
|
||||
", customerId=" + customerId +
|
||||
", storeId=" + storeId +
|
||||
", storeName='" + storeName + '\'' +
|
||||
'}';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.petshop.backend.dto.chat;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
|
||||
public class UpdateConversationRequest {
|
||||
@NotBlank(message = "Status is required")
|
||||
@Pattern(regexp = "^(OPEN|CLOSED)$", message = "Status must be OPEN or CLOSED")
|
||||
private String status;
|
||||
|
||||
public UpdateConversationRequest() {
|
||||
}
|
||||
|
||||
public UpdateConversationRequest(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
@@ -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,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 +
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.petshop.backend.dto.pet;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
public class MyPetRequest {
|
||||
|
||||
@NotBlank(message = "Pet name is required")
|
||||
@Size(max = 50, message = "Pet name must not exceed 50 characters")
|
||||
private String petName;
|
||||
|
||||
@NotBlank(message = "Species is required")
|
||||
@Size(max = 50, message = "Species must not exceed 50 characters")
|
||||
private String species;
|
||||
|
||||
@Size(max = 50, message = "Breed must not exceed 50 characters")
|
||||
private String breed;
|
||||
|
||||
public String getPetName() {
|
||||
return petName;
|
||||
}
|
||||
|
||||
public void setPetName(String petName) {
|
||||
this.petName = petName;
|
||||
}
|
||||
|
||||
public String getSpecies() {
|
||||
return species;
|
||||
}
|
||||
|
||||
public void setSpecies(String species) {
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
public String getBreed() {
|
||||
return breed;
|
||||
}
|
||||
|
||||
public void setBreed(String breed) {
|
||||
this.breed = breed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.petshop.backend.dto.pet;
|
||||
|
||||
public class MyPetResponse {
|
||||
|
||||
private Long customerPetId;
|
||||
private String petName;
|
||||
private String species;
|
||||
private String breed;
|
||||
private String imageUrl;
|
||||
|
||||
public MyPetResponse() {
|
||||
}
|
||||
|
||||
public MyPetResponse(Long customerPetId, String petName, String species, String breed, String imageUrl) {
|
||||
this.customerPetId = customerPetId;
|
||||
this.petName = petName;
|
||||
this.species = species;
|
||||
this.breed = breed;
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public Long getCustomerPetId() {
|
||||
return customerPetId;
|
||||
}
|
||||
|
||||
public void setCustomerPetId(Long customerPetId) {
|
||||
this.customerPetId = customerPetId;
|
||||
}
|
||||
|
||||
public String getPetName() {
|
||||
return petName;
|
||||
}
|
||||
|
||||
public void setPetName(String petName) {
|
||||
this.petName = petName;
|
||||
}
|
||||
|
||||
public String getSpecies() {
|
||||
return species;
|
||||
}
|
||||
|
||||
public void setSpecies(String species) {
|
||||
this.species = species;
|
||||
}
|
||||
|
||||
public String getBreed() {
|
||||
return breed;
|
||||
}
|
||||
|
||||
public void setBreed(String breed) {
|
||||
this.breed = breed;
|
||||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,10 @@ public class PetRequest {
|
||||
|
||||
private BigDecimal petPrice;
|
||||
|
||||
private Long customerId;
|
||||
|
||||
private Long storeId;
|
||||
|
||||
public String getPetName() {
|
||||
return petName;
|
||||
}
|
||||
@@ -71,6 +75,22 @@ public class PetRequest {
|
||||
this.petPrice = petPrice;
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public Long getStoreId() {
|
||||
return storeId;
|
||||
}
|
||||
|
||||
public void setStoreId(Long storeId) {
|
||||
this.storeId = storeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
@@ -15,11 +15,15 @@ public class PetResponse {
|
||||
private String imageUrl;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
private Long customerId;
|
||||
private String customerName;
|
||||
private Long storeId;
|
||||
private String storeName;
|
||||
|
||||
public PetResponse() {
|
||||
}
|
||||
|
||||
public PetResponse(Long petId, String petName, String petSpecies, String petBreed, Integer petAge, String petStatus, BigDecimal petPrice, String imageUrl, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public PetResponse(Long petId, String petName, String petSpecies, String petBreed, Integer petAge, String petStatus, BigDecimal petPrice, String imageUrl, LocalDateTime createdAt, LocalDateTime updatedAt, Long customerId, String customerName, Long storeId, String storeName) {
|
||||
this.petId = petId;
|
||||
this.petName = petName;
|
||||
this.petSpecies = petSpecies;
|
||||
@@ -30,6 +34,10 @@ public class PetResponse {
|
||||
this.imageUrl = imageUrl;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
this.customerId = customerId;
|
||||
this.customerName = customerName;
|
||||
this.storeId = storeId;
|
||||
this.storeName = storeName;
|
||||
}
|
||||
|
||||
public Long getPetId() {
|
||||
@@ -112,17 +120,49 @@ public class PetResponse {
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Long getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(Long customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public String getCustomerName() {
|
||||
return customerName;
|
||||
}
|
||||
|
||||
public void setCustomerName(String customerName) {
|
||||
this.customerName = customerName;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
PetResponse that = (PetResponse) o;
|
||||
return Objects.equals(petId, that.petId) && Objects.equals(petName, that.petName) && Objects.equals(petSpecies, that.petSpecies) && Objects.equals(petBreed, that.petBreed) && Objects.equals(petAge, that.petAge) && Objects.equals(petStatus, that.petStatus) && Objects.equals(petPrice, that.petPrice) && Objects.equals(imageUrl, that.imageUrl) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt);
|
||||
return Objects.equals(petId, that.petId) && Objects.equals(petName, that.petName) && Objects.equals(petSpecies, that.petSpecies) && Objects.equals(petBreed, that.petBreed) && Objects.equals(petAge, that.petAge) && Objects.equals(petStatus, that.petStatus) && Objects.equals(petPrice, that.petPrice) && Objects.equals(imageUrl, that.imageUrl) && Objects.equals(createdAt, that.createdAt) && Objects.equals(updatedAt, that.updatedAt) && Objects.equals(customerId, that.customerId) && Objects.equals(customerName, that.customerName) && Objects.equals(storeId, that.storeId) && Objects.equals(storeName, that.storeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(petId, petName, petSpecies, petBreed, petAge, petStatus, petPrice, imageUrl, createdAt, updatedAt);
|
||||
return Objects.hash(petId, petName, petSpecies, petBreed, petAge, petStatus, petPrice, imageUrl, createdAt, updatedAt, customerId, customerName, storeId, storeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,6 +178,10 @@ public class PetResponse {
|
||||
", imageUrl='" + imageUrl + '\'' +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
", customerId=" + customerId +
|
||||
", customerName='" + customerName + '\'' +
|
||||
", storeId=" + storeId +
|
||||
", storeName='" + storeName + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 +
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.petshop.backend.dto.refund;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class RefundItemResponse {
|
||||
private Long id;
|
||||
private Long prodId;
|
||||
private String prodName;
|
||||
private Integer quantity;
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
public RefundItemResponse() {
|
||||
}
|
||||
|
||||
public RefundItemResponse(Long id, Long prodId, String prodName, Integer quantity, BigDecimal unitPrice) {
|
||||
this.id = id;
|
||||
this.prodId = prodId;
|
||||
this.prodName = prodName;
|
||||
this.quantity = quantity;
|
||||
this.unitPrice = unitPrice;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getProdId() {
|
||||
return prodId;
|
||||
}
|
||||
|
||||
public void setProdId(Long prodId) {
|
||||
this.prodId = prodId;
|
||||
}
|
||||
|
||||
public String getProdName() {
|
||||
return prodName;
|
||||
}
|
||||
|
||||
public void setProdName(String prodName) {
|
||||
this.prodName = prodName;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.petshop.backend.dto.refund;
|
||||
|
||||
import com.petshop.backend.dto.sale.SaleItemRequest;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RefundRequest {
|
||||
@@ -11,6 +15,10 @@ public class RefundRequest {
|
||||
@NotBlank(message = "Reason is required")
|
||||
private String reason;
|
||||
|
||||
@NotEmpty(message = "At least one item is required")
|
||||
@Valid
|
||||
private List<SaleItemRequest> items;
|
||||
|
||||
public Long getSaleId() {
|
||||
return saleId;
|
||||
}
|
||||
@@ -27,18 +35,27 @@ public class RefundRequest {
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
public List<SaleItemRequest> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<SaleItemRequest> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
RefundRequest that = (RefundRequest) o;
|
||||
return Objects.equals(saleId, that.saleId) &&
|
||||
Objects.equals(reason, that.reason);
|
||||
Objects.equals(reason, that.reason) &&
|
||||
Objects.equals(items, that.items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(saleId, reason);
|
||||
return Objects.hash(saleId, reason, items);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,6 +63,7 @@ public class RefundRequest {
|
||||
return "RefundRequest{" +
|
||||
"saleId=" + saleId +
|
||||
", reason='" + reason + '\'' +
|
||||
", items=" + items +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.petshop.backend.dto.refund;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class RefundResponse {
|
||||
@@ -11,22 +12,32 @@ public class RefundResponse {
|
||||
private BigDecimal amount;
|
||||
private String reason;
|
||||
private String status;
|
||||
private List<RefundItemResponse> items;
|
||||
private LocalDateTime createdAt;
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
public RefundResponse() {
|
||||
}
|
||||
|
||||
public RefundResponse(Long id, Long saleId, Long customerId, BigDecimal amount, String reason, String status, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
public RefundResponse(Long id, Long saleId, Long customerId, BigDecimal amount, String reason, String status, List<RefundItemResponse> items, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.id = id;
|
||||
this.saleId = saleId;
|
||||
this.customerId = customerId;
|
||||
this.amount = amount;
|
||||
this.reason = reason;
|
||||
this.status = status;
|
||||
this.items = items;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
// ...
|
||||
public List<RefundItemResponse> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<RefundItemResponse> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
|
||||
@@ -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,10 +22,15 @@ public class Adoption {
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "customerId", nullable = false)
|
||||
private Customer customer;
|
||||
private User customer;
|
||||
|
||||
@ManyToOne
|
||||
private Employee employee;
|
||||
@JoinColumn(name = "employeeId", nullable = false)
|
||||
private User employee;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "sourceStoreId")
|
||||
private StoreLocation sourceStore;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDate adoptionDate;
|
||||
@@ -45,16 +49,6 @@ public class Adoption {
|
||||
public Adoption() {
|
||||
}
|
||||
|
||||
public Adoption(Long adoptionId, Pet pet, Customer customer, LocalDate adoptionDate, String adoptionStatus, LocalDateTime createdAt, LocalDateTime updatedAt) {
|
||||
this.adoptionId = adoptionId;
|
||||
this.pet = pet;
|
||||
this.customer = customer;
|
||||
this.adoptionDate = adoptionDate;
|
||||
this.adoptionStatus = adoptionStatus;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Long getAdoptionId() {
|
||||
return adoptionId;
|
||||
}
|
||||
@@ -71,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;
|
||||
}
|
||||
@@ -136,15 +138,8 @@ public class Adoption {
|
||||
public String toString() {
|
||||
return "Adoption{" +
|
||||
"adoptionId=" + adoptionId +
|
||||
", pet=" + pet +
|
||||
", customer=" + customer +
|
||||
", adoptionDate=" + adoptionDate +
|
||||
", adoptionStatus='" + adoptionStatus + '\'' +
|
||||
", createdAt=" + createdAt +
|
||||
", updatedAt=" + updatedAt +
|
||||
", adoptionDate=" + adoptionDate +
|
||||
'}';
|
||||
}
|
||||
|
||||
public void setEmployeeName(String s) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -32,8 +30,8 @@ public class Appointment {
|
||||
private Service service;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "employeeId")
|
||||
private Employee employee;
|
||||
@JoinColumn(name = "employeeId", nullable = false)
|
||||
private User employee;
|
||||
|
||||
@Column(nullable = false)
|
||||
private LocalDate appointmentDate;
|
||||
@@ -44,13 +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<>();
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "petId")
|
||||
private Pet pet;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
@@ -63,19 +57,6 @@ public class Appointment {
|
||||
public Appointment() {
|
||||
}
|
||||
|
||||
public Appointment(Long appointmentId, Customer customer, StoreLocation store, Service service, 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.appointmentDate = appointmentDate;
|
||||
this.appointmentTime = appointmentTime;
|
||||
this.appointmentStatus = appointmentStatus;
|
||||
this.pets = pets;
|
||||
this.createdAt = createdAt;
|
||||
this.updatedAt = updatedAt;
|
||||
}
|
||||
|
||||
public Long getAppointmentId() {
|
||||
return appointmentId;
|
||||
}
|
||||
@@ -84,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;
|
||||
}
|
||||
|
||||
@@ -108,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;
|
||||
}
|
||||
|
||||
@@ -140,12 +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 void setPet(Pet pet) {
|
||||
this.pet = pet;
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
@@ -184,10 +165,11 @@ public class Appointment {
|
||||
", customer=" + customer +
|
||||
", store=" + store +
|
||||
", service=" + service +
|
||||
", employee=" + employee +
|
||||
", 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,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,21 +23,29 @@ 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 = "ownerUserId")
|
||||
private User owner;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "storeId")
|
||||
private StoreLocation store;
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
@@ -49,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;
|
||||
}
|
||||
@@ -126,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;
|
||||
}
|
||||
@@ -161,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;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import org.hibernate.annotations.UpdateTimestamp;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@@ -32,9 +34,30 @@ public class Refund {
|
||||
@Column(nullable = false, length = 20, columnDefinition = "VARCHAR(20)")
|
||||
private RefundStatus status;
|
||||
|
||||
@OneToMany(mappedBy = "refund", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
private List<RefundItem> items = new ArrayList<>();
|
||||
|
||||
@CreationTimestamp
|
||||
@Column(name = "created_at", updatable = false)
|
||||
private LocalDateTime createdAt;
|
||||
// ...
|
||||
public List<RefundItem> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(List<RefundItem> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public void addItem(RefundItem item) {
|
||||
items.add(item);
|
||||
item.setRefund(this);
|
||||
}
|
||||
|
||||
public void removeItem(RefundItem item) {
|
||||
items.remove(item);
|
||||
item.setRefund(null);
|
||||
}
|
||||
|
||||
@UpdateTimestamp
|
||||
@Column(name = "updated_at")
|
||||
|
||||
112
backend/src/main/java/com/petshop/backend/entity/RefundItem.java
Normal file
112
backend/src/main/java/com/petshop/backend/entity/RefundItem.java
Normal file
@@ -0,0 +1,112 @@
|
||||
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 = "refund_item")
|
||||
public class RefundItem {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "refund_id", nullable = false)
|
||||
private Refund refund;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "prod_id", nullable = false)
|
||||
private Product product;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Integer quantity;
|
||||
|
||||
@Column(name = "unit_price", 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 RefundItem() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Refund getRefund() {
|
||||
return refund;
|
||||
}
|
||||
|
||||
public void setRefund(Refund refund) {
|
||||
this.refund = refund;
|
||||
}
|
||||
|
||||
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;
|
||||
RefundItem that = (RefundItem) o;
|
||||
return Objects.equals(id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.petshop.backend.entity;
|
||||
|
||||
import com.petshop.backend.util.PhoneUtils;
|
||||
import jakarta.persistence.*;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
@@ -27,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;
|
||||
@@ -77,7 +81,7 @@ public class StoreLocation {
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
this.phone = PhoneUtils.normalize(phone);
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
@@ -88,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;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.petshop.backend.entity;
|
||||
|
||||
import com.petshop.backend.util.PhoneUtils;
|
||||
import jakarta.persistence.*;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
@@ -97,7 +98,7 @@ public class Supplier {
|
||||
}
|
||||
|
||||
public void setSupPhone(String supPhone) {
|
||||
this.supPhone = supPhone;
|
||||
this.supPhone = PhoneUtils.normalize(supPhone);
|
||||
}
|
||||
|
||||
public LocalDateTime getCreatedAt() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.petshop.backend.entity;
|
||||
|
||||
import com.petshop.backend.util.PhoneUtils;
|
||||
import jakarta.persistence.*;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.UpdateTimestamp;
|
||||
@@ -15,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;
|
||||
|
||||
@@ -37,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;
|
||||
|
||||
@@ -58,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;
|
||||
}
|
||||
@@ -105,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;
|
||||
}
|
||||
@@ -118,7 +136,7 @@ public class User {
|
||||
}
|
||||
|
||||
public void setPhone(String phone) {
|
||||
this.phone = phone;
|
||||
this.phone = PhoneUtils.normalize(phone);
|
||||
}
|
||||
|
||||
public String getAvatarUrl() {
|
||||
@@ -137,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;
|
||||
}
|
||||
@@ -187,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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.petshop.backend.exception;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -13,7 +14,10 @@ import java.time.LocalDateTime;
|
||||
@Component
|
||||
public class ApiErrorResponder {
|
||||
|
||||
private final ObjectMapper objectMapper = JsonMapper.builder().findAndAddModules().build();
|
||||
private final ObjectMapper objectMapper = JsonMapper.builder()
|
||||
.findAndAddModules()
|
||||
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
.build();
|
||||
|
||||
public void write(HttpServletResponse response, HttpStatus status, String message, String details, String path) throws IOException {
|
||||
response.setStatus(status.value());
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
package com.petshop.backend.exception;
|
||||
|
||||
import com.petshop.backend.service.PetService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.data.core.PropertyReferenceException;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
@@ -78,6 +82,26 @@ public class GlobalExceptionHandler {
|
||||
return buildErrorResponse(HttpStatus.valueOf(ex.getStatusCode().value()), message, ex, request);
|
||||
}
|
||||
|
||||
@ExceptionHandler(NoResourceFoundException.class)
|
||||
public ResponseEntity<ApiErrorResponse> handleNoResourceFound(NoResourceFoundException ex, HttpServletRequest request) {
|
||||
return buildErrorResponse(HttpStatus.NOT_FOUND, "Route not found", ex, request);
|
||||
}
|
||||
|
||||
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
|
||||
public ResponseEntity<ApiErrorResponse> handleMethodNotSupported(HttpRequestMethodNotSupportedException ex, HttpServletRequest request) {
|
||||
return buildErrorResponse(HttpStatus.METHOD_NOT_ALLOWED, ex.getMessage(), ex, request);
|
||||
}
|
||||
|
||||
@ExceptionHandler(PropertyReferenceException.class)
|
||||
public ResponseEntity<ApiErrorResponse> handleBadSortProperty(PropertyReferenceException ex, HttpServletRequest request) {
|
||||
return buildErrorResponse(HttpStatus.BAD_REQUEST, "Invalid sort field: " + ex.getPropertyName(), ex, request);
|
||||
}
|
||||
|
||||
@ExceptionHandler(PetService.ForbiddenImageAccessException.class)
|
||||
public ResponseEntity<ApiErrorResponse> handleForbiddenImageAccess(PetService.ForbiddenImageAccessException ex, HttpServletRequest request) {
|
||||
return buildErrorResponse(HttpStatus.FORBIDDEN, "Access to this pet image is not allowed", ex, request);
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<ApiErrorResponse> handleGenericException(Exception ex, HttpServletRequest request) {
|
||||
String message = ex.getMessage() == null || ex.getMessage().isBlank()
|
||||
|
||||
@@ -8,24 +8,33 @@ import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface AdoptionRepository extends JpaRepository<Adoption, Long> {
|
||||
|
||||
@Query("SELECT a FROM Adoption a WHERE " +
|
||||
"(:q IS NULL OR (" +
|
||||
"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, '%'))")
|
||||
Page<Adoption> searchAdoptions(@Param("q") String query, Pageable pageable);
|
||||
|
||||
Page<Adoption> findByCustomerCustomerId(Long customerId, Pageable pageable);
|
||||
|
||||
@Query("SELECT a FROM Adoption a WHERE a.customer.customerId = :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, '%')))")
|
||||
Page<Adoption> searchAdoptionsByCustomer(@Param("customerId") Long customerId, @Param("q") String query, Pageable pageable);
|
||||
"LOWER(a.pet.petName) LIKE LOWER(CONCAT('%', :q, '%'))" +
|
||||
")) AND " +
|
||||
"(:customerId IS NULL OR a.customer.id = :customerId) AND " +
|
||||
"(:status IS NULL OR LOWER(a.adoptionStatus) = LOWER(:status)) AND " +
|
||||
"(:storeId IS NULL OR a.sourceStore.storeId = :storeId) AND " +
|
||||
"(:date IS NULL OR a.adoptionDate = :date)")
|
||||
Page<Adoption> searchAdoptions(
|
||||
@Param("q") String query,
|
||||
@Param("customerId") Long customerId,
|
||||
@Param("status") String status,
|
||||
@Param("storeId") Long storeId,
|
||||
@Param("date") LocalDate date,
|
||||
Pageable pageable);
|
||||
|
||||
Optional<Adoption> findFirstByPet_IdAndAdoptionStatusOrderByAdoptionDateDesc(Long petId, String adoptionStatus);
|
||||
|
||||
boolean existsByPet_IdAndAdoptionStatusIgnoreCaseAndAdoptionIdNot(Long petId, String adoptionStatus, Long adoptionId);
|
||||
|
||||
boolean existsByPet_IdAndAdoptionStatusIgnoreCase(Long petId, String adoptionStatus);
|
||||
}
|
||||
|
||||
@@ -18,22 +18,33 @@ public interface AppointmentRepository extends JpaRepository<Appointment, Long>
|
||||
@Query("SELECT a FROM Appointment a WHERE a.appointmentDate = :date AND a.appointmentTime = :time")
|
||||
List<Appointment> findByDateAndTime(@Param("date") LocalDate date, @Param("time") LocalTime time);
|
||||
|
||||
@Query("SELECT a FROM Appointment a JOIN FETCH a.service WHERE a.store.storeId = :storeId AND a.appointmentDate = :date AND LOWER(a.appointmentStatus) <> 'cancelled'")
|
||||
@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 " +
|
||||
"(:q IS NULL OR (" +
|
||||
"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);
|
||||
"LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%'))" +
|
||||
")) AND " +
|
||||
"(:customerId IS NULL OR a.customer.id = :customerId) AND " +
|
||||
"(:employeeId IS NULL OR a.employee.id = :employeeId) AND " +
|
||||
"(:storeId IS NULL OR a.store.storeId = :storeId) AND " +
|
||||
"(:status IS NULL OR LOWER(a.appointmentStatus) = LOWER(:status)) AND " +
|
||||
"(:date IS NULL OR a.appointmentDate = :date)")
|
||||
Page<Appointment> searchAppointments(
|
||||
@Param("q") String query,
|
||||
@Param("customerId") Long customerId,
|
||||
@Param("employeeId") Long employeeId,
|
||||
@Param("storeId") Long storeId,
|
||||
@Param("status") String status,
|
||||
@Param("date") LocalDate date,
|
||||
Pageable pageable);
|
||||
|
||||
Page<Appointment> findByCustomerCustomerId(Long customerId, Pageable pageable);
|
||||
@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 DISTINCT a FROM Appointment a LEFT JOIN a.pets p WHERE a.customer.customerId = :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.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);
|
||||
}
|
||||
@@ -16,7 +16,7 @@ public interface CategoryRepository extends JpaRepository<Category, Long> {
|
||||
Optional<Category> findByCategoryName(String categoryName);
|
||||
|
||||
@Query("SELECT c FROM Category c WHERE " +
|
||||
"LOWER(c.categoryName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(c.categoryType) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
Page<Category> searchCategories(@Param("q") String query, Pageable pageable);
|
||||
"(:q IS NULL OR LOWER(c.categoryName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(c.categoryType) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
|
||||
"(:type IS NULL OR LOWER(c.categoryType) = LOWER(:type))")
|
||||
Page<Category> searchCategories(@Param("q") String query, @Param("type") String type, Pageable pageable);
|
||||
}
|
||||
|
||||
@@ -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,26 +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 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,28 +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);
|
||||
|
||||
@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,12 +0,0 @@
|
||||
package com.petshop.backend.repository;
|
||||
|
||||
import com.petshop.backend.entity.EmployeeStore;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface EmployeeStoreRepository extends JpaRepository<EmployeeStore, EmployeeStore.EmployeeStoreId> {
|
||||
Optional<EmployeeStore> findByEmployeeEmployeeId(Long employeeId);
|
||||
}
|
||||
@@ -16,8 +16,14 @@ 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 " +
|
||||
"(:q IS NULL OR (" +
|
||||
"LOWER(i.product.prodName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(i.product.category.categoryName) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
Page<Inventory> searchInventory(@Param("q") String query, Pageable pageable);
|
||||
"LOWER(i.product.category.categoryName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(s.storeName) LIKE LOWER(CONCAT('%', :q, '%')))) AND " +
|
||||
"(:storeId IS NULL OR i.store.storeId = :storeId)")
|
||||
Page<Inventory> searchInventory(@Param("q") String query, @Param("storeId") Long storeId, Pageable pageable);
|
||||
}
|
||||
|
||||
@@ -8,12 +8,33 @@ 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 PetRepository extends JpaRepository<Pet, Long> {
|
||||
|
||||
List<Pet> findAllByPetStatusIgnoreCaseOrderByPetNameAsc(String petStatus);
|
||||
List<Pet> findAllByOwner_IdOrderByPetNameAsc(Long ownerId);
|
||||
Optional<Pet> findByIdAndOwner_Id(Long id, Long ownerId);
|
||||
|
||||
@Query("SELECT p FROM Pet p WHERE " +
|
||||
"LOWER(p.petName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(p.petSpecies) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(p.petBreed) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
Page<Pet> searchPets(@Param("q") String query, Pageable pageable);
|
||||
"(: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(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.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);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.springframework.stereotype.Repository;
|
||||
public interface ProductRepository extends JpaRepository<Product, Long> {
|
||||
|
||||
@Query("SELECT p FROM Product p WHERE " +
|
||||
"LOWER(p.prodName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(p.prodDesc) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
Page<Product> searchProducts(@Param("q") String query, Pageable pageable);
|
||||
"(:q IS NULL OR LOWER(p.prodName) LIKE LOWER(CONCAT('%', :q, '%')) OR LOWER(COALESCE(p.prodDesc, '')) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
|
||||
"(:categoryId IS NULL OR p.category.categoryId = :categoryId)")
|
||||
Page<Product> searchProducts(@Param("q") String query, @Param("categoryId") Long categoryId, Pageable pageable);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,13 @@ import org.springframework.stereotype.Repository;
|
||||
public interface ProductSupplierRepository extends JpaRepository<ProductSupplier, ProductSupplier.ProductSupplierId> {
|
||||
|
||||
@Query("SELECT ps FROM ProductSupplier ps WHERE " +
|
||||
"LOWER(ps.product.prodName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(ps.supplier.supCompany) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
Page<ProductSupplier> searchProductSuppliers(@Param("q") String query, Pageable pageable);
|
||||
"(:q IS NULL OR (LOWER(ps.product.prodName) LIKE LOWER(CONCAT('%', :q, '%')) OR " +
|
||||
"LOWER(ps.supplier.supCompany) LIKE LOWER(CONCAT('%', :q, '%')))) AND " +
|
||||
"(:productId IS NULL OR ps.product.prodId = :productId) AND " +
|
||||
"(:supplierId IS NULL OR ps.supplier.supId = :supplierId)")
|
||||
Page<ProductSupplier> searchProductSuppliers(
|
||||
@Param("q") String query,
|
||||
@Param("productId") Long productId,
|
||||
@Param("supplierId") Long supplierId,
|
||||
Pageable pageable);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.springframework.stereotype.Repository;
|
||||
public interface PurchaseOrderRepository extends JpaRepository<PurchaseOrder, Long> {
|
||||
|
||||
@Query("SELECT po FROM PurchaseOrder po WHERE " +
|
||||
"LOWER(po.supplier.supCompany) LIKE LOWER(CONCAT('%', :q, '%'))")
|
||||
Page<PurchaseOrder> searchPurchaseOrders(@Param("q") String query, Pageable pageable);
|
||||
"(:q IS NULL OR LOWER(po.supplier.supCompany) LIKE LOWER(CONCAT('%', :q, '%'))) AND " +
|
||||
"(:storeId IS NULL OR po.store.storeId = :storeId)")
|
||||
Page<PurchaseOrder> searchPurchaseOrders(@Param("q") String query, @Param("storeId") Long storeId, 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, '%')))")
|
||||
|
||||
@@ -17,6 +17,11 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@@ -28,12 +33,10 @@ public class SecurityConfig {
|
||||
private final RestAuthenticationEntryPoint restAuthenticationEntryPoint;
|
||||
private final RestAccessDeniedHandler restAccessDeniedHandler;
|
||||
|
||||
public SecurityConfig(
|
||||
JwtAuthenticationFilter jwtAuthFilter,
|
||||
public SecurityConfig(JwtAuthenticationFilter jwtAuthFilter,
|
||||
UserDetailsService userDetailsService,
|
||||
RestAuthenticationEntryPoint restAuthenticationEntryPoint,
|
||||
RestAccessDeniedHandler restAccessDeniedHandler
|
||||
) {
|
||||
RestAccessDeniedHandler restAccessDeniedHandler) {
|
||||
this.jwtAuthFilter = jwtAuthFilter;
|
||||
this.userDetailsService = userDetailsService;
|
||||
this.restAuthenticationEntryPoint = restAuthenticationEntryPoint;
|
||||
@@ -42,7 +45,7 @@ public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
http.cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/api/v1/auth/login", "/api/v1/auth/register").permitAll()
|
||||
@@ -56,8 +59,7 @@ public class SecurityConfig {
|
||||
.requestMatchers(HttpMethod.GET, "/api/v1/appointments/availability").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.exceptionHandling(ex -> ex
|
||||
.authenticationEntryPoint(restAuthenticationEntryPoint)
|
||||
.exceptionHandling(ex -> ex.authenticationEntryPoint(restAuthenticationEntryPoint)
|
||||
.accessDeniedHandler(restAccessDeniedHandler)
|
||||
)
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
@@ -70,16 +72,32 @@ public class SecurityConfig {
|
||||
private DaoAuthenticationProvider daoAuthenticationProvider() {
|
||||
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(userDetailsService);
|
||||
authProvider.setPasswordEncoder(passwordEncoder());
|
||||
|
||||
return authProvider;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||
|
||||
return new ProviderManager(daoAuthenticationProvider());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CorsConfigurationSource corsConfigurationSource() {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
config.setAllowedOriginPatterns(List.of("http://localhost:*", "http://127.0.0.1:*"));
|
||||
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
|
||||
config.setAllowedHeaders(List.of("*"));
|
||||
config.setAllowCredentials(true);
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,52 +4,54 @@ 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.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;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.petshop.backend.repository.EmployeeRepository;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Service
|
||||
public class AdoptionService {
|
||||
|
||||
private static final String ADOPTION_STATUS_PENDING = "Pending";
|
||||
private static final String ADOPTION_STATUS_COMPLETED = "Completed";
|
||||
private static final String ADOPTION_STATUS_CANCELLED = "Cancelled";
|
||||
private static final String PET_STATUS_AVAILABLE = "Available";
|
||||
private static final String PET_STATUS_ADOPTED = "Adopted";
|
||||
|
||||
private final AdoptionRepository adoptionRepository;
|
||||
private final PetRepository petRepository;
|
||||
private final CustomerRepository customerRepository;
|
||||
private final EmployeeRepository employeeRepository;
|
||||
private Adoption response;
|
||||
private final UserRepository userRepository;
|
||||
private final StoreRepository storeRepository;
|
||||
|
||||
public AdoptionService(AdoptionRepository adoptionRepository, PetRepository petRepository, CustomerRepository customerRepository, EmployeeRepository employeeRepository) {
|
||||
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) {
|
||||
Page<Adoption> adoptions;
|
||||
public Page<AdoptionResponse> getAllAdoptions(String query, Long customerId, String status, Long storeId, LocalDate date, Pageable pageable) {
|
||||
String normalizedQuery = normalizeFilter(query);
|
||||
String normalizedStatus = normalizeFilter(status);
|
||||
|
||||
if (customerId != null) {
|
||||
if (query != null && !query.trim().isEmpty()) {
|
||||
adoptions = adoptionRepository.searchAdoptionsByCustomer(customerId, query, pageable);
|
||||
} else {
|
||||
adoptions = adoptionRepository.findByCustomerCustomerId(customerId, pageable);
|
||||
}
|
||||
} else {
|
||||
if (query != null && !query.trim().isEmpty()) {
|
||||
adoptions = adoptionRepository.searchAdoptions(query, pageable);
|
||||
} else {
|
||||
adoptions = adoptionRepository.findAll(pageable);
|
||||
}
|
||||
}
|
||||
Page<Adoption> adoptions = adoptionRepository.searchAdoptions(
|
||||
normalizedQuery,
|
||||
customerId,
|
||||
normalizedStatus,
|
||||
storeId,
|
||||
date,
|
||||
pageable
|
||||
);
|
||||
|
||||
return adoptions.map(this::mapToResponse);
|
||||
}
|
||||
@@ -58,7 +60,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");
|
||||
}
|
||||
|
||||
@@ -70,17 +72,26 @@ 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()));
|
||||
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);
|
||||
|
||||
Adoption adoption = new Adoption();
|
||||
adoption.setPet(pet);
|
||||
adoption.setCustomer(customer);
|
||||
adoption.setEmployee(employee);
|
||||
adoption.setSourceStore(sourceStore);
|
||||
adoption.setAdoptionDate(request.getAdoptionDate());
|
||||
adoption.setAdoptionStatus(request.getAdoptionStatus());
|
||||
|
||||
adoption.setAdoptionStatus(adoptionStatus);
|
||||
|
||||
adoption = adoptionRepository.save(adoption);
|
||||
syncPetStatus(pet, adoptionStatus, adoption.getAdoptionId());
|
||||
return mapToResponse(adoption);
|
||||
}
|
||||
|
||||
@@ -92,20 +103,25 @@ 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()));
|
||||
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(request.getAdoptionStatus());
|
||||
if (request.getEmployeeId() != null) {
|
||||
Employee employee = employeeRepository.findById(request.getEmployeeId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Employee not found with id: " + request.getEmployeeId()));
|
||||
adoption.setEmployee(employee);
|
||||
}
|
||||
adoption.setAdoptionStatus(adoptionStatus);
|
||||
|
||||
adoption = adoptionRepository.save(adoption);
|
||||
syncPetStatus(pet, adoptionStatus, adoption.getAdoptionId());
|
||||
return mapToResponse(adoption);
|
||||
}
|
||||
|
||||
@@ -122,28 +138,90 @@ public class AdoptionService {
|
||||
adoptionRepository.deleteAllById(request.getIds());
|
||||
}
|
||||
|
||||
private AdoptionResponse mapToResponse(Adoption adoption) {
|
||||
AdoptionResponse response = new AdoptionResponse(
|
||||
adoption.getAdoptionId(),
|
||||
adoption.getPet().getPetId(),
|
||||
adoption.getPet().getPetName(),
|
||||
adoption.getCustomer().getCustomerId(),
|
||||
adoption.getCustomer().getFirstName() + " " + adoption.getCustomer().getLastName(),
|
||||
adoption.getAdoptionDate(),
|
||||
adoption.getAdoptionStatus(),
|
||||
adoption.getPet().getPetPrice(),
|
||||
adoption.getCreatedAt(),
|
||||
adoption.getUpdatedAt()
|
||||
);
|
||||
// Add employee name
|
||||
if (adoption.getEmployee() != null) {
|
||||
response.setEmployeeId(adoption.getEmployee().getEmployeeId());
|
||||
response.setEmployeeName(
|
||||
adoption.getEmployee().getFirstName() + " " +
|
||||
adoption.getEmployee().getLastName());
|
||||
} else {
|
||||
response.setEmployeeName("Unassigned");
|
||||
private String normalizeFilter(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return response;
|
||||
String trimmed = value.trim();
|
||||
return trimmed.isEmpty() ? null : trimmed;
|
||||
}
|
||||
|
||||
private AdoptionResponse mapToResponse(Adoption adoption) {
|
||||
StoreLocation sourceStore = adoption.getSourceStore();
|
||||
return new AdoptionResponse(
|
||||
adoption.getAdoptionId(),
|
||||
adoption.getPet().getPetId(),
|
||||
adoption.getPet().getPetName(),
|
||||
adoption.getCustomer().getId(),
|
||||
adoption.getCustomer().getFirstName() + " " + adoption.getCustomer().getLastName(),
|
||||
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(),
|
||||
adoption.getCreatedAt(),
|
||||
adoption.getUpdatedAt()
|
||||
);
|
||||
}
|
||||
|
||||
private User resolveAdoptionEmployee(Long requestedEmployeeId) {
|
||||
if (requestedEmployeeId != null) {
|
||||
User employee = userRepository.findById(requestedEmployeeId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + requestedEmployeeId));
|
||||
if (!isAssignableUser(employee)) {
|
||||
throw new IllegalArgumentException("Selected employee is not assignable for adoption work");
|
||||
}
|
||||
return employee;
|
||||
}
|
||||
|
||||
return userRepository.findFirstByRoleAndActiveTrueOrderByIdAsc(User.Role.STAFF)
|
||||
.orElseThrow(() -> new IllegalArgumentException("No assignable staff member is available for adoption assignment"));
|
||||
}
|
||||
|
||||
private boolean isAssignableUser(User user) {
|
||||
return user.getRole() == User.Role.STAFF && Boolean.TRUE.equals(user.getActive());
|
||||
}
|
||||
|
||||
private String normalizeAdoptionStatus(String adoptionStatus) {
|
||||
if (adoptionStatus == null) {
|
||||
throw new IllegalArgumentException("Adoption status is required");
|
||||
}
|
||||
String trimmedStatus = adoptionStatus.trim();
|
||||
if (ADOPTION_STATUS_PENDING.equalsIgnoreCase(trimmedStatus)) {
|
||||
return ADOPTION_STATUS_PENDING;
|
||||
}
|
||||
if (ADOPTION_STATUS_COMPLETED.equalsIgnoreCase(trimmedStatus)) {
|
||||
return ADOPTION_STATUS_COMPLETED;
|
||||
}
|
||||
if (ADOPTION_STATUS_CANCELLED.equalsIgnoreCase(trimmedStatus)) {
|
||||
return ADOPTION_STATUS_CANCELLED;
|
||||
}
|
||||
throw new IllegalArgumentException("Adoption status must be Pending, Completed, or Cancelled");
|
||||
}
|
||||
|
||||
private void validatePetAvailability(Pet pet, Long adoptionId) {
|
||||
boolean adoptedElsewhere = adoptionId == null
|
||||
? adoptionRepository.existsByPet_IdAndAdoptionStatusIgnoreCase(pet.getPetId(), ADOPTION_STATUS_COMPLETED)
|
||||
: adoptionRepository.existsByPet_IdAndAdoptionStatusIgnoreCaseAndAdoptionIdNot(pet.getPetId(), ADOPTION_STATUS_COMPLETED, adoptionId);
|
||||
if (adoptedElsewhere) {
|
||||
throw new IllegalArgumentException("Selected pet has already been adopted");
|
||||
}
|
||||
|
||||
if (!PET_STATUS_AVAILABLE.equalsIgnoreCase(pet.getPetStatus()) && adoptionId == null) {
|
||||
throw new IllegalArgumentException("Selected pet is not available for adoption");
|
||||
}
|
||||
}
|
||||
|
||||
private void syncPetStatus(Pet pet, String adoptionStatus, Long adoptionId) {
|
||||
boolean completedElsewhere = adoptionId != null
|
||||
&& adoptionRepository.existsByPet_IdAndAdoptionStatusIgnoreCaseAndAdoptionIdNot(pet.getPetId(), ADOPTION_STATUS_COMPLETED, adoptionId);
|
||||
if (ADOPTION_STATUS_COMPLETED.equalsIgnoreCase(adoptionStatus) || completedElsewhere) {
|
||||
pet.setPetStatus(PET_STATUS_ADOPTED);
|
||||
} else {
|
||||
pet.setPetStatus(PET_STATUS_AVAILABLE);
|
||||
}
|
||||
petRepository.save(pet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.petshop.backend.dto.analytics.DashboardResponse;
|
||||
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.InventoryRepository;
|
||||
import com.petshop.backend.repository.ProductRepository;
|
||||
import com.petshop.backend.repository.SaleRepository;
|
||||
@@ -32,19 +33,22 @@ public class AnalyticsService {
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public DashboardResponse getDashboardData(int days, int top) {
|
||||
public DashboardResponse getDashboardData(int days, int top, User user) {
|
||||
LocalDateTime startDate = LocalDateTime.now().minusDays(days);
|
||||
|
||||
List<Sale> sales = saleRepository.findAll().stream()
|
||||
.filter(sale -> sale.getSaleDate().isAfter(startDate))
|
||||
.filter(sale -> includeSaleForUser(sale, user))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
DashboardResponse.SalesSummary salesSummary = calculateSalesSummary(sales);
|
||||
DashboardResponse.InventorySummary inventorySummary = calculateInventorySummary();
|
||||
DashboardResponse.InventorySummary inventorySummary = user.getRole() == User.Role.ADMIN ? calculateInventorySummary() : null;
|
||||
List<DashboardResponse.TopProduct> topProducts = calculateTopProducts(sales, top);
|
||||
List<DashboardResponse.DailySales> dailySales = calculateDailySales(sales, days);
|
||||
List<DashboardResponse.PaymentMethodData> paymentMethods = calculatePaymentMethods(sales);
|
||||
List<DashboardResponse.EmployeePerformanceData> employeePerformance = calculateEmployeePerformance(sales, user);
|
||||
|
||||
return new DashboardResponse(salesSummary, inventorySummary, topProducts, dailySales);
|
||||
return new DashboardResponse(salesSummary, inventorySummary, topProducts, dailySales, paymentMethods, employeePerformance);
|
||||
}
|
||||
|
||||
private DashboardResponse.SalesSummary calculateSalesSummary(List<Sale> sales) {
|
||||
@@ -66,7 +70,13 @@ public class AnalyticsService {
|
||||
.filter(Sale::getIsRefund)
|
||||
.count();
|
||||
|
||||
return new DashboardResponse.SalesSummary(totalRevenue, totalSales, totalRefunds, totalRefundCount);
|
||||
Long totalItemsSold = sales.stream()
|
||||
.filter(sale -> !sale.getIsRefund())
|
||||
.flatMap(sale -> sale.getItems().stream())
|
||||
.mapToLong(item -> item.getQuantity())
|
||||
.sum();
|
||||
|
||||
return new DashboardResponse.SalesSummary(totalRevenue, totalSales, totalRefunds, totalRefundCount, totalItemsSold);
|
||||
}
|
||||
|
||||
private DashboardResponse.InventorySummary calculateInventorySummary() {
|
||||
@@ -93,6 +103,9 @@ public class AnalyticsService {
|
||||
Map<Long, DashboardResponse.TopProduct> productSalesMap = new HashMap<>();
|
||||
|
||||
for (Sale sale : sales) {
|
||||
if (sale.getIsRefund()) {
|
||||
continue;
|
||||
}
|
||||
for (var item : sale.getItems()) {
|
||||
Long productId = item.getProduct().getProdId();
|
||||
String productName = item.getProduct().getProdName();
|
||||
@@ -128,6 +141,9 @@ public class AnalyticsService {
|
||||
}
|
||||
|
||||
for (Sale sale : sales) {
|
||||
if (sale.getIsRefund()) {
|
||||
continue;
|
||||
}
|
||||
LocalDate saleDate = sale.getSaleDate().toLocalDate();
|
||||
if (dailySalesMap.containsKey(saleDate)) {
|
||||
DashboardResponse.DailySales dailySale = dailySalesMap.get(saleDate);
|
||||
@@ -138,4 +154,47 @@ public class AnalyticsService {
|
||||
|
||||
return new ArrayList<>(dailySalesMap.values());
|
||||
}
|
||||
|
||||
private List<DashboardResponse.PaymentMethodData> calculatePaymentMethods(List<Sale> sales) {
|
||||
return sales.stream()
|
||||
.filter(sale -> !sale.getIsRefund())
|
||||
.collect(Collectors.groupingBy(
|
||||
sale -> sale.getPaymentMethod() == null ? "Unknown" : sale.getPaymentMethod(),
|
||||
TreeMap::new,
|
||||
Collectors.counting()))
|
||||
.entrySet().stream()
|
||||
.map(entry -> new DashboardResponse.PaymentMethodData(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<DashboardResponse.EmployeePerformanceData> calculateEmployeePerformance(List<Sale> sales, User user) {
|
||||
Map<String, BigDecimal> employeeRevenue = new TreeMap<>();
|
||||
|
||||
for (Sale sale : sales) {
|
||||
if (sale.getIsRefund()) {
|
||||
continue;
|
||||
}
|
||||
String employeeName = sale.getEmployee().getFirstName() + " " + sale.getEmployee().getLastName();
|
||||
employeeRevenue.merge(employeeName, sale.getTotalAmount(), BigDecimal::add);
|
||||
}
|
||||
|
||||
if (user.getRole() == User.Role.STAFF && employeeRevenue.isEmpty()) {
|
||||
String employeeName = user.getFirstName() + " " + user.getLastName();
|
||||
employeeRevenue.put(employeeName, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
return employeeRevenue.entrySet().stream()
|
||||
.map(entry -> new DashboardResponse.EmployeePerformanceData(entry.getKey(), entry.getValue()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean includeSaleForUser(Sale sale, User user) {
|
||||
if (user.getRole() == User.Role.ADMIN) {
|
||||
return true;
|
||||
}
|
||||
if (user.getRole() == User.Role.STAFF) {
|
||||
return sale.getEmployee() != null && sale.getEmployee().getId() != null && sale.getEmployee().getId().equals(user.getId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,17 +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.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.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;
|
||||
@@ -30,51 +24,48 @@ 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 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, 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.serviceRepository = serviceRepository;
|
||||
this.petRepository = petRepository;
|
||||
this.storeRepository = storeRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.employeeRepository = employeeRepository;
|
||||
this.employeeStoreRepository = employeeStoreRepository;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<AppointmentResponse> getAllAppointments(String query, Pageable pageable, Long customerId) {
|
||||
Page<Appointment> appointments;
|
||||
public Page<AppointmentResponse> getAllAppointments(
|
||||
String query,
|
||||
Long customerId,
|
||||
Long employeeId,
|
||||
Long storeId,
|
||||
String status,
|
||||
LocalDate date,
|
||||
Pageable pageable) {
|
||||
|
||||
if (customerId != null) {
|
||||
if (query != null && !query.trim().isEmpty()) {
|
||||
appointments = appointmentRepository.searchAppointmentsByCustomer(customerId, query, pageable);
|
||||
} else {
|
||||
appointments = appointmentRepository.findByCustomerCustomerId(customerId, pageable);
|
||||
}
|
||||
} else {
|
||||
if (query != null && !query.trim().isEmpty()) {
|
||||
appointments = appointmentRepository.searchAppointments(query, pageable);
|
||||
} else {
|
||||
appointments = appointmentRepository.findAll(pageable);
|
||||
}
|
||||
}
|
||||
String normalizedQuery = normalizeFilter(query);
|
||||
String normalizedStatus = normalizeFilter(status);
|
||||
|
||||
Page<Appointment> appointments = appointmentRepository.searchAppointments(
|
||||
normalizedQuery,
|
||||
customerId,
|
||||
employeeId,
|
||||
storeId,
|
||||
normalizedStatus,
|
||||
date,
|
||||
pageable
|
||||
);
|
||||
|
||||
return appointments.map(this::mapToResponse);
|
||||
}
|
||||
@@ -84,7 +75,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");
|
||||
}
|
||||
|
||||
@@ -95,15 +86,11 @@ public class AppointmentService {
|
||||
public AppointmentResponse createAppointment(AppointmentRequest request) {
|
||||
validateAppointmentRequest(request);
|
||||
|
||||
Customer customer = customerRepository.findById(request.getCustomerId())
|
||||
User authenticatedUser = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
|
||||
User customer = userRepository.findById(request.getCustomerId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId()));
|
||||
|
||||
Employee employee;
|
||||
if (request.getEmployeeId() != null) {
|
||||
employee = employeeRepository.findById(request.getEmployeeId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException(
|
||||
"Employee not found with id: " + request.getEmployeeId()));
|
||||
} else {
|
||||
employee = AuthenticationHelper.getAuthenticatedEmployee(
|
||||
userRepository, employeeRepository);
|
||||
}
|
||||
@@ -114,10 +101,11 @@ public class AppointmentService {
|
||||
com.petshop.backend.entity.Service service = serviceRepository.findById(request.getServiceId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Service not found with id: " + request.getServiceId()));
|
||||
|
||||
validateStoreAccess(store.getStoreId());
|
||||
validateAvailability(store, service, request.getAppointmentDate(), request.getAppointmentTime(), null);
|
||||
Pet pet = request.getPetId() != null ? fetchPet(request.getPetId()) : null;
|
||||
User employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId());
|
||||
|
||||
Set<Pet> pets = fetchPets(request.getPetIds());
|
||||
validateStoreAccess(store.getStoreId(), authenticatedUser);
|
||||
validateAvailability(employee, service, request.getAppointmentDate(), request.getAppointmentTime(), null);
|
||||
|
||||
Appointment appointment = new Appointment();
|
||||
appointment.setCustomer(customer);
|
||||
@@ -127,7 +115,8 @@ public class AppointmentService {
|
||||
appointment.setAppointmentDate(request.getAppointmentDate());
|
||||
appointment.setAppointmentTime(request.getAppointmentTime());
|
||||
appointment.setAppointmentStatus(request.getAppointmentStatus());
|
||||
appointment.setPets(pets);
|
||||
appointment.setPet(pet);
|
||||
appointment.setEmployee(employee);
|
||||
|
||||
appointment = appointmentRepository.save(appointment);
|
||||
return mapToResponse(appointment);
|
||||
@@ -137,10 +126,12 @@ public class AppointmentService {
|
||||
public AppointmentResponse updateAppointment(Long id, AppointmentRequest request) {
|
||||
validateAppointmentRequest(request);
|
||||
|
||||
User authenticatedUser = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
|
||||
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())
|
||||
@@ -149,10 +140,11 @@ public class AppointmentService {
|
||||
com.petshop.backend.entity.Service service = serviceRepository.findById(request.getServiceId())
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Service not found with id: " + request.getServiceId()));
|
||||
|
||||
validateStoreAccess(store.getStoreId());
|
||||
validateAvailability(store, service, request.getAppointmentDate(), request.getAppointmentTime(), id);
|
||||
Pet pet = request.getPetId() != null ? fetchPet(request.getPetId()) : null;
|
||||
User employee = resolveAppointmentEmployee(request.getEmployeeId(), store.getStoreId());
|
||||
|
||||
Set<Pet> pets = fetchPets(request.getPetIds());
|
||||
validateStoreAccess(store.getStoreId(), authenticatedUser);
|
||||
validateAvailability(employee, service, request.getAppointmentDate(), request.getAppointmentTime(), id);
|
||||
|
||||
appointment.setCustomer(customer);
|
||||
appointment.setStore(store);
|
||||
@@ -160,7 +152,8 @@ public class AppointmentService {
|
||||
appointment.setAppointmentDate(request.getAppointmentDate());
|
||||
appointment.setAppointmentTime(request.getAppointmentTime());
|
||||
appointment.setAppointmentStatus(request.getAppointmentStatus());
|
||||
appointment.setPets(pets);
|
||||
appointment.setPet(pet);
|
||||
appointment.setEmployee(employee);
|
||||
|
||||
appointment = appointmentRepository.save(appointment);
|
||||
return mapToResponse(appointment);
|
||||
@@ -180,7 +173,6 @@ public class AppointmentService {
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
|
||||
public List<String> checkAvailability(Long storeId, Long serviceId, LocalDate date) {
|
||||
storeRepository.findById(storeId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + storeId));
|
||||
@@ -188,16 +180,17 @@ public class AppointmentService {
|
||||
com.petshop.backend.entity.Service service = serviceRepository.findById(serviceId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Service not found with id: " + serviceId));
|
||||
|
||||
List<User> assignableUsers = userRepository.findByPrimaryStoreStoreIdAndRoleAndActiveTrue(storeId, User.Role.STAFF);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// CHANGED: filter by serviceId too
|
||||
List<Appointment> existingAppointments = appointmentRepository
|
||||
.findByStoreAndDate(storeId, date)
|
||||
.stream()
|
||||
.filter(a -> a.getService().getServiceId().equals(serviceId))
|
||||
.collect(Collectors.toList());
|
||||
// -------------------------------------------------------
|
||||
if (assignableUsers.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
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().getId()));
|
||||
|
||||
List<String> availableSlots = new ArrayList<>();
|
||||
LocalTime startTime = LocalTime.of(9, 0);
|
||||
@@ -206,7 +199,13 @@ public class AppointmentService {
|
||||
|
||||
LocalTime currentTime = startTime;
|
||||
while (!currentTime.isAfter(latestStart)) {
|
||||
if (isSlotAvailable(existingAppointments, service, currentTime, null)) {
|
||||
final LocalTime slotTime = currentTime;
|
||||
boolean anyEmployeeAvailable = assignableUsers.stream().anyMatch(emp -> {
|
||||
List<Appointment> empAppointments = appointmentsByEmployee.getOrDefault(emp.getId(), List.of());
|
||||
return isSlotAvailable(empAppointments, service, slotTime, null);
|
||||
});
|
||||
|
||||
if (anyEmployeeAvailable) {
|
||||
availableSlots.add(currentTime.toString());
|
||||
}
|
||||
currentTime = currentTime.plusMinutes(30);
|
||||
@@ -215,6 +214,14 @@ public class AppointmentService {
|
||||
return availableSlots;
|
||||
}
|
||||
|
||||
private String normalizeFilter(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String trimmed = value.trim();
|
||||
return trimmed.isEmpty() ? null : trimmed;
|
||||
}
|
||||
|
||||
private void validateAppointmentRequest(AppointmentRequest request) {
|
||||
if ("Booked".equalsIgnoreCase(request.getAppointmentStatus())) {
|
||||
LocalDateTime appointmentDateTime = LocalDateTime.of(request.getAppointmentDate(), request.getAppointmentTime());
|
||||
@@ -224,64 +231,63 @@ 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 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());
|
||||
Pet pet = appointment.getPet();
|
||||
|
||||
List<Long> petIds = appointment.getPets().stream()
|
||||
.map(Pet::getPetId)
|
||||
.collect(Collectors.toList());
|
||||
AppointmentResponse response = new AppointmentResponse();
|
||||
response.setAppointmentId(appointment.getAppointmentId());
|
||||
response.setCustomerId(appointment.getCustomer().getId());
|
||||
response.setCustomerName(appointment.getCustomer().getFirstName() + " " + appointment.getCustomer().getLastName());
|
||||
response.setStoreId(appointment.getStore().getStoreId());
|
||||
response.setStoreName(appointment.getStore().getStoreName());
|
||||
response.setServiceId(appointment.getService().getServiceId());
|
||||
response.setServiceName(appointment.getService().getServiceName());
|
||||
response.setAppointmentDate(appointment.getAppointmentDate());
|
||||
response.setAppointmentTime(appointment.getAppointmentTime());
|
||||
response.setAppointmentStatus(appointment.getAppointmentStatus());
|
||||
response.setEmployeeId(appointment.getEmployee().getId());
|
||||
response.setEmployeeName(appointment.getEmployee().getFirstName() + " " + appointment.getEmployee().getLastName());
|
||||
response.setPetName(pet != null ? pet.getPetName() : null);
|
||||
response.setPetId(pet != null ? pet.getPetId() : null);
|
||||
response.setCreatedAt(appointment.getCreatedAt());
|
||||
response.setUpdatedAt(appointment.getUpdatedAt());
|
||||
|
||||
return new AppointmentResponse(
|
||||
appointment.getAppointmentId(),
|
||||
appointment.getCustomer().getCustomerId(),
|
||||
appointment.getCustomer().getFirstName() + " " + appointment.getCustomer().getLastName(),
|
||||
appointment.getStore().getStoreId(),
|
||||
appointment.getStore().getStoreName(),
|
||||
appointment.getService().getServiceId(),
|
||||
appointment.getService().getServiceName(),
|
||||
appointment.getAppointmentDate(),
|
||||
appointment.getAppointmentTime(),
|
||||
appointment.getAppointmentStatus(),
|
||||
petNames,
|
||||
petIds,
|
||||
appointment.getCreatedAt(),
|
||||
appointment.getUpdatedAt(),
|
||||
appointment.getEmployee() != null ? appointment.getEmployee().getEmployeeId() : null,
|
||||
appointment.getEmployee() != null ?
|
||||
appointment.getEmployee().getFirstName() + " " + appointment.getEmployee().getLastName()
|
||||
: "Unassigned"
|
||||
return response;
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
private void validateAvailability(StoreLocation store, com.petshop.backend.entity.Service service, LocalDate date, LocalTime time, Long appointmentIdToIgnore) {
|
||||
// Filter by same service only - different services can run at same time
|
||||
private User resolveAppointmentEmployee(Long requestedEmployeeId, Long storeId) {
|
||||
List<User> assignableUsers = userRepository.findByPrimaryStoreStoreIdAndRoleAndActiveTrue(storeId, User.Role.STAFF);
|
||||
|
||||
if (requestedEmployeeId != null) {
|
||||
User employee = userRepository.findById(requestedEmployeeId)
|
||||
.orElseThrow(() -> new ResourceNotFoundException("Employee not found with id: " + 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 assignableUsers.stream()
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalArgumentException("No assignable staff member is assigned to the selected store"));
|
||||
}
|
||||
|
||||
private void validateAvailability(User employee, com.petshop.backend.entity.Service service, LocalDate date, LocalTime time, Long appointmentIdToIgnore) {
|
||||
List<Appointment> existingAppointments = appointmentRepository
|
||||
.findByStoreAndDate(store.getStoreId(), date)
|
||||
.stream()
|
||||
.filter(a -> a.getService().getServiceId().equals(service.getServiceId()))
|
||||
.collect(Collectors.toList());
|
||||
.findByEmployeeIdAndAppointmentDate(employee.getId(), date);
|
||||
if (!isSlotAvailable(existingAppointments, service, time, appointmentIdToIgnore)) {
|
||||
throw new IllegalArgumentException("Appointment time is not available for the selected store and service");
|
||||
throw new IllegalArgumentException("The selected employee is already booked for this time slot");
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
|
||||
private boolean isSlotAvailable(List<Appointment> existingAppointments, com.petshop.backend.entity.Service requestedService, LocalTime requestedStart, Long appointmentIdToIgnore) {
|
||||
LocalTime requestedEnd = requestedStart.plusMinutes(requestedService.getServiceDuration());
|
||||
for (Appointment existingAppointment : existingAppointments) {
|
||||
@@ -297,17 +303,12 @@ public class AppointmentService {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void validateStoreAccess(Long requestedStoreId) {
|
||||
User user = AuthenticationHelper.getAuthenticatedUser(userRepository);
|
||||
private void validateStoreAccess(Long requestedStoreId, User user) {
|
||||
if (user.getRole() != User.Role.STAFF) {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,10 @@ public class AvatarStorageService {
|
||||
if (user.getAvatarUrl() == null || user.getAvatarUrl().isBlank()) {
|
||||
return;
|
||||
}
|
||||
Files.deleteIfExists(resolveStoredAvatarPath(user.getAvatarUrl()));
|
||||
try {
|
||||
Files.deleteIfExists(resolveStoredAvatarPath(user.getAvatarUrl()));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public String toOwnerAvatarUrl(User user) {
|
||||
|
||||
@@ -20,14 +20,9 @@ public class CategoryService {
|
||||
this.categoryRepository = categoryRepository;
|
||||
}
|
||||
|
||||
public Page<CategoryResponse> getAllCategories(String query, Pageable pageable) {
|
||||
Page<Category> categories;
|
||||
if (query != null && !query.trim().isEmpty()) {
|
||||
categories = categoryRepository.searchCategories(query, pageable);
|
||||
} else {
|
||||
categories = categoryRepository.findAll(pageable);
|
||||
}
|
||||
return categories.map(this::mapToResponse);
|
||||
public Page<CategoryResponse> getAllCategories(String query, String type, Pageable pageable) {
|
||||
return categoryRepository.searchCategories(normalizeFilter(query), normalizeFilter(type), pageable)
|
||||
.map(this::mapToResponse);
|
||||
}
|
||||
|
||||
public CategoryResponse getCategoryById(Long id) {
|
||||
@@ -80,4 +75,12 @@ public class CategoryService {
|
||||
category.getUpdatedAt()
|
||||
);
|
||||
}
|
||||
|
||||
private String normalizeFilter(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String trimmed = value.trim();
|
||||
return trimmed.isEmpty() ? null : trimmed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user