87 Commits

Author SHA1 Message Date
3a36dc2400 feat: one-click ensure contract/agreement from supplier/distributor list
- api/ensure_distribution_agreement.dspy: check/create distribution_agreement for sub_reseller
- api/ensure_supply_contract.dspy: check/create supply_contract for supplier
- sub_distributors_list: toolbar '分销协议' now calls ensure endpoint (was PopupWindow)
- suppliers_list: add toolbar '供销协议' calling ensure endpoint
2026-07-10 10:37:17 +08:00
ccd1a6f0e8 fix: remove cheight from all CRUD index.ui — let bricks Tabular auto-height
Removed cheight:40 from outer VBox and inner Tabular options in:
- suppliers_list
- sub_resellers_list
- sub_distributors_list
- supply_contracts_list
- distribution_agreements_list

CRUD Tabular handles its own height; hardcoding cheight causes
title row to fill entire viewport.
2026-07-10 09:29:40 +08:00
6314b98c76 fix: add missing code fields to editexclouded in CRUD index.ui
- supply_contracts_list: add supplier_id to editexclouded
- distribution_agreements_list: add sub_reseller_id to editexclouded
- distribution_agreements_list: fix editable URLs to use custom API dspy paths
- distribution_agreements_list JSON: remove sub_reseller_id query param from new_data_url

Root cause: xls2ui strips code-type fields (those in browserfields.alters with
uitype=code and dataurl) from the generated editexclouded list, even though
they're in the source CRUD JSON config. This causes bricks.js to render UiCode
widgets in add/edit forms that try to call .length on undefined options data,
producing: TypeError: Cannot read properties of undefined (reading 'length')

Force-added generated files (normally gitignored) as temporary fix until
xls2ui is corrected.
2026-07-10 09:15:13 +08:00
aae4271668 fix: align create_sub_reseller with sub_distributors model — sub_dist_name, no code field 2026-07-09 16:55:07 +08:00
880e9e59c4 fix: use datetime.now instead of ServerEnv in _generate_sub_reseller_code 2026-07-09 16:53:49 +08:00
06f809fc32 fix: use request._run_ns instead of ServerEnv() in create_sub_reseller 2026-07-09 16:39:07 +08:00
da5fd85984 fix: add_sub_distributors calls create_sub_reseller for org+account creation 2026-07-09 16:29:11 +08:00
160bc36fb1 fix: remove unused sub_dist_code field 2026-07-09 16:24:48 +08:00
3f46b93b65 fix: sub_dist_code auto-generated with getID() 2026-07-09 16:18:37 +08:00
d7d53d2e3b fix: remove unique idx_sd_code — one distributor can have multiple sub-distributors 2026-07-09 16:17:14 +08:00
e836991c23 fix: add CURRENT_TIMESTAMP defaults to created_at/updated_at 2026-07-09 15:04:44 +08:00
48658403a3 fix: add default to sub_dist_code and created_by 2026-07-09 14:57:09 +08:00
2a3eb72d2b fix: remove duplicate status code entry in suppliers model 2026-07-09 14:38:38 +08:00
6c926cf3d5 fix: add status codes to models — prevents empty code field in search_form 2026-07-09 14:07:17 +08:00
5705e674b5 feat: add orgid to sub_resellers + get_distribution_chain
- create_sub_reseller auto-creates organization record with orgid
- get_distribution_chain walks from product_owner down to seller via sub_resellers
2026-07-07 12:20:39 +08:00
7c0acb5245 fix: UiFile-based upload with drag-drop support, download/delete toolbar 2026-07-03 17:57:48 +08:00
07d5173d75 feat: add download and delete actions to contract attachment list 2026-07-03 17:45:57 +08:00
3017ac295b fix: bricks.app.getWidgetById → bricks.getWidgetById (app is not the root for widget lookup) 2026-07-03 17:42:03 +08:00
82579b14ad fix: override file_uploaded to return FileMgrResult — base returns None causing NoneType.status 2026-07-03 17:37:06 +08:00
0203dc1c24 fix: quota 0→1000000000 (unlimited) for contract attachments 2026-07-03 17:33:31 +08:00
587cabeb1e fix: ContractAttachMgr 覆盖 owner/quota 校验
is_folder_ownerid: 直接返回 True (合同附件不校验owner)
get_organization_quota: 无限制配额
2026-07-03 17:18:03 +08:00
b375ba5155 chore: remove vim swap file 2026-07-03 17:05:35 +08:00
a914380a9b feat: ContractAttachMgr — supplychain 自有附件管理器
ContractAttachMgr 继承 FileMgr, fiid 从 params_kw 透传
contract_upload.dspy: 自有上传端点
contract_attach.ui: 改用 supplychain 自己的上传 dspy
2026-07-03 17:05:24 +08:00
64e240872f fix: show_error → console.error (bricks 无此方法) 2026-07-03 16:54:26 +08:00
b4d66933a6 fix: get_files() -> this.value (UiFile 正确取值方式) 2026-07-03 16:51:51 +08:00
3497d946ce fix: Jinja2 转义 — upload_url 用 {% set %} 预计算
entire_url("/filemgr/...") 中的 " 导致 Jinja2 解析报错
改用 {% set upload_url = entire_url('/filemgr/upload_file.dspy') %}
2026-07-03 16:48:24 +08:00
a63b6ce427 fix: 附件上传改用 UiFile changed + fetch FormData
UiFile changed 事件 → script fetch POST multipart → 成功后 render Tabular
无需点击上传按钮,选择文件即自动上传
2026-07-03 16:46:14 +08:00
5968b3a527 feat: 注册 contract_attach RBAC 权限 2026-07-03 16:40:11 +08:00
1f06a23fa3 fix: 附件上传改用 Form submit_url (multipart) + UiFile multiple
Form submit_url 直接POST到 filemgr, 支持multipart文件上传
UiFile multiple: true 浏览器原生支持拖拽
去掉无用的按钮+toolbar
2026-07-03 16:37:26 +08:00
832d0828df fix: ensure_contract_folder 去掉不存在的 ownerid 列 2026-07-03 16:27:01 +08:00
3df4e237fc feat: 合同附件支持拖拽上传
drop_zone: 虚线边框拖放区域, 点击选择文件
Form: 隐藏字段 folderid+fiid + file input
Script: dragover/drop 事件处理, 拖入文件自动上传
2026-07-03 16:23:21 +08:00
fcec9422ab fix: supply_contract_items codes 表名修正
product_types → product_category (textfield: type_name → name)
products → product
2026-07-03 16:21:59 +08:00
e44c84d14c fix: created_by should be user_id not userorgid 2026-07-03 16:10:02 +08:00
724a912bc9 fix: remove duplicate supplier_id in new_data_url; JSON config is the correct fix, not dspy workaround 2026-07-03 16:09:30 +08:00
698f0f6e29 fix: unwrap list values from bricks code lookups (supplier_id was ['x','x']) before sor.C 2026-07-03 16:00:39 +08:00
fa81da2bbf fix: return plain dict (ahserver handles serialization), match CRUD pattern exactly 2026-07-03 15:54:19 +08:00
4a0b9db82a fix: follow CRUD add_llm pattern exactly — ns.copy(), sor.C, no param cleaning 2026-07-03 15:41:58 +08:00
6b6489af02 fix: back to sor.C with simple param cleaning 2026-07-03 15:40:11 +08:00
37c39a053f fix: sor.I takes 1 arg (data), not 2 2026-07-03 15:33:42 +08:00
fa5a1a3a8e feat: 供应合同和分销协议支持附件上传下载
contract_attach.ui: 附件管理页面(Tabular文件列表 + 上传按钮)
contract_attach_list.dspy: 查询合同附件列表
init.py: ensure_contract_folder() 自动创建附件目录
supply_contracts_list + distribution_agreements_list: 新增'合同附件'toolbar

实现: filemgr folder(contract_id=id, fiid=type)自动管理
2026-07-03 15:32:41 +08:00
1d99375578 fix: use whitelist approach - only pass known table columns to sor.I 2026-07-03 15:29:08 +08:00
959d021537 fix: clean _text suffix fields, use sor.I instead of sor.C, json.dumps return 2026-07-03 15:11:26 +08:00
da64e09090 fix: supply_contracts_create remove json.dumps 2026-07-03 15:10:01 +08:00
32070a53b1 fix: supplychain_accounting update/delete return widgettype format 2026-07-03 15:08:21 +08:00
63a1bedeba fix: clean non-table params before sor.C; return json.dumps instead of dict 2026-07-03 15:04:34 +08:00
f325ad0c93 fix: CRUD endpoint return format - remove json.dumps 2026-07-03 15:01:08 +08:00
2828426f76 fix: CRUD endpoint return format - remove json.dumps, use widgettype format 2026-07-03 14:53:31 +08:00
7c214552c5 fix: 供应商合同新增时 supplier_id 自动带过来
1. supplier_id 加入 editexclouded(表单不显示)
2. new_data_url 携带 supplier_id 查询参数
   → /api/supply_contracts_create.dspy?supplier_id=xxx
3. dspy 从 params_kw 自动获取 supplier_id
2026-07-03 14:34:37 +08:00
813882ff71 fix: supply_contracts_create generates contract_code automatically 2026-07-03 14:30:35 +08:00
3c742c0674 feat: 供应商管理添加「供应商合同」子表toolbar
选中供应商 → 点击「供应商合同」→ 弹出该供应商的合同列表
supplier_id 自动带过来,新增合同无需手动输入供应商
2026-07-03 14:23:20 +08:00