付款申请单
一、背景
客户已经做了预付款。然后走【采购发票】-【应付事项】流程
【应付事项】下推财务【付款】时,增加审批流流程:【付款申请单】。
【付款申请单】审批通过后进入财务【付款】单
通过此案例我们来学习开发技术,业务逻辑并不完善,请注意
二、能力清单
编号 |
能力清单 |
1 |
开放平台接口调用 |
2 |
页面设计器常用操作 |
3 |
自定义模态框 |
4 |
无强关联数据页面显示 |
5 |
常用函数使用 |
三、业务流程

四、操作流程

五、数据建模
5.1、应付事项实体
操作 |
描述 |
|
|
|
|
|
名称 |
应付事项 |
|
|
|
|
|
编码 |
fioap |
|
|
|
|
|
父实体 |
|
|
|
|
|
|
引用接口 |
|
|
|
|
|
|
|
属性 |
编码 |
名称 |
类型 |
引用 |
|
|
|
currency_moneyDigit |
原币币种精度 |
数值 |
|
|
|
|
currency_priceDigit |
原币价格精度 |
数值 |
|
|
|
|
code |
单据编号 |
文本 |
|
|
|
|
billdirection |
单据方向 |
文本 |
|
|
|
|
oriTax |
原币税额 |
文本 |
|
|
|
|
provisionalestimateflag |
是否暂估 |
文本 |
|
|
|
|
exchRate |
汇率 |
文本 |
|
|
|
|
accentity_name |
会计主体 |
文本 |
|
|
|
|
taxsubject |
税目 |
文本 |
|
|
|
|
deatil_supplier_name |
表体供应商 |
文本 |
|
|
|
|
vouchdate |
单据日期 |
文本 |
|
|
|
|
natCurrency_name |
本币币种名称 |
文本 |
|
|
|
|
billtype |
应付事项类型 |
文本 |
|
|
|
|
balance |
余额 |
文本 |
|
|
|
|
period_code |
会计期间 |
文本 |
|
|
|
|
supplier_name |
供应商名称 |
文本 |
|
|
|
|
exchangeRateType_digit |
汇率精度 |
文本 |
|
|
|
|
auditstatus |
审批状态 |
文本 |
|
|
|
|
currency_name |
币种名称 |
文本 |
|
|
|
|
oriSum |
金额 |
文本 |
|
|
|
|
tradetype_name |
交易类型名称 |
文本 |
|
|
|
|
localbalance |
本币余额 |
文本 |
|
|
|
|
natSum |
本币含税金额 |
文本 |
|
|
|
|
natCurrency_moneyDigit |
本币币种金额精度 |
文本 |
|
|
|
|
natCurrency_priceDigit |
本币币种单价精度 |
文本 |
|
|
|
|
exchangeRateType_name |
汇率类型名称 |
文本 |
|
|
|
|
accountdate |
立账日期 |
文本 |
|
|
|
|
oriMoney |
原币金额 |
文本 |
|
|
|
|
natMoney |
本币金额 |
文本 |
|
|
|
|
basebilltype_name |
事项类型名称 |
文本 |
|
|
5.2、付款申请实体
操作 |
描述 |
|
|
|
|
|
名称 |
付款申请 |
|
|
|
|
|
编码 |
payment |
|
|
|
|
|
父实体 |
|
|
|
|
|
|
引用接口 |
审批 |
自动编码 |
交易类型 |
|
|
|
|
属性 |
编码 |
名称 |
类型 |
引用 |
|
|
|
vouchdate |
单据日期 |
日期 |
|
|
|
|
accentity |
会计主体 |
单选引用 |
会计主体 |
bd.adminOrg.FinanceOrgVO |
|
|
oriSum |
付款金额 |
数值 |
|
|
|
|
natSum |
本币金额 |
数值 |
|
|
|
|
balance |
余额 |
数值 |
|
|
|
|
supplier |
供应商 |
单选引用 |
供应商 |
aa.vendor.Vendor |
|
|
supplierbankname |
收款银行 |
文本 |
|
|
|
|
supplierbankaccount_accountname |
收款银行账户 |
文本 |
|
|
|
|
period |
会计期间 |
单选引用 |
会计期间 |
bd.period.Period |
|
|
settlemode |
结算方式 |
单选引用 |
结算方式 |
aa.settlemethod.SettleMethod |
|
|
currency |
币种 |
单选引用 |
币种 |
bd.currencytenant.CurrencyTenantVO |
|
|
currency_priceDigit |
币种单价精度 |
数值 |
|
|
|
|
currency_moneyDigit |
币种金额精度 |
数值 |
|
|
|
|
natCurrency |
本币币种 |
单选引用 |
币种 |
bd.currencytenant.CurrencyTenantVO |
|
|
natCurrency_priceDigit |
本币币种单价精度 |
数值 |
|
|
|
|
natCurrency_moneyDigit |
本币币种金额精度 |
数值 |
|
|
|
|
exchRate |
汇率 |
数值 |
|
|
|
|
dept |
部门 |
单选引用 |
部门 |
bd.adminOrg.AdminOrgVO |
|
|
operator |
业务员 |
单选引用 |
员工 |
bd.staff.StaffNew |
|
|
exchangeRateType_digit |
汇率类型金额精度 |
数值 |
|
|
|
|
exchangeRateType |
汇率类型 |
单选引用 |
汇率类型 |
bd.exchangeRate.ExchangeRateTypeVO |
|
|
project |
项目 |
单选引用 |
项目 |
bd.project.ProjectVO |
|
|
enterprisebankaccount |
付款银行账户id |
单选引用 |
企业银行账户 |
bd.enterprise.OrgFinBankacctVO |
|
|
description |
备注 |
文本 |
|
|
|
|
noteno |
票据号 |
文本 |
|
|
|
|
org |
采购组织 |
单选引用 |
采购组织 |
bd.adminOrg.PurchaseOrgVO |
|
|
cashaccount |
付款现金账户 |
单选引用 |
企业现金账户 |
bd.enterprise.OrgFinCashacctVO |
|
|
isSync |
是否同步 |
单选 |
是否同步 |
|
|
|
orderno |
订单编号 |
文本 |
|
|
|
|
sourcebillnum |
原单金额 |
数值 |
|
|
5.3、付款申请支付明细实体
操作 |
描述 |
|
|
|
|
|
名称 |
付款申请支付明细 |
|
|
|
|
|
编码 |
paybillbapply |
|
|
|
|
|
父实体 |
付款申请 |
|
|
|
|
|
引用接口 |
|
|
|
|
|
|
|
属性 |
编码 |
名称 |
类型 |
引用 |
|
|
|
expenseitem |
费用项目 |
单选引用 |
费用项目 |
bd.expenseitem.ExpenseItem |
|
|
oriSum |
金额 |
数值 |
|
|
|
natSum |
本币金额 |
数值 |
|
|
|
customer_code |
客户编码 |
文本 |
|
|
|
customer |
客户 |
单选引用 |
客户档案 |
aa.merchant.Merchant |
|
|
supplier |
供应商 |
单选引用 |
供应商 |
aa.vendor.Vendor |
|
|
employee |
员工 |
单选引用 |
员工 |
bd.staff.StaffNew |
|
|
dept |
部门 |
单选引用 |
部门 |
bd.adminOrg.AdminOrgVO |
|
|
project |
项目 |
单选引用 |
项目 |
bd.project.ProjectVO |
|
|
orderno |
订单编号 |
文本 |
|
|
|
description |
备注 |
文本 |
|
|
|
product |
物料 |
单选引用 |
物料 |
pc.product.Product |
|
|
quickType_code |
款项类型 |
单选 |
款项类型 |
|
5.4、预付款申请实体
- 可通过复制【预付款申请】实体快速实现
- 该实体仅用来构建页面,不存储业务数据
操作 |
描述 |
|
|
|
|
|
名称 |
预付款申请ch |
|
|
|
|
|
编码 |
prepaymentch |
|
|
|
|
|
父实体 |
付款申请 |
|
|
|
|
|
引用接口 |
|
|
|
|
|
|
|
属性 |
编码 |
名称 |
类型 |
引用 |
|
|
|
vouchdate |
单据日期 |
日期 |
|
|
|
|
accentity |
会计主体 |
单选引用 |
会计主体 |
bd.adminOrg.FinanceOrgVO |
|
|
oriSum |
付款金额 |
数值 |
|
|
|
|
natSum |
本币金额 |
数值 |
|
|
|
|
balance |
余额 |
数值 |
|
|
|
|
supplier |
供应商 |
单选引用 |
供应商 |
aa.vendor.Vendor |
|
|
supplierbankname |
收款银行 |
文本 |
|
|
|
|
supplierbankaccount_accountname |
收款银行账户 |
文本 |
|
|
|
|
period |
会计期间 |
单选引用 |
会计期间 |
bd.period.Period |
|
|
settlemode |
结算方式 |
单选引用 |
结算方式 |
aa.settlemethod.SettleMethod |
|
|
currency |
币种 |
单选引用 |
币种 |
bd.currencytenant.CurrencyTenantVO |
|
|
currency_priceDigit |
币种单价精度 |
数值 |
|
|
|
|
currency_moneyDigit |
币种金额精度 |
数值 |
|
|
|
|
natCurrency |
本币币种 |
单选引用 |
币种 |
bd.currencytenant.CurrencyTenantVO |
|
|
natCurrency_priceDigit |
本币币种单价精度 |
数值 |
|
|
|
|
natCurrency_moneyDigit |
本币币种金额精度 |
数值 |
|
|
|
|
exchRate |
汇率 |
数值 |
|
|
|
|
dept |
部门 |
单选引用 |
部门 |
bd.adminOrg.AdminOrgVO |
|
|
operator |
业务员 |
单选引用 |
员工 |
bd.staff.StaffNew |
|
|
exchangeRateType_digit |
汇率类型金额精度 |
数值 |
|
|
|
|
exchangeRateType |
汇率类型 |
单选引用 |
汇率类型 |
bd.exchangeRate.ExchangeRateTypeVO |
|
|
project |
项目 |
单选引用 |
项目 |
bd.project.ProjectVO |
|
|
enterprisebankaccount |
付款银行账户id |
单选引用 |
企业银行账户 |
bd.enterprise.OrgFinBankacctVO |
|
|
description |
备注 |
文本 |
|
|
|
|
noteno |
票据号 |
文本 |
|
|
|
|
org |
采购组织 |
单选引用 |
采购组织 |
bd.adminOrg.PurchaseOrgVO |
|
|
cashaccount |
付款现金账户 |
单选引用 |
企业现金账户 |
bd.enterprise.OrgFinCashacctVO |
|
|
isSync |
是否同步 |
单选 |
是否同步 |
|
|
|
orderno |
订单编号 |
文本 |
|
|
|
|
sourcebillnum |
原单金额 |
数值 |
|
|
六、页面建模
6.1、【付款申请】一主多子页面


6.2、应付事项单表弹框


- 调整页面布局
- 删除系统预制的按钮栏,工具栏
- 新增底部栏,添加两个按钮,实现如下布局


function (event) {
var viewModel = this;
viewModel.communication({type:'modal',payload:{data:false}});
}


let AbstractAPIHandler = require('AbstractAPIHandler');
class MyAPIHandler extends AbstractAPIHandler {
execute(request){
let func1 = extrequire("GT10894AT82.common.getOpenApiToken");
let res = func1.execute(request);
let configfun = extrequire("GT10894AT82.common.config");
let config = configfun.execute(request);
var token = res.access_token;
var deptId = request;
var requrl = config.config.sandboxopenapiurl+"/yonbip/fi/oap/list?access_token="+token;
var header = {'Content-Type':"application/json;charset=UTF-8"};
var apiData = {
"pageIndex":1,
"pageSize":20
}
var queryQ = request.queryCondition;
for(let i in queryQ){
apiData[queryQ[i].itemName] = queryQ[i].value1;
}
var strResponse = postman("POST", requrl,JSON.stringify(header),JSON.stringify(apiData));
var responseObj = JSON.parse(strResponse);
return {responseObj};
}
}
exports({"entryPoint":MyAPIHandler});
- 绑定页面初始化函数,并配置以下函数
- 函数主要功能调用应付事项API函数

function (event) {
var viewModel = this;
viewModel.getParams().autoLoad = false;
var gridModel = viewModel.getGridModel();
gridModel.setState("showCheckBox",false);
var queryCondition;
viewModel.on("beforeSearch",function(params){
queryCondition = params.params.condition.commonVOs;
})
viewModel.on("afterSearch",function(params){
cb.rest.invokeFunction("GT10894AT82.fioap.fiaoplist", {'queryCondition':queryCondition},
function(err, res) {
if(err!=null){
cb.utils.alert(err,"error");
}else{
console.log(res);
var resP = res.responseObj.data.recordList;
for(let i in resP){
if(resP[i].id!=undefined)
gridModel.appendRow(resP[i]);
}
}
})
})
}
let AbstractAPIHandler = require('AbstractAPIHandler');
class MyAPIHandler extends AbstractAPIHandler {
execute(request){
let func1 = extrequire("GT12951AT32.config.getApiAccessToken");
let res = func1.execute(request);
let configfun = extrequire("GT12951AT32.config.baseConfig");
let config = configfun.execute(request);
var token = res.access_token;
var id = request;
var requrl = config.config.baseUrl+"/yonbip/fi/oap/detail?access_token="+token+"&id="+id;
var header = {'Content-Type':"application/json;charset=UTF-8"};
var strResponse = postman("GET", requrl,JSON.stringify(header));
var responseObj = JSON.parse(strResponse);
return {responseObj};
}
}
exports({"entryPoint":MyAPIHandler});

let AbstractAPIHandler = require('AbstractAPIHandler');
class MyAPIHandler extends AbstractAPIHandler {
execute(request){
var id = request.id;
var code = request.code;
var isCodeExist = ObjectStore.queryByYonQL('select code, id from GT12951AT32.GT12951AT32.paymentnishch where dr=0 and orderno="'+code+'"');
if(isCodeExist.length>0){
throw new Error("该单据已经生成付款申请单");
}
let func1 = extrequire("GT12951AT32.fiaoplist.fioapdetail");
let fiaopD = func1.execute(id);
var insertData = fiaopD.responseObj.data;
insertData.paybillbnishch2List = insertData.oapDetail;
var orderno = insertData.paybillbnishch2List[0].orderno;
insertData.sourcebillnum = insertData.oriSum;
var chSum = ObjectStore.queryByYonQL('select oriSum, id,isSync from GT12951AT32.GT12951AT32.prepaymentnishch where dr=0 and orderno="'+orderno+'"');
if(chSum.length>0){
for(let j in chSum){
if(chSum[j].isSync=="2"){
throw new Error("当前未同步付款的预付款申请流程");
}
insertData.oriSum = insertData.oriSum-chSum[j].oriSum;
}
}
insertData.paybillbnishch2List[0].quickType_code = "6";
insertData.paybillbnishch2List[0].oriSum = insertData.oriSum;
insertData.paybillbnishch2List[0].natSum = insertData.oriSum;
insertData.paybillbnishch2List[0].product = insertData.paybillbnishch2List[0].material;
insertData.natSum = insertData.oriSum;
insertData.balance = insertData.oriSum;
insertData.sourcebillcode = insertData.code;
insertData.bustype = "2281177064296712";
delete insertData.code;
delete insertData.oapDetail;
var res = ObjectStore.insert("GT12951AT32.GT12951AT32.paymentnishch2",insertData,"294cbb05");
return {res};
}
}
exports({"entryPoint":MyAPIHandler});

function (event) {
var viewModel = this;
var gridModel = viewModel.getGridModel();
var rows = gridModel.getSelectedRows();
if(rows.length==0)return cb.utils.alert("请选择数据","alert");
cb.rest.invokeFunction("GT10894AT82.fioap.insertPayMentApply", {id:rows[0].id,code:rows[0].code},
function(err, res) {
if(err!=null){
cb.utils.alert(err.message);
}else{
var parentViewModel = viewModel.getCache('parentViewModel');
parentViewModel.execute("refresh");
viewModel.communication({type:'modal',payload:{data:false}});
}
})
}
6.3、付款申请列表新增【应付事项】按钮打开【应付事项弹框】
- 进入列表页面设计器新增一个按钮,修改多语标题为【应付事项】
- 页面布局可根据情况调整,不影响功能效果

- 应付事项按钮绑定点击事件,功能:打开【应付事项弹框】

function (event) {
var viewModel = this;
let data = {
billtype: 'VoucherList',
billno: '9b372483',
params: {
mode: 'browse',
}
};
cb.loader.runCommandLine('bill', data, viewModel);
}
6.4、【付款申请列表】功能测试



6.5、【付款申请】卡片页面设计器内容调整


- 设置原单金额、是否同步不允许修改,其它根据情况调整,不影响功能效果

6.6、【付款申请】卡片联查预付款


let AbstractAPIHandler = require('AbstractAPIHandler');
class MyAPIHandler extends AbstractAPIHandler {
execute(request){
var orderno = request.orderno;
var sql = "select distinct vouchdate ,accentity ,accentity.name, oriSum, natSum, balance, supplier, supplierbankname, supplierbankaccount_accountname,"+
" period,settlemode,currency,currency_priceDigit,currency_moneyDigit,natCurrency,code "+
"from GT12951AT32.GT12951AT32.prepaymentnishch where orderno = '"+orderno+"'";
var res = ObjectStore.queryByYonQL(sql);
return {res};
}
}
exports({"entryPoint":MyAPIHandler});

function (event) {
var viewModel = this;
viewModel.on("afterLoadData",function(){
getPrePay();
})
function getPrePay(){
var gridModel = viewModel.get("paybillbapply0526List");
var gridModelPre = viewModel.get("prepaymentchList");
if(gridModelPre.getRows().length>0){
return true;
}
var orderno = viewModel.get('orderno').getValue();
cb.rest.invokeFunction("GT10894AT82.prepayment.getInfoByOrderNo", {orderno:orderno},
function(err, res) {
if(err!=null){
cb.utils.alert(JSON.stringify(err));
}else{
var data = res.res
for(let i in data){
if(data[i].id!=undefined)
preGridModel.appendRow(data[i]);
}
}
})
}
}
6.7、【付款申请】卡片,付款功能实现

let AbstractAPIHandler = require('AbstractAPIHandler');
class MyAPIHandler extends AbstractAPIHandler {
execute(request){
var reqBodyData = request.reqBody;
var uri = request.uri;
let tokenFun = extrequire("GT12951AT32.config.getApiAccessToken");
let tokenRes = tokenFun.execute(request);
var access_token = tokenRes.access_token;
let configFun = extrequire("GT12951AT32.config.baseConfig");
let configRes = configFun.execute(request);
var baseUrl = configRes.config.baseUrl;
var useUrl = baseUrl+uri+"?access_token="+access_token;
var header = {'Content-Type':"application/json;charset=UTF-8"};
var strResponse = postman("POST", useUrl,JSON.stringify(header),JSON.stringify(reqBodyData));
var responseObj = JSON.parse(strResponse);
return {responseObj};
}
}
exports({"entryPoint":MyAPIHandler});

let AbstractAPIHandler = require('AbstractAPIHandler');
class MyAPIHandler extends AbstractAPIHandler {
execute(request){
var main = request.params.billData;
main._status = "Insert";
var ch = request.params.billData.paybillbapply0526List;
for(let i in ch){
ch[i]._status = "Insert";
}
main.PayBillb = ch;
delete main.paybillbapply0526List;
var apiData = {"data":[main]};
let func1 = extrequire("GT10894AT82.common.getOpenApiToken");
let res = func1.execute(request);
let configfun = extrequire("GT10894AT82.common.config");
let config = configfun.execute(request);
var token = res.access_token;
var deptId = request;
var requrl = config.config.sandboxopenapiurl+"/yonbip/fi/payment/save?access_token="+token;
var header = {'Content-Type':"application/json;charset=UTF-8"};
var strResponse = postman("POST", requrl,JSON.stringify(header),JSON.stringify(apiData));
var responseObj = JSON.parse(strResponse);
if(responseObj.data.failCount==0){
var object = {id:main.id,isSync:"1"};
ObjectStore.updateById("GT10894AT82.GT10894AT82.paymentapply0526",object,"b1c1b909");
}
return {responseObj};
}
}
exports({"entryPoint":MyAPIHandler});
- 付款申请卡片增加付款按钮,绑定前端函数点击事件,调用付款保存api函数

let AbstractAPIHandler = require('AbstractAPIHandler');
class MyAPIHandler extends AbstractAPIHandler {
execute(request){
request.uri = "/yonbip/fi/payment/save";
var reqBody = request.params.billData;
reqBody._status = "Insert";
reqBody.tradetype = reqBody.bustype;
var ch = reqBody.paybillbnishch2List;
for(let i in ch){
ch[i]._status = "Insert";
}
reqBody.PayBillb = ch;
delete reqBody.paybillbnishch2List;
request.reqBody = {"data":[reqBody]};
let apiUtilFunc = extrequire("GT12951AT32.config.openApiUtils");
let apiUtilRes = apiUtilFunc.execute(request);
if(apiUtilRes.responseObj.data.failCount==0){
var object = {id:reqBody.id,isSync:"1"};
var res = ObjectStore.updateById("GT12951AT32.GT12951AT32.paymentnishch2",object,"294cbb05");
}
return {responseObj:apiUtilRes.responseObj};
}
}
exports({"entryPoint":MyAPIHandler});
七、配置审批流

八、付款测试




- 查看付款单,款项类型为:应付款
- 可根据情况,付款保存函数字段对应情况,此处仅实现流程并未完全对应
