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,
|
async def calculate_product_cost(self, product_id=None, product_code=None,
|
||||||
usage_data=None, user_org_id=None):
|
usage_data=None, user_org_id=None):
|
||||||
"""计算消费费用:资源真实定价 × 产品级折扣。
|
"""计算消费费用:资源真实定价 + 客户折扣(售价) + 供应商折扣(成本)。
|
||||||
|
|
||||||
折扣精确到 product_id(discount_detail.productid),三类折扣取最优惠:
|
三类折扣各自独立、归属不同环节,不取 min:
|
||||||
- 客户折扣:get_min_product_discount(product_id, resellerid, customerid)
|
- 客户折扣 discount 模块 get_min_product_discount → amount(客户应付售价)
|
||||||
- 分销商折扣:get_min_distributor_discount(product_id, resellerid, distributorid)
|
- 供应商折扣 supplychain 模块 calculate_sale_amounts → cost(平台进货成本)
|
||||||
- 供应商折扣:get_min_supplier_discount(product_id, resellerid, supplierid)
|
- 分销商折扣 分销场景单独用(calculate_sale_amounts 的 distribution_amount),
|
||||||
|
不进本函数。
|
||||||
|
|
||||||
|
返回:original_amount(资源真实定价)、amount(售价=原价×客户折扣)、
|
||||||
|
cost(成本=原价×供应商折扣)、discount(客户折扣率)
|
||||||
"""
|
"""
|
||||||
iface, product, err = await self._get_product_interface(
|
iface, product, err = await self._get_product_interface(
|
||||||
product_id, product_code)
|
product_id, product_code)
|
||||||
@ -1423,51 +1427,59 @@ class ProductManager:
|
|||||||
original_amount = float(result.get('original_amount',
|
original_amount = float(result.get('original_amount',
|
||||||
result.get('amount', 0) or 0))
|
result.get('amount', 0) or 0))
|
||||||
|
|
||||||
# 2. 产品级折扣:精确到 product_id,取最优惠(min)
|
|
||||||
env = ServerEnv()
|
env = ServerEnv()
|
||||||
resellerid = product.get('org_id') or '0'
|
resellerid = product.get('org_id') or '0'
|
||||||
pid = product.get('id') or ''
|
pid = product.get('id') or ''
|
||||||
final_discount = 1.0
|
|
||||||
|
|
||||||
# 2a. 客户折扣(customerid 精确 + '*'/NULL 通配)
|
# 2. 客户折扣(discount 模块,售价侧)→ amount
|
||||||
|
discount = 1.0
|
||||||
if user_org_id:
|
if user_org_id:
|
||||||
try:
|
try:
|
||||||
d = await env.get_min_product_discount(pid, resellerid, user_org_id)
|
d = await env.get_min_product_discount(pid, resellerid, user_org_id)
|
||||||
if d not in (None, '', 0):
|
if d not in (None, '', 0):
|
||||||
final_discount = min(final_discount, float(d))
|
discount = float(d)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
amount = original_amount * discount
|
||||||
|
|
||||||
# 2b. 分销商折扣(客户归属的分销商,discount_customer_bind)
|
# 3. 供应商折扣(supplychain 模块,成本侧)→ cost
|
||||||
|
# 供应商折扣是平台进货折扣,与客户折扣独立,不取 min。
|
||||||
|
cost = original_amount
|
||||||
try:
|
try:
|
||||||
dbname = self._get_dbname()
|
supplier_id = product.get('providerid') or ''
|
||||||
async with DBPools().sqlorContext(dbname) as sor:
|
if not supplier_id:
|
||||||
binds = await sor.R('discount_customer_bind',
|
# 从 supplychain 的产品→供应商映射查首选供应商
|
||||||
{'customerid': user_org_id})
|
dbname = self._get_dbname()
|
||||||
if binds:
|
async with DBPools().sqlorContext(dbname) as sor:
|
||||||
distributorid = getattr(binds[0], 'resellerid', '') or ''
|
maps = await sor.R('product_supplier_mapping',
|
||||||
if distributorid:
|
{'product_id': pid})
|
||||||
d = await env.get_min_distributor_discount(
|
if maps:
|
||||||
pid, resellerid, distributorid)
|
pref = [m for m in maps
|
||||||
if d not in (None, '', 0):
|
if str(getattr(m, 'is_preferred', '')) == '1'] or maps
|
||||||
final_discount = min(final_discount, float(d))
|
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:
|
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['amount'] = round(amount, 6)
|
||||||
result['original_amount'] = round(original_amount, 6)
|
result['original_amount'] = round(original_amount, 6)
|
||||||
result['discount'] = final_discount
|
result['cost'] = round(cost, 6)
|
||||||
|
result['discount'] = discount
|
||||||
return result
|
return result
|
||||||
|
|
||||||
async def llm_id_to_product_id(self, llm_id):
|
async def llm_id_to_product_id(self, llm_id):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user