diff --git a/pricing/init.py b/pricing/init.py index 0270dac..3f59104 100644 --- a/pricing/init.py +++ b/pricing/init.py @@ -1,7 +1,13 @@ -from pricing.pricing import pricing_program_charging, get_pricing_specs_by_pptid +from pricing.pricing import ( + pricing_program_charging, + get_pricing_specs_by_pptid, + get_all_spec_fields_by_pptid, + get_spec_names_fields) from ahserver.serverenv import ServerEnv def load_pricing(): env = ServerEnv() env.pricing_program_charging = pricing_program_charging env.get_pricing_specs_by_pptid = get_pricing_specs_by_pptid + env.get_spec_names_fields = get_spec_names_fields + env.get_all_spec_fields_by_pptid = get_all_spec_fields_by_pptid diff --git a/pricing/pricing.py b/pricing/pricing.py index 6bda05e..4165f82 100644 --- a/pricing/pricing.py +++ b/pricing/pricing.py @@ -131,3 +131,54 @@ async def pricing_program_charging(sor, pricing_program_id, data): return charges +async def sor_get_spec_fields(sor, piid): + sql = "select a.spec_names from pricing_spec a, pricing_item b where a.id = b.psid and b.id = ${piid}$" + recs = await sor.sqlExe(sql, {'piid': piid}) + if len(recs) < 1: + return [] + b = recs[0].spec_names + if b is None: + return [] + return json.loads(b) + +async def get_spec_names_fields(request, piid): + async with get_sor_context(request._run_ns, 'pricing') as sor: + fields = await sor_get_spec_fields(sor, piid) + if len(fields) < 1: + return '' + x = '' + for f in fields: + x += ','+ json.dumps(f) + return x + return '' + +async def get_spec_names_fields_names(request, piid): + async with get_sor_context(request._run_ns, 'pricing') as sor: + fs = await sor_get_spec_fields(sor, piid) + return [f['name'] for f in fs] + +async def get_all_spec_fields_by_pptid(request, pptid): + env = request._run_ns + async with get_sor_context(env, 'pricing') as sor: + sql = """select a.* +from pricing_spec a, + pricing_type b, + pricing_program c, + pricing_program_timing d +where + b.id=a.ptid + and b.id = c.ptid + and c.id = d.ppid + and d.id = ${pptid}$""" + recs = await sor.sqlExe(sql, {'pptid': pptid}) + ret = '' + for r in recs: + if r.spec_names: + x = { + "name":r.id, + "uitype":"group", + "nouse": True + } + x['fields'] = json.loads(r.spec_names) + ret += ','+ json.dumps(x, ensure_ascii=False, indent=4) + return ret diff --git a/wwwroot/pricing_item/add_pricing_item.dspy b/wwwroot/pricing_item/add_pricing_item.dspy new file mode 100644 index 0000000..0a0df04 --- /dev/null +++ b/wwwroot/pricing_item/add_pricing_item.dspy @@ -0,0 +1,40 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None +id = params_kw.id +if not id or len(id) > 32: + id = uuid() +ns['id'] = id + +db = DBPools() +dbname = get_module_dbname('pricing') +async with db.sqlorContext(dbname) as sor: + fs = await sor_get_spec_fields(sor, ns.id) + if len(fs): + ns1 = {k:ns[k] for k in fs} + ns.spec_value = json.dumps(ns1) + r = await sor.C('pricing_item', ns.copy()) + return { + "widgettype":"Message", + "options":{ + "user_data":ns, + "cwidth":16, + "cheight":9, + "title":"Add Success", + "timeout":3, + "message":"ok" + } + } + +return { + "widgettype":"Error", + "options":{ + "title":"Add Error", + "cwidth":16, + "cheight":9, + "timeout":3, + "message":"failed" + } +} diff --git a/wwwroot/pricing_item/delete_pricing_item.dspy b/wwwroot/pricing_item/delete_pricing_item.dspy new file mode 100644 index 0000000..063cc4e --- /dev/null +++ b/wwwroot/pricing_item/delete_pricing_item.dspy @@ -0,0 +1,33 @@ + +ns = { + 'id':params_kw['id'], +} + + +db = DBPools() +dbname = get_module_dbname('pricing') +async with db.sqlorContext(dbname) as sor: + r = await sor.D('pricing_item', ns) + debug('delete success'); + return { + "widgettype":"Message", + "options":{ + "title":"Delete Success", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"ok" + } + } + +debug('Delete failed'); +return { + "widgettype":"Error", + "options":{ + "title":"Delete Error", + "timeout":3, + "cwidth":16, + "cheight":9, + "message":"failed" + } +} \ No newline at end of file diff --git a/wwwroot/pricing_item/get_pricing_item.dspy b/wwwroot/pricing_item/get_pricing_item.dspy new file mode 100644 index 0000000..8471e1b --- /dev/null +++ b/wwwroot/pricing_item/get_pricing_item.dspy @@ -0,0 +1,118 @@ + +ns = params_kw.copy() + + +debug(f'get_pricing_item.dspy:{ns=}') +if not ns.get('page'): + ns['page'] = 1 +if not ns.get('sort'): + + + ns['sort'] = 'name' + + + +sql = '''select a.*, b.pptid_text, c.psid_text, d.subppid_text +from (select * from pricing_item where 1=1 [[filterstr]]) a left join (select id as pptid, + id as pptid_text from pricing_program_timing where 1 = 1) b on a.pptid = b.pptid left join (select id as psid, + name as psid_text from pricing_spec where 1 = 1) c on a.psid = c.psid left join (select id as subppid, + name as subppid_text from pricing_program where 1 = 1) d on a.subppid = d.subppid''' + +filterjson = params_kw.get('data_filter') +if not filterjson: + fields = [ f['name'] for f in [ + { + "name": "id", + "title": "id", + "type": "str", + "length": 32 + }, + { + "name": "name", + "title": "定价项名", + "type": "str", + "length": 256 + }, + { + "name": "description", + "title": "描述", + "type": "text" + }, + { + "name": "pptid", + "title": "项目id", + "type": "str", + "length": 32 + }, + { + "name": "psid", + "title": "定价规格id", + "type": "str", + "length": 32 + }, + { + "name": "subppid", + "title": "子项目id", + "type": "str", + "length": 32, + "nullable": "yes" + }, + { + "name": "spec_value", + "title": "规格值", + "type": "text" + }, + { + "name": "pricing_unit", + "title": "定价单位", + "type": "float", + "length": 18, + "dec": 5 + }, + { + "name": "pricing_amount", + "title": "定价金额", + "type": "float", + "length": 18, + "dec": 5 + }, + { + "name": "cost_amount", + "title": "成本金额", + "type": "float", + "length": 18, + "dec": 5 + } +] ] + filterjson = default_filterjson(fields, ns) +filterdic = ns.copy() +filterdic['filterstr'] = '' +filterdic['userorgid'] = '${userorgid}$' +filterdic['userid'] = '${userid}$' +if filterjson: + dbf = DBFilter(filterjson) + conds = dbf.gen(ns) + if conds: + ns.update(dbf.consts) + conds = f' and {conds}' + filterdic['filterstr'] = conds +ac = ArgsConvert('[[', ']]') +vars = ac.findAllVariables(sql) +NameSpace = {v:'${' + v + '}$' for v in vars if v != 'filterstr' } +filterdic.update(NameSpace) +sql = ac.convert(sql, filterdic) + +debug(f'{sql=}') +db = DBPools() +dbname = get_module_dbname('pricing') +async with db.sqlorContext(dbname) as sor: + r = await sor.sqlPaging(sql, ns) + for d in r['rows']: + if d.spec_value: + ad = json.loads(d.spec_value) + d.update(ad) + return r +return { + "total":0, + "rows":[] +} diff --git a/wwwroot/pricing_item/index.ui b/wwwroot/pricing_item/index.ui new file mode 100644 index 0000000..240c809 --- /dev/null +++ b/wwwroot/pricing_item/index.ui @@ -0,0 +1,189 @@ +{ + "id":"pricing_item_tbl", + "widgettype":"Tabular", + "options":{ + "width":"100%", + "height":"100%", + + + "title":"项目定价项", + + + + + "css":"card", + + + "editable":{ + + "new_data_url":"{{entire_url('add_pricing_item.dspy')}}", + + + "delete_data_url":"{{entire_url('delete_pricing_item.dspy')}}", + + + "update_data_url":"{{entire_url('update_pricing_item.dspy')}}" + + }, + + + "data_url":"{{entire_url('./get_pricing_item.dspy')}}", + + "data_method":"GET", + "data_params":{{json.dumps(params_kw, indent=4, ensure_ascii=False)}}, + "row_options":{ + "browserfields": { + "exclouded": [ + "id", + "pptid" + ], + "alters": { + "psid": { + "dataurl": "{{entire_url('../pi_get_all_specs.dspy')}}", + "textField": "name", + "valueField": "id", + "params": { + "pptid": "{{params_kw.pptid}}" + } + } + } +}, + "editexclouded":[ + "id", + "pptid" +], + + "fields":[ + { + "name": "id", + "title": "id", + "type": "str", + "length": 32, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "id" + }, + { + "name": "name", + "title": "定价项名", + "type": "str", + "length": 256, + "cwidth": 18, + "uitype": "str", + "datatype": "str", + "label": "定价项名" + }, + { + "name": "description", + "title": "描述", + "type": "text", + "length": 0, + "uitype": "text", + "datatype": "text", + "label": "描述" + }, + { + "name": "pptid", + "title": "项目id", + "type": "str", + "length": 32, + "label": "项目id", + "uitype": "code", + "valueField": "pptid", + "textField": "pptid_text", + "params": { + "dbname": "{{get_module_dbname('pricing')}}", + "table": "pricing_program_timing", + "tblvalue": "id", + "tbltext": "id", + "valueField": "pptid", + "textField": "pptid_text" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "psid", + "title": "定价规格id", + "type": "str", + "length": 32, + "label": "定价规格id", + "uitype": "code", + "valueField": "id", + "textField": "name", + "params": { + "pptid": "{{params_kw.pptid}}" + }, + "dataurl": "{{entire_url('../pi_get_all_specs.dspy')}}" + }, + { + "name": "subppid", + "title": "子项目id", + "type": "str", + "length": 32, + "nullable": "yes", + "label": "子项目id", + "uitype": "code", + "valueField": "subppid", + "textField": "subppid_text", + "params": { + "dbname": "{{get_module_dbname('pricing')}}", + "table": "pricing_program", + "tblvalue": "id", + "tbltext": "name", + "valueField": "subppid", + "textField": "subppid_text" + }, + "dataurl": "{{entire_url('/appbase/get_code.dspy')}}" + }, + { + "name": "pricing_unit", + "title": "定价单位", + "type": "float", + "length": 18, + "dec": 5, + "cwidth": 18, + "uitype": "float", + "datatype": "float", + "label": "定价单位" + }, + { + "name": "pricing_amount", + "title": "定价金额", + "type": "float", + "length": 18, + "dec": 5, + "cwidth": 18, + "uitype": "float", + "datatype": "float", + "label": "定价金额" + }, + { + "name": "cost_amount", + "title": "成本金额", + "type": "float", + "length": 18, + "dec": 5, + "cwidth": 18, + "uitype": "float", + "datatype": "float", + "label": "成本金额" + } + {{get_all_spec_fields_by_pptid(request, params_kw.pptid)}} +] + }, + "page_rows":160, + "cache_limit":5 + } + + ,"binds":[ + { + "wid":"psid", + "event":"changed", + "actiontype":"script", + "target":"self", + "script":"this.hide_field(params.psid);" + } + ] + +} diff --git a/wwwroot/pricing_item/update_pricing_item.dspy b/wwwroot/pricing_item/update_pricing_item.dspy new file mode 100644 index 0000000..a9d5c41 --- /dev/null +++ b/wwwroot/pricing_item/update_pricing_item.dspy @@ -0,0 +1,36 @@ + +ns = params_kw.copy() +for k,v in ns.items(): + if v == 'NaN' or v == 'null': + ns[k] = None + + + + +db = DBPools() +dbname = get_module_dbname('pricing') +async with db.sqlorContext(dbname) as sor: + + r = await sor.U('pricing_item', ns) + debug('update success'); + return { + "widgettype":"Message", + "options":{ + "title":"Update Success", + "cwidth":16, + "cheight":9, + "timeout":3, + "message":"ok" + } + } + +return { + "widgettype":"Error", + "options":{ + "title":"Update Error", + "cwidth":16, + "cheight":9, + "timeout":3, + "message":"failed" + } +} \ No newline at end of file