fix(discount): 折扣模型纠正——三类折扣各归其位,不取 min
- 客户折扣(discount 模块 get_min_product_discount) → amount 售价 - 供应商折扣(supplychain 模块 calculate_sale_amounts) → cost 平台进货成本 - 分销商折扣不进本函数(分销场景单独用 calculate_sale_amounts 的 distribution_amount) - 供应商 id 来源:product.providerid,空则查 product_supplier_mapping 首选供应商 之前"取 min 三类折扣"是错的:用户折扣不能采用供应商折扣,两者独立。
This commit is contained in:
parent
4ed6d15a59
commit
7852583739
@ -1389,12 +1389,16 @@ class ProductManager:
|
||||
|
||||
async def calculate_product_cost(self, product_id=None, product_code=None,
|
||||
usage_data=None, user_org_id=None):
|
||||
"""计算消费费用:资源真实定价 × 产品级折扣。
|
||||
"""计算消费费用:资源真实定价 + 客户折扣(售价) + 供应商折扣(成本)。
|
||||
|
||||
折扣精确到 product_id(discount_detail.productid),三类折扣取最优惠:
|
||||
- 客户折扣:get_min_product_discount(product_id, resellerid, customerid)
|
||||
- 分销商折扣:get_min_distributor_discount(product_id, resellerid, distributorid)
|
||||
- 供应商折扣:get_min_supplier_discount(product_id, resellerid, supplierid)
|
||||
三类折扣各自独立、归属不同环节,不取 min:
|
||||
- 客户折扣 discount 模块 get_min_product_discount → amount(客户应付售价)
|
||||
- 供应商折扣 supplychain 模块 calculate_sale_amounts → cost(平台进货成本)
|
||||
- 分销商折扣 分销场景单独用(calculate_sale_amounts 的 distribution_amount),
|
||||
不进本函数。
|
||||
|
||||
返回:original_amount(资源真实定价)、amount(售价=原价×客户折扣)、
|
||||
cost(成本=原价×供应商折扣)、discount(客户折扣率)
|
||||
"""
|
||||
iface, product, err = await self._get_product_interface(
|
||||
product_id, product_code)
|
||||
@ -1423,51 +1427,59 @@ class ProductManager:
|
||||
original_amount = float(result.get('original_amount',
|
||||
result.get('amount', 0) or 0))
|
||||
|
||||
# 2. 产品级折扣:精确到 product_id,取最优惠(min)
|
||||
env = ServerEnv()
|
||||
resellerid = product.get('org_id') or '0'
|
||||
pid = product.get('id') or ''
|
||||
final_discount = 1.0
|
||||
|
||||
# 2a. 客户折扣(customerid 精确 + '*'/NULL 通配)
|
||||
# 2. 客户折扣(discount 模块,售价侧)→ amount
|
||||
discount = 1.0
|
||||
if user_org_id:
|
||||
try:
|
||||
d = await env.get_min_product_discount(pid, resellerid, user_org_id)
|
||||
if d not in (None, '', 0):
|
||||
final_discount = min(final_discount, float(d))
|
||||
discount = float(d)
|
||||
except Exception:
|
||||
pass
|
||||
amount = original_amount * discount
|
||||
|
||||
# 2b. 分销商折扣(客户归属的分销商,discount_customer_bind)
|
||||
# 3. 供应商折扣(supplychain 模块,成本侧)→ cost
|
||||
# 供应商折扣是平台进货折扣,与客户折扣独立,不取 min。
|
||||
cost = original_amount
|
||||
try:
|
||||
dbname = self._get_dbname()
|
||||
async with DBPools().sqlorContext(dbname) as sor:
|
||||
binds = await sor.R('discount_customer_bind',
|
||||
{'customerid': user_org_id})
|
||||
if binds:
|
||||
distributorid = getattr(binds[0], 'resellerid', '') or ''
|
||||
if distributorid:
|
||||
d = await env.get_min_distributor_discount(
|
||||
pid, resellerid, distributorid)
|
||||
if d not in (None, '', 0):
|
||||
final_discount = min(final_discount, float(d))
|
||||
supplier_id = product.get('providerid') or ''
|
||||
if not supplier_id:
|
||||
# 从 supplychain 的产品→供应商映射查首选供应商
|
||||
dbname = self._get_dbname()
|
||||
async with DBPools().sqlorContext(dbname) as sor:
|
||||
maps = await sor.R('product_supplier_mapping',
|
||||
{'product_id': pid})
|
||||
if maps:
|
||||
pref = [m for m in maps
|
||||
if str(getattr(m, 'is_preferred', '')) == '1'] or maps
|
||||
supplier_id = (getattr(pref[0], 'external_supplier_id', '')
|
||||
or getattr(pref[0], 'supplier_org_id', '')
|
||||
or '')
|
||||
if supplier_id:
|
||||
sc = await env.calculate_sale_amounts(None, {
|
||||
'resellerid': resellerid,
|
||||
'supplier_id': supplier_id,
|
||||
'productid': pid,
|
||||
'prodtypeid': product.get('category_id') or '',
|
||||
'quantity': 1,
|
||||
'unit_price': original_amount,
|
||||
})
|
||||
if sc:
|
||||
sc_data = json.loads(sc) if isinstance(sc, str) else sc
|
||||
sc_data = sc_data.get('data', {}) if isinstance(sc_data, dict) else {}
|
||||
supply_discount = float(sc_data.get('supply_discount', 1.0) or 1.0)
|
||||
cost = original_amount * supply_discount
|
||||
except Exception:
|
||||
pass
|
||||
cost = original_amount
|
||||
|
||||
# 2c. 供应商折扣(product.providerid)
|
||||
supplierid = product.get('providerid') or ''
|
||||
if supplierid:
|
||||
try:
|
||||
d = await env.get_min_supplier_discount(pid, resellerid, supplierid)
|
||||
if d not in (None, '', 0):
|
||||
final_discount = min(final_discount, float(d))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
amount = original_amount * final_discount
|
||||
result['amount'] = round(amount, 6)
|
||||
result['original_amount'] = round(original_amount, 6)
|
||||
result['discount'] = final_discount
|
||||
result['cost'] = round(cost, 6)
|
||||
result['discount'] = discount
|
||||
return result
|
||||
|
||||
async def llm_id_to_product_id(self, llm_id):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user