55 Commits

Author SHA1 Message Date
7dbac3bfdb fix: use env.get_module_dbname('sage') instead of hardcoded 'sage' 2026-07-15 14:02:25 +08:00
d05bd3ec6f fix: free customer name empty when org missing; use LEFT JOIN + COALESCE fallback 2026-07-14 12:00:53 +08:00
5b789995a6 fix: get_reseller_sales统一按当前机构过滤销售列表 2026-07-14 11:39:34 +08:00
6c0f5a6572 fix: customerid改存orgid; init_free按机构去重; 查询回JOIN organization 2026-07-14 11:18:13 +08:00
5626e1b516 fix: 自由客户分配-客户名JOIN users; 销售下拉COALESCE username防NULL 2026-07-14 11:15:08 +08:00
429cee6e9d fix: owner (org=0) can see all customers and sales across orgs 2026-07-14 10:50:59 +08:00
1e0081862d fix: use empty string instead of None for NOT NULL sale_id/promo_code_id 2026-07-14 10:45:07 +08:00
029fd91d79 feat: customer assignment - free_customer_assign + customer_reassign pages, register hook bind_type=3, sales list filter 2026-07-13 17:56:05 +08:00
690e36d4ff fix: 营销方案created_by/促销码sale_id为空 — ServerEnv()→request._run_ns 2026-07-13 11:54:24 +08:00
6c8d23b986 refactor: resellerid → auto from get_userorgid(), remove from codes 2026-07-09 13:39:10 +08:00
de1e873d91 feat: add get_min_supplier_discount and get_min_distributor_discount
- sor_get_min_product_discount now accepts exact_match param
- exact_match=True: no wildcard/NULL fallback (supplier/distributor)
- exact_match=False (default): includes '*' and NULL fallback (customer)
- Both new functions registered in load_discount()
2026-07-06 17:15:32 +08:00
8b054f01d1 fix: bind_customer env=ServerEnv()→request._run_ns 2026-07-06 15:11:34 +08:00
bb5cb57d89 refactor: keep get_min_product_discount in discount, move llm_id_to_product_id to product_management 2026-07-06 14:23:57 +08:00
10fe38b4e0 feat: add get_min_product_discount and llm_id_to_product_id
- get_min_product_discount: find minimum discount for a product across all
  active discount records (customer-specific + NULL + '*' fallback)
- llm_id_to_product_id: convert llmage.llm.id to sage.product.id
- Both registered in load_discount() for use in pricing display
2026-07-06 14:19:12 +08:00
183263eabd fix: generate_promo_code 用 request._run_ns 替代 ServerEnv()
env = request._run_ns 绑定 request 上下文,env.get_user() 正确返回 userid 字符串
2026-07-06 13:37:54 +08:00
9bb5c9e506 促销码扫码流程: dspy端点改为UI公开入口,登录后绑定并跳转主页
- 新建 promote/index.ui: 公开入口,未登录显示登录按钮,已登录自动跳dspy
- QR URL 改为 promote/index.ui (原 promote.dspy)
- load_path.py 注册 promote/index.ui 为 any 角色
- index.dspy 绑定成功后显示返回首页按钮跳转主页
- 修复 generate_promo_code sale_id: get_user() -> get_userid()
2026-07-06 13:34:25 +08:00
ceb997da09 fix: generate_promo_qr/discount_qrcode 用 request._run_ns 替代 ServerEnv() 修复 entire_url 为 None 的500错 2026-07-06 08:09:10 +08:00
62f07bc8bb fix: before_insert hook自动填充sale_id+resellerid; sync generate_promo_qr到site-packages 2026-07-05 14:24:13 +08:00
7daff0fcd6 fix: QR URL改为promote.dspy; 恢复完整表单 2026-07-05 11:02:41 +08:00
0ceb2b84c1 fix: QR生成移到async Python函数,修复DSPY中async/await不可用问题 2026-07-05 10:36:12 +08:00
90e2fd0c0c fix: get_discount_info查询discount_marketing表而非discount表 2026-07-04 20:23:07 +08:00
bc8af7a4cf fix: 产品折扣设置显示基准折扣(1.0)并标记方案内产品
- get_discount_setting_products: LEFT JOIN基准折扣方案_HeaX, COALESCE优先方案折扣, 新增in_plan字段
- get_products_with_discount.dspy: 同步加基准折扣COALESCE
- index.ui: 折扣默认1.0, 新增'✓方案内'标记列
- save_discount: old_discount默认1.0
2026-07-04 19:49:02 +08:00
51a1616b9f fix: restore IS NULL OR * to cover both conventions; keep direct dd.discount without GROUP BY 2026-07-03 18:06:56 +08:00
5e90686fbd fix: base discount query — customerid default is '*' not NULL, remove IS NULL and unnecessary GROUP BY 2026-07-03 18:05:14 +08:00
33cd1d287d feat: 营销方案产品折扣设置(独立于普通折扣方案)
index.ui: 显示所有产品 + 基准折扣(全部用户) + 方案折扣, 标志'已加入/未加入'
get_products.dspy: 左联全部用户基准折扣 + 营销方案专属折扣
save_discount.dspy: 验证 0<新<基准, upsert 到 discount_detail
init.py: get_marketing_discount_products + get_marketing_info
marketing_list.json: toolbar 指向新页面
2026-07-03 16:05:21 +08:00
02f00c6739 feat: 顶部显示折扣名称和客户名称 2026-06-29 17:02:57 +08:00
0eba657ce4 fix: 移除ORDER BY 2026-06-29 15:57:57 +08:00
0c5f0cfcc3 fix: sort改为list格式 2026-06-29 15:56:30 +08:00
52d48c964a fix: ORDER BY改用$参数化 2026-06-29 15:56:09 +08:00
dafa2d5eb2 fix: request._run_ns.params_kw 2026-06-29 15:30:14 +08:00
6e6a6a14f0 fix: discountid改用request._params_kw(同accounting模块方式) 2026-06-29 15:28:53 +08:00
6000ea7b01 fix: discountid改用request.query.get, aiohttp标准方式 2026-06-29 15:26:11 +08:00
a2aa95ef94 fix: _run_env→_run_ns 2026-06-29 13:35:22 +08:00
89d116acfd refactor: discountid获取简化为单一路径request._run_env.param_kw 2026-06-29 13:22:56 +08:00
b20c580193 fix: discountid优先从request._run_env.param_kw获取 2026-06-29 13:18:18 +08:00
2d869c1fbc fix: cwidth改为width百分比(22/34/22/22); discountid改用rel_url.query多种方式获取 2026-06-29 12:05:41 +08:00
2259b68789 refactor: 折扣设置改用Jinja2直建HBox列表+Form/UiFloat+changed事件, 废弃Tabular和inline_edit.js 2026-06-29 11:54:12 +08:00
Hermes Agent
d87d8f5ffa chore: add __pycache__ to .gitignore 2026-06-24 00:56:40 +08:00
Hermes Agent
f5250fb261 feat: 营销方案、促销码、客户归属绑定功能
- 新增3个数据模型: discount_marketing, discount_promo_code, discount_customer_bind
- 新增CRUD定义: marketing/promo_code/customer_bind 的list和api
- 新增init/data.json: appcodes编码(促销码类型、绑定方式)
- init.py: bind_customer支持customerid参数覆盖(注册场景)
- 折扣校验放宽至 0 < discount <= 1
2026-06-24 00:56:32 +08:00
d514d10319 chore: remove __pycache__ from git 2026-05-24 22:31:52 +08:00
3a57205337 fix(discount): 兼容discount_detail表不存在的情况,fallback到discount.discount字段 + 新增discount_detail表定义和迁移脚本 + 修复discount.json中float类型缺少dec字段 2026-05-24 22:31:42 +08:00
b41c89e9dd bugfix 2026-05-11 11:30:57 +08:00
a25c9e56dc bugfix 2026-04-08 14:27:38 +08:00
678cf4bac8 bugfix 2026-03-30 14:05:04 +08:00
aaf09f50a0 bugfix 2026-03-30 14:01:10 +08:00
41a7412283 bugfix 2026-02-26 11:19:39 +08:00
a563f92fd5 bugfix 2026-02-26 11:18:16 +08:00
8ab227ddd3 bugfix 2026-02-25 19:06:47 +08:00
98581b2a37 bugfix 2026-02-25 13:49:16 +08:00
c890fdf249 bugfix 2026-02-25 12:05:48 +08:00