feat: multi-currency in product_accounting — real-time exchange + currency on accounting items

This commit is contained in:
yumoqing 2026-07-07 16:25:23 +08:00
parent 89847538f7
commit 4f5a81e646

View File

@ -1390,6 +1390,32 @@ WHERE resource_ref_id = ${llm_id}$ AND product_type = 'llm_model' LIMIT 1"""
raise Exception(f'calculate_product_cost failed: {cost_result}')
raw_cost = cost_result.get('amount', 0)
# 4b. Get product currency
prod_currency = 'CNY'
try:
dbname = self._get_dbname()
async with DBPools().sqlorContext(dbname) as sor:
prod_rows = await sor.sqlExe(
"SELECT currency FROM product WHERE id=${pid}$", {'pid': product_id})
if prod_rows:
prod_currency = prod_rows[0].currency or 'CNY'
except Exception:
pass
# 4c. Get user billing currency and exchange rates
user_currency = 'CNY'
cost_in_user = raw_cost
cost_base = raw_cost
try:
env = ServerEnv()
user_currency = await env.get_user_currency(userorgid)
if prod_currency != user_currency:
rate = await env.get_exchange_rate(prod_currency, user_currency, 'sell_rate')
cost_in_user = round(raw_cost * rate, 2)
cost_base = await env.convert_to_base(cost_in_user, user_currency, 'sell_rate')
except Exception:
pass
# 5. Determine seller (who sold to customer)
dbname = self._get_dbname()
seller_orgid = userorgid # default: customer bought directly from owner
@ -1409,7 +1435,7 @@ WHERE resource_ref_id = ${llm_id}$ AND product_type = 'llm_model' LIMIT 1"""
# 7. Get customer discount (seller gives to customer)
cust_discount = await env.get_min_product_discount(
product_id, seller_orgid, userorgid)
customer_amount = raw_cost * cust_discount
customer_amount = cost_in_user * cust_discount
# 8. Build accounting items for each link in chain
# Chain: product_owner → ... → seller
@ -1435,30 +1461,31 @@ WHERE resource_ref_id = ${llm_id}$ AND product_type = 'llm_model' LIMIT 1"""
action='PAY', customerid=userorgid, resellerid=ownerid,
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
productid=product_id, transamt=customer_amount,
variable={"交易金额": customer_amount, "交易手续费": 0}))
currency=user_currency, base_amount=round(customer_amount, 2),
variable={"交易金额": customer_amount, "交易币种": user_currency, "交易手续费": 0}))
# PAY*: owner → supplier, amount = raw_cost * supplier_discount
supplier_amount = raw_cost * last_link_discount
accounting_items.append(DictObject(
action='PAY*', customerid=ownerid, resellerid=providerid,
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
productid=product_id, transamt=supplier_amount,
variable={"采购成本": supplier_amount}))
currency=prod_currency, base_amount=cost_base,
variable={"采购成本": supplier_amount, "采购币种": prod_currency}))
else:
# Multi-level distribution chain
for i, orgid in enumerate(chain):
is_last = (i == len(chain) - 1)
if is_last:
# Last link (closest to customer): PAY
# Get this distributor's discount towards their downstream
accounting_items.append(DictObject(
action='PAY', customerid=userorgid, resellerid=orgid,
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
productid=product_id, transamt=customer_amount,
variable={"交易金额": customer_amount, "交易手续费": 0}))
currency=user_currency, base_amount=round(customer_amount, 2),
variable={"交易金额": customer_amount, "交易币种": user_currency, "交易手续费": 0}))
else:
# Middle link: PAY*
next_orgid = chain[i + 1]
# Get discount from this level to next level
up_discount = 1.0
try:
up_discount = await env.get_min_distributor_discount(
@ -1470,14 +1497,16 @@ WHERE resource_ref_id = ${llm_id}$ AND product_type = 'llm_model' LIMIT 1"""
action='PAY*', customerid=orgid, resellerid=next_orgid,
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
productid=product_id, transamt=link_amount,
variable={"分销结算": link_amount}))
currency=prod_currency, base_amount=round(link_amount, 2),
variable={"分销结算": link_amount, "结算币种": prod_currency}))
# Final PAY*: top of chain → supplier
supplier_amount = raw_cost * last_link_discount
accounting_items.append(DictObject(
action='PAY*', customerid=chain[0], resellerid=providerid,
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
productid=product_id, transamt=supplier_amount,
variable={"采购成本": supplier_amount}))
currency=prod_currency, base_amount=cost_base,
variable={"采购成本": supplier_amount, "采购币种": prod_currency}))
# 9. Write biz_order and call consume_accounting
dbname = self._get_dbname()
@ -1493,6 +1522,7 @@ WHERE resource_ref_id = ${llm_id}$ AND product_type = 'llm_model' LIMIT 1"""
"order_status": "1",
"business_op": "PAY",
"amount": customer_amount,
"currency": user_currency,
"userid": userid,
"productid": product_id
}
@ -1502,7 +1532,8 @@ WHERE resource_ref_id = ${llm_id}$ AND product_type = 'llm_model' LIMIT 1"""
"orderid": orderid,
"productid": product_id,
"product_cnt": 1,
"trans_amount": customer_amount
"trans_amount": customer_amount,
"currency": user_currency,
}
await sor.C('biz_orderdetail', orderdetail)
await consume_accounting(sor, orderid, accounting_items)