196 lines
5.2 KiB
Go
196 lines
5.2 KiB
Go
package models
|
|
|
|
import (
|
|
"database/sql"
|
|
"database/sql/driver"
|
|
"encoding/json"
|
|
"time"
|
|
)
|
|
|
|
// NullableInt32 is a custom type to replace sql.NullInt32 for swagger compatibility
|
|
type NullableInt32 struct {
|
|
Int32 int32 `json:"int32,omitempty"`
|
|
Valid bool `json:"valid"`
|
|
}
|
|
|
|
// Scan implements the sql.Scanner interface for NullableInt32
|
|
func (n *NullableInt32) Scan(value interface{}) error {
|
|
var ni sql.NullInt32
|
|
if err := ni.Scan(value); err != nil {
|
|
return err
|
|
}
|
|
n.Int32 = ni.Int32
|
|
n.Valid = ni.Valid
|
|
return nil
|
|
}
|
|
|
|
// Value implements the driver.Valuer interface for NullableInt32
|
|
func (n NullableInt32) Value() (driver.Value, error) {
|
|
if !n.Valid {
|
|
return nil, nil
|
|
}
|
|
return n.Int32, nil
|
|
}
|
|
|
|
// Order represents the data structure for the order table
|
|
type Order struct {
|
|
ID string `json:"id" db:"id"`
|
|
Status string `json:"status" db:"status"`
|
|
Sort NullableInt32 `json:"sort,omitempty" db:"sort"`
|
|
UserCreated sql.NullString `json:"user_created,omitempty" db:"user_created"`
|
|
DateCreated sql.NullTime `json:"date_created,omitempty" db:"date_created"`
|
|
UserUpdated sql.NullString `json:"user_updated,omitempty" db:"user_updated"`
|
|
DateUpdated sql.NullTime `json:"date_updated,omitempty" db:"date_updated"`
|
|
Name sql.NullString `json:"name,omitempty" db:"name"`
|
|
}
|
|
|
|
// Custom JSON marshaling for Order
|
|
func (r Order) MarshalJSON() ([]byte, error) {
|
|
type Alias Order
|
|
aux := &struct {
|
|
Sort *int `json:"sort,omitempty"`
|
|
UserCreated *string `json:"user_created,omitempty"`
|
|
DateCreated *time.Time `json:"date_created,omitempty"`
|
|
UserUpdated *string `json:"user_updated,omitempty"`
|
|
DateUpdated *time.Time `json:"date_updated,omitempty"`
|
|
Name *string `json:"name,omitempty"`
|
|
*Alias
|
|
}{
|
|
Alias: (*Alias)(&r),
|
|
}
|
|
|
|
if r.Sort.Valid {
|
|
sort := int(r.Sort.Int32)
|
|
aux.Sort = &sort
|
|
}
|
|
if r.UserCreated.Valid {
|
|
aux.UserCreated = &r.UserCreated.String
|
|
}
|
|
if r.DateCreated.Valid {
|
|
aux.DateCreated = &r.DateCreated.Time
|
|
}
|
|
if r.UserUpdated.Valid {
|
|
aux.UserUpdated = &r.UserUpdated.String
|
|
}
|
|
if r.DateUpdated.Valid {
|
|
aux.DateUpdated = &r.DateUpdated.Time
|
|
}
|
|
if r.Name.Valid {
|
|
aux.Name = &r.Name.String
|
|
}
|
|
|
|
return json.Marshal(aux)
|
|
}
|
|
|
|
// Helper methods
|
|
func (r *Order) GetName() string {
|
|
if r.Name.Valid {
|
|
return r.Name.String
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Response struct for GET by ID
|
|
type OrderGetByIDResponse struct {
|
|
Message string `json:"message"`
|
|
Data *Order `json:"data"`
|
|
}
|
|
|
|
// Enhanced GET response with pagination and aggregation
|
|
type OrderGetResponse struct {
|
|
Message string `json:"message"`
|
|
Data []Order `json:"data"`
|
|
Meta MetaResponse `json:"meta"`
|
|
Summary *AggregateData `json:"summary,omitempty"`
|
|
}
|
|
|
|
// Request struct for create
|
|
type OrderCreateRequest struct {
|
|
Status string `json:"status" validate:"required,oneof=draft active inactive"`
|
|
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
|
}
|
|
|
|
// Response struct for create
|
|
type OrderCreateResponse struct {
|
|
Message string `json:"message"`
|
|
Data *Order `json:"data"`
|
|
}
|
|
|
|
// Update request
|
|
type OrderUpdateRequest struct {
|
|
ID string `json:"-" validate:"required,uuid4"` // ID dari URL path
|
|
Status string `json:"status" validate:"required,oneof=draft active inactive"`
|
|
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
|
}
|
|
|
|
// Response struct for update
|
|
type OrderUpdateResponse struct {
|
|
Message string `json:"message"`
|
|
Data *Order `json:"data"`
|
|
}
|
|
|
|
// Response struct for delete
|
|
type OrderDeleteResponse struct {
|
|
Message string `json:"message"`
|
|
ID string `json:"id"`
|
|
}
|
|
|
|
// Metadata for pagination
|
|
type MetaResponse struct {
|
|
Limit int `json:"limit"`
|
|
Offset int `json:"offset"`
|
|
Total int `json:"total"`
|
|
TotalPages int `json:"total_pages"`
|
|
CurrentPage int `json:"current_page"`
|
|
HasNext bool `json:"has_next"`
|
|
HasPrev bool `json:"has_prev"`
|
|
}
|
|
|
|
// Aggregate data for summary
|
|
type AggregateData struct {
|
|
TotalActive int `json:"total_active"`
|
|
TotalDraft int `json:"total_draft"`
|
|
TotalInactive int `json:"total_inactive"`
|
|
ByStatus map[string]int `json:"by_status"`
|
|
LastUpdated *time.Time `json:"last_updated,omitempty"`
|
|
CreatedToday int `json:"created_today"`
|
|
UpdatedToday int `json:"updated_today"`
|
|
}
|
|
|
|
// Error response
|
|
type ErrorResponse struct {
|
|
Error string `json:"error"`
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
Timestamp time.Time `json:"timestamp"`
|
|
}
|
|
|
|
// Filter struct for query parameters
|
|
type OrderFilter struct {
|
|
Status *string `json:"status,omitempty" form:"status"`
|
|
Search *string `json:"search,omitempty" form:"search"`
|
|
DateFrom *time.Time `json:"date_from,omitempty" form:"date_from"`
|
|
DateTo *time.Time `json:"date_to,omitempty" form:"date_to"`
|
|
}
|
|
|
|
// Validation constants
|
|
const (
|
|
StatusDraft = "draft"
|
|
StatusActive = "active"
|
|
StatusInactive = "inactive"
|
|
StatusDeleted = "deleted"
|
|
)
|
|
|
|
// ValidStatuses for validation
|
|
var ValidStatuses = []string{StatusDraft, StatusActive, StatusInactive}
|
|
|
|
// IsValidStatus helper function
|
|
func IsValidStatus(status string) bool {
|
|
for _, validStatus := range ValidStatuses {
|
|
if status == validStatus {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|