package handlers import ( "encoding/json" "net/http" "time" ) // PostingFBSListRequest - POST /v2/posting/fbs/list type PostingFBSListRequest struct { Dir string `json:"dir"` // "asc" or "desc" Filter struct { Since string `json:"since"` To string `json:"to"` Status string `json:"status"` PostingNumber []string `json:"posting_number"` DeliveryMethod int `json:"delivery_method"` } `json:"filter"` Limit int `json:"limit"` With struct { AnalyticsData bool `json:"analytics_data"` } `json:"with"` } type PostingItem struct { ProductID int64 `json:"product_id"` OfferID string `json:"offer_id"` Name string `json:"name"` Quantity int `json:"quantity"` Price float64 `json:"price"` ItemsCount int `json:"items_count"` } type Posting struct { PostingNumber string `json:"posting_number"` OrderID int64 `json:"order_id"` OrderNumber string `json:"order_number"` Status string `json:"status"` Products []PostingItem `json:"products"` AnalyticsData any `json:"analytics_data,omitempty"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` Warehouses []int64 `json:"warehouses"` WarehouseID int64 `json:"warehouse_id"` OrderType string `json:"order_type"` } func PostingFBSList(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", 405) return } var req PostingFBSListRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, 400, "invalid json") return } if req.Limit == 0 { req.Limit = 100 } if req.Limit > 1000 { req.Limit = 1000 } postings := GetPostingsFixtures() // Filter by status if provided if req.Filter.Status != "" { filtered := make([]Posting, 0) for _, p := range postings { if p.Status == req.Filter.Status { filtered = append(filtered, p) } } postings = filtered } // Filter by posting_number if provided if len(req.Filter.PostingNumber) > 0 { filtered := make([]Posting, 0) for _, p := range postings { for _, num := range req.Filter.PostingNumber { if p.PostingNumber == num { filtered = append(filtered, p) break } } } postings = filtered } // Apply limit if len(postings) > req.Limit { postings = postings[:req.Limit] } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]any{ "postings": postings, "total": len(postings), }) } // PostingFBSGetRequest - POST /v2/posting/fbs/get type PostingFBSGetRequest struct { PostingNumber string `json:"posting_number"` } func PostingFBSGet(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", 405) return } var req PostingFBSGetRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, 400, "invalid json") return } postings := GetPostingsFixtures() for _, p := range postings { if p.PostingNumber == req.PostingNumber { w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]any{ "posting": p, }) return } } writeError(w, 404, "posting not found") } // CancelPostingRequest - POST /v1/posting/fbs/cancel type CancelPostingRequest struct { PostingNumber string `json:"posting_number"` } type CancelPostingResponse struct { PostingNumber string `json:"posting_number"` Status string `json:"status"` } func CancelPosting(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", 405) return } var req CancelPostingRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, 400, "invalid json") return } if req.PostingNumber == "" { writeError(w, 400, "posting_number is required") return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(CancelPostingResponse{ PostingNumber: req.PostingNumber, Status: "cancelled", }) } // Returns type ReturnsListRequest struct { Filter struct { Since string `json:"since"` To string `json:"to"` Status string `json:"status"` ReturnID int64 `json:"return_id"` } `json:"filter"` Limit int `json:"limit"` } type ReturnItem struct { ProductID int64 `json:"product_id"` OfferID string `json:"offer_id"` Name string `json:"name"` Quantity int `json:"quantity"` IsOptional bool `json:"is_optional"` } type Return struct { ReturnID int64 `json:"return_id"` PostingNumber string `json:"posting_number"` Status string `json:"status"` Reason string `json:"reason"` ReasonID int64 `json:"reason_id"` CreatedAt string `json:"created_at"` RejectedAt string `json:"rejected_at,omitempty"` DeliveredAt string `json:"delivered_at,omitempty"` Items []ReturnItem `json:"items"` } func ReturnsList(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "method not allowed", 405) return } var req ReturnsListRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, 400, "invalid json") return } returns := GetReturnsFixtures() if req.Limit == 0 { req.Limit = 100 } if len(returns) > req.Limit { returns = returns[:req.Limit] } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]any{ "result": returns, "total": len(returns), }) } func init() { // Ensure timestamps are consistent _ = time.RFC3339 }