#!/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 "===== 全部通过 ====="