Fix backend business logic and remove hardcoded IDs

- Add customerId to SaleRequest DTO
- Update SaleService to use AuthenticationHelper for employee attribution
- Populate sale.customer when customerId provided in request
- Fix AdoptionController to use authenticated customer instead of hardcoded ID 1
- Fix AppointmentController to use authenticated customer instead of hardcoded ID 1
- Fix RefundController to use authenticated customer instead of hardcoded ID 1
- Update data.sql sales to include customer linkage for refund testing
- Update Postman collection sale creation with customerId and items
This commit is contained in:
2026-03-08 21:58:50 -06:00
parent a0d14e493f
commit a0c782f4cc
7 changed files with 111 additions and 38 deletions

View File

@@ -509,7 +509,7 @@
],
"body": {
"mode": "raw",
"raw": "{\n \"employeeId\": 1,\n \"storeId\": 1,\n \"totalAmount\": 100.0,\n \"paymentMethod\": \"Card\",\n \"isRefund\": false\n}"
"raw": "{\n \"storeId\": 1,\n \"paymentMethod\": \"Card\",\n \"customerId\": 1,\n \"items\": [\n {\n \"prodId\": 1,\n \"quantity\": 2\n },\n {\n \"prodId\": 2,\n \"quantity\": 1\n }\n ],\n \"isRefund\": false\n}"
}
}
}

View File

@@ -3,7 +3,11 @@ 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.repository.UserRepository;
import com.petshop.backend.service.AdoptionService;
import com.petshop.backend.util.AuthenticationHelper;
import jakarta.validation.Valid;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -19,9 +23,13 @@ import org.springframework.web.bind.annotation.*;
public class AdoptionController {
private final AdoptionService adoptionService;
private final UserRepository userRepository;
private final CustomerRepository customerRepository;
public AdoptionController(AdoptionService adoptionService) {
public AdoptionController(AdoptionService adoptionService, UserRepository userRepository, CustomerRepository customerRepository) {
this.adoptionService = adoptionService;
this.userRepository = userRepository;
this.customerRepository = customerRepository;
}
@GetMapping
@@ -35,7 +43,11 @@ public class AdoptionController {
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
.orElse(null);
Long customerId = role != null && role.equals("CUSTOMER") ? 1L : null;
Long customerId = null;
if (role != null && role.equals("CUSTOMER")) {
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
customerId = customer.getCustomerId();
}
return ResponseEntity.ok(adoptionService.getAllAdoptions(q, pageable, customerId));
}
@@ -49,7 +61,11 @@ public class AdoptionController {
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
.orElse(null);
Long customerId = role != null && role.equals("CUSTOMER") ? 1L : null;
Long customerId = null;
if (role != null && role.equals("CUSTOMER")) {
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
customerId = customer.getCustomerId();
}
return ResponseEntity.ok(adoptionService.getAdoptionById(id, customerId));
}

View File

@@ -3,7 +3,11 @@ 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.repository.UserRepository;
import com.petshop.backend.service.AppointmentService;
import com.petshop.backend.util.AuthenticationHelper;
import jakarta.validation.Valid;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -22,9 +26,13 @@ import java.util.List;
public class AppointmentController {
private final AppointmentService appointmentService;
private final UserRepository userRepository;
private final CustomerRepository customerRepository;
public AppointmentController(AppointmentService appointmentService) {
public AppointmentController(AppointmentService appointmentService, UserRepository userRepository, CustomerRepository customerRepository) {
this.appointmentService = appointmentService;
this.userRepository = userRepository;
this.customerRepository = customerRepository;
}
@GetMapping
@@ -38,7 +46,11 @@ public class AppointmentController {
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
.orElse(null);
Long customerId = role != null && role.equals("CUSTOMER") ? 1L : null;
Long customerId = null;
if (role != null && role.equals("CUSTOMER")) {
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
customerId = customer.getCustomerId();
}
return ResponseEntity.ok(appointmentService.getAllAppointments(q, pageable, customerId));
}
@@ -52,7 +64,11 @@ public class AppointmentController {
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
.orElse(null);
Long customerId = role != null && role.equals("CUSTOMER") ? 1L : null;
Long customerId = null;
if (role != null && role.equals("CUSTOMER")) {
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
customerId = customer.getCustomerId();
}
return ResponseEntity.ok(appointmentService.getAppointmentById(id, customerId));
}

View File

@@ -3,7 +3,11 @@ 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.repository.UserRepository;
import com.petshop.backend.service.RefundService;
import com.petshop.backend.util.AuthenticationHelper;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -21,9 +25,13 @@ import java.util.Map;
public class RefundController {
private final RefundService refundService;
private final UserRepository userRepository;
private final CustomerRepository customerRepository;
public RefundController(RefundService refundService) {
public RefundController(RefundService refundService, UserRepository userRepository, CustomerRepository customerRepository) {
this.refundService = refundService;
this.userRepository = userRepository;
this.customerRepository = customerRepository;
}
@PostMapping
@@ -36,7 +44,11 @@ public class RefundController {
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
.orElse(null);
Long customerId = role != null && role.equals("CUSTOMER") ? 1L : 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);
@@ -56,7 +68,11 @@ public class RefundController {
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
.orElse(null);
Long customerId = role != null && role.equals("CUSTOMER") ? 1L : null;
Long customerId = null;
if (role != null && role.equals("CUSTOMER")) {
Customer customer = AuthenticationHelper.getAuthenticatedCustomer(userRepository, customerRepository);
customerId = customer.getCustomerId();
}
List<RefundResponse> refunds = refundService.getAllRefunds(customerId);
return ResponseEntity.ok(refunds);
@@ -72,7 +88,11 @@ public class RefundController {
.map(authority -> authority.getAuthority().replace("ROLE_", ""))
.orElse(null);
Long customerId = role != null && role.equals("CUSTOMER") ? 1L : 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);

View File

@@ -20,6 +20,8 @@ public class SaleRequest {
private Long originalSaleId;
private Long customerId;
public Long getStoreId() {
return storeId;
}
@@ -60,6 +62,14 @@ public class SaleRequest {
this.originalSaleId = originalSaleId;
}
public Long getCustomerId() {
return customerId;
}
public void setCustomerId(Long customerId) {
this.customerId = customerId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -69,12 +79,13 @@ public class SaleRequest {
Objects.equals(paymentMethod, that.paymentMethod) &&
Objects.equals(items, that.items) &&
Objects.equals(isRefund, that.isRefund) &&
Objects.equals(originalSaleId, that.originalSaleId);
Objects.equals(originalSaleId, that.originalSaleId) &&
Objects.equals(customerId, that.customerId);
}
@Override
public int hashCode() {
return Objects.hash(storeId, paymentMethod, items, isRefund, originalSaleId);
return Objects.hash(storeId, paymentMethod, items, isRefund, originalSaleId, customerId);
}
@Override
@@ -85,6 +96,7 @@ public class SaleRequest {
", items=" + items +
", isRefund=" + isRefund +
", originalSaleId=" + originalSaleId +
", customerId=" + customerId +
'}';
}
}

View File

@@ -6,6 +6,7 @@ import com.petshop.backend.entity.*;
import com.petshop.backend.exception.BusinessException;
import com.petshop.backend.exception.ResourceNotFoundException;
import com.petshop.backend.repository.*;
import com.petshop.backend.util.AuthenticationHelper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -25,13 +26,17 @@ public class SaleService {
private final StoreRepository storeRepository;
private final InventoryRepository inventoryRepository;
private final EmployeeRepository employeeRepository;
private final UserRepository userRepository;
private final CustomerRepository customerRepository;
public SaleService(SaleRepository saleRepository, ProductRepository productRepository, StoreRepository storeRepository, InventoryRepository inventoryRepository, EmployeeRepository employeeRepository) {
public SaleService(SaleRepository saleRepository, ProductRepository productRepository, StoreRepository storeRepository, InventoryRepository inventoryRepository, EmployeeRepository employeeRepository, UserRepository userRepository, CustomerRepository customerRepository) {
this.saleRepository = saleRepository;
this.productRepository = productRepository;
this.storeRepository = storeRepository;
this.inventoryRepository = inventoryRepository;
this.employeeRepository = employeeRepository;
this.userRepository = userRepository;
this.customerRepository = customerRepository;
}
public Page<SaleResponse> getAllSales(String query, Pageable pageable) {
@@ -52,9 +57,7 @@ public class SaleService {
@Transactional
public SaleResponse createSale(SaleRequest request) {
Employee employee = employeeRepository.findAll().stream()
.findFirst()
.orElseThrow(() -> new ResourceNotFoundException("No employees found"));
Employee employee = AuthenticationHelper.getAuthenticatedEmployee(userRepository, employeeRepository);
StoreLocation store = storeRepository.findById(request.getStoreId())
.orElseThrow(() -> new ResourceNotFoundException("Store not found with id: " + request.getStoreId()));
@@ -66,6 +69,12 @@ public class SaleService {
sale.setPaymentMethod(request.getPaymentMethod());
sale.setIsRefund(request.getIsRefund() != null ? request.getIsRefund() : false);
if (request.getCustomerId() != null) {
Customer customer = customerRepository.findById(request.getCustomerId())
.orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId()));
sale.setCustomer(customer);
}
if (sale.getIsRefund() && request.getOriginalSaleId() != null) {
Sale originalSale = saleRepository.findById(request.getOriginalSaleId())
.orElseThrow(() -> new ResourceNotFoundException("Original sale not found with id: " + request.getOriginalSaleId()));

View File

@@ -123,28 +123,28 @@ VALUES
(4, 5),
(5, 6);
INSERT INTO sale (saleDate, totalAmount, paymentMethod, employeeId, storeId)
INSERT INTO sale (saleDate, totalAmount, paymentMethod, employeeId, storeId, customerId)
VALUES
('2026-01-05 09:15:00', 125.00, 'Card', 1, 1),
('2026-01-08 11:30:00', 200.00, 'Card', 2, 1),
('2026-01-12 14:20:00', 60.00, 'Cash', 3, 2),
('2026-01-15 10:45:00', 150.00, 'Debit', 1, 1),
('2026-01-18 16:30:00', 80.00, 'Card', 4, 3),
('2026-01-22 13:15:00', 95.00, 'Cash', 2, 2),
('2026-01-25 15:40:00', 240.00, 'Card', 5, 4),
('2026-01-28 10:30:00', 80.00, 'Cash', 1, 1),
('2026-02-01 09:00:00', 175.00, 'Card', 3, 3),
('2026-02-03 11:20:00', 120.00, 'Card', 2, 1),
('2026-02-05 14:50:00', 45.00, 'Cash', 4, 2),
('2026-02-08 16:15:00', 160.00, 'Debit', 1, 1),
('2026-02-10 10:25:00', 100.00, 'Card', 5, 4),
('2026-02-12 13:45:00', 50.00, 'Cash', 2, 2),
('2026-02-15 15:30:00', 85.00, 'Card', 3, 3),
('2026-02-18 11:10:00', 200.00, 'Card', 1, 1),
('2026-02-20 14:35:00', 155.00, 'Debit', 4, 3),
('2026-02-22 16:50:00', 75.00, 'Cash', 2, 1),
('2026-02-24 10:15:00', 140.00, 'Card', 5, 4),
(NOW(), 95.00, 'Card', 1, 1);
('2026-01-05 09:15:00', 125.00, 'Card', 1, 1, 1),
('2026-01-08 11:30:00', 200.00, 'Card', 2, 1, 2),
('2026-01-12 14:20:00', 60.00, 'Cash', 3, 2, 3),
('2026-01-15 10:45:00', 150.00, 'Debit', 1, 1, 1),
('2026-01-18 16:30:00', 80.00, 'Card', 4, 3, 2),
('2026-01-22 13:15:00', 95.00, 'Cash', 2, 2, NULL),
('2026-01-25 15:40:00', 240.00, 'Card', 5, 4, 4),
('2026-01-28 10:30:00', 80.00, 'Cash', 1, 1, NULL),
('2026-02-01 09:00:00', 175.00, 'Card', 3, 3, 1),
('2026-02-03 11:20:00', 120.00, 'Card', 2, 1, 3),
('2026-02-05 14:50:00', 45.00, 'Cash', 4, 2, NULL),
('2026-02-08 16:15:00', 160.00, 'Debit', 1, 1, 2),
('2026-02-10 10:25:00', 100.00, 'Card', 5, 4, NULL),
('2026-02-12 13:45:00', 50.00, 'Cash', 2, 2, 1),
('2026-02-15 15:30:00', 85.00, 'Card', 3, 3, NULL),
('2026-02-18 11:10:00', 200.00, 'Card', 1, 1, 4),
('2026-02-20 14:35:00', 155.00, 'Debit', 4, 3, NULL),
('2026-02-22 16:50:00', 75.00, 'Cash', 2, 1, 2),
('2026-02-24 10:15:00', 140.00, 'Card', 5, 4, NULL),
(NOW(), 95.00, 'Card', 1, 1, 1);
INSERT INTO saleItem (saleId, prodId, quantity, unitPrice)
VALUES