用友uap nc65开发-单据联查相关开发

来源:互联网 发布:进入大数据时代 编辑:程序博客网 时间:2024/05/17 03:03
用友uap nc65开发-单据联查相关开发
1.单据联查:针对有上下游数据单据,通过单据联查使用图形化界面显示该单据上下游。本教程分两部分,上游和下游。
2.前期配置:xml配置对应的按钮,这里指定当前节点的单据类型,id,编码。
<!--======= 动作:[newActions] [联查单据] ===========--><bean id="linkQueryAction" class="nc.ui.pr.pub.linkquery.LinkQueryAction"><property name="model"><ref bean="bmModel"/></property><property name="billtype" value="H351"/><property name="billid" value="pk_head"/><property name="billcode" value="vbillno"/><property name="exceptionHandler"><ref bean="exceptionHandler" /></property></bean>
LinkQueryAction支持类如下:
package nc.ui.pr.pub.linkquery;import java.awt.event.ActionEvent;import java.awt.event.InputEvent;import java.awt.event.KeyEvent;import javax.swing.Action;import javax.swing.KeyStroke;import nc.md.data.access.NCObject;import nc.ui.ml.NCLangRes;import nc.ui.pubapp.billgraph.RowLinkQueryUtil;import nc.ui.trade.billgraph.billflow.control.DefaultBillGraphListener;import nc.ui.trade.billgraph.billflow.control.IBillGraphListener;import nc.ui.trade.billgraph.billflow.view.BillLinkFlowDlg;import nc.ui.trade.billgraph.billflow.view.SourceBillFlowDlg;import nc.ui.uif2.NCAction;import nc.ui.uif2.ShowStatusBarMsgUtil;import nc.ui.uif2.UIState;import nc.ui.uif2.editor.BillForm;import nc.ui.uif2.editor.BillListView;import nc.ui.uif2.model.AbstractUIAppModel;import nc.uif2.annoations.MethodType;import nc.uif2.annoations.ModelMethod;import nc.uif2.annoations.ModelType;import nc.vo.uap.busibean.exception.BusiBeanException;/** * 单据联查Action *  * @author zenglong *  */public class LinkQueryAction extends NCAction {private static final long serialVersionUID = -604785789980468531L;private static final String BILL_FINDER_CLASSNAME = "nc.vo.pr.pub.linkquery.BillTypeSetBillFinder";private String billType;private BillForm editor;private BillListView view;private String rowNoKey;private AbstractUIAppModel model;private IBillGraphListener billGraphListener = null;private SourceBillFlowDlg sourceBillFlowDlg = null;private String billtype;private String billid;private String billcode;public LinkQueryAction() {this.setCode("BillLinkQuery");// 增加默认监听this.billGraphListener = new DefaultBillGraphListener();this.setBtnName();}@Overridepublic void doAction(ActionEvent e) throws Exception {initUI();Object selectedData = LinkQueryAction.this.getModel().getSelectedData();NCObject ncObject = NCObject.newInstance(selectedData);if(ncObject.getAttributeValue(billid)==null){throw new BusiBeanException(billid+"指定的不对,请检查");}if(ncObject.getAttributeValue(billcode)==null){throw new BusiBeanException(billcode+"指定的不对,请检查");}// 设置参数this.sourceBillFlowDlg.setBillType(billtype);this.sourceBillFlowDlg.setBillID(ncObject.getAttributeValue(billid).toString());this.sourceBillFlowDlg.setBillNO(ncObject.getAttributeValue(billcode).toString());this.sourceBillFlowDlg.setNodeCode(getModel().getContext().getNodeCode());// 设置监听器this.sourceBillFlowDlg.setBillGraphListener(this.billGraphListener);// 打开对话框if (this.sourceBillFlowDlg.showModal() == -1) {ShowStatusBarMsgUtil.showStatusBarMsg(NCLangRes.getInstance().getStrByID("uif2","SourceBillFlowDlg-0006")/* 未找到单据联查信息! */, this.getModel().getContext());}}protected void initUI() {if (this.sourceBillFlowDlg == null) {// 初始化对话框if (Thread.currentThread().getContextClassLoader() == null)Thread.currentThread().setContextClassLoader(LinkQueryAction.class.getClassLoader());this.sourceBillFlowDlg = new BillLinkFlowDlg(this.model.getContext().getEntranceUI());this.sourceBillFlowDlg.setBillFinderClassname(LinkQueryAction.BILL_FINDER_CLASSNAME);}}public SourceBillFlowDlg getSourceBillFlowDlg() {return sourceBillFlowDlg;}public String getBillType() {return this.billType;}@ModelMethod(modelType = ModelType.AbstractAppModel, methodType = MethodType.GETTER)public AbstractUIAppModel getModel() {return this.model;}public void setBillType(String billType) {this.billType = billType;}@ModelMethod(modelType = ModelType.AbstractAppModel, methodType = MethodType.SETTER)public void setModel(AbstractUIAppModel model) {this.model = model;model.addAppEventListener(this);}public void setOpenMode(int openMode) {// 设置是否权限模式if (this.billGraphListener != null&& this.billGraphListener instanceof DefaultBillGraphListener) {((DefaultBillGraphListener) this.billGraphListener).setOpenMode(openMode);}this.setBtnName();}public int getOpenMode() {if (this.billGraphListener != null&& this.billGraphListener instanceof DefaultBillGraphListener) {return ((DefaultBillGraphListener) this.billGraphListener).getOpenMode();} else {return -1;}}public void setBillGraphListeners(final IBillGraphListener listener) {this.billGraphListener = listener;}public String getRowNoKey() {if (rowNoKey == null) {rowNoKey = RowLinkQueryUtil.getRowNoKey(getEditor());}return rowNoKey;}public void setRowNoKey(String rowNoKey) {this.rowNoKey = rowNoKey;}public BillForm getEditor() {return editor;}public void setEditor(BillForm editor) {this.editor = editor;this.editor.addHeadMouseClicked(this);}public BillListView getView() {return view;}protected void setBtnName() {// 根据权限判断走哪种模式,单据联查还是单据追溯if (getOpenMode() == 1) {this.setBtnName(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("pubapp_0", "0pubapp-0361")/* @res "单据追溯" */);this.putValue(Action.SHORT_DESCRIPTION, nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("pubapp_0", "0pubapp-0363")/* */);this.putValue(Action.ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));} else {this.setBtnName(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("pubapp_0", "0pubapp-0130")/* @res "联查单据" */);this.putValue(Action.SHORT_DESCRIPTION, nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("pubapp_0", "0pubapp-0131")/* */);this.putValue(Action.ACCELERATOR_KEY,KeyStroke.getKeyStroke(KeyEvent.VK_K, InputEvent.CTRL_MASK));}}@Overrideprotected boolean isActionEnable() {return this.model.getUiState() == UIState.NOT_EDIT&& this.model.getSelectedData() != null;}public void setView(BillListView view) {this.view = view;this.view.addHeadMouseClicked(this);}public String getBilltype() {return billtype;}public void setBilltype(String billtype) {this.billtype = billtype;}public String getBillid() {return billid;}public void setBillid(String billid) {this.billid = billid;}public String getBillcode() {return billcode;}public void setBillcode(String billcode) {this.billcode = billcode;}}
首先指定private static final String BILL_FINDER_CLASSNAME = "nc.vo.pr.pub.linkquery.BillTypeSetBillFinder"; 此类主要是在联查上下游单据做的相关处理。
在doaction中,校验相关信息,后面联查需要。

3.下游:如图所示:

找下游单据需要字段
主键 公司 单据编号 类型 交易类型pk(随便) 来源单据(子表)
在按钮类的doAction中

进入nc.ui.trade.billgraph.billflow.view.SourceBillFlowDlg类(单据联查和行联查对话框 )
进入initData方法中。

进入
nc.ui.trade.billgraph.billflow.view.BillLinkFlowDlg类中

进入nc.ui.trade.billgraph.billflow.view.SourceBillFlowDlg类的querySourceBillVO方法。

this.getBillFinderClassname()方法,在该类定义为全局变量
private String billFinderClassname = "nc.bs.trade.billsource.DefaultBillFinder";
进入nc.bs.trade.billsource.DefaultBillFinder这个类中的findForwardBillsForBillByLayer方法,递归函数,为当前VO合并查找后继单据VO
protected void findForwardBillsForBillByLayer(LightBillVO... bills)throws Exception {// 查找本层的单据Map<String, Map<String, LightBillVO>> billByType = new HashMap<String, Map<String, LightBillVO>>();for (LightBillVO billVO : bills) {// 设置单据类型和交易类型Namethis.setBillProperties(billVO);if (StringUtils.isEmpty(billVO.getType())|| StringUtils.isEmpty(billVO.getID())) {continue;}if (billByType.containsKey(billVO.getType())) {billByType.get(billVO.getType()).put(billVO.getID(), billVO);} else {Map<String, LightBillVO> billsSameType = new HashMap<String, LightBillVO>();billsSameType.put(billVO.getID(), billVO);billByType.put(billVO.getType(), billsSameType);}}// 获得单据的驱动单据,并且获得单据的单据号this.searchForwardBillsByLayer(billByType, null);List<LightBillVO> forwardBills = new ArrayList<LightBillVO>();for (LightBillVO billVO : bills) {LightBillVO[] forwards = billVO.getForwardBillVOs();if (forwards != null) {for (LightBillVO vo : forwards) {forwardBills.add(vo);}}}if (forwardBills.size() > 0) {findForwardBillsForBillByLayer(forwardBills.toArray(new LightBillVO[1]));}}

进入到该类的searchForwardBillsByLayer方法中,如图所示:

获得下游单据类型,如果在此处无法获得,需要在单据类型管理设置下游,


在此通过获得的下游单据类型,IBillDataFinder finder = getBillDataFinder(types[i]);找到
/** * 返回具体的单据数据查找器。 该处返回默认的数据查找器。 创建日期:(2004-6-21 20:02:15) *  * @return nc.bs.trade.billsource.IBillDataFinder * @exception java.lang.Exception *                异常说明。 */private IBillDataFinder getBillDataFinder(String billType) throws Exception {if (!this.finderMap.containsKey(billType))this.finderMap.put(billType, createBillDataFinder(billType));return this.finderMap.get(billType);}
这里的createBillDataFinder(billType)方法调用我们在action中设置的BillTypeSetBillFinder类中的createBillDataFinder方法
在重写的BillTypeSetBillFinder类中,我们重写了其中几个需要的节点。
package nc.vo.pr.pub.linkquery;import nc.bs.pf.pub.PfDataCache;import nc.bs.trade.billsource.DefaultBillFinder;import nc.bs.trade.billsource.DefaultDataFinder;import nc.bs.trade.billsource.IBillDataFinder;import nc.bs.trade.billsource.NullDataFinder;import nc.vo.pf.change.PfUtilBaseTools;import nc.vo.pub.billtype.BilltypeVO;public class BillTypeSetBillFinder extends DefaultBillFinder {@Overridepublic IBillDataFinder createBillDataFinder(String billType)throws Exception {billType = PfUtilBaseTools.getRealBilltype(billType);BilltypeVO type = PfDataCache.getBillType(billType);if(type == null)return  new NullDataFinder();IBillDataFinder finder = null;// 收款单汇总if ("H351".equalsIgnoreCase(billType)) {finder = new BillDataFinderForH351();} else if ("H350".equalsIgnoreCase(billType)) {// 收款单finder = new BillDataFinderForH350();} else if ("H345".equalsIgnoreCase(billType)) {// 收费清单finder = new BillDataFinderForH345();} else if ("H338".equalsIgnoreCase(billType)) {// 财务应收单finder = new BillDataFinderForH338();} else if ("H318".equalsIgnoreCase(billType)) {// 财务应收单finder = new BillDataFinderForH318();} else if ("H313".equalsIgnoreCase(billType)) {//合同临时费用单finder = new BillDataFinderForH313();} else {finder = new DefaultDataFinder();}return finder;}}
我们以收款单为例,如果下游是收款单,我们重写了收款单的DefaultDataFinder类
package nc.vo.pr.pub.linkquery;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import nc.bs.logging.Logger;import nc.bs.pf.pub.BillTypeCacheKey;import nc.bs.pf.pub.PfDataCache;import nc.bs.trade.billsource.DefaultDataFinder;import nc.bs.trade.billsource.IBillFlow;import nc.bs.trade.billsource.DefaultDataFinder.BillTypeInfo;import nc.jdbc.framework.JdbcSession;import nc.jdbc.framework.PersistenceManager;import nc.jdbc.framework.SQLParameter;import nc.jdbc.framework.exception.DbException;import nc.jdbc.framework.processor.BeanListProcessor;import nc.jdbc.framework.processor.ResultSetProcessor;import nc.uif.pub.exception.UifRuntimeException;import nc.vo.jcom.lang.StringUtil;import nc.vo.pub.BusinessException;import nc.vo.pub.billtype.BilltypeVO;import nc.vo.trade.billsource.LightBillVO;public class BillDataFinderForH350 extends DefaultDataFinder {/** * 当前单据类型,查询来源单据的sql * vsourcebilltype, vsourcebillid 顺序不能改变 * @author zhangqiang */@Overrideprotected String createSQL(String billType) {// TODO 自动生成的方法存根//收款单if("H350".equalsIgnoreCase(billType)){String sql="SELECT DISTINCT  vsourcebilltype as vsourcebilltype, vsourcebillid as vsourcebillid FROM fdc_pr_RevfareBody WHERE pk_head=? and isnull(dr,0)=0";return sql;}return super.createSQL(billType);}@SuppressWarnings( { "serial", "unchecked" })public nc.vo.trade.billsource.LightBillVO[] getSourceBills(String curBillType, String curBillID) {String sql = createSQL(curBillType);if (sql == null)return null;PersistenceManager sessionManager = null;try {sessionManager = PersistenceManager.getInstance();JdbcSession session = sessionManager.getJdbcSession();SQLParameter para = new SQLParameter();para.addParam(curBillID);ResultSetProcessor p = new ResultSetProcessor() {@SuppressWarnings("unchecked")public Object handleResultSet(ResultSet rs) throws SQLException {ArrayList al = new ArrayList();while (rs.next()) {String type = rs.getString(1);String id = rs.getString(2);if (type != null && id != null&& type.trim().length() > 0&& id.trim().length() > 0) {LightBillVO svo = new LightBillVO();svo.setType(type);svo.setID(id);al.add(svo);}}return al;}};ArrayList<LightBillVO> result = (ArrayList<LightBillVO>) session.executeQuery(sql, para, p);if (result.size() == 0)return null;// 增补上游单据号for (LightBillVO vo : result) {BillTypeInfo info = getBillCodeAndCorp_V61(vo.getType(), vo.getID());if(info != null){vo.setCode(info.getCode());vo.setCorp(info.getCorp());if(info.getBilltype()!=null){vo.setType(info.getBilltype());}vo.setTranstype(info.getTranstype());vo.setTranstypepk(info.getTranstypepk());}}return (nc.vo.trade.billsource.LightBillVO[]) result.toArray(new nc.vo.trade.billsource.LightBillVO[result.size()]);} catch (DbException e) { Logger.error(e.getMessage(), e);throw new UifRuntimeException(e.getMessage());} finally {sessionManager.release();}}public String[] getForwardBillTypes(LightBillVO vo)throws BusinessException {BilltypeVO billtypevo = PfDataCache.getBillTypeInfo(new BillTypeCacheKey().buildBilltype(vo.getType()));if(billtypevo == null)return null;if(billtypevo.getForwardbilltype() == null ){return null;}return billtypevo.getForwardbilltype().split(",");}@Override@SuppressWarnings( { "unchecked", "serial" })public nc.vo.trade.billsource.LightBillVO[] getForwardBills(String srcBillType,String curBillType, String... srcBillID) {String sql=null;if(curBillType.equalsIgnoreCase("H350")){ sql= "SELECT DISTINCT  fdc_pr_Revfare.pk_head id, fdc_pr_Revfare.pk_org corp, fdc_pr_Revfare.billno code ,'H350','0001B110000000002H31', B.vsourcebillid sourceID  FROM fdc_pr_Revfare, fdc_pr_RevfareBody B WHERE fdc_pr_Revfare.pk_head=B.pk_head and B.vsourcebillid in('"+srcBillID[0]+"') and fdc_pr_Revfare.dr =0 and B.dr =0";}else{ sql = createSQL1(curBillType, srcBillID);}if(sql == null)return null;PersistenceManager sessionManager = null;try {sessionManager = PersistenceManager.getInstance();JdbcSession session = sessionManager.getJdbcSession();ArrayList result = (ArrayList) session.executeQuery(sql, new BeanListProcessor(LightBillVO.class));if (result.size() == 0){return null;}else{LightBillVO  lightBillVO  = (LightBillVO) result.get(0); lightBillVO.setType("H350");return (LightBillVO[]) result.toArray(new LightBillVO[result.size()]);}} catch (DbException e) {Logger.error(e.getMessage(), e);throw new UifRuntimeException("getForwardBills error");} finally {sessionManager.release();}}/** * 功能描述:创建查询语句;在该类型的单据中查找某种类型单据的后续单据  *  * 输入参数:String billType,单据类型. *  * 返回值: SQL语句 *  * 主表表名、主表主键字段名、主表单据号字段名、子表表名、子表外键字段名、单据来源类型字段名、来源单据ID字段名 * @param srcBillID  *  */protected String createSQL1(String curBillType, String... srcBillID) {IBillFlow billflow = getBillFlow(curBillType);if (billflow == null) {nc.bs.logging.Logger.error("单据类型:" + curBillType + "没有找到单据流程信息!");return null;}String hTable = billflow.getMainTableName();String hPkField = billflow.getMainTablePrimaryKeyFiled();String hPkCorp = billflow.getBillCorp();String hBillCodeField = billflow.getBillNOField();String hBillTypeField = billflow.getBillTypeField();String hTransTypeField = billflow.getTransTypeField();String hTransTypePkField = billflow.getTransTypePkField();String bTable = billflow.getSubTableName();String bFkField = billflow.getSubTableForeignKeyFiled();//String bTableSourceTypeField = billflow.getSourceTypeField();String bTableSourceIDField = billflow.getSourceIDField();// 如果单据没有来源单据类型字段,则返回空.即如果该类型单据没有标识来源单据// 类型,就无法定位它是否是后单据.// 通常该情况是:它是某种固定类型单据的后续单据.if (bTableSourceIDField == null)return null;// 在该类型的单据中查找某种类型单据的后续单据StringBuffer sb = new StringBuffer("SELECT DISTINCT ");sb.append(" ");sb.append(hTable + "." + hPkField);sb.append(" id, ");sb.append(hTable + "." + hPkCorp);sb.append(" corp, ");sb.append(hTable + "." + hBillCodeField);sb.append(" code ");if(!StringUtil.isEmptyWithTrim(hBillTypeField)){sb.append( "," + hTable + "." + hBillTypeField);sb.append(" type");}if(!StringUtil.isEmptyWithTrim(hTransTypeField)){sb.append(", ");sb.append(hTable + "." + hTransTypeField);sb.append(" transtype ");}if(!StringUtil.isEmptyWithTrim(hTransTypePkField)){sb.append(", ");sb.append(hTable + "." + hTransTypePkField);sb.append(" transtypepk ");}{sb.append(", ");if (hTable.equalsIgnoreCase(bTable)) {sb.append("B" + "." + bTableSourceIDField);} else {sb.append(bTable + "." + bTableSourceIDField);}sb.append(" sourceID ");}sb.append(" ");sb.append("FROM");sb.append(" ");sb.append(hTable);sb.append(", ");if (hTable.equalsIgnoreCase(bTable)) {sb.append(bTable + " B");} else {sb.append(bTable);}sb.append(" ");sb.append("WHERE");sb.append(" ");sb.append(hTable + "." + hPkField);sb.append("=");if (hTable.equalsIgnoreCase(bTable)) {sb.append("B" + "." + bFkField);} else {sb.append(bTable + "." + bFkField);}sb.append(" and ");if (hTable.equalsIgnoreCase(bTable)) {sb.append("B" + "." + bTableSourceIDField);} else {sb.append(bTable + "." + bTableSourceIDField);}sb.append(" in(");    // 构造来源单据主键参数    for (String id : srcBillID) {    sb.append("'");    sb.append(id);    sb.append("'");    sb.append(",");    }    sb.deleteCharAt(sb.length() - 1);    sb.append(")");//if (hTableBillTypeField != null) {//sb.append(" and ");//sb.append(hTable + "." + hTableBillTypeField);//sb.append("=?");//}sb.append(" and ");sb.append(hTable + ".dr =0");sb.append(" and ");if (hTable.equalsIgnoreCase(bTable)) {sb.append("B" + ".dr =0");} else {sb.append(bTable + ".dr =0");}return sb.toString();}}
先执行方法public nc.vo.trade.billsource.LightBillVO[] getForwardBills(String srcBillType,String curBillType, String... srcBillID)在这里我们主要重写一句sql
sql= "SELECT DISTINCT  fdc_pr_Revfare.pk_head id, fdc_pr_Revfare.pk_org corp, fdc_pr_Revfare.billno code ,'H350','0001B110000000002H31', B.vsourcebillid sourceID  FROM fdc_pr_Revfare, fdc_pr_RevfareBody B WHERE fdc_pr_Revfare.pk_head=B.pk_head and B.vsourcebillid in('"+srcBillID[0]+"') and fdc_pr_Revfare.dr =0 and B.dr =0";

找下游单据需要字段
主键 公司 单据编号 类型 交易类型pk(随便) 来源单据(子表)
然后执行方法getForwardBillTypes(LightBillVO vo)找收款单下游,如此递归查找。
4.上游:从nc.bs.trade.billsource.DefaultBillFinder类中的findSourceBillsForBill方法开始
/** * 递归函数,为当前VO查找来源单据VO */protected void findSourceBillsForBill(LightBillVO bill) throws Exception {// 设置单据类型和交易类型Namethis.setBillProperties(bill);// 获得单据的来源单据,并且获得单据的单据号this.searchSourceBills(bill, null);// 递归调用LightBillVO[] sources = bill.getSourceBillVOs();for (int i = 0; sources != null && i < sources.length; i++) {findSourceBillsForBill(sources[i]);}}
而后的过程和下游一样,进入DefaultDataFinder类中,先执行createSQL方法,
/** * 当前单据类型,查询来源单据的sql vsourcebilltype, vsourcebillid 顺序不能改变 *  * @author zhangqiang */@Overrideprotected String createSQL(String billType) {// TODO 自动生成的方法存根// 收费清单if ("H345".equalsIgnoreCase(billType)) {String sql = "SELECT DISTINCT  vsourcebilltype as vsourcebilltype, vsourcebillid as vsourcebillid FROM fdc_pr_Bill WHERE pk_head=? and isnull(dr,0)=0";return sql;}return super.createSQL(billType);}
然后再掉用getSourceBills方法找收费清单的上游。如此递归。

如图所示:



阅读全文
0 0