Merge branch 'AttachmentsToChat'

This commit is contained in:
Alex
2026-04-12 01:09:25 -06:00
64 changed files with 2303 additions and 193 deletions

View File

@@ -12,6 +12,8 @@ public class SaleResponse {
private String employeeName;
private Long storeId;
private String storeName;
private Long customerId;
private String customerName;
private BigDecimal totalAmount;
private BigDecimal subtotalAmount;
private BigDecimal couponDiscountAmount;
@@ -77,6 +79,22 @@ public class SaleResponse {
this.storeName = storeName;
}
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 BigDecimal getTotalAmount() {
return totalAmount;
}

View File

@@ -13,6 +13,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@@ -20,6 +21,8 @@ import java.util.List;
@Service
public class SaleService {
private static final BigDecimal EMPLOYEE_DISCOUNT_PERCENT = new BigDecimal("0.10");
private final SaleRepository saleRepository;
private final ProductRepository productRepository;
private final StoreRepository storeRepository;
@@ -76,6 +79,7 @@ public class SaleService {
if (request.getCouponId() != null) {
Coupon coupon = couponRepository.findById(request.getCouponId())
.orElseThrow(() -> new ResourceNotFoundException("Coupon not found with id: " + request.getCouponId()));
validateCoupon(coupon);
sale.setCoupon(coupon);
}
@@ -85,8 +89,9 @@ public class SaleService {
sale.setCart(cart);
}
User customer = null;
if (request.getCustomerId() != null) {
User customer = userRepository.findById(request.getCustomerId())
customer = userRepository.findById(request.getCustomerId())
.orElseThrow(() -> new ResourceNotFoundException("Customer not found with id: " + request.getCustomerId()));
sale.setCustomer(customer);
}
@@ -97,7 +102,7 @@ public class SaleService {
sale.setOriginalSale(originalSale);
}
BigDecimal totalAmount = BigDecimal.ZERO;
BigDecimal subtotalAmount = BigDecimal.ZERO;
List<SaleItem> saleItems = new ArrayList<>();
if (sale.getIsRefund() && sale.getOriginalSale() != null) {
@@ -145,9 +150,11 @@ public class SaleService {
saleItem.setUnitPrice(unitPrice);
saleItems.add(saleItem);
totalAmount = totalAmount.add(itemTotal);
subtotalAmount = subtotalAmount.add(itemTotal);
}
totalAmount = totalAmount.negate();
subtotalAmount = subtotalAmount.negate();
sale.setSubtotalAmount(subtotalAmount);
sale.setTotalAmount(subtotalAmount);
} else {
for (var itemRequest : request.getItems()) {
Product product = productRepository.findById(itemRequest.getProdId())
@@ -174,17 +181,77 @@ public class SaleService {
saleItem.setUnitPrice(unitPrice);
saleItems.add(saleItem);
totalAmount = totalAmount.add(itemTotal);
subtotalAmount = subtotalAmount.add(itemTotal);
}
sale.setSubtotalAmount(subtotalAmount);
BigDecimal couponDiscount = calculateCouponDiscount(sale.getCoupon(), subtotalAmount);
sale.setCouponDiscountAmount(couponDiscount);
BigDecimal employeeDiscount = calculateEmployeeDiscount(customer, subtotalAmount.subtract(couponDiscount));
sale.setEmployeeDiscountAmount(employeeDiscount);
BigDecimal finalTotal = subtotalAmount.subtract(couponDiscount).subtract(employeeDiscount);
sale.setTotalAmount(finalTotal.max(BigDecimal.ZERO));
sale.setPointsEarned(sale.getTotalAmount().setScale(0, RoundingMode.FLOOR).intValue());
if (customer != null) {
customer.setLoyaltyPoints(customer.getLoyaltyPoints() + sale.getPointsEarned());
userRepository.save(customer);
}
}
sale.setTotalAmount(totalAmount);
sale.setItems(saleItems);
Sale savedSale = saleRepository.save(sale);
return mapToResponse(savedSale);
}
private void validateCoupon(Coupon coupon) {
if (!Boolean.TRUE.equals(coupon.getActive())) {
throw new BusinessException("Coupon is not active");
}
LocalDateTime now = LocalDateTime.now();
if (coupon.getStartsAt() != null && now.isBefore(coupon.getStartsAt())) {
throw new BusinessException("Coupon has not started yet");
}
if (coupon.getEndsAt() != null && now.isAfter(coupon.getEndsAt())) {
throw new BusinessException("Coupon has expired");
}
}
private BigDecimal calculateCouponDiscount(Coupon coupon, BigDecimal subtotal) {
if (coupon == null || subtotal.compareTo(BigDecimal.ZERO) <= 0) {
return BigDecimal.ZERO;
}
if (coupon.getMinOrderAmount() != null && subtotal.compareTo(coupon.getMinOrderAmount()) < 0) {
return BigDecimal.ZERO;
}
BigDecimal discount = BigDecimal.ZERO;
String type = coupon.getDiscountType().trim().toUpperCase();
if ("PERCENTAGE".equals(type) || "PERCENT".equals(type)) {
discount = subtotal.multiply(coupon.getDiscountValue().divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP));
} else if ("FIXED".equals(type)) {
discount = coupon.getDiscountValue();
}
return discount.min(subtotal).setScale(2, RoundingMode.HALF_UP);
}
private BigDecimal calculateEmployeeDiscount(User customer, BigDecimal remainingAmount) {
if (customer == null || remainingAmount.compareTo(BigDecimal.ZERO) <= 0) {
return BigDecimal.ZERO;
}
if (customer.getRole() == User.Role.STAFF || customer.getRole() == User.Role.ADMIN) {
return remainingAmount.multiply(EMPLOYEE_DISCOUNT_PERCENT).setScale(2, RoundingMode.HALF_UP);
}
return BigDecimal.ZERO;
}
private SaleResponse mapToResponse(Sale sale) {
SaleResponse response = new SaleResponse();
response.setSaleId(sale.getSaleId());
@@ -197,6 +264,11 @@ public class SaleService {
response.setStoreName(sale.getStore().getStoreName());
}
if (sale.getCustomer() != null) {
response.setCustomerId(sale.getCustomer().getId());
response.setCustomerName(sale.getCustomer().getFirstName() + " " + sale.getCustomer().getLastName());
}
response.setTotalAmount(sale.getTotalAmount());
response.setSubtotalAmount(sale.getSubtotalAmount());
response.setCouponDiscountAmount(sale.getCouponDiscountAmount());