Files

115 lines
5.0 KiB
Python

"""报表与 BI 大盘集成测试。"""
import pytest
from datetime import date
from decimal import Decimal
from model_bakery import baker
from rest_framework.test import APIClient
from rest_framework_simplejwt.tokens import RefreshToken
from apps.catalog.models import Product
from apps.inventory.models import Warehouse, Stock
from apps.partner.models import Customer, Supplier
from apps.sales.models import SalesBill, SalesBillLine
from apps.purchase.models import PurchaseBill
from apps.finance.models import Receivable, Payable
from apps.report import services as report_services
from apps.report.models import ReportDefinition
@pytest.fixture
def auth_client(db, user, tenant):
client = APIClient()
refresh = RefreshToken.for_user(user)
client.credentials(
HTTP_AUTHORIZATION=f"Bearer {refresh.access_token}",
HTTP_X_TENANT_ID=tenant.code,
)
return client
@pytest.mark.django_db
def test_init_system_reports(tenant):
count = report_services.init_system_reports(tenant)
assert count == 4
assert ReportDefinition.objects.filter(tenant=tenant).count() == 4
# 幂等性
assert report_services.init_system_reports(tenant) == 0
@pytest.mark.django_db
def test_dashboard_summary_and_valuation(tenant):
wh = baker.make(Warehouse, tenant=tenant, code="WH01", name="总仓")
p1 = baker.make(Product, tenant=tenant, code="P01", name="商品1")
p2 = baker.make(Product, tenant=tenant, code="P02", name="商品2")
# 创建库存并设置成本
baker.make(Stock, tenant=tenant, warehouse=wh, product=p1, on_hand=Decimal("100"), avg_cost=Decimal("10"))
baker.make(Stock, tenant=tenant, warehouse=wh, product=p2, on_hand=Decimal("50"), avg_cost=Decimal("20"))
# 创建销售与采购
cust = baker.make(Customer, tenant=tenant, code="C01", name="客户1")
sb = baker.make(SalesBill, tenant=tenant, customer=cust, bill_date=date.today(), total_amount=Decimal("5000"), state="confirmed")
sup = baker.make(Supplier, tenant=tenant, code="S01", name="供应商1")
pb = baker.make(PurchaseBill, tenant=tenant, supplier=sup, bill_date=date.today(), total_amount=Decimal("3000"), state="confirmed")
# 应收应付
baker.make(Receivable, tenant=tenant, customer=cust, total_amount=Decimal("5000"), paid_amount=Decimal("2000"), status="partial", bill_date=date.today())
baker.make(Payable, tenant=tenant, supplier=sup, total_amount=Decimal("3000"), paid_amount=Decimal("1000"), status="partial", bill_date=date.today())
summary = report_services.get_dashboard_summary(tenant)
assert summary["month_sales"]["amount"] == Decimal("5000")
assert summary["month_purchase"]["amount"] == Decimal("3000")
assert summary["inventory"]["sku_count"] == 2
assert summary["inventory"]["total_quantity"] == Decimal("150")
# 估值 = 100*10 + 50*20 = 2000
assert summary["inventory"]["valuation"] == Decimal("2000")
# 待收 3000,待付 2000
assert summary["finance"]["receivable_balance"] == Decimal("3000")
assert summary["finance"]["payable_balance"] == Decimal("2000")
@pytest.mark.django_db
def test_sales_rank_analytics(tenant):
cust1 = baker.make(Customer, tenant=tenant, code="C1", name="客户1")
cust2 = baker.make(Customer, tenant=tenant, code="C2", name="客户2")
prod1 = baker.make(Product, tenant=tenant, code="P1", name="雪碧")
prod2 = baker.make(Product, tenant=tenant, code="P2", name="可乐")
bill1 = baker.make(SalesBill, tenant=tenant, customer=cust1, state="confirmed", bill_date=date.today())
baker.make(SalesBillLine, tenant=tenant, bill=bill1, product=prod1, quantity=Decimal("10"), amount=Decimal("300"))
baker.make(SalesBillLine, tenant=tenant, bill=bill1, product=prod2, quantity=Decimal("5"), amount=Decimal("200"))
bill2 = baker.make(SalesBill, tenant=tenant, customer=cust2, state="confirmed", bill_date=date.today())
baker.make(SalesBillLine, tenant=tenant, bill=bill2, product=prod1, quantity=Decimal("20"), amount=Decimal("600"))
# 按商品排行
prod_rank = report_services.get_sales_rank(tenant, rank_by="product")
assert len(prod_rank) == 2
assert prod_rank[0]["product_code"] == "P1"
assert prod_rank[0]["total_amount"] == Decimal("900")
# 按客户排行
cust_rank = report_services.get_sales_rank(tenant, rank_by="customer")
assert len(cust_rank) == 2
assert cust_rank[0]["customer_code"] == "C2"
assert cust_rank[0]["total_amount"] == Decimal("600")
@pytest.mark.django_db
def test_report_api_endpoints(auth_client, tenant):
# 初始化报表
r1 = auth_client.post("/api/v1/report/definitions/init-system/")
assert r1.status_code == 200
assert r1.json()["ok"] is True
# 查询大盘总览 API
r2 = auth_client.get("/api/v1/report/dashboard/summary/")
assert r2.status_code == 200
assert "inventory" in r2.json()
# 查询销售排行 API
r3 = auth_client.get("/api/v1/report/dashboard/sales-rank/?rank_by=product")
assert r3.status_code == 200
assert "results" in r3.json()