Files
ozon-mock/internal/handlers/finance.go
Rinat 842f87f576 Initial commit: ozon-mock Go server
- Mock Ozon Seller API endpoints
- Products, Postings, Finance, Returns, Analytics
- JSON fixtures for testing
- Docker support
- Gitea Actions CI/CD
2026-07-15 16:19:24 +03:00

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},
},
})
}