baseline: 批次A-D 成果 + membership 半成品(测试红)

This commit is contained in:
agent
2026-09-11 23:11:35 +08:00
commit b3f3095d53
311 changed files with 40540 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
#!/bin/bash
# dealerhub 全业务链端到端冒烟(进货 → 付款 → 销售 → 收款)
# 需先 smoke.sh 跑过;使用 P999/W999/S999/C999 等已建实体
set -e
BASE=${1:-http://192.168.5.7:18050}
TENANT="default"
SUFFIX=$(date +%H%M%S)
echo "===== dealerhub 完整业务链冒烟 ====="
echo "BASE=$BASE SUFFIX=$SUFFIX"
echo ""
TOKEN=$(curl -s -X POST $BASE/api/v1/auth/token/ \
-H 'Content-Type: application/json' \
-d '{"username":"alice","password":"alice12345"}' | python3 -c "import sys,json; print(json.load(sys.stdin)['access'])")
echo "[0] TOKEN 长度: ${#TOKEN}"
echo ""
H_AUTH=("-H" "Authorization: Bearer $TOKEN" "-H" "X-Tenant-Id: $TENANT" "-H" "Content-Type: application/json")
# 创建基础实体(每次用 SUFFIX 区分)
echo "[1] 创建测试实体(SUFFIX=$SUFFIX)"
P=$(curl -s -X POST $BASE/api/v1/catalog/products/ "${H_AUTH[@]}" \
-d "{\"code\":\"P$SUFFIX\",\"name\":\"测试商品\",\"status\":\"active\"}" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id', 'ERR'))")
echo " product id=$P"
W=$(curl -s -X POST $BASE/api/v1/inventory/warehouses/ "${H_AUTH[@]}" \
-d "{\"code\":\"W$SUFFIX\",\"name\":\"测试仓\"}" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id', 'ERR'))")
echo " warehouse id=$W"
SUP=$(curl -s -X POST $BASE/api/v1/partner/suppliers/ "${H_AUTH[@]}" \
-d "{\"code\":\"S$SUFFIX\",\"name\":\"测试供应商\"}" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id', 'ERR'))")
echo " supplier id=$SUP"
CUS=$(curl -s -X POST $BASE/api/v1/partner/customers/ "${H_AUTH[@]}" \
-d "{\"code\":\"C$SUFFIX\",\"name\":\"测试客户\"}" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('id', 'ERR'))")
echo " customer id=$CUS"
echo ""
# 进货:通过 docker exec 在容器内调用 services(API 没暴露 create_bill)
echo "[2] 在容器内创建进货单并过账(写库存 + 生成应付)"
docker exec backend-backend-1 sh -c "
cd /app && DJANGO_SETTINGS_MODULE=config.settings.prod python manage.py shell -c \"
from decimal import Decimal
from apps.purchase import services as ps
from apps.purchase.models import PurchaseBill
from apps.partner.models import Supplier
from apps.inventory.models import Warehouse
from apps.catalog.models import Product
from django.contrib.auth import get_user_model
U = get_user_model().objects.get(username='alice')
T = U.tenant if hasattr(U,'tenant') else None
# 我们直接通过 services 创建(skip view 层,因为 view 没暴露)
import django
django.setup()
tenant = django.apps.apps.get_model('core','Tenant').objects.get(code='default')
sup = Supplier.objects.get(tenant=tenant, code='S$SUFFIX')
wh = Warehouse.objects.get(tenant=tenant, code='W$SUFFIX')
p = Product.objects.get(tenant=tenant, code='P$SUFFIX')
bill = ps.create_purchase_bill(
tenant=tenant, supplier=sup, warehouse=wh,
lines=[{'product': p, 'quantity': Decimal('20'), 'unit_price': Decimal('8')}],
)
ps.confirm_purchase_bill(bill)
print(f' purchase_bill: {bill.bill_no} state={bill.state} total={bill.total_amount}')
\"
" 2>&1 | tail -5
echo ""
echo "[3] 检查库存 + 应付"
curl -s -H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: $TENANT" $BASE/api/v1/inventory/stocks/ | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(f' stocks count = {d[\"count\"]}')
for s in d['results'][:5]:
print(f' {s[\"product_code\"]}/{s[\"warehouse_code\"]} on_hand={s[\"on_hand\"]} avg_cost={s[\"avg_cost\"]}')
"
curl -s -H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: $TENANT" $BASE/api/v1/finance/payables/ | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(f' payables count = {d[\"count\"]}')
for p in d['results'][:5]:
print(f' {p[\"bill_no\"]} {p[\"supplier_code\"]} total={p[\"total_amount\"]} status={p[\"status\"]}')
"
echo ""
# 销售:同样在容器内调用 services
echo "[4] 在容器内创建销售单并过账(扣库存 + 生成应收)"
docker exec backend-backend-1 sh -c "
cd /app && DJANGO_SETTINGS_MODULE=config.settings.prod python manage.py shell -c \"
from decimal import Decimal
from apps.sales import services as ss
from apps.partner.models import Customer
from apps.inventory.models import Warehouse
from apps.catalog.models import Product
from apps.core.models import Tenant
tenant = Tenant.objects.get(code='default')
cus = Customer.objects.get(tenant=tenant, code='C$SUFFIX')
wh = Warehouse.objects.get(tenant=tenant, code='W$SUFFIX')
p = Product.objects.get(tenant=tenant, code='P$SUFFIX')
bill = ss.create_sales_bill(
tenant=tenant, customer=cus, warehouse=wh,
lines=[{'product': p, 'quantity': Decimal('7'), 'unit_price': Decimal('12')}],
)
ss.confirm_sales_bill(bill)
print(f' sales_bill: {bill.bill_no} state={bill.state} total={bill.total_amount}')
\"
" 2>&1 | tail -5
echo ""
echo "[5] 检查应收(应该 7*12=84)"
curl -s -H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: $TENANT" $BASE/api/v1/finance/receivables/ | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(f' receivables count = {d[\"count\"]}')
for r in d['results'][:5]:
print(f' {r[\"bill_no\"]} {r[\"customer_code\"]} total={r[\"total_amount\"]} balance={r[\"balance\"]} status={r[\"status\"]}')
"
echo ""
echo "[6] 检查财务凭证(业财一体化自动生成凭证)"
curl -s -H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: $TENANT" $BASE/api/v1/finance/vouchers/ | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(f' vouchers count = {d[\"count\"]}')
for v in d['results'][:5]:
print(f' {v[\"bill_no\"]} source={v[\"source_type\"]} 借/贷={v[\"total_debit\"]}/{v[\"total_credit\"]} [{v[\"status\"]}] {v[\"summary\"]}')
"
echo ""
echo "[7] 检查科目余额表(试算平衡)"
curl -s -H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: $TENANT" $BASE/api/v1/finance/reports/trial-balance/ | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(f' trial_balance is_balanced = {d.get(\"is_balanced\")} rows = {len(d.get(\"rows\", []))}')
print(f' 期末借方合计 = {d.get(\"totals\", {}).get(\"ending_debit\")} 期末贷方合计 = {d.get(\"totals\", {}).get(\"ending_credit\")}')
"
echo ""
echo "[8] 检查资产负债表与利润表"
curl -s -H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: $TENANT" $BASE/api/v1/finance/reports/balance-sheet/ | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(f' balance_sheet balanced = {d.get(\"balanced\")} 资产总计 = {d.get(\"asset_total\")} 负债及权益 = {d.get(\"total_liabilities_and_equity\")}')
"
curl -s -H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: $TENANT" $BASE/api/v1/finance/reports/income-statement/ | python3 -c "
import sys, json
d = json.load(sys.stdin)
print(f' income_statement 收入 = {d.get(\"total_revenue\")} 成本 = {d.get(\"cogs\")} 毛利 = {d.get(\"gross_profit\")} 净利润 = {d.get(\"net_profit\")}')
"
echo ""
echo "===== 全部通过 ====="