NAC_Blockchain/gnacs-service/routers/jurisdiction.py

113 lines
4.4 KiB
Python
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.

"""GNACS 司法辖区路由"""
from fastapi import APIRouter, HTTPException, Query
import database
router = APIRouter()
def serialize(doc):
if doc is None:
return None
result = {}
for k, v in doc.items():
if k == "_id":
result["_id"] = str(v)
elif isinstance(v, dict):
result[k] = serialize(v)
else:
result[k] = v
return result
@router.get("/list")
async def list_jurisdictions(
tier: int = Query(None, description="按监管等级筛选1=高度成熟2=中等成熟3=新兴市场"),
region: str = Query(None, description="按地区筛选Americas/Europe/Asia/ASEAN/GCC/Africa/Oceania"),
limit: int = Query(100, description="返回数量限制")
):
"""列出所有支持的司法辖区"""
col = database.jurisdictions_col
query = {}
if tier is not None:
query["tier"] = tier
if region:
query["region"] = region
cursor = col.find(query, sort=[("tier", 1), ("code", 1)]).limit(limit)
jurisdictions = []
async for doc in cursor:
jurisdictions.append(serialize(doc))
total = await col.count_documents(query)
return {"success": True, "jurisdictions": jurisdictions, "total": total}
@router.get("/check-cross-border")
async def check_cross_border(
investor_jurisdiction: str = Query(..., description="投资者所在辖区代码如CN"),
asset_jurisdiction: str = Query(..., description="资产所在辖区代码如US")
):
"""检查是否为跨境交易,并返回双重合规要求"""
col = database.jurisdictions_col
treaties_col = database.tax_treaties_col
investor_j = await col.find_one({"code": investor_jurisdiction.upper()})
asset_j = await col.find_one({"code": asset_jurisdiction.upper()})
if not investor_j:
raise HTTPException(status_code=404, detail=f"投资者辖区 {investor_jurisdiction} 不存在")
if not asset_j:
raise HTTPException(status_code=404, detail=f"资产辖区 {asset_jurisdiction} 不存在")
is_cross_border = investor_jurisdiction.upper() != asset_jurisdiction.upper()
# 查询双边税收协定
treaty = await treaties_col.find_one({
"$or": [
{"source": investor_jurisdiction.upper(), "target": asset_jurisdiction.upper()},
{"source": asset_jurisdiction.upper(), "target": investor_jurisdiction.upper()}
]
})
# 综合KYC要求取两者最高
combined_kyc = max(
investor_j.get("tier", 1),
asset_j.get("tier", 1)
)
# Tier转KYC等级映射
tier_to_kyc = {0: 1, 1: 2, 2: 3, 3: 3}
combined_kyc_level = tier_to_kyc.get(combined_kyc, 2)
result = {
"is_cross_border": is_cross_border,
"investor_jurisdiction": serialize(investor_j),
"asset_jurisdiction": serialize(asset_j),
"combined_kyc_level": combined_kyc_level,
"forex_control_applicable": investor_j.get("forex_control", False) or asset_j.get("forex_control", False),
"fatca_applicable": investor_j.get("fatca_applicable", False) or asset_j.get("fatca_applicable", False),
"crs_applicable": investor_j.get("crs_participant", False) and asset_j.get("crs_participant", False),
"tax_treaty": serialize(treaty) if treaty else None,
"compliance_notes": []
}
if is_cross_border:
notes = []
if investor_j.get("forex_control"):
notes.append(f"{investor_jurisdiction}有外汇管制,跨境转账需申报")
if investor_j.get("fatca_applicable"):
notes.append("需提交FATCA表格美国纳税人")
if result["crs_applicable"]:
notes.append("CRS信息自动交换适用账户信息将共享给税务机关")
if not treaty:
notes.append(f"{investor_jurisdiction}{asset_jurisdiction}之间无双边税收协定,可能面临双重征税")
else:
notes.append(f"适用{treaty.get('treaty_code','')}税收协定")
result["compliance_notes"] = notes
return {"success": True, "data": result}
@router.get("/{code}")
async def get_jurisdiction_detail(code: str):
"""获取指定辖区的详细信息"""
col = database.jurisdictions_col
doc = await col.find_one({"code": code.upper()})
if not doc:
raise HTTPException(status_code=404, detail=f"辖区 {code} 不存在")
return {"success": True, "data": serialize(doc)}