From be1e1713c9ed5cf936391716fa4420971749732e Mon Sep 17 00:00:00 2001 From: sun Date: Fri, 27 Jun 2025 15:08:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=AD=E8=AF=81=E5=90=88=E5=B9=B6=E5=88=B6?= =?UTF-8?q?=E5=8D=95=E4=BA=BA=E6=8C=89=E8=BD=AC=E6=8D=A2=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=85=AC=E5=BC=8F=E5=8F=96=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fip/NVoucherSumInDBProcessor.java | 839 ++++++++++++++++++ 1 file changed, 839 insertions(+) create mode 100644 gl/src/private/nc/bs/gl/glvoucher/processor/fip/NVoucherSumInDBProcessor.java diff --git a/gl/src/private/nc/bs/gl/glvoucher/processor/fip/NVoucherSumInDBProcessor.java b/gl/src/private/nc/bs/gl/glvoucher/processor/fip/NVoucherSumInDBProcessor.java new file mode 100644 index 0000000..9b15b2d --- /dev/null +++ b/gl/src/private/nc/bs/gl/glvoucher/processor/fip/NVoucherSumInDBProcessor.java @@ -0,0 +1,839 @@ +package nc.bs.gl.glvoucher.processor.fip; + +import nc.bs.dao.BaseDAO; +import nc.bs.dao.DAOException; +import nc.bs.framework.common.InvocationInfoProxy; +import nc.bs.framework.common.NCLocator; +import nc.bs.gl.dao.GLBaseDAO; +import nc.bs.gl.voucher.service.TempTableUtils; +import nc.gl.utils.GLNumUtils; +import nc.impl.gl.pub.TempTableCreater; +import nc.itf.gl.pub.ICashFlowCase; +import nc.jdbc.framework.processor.BeanListProcessor; +import nc.vo.fi.pub.SqlUtils; +import nc.vo.fip.external.FipBillSumRSVO; +import nc.vo.fip.service.FipRelationInfoVO; +import nc.vo.fipub.freevalue.GlAssVO; +import nc.vo.fipub.freevalue.Module; +import nc.vo.fipub.utils.StrTools; +import nc.vo.gateway60.itfs.AssByPkThreadCache; +import nc.vo.gl.cashflowcase.CashflowcaseVO; +import nc.vo.gl.glvoucher.AggNVoucherVO; +import nc.vo.gl.glvoucher.NDetailVO; +import nc.vo.gl.glvoucher.NVoucherVO; +import nc.vo.glcom.ass.AssVO; +import nc.vo.glcom.constant.GLVoucherKindConst; +import nc.vo.ml.NCLangRes4VoTransl; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFDouble; +import nc.vo.pubapp.pattern.pub.MapList; +import nc.vo.voucher.fip.SchemeConst; + +import java.sql.SQLException; +import java.sql.Types; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class NVoucherSumInDBProcessor extends NVoucherSumProcessor { + public NVoucherSumInDBProcessor(String pk_sumrule) { + super(pk_sumrule); + } + + private Map mergedHead = new HashMap<>(); + + private MapList detailContainer = new MapList<>(); + + private MapList groupedRelationIdMap = new MapList<>(); + + private MapList groupedRelationVOMap = new MapList<>(); + + private Map assVOMap = new HashMap<>(); + + private String groupTempTableName; + + @Override + public List processSumData(List sumRSVOs) throws BusinessException { + fillGroupedRelationMap(sumRSVOs); + createGroupTempTable(); + prepareGroupTempTableData(); + generateMergedHead(); + loadSchemeInfo(); + sumDetail(); + List aggVouchers = constructVouchers(); + + List results = new ArrayList<>(); + for(AggNVoucherVO aggVoucher : aggVouchers) { + NVoucherSupply4FipProcessor supplyProcessor = new NVoucherSupply4FipProcessor(aggVoucher); + supplyProcessor.process(); + FipBillSumRSVO sumRSVO = new FipBillSumRSVO(); + sumRSVO.setBillVO(aggVoucher); + NVoucherVO voucher = aggVoucher.getParentVO(); + String groupId = (String)voucher.getAttributeValue("groupid"); + sumRSVO.setRelationvos(groupedRelationVOMap.get(groupId).toArray(new FipRelationInfoVO[0])); + sumRSVO.setMessageinfo(generateMsgInfo(aggVoucher)); + results.add(sumRSVO); + } + return results; + } + + private void fillGroupedRelationMap(Collection sumRsVOs) { + int groupIndex = 0; //分组号 + for(FipBillSumRSVO sumRSVO : sumRsVOs) { + FipRelationInfoVO[] relationInfos = sumRSVO.getRelationvos(); + if(relationInfos == null || relationInfos.length == 0) { + continue; + } + + String groupNO = generateGroupNO(++groupIndex); + for(FipRelationInfoVO relationInfo : relationInfos) { + groupedRelationIdMap.put(groupNO, relationInfo.getRelationID()); + groupedRelationVOMap.put(groupNO, relationInfo); + } + } + } + + private String generateGroupNO(int groupIndex) { + int maxLength = 8; + String groupNO = StrTools.supplementStr(groupIndex, maxLength, '0', true); + return groupNO; + } + + private void createGroupTempTable() throws BusinessException { + String[] columns = new String[]{"pk_voucher", "pk_detail", "groupid"}; + int[] coltype = new int[] {Types.VARCHAR, Types.VARCHAR, Types.VARCHAR}; + try { + groupTempTableName = TempTableCreater.createTempTable("tmp_gl_fipsum", columns, coltype); + } catch (SQLException e) { + throw new BusinessException(e); + } + } + + /** + * 准备分组临时表数据 + * @throws BusinessException + */ + private void prepareGroupTempTableData() throws BusinessException { + String[] columns = new String[] {"pk_voucher", "groupid"}; + List datas = new ArrayList<>(); + for(String groupId : groupedRelationIdMap.keySet()) { + List pk_vouchers = groupedRelationIdMap.get(groupId); + for(String pk_voucher : pk_vouchers) { + Object[] data = new Object[] {pk_voucher, groupId}; + datas.add(data); + } + } + new GLBaseDAO().excuteInsertBatch(groupTempTableName, columns, datas); + } + + /** + * 生成主表合并后数据 + * @throws BusinessException + */ + + private void generateMergedHead() throws BusinessException { + String sql = generateMergeHeadSql(); + List vouchers = new GLBaseDAO().excuteQuery(sql, NVoucherVO.class); + if(vouchers==null || vouchers.size()==0) { + throw new BusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("glnvoucher_0", + "0glnvoucher-0114")/* "查询不到临时凭证,可能是冻结状态" */); + } + //针对合并凭证,需要用的制单人转换模板制单人设置公式,其余单据不设置,用min取设置公式的制单人 sunfj + if(StrTools.isEmptyStr((vouchers.get(0)).getPk_prepared())) { + String sql2 = sql.replace("max(pk_prepared) as pk_prepared","min(pk_prepared) as pk_prepared " ); + List vouchers2 = new GLBaseDAO().excuteQuery(sql2, NVoucherVO.class); + if(vouchers2 != null && !vouchers2.isEmpty()) { + vouchers = vouchers2; + } + } + + + for(NVoucherVO voucher : vouchers) { + //补充制单人 + if(StrTools.isEmptyStr(voucher.getPk_prepared())) { + voucher.setPk_prepared(InvocationInfoProxy.getInstance().getUserId()); + } + + if(voucher.getVoucherkind() == null) { + voucher.setVoucherkind(GLVoucherKindConst.NORMAL); + } + + if(voucher.getPk_exratetype2() == null) { +// RateTypeVO rateTypeVO = new RateTypeThreadCache().getRateTypeByPk_Accountingbook(voucher.getPk_accountingbook()); +// String pk_exratetype2 = RateUtil.getInstance(voucher.getPk_accountingbook()).getDefaultPk_exratetype();//TODO 添加缓存缓存 +// voucher.setPk_exratetype2(rateTypeVO.getPk_ratetype()); + } + + //FIXME 重置adjustperiod,测试提问题:前台生成列表页面 期间都是空的受不了了 + if(voucher.getAdjustperiod() == null && voucher.getPeriod()!=null) { + voucher.setAdjustperiod(voucher.getPeriod()); + } + + String groupid = (String)voucher.getAttributeValue("groupid"); + if(mergedHead.get(groupid) != null) { + throw new BusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("glnvoucher_0","0glnvoucher-0014")/*@res "数据中因为有些字段不同,有不能合并成一张凭证的情况,请检查下面的字段是否相同:集团,组织,财务核算账簿,凭证类别,交易类型,自定义项。"*/); + } + mergedHead.put(groupid, voucher); + } + + combinSystem(); + } + + private void loadSchemeInfo() throws BusinessException { + NVoucherVO voucher = mergedHead.values().toArray(new NVoucherVO[0])[0]; + String pk_accountingbook = voucher.getPk_accountingbook(); + String versionDate = voucher.getPrepareddate().toStdString(); + loadSchemeInfo(pk_accountingbook, versionDate); + } + + private void sumDetail() throws BusinessException { + String[] sumSqls = getSumSql(); + String[] normalSqls = getNormalSql(); + + String[] sumConditions = getSumConditions(); + String unSumCondition = getUnSumCondition(); + + if(sumConditions != null && sumConditions.length > 0) { + for(String sumCondition : sumConditions) { + String sql = sumSqls[0] + sumSqls[1] + sumSqls[2] + sumCondition + sumSqls[3] + sumSqls[4]; + MapList results = queryDetailsBySql(sql); + //cat 现金流量 + catCashFlowCaseForSum(results, sumSqls[3].substring(6), sumSqls[1], sumCondition); + mixDetail(detailContainer, results); + } + } + + if(isCombinSameAccount()) { + if(unSumCondition != null && unSumCondition.length() > 0) { + String sql = normalSqls[0] + normalSqls[1] + normalSqls[2] + unSumCondition + normalSqls[3] + normalSqls[4]; + MapList results = queryDetailsBySql(sql); + //cat 现金流量 + catCashFlowCase(results); + mixDetail(detailContainer, results); + } + }else { + String sql = normalSqls[0] + normalSqls[1] + normalSqls[2] + unSumCondition + normalSqls[3] + normalSqls[4]; + MapList results = queryDetailsBySql(sql); + //cat 现金流量 + catCashFlowCase(results); + mixDetail(detailContainer, results); + } + } + + /** + * 构造凭证 + * modify 2022-02-23 没有分录返回主表信息 + * @return + * @throws BusinessException + */ + private List constructVouchers() throws BusinessException{ + List results= new ArrayList<>(); + //加载辅助核算信息 + loadAssInfo(); + //TODO 加载科目信息 + + String[] groupIds = groupedRelationIdMap.keySet().toArray(new String[0]); + Arrays.sort(groupIds);//分组id排序 + + for(String groupid : groupIds) { + + NVoucherVO voucher = mergedHead.get(groupid); + List details = detailContainer.get(groupid); + + if(details == null) { + details = new ArrayList<>(); + } + //补充ASSVO + for(NDetailVO detail : details) { + if(StrTools.isEmptyStr(detail.getAssid())) { + continue; + } + if(detail.getAssvos() == null) { + AssVO[] assVOs = assVOMap.get(detail.getAssid()); + detail.setAssvos(assVOs); + } + } + AggNVoucherVO aggVoucher = combinAggVoucher(voucher, details); + results.add(aggVoucher); + + } + return results; + } + + /** + * 生成合并表头的sql + * TODO 交易类型 + * @return + */ + private String generateMergeHeadSql() { + StringBuilder sql = new StringBuilder(); + sql.append("select b.groupid as groupid,pk_group, pk_org,pk_accountingbook,pk_vouchertype, pk_tradetype, 'C0' as pk_billtype, ") + .append("max(year) as year, max(period) as period, 0 as no, max(prepareddate) as prepareddate, null as pk_system,") + .append(" null as tallydate, sum(attachment) as attachment, max(pk_prepared) as pk_prepared, null as checker, null as casher, ") + .append(" null as manager, min(signflag) as signflag, min(modifyflag) as modifyflag, 'N' as discardflag, max(addclass) as addclass,") + .append(" max(deleteclass) as deleteclass, min(DETAILMODFLAG) as detailModflag, ") + .append(" null as pk_billtype, "); + for(int i = 1; i<= 30; i++) { + sql.append(" vdef").append(i).append(","); + } + sql.append(" null as pk_voucher, max(pk_exratetype2) as pk_exratetype2 "); + + sql.append("from gl_rtvoucher a inner join ").append(groupTempTableName).append(" b on a.pk_voucher = b.pk_voucher "); + sql.append("group by groupid,pk_group,pk_org,pk_accountingbook,pk_vouchertype,pk_tradetype,"); + for(int i = 1; i<= 30; i++) { + sql.append(" vdef").append(i).append(","); + } + sql.deleteCharAt(sql.length() - 1); + return sql.toString(); + } + + + /** + * 合并制单系统 + * @throws DAOException + */ + private void combinSystem() throws DAOException { + Map combinSystemMap = queryCombinSystem(); + for(String groupid : mergedHead.keySet()) { + NVoucherVO voucher = mergedHead.get(groupid); + voucher.setPk_system(combinSystemMap.get(groupid)); + } + } + + /** + * 查询制单系统 + * @return + * @throws DAOException + */ + private Map queryCombinSystem() throws DAOException{ + String sql = "select distinct groupid,pk_system from gl_rtvoucher a inner join " + + groupTempTableName + " b on a.pk_voucher = b.pk_voucher where isnull(groupid, '~') <> '~'"; + List> groupSystemList = new GLBaseDAO().excuteQuery(sql); + + MapList groupedSystem = new MapList<>(); + for(Map groupSystem : groupSystemList) { + String pk_system = (String)groupSystem.get("pk_system"); + if(pk_system != null) { + groupedSystem.put((String)groupSystem.get("groupid"), pk_system.trim()); + } + } + + Map result = new HashMap<>(); + for(String groupid : groupedSystem.keySet()) { + List systems = groupedSystem.get(groupid); + if(systems != null && systems.size() > 0) { + //去重 + Set systemSet = new LinkedHashSet(); + systemSet.addAll(systems); + + result.put(groupid, StrTools.join(systemSet.iterator(), ",")); + } + } + return result; + } + + + + + /** + * 0 select + * 1 from + * 2 where + * 3 group + * 4 order + * @return + */ + private String[] getSumSql() { + String[] results = new String[5]; + results[0] = generateSumSelectSql(); + results[1] = " from gl_rtdetail a inner join " + groupTempTableName + " b on a.pk_voucher = b.pk_voucher "; + results[2] = " where a.dr = 0 "; + results[3] = generateSumGroupSql(); + results[4] = " order by groupid "; + + if(isCombinExplan()) { + results[0] = results[0].replaceFirst("a.explanation", "max(a.explanation)"); + results[3] = results[3].replaceFirst(",a.explanation,", ","); + } + + if(isCombinPrice()) { + results[0] = results[0].replaceFirst("a.price", "sum(a.price)"); + results[3] = results[3].replaceFirst(", a.price,", ","); + } + + if(isCombinExrateInfo()) { + results[0] = results[0].replaceFirst("a." + NDetailVO.PK_EXRATETYPE2, "max(a." + NDetailVO.PK_EXRATETYPE2 + ")"); + results[0] = results[0].replaceFirst("a." + NDetailVO.EXRATEDATE2, "max(a." + NDetailVO.EXRATEDATE2 + ")"); + results[3] = results[3].replaceFirst(", " + NDetailVO.PK_EXRATETYPE2 + ",", ","); + results[3] = results[3].replaceFirst(", " + NDetailVO.EXRATEDATE2 + ",", ","); + } + + return results; + } + + /** + * 0 select + * 1 from + * 2 where + * 3 group + * 4 order + * @return + */ + private String[] getNormalSql() { + String[] results = new String[5]; + results[0] = generateNormalSelectSql(); + results[1] = " from gl_rtdetail a inner join " + groupTempTableName + " b on a.pk_voucher = b.pk_voucher "; + results[2] = " where a.dr = 0 "; + results[3] = ""; + results[4] = " order by groupid "; + + return results; + } + + private List generateDetailFields() { + /** + * 第一个字段 为 a + * 第二个字段 + * "null" => null as a + * null => a as a + * min => min(a) as a + * max => max(a) as a + * sum => sum(a) as a + */ + List fields = new ArrayList<>(); + fields.add(new String[] {NDetailVO.PK_DETAIL, "min"}); + fields.add(new String[] {NDetailVO.NOV, "null"}); + fields.add(new String[] {NDetailVO.OPPOSITESUBJ, "null"}); + fields.add(new String[] {NDetailVO.BANKACCOUNT, null}); + fields.add(new String[] {NDetailVO.PK_VOUCHER, "null"}); + fields.add(new String[] {NDetailVO.PK_ORG, "min"}); + fields.add(new String[] {NDetailVO.MODIFYFLAG, "min"}); + fields.add(new String[] {NDetailVO.RECIEPTCLASS, "min"}); + fields.add(new String[] {NDetailVO.DEBITAMOUNT, "sum"}); + fields.add(new String[] {NDetailVO.DEBITQUANTITY, "sum"}); + fields.add(new String[] {NDetailVO.LOCALDEBITAMOUNT, "sum"}); + fields.add(new String[] {NDetailVO.GROUPDEBITAMOUNT, "sum"}); + fields.add(new String[] {NDetailVO.GLOBALDEBITAMOUNT, "sum"}); + fields.add(new String[] {NDetailVO.CREDITAMOUNT, "sum"}); + fields.add(new String[] {NDetailVO.CREDITQUANTITY, "sum"}); + fields.add(new String[] {NDetailVO.LOCALCREDITAMOUNT, "sum"}); + fields.add(new String[] {NDetailVO.GROUPCREDITAMOUNT, "sum"}); + fields.add(new String[] {NDetailVO.GLOBALCREDITAMOUNT, "sum"}); + fields.add(new String[] {NDetailVO.PK_ACCOUNTINGBOOK, null}); + fields.add(new String[] {NDetailVO.PK_UNIT, null}); + fields.add(new String[] {NDetailVO.PK_UNIT_V, null}); + fields.add(new String[] {NDetailVO.PK_VOUCHERTYPEV, null}); + fields.add(new String[] {NDetailVO.YEARV, null}); + fields.add(new String[] {NDetailVO.PERIODV, null}); + fields.add(new String[] {NDetailVO.EXPLANATION, null}); + fields.add(new String[] {NDetailVO.PK_ACCASOA, null}); + fields.add(new String[] {NDetailVO.ASSID, null}); + fields.add(new String[] {NDetailVO.PK_CURRTYPE, null}); + fields.add(new String[] {NDetailVO.PRICE, null}); + fields.add(new String[] {NDetailVO.EXCRATE2, null}); + fields.add(new String[] {NDetailVO.EXCRATE3, null}); + fields.add(new String[] {NDetailVO.EXCRATE4, null}); + fields.add(new String[] {NDetailVO.CHECKSTYLE, null}); + fields.add(new String[] {NDetailVO.CHECKNO, null}); + fields.add(new String[] {NDetailVO.CHECKDATE, null}); + fields.add(new String[] {NDetailVO.BILLTYPE, null}); + fields.add(new String[] {NDetailVO.BUSIRECONNO, null}); + fields.add(new String[] {NDetailVO.NETBANKFLAG, null}); + fields.add(new String[] {NDetailVO.VERIFYDATE, null}); + fields.add(new String[] {NDetailVO.VERIFYNO, null}); + fields.add(new String[] {NDetailVO.PK_LIABILITYCENTER, null}); + fields.add(new String[] {NDetailVO.PK_LIABILITYCENTER_V, null}); + fields.add(new String[] {NDetailVO.PK_EXRATETYPE2, null}); + fields.add(new String[] {NDetailVO.EXRATEDATE2, null}); + fields.add(new String[] {NDetailVO.DUEDATE, null}); + fields.add(new String[] {NDetailVO.ORDERSTR, "max"}); + for(int i = 1; i <= 80 ;i ++) { + fields.add(new String[] {"vbdef" + i, null}); + } + return fields; + } + + private String generateSumColumnStr(String tableAlias, String[] field) { + StringBuilder columnStr = new StringBuilder(" "); + String fieldName = field[0]; + String oper = field[1]; + if(oper == null) { + columnStr.append(tableAlias).append(".").append(fieldName); + }else if(oper.equals("null")) { + columnStr.append("null"); + }else if(oper.equals("sum")) { + columnStr.append("sum(").append(tableAlias).append(".").append(fieldName).append(")"); + }else if(oper.equals("min")) { + columnStr.append("min(").append(tableAlias).append(".").append(fieldName).append(")"); + }else if(oper.equals("max")){ + columnStr.append("max(").append(tableAlias).append(".").append(fieldName).append(")"); + } + + columnStr.append(" as ").append(fieldName); + return columnStr.toString(); + } + + private String generateSumSelectSql() { + StringBuilder selectSql = new StringBuilder("select "); + List fields = generateDetailFields(); + for(String[] field : fields) { + selectSql.append(generateSumColumnStr("a", field)); + selectSql.append(", "); + } + selectSql.append("b.groupid as groupid "); + return selectSql.toString(); + } + + private String generateSumGroupSql() { + StringBuilder groupSql = new StringBuilder(); + groupSql.append(" group by b.groupid,a.pk_accountingbook,a.pk_unit,a.pk_unit_v,pk_vouchertypev,yearv,periodv,a.explanation,"); + groupSql.append(" a.pk_accasoa, assid, pk_currtype, a.price, excrate2, excrate3,excrate4,bankaccount,checkstyle, checkno,"); + groupSql.append(" checkdate, billtype, innerbusno, innerbusdate, busireconno,netbankflag, verifydate, verifyno, "); + groupSql.append(" pk_liabilitycenter, pk_liabilitycenter_v, duedate, "); + + for(int i = 1; i <= 80; i++) { + groupSql.append("vbdef").append(i).append(","); + } + groupSql.append(" pk_exratetype2, exratedate2 "); + return groupSql.toString(); + } + + private String generateNormalSelectSql() { + StringBuilder selectSql = new StringBuilder(); + selectSql.append("select "); + List fields = generateDetailFields(); + for(String[] field : fields) { + selectSql.append(" a.").append(field[0]).append(" as ").append(field[0]); + selectSql.append(", "); + } + selectSql.append(" b.groupid as groupid "); + return selectSql.toString(); + } + + /** + * 构造需要合并的查询条件 + * @return + * @throws BusinessException + */ + private String[] getSumConditions() throws BusinessException { + List conditions = new ArrayList<>(); + + boolean isCombinAccount = isCombinSameAccount(); + + StringBuilder condition = new StringBuilder(); + if(isCombinAccount) {//合并科目,排除例外科目 + //科目条件 + if(getExAccountPks() != null && getExAccountPks().length > 0) { + String inAccountSql = SqlUtils.getInStr("a.pk_accasoa", getExAccountPks(),Boolean.TRUE); + String notInAccountSql = inAccountSql.replaceFirst("in", "not in"); + condition.append(" and ").append(notInAccountSql); + } + }else {//不合并科目,则只合并例外科目 + if(getExAccountPks() == null || getExAccountPks().length == 0) { + return null; + }else { + String inAccountSql = SqlUtils.getInStr("a.pk_accasoa", getExAccountPks(),Boolean.TRUE); + condition.append(" and ").append(inAccountSql); + } + } + + //借贷条件 + if(SchemeConst.COMBINTYPE_D.equals(getCominType())){ + condition.append(" and ").append("(debitquantity<>0 or localdebitamount<>0 or groupdebitamount<>0 or globaldebitamount<>0) "); + conditions.add(condition.toString()); + }else if(SchemeConst.COMBINTYPE_C.equals(getCominType())) { + condition.append(" and ").append("(creditquantity<>0 or localcreditamount<>0 or groupcreditamount<>0 or globalcreditamount<>0) "); + conditions.add(condition.toString()); + }else { + if(isCombinDiffDirection()) { + conditions.add(condition.toString()); + }else { + //借方条件 + String conditionDebit = condition.toString() + " and (debitquantity<>0 or localdebitamount<>0 or groupdebitamount<>0 or globaldebitamount<>0) "; + conditions.add(conditionDebit); + //贷方条件 + String conditionCredit = condition.toString() + " and (creditquantity<>0 or localcreditamount<>0 or groupcreditamount<>0 or globalcreditamount<>0) "; + conditions.add(conditionCredit); + } + } + + return conditions.toArray(new String[0]); + + } + + /** + * 构造不需要合并的查询条件 + * @return null 说明 不合并科目且没有例外科目,全部采用不合并逻辑处理 + * @throws BusinessException + */ + private String getUnSumCondition() throws BusinessException { + StringBuilder condition = new StringBuilder(); + + if(isCombinSameAccount()) { + if(getExAccountPks() != null && getExAccountPks().length > 0) { + String inAccountSql = SqlUtils.getInStr("a.pk_accasoa", getExAccountPks(),Boolean.TRUE); + condition.append(inAccountSql); + } + }else { + if(getExAccountPks() != null && getExAccountPks().length > 0) { + String inAccountSql = SqlUtils.getInStr("a.pk_accasoa", getExAccountPks(),Boolean.TRUE); + String notInAccountSql = inAccountSql.replaceFirst("in", "not in"); + condition.append(notInAccountSql); + }else { + return ""; + } + } + + if(SchemeConst.COMBINTYPE_D.equals(getCominType())) { + if(condition.length() > 0){ + condition.append(" or "); + } + condition.append("(creditquantity<>0 or localcreditamount<>0 or groupcreditamount<>0 or globalcreditamount<>0) "); + }else if(SchemeConst.COMBINTYPE_C.equals(getCominType())) { + if(condition.length() > 0){ + condition.append(" or "); + } + condition.append(" (debitquantity<>0 or localdebitamount<>0 or groupdebitamount<>0 or globaldebitamount<>0) "); + } + + if(condition.length() > 0) { + condition.insert(0, " and ("); + condition.append(") "); + } + + return condition.toString(); + } + + private MapList queryDetailsBySql(String sql) throws DAOException{ + MapList results = new MapList<>(); + @SuppressWarnings("unchecked") + List details = (List)new BaseDAO().executeQuery(sql, new BeanListProcessor(NDetailVO.class)); + if(details != null && details.size() > 0) { + for(NDetailVO detail : details) { + results.put((String)detail.getAttributeValue("groupid"), detail); + } + } + return results; + } + + private void mixDetail(MapList container, MapList queryResults) { + if(queryResults != null) { + for(String key : queryResults.keySet()) { + container.putAll(key, queryResults.get(key)); + } + } + } + + private boolean isAllZero(NDetailVO detail) { + return GLNumUtils.allZero( + detail.getCreditquantity(), detail.getDebitquantity(), + detail.getCreditamount(), detail.getDebitamount(), + detail.getLocalcreditamount(), detail.getLocaldebitamount(), + detail.getGroupcreditamount(), detail.getGroupdebitamount(), + detail.getGlobalcreditamount(), detail.getGlobaldebitamount() + ); + } + + /** + * 参数顺序决定优先级 + * + * result > 0 借 + * result < 0 贷 + * result == 0 平 + * @return + */ + private int detailDirection(UFDouble... amounts) { + for(UFDouble amount : amounts) { + if(amount.compareTo(UFDouble.ZERO_DBL) != 0) { + return amount.compareTo(UFDouble.ZERO_DBL); + } + } + return 0; + } + + private int detailDirection(NDetailVO detail) { + UFDouble amount = GLNumUtils.sub(detail.getDebitamount(), detail.getCreditamount()); + UFDouble quantity = GLNumUtils.sub(detail.getDebitquantity(), detail.getCreditquantity()); + UFDouble localAmount = GLNumUtils.sub(detail.getLocaldebitamount(), detail.getLocalcreditamount()); + UFDouble groupAmount = GLNumUtils.sub(detail.getGroupdebitamount(), detail.getGroupcreditamount()); + UFDouble globalAmount = GLNumUtils.sub(detail.getGlobaldebitamount(), detail.getGlobalcreditamount()); + return detailDirection(localAmount, groupAmount, globalAmount, amount, quantity); + } + + private void clearAmount(NDetailVO detail, boolean isDebit) { + if(isDebit) { + detail.setDebitquantity(UFDouble.ZERO_DBL); + detail.setDebitamount(UFDouble.ZERO_DBL); + detail.setLocaldebitamount(UFDouble.ZERO_DBL); + detail.setGroupdebitamount(UFDouble.ZERO_DBL); + detail.setGlobaldebitamount(UFDouble.ZERO_DBL); + }else { + detail.setCreditquantity(UFDouble.ZERO_DBL); + detail.setCreditamount(UFDouble.ZERO_DBL); + detail.setLocalcreditamount(UFDouble.ZERO_DBL); + detail.setGroupcreditamount(UFDouble.ZERO_DBL); + detail.setGlobalcreditamount(UFDouble.ZERO_DBL); + } + } + + private void loadAssInfo() throws BusinessException { + Set assidSet = new HashSet<>(); + for(String groupid : detailContainer.keySet()) { + List details = detailContainer.get(groupid); + if(details == null || details.size() == 0) { + continue; + } + for(NDetailVO detail : details) { + if(detail == null) { + continue; + } + if(!StrTools.isEmptyStr(detail.getAssid())) { + assidSet.add(detail.getAssid()); + } + } + } + + if(assidSet.size() == 0) { + return; + } +// IFreevaluePub freevalue = (IFreevaluePub) NCLocator.getInstance().lookup(IFreevaluePub.class.getName()); +// GlAssVO[] glAssVOs = freevalue.queryAllByIDs(assidSet.toArray(new String[0]),null,Module.GL); + GlAssVO[] glAssVOs = AssByPkThreadCache.getInstance().getAssVO(assidSet.toArray(new String[0]), Module.GL); + if(glAssVOs != null && glAssVOs.length>0) { + for(int i=0;i details, String groupByStr, String fromStr, String sumSqlWherePart) throws BusinessException { + if(details == null || details.size() == 0) { + return; + } + + String querysql = "select a.pk_detail,min(a.pk_detail) over(partition " + groupByStr + ") as groupid " + fromStr + "" + (sumSqlWherePart == null ? "" : sumSqlWherePart); + + String tablename = "T_DETAILGROUP"; + String pkfield = "pk_detail"; + String groupfield = "groupid"; + try { + tablename = TempTableUtils.createTempTable(tablename, " " + pkfield + " varchar(40), " + groupfield + " varchar(40) ", null); + } catch (SQLException e) { + throw new BusinessException(e); + } + String insertsql = "insert into " + tablename + " (" + pkfield + "," + groupfield + ") (" + querysql + ")"; + new GLBaseDAO().excuteUpdate(insertsql); + + // 获得现金流量信息 + String[] tableinfo = new String[] { + tablename, pkfield, groupfield + }; + + ICashFlowCase cashflowproxy = (ICashFlowCase) NCLocator.getInstance().lookup(ICashFlowCase.class.getName()); + CashflowcaseVO[] cashvo = cashflowproxy.querySumCashflow4Fip(tableinfo); + + if(cashvo == null || cashvo.length == 0) { + return; + } + + //补充币种信息 + + MapList cashflowCaseMapList = new MapList<>(); + for (CashflowcaseVO cashflowcaseVO : cashvo) { + cashflowCaseMapList.put(cashflowcaseVO.getPk_detail(), cashflowcaseVO); + } + + ArrayList extGroup = new ArrayList();// 需要展开不汇总的分组,这是由于该组分录合计为0可是又有现金流量造成的 + + for(String groupId : details.keySet()) { + List detailList = details.get(groupId); + List newDetails = new ArrayList<>(); + for(NDetailVO detail : detailList) { + List cashflowList = cashflowCaseMapList.get(detail.getPk_detail()); + if(cashflowList == null || cashflowList.isEmpty()) { + continue; + } + cashFlowCaseFillCurrtype(cashflowList, detail.getPk_currtype()); + + if(isAllZero(detail)) { + extGroup.add(detail.getPk_detail()); + }else { + // 金额的校验,有现金流量的分录不允许出现借贷合计为0的情况,因为借贷合计为0的分录可能被删除,会缺失部分现金流量数据 + if(detailDirection(detail) == 0) { + NDetailVO newDetail = (NDetailVO) detail.clone(); + clearAmount(detail, false); + clearAmount(newDetail, true); + newDetails.add(newDetail); + } + detail.setCashflow(cashflowList.toArray(new CashflowcaseVO[0])); + } + cashflowCaseMapList.remove(detail.getPk_detail()); + } + } + if (cashflowCaseMapList.size() > 0) { + throw new BusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("glnvoucher_0","0glnvoucher-0015")/*@res "补现金流量出错,分录和现金流量表的分组不一致造成部分现金流量没有归属。"*//*-=notranslate=-*/); + } + + //FIXME 原有逻辑在这里将合并后借贷为0,现金流量不为0的分录补充了回来,但是后续并没有使用,这里先不补充 + + } + + + private void catCashFlowCase(MapList details) throws BusinessException { + if(details == null || details.size() == 0) { + return; + } + + List pk_details = new ArrayList<>(); + Map detailCurrTypeMap = new HashMap<>(); + for(String groupid : details.keySet()) { + for(NDetailVO detail : details.get(groupid)) { + pk_details.add(detail.getPk_detail()); + detailCurrTypeMap.put(detail.getPk_detail(), detail.getPk_currtype()); + } + } + + ICashFlowCase cashflowproxy = (ICashFlowCase) NCLocator.getInstance().lookup(ICashFlowCase.class.getName()); + CashflowcaseVO[] cashflowcasevos = cashflowproxy.queryByPKRtDetails(pk_details.toArray(new String[0])); + if(cashflowcasevos == null || cashflowcasevos.length == 0) { + return; + } + + // 如果不是总帐凭证,那么这个接口读出来的CashflowcaseVO里有可能没有币种信息,需要补上 + for(CashflowcaseVO caseVO : cashflowcasevos) { + if(caseVO != null && StrTools.isEmptyStr(caseVO.getM_pk_currtype())) { + caseVO.setM_pk_currtype(detailCurrTypeMap.get(caseVO.getPk_detail())); + } + } + + MapList caseMapList = new MapList<>(); + for(CashflowcaseVO caseVO : cashflowcasevos) { + caseMapList.put(caseVO.getPk_detail(), caseVO); + } + + for(String groupid : details.keySet()) { + for(NDetailVO detail : details.get(groupid)) { + List caseVOs = caseMapList.get(detail.getPk_detail()); + if(caseVOs == null || caseVOs.isEmpty()) { + continue; + } + detail.setCashflow(caseVOs.toArray(new CashflowcaseVO[0])); + } + } + } + + private void cashFlowCaseFillCurrtype(List cashflowCases, String defaultCurrtype) { + for(CashflowcaseVO caseVO : cashflowCases) { + if(caseVO != null && StrTools.isEmptyStr(caseVO.getM_pk_currtype())) { + caseVO.setM_pk_currtype(defaultCurrtype); + } + } + } +} \ No newline at end of file