diff --git a/wwwroot/distribution_agreements_list/add_distribution_agreements.dspy b/wwwroot/distribution_agreements_list/add_distribution_agreements.dspy index 39a0c38..13b58fc 100644 --- a/wwwroot/distribution_agreements_list/add_distribution_agreements.dspy +++ b/wwwroot/distribution_agreements_list/add_distribution_agreements.dspy @@ -24,21 +24,6 @@ if not userorgid: } ns['resellerid'] = userorgid -# Auto-generate agreement_code if not provided -if not ns.get('agreement_code'): - from datetime import datetime as _dt - _prefix = f"DA-{_dt.now().strftime('%Y%m%d')}" - async with DBPools().sqlorContext(get_module_dbname('supplychain')) as _sor: - _recs = await _sor.sqlExe( - "SELECT COUNT(*) as cnt FROM distribution_agreements WHERE resellerid = ${rid}$ AND agreement_code LIKE ${p}$", - {"rid": userorgid, "p": _prefix + "%"} - ) - _seq = (_recs[0].cnt if _recs else 0) + 1 - ns['agreement_code'] = f"{_prefix}-{_seq:04d}" -ns['created_by'] = userorgid -ns['created_at'] = timestampstr() -ns['updated_at'] = timestampstr() - db = DBPools() dbname = get_module_dbname('supplychain') async with db.sqlorContext(dbname) as sor: @@ -46,6 +31,7 @@ async with db.sqlorContext(dbname) as sor: return { "widgettype":"Message", "options":{ + "user_data":ns, "cwidth":16, "cheight":9, "title":"Add Success", @@ -63,4 +49,4 @@ return { "timeout":3, "message":"failed" } -} +} \ No newline at end of file diff --git a/wwwroot/distribution_agreements_list/delete_distribution_agreements.dspy b/wwwroot/distribution_agreements_list/delete_distribution_agreements.dspy index 12ad247..b76e43c 100644 --- a/wwwroot/distribution_agreements_list/delete_distribution_agreements.dspy +++ b/wwwroot/distribution_agreements_list/delete_distribution_agreements.dspy @@ -21,8 +21,6 @@ ns['resellerid'] = userorgid db = DBPools() dbname = get_module_dbname('supplychain') async with db.sqlorContext(dbname) as sor: - # Cascade delete agreement items first - await sor.D('distribution_agreement_items', {'agreement_id': ns['id']}) r = await sor.D('distribution_agreements', ns) debug('delete success'); return { diff --git a/wwwroot/distribution_agreements_list/get_distribution_agreements.dspy b/wwwroot/distribution_agreements_list/get_distribution_agreements.dspy index ca68d4d..8c2fc3d 100644 --- a/wwwroot/distribution_agreements_list/get_distribution_agreements.dspy +++ b/wwwroot/distribution_agreements_list/get_distribution_agreements.dspy @@ -33,12 +33,8 @@ from (select * from distribution_agreements where 1=1 [[filterstr]]) a left join orgname as resellerid_text from organization where 1 = 1) c on a.resellerid = c.resellerid''' filterjson = params_kw.get('data_filter') -if filterjson and isinstance(filterjson, str): - try: - filterjson = json.loads(filterjson) - except (json.JSONDecodeError, TypeError): - filterjson = None -fields_str=r'''[ +if not filterjson: + fields = [ f['name'] for f in [ { "name": "id", "title": "主键ID", @@ -128,22 +124,8 @@ fields_str=r'''[ "title": "更新时间", "type": "datetime" } -]''' -ori_fields = json.loads(fields_str) -if not filterjson: - fields = [ f['name'] for f in ori_fields ] +] ] filterjson = default_filterjson(fields, ns) - -# 确保 logined 过滤条件始终生效 -if filterjson: - if not isinstance(filterjson, dict) or 'AND' not in filterjson: - filterjson = {'AND': [filterjson] if filterjson else []} - - filterjson['AND'].append({'field': 'resellerid', 'op': '=', 'var': '__logined_orgid__'}) - ns['__logined_orgid__'] = userorgid - - - filterdic = ns.copy() filterdic['filterstr'] = '' filterdic['userorgid'] = '${userorgid}$' diff --git a/wwwroot/distribution_agreements_list/index.ui b/wwwroot/distribution_agreements_list/index.ui index c900917..f7f0475 100644 --- a/wwwroot/distribution_agreements_list/index.ui +++ b/wwwroot/distribution_agreements_list/index.ui @@ -1,12 +1,10 @@ { - "widgettype":"VBox", - "options":{"width":"100%"}, - "subwidgets":[{ "id":"distribution_agreements_tbl", "widgettype":"Tabular", "options":{ "width":"100%", + "height":"100%", "title":"分销协议表", @@ -21,6 +19,12 @@ "name": "distribution_agreement_items", "icon": "{{entire_url('/imgs/distribution_agreement_items.svg')}}", "label": "产品分销折扣" + }, + { + "selected_row": true, + "name": "contract_attach", + "icon": "{{entire_url('/imgs/contract_attach.svg')}}", + "label": "合同附件" } ] }, @@ -30,18 +34,18 @@ "editable":{ - "new_data_url":"{{entire_url('/supplychain/api/distribution_agreements_create.dspy')}}", + "new_data_url":"{{entire_url('add_distribution_agreements.dspy')}}", - "delete_data_url":"{{entire_url('/supplychain/api/distribution_agreements_delete.dspy')}}", + "delete_data_url":"{{entire_url('delete_distribution_agreements.dspy')}}", - "update_data_url":"{{entire_url('/supplychain/api/distribution_agreements_update.dspy')}}" + "update_data_url":"{{entire_url('update_distribution_agreements.dspy')}}" }, - "data_url":"{{entire_url('/supplychain/distribution_agreements_list/get_distribution_agreements.dspy')}}", + "data_url":"{{entire_url('./get_distribution_agreements.dspy')}}", "data_method":"GET", "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, @@ -275,42 +279,6 @@ - "data_filter":{ - "AND": [ - { - "field": "agreement_name", - "op": "LIKE", - "var": "agreement_name" - }, - { - "field": "agreement_code", - "op": "LIKE", - "var": "agreement_code" - }, - { - "field": "sub_reseller_id", - "op": "=", - "var": "sub_reseller_id" - }, - { - "field": "status", - "op": "=", - "var": "status" - } - ] -}, - - - "filter_labels":{ - "agreement_name": "协议名称", - "agreement_code": "协议编号", - "sub_reseller_id": "二级分销商", - "status": "状态" -}, - - - - "page_rows":160, "cache_limit":5 } @@ -340,8 +308,33 @@ "params": {}, "url": "{{entire_url('/supplychain/agreement_discount_setting.ui')}}" } + }, + { + "wid": "self", + "event": "contract_attach", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "合同附件", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=contract_attach", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "contract_id", + "referer_widget": "referer_widget", + "contract_id": "id" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "{{entire_url('/supplychain/api/contract_attach.ui')}}?contract_type=distribution" + } } ] -}] } \ No newline at end of file diff --git a/wwwroot/imgs/contract_attach.svg b/wwwroot/imgs/contract_attach.svg new file mode 100644 index 0000000..78e4f5f --- /dev/null +++ b/wwwroot/imgs/contract_attach.svg @@ -0,0 +1,3 @@ + + + diff --git a/wwwroot/supply_contracts_list/add_supply_contracts.dspy b/wwwroot/supply_contracts_list/add_supply_contracts.dspy index 998d9d8..3efae94 100644 --- a/wwwroot/supply_contracts_list/add_supply_contracts.dspy +++ b/wwwroot/supply_contracts_list/add_supply_contracts.dspy @@ -24,21 +24,6 @@ if not userorgid: } ns['resellerid'] = userorgid -# Auto-generate contract_code if not provided -if not ns.get('contract_code'): - _today = curDateString().replace('-', '') - _prefix = f"SC-{_today}" - async with DBPools().sqlorContext(get_module_dbname('supplychain')) as _sor: - _recs = await _sor.sqlExe( - "SELECT COUNT(*) as cnt FROM supply_contracts WHERE resellerid = ${rid}$ AND contract_code LIKE ${p}$", - {"rid": userorgid, "p": _prefix + "%"} - ) - _seq = (_recs[0].cnt if _recs else 0) + 1 - ns['contract_code'] = f"{_prefix}-{_seq:04d}" -ns['created_by'] = userorgid -ns['created_at'] = timestampstr() -ns['updated_at'] = timestampstr() - db = DBPools() dbname = get_module_dbname('supplychain') async with db.sqlorContext(dbname) as sor: @@ -46,6 +31,7 @@ async with db.sqlorContext(dbname) as sor: return { "widgettype":"Message", "options":{ + "user_data":ns, "cwidth":16, "cheight":9, "title":"Add Success", diff --git a/wwwroot/supply_contracts_list/delete_supply_contracts.dspy b/wwwroot/supply_contracts_list/delete_supply_contracts.dspy index e77ec25..bbf6bb1 100644 --- a/wwwroot/supply_contracts_list/delete_supply_contracts.dspy +++ b/wwwroot/supply_contracts_list/delete_supply_contracts.dspy @@ -21,8 +21,6 @@ ns['resellerid'] = userorgid db = DBPools() dbname = get_module_dbname('supplychain') async with db.sqlorContext(dbname) as sor: - # Cascade delete contract items first - await sor.D('supply_contract_items', {'contract_id': params_kw['id'], 'resellerid': userorgid}) r = await sor.D('supply_contracts', ns) debug('delete success'); return { diff --git a/wwwroot/supply_contracts_list/get_supply_contracts.dspy b/wwwroot/supply_contracts_list/get_supply_contracts.dspy index 73cfdf0..3d7c57c 100644 --- a/wwwroot/supply_contracts_list/get_supply_contracts.dspy +++ b/wwwroot/supply_contracts_list/get_supply_contracts.dspy @@ -33,12 +33,8 @@ from (select * from supply_contracts where 1=1 [[filterstr]]) a left join (selec orgname as resellerid_text from organization where 1 = 1) c on a.resellerid = c.resellerid''' filterjson = params_kw.get('data_filter') -if filterjson and isinstance(filterjson, str): - try: - filterjson = json.loads(filterjson) - except (json.JSONDecodeError, TypeError): - filterjson = None -fields_str=r'''[ +if not filterjson: + fields = [ f['name'] for f in [ { "name": "id", "title": "主键ID", @@ -128,22 +124,8 @@ fields_str=r'''[ "title": "更新时间", "type": "datetime" } -]''' -ori_fields = json.loads(fields_str) -if not filterjson: - fields = [ f['name'] for f in ori_fields ] +] ] filterjson = default_filterjson(fields, ns) - -# 确保 logined 过滤条件始终生效 -if filterjson: - if not isinstance(filterjson, dict) or 'AND' not in filterjson: - filterjson = {'AND': [filterjson] if filterjson else []} - - filterjson['AND'].append({'field': 'resellerid', 'op': '=', 'var': '__logined_orgid__'}) - ns['__logined_orgid__'] = userorgid - - - filterdic = ns.copy() filterdic['filterstr'] = '' filterdic['userorgid'] = '${userorgid}$' diff --git a/wwwroot/supply_contracts_list/index.ui b/wwwroot/supply_contracts_list/index.ui index eeeb872..5ef0906 100644 --- a/wwwroot/supply_contracts_list/index.ui +++ b/wwwroot/supply_contracts_list/index.ui @@ -1,12 +1,10 @@ { - "widgettype":"VBox", - "options":{"width":"100%"}, - "subwidgets":[{ "id":"supply_contracts_tbl", "widgettype":"Tabular", "options":{ "width":"100%", + "height":"100%", "title":"供销合同表", @@ -21,6 +19,12 @@ "name": "supply_contract_items", "icon": "{{entire_url('/imgs/supply_contract_items.svg')}}", "label": "产品折扣明细" + }, + { + "selected_row": true, + "name": "contract_attach", + "icon": "{{entire_url('/imgs/contract_attach.svg')}}", + "label": "合同附件" } ] }, @@ -30,18 +34,18 @@ "editable":{ - "new_data_url":"{{entire_url('/supplychain/api/supply_contracts_create.dspy')}}", + "new_data_url":"{{entire_url('add_supply_contracts.dspy')}}", - "delete_data_url":"{{entire_url('/supplychain/api/supply_contracts_delete.dspy')}}", + "delete_data_url":"{{entire_url('delete_supply_contracts.dspy')}}", - "update_data_url":"{{entire_url('/supplychain/api/supply_contracts_update.dspy')}}" + "update_data_url":"{{entire_url('update_supply_contracts.dspy')}}" }, - "data_url":"{{entire_url('/supplychain/supply_contracts_list/get_supply_contracts.dspy')}}", + "data_url":"{{entire_url('./get_supply_contracts.dspy')}}", "data_method":"GET", "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, @@ -275,42 +279,6 @@ - "data_filter":{ - "AND": [ - { - "field": "contract_name", - "op": "LIKE", - "var": "contract_name" - }, - { - "field": "contract_code", - "op": "LIKE", - "var": "contract_code" - }, - { - "field": "supplier_id", - "op": "=", - "var": "supplier_id" - }, - { - "field": "status", - "op": "=", - "var": "status" - } - ] -}, - - - "filter_labels":{ - "contract_name": "合同名称", - "contract_code": "合同编号", - "supplier_id": "供应商", - "status": "状态" -}, - - - - "page_rows":160, "cache_limit":5 } @@ -340,8 +308,33 @@ "params": {}, "url": "{{entire_url('/supplychain/contract_discount_setting.ui')}}" } + }, + { + "wid": "self", + "event": "contract_attach", + "actiontype": "urlwidget", + "target": "PopupWindow", + "popup_options": { + "title": "合同附件", + "icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=contract_attach", + "resizable": true, + "height": "70%", + "width": "70%" + }, + "params_mapping": { + "mapping": { + "id": "contract_id", + "referer_widget": "referer_widget", + "contract_id": "id" + }, + "need_other": false + }, + "options": { + "method": "POST", + "params": {}, + "url": "{{entire_url('/supplychain/api/contract_attach.ui')}}?contract_type=supply" + } } ] -}] } \ No newline at end of file