package validator import ( "errors" "strings" "apskel-pos-be/internal/constants" "apskel-pos-be/internal/contract" "github.com/google/uuid" ) type ExpenseValidator interface { ValidateCreateExpenseRequest(req *contract.CreateExpenseRequest) (error, string) ValidateUpdateExpenseRequest(req *contract.UpdateExpenseRequest) (error, string) ValidateListExpenseRequest(req *contract.ListExpenseRequest) (error, string) } type ExpenseValidatorImpl struct{} func NewExpenseValidator() *ExpenseValidatorImpl { return &ExpenseValidatorImpl{} } func (v *ExpenseValidatorImpl) ValidateCreateExpenseRequest(req *contract.CreateExpenseRequest) (error, string) { if req == nil { return errors.New("request body is required"), constants.MissingFieldErrorCode } if strings.TrimSpace(req.Receiver) == "" { return errors.New("receiver is required"), constants.MissingFieldErrorCode } if strings.TrimSpace(req.TransactionDate) == "" { return errors.New("transaction_date is required"), constants.MissingFieldErrorCode } if strings.TrimSpace(req.CodeNumber) == "" { return errors.New("code_number is required"), constants.MissingFieldErrorCode } if strings.TrimSpace(req.ChartOfAccountID) == "" { return errors.New("chart_of_account_id is required"), constants.MissingFieldErrorCode } if _, err := uuid.Parse(req.ChartOfAccountID); err != nil { return errors.New("chart_of_account_id must be a valid UUID"), constants.MalformedFieldErrorCode } if strings.TrimSpace(req.OutletID) == "" { return errors.New("outlet_id is required"), constants.MissingFieldErrorCode } if _, err := uuid.Parse(req.OutletID); err != nil { return errors.New("outlet_id must be a valid UUID"), constants.MalformedFieldErrorCode } if req.Total <= 0 { return errors.New("total must be greater than 0"), constants.MalformedFieldErrorCode } if req.Tax < 0 { return errors.New("tax cannot be negative"), constants.MalformedFieldErrorCode } return nil, "" } func (v *ExpenseValidatorImpl) ValidateUpdateExpenseRequest(req *contract.UpdateExpenseRequest) (error, string) { if req == nil { return errors.New("request body is required"), constants.MissingFieldErrorCode } if req.Receiver != nil && strings.TrimSpace(*req.Receiver) == "" { return errors.New("receiver cannot be empty"), constants.MalformedFieldErrorCode } if req.CodeNumber != nil && strings.TrimSpace(*req.CodeNumber) == "" { return errors.New("code_number cannot be empty"), constants.MalformedFieldErrorCode } if req.ChartOfAccountID != nil { if strings.TrimSpace(*req.ChartOfAccountID) == "" { return errors.New("chart_of_account_id cannot be empty"), constants.MalformedFieldErrorCode } if _, err := uuid.Parse(*req.ChartOfAccountID); err != nil { return errors.New("chart_of_account_id must be a valid UUID"), constants.MalformedFieldErrorCode } } if req.OutletID != nil { if strings.TrimSpace(*req.OutletID) == "" { return errors.New("outlet_id cannot be empty"), constants.MalformedFieldErrorCode } if _, err := uuid.Parse(*req.OutletID); err != nil { return errors.New("outlet_id must be a valid UUID"), constants.MalformedFieldErrorCode } } if req.Total != nil && *req.Total <= 0 { return errors.New("total must be greater than 0"), constants.MalformedFieldErrorCode } if req.Tax != nil && *req.Tax < 0 { return errors.New("tax cannot be negative"), constants.MalformedFieldErrorCode } return nil, "" } func (v *ExpenseValidatorImpl) ValidateListExpenseRequest(req *contract.ListExpenseRequest) (error, string) { if req == nil { return errors.New("request body is required"), constants.MissingFieldErrorCode } if req.Page < 1 { return errors.New("page must be at least 1"), constants.MalformedFieldErrorCode } if req.Limit < 1 || req.Limit > 100 { return errors.New("limit must be between 1 and 100"), constants.MalformedFieldErrorCode } return nil, "" }