Add UI-ready DTOs with joined fields

This commit is contained in:
2026-03-04 17:05:29 -07:00
parent 06191d2958
commit cb432fb2b1
31 changed files with 793 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
package com.petshop.backend.dto.adoption;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDate;
@Data
public class AdoptionRequest {
@NotNull(message = "Pet ID is required")
private Long petId;
@NotNull(message = "Customer ID is required")
private Long customerId;
@NotNull(message = "Adoption date is required")
private LocalDate adoptionDate;
@NotNull(message = "Adoption fee is required")
@Positive(message = "Adoption fee must be positive")
private BigDecimal adoptionFee;
private String notes;
}

View File

@@ -0,0 +1,25 @@
package com.petshop.backend.dto.adoption;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdoptionResponse {
private Long id;
private Long petId;
private String petName;
private Long customerId;
private String customerName;
private LocalDate adoptionDate;
private BigDecimal adoptionFee;
private String notes;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,57 @@
package com.petshop.backend.dto.analytics;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DashboardResponse {
private SalesSummary salesSummary;
private InventorySummary inventorySummary;
private List<TopProduct> topProducts;
private List<DailySales> dailySales;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class SalesSummary {
private BigDecimal totalRevenue;
private Long totalSales;
private BigDecimal totalRefunds;
private Long totalRefundCount;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class InventorySummary {
private Long totalProducts;
private Long lowStockProducts;
private Long outOfStockProducts;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class TopProduct {
private Long productId;
private String productName;
private Long quantitySold;
private BigDecimal revenue;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class DailySales {
private String date;
private BigDecimal revenue;
private Long salesCount;
}

View File

@@ -0,0 +1,33 @@
package com.petshop.backend.dto.appointment;
import com.petshop.backend.entity.Appointment;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
@Data
public class AppointmentRequest {
@NotNull(message = "Customer ID is required")
private Long customerId;
@NotNull(message = "Service ID is required")
private Long serviceId;
@NotNull(message = "Appointment date is required")
private LocalDate appointmentDate;
@NotNull(message = "Appointment time is required")
private LocalTime appointmentTime;
@NotNull(message = "Status is required")
private Appointment.AppointmentStatus status;
@NotEmpty(message = "At least one pet must be specified")
private List<Long> petIds;
private String notes;
}

View File

@@ -0,0 +1,29 @@
package com.petshop.backend.dto.appointment;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AppointmentResponse {
private Long id;
private Long customerId;
private String customerName;
private Long serviceId;
private String serviceName;
private LocalDate appointmentDate;
private LocalTime appointmentTime;
private String status;
private List<String> petNames;
private List<Long> petIds;
private String notes;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,12 @@
package com.petshop.backend.dto.category;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class CategoryRequest {
@NotBlank(message = "Category name is required")
private String categoryName;
private String categoryDescription;
}

View File

@@ -0,0 +1,18 @@
package com.petshop.backend.dto.category;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CategoryResponse {
private Long id;
private String categoryName;
private String categoryDescription;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,12 @@
package com.petshop.backend.dto.common;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
@Data
public class BulkDeleteRequest {
@NotEmpty(message = "IDs list cannot be empty")
private List<Long> ids;
}

View File

@@ -0,0 +1,11 @@
package com.petshop.backend.dto.common;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class DropdownOption {
private Long id;
private String label;
}

View File

@@ -0,0 +1,17 @@
package com.petshop.backend.dto.customer;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class CustomerRequest {
@NotBlank(message = "Customer name is required")
private String customerName;
@Email(message = "Invalid email format")
private String customerEmail;
private String customerPhone;
private String customerAddress;
}

View File

@@ -0,0 +1,20 @@
package com.petshop.backend.dto.customer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CustomerResponse {
private Long id;
private String customerName;
private String customerEmail;
private String customerPhone;
private String customerAddress;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,21 @@
package com.petshop.backend.dto.inventory;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.Data;
@Data
public class InventoryRequest {
@NotNull(message = "Product ID is required")
private Long productId;
@NotNull(message = "Store ID is required")
private Long storeId;
@NotNull(message = "Quantity is required")
@PositiveOrZero(message = "Quantity must be zero or positive")
private Integer quantity;
@PositiveOrZero(message = "Reorder level must be zero or positive")
private Integer reorderLevel = 10;
}

View File

@@ -0,0 +1,24 @@
package com.petshop.backend.dto.inventory;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class InventoryResponse {
private Long id;
private Long productId;
private String productName;
private String categoryName;
private Long storeId;
private String storeName;
private Integer quantity;
private Integer reorderLevel;
private LocalDateTime lastRestocked;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,28 @@
package com.petshop.backend.dto.pet;
import com.petshop.backend.entity.Pet;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class PetRequest {
@NotBlank(message = "Pet name is required")
private String petName;
@NotBlank(message = "Species is required")
private String petSpecies;
private String petBreed;
@Positive(message = "Age must be positive")
private Integer petAge;
@NotNull(message = "Status is required")
private Pet.PetStatus petStatus;
private BigDecimal petPrice;
}

View File

@@ -0,0 +1,23 @@
package com.petshop.backend.dto.pet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PetResponse {
private Long id;
private String petName;
private String petSpecies;
private String petBreed;
private Integer petAge;
private String petStatus;
private BigDecimal petPrice;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,25 @@
package com.petshop.backend.dto.product;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ProductRequest {
@NotBlank(message = "Product name is required")
private String productName;
@NotNull(message = "Category ID is required")
private Long categoryId;
private String productDescription;
@NotNull(message = "Product price is required")
@Positive(message = "Price must be positive")
private BigDecimal productPrice;
private Boolean active = true;
}

View File

@@ -0,0 +1,23 @@
package com.petshop.backend.dto.product;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ProductResponse {
private Long id;
private String productName;
private Long categoryId;
private String categoryName;
private String productDescription;
private BigDecimal productPrice;
private Boolean active;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,18 @@
package com.petshop.backend.dto.productsupplier;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
@Data
public class ProductSupplierKey {
private Long productId;
private Long supplierId;
}
@Data
class BulkDeleteProductSupplierRequest {
@NotEmpty(message = "Keys list cannot be empty")
private List<ProductSupplierKey> keys;
}

View File

@@ -0,0 +1,26 @@
package com.petshop.backend.dto.productsupplier;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ProductSupplierRequest {
@NotNull(message = "Product ID is required")
private Long productId;
@NotNull(message = "Supplier ID is required")
private Long supplierId;
@NotNull(message = "Cost price is required")
@Positive(message = "Cost price must be positive")
private BigDecimal costPrice;
@PositiveOrZero(message = "Lead time must be zero or positive")
private Integer leadTimeDays;
private Boolean isPreferred = false;
}

View File

@@ -0,0 +1,23 @@
package com.petshop.backend.dto.productsupplier;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ProductSupplierResponse {
private Long productId;
private String productName;
private Long supplierId;
private String supplierName;
private BigDecimal costPrice;
private Integer leadTimeDays;
private Boolean isPreferred;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,39 @@
package com.petshop.backend.dto.purchaseorder;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PurchaseOrderResponse {
private Long id;
private Long supplierId;
private String supplierName;
private LocalDate orderDate;
private LocalDate expectedDelivery;
private String status;
private BigDecimal totalAmount;
private String notes;
private List<PurchaseOrderItemResponse> items;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class PurchaseOrderItemResponse {
private Long id;
private Long productId;
private String productName;
private Integer quantity;
private BigDecimal unitCost;
private BigDecimal subtotal;
}

View File

@@ -0,0 +1,28 @@
package com.petshop.backend.dto.refund;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Data;
import java.util.List;
@Data
public class RefundRequest {
@NotEmpty(message = "At least one item is required")
@Valid
private List<RefundItemRequest> items;
private String refundReason;
}
@Data
class RefundItemRequest {
@NotNull(message = "Sale item ID is required")
private Long saleItemId;
@NotNull(message = "Quantity is required")
@Positive(message = "Quantity must be positive")
private Integer quantity;
}

View File

@@ -0,0 +1,36 @@
package com.petshop.backend.dto.refund;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RefundResponse {
private Long id;
private Long saleId;
private LocalDateTime refundDate;
private BigDecimal refundAmount;
private String refundReason;
private Long processedBy;
private String processedByName;
private List<RefundItemResponse> items;
private LocalDateTime createdAt;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class RefundItemResponse {
private Long id;
private Long saleItemId;
private Long productId;
private String productName;
private Integer quantity;
private BigDecimal refundAmount;
}

View File

@@ -0,0 +1,38 @@
package com.petshop.backend.dto.sale;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
public class SaleRequest {
private Long customerId;
@NotNull(message = "Store ID is required")
private Long storeId;
private String paymentMethod;
private BigDecimal tax = BigDecimal.ZERO;
@NotEmpty(message = "At least one item is required")
@Valid
private List<SaleItemRequest> items;
private String notes;
}
@Data
class SaleItemRequest {
@NotNull(message = "Product ID is required")
private Long productId;
@NotNull(message = "Quantity is required")
@Positive(message = "Quantity must be positive")
private Integer quantity;
}

View File

@@ -0,0 +1,42 @@
package com.petshop.backend.dto.sale;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SaleResponse {
private Long id;
private LocalDateTime saleDate;
private Long employeeId;
private String employeeName;
private Long customerId;
private String customerName;
private Long storeId;
private String storeName;
private BigDecimal subtotal;
private BigDecimal tax;
private BigDecimal total;
private String paymentMethod;
private String notes;
private List<SaleItemResponse> items;
private LocalDateTime createdAt;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class SaleItemResponse {
private Long id;
private Long productId;
private String productName;
private Integer quantity;
private BigDecimal unitPrice;
private BigDecimal subtotal;
}

View File

@@ -0,0 +1,25 @@
package com.petshop.backend.dto.service;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ServiceRequest {
@NotBlank(message = "Service name is required")
private String serviceName;
private String serviceDescription;
@NotNull(message = "Service price is required")
@Positive(message = "Price must be positive")
private BigDecimal servicePrice;
@Positive(message = "Duration must be positive")
private Integer serviceDurationMinutes;
private Boolean active = true;
}

View File

@@ -0,0 +1,22 @@
package com.petshop.backend.dto.service;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ServiceResponse {
private Long id;
private String serviceName;
private String serviceDescription;
private BigDecimal servicePrice;
private Integer serviceDurationMinutes;
private Boolean active;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,20 @@
package com.petshop.backend.dto.supplier;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class SupplierRequest {
@NotBlank(message = "Supplier name is required")
private String supplierName;
private String supplierContact;
@Email(message = "Invalid email format")
private String supplierEmail;
private String supplierPhone;
private String supplierAddress;
private Boolean active = true;
}

View File

@@ -0,0 +1,22 @@
package com.petshop.backend.dto.supplier;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SupplierResponse {
private Long id;
private String supplierName;
private String supplierContact;
private String supplierEmail;
private String supplierPhone;
private String supplierAddress;
private Boolean active;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@@ -0,0 +1,29 @@
package com.petshop.backend.dto.user;
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;
import lombok.Data;
@Data
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")
private String fullName;
@Email(message = "Invalid email format")
private String email;
@NotNull(message = "Role is required")
private User.Role role;
private Boolean active = true;
}

View File

@@ -0,0 +1,21 @@
package com.petshop.backend.dto.user;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserResponse {
private Long id;
private String username;
private String fullName;
private String email;
private String role;
private Boolean active;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}