113 lines
4.4 KiB
Python
113 lines
4.4 KiB
Python
"""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)}
|
||
|