test_lq_inventory_update.sh
7.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#!/bin/bash
# 库存更新接口(PUT /api/Extend/LqInventory/Update)测试脚本
# 覆盖:采购入库(stockInType=2) 与 普通入库(stockInType=1) 的价格变更逻辑
# 测试前请确保后端服务已启动(如 http://localhost:2011)
set -e
BASE_URL="${BASE_URL:-http://localhost:2011}"
API_UPDATE="${BASE_URL}/api/Extend/LqInventory/Update"
API_GETLIST="${BASE_URL}/api/Extend/LqInventory/GetList"
echo "=========================================="
echo "库存更新接口测试 (LqInventory/Update)"
echo "BASE_URL=$BASE_URL"
echo "=========================================="
# 获取 Token
echo ""
echo "正在获取 Token..."
LOGIN_RESPONSE=$(curl -s -X POST "${BASE_URL}/api/oauth/Login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "account=admin&password=e10adc3949ba59abbe56e057f20f883e")
TOKEN=$(echo "$LOGIN_RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin).get('data',{}).get('token',''))" 2>/dev/null)
if [ -z "$TOKEN" ]; then
echo "❌ 获取 Token 失败"
echo "响应: $LOGIN_RESPONSE"
exit 1
fi
echo "✅ Token 获取成功"
# 获取一条有效库存记录(用于更新测试)
echo ""
echo "正在获取一条库存记录(用于更新)..."
LIST_RESPONSE=$(curl -s -X GET "${API_GETLIST}?currentPage=1&pageSize=1" -H "Authorization: $TOKEN")
CODE=$(echo "$LIST_RESPONSE" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('code', 0))" 2>/dev/null)
if [ "$CODE" != "200" ]; then
echo "❌ GetList 失败 (code=$CODE)"
echo "$LIST_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$LIST_RESPONSE"
exit 1
fi
INVENTORY_ID=$(echo "$LIST_RESPONSE" | python3 -c "
import sys, json
d = json.load(sys.stdin)
lst = d.get('data',{}).get('list') or d.get('data',{}).get('data',[]) or []
if not lst:
sys.exit(1)
print(lst[0].get('id',''))
" 2>/dev/null)
PRODUCT_ID=$(echo "$LIST_RESPONSE" | python3 -c "
import sys, json
d = json.load(sys.stdin)
lst = d.get('data',{}).get('list') or d.get('data',{}).get('data',[]) or []
if not lst:
sys.exit(1)
print(lst[0].get('productId',''))
" 2>/dev/null)
if [ -z "$INVENTORY_ID" ] || [ -z "$PRODUCT_ID" ]; then
echo "⚠️ 未获取到库存记录,将使用占位 ID 仅验证接口可达性与参数校验"
INVENTORY_ID="${INVENTORY_ID:-test-invalid-id}"
PRODUCT_ID="${PRODUCT_ID:-test-invalid-product}"
fi
# 测试1:采购入库更新(stockInType=2,带单价与金额)
echo ""
echo "=== 测试1: 采购入库更新 (stockInType=2, purchaseUnitPrice=50, finalAmount=5000) ==="
BODY1=$(cat <<EOF
{
"id": "$INVENTORY_ID",
"productId": "$PRODUCT_ID",
"quantity": 100,
"stockInType": 2,
"purchaseUnitPrice": 50.00,
"finalAmount": 5000.00
}
EOF
)
RESP1=$(curl -s -w "\n%{http_code}" -X PUT "$API_UPDATE" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d "$BODY1")
HTTP1=$(echo "$RESP1" | tail -n1)
BODY1_RESP=$(echo "$RESP1" | sed '$d')
CODE1=$(echo "$BODY1_RESP" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('code', d.get('statusCode', 0)))" 2>/dev/null || echo "0")
echo "HTTP: $HTTP1, 业务 code: $CODE1"
echo "$BODY1_RESP" | python3 -m json.tool 2>/dev/null || echo "$BODY1_RESP"
if [ "$HTTP1" = "200" ] && [ "$CODE1" = "200" ]; then
echo "✅ 测试1 通过:采购入库更新成功"
else
if [ "$INVENTORY_ID" = "test-invalid-id" ]; then
echo "⚠️ 预期失败(无有效库存ID),接口与参数格式正常"
else
echo "❌ 测试1 失败"
exit 1
fi
fi
# 测试2:普通入库更新(stockInType=1,带单价与金额)
echo ""
echo "=== 测试2: 普通入库更新 (stockInType=1, purchaseUnitPrice=30, finalAmount=3000) ==="
BODY2=$(cat <<EOF
{
"id": "$INVENTORY_ID",
"productId": "$PRODUCT_ID",
"quantity": 100,
"stockInType": 1,
"purchaseUnitPrice": 30.00,
"finalAmount": 3000.00
}
EOF
)
RESP2=$(curl -s -w "\n%{http_code}" -X PUT "$API_UPDATE" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d "$BODY2")
HTTP2=$(echo "$RESP2" | tail -n1)
BODY2_RESP=$(echo "$RESP2" | sed '$d')
CODE2=$(echo "$BODY2_RESP" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('code', d.get('statusCode', 0)))" 2>/dev/null || echo "0")
echo "HTTP: $HTTP2, 业务 code: $CODE2"
echo "$BODY2_RESP" | python3 -m json.tool 2>/dev/null || echo "$BODY2_RESP"
if [ "$HTTP2" = "200" ] && [ "$CODE2" = "200" ]; then
echo "✅ 测试2 通过:普通入库价格变更成功"
else
if [ "$INVENTORY_ID" = "test-invalid-id" ]; then
echo "⚠️ 预期失败(无有效库存ID),接口与参数格式正常"
else
echo "❌ 测试2 失败"
exit 1
fi
fi
# 测试3:参数校验(数量<=0 应报错)
echo ""
echo "=== 测试3: 参数校验(quantity=0 应返回错误) ==="
BODY3=$(cat <<EOF
{
"id": "$INVENTORY_ID",
"productId": "$PRODUCT_ID",
"quantity": 0,
"stockInType": 1
}
EOF
)
RESP3=$(curl -s -X PUT "$API_UPDATE" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d "$BODY3")
CODE3=$(echo "$RESP3" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('code', 200))" 2>/dev/null || echo "200")
echo "业务 code: $CODE3 (预期非 200)"
if [ "$CODE3" != "200" ]; then
echo "✅ 测试3 通过:数量校验生效"
else
echo "⚠️ 测试3:接口未对 quantity<=0 返回错误(请确认业务是否允许)"
fi
# 测试4:验证更新后加权平均单价计算正确(与 RecalculateProductAveragePriceAsync 一致)
if [ "$INVENTORY_ID" != "test-invalid-id" ] && [ -n "$PRODUCT_ID" ]; then
echo ""
echo "=== 测试4: 验证加权平均单价计算 ==="
API_GETINFO="${BASE_URL}/api/Extend/LqProduct/GetInfo"
INFO_RESP=$(curl -s -X GET "${API_GETINFO}?id=${PRODUCT_ID}" -H "Authorization: $TOKEN")
LIST_FULL=$(curl -s -X GET "${API_GETLIST}?productId=${PRODUCT_ID}¤tPage=1&pageSize=100" -H "Authorization: $TOKEN")
VERIFY=$(echo "$INFO_RESP
$LIST_FULL" | python3 -c "
import sys, json
lines = sys.stdin.read().strip().split('\n')
if len(lines) < 2:
print('FAIL: no data')
sys.exit(1)
info = json.loads(lines[0])
lst_data = json.loads(lines[1])
if info.get('code') != 200:
print('FAIL: GetInfo code', info.get('code'))
sys.exit(1)
lst = lst_data.get('data',{}).get('list') or lst_data.get('data',{}).get('data',[]) or []
# 产品基础价(无 FinalAmount/PurchaseUnitPrice 时用);产品当前平均单价(接口返回)
product_price = float(info.get('data',{}).get('price') or 0)
product_avg = float(info.get('data',{}).get('averagePrice') or 0)
# 与 RecalculateProductAveragePriceAsync 一致:优先 FinalAmount/Quantity,其次 PurchaseUnitPrice,最后 Product.Price
total_amount = 0
total_qty = 0
for row in lst:
qty = int(row.get('quantity') or 0)
if qty <= 0:
continue
fa = row.get('finalAmount')
pu = row.get('purchaseUnitPrice')
if fa is not None and float(fa or 0) > 0:
unit = float(fa) / qty
elif pu is not None and float(pu or 0) > 0:
unit = float(pu)
else:
unit = product_price
total_amount += unit * qty
total_qty += qty
expected_avg = (total_amount / total_qty) if total_qty > 0 else product_price
diff = abs(expected_avg - product_avg) if product_avg else abs(expected_avg)
# 允许四舍五入误差
ok = diff < 0.02
print('OK' if ok else 'FAIL')
print('expected_avg=%.4f product_avg=%.4f total_amount=%.2f total_qty=%d' % (expected_avg, product_avg, total_amount, total_qty))
" 2>/dev/null)
VERIFY_OK=$(echo "$VERIFY" | head -1)
VERIFY_DETAIL=$(echo "$VERIFY" | tail -1)
if [ "$VERIFY_OK" = "OK" ]; then
echo "✅ 测试4 通过:加权平均单价与接口返回一致 ($VERIFY_DETAIL)"
else
echo "❌ 测试4 失败:加权平均与产品平均单价不一致"
echo " $VERIFY_DETAIL"
exit 1
fi
else
echo ""
echo "=== 测试4: 跳过(无有效库存/产品ID) ==="
fi
echo ""
echo "=========================================="
echo "库存更新接口测试完成"
echo "=========================================="