package handlers import ( "encoding/json" "net/http" "time" ) type PostingFBSListRequest struct { Dir string `json:"dir"` 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() if req.Filter.Since != "" { sinceTs := parseTimeOrZero(req.Filter.Since) filtered := make([]Posting, 0) for _, p := range postings { ts := parseTimeOrZero(p.CreatedAt) if ts >= sinceTs { filtered = append(filtered, p) } } postings = filtered } if req.Filter.To != "" { toTs := parseTimeOrZero(req.Filter.To) filtered := make([]Posting, 0) for _, p := range postings { ts := parseTimeOrZero(p.CreatedAt) if ts <= toTs { filtered = append(filtered, p) } } postings = filtered } if req.Filter.Status != "" { filtered := make([]Posting, 0) for _, p := range postings { if p.Status == req.Filter.Status { filtered = append(filtered, p) } } postings = filtered } 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 } if req.Dir == "asc" { for i, j := 0, len(postings)-1; i < j; i, j = i+1, j-1 { postings[i], postings[j] = postings[j], postings[i] } } if req.With.AnalyticsData { for i := range postings { postings[i].AnalyticsData = map[string]any{ "commission": 5.0, "delivery": 150.00, "return": 0, } } } 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), }) } 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") } 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 } postings := GetPostingsFixtures() found := false for _, p := range postings { if p.PostingNumber == req.PostingNumber { found = true break } } if !found { writeError(w, 404, "posting not found") return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(CancelPostingResponse{ PostingNumber: req.PostingNumber, Status: "cancelled", }) } 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.Filter.Since != "" { sinceTs := parseTimeOrZero(req.Filter.Since) filtered := make([]Return, 0) for _, ret := range returns { ts := parseTimeOrZero(ret.CreatedAt) if ts >= sinceTs { filtered = append(filtered, ret) } } returns = filtered } if req.Filter.To != "" { toTs := parseTimeOrZero(req.Filter.To) filtered := make([]Return, 0) for _, ret := range returns { ts := parseTimeOrZero(ret.CreatedAt) if ts <= toTs { filtered = append(filtered, ret) } } returns = filtered } if req.Filter.Status != "" { filtered := make([]Return, 0) for _, ret := range returns { if ret.Status == req.Filter.Status { filtered = append(filtered, ret) } } returns = filtered } if req.Filter.ReturnID > 0 { filtered := make([]Return, 0) for _, ret := range returns { if ret.ReturnID == req.Filter.ReturnID { filtered = append(filtered, ret) } } returns = filtered } 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 parseTimeOrZero(s string) int64 { t, err := time.Parse(time.RFC3339, s) if err != nil { return 0 } return t.Unix() } func init() { _ = time.RFC3339 }