174 lines
3.9 KiB
Go
174 lines
3.9 KiB
Go
|
|
package validator
|
||
|
|
|
||
|
|
import (
|
||
|
|
"apskel-pos-be/internal/constants"
|
||
|
|
"apskel-pos-be/internal/contract"
|
||
|
|
"fmt"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"github.com/go-playground/validator/v10"
|
||
|
|
"github.com/google/uuid"
|
||
|
|
)
|
||
|
|
|
||
|
|
type TableValidator struct {
|
||
|
|
validate *validator.Validate
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewTableValidator() *TableValidator {
|
||
|
|
return &TableValidator{
|
||
|
|
validate: validator.New(),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *TableValidator) ValidateCreateTableRequest(req contract.CreateTableRequest) error {
|
||
|
|
if err := v.validate.Struct(req); err != nil {
|
||
|
|
return formatValidationError(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Additional custom validations
|
||
|
|
if req.OutletID == uuid.Nil {
|
||
|
|
return fmt.Errorf("outlet_id is required")
|
||
|
|
}
|
||
|
|
|
||
|
|
if strings.TrimSpace(req.TableName) == "" {
|
||
|
|
return fmt.Errorf("table_name cannot be empty")
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.Capacity < 1 || req.Capacity > 20 {
|
||
|
|
return fmt.Errorf("capacity must be between 1 and 20")
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *TableValidator) ValidateUpdateTableRequest(req contract.UpdateTableRequest) error {
|
||
|
|
if err := v.validate.Struct(req); err != nil {
|
||
|
|
return formatValidationError(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Additional custom validations
|
||
|
|
if req.TableName != nil && strings.TrimSpace(*req.TableName) == "" {
|
||
|
|
return fmt.Errorf("table_name cannot be empty")
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.Capacity != nil && (*req.Capacity < 1 || *req.Capacity > 20) {
|
||
|
|
return fmt.Errorf("capacity must be between 1 and 20")
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.Status != nil {
|
||
|
|
if !isValidTableStatus(*req.Status) {
|
||
|
|
return fmt.Errorf("invalid table status: %s", *req.Status)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *TableValidator) ValidateOccupyTableRequest(req contract.OccupyTableRequest) error {
|
||
|
|
if err := v.validate.Struct(req); err != nil {
|
||
|
|
return formatValidationError(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Additional custom validations
|
||
|
|
if req.OrderID == uuid.Nil {
|
||
|
|
return fmt.Errorf("order_id is required")
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *TableValidator) ValidateReleaseTableRequest(req contract.ReleaseTableRequest) error {
|
||
|
|
if err := v.validate.Struct(req); err != nil {
|
||
|
|
return formatValidationError(err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Additional custom validations
|
||
|
|
if req.PaymentAmount < 0 {
|
||
|
|
return fmt.Errorf("payment_amount cannot be negative")
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *TableValidator) ValidateTableID(id string) error {
|
||
|
|
if id == "" {
|
||
|
|
return fmt.Errorf("table ID is required")
|
||
|
|
}
|
||
|
|
|
||
|
|
if _, err := uuid.Parse(id); err != nil {
|
||
|
|
return fmt.Errorf("invalid table ID format")
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *TableValidator) ValidateOutletID(id string) error {
|
||
|
|
if id == "" {
|
||
|
|
return fmt.Errorf("outlet ID is required")
|
||
|
|
}
|
||
|
|
|
||
|
|
if _, err := uuid.Parse(id); err != nil {
|
||
|
|
return fmt.Errorf("invalid outlet ID format")
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *TableValidator) ValidateListTablesQuery(query contract.ListTablesQuery) error {
|
||
|
|
// Validate pagination
|
||
|
|
if query.Page < 1 {
|
||
|
|
return fmt.Errorf("page must be greater than 0")
|
||
|
|
}
|
||
|
|
|
||
|
|
if query.Limit < 1 || query.Limit > 100 {
|
||
|
|
return fmt.Errorf("limit must be between 1 and 100")
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate organization_id if provided
|
||
|
|
if query.OrganizationID != "" {
|
||
|
|
if _, err := uuid.Parse(query.OrganizationID); err != nil {
|
||
|
|
return fmt.Errorf("invalid organization_id format")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate outlet_id if provided
|
||
|
|
if query.OutletID != "" {
|
||
|
|
if _, err := uuid.Parse(query.OutletID); err != nil {
|
||
|
|
return fmt.Errorf("invalid outlet_id format")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate status if provided
|
||
|
|
if query.Status != "" {
|
||
|
|
if !isValidTableStatus(query.Status) {
|
||
|
|
return fmt.Errorf("invalid table status: %s", query.Status)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Validate is_active if provided
|
||
|
|
if query.IsActive != "" {
|
||
|
|
if query.IsActive != "true" && query.IsActive != "false" {
|
||
|
|
return fmt.Errorf("is_active must be 'true' or 'false'")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func isValidTableStatus(status string) bool {
|
||
|
|
validStatuses := []string{
|
||
|
|
string(constants.TableStatusAvailable),
|
||
|
|
string(constants.TableStatusOccupied),
|
||
|
|
string(constants.TableStatusReserved),
|
||
|
|
string(constants.TableStatusCleaning),
|
||
|
|
string(constants.TableStatusMaintenance),
|
||
|
|
}
|
||
|
|
|
||
|
|
for _, validStatus := range validStatuses {
|
||
|
|
if status == validStatus {
|
||
|
|
return true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false
|
||
|
|
}
|