Files
jiu/backend/internal/handler/finance_test.go
T

114 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package handler
import (
"fmt"
"net/http"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/wangjia/jiu/backend/internal/model"
"github.com/wangjia/jiu/backend/testutil"
)
// Trend:近 N 月按 order_date 聚合出库(in)/入库(out)金额,多租户隔离
func TestFinanceHandler_Trend(t *testing.T) {
db := testutil.SetupTestDB()
shop := testutil.CreateTestShop(db, "FIN001")
other := testutil.CreateTestShop(db, "FIN001B")
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
warehouse := testutil.CreateTestWarehouse(db, shop.ID, "Main")
token := getAuthToken(user.ID, shop.ID, "admin")
r := setupProtectedRouter(db)
now := time.Now()
thisMonth := time.Date(now.Year(), now.Month(), 5, 0, 0, 0, 0, time.UTC)
lastMonth := thisMonth.AddDate(0, -1, 0)
mkOut := func(shopID uint64, date time.Time, amount float64) {
require.NoError(t, db.Create(&model.StockOutOrder{
TenantBase: model.TenantBase{ShopID: shopID},
OrderNo: fmt.Sprintf("CK-%d-%d", shopID, time.Now().UnixNano()),
WarehouseID: warehouse.ID,
OperatorID: user.ID,
Status: "approved",
OrderDate: model.Date{Time: date},
TotalAmount: amount,
}).Error)
}
mkIn := func(shopID uint64, date time.Time, amount float64) {
require.NoError(t, db.Create(&model.StockInOrder{
TenantBase: model.TenantBase{ShopID: shopID},
OrderNo: fmt.Sprintf("RK-%d-%d", shopID, time.Now().UnixNano()),
WarehouseID: warehouse.ID,
OperatorID: user.ID,
Status: "approved",
OrderDate: model.Date{Time: date},
TotalAmount: amount,
}).Error)
}
mkOut(shop.ID, thisMonth, 1000)
mkOut(shop.ID, thisMonth, 860)
mkOut(shop.ID, lastMonth, 500)
mkIn(shop.ID, thisMonth, 700)
mkOut(other.ID, thisMonth, 99999) // 别店数据不得串店
w := makeRequest(r, "GET", "/api/v1/finance/trend?months=2", token, nil)
require.Equal(t, http.StatusOK, w.Code)
data := parseResponse(w)["data"].([]interface{})
require.Len(t, data, 2)
prev := data[0].(map[string]interface{})
cur := data[1].(map[string]interface{})
assert.Equal(t, lastMonth.Format("2006-01"), prev["month"])
assert.Equal(t, float64(500), prev["in"])
assert.Equal(t, float64(0), prev["out"])
assert.Equal(t, thisMonth.Format("2006-01"), cur["month"])
assert.Equal(t, float64(1860), cur["in"])
assert.Equal(t, float64(700), cur["out"])
}
// ListRecords 日期区间:start_date/end_date 过滤 record_date(区间优先于 month
func TestFinanceHandler_ListRecords_DateRange(t *testing.T) {
db := testutil.SetupTestDB()
shop := testutil.CreateTestShop(db, "FIN002")
user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin")
token := getAuthToken(user.ID, shop.ID, "admin")
r := setupProtectedRouter(db)
mk := func(date string, amount float64) {
d, err := time.Parse("2006-01-02", date)
require.NoError(t, err)
require.NoError(t, db.Create(&model.FinanceRecord{
ShopID: shop.ID,
Type: "receipt",
Amount: amount,
Status: "closed",
OperatorID: user.ID,
RecordDate: d,
}).Error)
}
mk("2026-04-10", 100)
mk("2026-05-15", 200)
mk("2026-06-20", 300)
// 区间 [2026-05-01, 2026-06-30] → 命中 2 条
w := makeRequest(r, "GET",
"/api/v1/finance/records?start_date=2026-05-01&end_date=2026-06-30", token, nil)
require.Equal(t, http.StatusOK, w.Code)
assert.Equal(t, float64(2), parseResponse(w)["total"].(float64))
// 只给 start → 下界过滤
w = makeRequest(r, "GET",
"/api/v1/finance/records?start_date=2026-06-01", token, nil)
assert.Equal(t, float64(1), parseResponse(w)["total"].(float64))
// 区间优先于 monthmonth 会被忽略)
w = makeRequest(r, "GET",
"/api/v1/finance/records?start_date=2026-04-01&end_date=2026-04-30&month=2026-06",
token, nil)
assert.Equal(t, float64(1), parseResponse(w)["total"].(float64))
}