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",
|
"tblname": "distribution_agreement_items",
|
||||||
"alias": "distribution_agreement_items_list",
|
"alias": "distribution_agreement_items_list",
|
||||||
"title": "分销协议产品折扣",
|
"title": "分销协议产品折扣管理",
|
||||||
"params": {
|
"params": {
|
||||||
"sortby": ["prodtypeid", "productid"],
|
"sortby": [
|
||||||
|
"prodtypeid",
|
||||||
|
"productid"
|
||||||
|
],
|
||||||
"logined_userorgid": "resellerid",
|
"logined_userorgid": "resellerid",
|
||||||
"browserfields": {
|
"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": {
|
"editable": {
|
||||||
"new_data_url": "{{entire_url('../api/distribution_agreement_items_create.dspy')}}",
|
"new_data_url": "{{entire_url('../api/distribution_agreement_items_create.dspy')}}",
|
||||||
"update_data_url": "{{entire_url('../api/distribution_agreement_items_update.dspy')}}",
|
"update_data_url": "{{entire_url('../api/distribution_agreement_items_update.dspy')}}",
|
||||||
"delete_data_url": "{{entire_url('../api/distribution_agreement_items_delete.dspy')}}"
|
"delete_data_url": "{{entire_url('../api/distribution_agreement_items_delete.dspy')}}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3,33 +3,79 @@
|
|||||||
"alias": "distribution_agreements_list",
|
"alias": "distribution_agreements_list",
|
||||||
"title": "分销协议管理",
|
"title": "分销协议管理",
|
||||||
"params": {
|
"params": {
|
||||||
"sortby": ["created_at desc"],
|
"sortby": [
|
||||||
|
"created_at desc"
|
||||||
|
],
|
||||||
"logined_userorgid": "resellerid",
|
"logined_userorgid": "resellerid",
|
||||||
"data_filter": {
|
"data_filter": {
|
||||||
"AND": [
|
"AND": [
|
||||||
{"field": "agreement_name", "op": "LIKE", "var": "agreement_name"},
|
{
|
||||||
{"field": "agreement_code", "op": "LIKE", "var": "agreement_code"},
|
"field": "agreement_name",
|
||||||
{"field": "status", "op": "=", "var": "status"}
|
"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": {
|
"filter_labels": {
|
||||||
"agreement_name": "协议名称",
|
"agreement_name": "协议名称",
|
||||||
"agreement_code": "协议编号",
|
"agreement_code": "协议编号",
|
||||||
|
"sub_reseller_id": "二级分销商",
|
||||||
"status": "状态"
|
"status": "状态"
|
||||||
},
|
},
|
||||||
"browserfields": {
|
"browserfields": {
|
||||||
"exclouded": ["id"],
|
"exclouded": [
|
||||||
|
"id",
|
||||||
|
"resellerid"
|
||||||
|
],
|
||||||
"alters": {
|
"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": {
|
"status": {
|
||||||
"uitype": "code",
|
"uitype": "code",
|
||||||
"data": [
|
"data": [
|
||||||
{"value": "1", "text": "生效中"},
|
{
|
||||||
{"value": "2", "text": "已到期"},
|
"value": "1",
|
||||||
{"value": "0", "text": "已终止"}
|
"text": "生效中"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "2",
|
||||||
|
"text": "已到期"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "0",
|
||||||
|
"text": "已终止"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id",
|
||||||
|
"resellerid",
|
||||||
|
"agreement_code",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at"
|
||||||
|
],
|
||||||
"subtables": [
|
"subtables": [
|
||||||
{
|
{
|
||||||
"field": "agreement_id",
|
"field": "agreement_id",
|
||||||
@ -44,4 +90,4 @@
|
|||||||
"delete_data_url": "{{entire_url('../api/distribution_agreements_delete.dspy')}}"
|
"delete_data_url": "{{entire_url('../api/distribution_agreements_delete.dspy')}}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,22 +1,64 @@
|
|||||||
{
|
{
|
||||||
"tblname": "sub_distributors",
|
"tblname": "sub_distributors",
|
||||||
"alias": "sub_distributors_list",
|
"alias": "sub_distributors_list",
|
||||||
"title": "二级分销商管理",
|
"title": "分销商管理",
|
||||||
"params": {
|
"params": {
|
||||||
"sortby": [
|
"sortby": [
|
||||||
"created_at desc"
|
"created_at desc"
|
||||||
],
|
],
|
||||||
"logined_userorgid": "resellerid",
|
"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": {
|
"browserfields": {
|
||||||
"exclouded": [
|
"exclouded": [
|
||||||
|
"id",
|
||||||
|
"resellerid",
|
||||||
"created_by",
|
"created_by",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at"
|
"updated_at"
|
||||||
]
|
],
|
||||||
|
"alters": {
|
||||||
|
"status": {
|
||||||
|
"uitype": "code",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"value": "1",
|
||||||
|
"text": "正常"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "0",
|
||||||
|
"text": "停用"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"editexclouded": [
|
"editexclouded": [
|
||||||
"id",
|
"id",
|
||||||
"resellerid",
|
"resellerid",
|
||||||
|
"sub_dist_code",
|
||||||
"created_by",
|
"created_by",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at"
|
"updated_at"
|
||||||
@ -25,6 +67,14 @@
|
|||||||
"new_data_url": "{{entire_url('../api/sub_distributors_create.dspy')}}",
|
"new_data_url": "{{entire_url('../api/sub_distributors_create.dspy')}}",
|
||||||
"update_data_url": "{{entire_url('../api/sub_distributors_update.dspy')}}",
|
"update_data_url": "{{entire_url('../api/sub_distributors_update.dspy')}}",
|
||||||
"delete_data_url": "{{entire_url('../api/sub_distributors_delete.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_contract_id.dspy",
|
||||||
"/supplychain/api/get_search_prodtypeid.dspy",
|
"/supplychain/api/get_search_prodtypeid.dspy",
|
||||||
"/supplychain/api/get_search_productid.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
|
# CRUD API — sub_distributors
|
||||||
"/supplychain/api/sub_distributors_create.dspy",
|
"/supplychain/api/sub_distributors_create.dspy",
|
||||||
"/supplychain/api/sub_distributors_update.dspy",
|
"/supplychain/api/sub_distributors_update.dspy",
|
||||||
|
|||||||
@ -1,9 +1,2 @@
|
|||||||
import json
|
result = await create_distribution_agreement_items(request, params_kw)
|
||||||
from ahserver.serverenv import ServerEnv
|
return json.loads(result) if isinstance(result, str) else result
|
||||||
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)
|
|
||||||
|
|||||||
@ -1,9 +1,2 @@
|
|||||||
import json
|
result = await delete_distribution_agreement_items(request, params_kw)
|
||||||
from ahserver.serverenv import ServerEnv
|
return json.loads(result) if isinstance(result, str) else result
|
||||||
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)
|
|
||||||
|
|||||||
@ -1,9 +1,2 @@
|
|||||||
import json
|
result = await update_distribution_agreement_items(request, params_kw)
|
||||||
from ahserver.serverenv import ServerEnv
|
return json.loads(result) if isinstance(result, str) else result
|
||||||
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)
|
|
||||||
|
|||||||
@ -1,9 +1,2 @@
|
|||||||
import json
|
result = await create_distribution_agreements(request, params_kw)
|
||||||
from ahserver.serverenv import ServerEnv
|
return json.loads(result) if isinstance(result, str) else result
|
||||||
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)
|
|
||||||
|
|||||||
@ -1,9 +1,2 @@
|
|||||||
import json
|
result = await delete_distribution_agreements(request, params_kw)
|
||||||
from ahserver.serverenv import ServerEnv
|
return json.loads(result) if isinstance(result, str) else result
|
||||||
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)
|
|
||||||
|
|||||||
@ -1,9 +1,2 @@
|
|||||||
import json
|
result = await update_distribution_agreements(request, params_kw)
|
||||||
from ahserver.serverenv import ServerEnv
|
return json.loads(result) if isinstance(result, str) else result
|
||||||
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)
|
|
||||||
|
|||||||
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
|
result = await create_sub_distributors(request, params_kw)
|
||||||
from appPublic.uniqueID import getID
|
return json.loads(result) if isinstance(result, str) else result
|
||||||
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})
|
|
||||||
|
|||||||
@ -1,19 +1,2 @@
|
|||||||
import json
|
result = await delete_sub_distributors(request, params_kw)
|
||||||
|
return json.loads(result) if isinstance(result, str) else result
|
||||||
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"})
|
|
||||||
|
|||||||
@ -1,27 +1,2 @@
|
|||||||
import json
|
result = await update_sub_distributors(request, params_kw)
|
||||||
from datetime import datetime
|
return json.loads(result) if isinstance(result, str) else result
|
||||||
|
|
||||||
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})
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ if not userorgid:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ns['resellerid'] = userorgid
|
ns['resellerid'] = userorgid
|
||||||
|
ns['created_at'] = timestampstr()
|
||||||
|
|
||||||
db = DBPools()
|
db = DBPools()
|
||||||
dbname = get_module_dbname('supplychain')
|
dbname = get_module_dbname('supplychain')
|
||||||
|
|||||||
@ -23,7 +23,7 @@ if not ns.get('page'):
|
|||||||
if not ns.get('sort'):
|
if not ns.get('sort'):
|
||||||
|
|
||||||
|
|
||||||
ns['sort'] = ["prodtypeid","productid"]
|
ns['sort'] = ["prodtypeid", "productid"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -44,10 +44,36 @@
|
|||||||
"id",
|
"id",
|
||||||
"agreement_id",
|
"agreement_id",
|
||||||
"resellerid"
|
"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":[
|
"fields":[
|
||||||
{
|
{
|
||||||
"name": "id",
|
"name": "id",
|
||||||
@ -78,7 +104,7 @@
|
|||||||
"valueField": "agreement_id",
|
"valueField": "agreement_id",
|
||||||
"textField": "agreement_id_text"
|
"textField": "agreement_id_text"
|
||||||
},
|
},
|
||||||
"dataurl": "{{entire_url('/appbase/get_code.dspy')}}"
|
"dataurl": "{{entire_url('../api/get_search_agreement_id.dspy')}}"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "resellerid",
|
"name": "resellerid",
|
||||||
@ -97,9 +123,12 @@
|
|||||||
"type": "str",
|
"type": "str",
|
||||||
"length": 32,
|
"length": 32,
|
||||||
"cwidth": 18,
|
"cwidth": 18,
|
||||||
"uitype": "str",
|
"uitype": "code",
|
||||||
"datatype": "str",
|
"datatype": "str",
|
||||||
"label": "产品分类ID"
|
"label": "产品分类ID",
|
||||||
|
"dataurl": "{{entire_url('../api/get_search_prodtypeid.dspy')}}",
|
||||||
|
"valueField": "prodtypeid",
|
||||||
|
"textField": "prodtypeid_text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "productid",
|
"name": "productid",
|
||||||
@ -107,9 +136,12 @@
|
|||||||
"type": "str",
|
"type": "str",
|
||||||
"length": 32,
|
"length": 32,
|
||||||
"cwidth": 18,
|
"cwidth": 18,
|
||||||
"uitype": "str",
|
"uitype": "code",
|
||||||
"datatype": "str",
|
"datatype": "str",
|
||||||
"label": "产品ID"
|
"label": "产品ID",
|
||||||
|
"dataurl": "{{entire_url('../api/get_search_productid.dspy')}}",
|
||||||
|
"valueField": "productid",
|
||||||
|
"textField": "productid_text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "discount",
|
"name": "discount",
|
||||||
|
|||||||
@ -24,6 +24,21 @@ if not userorgid:
|
|||||||
}
|
}
|
||||||
ns['resellerid'] = 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()
|
db = DBPools()
|
||||||
dbname = get_module_dbname('supplychain')
|
dbname = get_module_dbname('supplychain')
|
||||||
async with db.sqlorContext(dbname) as sor:
|
async with db.sqlorContext(dbname) as sor:
|
||||||
@ -48,4 +63,4 @@ return {
|
|||||||
"timeout":3,
|
"timeout":3,
|
||||||
"message":"failed"
|
"message":"failed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,8 @@ ns['resellerid'] = userorgid
|
|||||||
db = DBPools()
|
db = DBPools()
|
||||||
dbname = get_module_dbname('supplychain')
|
dbname = get_module_dbname('supplychain')
|
||||||
async with db.sqlorContext(dbname) as sor:
|
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)
|
r = await sor.D('distribution_agreements', ns)
|
||||||
debug('delete success');
|
debug('delete success');
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -52,9 +52,16 @@
|
|||||||
|
|
||||||
"browserfields": {
|
"browserfields": {
|
||||||
"exclouded": [
|
"exclouded": [
|
||||||
"id"
|
"id",
|
||||||
|
"resellerid"
|
||||||
],
|
],
|
||||||
"alters": {
|
"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": {
|
"status": {
|
||||||
"uitype": "code",
|
"uitype": "code",
|
||||||
"data": [
|
"data": [
|
||||||
@ -76,6 +83,15 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
"editexclouded":[
|
||||||
|
"id",
|
||||||
|
"resellerid",
|
||||||
|
"agreement_code",
|
||||||
|
"created_by",
|
||||||
|
"created_at",
|
||||||
|
"updated_at"
|
||||||
|
],
|
||||||
|
|
||||||
"fields":[
|
"fields":[
|
||||||
{
|
{
|
||||||
"name": "id",
|
"name": "id",
|
||||||
@ -126,7 +142,7 @@
|
|||||||
"valueField": "sub_reseller_id",
|
"valueField": "sub_reseller_id",
|
||||||
"textField": "sub_reseller_id_text"
|
"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",
|
"name": "agreement_code",
|
||||||
@ -271,6 +287,11 @@
|
|||||||
"op": "LIKE",
|
"op": "LIKE",
|
||||||
"var": "agreement_code"
|
"var": "agreement_code"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"field": "sub_reseller_id",
|
||||||
|
"op": "=",
|
||||||
|
"var": "sub_reseller_id"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"field": "status",
|
"field": "status",
|
||||||
"op": "=",
|
"op": "=",
|
||||||
@ -283,6 +304,7 @@
|
|||||||
"filter_labels":{
|
"filter_labels":{
|
||||||
"agreement_name": "协议名称",
|
"agreement_name": "协议名称",
|
||||||
"agreement_code": "协议编号",
|
"agreement_code": "协议编号",
|
||||||
|
"sub_reseller_id": "二级分销商",
|
||||||
"status": "状态"
|
"status": "状态"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,20 @@ if not userorgid:
|
|||||||
}
|
}
|
||||||
ns['resellerid'] = 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()
|
db = DBPools()
|
||||||
dbname = get_module_dbname('supplychain')
|
dbname = get_module_dbname('supplychain')
|
||||||
async with db.sqlorContext(dbname) as sor:
|
async with db.sqlorContext(dbname) as sor:
|
||||||
@ -48,4 +62,4 @@ return {
|
|||||||
"timeout":3,
|
"timeout":3,
|
||||||
"message":"failed"
|
"message":"failed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,16 @@ ns['resellerid'] = userorgid
|
|||||||
db = DBPools()
|
db = DBPools()
|
||||||
dbname = get_module_dbname('supplychain')
|
dbname = get_module_dbname('supplychain')
|
||||||
async with db.sqlorContext(dbname) as sor:
|
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)
|
r = await sor.D('sub_distributors', ns)
|
||||||
debug('delete success');
|
debug('delete success');
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -15,6 +15,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"toolbar":{
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"selected_row": true,
|
||||||
|
"name": "distribution_agreements",
|
||||||
|
"icon": "{{entire_url('/imgs/distribution_agreements.svg')}}",
|
||||||
|
"label": "分销协议"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
"css":"card",
|
"css":"card",
|
||||||
|
|
||||||
|
|
||||||
@ -41,16 +52,34 @@
|
|||||||
|
|
||||||
"browserfields": {
|
"browserfields": {
|
||||||
"exclouded": [
|
"exclouded": [
|
||||||
|
"id",
|
||||||
|
"resellerid",
|
||||||
"created_by",
|
"created_by",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at"
|
"updated_at"
|
||||||
]
|
],
|
||||||
|
"alters": {
|
||||||
|
"status": {
|
||||||
|
"uitype": "code",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"value": "1",
|
||||||
|
"text": "正常"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "0",
|
||||||
|
"text": "停用"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
"editexclouded":[
|
"editexclouded":[
|
||||||
"id",
|
"id",
|
||||||
"resellerid",
|
"resellerid",
|
||||||
|
"sub_dist_code",
|
||||||
"created_by",
|
"created_by",
|
||||||
"created_at",
|
"created_at",
|
||||||
"updated_at"
|
"updated_at"
|
||||||
@ -198,9 +227,19 @@
|
|||||||
"nullable": "no",
|
"nullable": "no",
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"cwidth": 4,
|
"cwidth": 4,
|
||||||
"uitype": "str",
|
"uitype": "code",
|
||||||
"datatype": "char",
|
"datatype": "char",
|
||||||
"label": "状态"
|
"label": "状态",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"value": "1",
|
||||||
|
"text": "正常"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "0",
|
||||||
|
"text": "停用"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "remark",
|
"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
|
"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