feat: multi-currency in product_accounting — real-time exchange + currency on accounting items
This commit is contained in:
parent
89847538f7
commit
4f5a81e646
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user