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}')
|
raise Exception(f'calculate_product_cost failed: {cost_result}')
|
||||||
raw_cost = cost_result.get('amount', 0)
|
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)
|
# 5. Determine seller (who sold to customer)
|
||||||
dbname = self._get_dbname()
|
dbname = self._get_dbname()
|
||||||
seller_orgid = userorgid # default: customer bought directly from owner
|
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)
|
# 7. Get customer discount (seller gives to customer)
|
||||||
cust_discount = await env.get_min_product_discount(
|
cust_discount = await env.get_min_product_discount(
|
||||||
product_id, seller_orgid, userorgid)
|
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
|
# 8. Build accounting items for each link in chain
|
||||||
# Chain: product_owner → ... → seller
|
# 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,
|
action='PAY', customerid=userorgid, resellerid=ownerid,
|
||||||
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
||||||
productid=product_id, transamt=customer_amount,
|
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
|
# PAY*: owner → supplier, amount = raw_cost * supplier_discount
|
||||||
supplier_amount = raw_cost * last_link_discount
|
supplier_amount = raw_cost * last_link_discount
|
||||||
accounting_items.append(DictObject(
|
accounting_items.append(DictObject(
|
||||||
action='PAY*', customerid=ownerid, resellerid=providerid,
|
action='PAY*', customerid=ownerid, resellerid=providerid,
|
||||||
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
||||||
productid=product_id, transamt=supplier_amount,
|
productid=product_id, transamt=supplier_amount,
|
||||||
variable={"采购成本": supplier_amount}))
|
currency=prod_currency, base_amount=cost_base,
|
||||||
|
variable={"采购成本": supplier_amount, "采购币种": prod_currency}))
|
||||||
else:
|
else:
|
||||||
# Multi-level distribution chain
|
# Multi-level distribution chain
|
||||||
for i, orgid in enumerate(chain):
|
for i, orgid in enumerate(chain):
|
||||||
is_last = (i == len(chain) - 1)
|
is_last = (i == len(chain) - 1)
|
||||||
if is_last:
|
if is_last:
|
||||||
# Last link (closest to customer): PAY
|
# Last link (closest to customer): PAY
|
||||||
# Get this distributor's discount towards their downstream
|
|
||||||
accounting_items.append(DictObject(
|
accounting_items.append(DictObject(
|
||||||
action='PAY', customerid=userorgid, resellerid=orgid,
|
action='PAY', customerid=userorgid, resellerid=orgid,
|
||||||
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
||||||
productid=product_id, transamt=customer_amount,
|
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:
|
else:
|
||||||
# Middle link: PAY*
|
# Middle link: PAY*
|
||||||
next_orgid = chain[i + 1]
|
next_orgid = chain[i + 1]
|
||||||
# Get discount from this level to next level
|
|
||||||
up_discount = 1.0
|
up_discount = 1.0
|
||||||
try:
|
try:
|
||||||
up_discount = await env.get_min_distributor_discount(
|
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,
|
action='PAY*', customerid=orgid, resellerid=next_orgid,
|
||||||
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
||||||
productid=product_id, transamt=link_amount,
|
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
|
# Final PAY*: top of chain → supplier
|
||||||
supplier_amount = raw_cost * last_link_discount
|
supplier_amount = raw_cost * last_link_discount
|
||||||
accounting_items.append(DictObject(
|
accounting_items.append(DictObject(
|
||||||
action='PAY*', customerid=chain[0], resellerid=providerid,
|
action='PAY*', customerid=chain[0], resellerid=providerid,
|
||||||
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
providerid=providerid, biz_date=biz_date, timestamp=timestamp,
|
||||||
productid=product_id, transamt=supplier_amount,
|
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
|
# 9. Write biz_order and call consume_accounting
|
||||||
dbname = self._get_dbname()
|
dbname = self._get_dbname()
|
||||||
@ -1493,6 +1522,7 @@ WHERE resource_ref_id = ${llm_id}$ AND product_type = 'llm_model' LIMIT 1"""
|
|||||||
"order_status": "1",
|
"order_status": "1",
|
||||||
"business_op": "PAY",
|
"business_op": "PAY",
|
||||||
"amount": customer_amount,
|
"amount": customer_amount,
|
||||||
|
"currency": user_currency,
|
||||||
"userid": userid,
|
"userid": userid,
|
||||||
"productid": product_id
|
"productid": product_id
|
||||||
}
|
}
|
||||||
@ -1502,7 +1532,8 @@ WHERE resource_ref_id = ${llm_id}$ AND product_type = 'llm_model' LIMIT 1"""
|
|||||||
"orderid": orderid,
|
"orderid": orderid,
|
||||||
"productid": product_id,
|
"productid": product_id,
|
||||||
"product_cnt": 1,
|
"product_cnt": 1,
|
||||||
"trans_amount": customer_amount
|
"trans_amount": customer_amount,
|
||||||
|
"currency": user_currency,
|
||||||
}
|
}
|
||||||
await sor.C('biz_orderdetail', orderdetail)
|
await sor.C('biz_orderdetail', orderdetail)
|
||||||
await consume_accounting(sor, orderid, accounting_items)
|
await consume_accounting(sor, orderid, accounting_items)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user