121 lines
4.0 KiB
Go
121 lines
4.0 KiB
Go
|
|
package validator
|
||
|
|
|
||
|
|
import (
|
||
|
|
"apskel-pos-be/internal/models"
|
||
|
|
"fmt"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"github.com/go-playground/validator/v10"
|
||
|
|
)
|
||
|
|
|
||
|
|
type OrderIngredientTransactionValidator interface {
|
||
|
|
ValidateCreateOrderIngredientTransactionRequest(req *models.CreateOrderIngredientTransactionRequest) error
|
||
|
|
ValidateUpdateOrderIngredientTransactionRequest(req *models.UpdateOrderIngredientTransactionRequest) error
|
||
|
|
ValidateListOrderIngredientTransactionsRequest(req *models.ListOrderIngredientTransactionsRequest) error
|
||
|
|
}
|
||
|
|
|
||
|
|
type OrderIngredientTransactionValidatorImpl struct {
|
||
|
|
validator *validator.Validate
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewOrderIngredientTransactionValidator() OrderIngredientTransactionValidator {
|
||
|
|
v := validator.New()
|
||
|
|
return &OrderIngredientTransactionValidatorImpl{
|
||
|
|
validator: v,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *OrderIngredientTransactionValidatorImpl) ValidateCreateOrderIngredientTransactionRequest(req *models.CreateOrderIngredientTransactionRequest) error {
|
||
|
|
if err := v.validator.Struct(req); err != nil {
|
||
|
|
var validationErrors []string
|
||
|
|
for _, err := range err.(validator.ValidationErrors) {
|
||
|
|
validationErrors = append(validationErrors, fmt.Sprintf("%s: %s", err.Field(), getValidationMessage(err)))
|
||
|
|
}
|
||
|
|
return fmt.Errorf("validation failed: %s", strings.Join(validationErrors, ", "))
|
||
|
|
}
|
||
|
|
|
||
|
|
// Custom validations
|
||
|
|
if req.GrossQty < req.NetQty {
|
||
|
|
return fmt.Errorf("gross quantity must be greater than or equal to net quantity")
|
||
|
|
}
|
||
|
|
|
||
|
|
expectedWasteQty := req.GrossQty - req.NetQty
|
||
|
|
if req.WasteQty != expectedWasteQty {
|
||
|
|
return fmt.Errorf("waste quantity must equal gross quantity minus net quantity")
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *OrderIngredientTransactionValidatorImpl) ValidateUpdateOrderIngredientTransactionRequest(req *models.UpdateOrderIngredientTransactionRequest) error {
|
||
|
|
if err := v.validator.Struct(req); err != nil {
|
||
|
|
var validationErrors []string
|
||
|
|
for _, err := range err.(validator.ValidationErrors) {
|
||
|
|
validationErrors = append(validationErrors, fmt.Sprintf("%s: %s", err.Field(), getValidationMessage(err)))
|
||
|
|
}
|
||
|
|
return fmt.Errorf("validation failed: %s", strings.Join(validationErrors, ", "))
|
||
|
|
}
|
||
|
|
|
||
|
|
// Custom validations for partial updates
|
||
|
|
if req.GrossQty != nil && req.NetQty != nil {
|
||
|
|
if *req.GrossQty < *req.NetQty {
|
||
|
|
return fmt.Errorf("gross quantity must be greater than or equal to net quantity")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if req.GrossQty != nil && req.NetQty != nil && req.WasteQty != nil {
|
||
|
|
expectedWasteQty := *req.GrossQty - *req.NetQty
|
||
|
|
if *req.WasteQty != expectedWasteQty {
|
||
|
|
return fmt.Errorf("waste quantity must equal gross quantity minus net quantity")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (v *OrderIngredientTransactionValidatorImpl) ValidateListOrderIngredientTransactionsRequest(req *models.ListOrderIngredientTransactionsRequest) error {
|
||
|
|
if err := v.validator.Struct(req); err != nil {
|
||
|
|
var validationErrors []string
|
||
|
|
for _, err := range err.(validator.ValidationErrors) {
|
||
|
|
validationErrors = append(validationErrors, fmt.Sprintf("%s: %s", err.Field(), getValidationMessage(err)))
|
||
|
|
}
|
||
|
|
return fmt.Errorf("validation failed: %s", strings.Join(validationErrors, ", "))
|
||
|
|
}
|
||
|
|
|
||
|
|
// Custom validations
|
||
|
|
if req.StartDate != nil && req.EndDate != nil {
|
||
|
|
if req.StartDate.After(*req.EndDate) {
|
||
|
|
return fmt.Errorf("start date must be before end date")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func getValidationMessage(err validator.FieldError) string {
|
||
|
|
switch err.Tag() {
|
||
|
|
case "required":
|
||
|
|
return "is required"
|
||
|
|
case "min":
|
||
|
|
return fmt.Sprintf("must be at least %s", err.Param())
|
||
|
|
case "max":
|
||
|
|
return fmt.Sprintf("must be at most %s", err.Param())
|
||
|
|
case "gt":
|
||
|
|
return fmt.Sprintf("must be greater than %s", err.Param())
|
||
|
|
case "gte":
|
||
|
|
return fmt.Sprintf("must be greater than or equal to %s", err.Param())
|
||
|
|
case "lt":
|
||
|
|
return fmt.Sprintf("must be less than %s", err.Param())
|
||
|
|
case "lte":
|
||
|
|
return fmt.Sprintf("must be less than or equal to %s", err.Param())
|
||
|
|
case "email":
|
||
|
|
return "must be a valid email address"
|
||
|
|
case "uuid":
|
||
|
|
return "must be a valid UUID"
|
||
|
|
case "len":
|
||
|
|
return fmt.Sprintf("must be exactly %s characters long", err.Param())
|
||
|
|
default:
|
||
|
|
return "is invalid"
|
||
|
|
}
|
||
|
|
}
|