用户决策(2026-09-06): 1. 折扣率允许大于1:平台可加价卖产品给客户(如存储缺省1.5); 也可小于1让利(如百炼模型0.9,供应商有折扣传导给客户) 2. 解析规则:确定客户→查客户专属折扣;查不到→'*'通配兜底;再无→1.0 旧实现bug:专属与通配OR混查取全局min——专属0.95+通配0.8返回0.8, 专属记录形同虚设 改动: - init.py sor_get_min_product_discount: 两步查询(专属层min→通配层min) - init.py add/update_discount_detail: 上限1→9.9999(DB double(5,4)约束) - discount_setting/save_discount.dspy: 兜底记录识别'*'+NULL两种形态; 「客户折扣率不得高于通用折扣率」校验保留(加价语义下=单客户价不贵于通用价) - marketing_discount_setting/save_discount.dspy: >1上限放开,保留<基准约束 - generate_qr.dspy: 同上放开 - index.ui: placeholder 0~1→'>1加价 <1折扣',dec_len 2→4 本地mock测试5场景全过:专属优先/通配兜底/无记录1.0/exact_match不兜底/层内min
79 lines
3.2 KiB
Plaintext
79 lines
3.2 KiB
Plaintext
# 营销方案产品折扣保存
|
||
# 规则: 0 < 新折扣 < 全部用户基准折扣
|
||
# 自动 upsert 到 discount_detail
|
||
|
||
result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': 'Invalid', 'type': 'error', 'timeout': 3}}
|
||
|
||
try:
|
||
discountid = params_kw.get('discountid')
|
||
productid = params_kw.get('productid')
|
||
discount_val = params_kw.get('discount')
|
||
base_discount = params_kw.get('base_discount')
|
||
detail_id = params_kw.get('detail_id')
|
||
|
||
if not discountid or not productid:
|
||
raise Exception('缺少必要参数')
|
||
|
||
# 过滤 NaN/空值
|
||
if discount_val is not None:
|
||
s = str(discount_val).strip().lower()
|
||
if s in ('', 'nan', 'none', 'null'):
|
||
discount_val = None
|
||
|
||
user_orgid = await get_userorgid()
|
||
dbname = get_module_dbname('discount')
|
||
|
||
# discount为0或空 → 删除明细
|
||
if not discount_val or float(discount_val) == 0:
|
||
if detail_id:
|
||
async with DBPools().sqlorContext(dbname) as sor:
|
||
await sor.D('discount_detail', {'id': detail_id})
|
||
result = {'widgettype': 'Message', 'options': {'title': 'Success', 'message': '已移出营销方案', 'type': 'success', 'timeout': 3}}
|
||
else:
|
||
result = {'widgettype': 'Message', 'options': {'title': 'Success', 'message': 'ok', 'type': 'success', 'timeout': 3}}
|
||
return result
|
||
|
||
new_val = float(discount_val)
|
||
|
||
# 验证: 必须大于0
|
||
if new_val <= 0:
|
||
result = {'widgettype': 'Error', 'options': {'title': '折扣无效', 'message': '折扣必须大于0', 'timeout': 5}}
|
||
return result
|
||
|
||
# 验证: 不能超过基准折扣
|
||
if base_discount:
|
||
base_val = float(base_discount)
|
||
if new_val >= base_val:
|
||
result = {'widgettype': 'Error', 'options': {'title': '折扣无效', 'message': f'营销折扣率({new_val})必须小于基准折扣率({base_val})', 'timeout': 5}}
|
||
return result
|
||
|
||
# 2026-09-06: 放开 >1 上限——折扣率>1=加价(基准若是1.5加价,营销可设1.2仍低于基准)。
|
||
# 约束只剩两条:>0(上面已验)、< 基准折扣率(上面已验)、≤9.9999(DB double(5,4))
|
||
if new_val > 9.9999:
|
||
result = {'widgettype': 'Error', 'options': {'title': '折扣无效', 'message': '折扣率不能大于9.9999', 'timeout': 5}}
|
||
return result
|
||
|
||
async with DBPools().sqlorContext(dbname) as sor:
|
||
if detail_id:
|
||
await sor.U('discount_detail', {
|
||
'id': detail_id,
|
||
'discount': new_val
|
||
})
|
||
else:
|
||
await sor.C('discount_detail', {
|
||
'id': getID(),
|
||
'discountid': discountid,
|
||
'resellerid': user_orgid,
|
||
'prodtypeid': None,
|
||
'productid': productid,
|
||
'discount': new_val
|
||
})
|
||
|
||
result = {'widgettype': 'Message', 'options': {'title': 'Success', 'message': f'折扣保存成功({new_val})', 'type': 'success', 'timeout': 3}}
|
||
|
||
except Exception as e:
|
||
debug(f'save_marketing_discount error: {format_exc()}')
|
||
result['options'] = {'title': 'Error', 'message': f'保存失败: {str(e)}', 'type': 'error', 'timeout': 5}
|
||
|
||
return result
|