feat: 完善分销商管理CRUD — sub_distributors/distribution_agreements/distribution_agreement_items
- 增强3个CRUD JSON配置:过滤器、子表关联、下拉选择alters - 修复9个API dspy文件:移除违规import,改用init.py函数直接调用 - 新增2个搜索API:get_search_sub_reseller_id、get_search_agreement_id - 自动生成分销商编号(SD-YYYYMMDD-NNNN)和协议编号(DA-YYYYMMDD-NNNN) - 级联删除:删除分销商时级联删除协议及明细,删除协议时级联删除明细 - 更新load_path.py注册新API路径
This commit is contained in:
parent
669c491f93
commit
047ec1800a
@ -1,17 +1,49 @@
|
||||
{
|
||||
"tblname": "distribution_agreement_items",
|
||||
"alias": "distribution_agreement_items_list",
|
||||
"title": "分销协议产品折扣",
|
||||
"title": "分销协议产品折扣管理",
|
||||
"params": {
|
||||
"sortby": ["prodtypeid", "productid"],
|
||||
"sortby": [
|
||||
"prodtypeid",
|
||||
"productid"
|
||||
],
|
||||
"logined_userorgid": "resellerid",
|
||||
"browserfields": {
|
||||
"exclouded": ["id", "agreement_id", "resellerid"]
|
||||
"exclouded": [
|
||||
"id",
|
||||
"agreement_id",
|
||||
"resellerid"
|
||||
],
|
||||
"alters": {
|
||||
"agreement_id": {
|
||||
"uitype": "code",
|
||||
"dataurl": "{{entire_url('../api/get_search_agreement_id.dspy')}}",
|
||||
"valueField": "agreement_id",
|
||||
"textField": "agreement_id_text"
|
||||
},
|
||||
"prodtypeid": {
|
||||
"uitype": "code",
|
||||
"dataurl": "{{entire_url('../api/get_search_prodtypeid.dspy')}}",
|
||||
"valueField": "prodtypeid",
|
||||
"textField": "prodtypeid_text"
|
||||
},
|
||||
"productid": {
|
||||
"uitype": "code",
|
||||
"dataurl": "{{entire_url('../api/get_search_productid.dspy')}}",
|
||||
"valueField": "productid",
|
||||
"textField": "productid_text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id",
|
||||
"resellerid",
|
||||
"created_at"
|
||||
],
|
||||
"editable": {
|
||||
"new_data_url": "{{entire_url('../api/distribution_agreement_items_create.dspy')}}",
|
||||
"update_data_url": "{{entire_url('../api/distribution_agreement_items_update.dspy')}}",
|
||||
"delete_data_url": "{{entire_url('../api/distribution_agreement_items_delete.dspy')}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,33 +3,79 @@
|
||||
"alias": "distribution_agreements_list",
|
||||
"title": "分销协议管理",
|
||||
"params": {
|
||||
"sortby": ["created_at desc"],
|
||||
"sortby": [
|
||||
"created_at desc"
|
||||
],
|
||||
"logined_userorgid": "resellerid",
|
||||
"data_filter": {
|
||||
"AND": [
|
||||
{"field": "agreement_name", "op": "LIKE", "var": "agreement_name"},
|
||||
{"field": "agreement_code", "op": "LIKE", "var": "agreement_code"},
|
||||
{"field": "status", "op": "=", "var": "status"}
|
||||
{
|
||||
"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": "状态"
|
||||
},
|
||||
"browserfields": {
|
||||
"exclouded": ["id"],
|
||||
"exclouded": [
|
||||
"id",
|
||||
"resellerid"
|
||||
],
|
||||
"alters": {
|
||||
"sub_reseller_id": {
|
||||
"uitype": "code",
|
||||
"dataurl": "{{entire_url('../api/get_search_sub_reseller_id.dspy')}}",
|
||||
"valueField": "sub_reseller_id",
|
||||
"textField": "sub_reseller_id_text"
|
||||
},
|
||||
"status": {
|
||||
"uitype": "code",
|
||||
"data": [
|
||||
{"value": "1", "text": "生效中"},
|
||||
{"value": "2", "text": "已到期"},
|
||||
{"value": "0", "text": "已终止"}
|
||||
{
|
||||
"value": "1",
|
||||
"text": "生效中"
|
||||
},
|
||||
{
|
||||
"value": "2",
|
||||
"text": "已到期"
|
||||
},
|
||||
{
|
||||
"value": "0",
|
||||
"text": "已终止"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id",
|
||||
"resellerid",
|
||||
"agreement_code",
|
||||
"created_by",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
],
|
||||
"subtables": [
|
||||
{
|
||||
"field": "agreement_id",
|
||||
@ -44,4 +90,4 @@
|
||||
"delete_data_url": "{{entire_url('../api/distribution_agreements_delete.dspy')}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,22 +1,64 @@
|
||||
{
|
||||
"tblname": "sub_distributors",
|
||||
"alias": "sub_distributors_list",
|
||||
"title": "二级分销商管理",
|
||||
"title": "分销商管理",
|
||||
"params": {
|
||||
"sortby": [
|
||||
"created_at desc"
|
||||
],
|
||||
"logined_userorgid": "resellerid",
|
||||
"data_filter": {
|
||||
"AND": [
|
||||
{
|
||||
"field": "sub_dist_name",
|
||||
"op": "LIKE",
|
||||
"var": "sub_dist_name"
|
||||
},
|
||||
{
|
||||
"field": "sub_dist_code",
|
||||
"op": "LIKE",
|
||||
"var": "sub_dist_code"
|
||||
},
|
||||
{
|
||||
"field": "status",
|
||||
"op": "=",
|
||||
"var": "status"
|
||||
}
|
||||
]
|
||||
},
|
||||
"filter_labels": {
|
||||
"sub_dist_name": "分销商名称",
|
||||
"sub_dist_code": "分销商编号",
|
||||
"status": "状态"
|
||||
},
|
||||
"browserfields": {
|
||||
"exclouded": [
|
||||
"id",
|
||||
"resellerid",
|
||||
"created_by",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
]
|
||||
],
|
||||
"alters": {
|
||||
"status": {
|
||||
"uitype": "code",
|
||||
"data": [
|
||||
{
|
||||
"value": "1",
|
||||
"text": "正常"
|
||||
},
|
||||
{
|
||||
"value": "0",
|
||||
"text": "停用"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"editexclouded": [
|
||||
"id",
|
||||
"resellerid",
|
||||
"sub_dist_code",
|
||||
"created_by",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
@ -25,6 +67,14 @@
|
||||
"new_data_url": "{{entire_url('../api/sub_distributors_create.dspy')}}",
|
||||
"update_data_url": "{{entire_url('../api/sub_distributors_update.dspy')}}",
|
||||
"delete_data_url": "{{entire_url('../api/sub_distributors_delete.dspy')}}"
|
||||
}
|
||||
},
|
||||
"subtables": [
|
||||
{
|
||||
"field": "sub_reseller_id",
|
||||
"title": "分销协议",
|
||||
"url": "{{entire_url('../distribution_agreements_list')}}",
|
||||
"subtable": "distribution_agreements"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -99,6 +99,8 @@ PATHS_LOGINED = [
|
||||
"/supplychain/api/get_search_contract_id.dspy",
|
||||
"/supplychain/api/get_search_prodtypeid.dspy",
|
||||
"/supplychain/api/get_search_productid.dspy",
|
||||
"/supplychain/api/get_search_sub_reseller_id.dspy",
|
||||
"/supplychain/api/get_search_agreement_id.dspy",
|
||||
# CRUD API — sub_distributors
|
||||
"/supplychain/api/sub_distributors_create.dspy",
|
||||
"/supplychain/api/sub_distributors_update.dspy",
|
||||
|
||||
@ -1,9 +1,2 @@
|
||||
import json
|
||||
from ahserver.serverenv import ServerEnv
|
||||
env = ServerEnv()
|
||||
create_func = getattr(env, 'create_distribution_agreement_items', None)
|
||||
if create_func is None:
|
||||
print(json.dumps({"status": "error", "message": "create_distribution_agreement_items function not found"}))
|
||||
else:
|
||||
result = await create_func(request, params_kw)
|
||||
print(result)
|
||||
result = await create_distribution_agreement_items(request, params_kw)
|
||||
return json.loads(result) if isinstance(result, str) else result
|
||||
|
||||
@ -1,9 +1,2 @@
|
||||
import json
|
||||
from ahserver.serverenv import ServerEnv
|
||||
env = ServerEnv()
|
||||
delete_func = getattr(env, 'delete_distribution_agreement_items', None)
|
||||
if delete_func is None:
|
||||
print(json.dumps({"status": "error", "message": "delete_distribution_agreement_items function not found"}))
|
||||
else:
|
||||
result = await delete_func(request, params_kw)
|
||||
print(result)
|
||||
result = await delete_distribution_agreement_items(request, params_kw)
|
||||
return json.loads(result) if isinstance(result, str) else result
|
||||
|
||||
@ -1,9 +1,2 @@
|
||||
import json
|
||||
from ahserver.serverenv import ServerEnv
|
||||
env = ServerEnv()
|
||||
update_func = getattr(env, 'update_distribution_agreement_items', None)
|
||||
if update_func is None:
|
||||
print(json.dumps({"status": "error", "message": "update_distribution_agreement_items function not found"}))
|
||||
else:
|
||||
result = await update_func(request, params_kw)
|
||||
print(result)
|
||||
result = await update_distribution_agreement_items(request, params_kw)
|
||||
return json.loads(result) if isinstance(result, str) else result
|
||||
|
||||
@ -1,9 +1,2 @@
|
||||
import json
|
||||
from ahserver.serverenv import ServerEnv
|
||||
env = ServerEnv()
|
||||
create_func = getattr(env, 'create_distribution_agreements', None)
|
||||
if create_func is None:
|
||||
print(json.dumps({"status": "error", "message": "create_distribution_agreements function not found"}))
|
||||
else:
|
||||
result = await create_func(request, params_kw)
|
||||
print(result)
|
||||
result = await create_distribution_agreements(request, params_kw)
|
||||
return json.loads(result) if isinstance(result, str) else result
|
||||
|
||||
@ -1,9 +1,2 @@
|
||||
import json
|
||||
from ahserver.serverenv import ServerEnv
|
||||
env = ServerEnv()
|
||||
delete_func = getattr(env, 'delete_distribution_agreements', None)
|
||||
if delete_func is None:
|
||||
print(json.dumps({"status": "error", "message": "delete_distribution_agreements function not found"}))
|
||||
else:
|
||||
result = await delete_func(request, params_kw)
|
||||
print(result)
|
||||
result = await delete_distribution_agreements(request, params_kw)
|
||||
return json.loads(result) if isinstance(result, str) else result
|
||||
|
||||
@ -1,9 +1,2 @@
|
||||
import json
|
||||
from ahserver.serverenv import ServerEnv
|
||||
env = ServerEnv()
|
||||
update_func = getattr(env, 'update_distribution_agreements', None)
|
||||
if update_func is None:
|
||||
print(json.dumps({"status": "error", "message": "update_distribution_agreements function not found"}))
|
||||
else:
|
||||
result = await update_func(request, params_kw)
|
||||
print(result)
|
||||
result = await update_distribution_agreements(request, params_kw)
|
||||
return json.loads(result) if isinstance(result, str) else result
|
||||
|
||||
16
wwwroot/api/get_search_agreement_id.dspy
Normal file
16
wwwroot/api/get_search_agreement_id.dspy
Normal file
@ -0,0 +1,16 @@
|
||||
result = [{'agreement_id': '', 'agreement_id_text': '全部'}]
|
||||
try:
|
||||
userorgid = await get_userorgid()
|
||||
if not userorgid:
|
||||
return json.dumps(result, ensure_ascii=False)
|
||||
db = DBPools()
|
||||
dbname = get_module_dbname('supplychain')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
rows = await sor.sqlExe(
|
||||
"select id as agreement_id, agreement_name as agreement_id_text from distribution_agreements where resellerid = ${userorgid}$ and status = '1' order by agreement_name",
|
||||
{"userorgid": userorgid}
|
||||
)
|
||||
return json.dumps(result + list(rows), ensure_ascii=False)
|
||||
except Exception as e:
|
||||
debug(f'get_search_agreement_id error: {e}')
|
||||
return json.dumps(result, ensure_ascii=False)
|
||||
16
wwwroot/api/get_search_sub_reseller_id.dspy
Normal file
16
wwwroot/api/get_search_sub_reseller_id.dspy
Normal file
@ -0,0 +1,16 @@
|
||||
result = [{'sub_reseller_id': '', 'sub_reseller_id_text': '全部'}]
|
||||
try:
|
||||
userorgid = await get_userorgid()
|
||||
if not userorgid:
|
||||
return json.dumps(result, ensure_ascii=False)
|
||||
db = DBPools()
|
||||
dbname = get_module_dbname('supplychain')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
rows = await sor.sqlExe(
|
||||
"select id as sub_reseller_id, sub_reseller_name as sub_reseller_id_text from sub_resellers where resellerid = ${userorgid}$ and status = '1' order by sub_reseller_name",
|
||||
{"userorgid": userorgid}
|
||||
)
|
||||
return json.dumps(result + list(rows), ensure_ascii=False)
|
||||
except Exception as e:
|
||||
debug(f'get_search_sub_reseller_id error: {e}')
|
||||
return json.dumps(result, ensure_ascii=False)
|
||||
@ -1,28 +1,2 @@
|
||||
import json
|
||||
from appPublic.uniqueID import getID
|
||||
from datetime import datetime
|
||||
|
||||
async def main(request, params_kw):
|
||||
"""Create a new sub_distributors record."""
|
||||
user_id = await get_user()
|
||||
user_orgid = await get_userorgid()
|
||||
dbname = get_module_dbname('supplychain')
|
||||
|
||||
data = params_kw.get("data", "{}")
|
||||
if isinstance(data, str):
|
||||
data = json.loads(data)
|
||||
|
||||
data["id"] = getID()
|
||||
data["resellerid"] = user_orgid
|
||||
data["created_by"] = user_id
|
||||
data["created_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# Auto-generate sub distributor code
|
||||
if not data.get("sub_dist_code"):
|
||||
data["sub_dist_code"] = f"SUB-{datetime.now().strftime('%Y%m%d')}-{getID()[:4].upper()}"
|
||||
|
||||
config = getConfig(".")
|
||||
DBPools(config.databases)
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
await sor.C("sub_distributors", data)
|
||||
return json.dumps({"status": "ok", "data": data})
|
||||
result = await create_sub_distributors(request, params_kw)
|
||||
return json.loads(result) if isinstance(result, str) else result
|
||||
|
||||
@ -1,19 +1,2 @@
|
||||
import json
|
||||
|
||||
async def main(request, params_kw):
|
||||
"""Delete a sub_distributors record."""
|
||||
dbname = get_module_dbname('supplychain')
|
||||
|
||||
data = params_kw.get("data", "{}")
|
||||
if isinstance(data, str):
|
||||
data = json.loads(data)
|
||||
|
||||
record_id = data.get("id")
|
||||
if not record_id:
|
||||
return json.dumps({"status": "error", "message": "Missing record id"})
|
||||
|
||||
config = getConfig(".")
|
||||
DBPools(config.databases)
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
await sor.D("sub_distributors", {"id": record_id})
|
||||
return json.dumps({"status": "ok", "message": "Deleted successfully"})
|
||||
result = await delete_sub_distributors(request, params_kw)
|
||||
return json.loads(result) if isinstance(result, str) else result
|
||||
|
||||
@ -1,27 +1,2 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
async def main(request, params_kw):
|
||||
"""Update a sub_distributors record."""
|
||||
user_id = await get_user()
|
||||
dbname = get_module_dbname('supplychain')
|
||||
|
||||
data = params_kw.get("data", "{}")
|
||||
if isinstance(data, str):
|
||||
data = json.loads(data)
|
||||
|
||||
record_id = data.get("id")
|
||||
if not record_id:
|
||||
return json.dumps({"status": "error", "message": "Missing record id"})
|
||||
|
||||
data["updated_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# Remove fields that should not be updated
|
||||
for key in ["id", "resellerid", "created_by", "created_at"]:
|
||||
data.pop(key, None)
|
||||
|
||||
config = getConfig(".")
|
||||
DBPools(config.databases)
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
await sor.U("sub_distributors", data)
|
||||
return json.dumps({"status": "ok", "data": data})
|
||||
result = await update_sub_distributors(request, params_kw)
|
||||
return json.loads(result) if isinstance(result, str) else result
|
||||
|
||||
@ -23,6 +23,7 @@ if not userorgid:
|
||||
}
|
||||
}
|
||||
ns['resellerid'] = userorgid
|
||||
ns['created_at'] = timestampstr()
|
||||
|
||||
db = DBPools()
|
||||
dbname = get_module_dbname('supplychain')
|
||||
|
||||
@ -23,7 +23,7 @@ if not ns.get('page'):
|
||||
if not ns.get('sort'):
|
||||
|
||||
|
||||
ns['sort'] = ["prodtypeid","productid"]
|
||||
ns['sort'] = ["prodtypeid", "productid"]
|
||||
|
||||
|
||||
|
||||
|
||||
@ -44,10 +44,36 @@
|
||||
"id",
|
||||
"agreement_id",
|
||||
"resellerid"
|
||||
]
|
||||
],
|
||||
"alters": {
|
||||
"agreement_id": {
|
||||
"uitype": "code",
|
||||
"dataurl": "{{entire_url('../api/get_search_agreement_id.dspy')}}",
|
||||
"valueField": "agreement_id",
|
||||
"textField": "agreement_id_text"
|
||||
},
|
||||
"prodtypeid": {
|
||||
"uitype": "code",
|
||||
"dataurl": "{{entire_url('../api/get_search_prodtypeid.dspy')}}",
|
||||
"valueField": "prodtypeid",
|
||||
"textField": "prodtypeid_text"
|
||||
},
|
||||
"productid": {
|
||||
"uitype": "code",
|
||||
"dataurl": "{{entire_url('../api/get_search_productid.dspy')}}",
|
||||
"valueField": "productid",
|
||||
"textField": "productid_text"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"editexclouded":[
|
||||
"id",
|
||||
"resellerid",
|
||||
"created_at"
|
||||
],
|
||||
|
||||
"fields":[
|
||||
{
|
||||
"name": "id",
|
||||
@ -78,7 +104,7 @@
|
||||
"valueField": "agreement_id",
|
||||
"textField": "agreement_id_text"
|
||||
},
|
||||
"dataurl": "{{entire_url('/appbase/get_code.dspy')}}"
|
||||
"dataurl": "{{entire_url('../api/get_search_agreement_id.dspy')}}"
|
||||
},
|
||||
{
|
||||
"name": "resellerid",
|
||||
@ -97,9 +123,12 @@
|
||||
"type": "str",
|
||||
"length": 32,
|
||||
"cwidth": 18,
|
||||
"uitype": "str",
|
||||
"uitype": "code",
|
||||
"datatype": "str",
|
||||
"label": "产品分类ID"
|
||||
"label": "产品分类ID",
|
||||
"dataurl": "{{entire_url('../api/get_search_prodtypeid.dspy')}}",
|
||||
"valueField": "prodtypeid",
|
||||
"textField": "prodtypeid_text"
|
||||
},
|
||||
{
|
||||
"name": "productid",
|
||||
@ -107,9 +136,12 @@
|
||||
"type": "str",
|
||||
"length": 32,
|
||||
"cwidth": 18,
|
||||
"uitype": "str",
|
||||
"uitype": "code",
|
||||
"datatype": "str",
|
||||
"label": "产品ID"
|
||||
"label": "产品ID",
|
||||
"dataurl": "{{entire_url('../api/get_search_productid.dspy')}}",
|
||||
"valueField": "productid",
|
||||
"textField": "productid_text"
|
||||
},
|
||||
{
|
||||
"name": "discount",
|
||||
|
||||
@ -24,6 +24,21 @@ 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:
|
||||
@ -48,4 +63,4 @@ return {
|
||||
"timeout":3,
|
||||
"message":"failed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@ 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 {
|
||||
|
||||
@ -52,9 +52,16 @@
|
||||
|
||||
"browserfields": {
|
||||
"exclouded": [
|
||||
"id"
|
||||
"id",
|
||||
"resellerid"
|
||||
],
|
||||
"alters": {
|
||||
"sub_reseller_id": {
|
||||
"uitype": "code",
|
||||
"dataurl": "{{entire_url('../api/get_search_sub_reseller_id.dspy')}}",
|
||||
"valueField": "sub_reseller_id",
|
||||
"textField": "sub_reseller_id_text"
|
||||
},
|
||||
"status": {
|
||||
"uitype": "code",
|
||||
"data": [
|
||||
@ -76,6 +83,15 @@
|
||||
},
|
||||
|
||||
|
||||
"editexclouded":[
|
||||
"id",
|
||||
"resellerid",
|
||||
"agreement_code",
|
||||
"created_by",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
],
|
||||
|
||||
"fields":[
|
||||
{
|
||||
"name": "id",
|
||||
@ -126,7 +142,7 @@
|
||||
"valueField": "sub_reseller_id",
|
||||
"textField": "sub_reseller_id_text"
|
||||
},
|
||||
"dataurl": "{{entire_url('/appbase/get_code.dspy')}}"
|
||||
"dataurl": "{{entire_url('../api/get_search_sub_reseller_id.dspy')}}"
|
||||
},
|
||||
{
|
||||
"name": "agreement_code",
|
||||
@ -271,6 +287,11 @@
|
||||
"op": "LIKE",
|
||||
"var": "agreement_code"
|
||||
},
|
||||
{
|
||||
"field": "sub_reseller_id",
|
||||
"op": "=",
|
||||
"var": "sub_reseller_id"
|
||||
},
|
||||
{
|
||||
"field": "status",
|
||||
"op": "=",
|
||||
@ -283,6 +304,7 @@
|
||||
"filter_labels":{
|
||||
"agreement_name": "协议名称",
|
||||
"agreement_code": "协议编号",
|
||||
"sub_reseller_id": "二级分销商",
|
||||
"status": "状态"
|
||||
},
|
||||
|
||||
|
||||
@ -24,6 +24,20 @@ if not userorgid:
|
||||
}
|
||||
ns['resellerid'] = userorgid
|
||||
|
||||
# Auto-generate sub_dist_code if not provided
|
||||
if not ns.get('sub_dist_code'):
|
||||
from datetime import datetime as _dt
|
||||
_prefix = f"SD-{_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 sub_distributors WHERE resellerid = ${rid}$ AND sub_dist_code LIKE ${p}$",
|
||||
{"rid": userorgid, "p": _prefix + "%"}
|
||||
)
|
||||
_seq = (_recs[0].cnt if _recs else 0) + 1
|
||||
ns['sub_dist_code'] = f"{_prefix}-{_seq:04d}"
|
||||
ns['created_by'] = userorgid
|
||||
ns['created_at'] = timestampstr()
|
||||
|
||||
db = DBPools()
|
||||
dbname = get_module_dbname('supplychain')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
@ -48,4 +62,4 @@ return {
|
||||
"timeout":3,
|
||||
"message":"failed"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,16 @@ ns['resellerid'] = userorgid
|
||||
db = DBPools()
|
||||
dbname = get_module_dbname('supplychain')
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
# Cascade delete distribution_agreement_items first (by agreement_id)
|
||||
_agreements = await sor.sqlExe(
|
||||
"SELECT id FROM distribution_agreements WHERE sub_reseller_id = ${sid}$",
|
||||
{"sid": ns['id']}
|
||||
)
|
||||
for _ag in (_agreements or []):
|
||||
await sor.D('distribution_agreement_items', {'agreement_id': _ag.id})
|
||||
# Cascade delete distribution_agreements
|
||||
await sor.D('distribution_agreements', {'sub_reseller_id': ns['id']})
|
||||
# Delete the sub_distributor
|
||||
r = await sor.D('sub_distributors', ns)
|
||||
debug('delete success');
|
||||
return {
|
||||
|
||||
@ -15,6 +15,17 @@
|
||||
|
||||
|
||||
|
||||
"toolbar":{
|
||||
"tools": [
|
||||
{
|
||||
"selected_row": true,
|
||||
"name": "distribution_agreements",
|
||||
"icon": "{{entire_url('/imgs/distribution_agreements.svg')}}",
|
||||
"label": "分销协议"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"css":"card",
|
||||
|
||||
|
||||
@ -41,16 +52,34 @@
|
||||
|
||||
"browserfields": {
|
||||
"exclouded": [
|
||||
"id",
|
||||
"resellerid",
|
||||
"created_by",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
]
|
||||
],
|
||||
"alters": {
|
||||
"status": {
|
||||
"uitype": "code",
|
||||
"data": [
|
||||
{
|
||||
"value": "1",
|
||||
"text": "正常"
|
||||
},
|
||||
{
|
||||
"value": "0",
|
||||
"text": "停用"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
"editexclouded":[
|
||||
"id",
|
||||
"resellerid",
|
||||
"sub_dist_code",
|
||||
"created_by",
|
||||
"created_at",
|
||||
"updated_at"
|
||||
@ -198,9 +227,19 @@
|
||||
"nullable": "no",
|
||||
"default": "1",
|
||||
"cwidth": 4,
|
||||
"uitype": "str",
|
||||
"uitype": "code",
|
||||
"datatype": "char",
|
||||
"label": "状态"
|
||||
"label": "状态",
|
||||
"data": [
|
||||
{
|
||||
"value": "1",
|
||||
"text": "正常"
|
||||
},
|
||||
{
|
||||
"value": "0",
|
||||
"text": "停用"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "remark",
|
||||
@ -245,6 +284,32 @@
|
||||
|
||||
|
||||
|
||||
"data_filter":{
|
||||
"AND": [
|
||||
{
|
||||
"field": "sub_dist_name",
|
||||
"op": "LIKE",
|
||||
"var": "sub_dist_name"
|
||||
},
|
||||
{
|
||||
"field": "sub_dist_code",
|
||||
"op": "LIKE",
|
||||
"var": "sub_dist_code"
|
||||
},
|
||||
{
|
||||
"field": "status",
|
||||
"op": "=",
|
||||
"var": "status"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
"filter_labels":{
|
||||
"sub_dist_name": "分销商名称",
|
||||
"sub_dist_code": "分销商编号",
|
||||
"status": "状态"
|
||||
},
|
||||
|
||||
|
||||
|
||||
@ -253,7 +318,33 @@
|
||||
"cache_limit":5
|
||||
}
|
||||
|
||||
,"binds":[]
|
||||
,"binds":[
|
||||
{
|
||||
"wid": "self",
|
||||
"event": "distribution_agreements",
|
||||
"actiontype": "urlwidget",
|
||||
"target": "PopupWindow",
|
||||
"popup_options": {
|
||||
"title": "分销协议",
|
||||
"icon": "{{entire_url('/appbase/get_icon.dspy')}}?id=distribution_agreements",
|
||||
"resizable": true,
|
||||
"height": "70%",
|
||||
"width": "70%"
|
||||
},
|
||||
"params_mapping": {
|
||||
"mapping": {
|
||||
"id": "sub_reseller_id",
|
||||
"referer_widget": "referer_widget"
|
||||
},
|
||||
"need_other": false
|
||||
},
|
||||
"options": {
|
||||
"method": "POST",
|
||||
"params": {},
|
||||
"url": "{{entire_url('../distribution_agreements_list')}}"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user