This commit is contained in:
yumoqing 2026-04-04 18:14:16 +08:00
parent 270c5ec72a
commit 5c0e4a4397
7 changed files with 196 additions and 6 deletions

View File

@ -5,7 +5,7 @@
"sortby": "name", "sortby": "name",
"logined_userorgid": "ownerid", "logined_userorgid": "ownerid",
"browserfields": { "browserfields": {
"exclouded": ["id", "ownerid" ], "exclouded": ["id", "ownerid", "pricing_spec" ],
"alters": { "alters": {
"providerid":{ "providerid":{
"valueField": "id", "valueField": "id",
@ -24,6 +24,18 @@
"icon": "{{entire_url('/pricing/imgs/pricing_program_timing.svg')}}", "icon": "{{entire_url('/pricing/imgs/pricing_program_timing.svg')}}",
"subtable": "pricing_program_timing" "subtable": "pricing_program_timing"
} }
],
"toolbar":{
"tools":[
{
"name": "download_pattern",
"label": "定价模版",
"selected_row": true,
"icon": "{{entire_url('/bricks/imgs/download.svg')}}"
}
]
},
"binds":[
] ]
} }
} }

View File

@ -8,7 +8,7 @@
"alters": {} "alters": {}
}, },
"editexclouded": [ "editexclouded": [
"id", "ownerid", "ppid" "id", "ownerid", "ppid", "name"
], ],
"subtables":[ "subtables":[
{ {
@ -30,6 +30,14 @@
"name": "upload_pricing_data", "name": "upload_pricing_data",
"label": "上传定价数据", "label": "上传定价数据",
"icon": "{{entire_url('/bricks/imgs/upload.svg')}}" "icon": "{{entire_url('/bricks/imgs/upload.svg')}}"
}, {
"name": "download_pricing_data",
"label": "下载定价数据",
"icon": "{{entire_url('/bricks/imgs/download.svg')}}"
}, {
"name": "test",
"label": "验证定价",
"icon": "{{entire_url('/bricks/imgs/test.svg')}}"
} }
] ]
}, },
@ -57,6 +65,34 @@
}, },
"url": "{{entire_url('../load_pricing_data.ui')}}" "url": "{{entire_url('../load_pricing_data.ui')}}"
} }
},
{
"wid": "self",
"event": "download_pricing_data",
"actiontype": "urlwidget",
"target": "PopupWindow",
"popup_options":{
},
"options": {
"params": {
"pptid": "{{params_kw.id}}"
},
"url": "{{entire_url('../download_pricing_data.dspy')}}"
}
},
{
"wid": "self",
"event": "test",
"actiontype": "urlwidget",
"target": "PopupWindow",
"popup_options": {
},
"options":{
"params": {
"ppid": "{{params_kw.ppid}}"
},
"url": "{{entire_url('../pricing_test.ui')}}"
}
} }
] ]
} }

View File

@ -1,10 +1,14 @@
from pricing.pricing import ( from pricing.pricing import (
PricingProgram PricingProgram,
get_pricing_program,
get_pricing_program_timing
) )
from ahserver.serverenv import ServerEnv from ahserver.serverenv import ServerEnv
def load_pricing(): def load_pricing():
env = ServerEnv() env = ServerEnv()
env.get_pricing_program = get_pricing_program
env.get_pricing_program_timing = get_pricing_program_timing
env.write_pricing_patten = PricingProgram.write_pricing_patten env.write_pricing_patten = PricingProgram.write_pricing_patten
env.pricing_program_charging = PricingProgram.charging env.pricing_program_charging = PricingProgram.charging
env.load_pricing_data = PricingProgram.load_pricing_data env.load_pricing_data = PricingProgram.load_pricing_data

View File

@ -377,3 +377,44 @@ order by b.enabled_date desc"""
exception(e) exception(e)
raise Exception(e) raise Exception(e)
return ret_items return ret_items
async def get_pricing_program(ppid):
env = ServerEnv()
async with get_sor_context(env, 'pricing') as sor:
recs = await sor.R('pricing_program', {'id': ppid})
if len(recs) == 0:
exception(f'{ppid} not found in pricing_program_timing')
return None
pp = recs[0]
if ppt.pricing_data is None:
exception(f'{ppid} pricing_data is None in pricing_program_timing')
return None
try:
PricingProgram.pp_db2app(ppt)
except Exception as e:
return None
async def get_pricing_program_timeing(pptid):
env = ServerEnv()
async with get_sor_context(env, 'pricing') as sor:
recs = await sor.R('pricing_program_timing', {'id': pptid})
if len(recs) == 0:
exception(f'{pptid} not found in pricing_program_timing')
return None
ppt = recs[0]
if ppt.pricing_data is None:
exception(f'{pptid} pricing_data is None in pricing_program_timing')
return None
try:
PricingProgram.ppt_db2app(ppt)
except Exception as e:
return None
retrun ppt
async def test_pricing(pptid, data):
ppt = get_pricing_program_timeing(pptid)
prices = PricingProgram.get_pricing_from_ymalstr(data, ppt.pricing_data)
amount = 0
for p in prices:
amount += p.amount
return amount

View File

@ -19,7 +19,7 @@ def create_colnames():
colnames = create_colnames() colnames = create_colnames()
reverse_colnames = {v:k for k,v in colnames.items()} reverse_colnames = {v:k for k,v in colnames.items()}
def write_pattern_xlsx(name: str, fields: dict) -> str: def write_pattern_xlsx(name: str, fields: dict, data=None) -> str:
wb = Workbook() wb = Workbook()
ws_data = wb.active ws_data = wb.active
hidden = wb.create_sheet('dict') hidden = wb.create_sheet('dict')
@ -28,7 +28,7 @@ def write_pattern_xlsx(name: str, fields: dict) -> str:
headers = [] headers = []
c = 1 c = 1
opt_id = 0 opt_id = 0
for f in fields.values(): for name, f in fields.items():
if f.type == 'factor': if f.type == 'factor':
continue continue
ws_data.cell(row=1, column=c, value=f.label or f.name) ws_data.cell(row=1, column=c, value=f.label or f.name)
@ -38,12 +38,27 @@ def write_pattern_xlsx(name: str, fields: dict) -> str:
elif f.options: elif f.options:
create_options(ws_data, c, hidden, opt_id, f.options) create_options(ws_data, c, hidden, opt_id, f.options)
opt_id = opt_id + 1 opt_id = opt_id + 1
if data:
write(ws_data, 2, c, name, data)
c += 1 c += 1
fs = FileStorage() fs = FileStorage()
if data is None:
fp = fs._name2path(f'{name}_定价模版.xlsx') fp = fs._name2path(f'{name}_定价模版.xlsx')
else:
write_data(ws_data, fields, data)
fp = fs._name2path(f'{name}_定价.xlsx')
wb.save(fp) wb.save(fp)
return fp return fp
def write_data(sheet, start_row, col, fname, data):
r = start_row
for d in data:
v = d.get(fname)
if v:
sheet.cell(row=r, column=col, value=v)
r += 1
def create_options(ws, dcol, sheet, opt_id, options): def create_options(ws, dcol, sheet, opt_id, options):
r = 2 r = 2
vc = opt_id + 1 vc = opt_id + 1

View File

@ -0,0 +1,23 @@
pptid = params_kw.id
env = request._run_ns
orgid = await get_userorgid()
async with get_sor_context(env, 'pricing') as sor:
recs = await sor.R('pricing_program_timing', {'id': pptid})
if len(recs) == 0:
return UiError(title='下载定价信息', message=f'{pptid} 在pricing_program_timing中没找到')
ppt = recs[0]
recs = await sor.R('pricing_program', {'id': ppt.ppid})
if len(recs) == 0:
return UiError(title='下载定价信息', message=f'{ppt.ppid} 在pricing_program中没找到')
pp = recs[0]
if pp.ownerid != orgid:
return UiError(title='下载定价信息', message=f'{userorgid} != {pp.ownerid}非本机构定价')
data = json.loads(ppt.prcing_data)
fields = data.get('fields')
if fields is None:
return UiError(title='下载定价信息', message=f'{pptid} 定价字段数据为空')
pricing_data = data.get('pricings')
if pricing_data is None:
return UiError(title='下载定价信息', message=f'{pptid} 定价数据为空')
fpath = write_pattern_xlsx(name, fields, data=pricing_data)
return await file_response(request, fpath, download=True)

59
wwwroot/pricing_test.ui Normal file
View File

@ -0,0 +1,59 @@
{% set amount = test_pricing(params_kw.id, params_kw) %}
{% set ppt = get_pricing_program_timeing(params_kw.id) %}
{% if ppt %}
{
"widgettype": "Form",
"options": {
"width": "100%",
"height": "100%",
"fields": [
{% if amount is not None %}
{
"name": amoumt,
"label": "价格",
"value": {{amount}},
"uitype": "float"
},
{% endif %}
{% for f,spec in ppt.pricing_data.fields.items() %}
{
{% if params_kw.get(f) %}
"value": "{{params_kw.get(f)}}",
{% endif %}
"name": "{{f}},
"label": "{{spec.label}}",
"uitype": "{{spec.type}}"
}
{% if not loop.last %},{% endif %}
{% endfor %}
]
},
"binds":[
{
"wid": "self",
"event": "submit",
"actiontype": "urlwidget",
"target": "self",
"options": {
"params": {
"id": "{{params_kw.id}}"
},
"method": "POST",
"url": "{{entire_url('pricing_test.ui')}}"
}
}
]
}
{% else %}
{
"widgettype": "Text",
"options": {
"i18n": true,
"otext": "定价时序数据没找到",
"wrap": true,
"halign": "left",
"width": "100%",
"height": "100%"
}
}
{% endif %}