diff --git a/arap/src/private/nc/bs/pub/action/N_F3_SAVE.java b/arap/src/private/nc/bs/pub/action/N_F3_SAVE.java index ee95445..6c9728b 100644 --- a/arap/src/private/nc/bs/pub/action/N_F3_SAVE.java +++ b/arap/src/private/nc/bs/pub/action/N_F3_SAVE.java @@ -17,7 +17,9 @@ import nc.vo.arap.pub.BillEnumCollection.ApproveStatus; import nc.vo.fipub.exception.ExceptionHandler; import nc.vo.pub.AggregatedValueObject; import nc.vo.pub.BusinessException; +import nc.vo.pub.CircularlyAccessibleValueObject; import nc.vo.pub.compiler.PfParameterVO; +import nc.vo.pub.lang.UFDouble; import nccloud.bs.arap.util.commit.ArapCommitUtil; import nccloud.pubitf.arap.arappub.IArapBillPubUtilService; @@ -63,6 +65,7 @@ public class N_F3_SAVE extends N_BASE_ACTION { this.setParameter("context", paraVo.m_preValueVos); this.beforeCheck(); String primaryKey = paraVo.m_preValueVos[0].getParentVO().getPrimaryKey(); + paraVo = this.def10Change(paraVo); if (this.hasBill(primaryKey)) { obj = this.runClass("nc.bs.arap.actions.PaybillEditSaveBatchBSAction", "updateVOs", "&context:nc.vo.pub.AggregatedValueObject[]", paraVo, this.m_keyHas); } else { @@ -104,10 +107,138 @@ public class N_F3_SAVE extends N_BASE_ACTION { private PfParameterVO def10Change(PfParameterVO paraVo) { for(AggregatedValueObject vo : paraVo.m_preValueVos) { - vo.getParentVO().setAttributeValue("approvestatus", ApproveStatus.NOSTATE.VALUE); + UFDouble money_de = UFDouble.ZERO_DBL; + for(CircularlyAccessibleValueObject childVO : vo.getChildrenVO()) { + money_de =money_de.add((UFDouble) childVO.getAttributeValue("money_de")) ; + } + vo.getParentVO().setAttributeValue("def10",toChineseAmount(money_de.toBigDecimal())); } return paraVo; } + // 数字大写汉字映射表 + private static final String[] CHINESE_CHARS = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"}; + // 数位映射表 + private static final String[] DIGIT_UNITS = {"", "拾", "佰", "仟"}; + // 数映射表 + private static final String[] LARGE_NUMBERS = {"", "万", "亿", "万亿", "亿亿"}; + // 金额单位 + private static final String[] AMOUNT_UNITS = {"元", "角", "分"}; + // 特殊情况处理 + private static final String ZERO_YUAN = "零元整"; + + public static String toChineseAmount(BigDecimal number) { + if (number == null || number.compareTo(BigDecimal.ZERO) < 0) { + throw new IllegalArgumentException("请输入非负数字"); + } + + // 将数字分为整数部分和小数部分 + String numStr = number.stripTrailingZeros().toPlainString(); + String[] parts = numStr.split("\\."); + String integerPart = parts[0]; + String decimalPart = parts.length > 1 ? parts[1] : ""; + + // 处理整数部分 + StringBuilder chineseInteger = new StringBuilder(); + if ("0".equals(integerPart)) { + chineseInteger.append(CHINESE_CHARS[0]); + } else { + char[] intChars = integerPart.toCharArray(); + int len = intChars.length; + for (int i = 0; i < len; i++) { + int digit = intChars[i] - '0'; + int digitPosition = len - i - 1; + int section = digitPosition / 4; + int positionInSection = digitPosition % 4; + + if (digit != 0) { + chineseInteger.append(CHINESE_CHARS[digit]); + if (positionInSection > 0) { + chineseInteger.append(DIGIT_UNITS[positionInSection]); + } + } + if (positionInSection == 0) { + if (digit != 0 || chineseInteger.length() == 0) { + chineseInteger.append(LARGE_NUMBERS[section]); + } + } + if (digit == 0) { + chineseInteger.append(CHINESE_CHARS[digit]); + } + } + // 移除多余的零和重复的单位 + cleanUpChineseNumber(chineseInteger); + } + + // 处理小数部分 + StringBuilder chineseDecimal = new StringBuilder(); + int jiao = 0; + int fen = 0; + if (!decimalPart.isEmpty()) { + if (decimalPart.length() >= 1) { + jiao = Integer.parseInt(decimalPart.substring(0, 1)); + } + if (decimalPart.length() >= 2) { + fen = Integer.parseInt(decimalPart.substring(1, 2)); + } + if (jiao != 0) { + chineseDecimal.append(CHINESE_CHARS[jiao]).append(AMOUNT_UNITS[1]); + } + // 如果分不为0,才输出分部分 + if (fen != 0) { + chineseDecimal.append(CHINESE_CHARS[fen]).append(AMOUNT_UNITS[2]); + } + } + + // 整合整数部分和小数部分 + if (chineseInteger.length() == 0) { + chineseInteger.append(CHINESE_CHARS[0]); + } + chineseInteger.append(AMOUNT_UNITS[0]); + if (jiao == 0 && fen == 0) { + chineseInteger.append("整"); + } else { + if (fen == 0 && jiao != 0) { + chineseInteger.append(chineseDecimal).append("整"); + } else { + chineseInteger.append(chineseDecimal); + } + } + + // 特殊情况处理:零元整 + if (chineseInteger.toString().equals("零元")) { + return ZERO_YUAN; + } + + return chineseInteger.toString(); + } + + private static void cleanUpChineseNumber(StringBuilder sb) { + // 移除连续的零,只保留一个零 + while (sb.indexOf("零零") != -1) { + sb.replace(sb.indexOf("零零"), sb.indexOf("零零") + 2, "零"); + } + // 移除末尾的零 + if (sb.length() > 0 && sb.charAt(sb.length() - 1) == '零') { + sb.deleteCharAt(sb.length() - 1); + } + // 移除单位前面的零 + for (String unit : DIGIT_UNITS) { + if (!unit.isEmpty()) { + while (sb.indexOf("零" + unit) != -1) { + sb.replace(sb.indexOf("零" + unit), sb.indexOf("零" + unit) + 2, unit); + } + } + } + // 移除大数单位前面的零 + for (String largeNum : LARGE_NUMBERS) { + if (!largeNum.isEmpty()) { + while (sb.indexOf("零" + largeNum) != -1) { + sb.replace(sb.indexOf("零" + largeNum), sb.indexOf("零" + largeNum) + 2, largeNum); + } + } + } + } + } diff --git a/ic/src/client/nccloud/web/ic/pub/action/SaveAction.java b/ic/src/client/nccloud/web/ic/pub/action/SaveAction.java index 708ecf6..9bfa99d 100644 --- a/ic/src/client/nccloud/web/ic/pub/action/SaveAction.java +++ b/ic/src/client/nccloud/web/ic/pub/action/SaveAction.java @@ -13,6 +13,7 @@ import java.util.Map; import nc.bs.dao.BaseDAO; import nc.bs.dao.DAOException; import nc.itf.scmpub.reference.uap.bd.currency.CurrencyInfo; +import nc.jdbc.framework.processor.ColumnProcessor; import nc.pubitf.ic.flowaccount.BillInfo; import nc.pubitf.ic.flowaccount.FlowAccountQuery; import nc.vo.ic.general.define.ICBillBodyVO; @@ -287,11 +288,16 @@ public class SaveAction implements ICommonAction { operator.processICBillstatusForWeb(retcard); // 鑾峰彇鏉ユ簮鍗曟嵁鍙 -// String sourceBillNo = (String) vo.getHead().getAttributeValue("55A2250500000006"); -// if (StringUtils.isNotEmpty(sourceBillNo)) { -// // 鏇存柊鏉ユ簮鍗曟嵁鐘舵佷负 "宸插鐞" -// updateSourceBillStatus(sourceBillNo, "宸插鐞"); -// } + ICBillBodyVO[] bodys = vo.getChildrenVO(); + for(ICBillBodyVO body : bodys){ + String billid = body.getCfirstbillhid(); + String billid2 = body.getCfirstbillbid(); + //鍚堟牸鍏ュ簱鏁伴噺=鏁伴噺 + if (StringUtils.isNotEmpty(billid) && body.getCfirsttype().equals("55A2")) { + // 鏇存柊鏉ユ簮鍗曟嵁鐘舵佷负 瀹屾垚娉 + updateSourceBillStatus(billid,billid2, "2"); + } + } // 鍏朵粬澶勭悊閫昏緫 String ccurrencyid = (String) vo.getBody(0).getAttributeValue("ccurrencyid"); @@ -309,13 +315,20 @@ public class SaveAction implements ICommonAction { handler.process(); return retcard; } - private void updateSourceBillStatus(String sourceBillNo, String status) throws DAOException { - + private void updateSourceBillStatus(String sourceBillNo,String sourceBillbNo, String status) throws DAOException { + BaseDAO baseDAO = new BaseDAO(); //1.鏌ヨ 娴佺▼鐢熶骇璁㈠崟鏄庣粏琛屼骇鍝侊細鍚堟牸鍏ュ簱鏁伴噺=鏁伴噺 - String sql = "update mm_pickm set cstatus = '" + status + "' where ccode = '" + sourceBillNo + "'"; -// BaseDAO baseDAO = new BaseDAO(); -// baseDAO.executeUpdate(sql); - //2.鏇存柊娴佺▼鐢熶骇璁㈠崟鏄庣粏琛屽搴斾骇鍝佺殑涓嬫父鍗曟嵁澶囨枡璁″垝鐘舵佹敼涓哄畬鎴愭 + String getPlanNumSql = "SELECT nastnum from mm_mo WHERE cmoid='[sourceBillbNo]' AND nastnum = ninastnum"; + getPlanNumSql = getPlanNumSql.replace("[sourceBillbNo]", sourceBillbNo); + Object nplanoutastnum = baseDAO.executeQuery(getPlanNumSql, + new ColumnProcessor("nastnum")); + if (nplanoutastnum == null) { + return; + }else{ + // 2.鏇存柊娴佺▼鐢熶骇璁㈠崟鏄庣粏琛屽搴斾骇鍝佺殑涓嬫父鍗曟嵁澶囨枡璁″垝鐘舵佹敼涓哄畬鎴愭 + String sql = "update mm_pickm set fbillstatus = '" + status + "' where csourcebillrowid = '" + sourceBillbNo + "'"; + baseDAO.executeUpdate(sql); + } } protected ICBillType getBilltype() { diff --git a/sscivm/src/client/nccloud/web/sscivm/ivsale/application/invoice/action/ApplicationSplitMergeMakeInvoiceAction.java b/sscivm/src/client/nccloud/web/sscivm/ivsale/application/invoice/action/ApplicationSplitMergeMakeInvoiceAction.java new file mode 100644 index 0000000..04c8a96 --- /dev/null +++ b/sscivm/src/client/nccloud/web/sscivm/ivsale/application/invoice/action/ApplicationSplitMergeMakeInvoiceAction.java @@ -0,0 +1,238 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by FernFlower decompiler) +// + +package nccloud.web.sscivm.ivsale.application.invoice.action; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import nc.bs.sscivm.ivsale.util.IVApplicationSlsmUtil; +import nc.bs.sscivm.logger.SSCIVMLogger; +import nc.vo.ml.NCLangRes4VoTransl; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFDateTime; +import nc.vo.pub.lang.UFDouble; +import nc.vo.sscivm.ivmpub.IVAplocationKPFS; +import nc.vo.sscivm.ivsale.IVApplicationAggVO; +import nc.vo.sscivm.ivsale.IVApplicationBodyVO; +import nc.vo.sscivm.ivsale.IVApplicationHeadVO; +import nccloud.framework.core.exception.ExceptionUtils; +import nccloud.framework.core.json.IJson; +import nccloud.framework.service.ServiceLocator; +import nccloud.framework.web.action.itf.ICommonAction; +import nccloud.framework.web.container.IRequest; +import nccloud.framework.web.json.JsonFactory; +import nccloud.framework.web.processor.template.BillCardConvertProcessor; +import nccloud.framework.web.ui.pattern.billcard.BillCard; +import nccloud.itf.sscivm.ivsale.service.IVApplicationInvoiceService; +import nccloud.itf.sscivm.ivsale.service.IVApplicationQueryService; +import nccloud.web.sscivm.ivsale.application.util.ApplicationMainUtil; + +public class ApplicationSplitMergeMakeInvoiceAction implements ICommonAction { + public ApplicationSplitMergeMakeInvoiceAction() { + } + + public Object doAction(IRequest request) { + IJson json = JsonFactory.create(); + String read = request.read(); + JSONObject param = JSONObject.parseObject(read); + String slsm = param.getString("slsm"); + IVApplicationInvoiceService ivService = (IVApplicationInvoiceService)ServiceLocator.find(IVApplicationInvoiceService.class); + JSONObject clazz = new JSONObject(); + Map pkTsMap = new HashMap(); + + try { + List appVos = new ArrayList(); + Map appIdMap = new HashMap(); + JSONArray paramDatas = param.getJSONArray("datas"); + + for(int i = 0; i < paramDatas.size(); ++i) { + String Id = paramDatas.getJSONObject(i).getString("id"); + BillCard billcard = (BillCard)json.fromJson(paramDatas.getJSONObject(i).getString("rightdata"), BillCard.class); + billcard.setPageid("105802SQ_KPConfirm"); + BillCardConvertProcessor processor = new BillCardConvertProcessor(); + IVApplicationAggVO vo = (IVApplicationAggVO)processor.fromBillCard(billcard); + vo = ApplicationMainUtil.transToExtAggVO(billcard, vo); + appVos.add(vo); + appIdMap.put(vo.getParentVO().getPk_ivapplication(), Id); + } + + IVApplicationAggVO[] vos = this.checkAppVOs(appVos, clazz); + + for(IVApplicationAggVO vo : vos) { + vo = IVApplicationSlsmUtil.updateSlsm(vo, slsm); + JSONObject single = new JSONObject(); + pkTsMap.put(vo.getParentVO().getPk_ivapplication(), vo.getParentVO().getTs()); + ivService.makeInvoice(new IVApplicationAggVO[]{vo}, single, pkTsMap, false); + if (!clazz.containsKey("successNum")) { + clazz.put("successNum", single.getIntValue("successNum")); + clazz.put("failNum", single.getIntValue("failNum")); + clazz.put("failData", single.get("failData")); + } else { + int successNum = clazz.getIntValue("successNum"); + int failNum = clazz.getIntValue("failNum"); + List> failMapList = (List)clazz.get("failData"); + int ssuccessNum = single.getIntValue("successNum"); + int sfailNum = single.getIntValue("failNum"); + List> sfailMapList = (List)single.get("failData"); + failMapList.addAll(sfailMapList); + clazz.put("successNum", successNum + ssuccessNum); + clazz.put("failNum", failNum + sfailNum); + clazz.put("failData", failMapList); + if (ssuccessNum > 0) { + String id = clazz.getString("id"); + if (id == null) { + id = (String)appIdMap.get(vo.getParentVO().getPk_ivapplication()); + } else { + id = id + "," + (String)appIdMap.get(vo.getParentVO().getPk_ivapplication()); + } + + clazz.put("id", id); + } + } + } + } catch (Exception e) { + SSCIVMLogger.error(e.getMessage(), e); + ExceptionUtils.wrapException(e); + } + + return clazz; + } + + private IVApplicationAggVO[] checkAppVOs(List appVos, JSONObject clazz) throws BusinessException { + int failNum = 0; + List> failMapList = new ArrayList(); + List newAppVos = new ArrayList(); + List lastAppVos = new ArrayList(); + Map pkTsMap = new HashMap(); + Set appIds = new HashSet(); + Set noCheck = new HashSet(); + + for(IVApplicationAggVO appVo : appVos) { + IVApplicationBodyVO[] bodyVos = appVo.getBodyVOs(); + if (appVo.getParentVO().getKpfs() != null && appVo.getParentVO().getKpfs() != IVAplocationKPFS.ZLKP.toIntValue() && bodyVos[0].getPk_ivappdetail().length() > 20) { + Map failMap = new HashMap(); + failMap.put("billNo", appVo.getParentVO().getBillno()); + failMap.put("msg", NCLangRes4VoTransl.getNCLangRes().getStrByID("1058sal_0", "01058sal-0106")); + failMapList.add(failMap); + ++failNum; + } else { + if (bodyVos[0].getPk_ivappdetail().length() > 20) { + for(IVApplicationBodyVO bodyVo : bodyVos) { + String detailpk = bodyVo.getPk_ivappdetail(); + JSONArray arr = JSONArray.parseArray(bodyVo.getPk_ivappdetail()); + + for(int i = 0; i < arr.size(); ++i) { + String pk_ivapplication = arr.getJSONObject(i).getString("pk_ivapplication"); + appIds.add(pk_ivapplication); + } + } + } else { + appIds.add(appVo.getParentVO().getPk_ivapplication()); + } + + newAppVos.add(appVo); + } + } + + if (appIds.size() == 0) { + return (IVApplicationAggVO[])newAppVos.toArray(new IVApplicationAggVO[0]); + } else { + IVApplicationQueryService queryser = (IVApplicationQueryService)ServiceLocator.find(IVApplicationQueryService.class); + + for(IVApplicationHeadVO oldHeadVo : queryser.queryHeadVOsByPks((String[])appIds.toArray(new String[0]))) { + if (oldHeadVo.getInvoiced_jshj().compareTo(UFDouble.ZERO_DBL) != 0 || oldHeadVo.getInvoiceing_jshj().compareTo(UFDouble.ZERO_DBL) != 0) { + noCheck.add(oldHeadVo.getPk_ivapplication()); + } + + pkTsMap.put(oldHeadVo.getPk_ivapplication(), oldHeadVo.getTs()); + } + + for(IVApplicationAggVO appVo : appVos) { + IVApplicationBodyVO[] bodyVos = appVo.getBodyVOs(); + boolean pass = true; + if (bodyVos[0].getPk_ivappdetail().length() > 20) { + Set ids = new HashSet(); + + for(IVApplicationBodyVO bodyVo : bodyVos) { + JSONArray arr = JSONArray.parseArray(bodyVo.getPk_ivappdetail()); + + for(int i = 0; i < arr.size(); ++i) { + String pk_ivapplication = arr.getJSONObject(i).getString("pk_ivapplication"); + if (!ids.contains(pk_ivapplication) && !noCheck.contains(pk_ivapplication)) { + ids.add(pk_ivapplication); + String ts = arr.getJSONObject(i).getString("ts"); + if ((new UFDateTime(ts)).compareTo((UFDateTime)pkTsMap.get(pk_ivapplication)) != 0) { + Map failMap = new HashMap(); + failMap.put("billNo", appVo.getParentVO().getBillno()); + failMap.put("msg", NCLangRes4VoTransl.getNCLangRes().getStrByID("1058sal_0", "01058sal-0057")); + failMapList.add(failMap); + ++failNum; + pass = false; + } + } + } + } + } else if (!noCheck.contains(appVo.getParentVO().getPk_ivapplication()) && appVo.getParentVO().getTs().compareTo((UFDateTime)pkTsMap.get(appVo.getParentVO().getPk_ivapplication())) != 0) { + Map failMap = new HashMap(); + failMap.put("billNo", appVo.getParentVO().getBillno()); + failMap.put("msg", NCLangRes4VoTransl.getNCLangRes().getStrByID("1058sal_0", "01058sal-0057")); + failMapList.add(failMap); + ++failNum; + pass = false; + continue; + } + + if (pass) { + lastAppVos.add(appVo); + } + } + + clazz.put("successNum", 0); + clazz.put("failNum", failMapList.size()); + clazz.put("failData", failMapList); + return (IVApplicationAggVO[])lastAppVos.toArray(new IVApplicationAggVO[0]); + } + } + + private JSONArray converDetailPkToJSONArray(String detailPk) { + JSONArray jsonArr = new JSONArray(); + List datas = new ArrayList(); + detailPk = detailPk.substring(1, detailPk.length() - 1); + int start = 0; + int end = 0; + + for(int i = 0; i < detailPk.length(); ++i) { + if (detailPk.charAt(i) == '{') { + start = i; + } + + if (detailPk.charAt(i) == '}') { + datas.add(detailPk.substring(start, i + 1)); + } + } + + for(String data : datas) { + data = data.substring(1, data.length() - 1); + JSONObject json = new JSONObject(); + String[] values = data.split(","); + + for(String value : values) { + value = value.trim(); + String[] vas = value.split("="); + json.put(vas[0], vas[1]); + } + + jsonArr.add(json); + } + + return jsonArr; + } +} diff --git a/sscivm/src/private/nccloud/itf/sscivm/ivsale/splitmerge/processor/CommonProcessor.java b/sscivm/src/private/nccloud/itf/sscivm/ivsale/splitmerge/processor/CommonProcessor.java new file mode 100644 index 0000000..64f0b3f --- /dev/null +++ b/sscivm/src/private/nccloud/itf/sscivm/ivsale/splitmerge/processor/CommonProcessor.java @@ -0,0 +1,519 @@ +package nccloud.itf.sscivm.ivsale.splitmerge.processor; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import nc.bs.framework.common.NCLocator; +import nc.bs.sscivm.ivsale.ivaconst.IVAPPSplitMergeConst; +import nc.bs.sscivm.logger.SSCIVMLogger; +import nc.bs.sscivm.pubconst.SSCIVMPubConst; +import nc.jdbc.framework.generator.SequenceGenerator; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFDouble; +import nc.vo.sscivm.ivmpub.IVAplocationFPXZ; +import nc.vo.sscivm.ivmpub.IVAplocationKPFS; +import nc.vo.sscivm.ivmpub.InvoiceTypeEnum; +import nc.vo.sscivm.ivsale.IVApplicationAggVO; +import nc.vo.sscivm.ivsale.IVApplicationBodyVO; +import nc.vo.sscivm.ivsale.IVApplicationHeadVO; +import nc.vo.sscivm.ivsale.splitmerge.CommonPlanContext; +import nccloud.impl.platform.common.util.StringUtils; +import nccloud.itf.sscivm.ivsale.service.IVApplicationInvoiceService; +import nccloud.itf.sscivm.ivsale.service.IVApplicationQueryService; +import nccloud.itf.sscivm.ivsale.splitmerge.rule.SplitMergeBaseDocRule; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +/** + * 抽象处理实现类 + * @author wangyl7 + * @Date 2023-7-5 18:07:07 + */ +public abstract class CommonProcessor { + /** + * 执行处理器逻辑 + * @param context + * @return + * @throws BusinessException + */ + public abstract Map process(CommonPlanContext context) throws BusinessException; + + /** + * 一键还原处理 + * @param context + * @return + * @throws BusinessException + */ + public Map oneButtonRestore(CommonPlanContext context) throws BusinessException{ + Map result = new HashMap(); + //默认打开待开票明细页面 + result.put(SSCIVMPubConst.PAGECODE, IVAPPSplitMergeConst.SQ_KPDETAIL); + //收购标志 + result.put(IVApplicationHeadVO.SGBZ, context.getCurBills()[0].getParentVO().getSgbz().booleanValue()); + + //按照组织,发票类型,客户/供应商/散户 进行分组 + Map> groupVosMap = groupAppVos(context.getCurBills()); + + //对分组数据进行加工 + result.put(IVAPPSplitMergeConst.DATA, processData(groupVosMap)); + + return result; + } + + /** + * 预处理折扣行信息 + * @param context + */ + public void prepareZkh(CommonPlanContext context) { + for(IVApplicationAggVO appVo : context.getCurBills()) { + int zkbz = 1; + IVApplicationBodyVO[] bodys = appVo.getBodyVOs(); + for (IVApplicationBodyVO body : bodys) { + //正常行直接跳过 + if (body.getFphxz() == IVAplocationFPXZ.FPXZ_ZCH.toIntValue()) { + continue; + } + + //被折扣行也加入,同时找到对应折扣行也加入,并建立对应关联关系 + if (body.getFphxz() == IVAplocationFPXZ.PFPXZ_BZKH.toIntValue()) { + //查找对应折扣行 + for (IVApplicationBodyVO bVo : bodys) { + if (bVo.getFphxz() == IVAplocationFPXZ.FPXZ_ZKH.toIntValue()) { + if (body.getZkhhh().equals(bVo.getHh())) { + bVo.setZkhhh(IVAPPSplitMergeConst.ZKH + ":" + zkbz); + break; + } + } + } + //标记被折扣行并加入 + body.setZkhhh(IVAPPSplitMergeConst.BZKH + ":" + zkbz); + zkbz++; + } + } + } + } + + /** + * 按照组织,发票类型,客户/供应商/散户 进行分组 + * @param appVos + * @return + * @throws BusinessException + */ + public Map> groupAppVos(IVApplicationAggVO[] appVos) throws BusinessException{ + Map> groupVosMap = new HashMap>(); + for (IVApplicationAggVO appVo : appVos) { + IVApplicationHeadVO headVo = appVo.getHeadVO(); + //组装key key = 组织 + 发票类型 + 客户/供应商/散户 + //散户为空,收购申请取供应商,其他申请取客户 + String key = headVo.getPk_org() + headVo.getFplx() + headVo.getTspz(); + if (StringUtils.isEmpty(headVo.getPk_freecustom())) { + //收购 + if (headVo.getSgbz().booleanValue()) { + key += headVo.getPk_supplier(); + } else { + //其他 + key += headVo.getPk_customer(); + } + } else { + key += headVo.getPk_freecustom(); + } + + //key一致的归为一组 + List appVoList = groupVosMap.get(key); + if (appVoList == null) { + appVoList = new ArrayList(); + } + appVoList.add(appVo); + groupVosMap.put(key, appVoList); + } + return groupVosMap; + } + + /** + * 组装数据 + * @param groupVosMap + * @return + * @throws BusinessException + */ + public List> processData(Map> groupVosMap) throws BusinessException{ + List> datas = new ArrayList>(); + //初始主键 + int index = 1000; + + //组装分组申请数据 + SplitMergeBaseDocRule docRule = new SplitMergeBaseDocRule(groupVosMap); + for (String key : groupVosMap.keySet()) { + Map dataMap = new HashMap(); + //主键 + dataMap.put(IVAPPSplitMergeConst.ID, IVAPPSplitMergeConst.KPDETAIL + index); + + //左卡数据 + List appVos = groupVosMap.get(key); + Map docMap = docRule.processDoc(appVos); + dataMap.put(IVAPPSplitMergeConst.LEFTCARD, docMap); + + //右侧数据 + dataMap.put(IVAPPSplitMergeConst.RIGHTDATA, getRightData(appVos)); + datas.add(dataMap); + + index++; + } + return datas; + } + + /** + *待开票明细获取右侧数据 + * @param appVos + * @return + * @throws BusinessException + */ + private IVApplicationBodyVO[] getRightData(List appVos) throws BusinessException{ + List bodyVos = new ArrayList(); + //折扣标记 + int zkbz = 1; + + + //遍历开票申请,初始化表体 + for (IVApplicationAggVO appVo : appVos) { + IVApplicationBodyVO[] bVos = appVo.getBodyVOs(); + for (IVApplicationBodyVO bVo : bVos) { + //正常行直接加入 + if (bVo.getFphxz() == IVAplocationFPXZ.FPXZ_ZCH.toIntValue()) { + bodyVos.add(bVo); + } + + //被折扣行也加入,同时找到对应折扣行也加入,并建立对应关联关系 + if (bVo.getFphxz() == IVAplocationFPXZ.PFPXZ_BZKH.toIntValue()) { + + //查找对应折扣行 + for (IVApplicationBodyVO tbVo : bVos) { + if (tbVo.getFphxz() == IVAplocationFPXZ.FPXZ_ZKH.toIntValue()) { + if (bVo.getZkhhh().equals(tbVo.getHh())) { + //标记被折扣行并加入 + bVo.setZkhhh(IVAPPSplitMergeConst.BZKH + ":" + zkbz); + bodyVos.add(bVo); + tbVo.setZkhhh(IVAPPSplitMergeConst.ZKH + ":" + zkbz); + bodyVos.add(tbVo); + zkbz++; + break; + } + } + } + } + } + } + + //遍历开票申请,初始化表体 + for (IVApplicationAggVO appVo : appVos) { + IVApplicationBodyVO[] bVos = appVo.getBodyVOs(); + int hh = 1; + for (IVApplicationBodyVO bVo : bVos) { + //表体单据号赋值 + bVo.setBillno(appVo.getParentVO().getBillno()); + + //行号 + bVo.setHh(String.valueOf(hh)); + hh++; + } + } + return bodyVos.toArray(new IVApplicationBodyVO[0]); + } + + /** + * 发票预览处理 + * @param result + * @return + */ + public Map previewDMHM(Map result) { + List> datas = (List>)result.get(IVAPPSplitMergeConst.DATA); + for (Map dataMap : datas) { + IVApplicationAggVO appVo = (IVApplicationAggVO)dataMap.get(IVAPPSplitMergeConst.RIGHTDATA); + if (InvoiceTypeEnum.getPaperInvoice().contains(appVo.getParentVO().getFplx())) { + try { + appVo = NCLocator.getInstance().lookup(IVApplicationInvoiceService.class).previewFphmFpdm(appVo); + dataMap.put(IVAPPSplitMergeConst.RIGHTDATA, appVo); + } catch(Exception e) { + SSCIVMLogger.error(e.getMessage(), e); + } + break; + } + } + return result; + } + + /** + * 计算开票申请表头金额 + * @param appVos + * @return + */ + public List countHeadAmount(List appVos) { + for (IVApplicationAggVO appVo : appVos) { + UFDouble jshj = UFDouble.ZERO_DBL; + UFDouble hjje = UFDouble.ZERO_DBL; + UFDouble hjse = UFDouble.ZERO_DBL; + + IVApplicationBodyVO[] bodys = appVo.getBodyVOs(); + for (IVApplicationBodyVO body : bodys) { + //表体金额数量 + body.setXmsl(body.getCaninvoice_xmsl()); + body.setXmje(body.getCaninvoice_xmje()); + body.setSe(body.getCaninvoice_se()); + body.setXmjshj(body.getCaninvoice_xmjshj()); + + //金额累加 + jshj = jshj.add(body.getCaninvoice_xmjshj()); + hjje = hjje.add(body.getCaninvoice_xmje()); + hjse = hjse.add(body.getCaninvoice_se()); + } + + //重置表头金额 + IVApplicationHeadVO headVo = appVo.getHeadVO(); + headVo.setHjje(hjje); + headVo.setHjse(hjse); + headVo.setJshj(jshj); + + headVo.setCaninvoice_hjje(hjje); + headVo.setCaninvoice_hjse(hjse); + headVo.setCaninvoice_jshj(jshj); + + //虚拟主键 + headVo.setPk_ivapplication(new SequenceGenerator().generate()); + //默认直联 + headVo.setKpfs(IVAplocationKPFS.ZLKP.toIntValue()); + } + + return appVos; + } + + /** + * 重置开票申请表体行号,建立折扣对应关系 + * @param appVos + * @return + */ + public List resetHhWithAppId(List appVos){ + //重置行号,清空折扣行行号 + for (IVApplicationAggVO appVo : appVos) { + IVApplicationBodyVO[] bodys = appVo.getBodyVOs(); + int i = 1; + for (IVApplicationBodyVO body : bodys) { + body.setHh(String.valueOf(i)); + if (body.getFphxz() == IVAplocationFPXZ.FPXZ_ZCH.toIntValue()) { + body.setZkhhh(null); + } + i++; + } + + //被折扣行赋值 + for (IVApplicationBodyVO body : bodys) { + if (body.getFphxz() != IVAplocationFPXZ.PFPXZ_BZKH.toIntValue()) { + continue; + } + + for (IVApplicationBodyVO bvo : bodys) { + if (bvo.getFphxz() != IVAplocationFPXZ.FPXZ_ZKH.toIntValue()) { + continue; + } + if (body.getZkhhh().split(":")[1].equals(bvo.getZkhhh().split(":")[1]) && body.getPk_ivapplication().equals(bvo.getPk_ivapplication())) { + body.setZkhhh(bvo.getHh()); + break; + } + } + } + + for (IVApplicationBodyVO bvo : bodys){ + if (bvo.getFphxz() != IVAplocationFPXZ.FPXZ_ZKH.toIntValue()) { + continue; + } + bvo.setZkhhh(null); + } + } + return appVos; + } + + /** + * 重置开票申请表体行号,建立折扣对应关系 + * @param appVos + * @return + */ + public List resetHh(List appVos){ + //重置行号,清空折扣行行号 + for (IVApplicationAggVO appVo : appVos) { + IVApplicationBodyVO[] bodys = appVo.getBodyVOs(); + int i = 1; + for (IVApplicationBodyVO body : bodys) { + body.setHh(String.valueOf(i)); + if (body.getFphxz() == IVAplocationFPXZ.FPXZ_ZCH.toIntValue()) { + body.setZkhhh(null); + } + i++; + } + + //被折扣行赋值 + for (IVApplicationBodyVO body : bodys) { + if (body.getFphxz() != IVAplocationFPXZ.PFPXZ_BZKH.toIntValue()) { + continue; + } + + for (IVApplicationBodyVO bvo : bodys) { + if (bvo.getFphxz() != IVAplocationFPXZ.FPXZ_ZKH.toIntValue()) { + continue; + } + if (body.getZkhhh().split(":")[1].equals(bvo.getZkhhh().split(":")[1])) { + body.setZkhhh(bvo.getHh()); + break; + } + } + } + + for (IVApplicationBodyVO bvo : bodys){ + if (bvo.getFphxz() != IVAplocationFPXZ.FPXZ_ZKH.toIntValue()) { + continue; + } + bvo.setZkhhh(null); + } + } + return appVos; + } + + /** + * 重置表体主键数据 + * @param appVos + * @return + * @throws BusinessException + */ + public List prepareDetailPk(List appVos) throws BusinessException{ + Set appIds = new HashSet(); + for (IVApplicationAggVO appVo : appVos) { + IVApplicationBodyVO[] bodys = appVo.getBodyVOs(); + for (IVApplicationBodyVO body : bodys) { + appIds.add(body.getPk_ivapplication()); + } + } + + //建立主键和表头VO 关系 + Map map = new HashMap(); + if (appIds.size() > 0) { + List headVos = NCLocator.getInstance().lookup(IVApplicationQueryService.class).queryHeadVOsByPks(appIds.toArray(new String[0])); + for (IVApplicationHeadVO headVo : headVos) { + map.put(headVo.getPk_ivapplication(), headVo); + } + } + + //重置明细主键 + for (IVApplicationAggVO appVo : appVos) { + IVApplicationBodyVO[] bodys = appVo.getBodyVOs(); + for (IVApplicationBodyVO body : bodys) { + JSONArray arr = new JSONArray(); + arr.add(prepareJESl(body, map.get(body.getPk_ivapplication()))); + body.setPk_ivappdetail(arr.toString()); + } + } + return appVos; + } + + /** + * 组装金额数量 + * @param needMergeVO 待合并表体 + * @return JSONObject 组装的json + */ + public JSONObject prepareJESl(IVApplicationBodyVO bodyVo, IVApplicationHeadVO headVo){ + JSONObject json = new JSONObject(); + json.put(IVApplicationBodyVO.PK_IVAPPDETAIL, bodyVo.getPk_ivappdetail()); + json.put(IVApplicationBodyVO.XMJE,bodyVo.getXmje().doubleValue()); + json.put(IVApplicationBodyVO.XMSL,bodyVo.getXmsl()==null?"0":bodyVo.getXmsl().doubleValue()); + json.put(IVApplicationBodyVO.SE, bodyVo.getSe().doubleValue()); + json.put(IVApplicationBodyVO.XMJSHJ, bodyVo.getXmjshj().doubleValue()); + json.put(IVApplicationBodyVO.PK_IVAPPLICATION, bodyVo.getPk_ivapplication()); + json.put(IVApplicationBodyVO.HH, bodyVo.getHh()); + json.put(IVApplicationHeadVO.TS, headVo.getTs().toStdString()); + return json; + } + + /** + * 把行号更新到明细主键中 + * @param bvos 明细vo + * @return + * @throws BusinessException + */ + public List putHHToDetailPK(List appVos) throws BusinessException{ + Set appIds = new HashSet(); + for (IVApplicationAggVO appVo : appVos) { + for(IVApplicationBodyVO bvo : appVo.getBodyVOs()){ + JSONArray arr = JSONArray.parseArray(bvo.getPk_ivappdetail()); + for(int i = 0;i < arr.size();i++){ + JSONObject json = arr.getJSONObject(i); + appIds.add(json.getString(IVApplicationBodyVO.PK_IVAPPLICATION)); + } + } + } + + //建立主键和表头VO 关系 + Map map = new HashMap(); + if (appIds.size() > 0) { + List headVos = NCLocator.getInstance().lookup(IVApplicationQueryService.class).queryHeadVOsByPks(appIds.toArray(new String[0])); + for (IVApplicationHeadVO headVo : headVos) { + map.put(headVo.getPk_ivapplication(), headVo); + } + } + + //加入行号和时间戳 + for (IVApplicationAggVO appVo : appVos) { + for(IVApplicationBodyVO bvo : appVo.getBodyVOs()){ + JSONArray arr = JSONArray.parseArray(bvo.getPk_ivappdetail()); + for(int i = 0;i < arr.size();i++){ + JSONObject json = arr.getJSONObject(i); + String pk_ivapplication = json.getString(IVApplicationBodyVO.PK_IVAPPLICATION); + json.put(IVApplicationBodyVO.HH, bvo.getHh()); + json.put(IVApplicationHeadVO.TS, map.get(pk_ivapplication).getTs().toStdString()); + } + bvo.setPk_ivappdetail(arr.toString()); + } + } + return appVos; + } + + /** + * 多张开票申请合并成一张 + * @param appVos + * @return + */ + public IVApplicationAggVO mergeAppVos(List appVos) throws BusinessException { + //合并表体 + int index = 1; + List bodys = new ArrayList<>(); + StringBuffer bz = new StringBuffer(); + for (IVApplicationAggVO appVo : appVos){ + if(bz.length() == 0){ + bz.append(appVo.getParentVO().getBz()); + } else { + bz.append("\n"+appVo.getParentVO().getBz()); + } + + IVApplicationBodyVO[] bodyVOS = appVo.getBodyVOs(); + for (IVApplicationBodyVO bodyVO : bodyVOS){ + bodys.add(bodyVO); + } + } + IVApplicationAggVO appVo = appVos.get(0); + appVo.setChildrenVO(bodys.toArray(new IVApplicationBodyVO[0])); + + //截取备注 + if (bz != null && bz.length() > 100) { + appVo.getParentVO().setBz(bz.toString().substring(0,100)); + } + + List vos = new ArrayList<>(); + vos.add(appVo); + //重算表头 + vos = countHeadAmount(vos); + //重置行号 + vos = resetHhWithAppId(vos); + //重置表体主键数据 + vos = prepareDetailPk(vos); + return vos.get(0); + } + +}