- Mock Ozon Seller API endpoints - Products, Postings, Finance, Returns, Analytics - JSON fixtures for testing - Docker support - Gitea Actions CI/CD
181 lines
4.7 KiB
Go
181 lines
4.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// FinanceTransactionListRequest - POST /v1/finance/transaction/list
|
|
type FinanceTransactionListRequest struct {
|
|
Filter struct {
|
|
Since string `json:"since"`
|
|
To string `json:"to"`
|
|
TransactionType string `json:"transaction_type"`
|
|
PostingNumber []string `json:"posting_number"`
|
|
} `json:"filter"`
|
|
Limit int `json:"limit"`
|
|
}
|
|
|
|
type Transaction struct {
|
|
TransactionType string `json:"transaction_type"`
|
|
Amount float64 `json:"amount"`
|
|
CurrencyCode string `json:"currency_code"`
|
|
PostingNumber string `json:"posting_number,omitempty"`
|
|
OrderID int64 `json:"order_id,omitempty"`
|
|
Items []TransactionItem `json:"items,omitempty"`
|
|
CreatedAt string `json:"created_at"`
|
|
}
|
|
|
|
type TransactionItem struct {
|
|
Type string `json:"type"`
|
|
Amount float64 `json:"amount"`
|
|
Quantity int `json:"quantity,omitempty"`
|
|
ProductID int64 `json:"product_id,omitempty"`
|
|
OfferID string `json:"offer_id,omitempty"`
|
|
}
|
|
|
|
func FinanceTransactionList(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
http.Error(w, "method not allowed", 405)
|
|
return
|
|
}
|
|
|
|
var req FinanceTransactionListRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
writeError(w, 400, "invalid json")
|
|
return
|
|
}
|
|
|
|
transactions := GetTransactionsFixtures()
|
|
|
|
if req.Limit == 0 {
|
|
req.Limit = 100
|
|
}
|
|
|
|
if len(transactions) > req.Limit {
|
|
transactions = transactions[:req.Limit]
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]any{
|
|
"transactions": transactions,
|
|
"total": len(transactions),
|
|
})
|
|
}
|
|
|
|
// FinancePayoutListRequest - POST /v1/finance/payout/list
|
|
type FinancePayoutListRequest struct {
|
|
Filter struct {
|
|
Since string `json:"since"`
|
|
To string `json:"to"`
|
|
} `json:"filter"`
|
|
Limit int `json:"limit"`
|
|
}
|
|
|
|
type Payout struct {
|
|
PayoutID int64 `json:"payout_id"`
|
|
Type string `json:"type"`
|
|
Status string `json:"status"`
|
|
Amount float64 `json:"amount"`
|
|
CurrencyCode string `json:"currency_code"`
|
|
CreatedAt string `json:"created_at"`
|
|
OperationsCount int `json:"operations_count"`
|
|
}
|
|
|
|
func FinancePayoutList(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
http.Error(w, "method not allowed", 405)
|
|
return
|
|
}
|
|
|
|
var req FinancePayoutListRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
writeError(w, 400, "invalid json")
|
|
return
|
|
}
|
|
|
|
payouts := GetPayoutsFixtures()
|
|
|
|
if req.Limit == 0 {
|
|
req.Limit = 100
|
|
}
|
|
|
|
if len(payouts) > req.Limit {
|
|
payouts = payouts[:req.Limit]
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]any{
|
|
"payouts": payouts,
|
|
"total": len(payouts),
|
|
})
|
|
}
|
|
|
|
// AnalyticsDataRequest - POST /v1/analytics/data
|
|
type AnalyticsDataRequest struct {
|
|
DateFrom string `json:"date_from"`
|
|
DateTo string `json:"date_to"`
|
|
Metrics []string `json:"metrics"`
|
|
Dimension []string `json:"dimension"`
|
|
}
|
|
|
|
func AnalyticsData(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
http.Error(w, "method not allowed", 405)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(map[string]any{
|
|
"data": []map[string]any{
|
|
{
|
|
"date": time.Now().Format("2006-01-02"),
|
|
"orders_count": 42,
|
|
"revenue": 125000.50,
|
|
"avg_order": 2976.20,
|
|
},
|
|
},
|
|
"total": 1,
|
|
})
|
|
}
|
|
|
|
// TurnoverStocksRequest - POST /v1/analytics/turnover/stocks
|
|
type TurnoverStocksRequest struct {
|
|
Date string `json:"date"`
|
|
SKU []string `json:"sku"`
|
|
}
|
|
|
|
type TurnoverStocksResponse struct {
|
|
Items []struct {
|
|
SKU string `json:"sku"`
|
|
ProductID int64 `json:"product_id"`
|
|
OnHand int `json:"orders_count_canceled"`
|
|
Reserved int `json:"reserved"`
|
|
InWayToCustomer int `json:"in_way_to_customer"`
|
|
InWayFromCustomer int `json:"in_way_from_customer"`
|
|
} `json:"items"`
|
|
}
|
|
|
|
func TurnoverStocks(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodPost {
|
|
http.Error(w, "method not allowed", 405)
|
|
return
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(TurnoverStocksResponse{
|
|
Items: []struct {
|
|
SKU string `json:"sku"`
|
|
ProductID int64 `json:"product_id"`
|
|
OnHand int `json:"orders_count_canceled"`
|
|
Reserved int `json:"reserved"`
|
|
InWayToCustomer int `json:"in_way_to_customer"`
|
|
InWayFromCustomer int `json:"in_way_from_customer"`
|
|
}{
|
|
{SKU: "TEST-SKU-001", ProductID: 99001234001, OnHand: 150, Reserved: 0, InWayToCustomer: 10, InWayFromCustomer: 2},
|
|
{SKU: "TEST-SKU-002", ProductID: 99001234002, OnHand: 75, Reserved: 5, InWayToCustomer: 15, InWayFromCustomer: 1},
|
|
},
|
|
})
|
|
}
|