红冲发票生成开票申请逻辑调整
This commit is contained in:
		
							parent
							
								
									e64926cd6e
								
							
						
					
					
						commit
						677f7f9e56
					
				|  | @ -0,0 +1,190 @@ | |||
| package nccloud.api.so.saleinvoice.operator; | ||||
| 
 | ||||
| import nc.vo.pub.BusinessException; | ||||
| import nc.vo.pub.lang.UFDouble; | ||||
| import nc.vo.pubapp.pattern.log.Log; | ||||
| import nc.vo.pubapp.pattern.pub.MathTool; | ||||
| import nc.vo.pubapp.scale.ScaleUtils; | ||||
| import nc.vo.scmpub.util.ValueCheckUtil; | ||||
| import nc.vo.so.m32.entity.SaleInvoiceBVO; | ||||
| import nc.vo.so.m32.entity.SaleInvoiceVO; | ||||
| import nc.vo.so.m32trantype.entity.M32TranTypeVO; | ||||
| import nc.vo.so.m32trantype.enumeration.Finvoicetime; | ||||
| import nc.vo.so.pub.enumeration.BillStatus; | ||||
| import nc.vo.so.pub.util.AggVOUtil; | ||||
| import nccloud.framework.core.exception.ExceptionUtils; | ||||
| import nccloud.framework.service.ServiceLocator; | ||||
| import nccloud.itf.sscivm.ivsale.service.ExchangeToIvAppService; | ||||
| import nccloud.pubitf.so.saleinvoice.service.IM32TransTypeService; | ||||
| import nccloud.web.scmpub.pub.action.group.SysInitGroupQueryNcc; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Map.Entry; | ||||
| 
 | ||||
| public class ApplicationRedInvoiceService { | ||||
|     private static final String REDINVOICEMNYDEALFORSSC = "redinvoicemnydealforssc";// 红字发票传开票申请数据处理 | ||||
|     private static final String SL = "sl"; // 税率 | ||||
|     private static final String SESUM = "sesum"; // 税额合计 | ||||
|     private static final String JSHJSUM = "jshjsum"; // 价税合计 | ||||
|     private static final String JESUM = "jesum"; // 无税金额合计 | ||||
| 
 | ||||
|     /** | ||||
|      * 销售发票判断是否可以开红字发票 | ||||
|      * | ||||
|      * @param vos | ||||
|      * @return | ||||
|      */ | ||||
|     public List<Map<String, String>> getData(SaleInvoiceVO[] vos) { | ||||
|         Map<String, List<Map<String, String>>> dealMnyMap = new HashMap<String, List<Map<String, String>>>(); | ||||
|         try { | ||||
|             if (!SysInitGroupQueryNcc.isEndable("1058")) { | ||||
|                 ExceptionUtils.wrapBusinessException( | ||||
|                         nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4006013_0", "04006013-0038")/* @res "请启用发票管理模块!" */); | ||||
|             } | ||||
|             Map<String, Boolean> isCanGenerateMap = this.checkInvoiceStatus(AggVOUtil.getPrimaryKeys(vos)); | ||||
|             Map<String, M32TranTypeVO> invoicetime = this.qryinvoicetime(vos); | ||||
| 
 | ||||
|             for (SaleInvoiceVO vo : vos) { | ||||
|                 Boolean isCan = isCanGenerateMap.get(vo.getParentVO().getPrimaryKey()); | ||||
|                 if (isCan == null || !isCan) { | ||||
|                     ExceptionUtils.wrapBusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("4006013_0", | ||||
|                             "04006013-0039", null, new String[]{vo.getParentVO().getVbillcode()})/* 发票{0}已经开票,不能再进行开票! */); | ||||
|                 } | ||||
| 
 | ||||
|                 Integer fstatusflag = vo.getParentVO().getFstatusflag(); | ||||
|                 if (null != invoicetime && Finvoicetime.FINVOICETIEMAPPROVEAFTER | ||||
|                         .equalsValue(invoicetime.get(vo.getParentVO().getCtrantypeid()).getFinvoicetime())) { | ||||
|                     if (!BillStatus.AUDIT.getIntegerValue().equals(fstatusflag)) { | ||||
|                         ExceptionUtils.wrapBusinessException(nc.vo.ml.NCLangRes4VoTransl | ||||
|                                 .getNCLangRes().getStrByID("4006013_0", "04006013-0141", null, new String[]{vo.getParentVO().getVbillcode()})/* @res "发票{0}的状态不是审批通过状态,不能进行红字发票处理!" */); | ||||
|                     } | ||||
|                 } else if (null != invoicetime && Finvoicetime.FINVOICETIEMAPPROVEBEFORE | ||||
|                         .equalsValue(invoicetime.get(vo.getParentVO().getCtrantypeid()).getFinvoicetime())) { | ||||
|                     if (BillStatus.AUDIT.getIntegerValue().equals(fstatusflag)) { | ||||
|                         if (isCan == null || isCan) { | ||||
|                             ExceptionUtils | ||||
|                                     .wrapBusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes() | ||||
|                                             .getStrByID("4006013_0", "04006013-0146", null, new String[]{vo.getParentVO().getVbillcode()})/* @res "发票{0}的交易类型属性税务发票开票时机为先开票后审批通过,已审批通过不允许开票!" */); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             // 根据税率分组,Map<税率,Map<价税合计,税额>> | ||||
|             dealMnyMap = this.dealMnyForSSC(vos); | ||||
|         } catch (Exception e) { | ||||
|             ExceptionUtils.wrapException(e); | ||||
|         } | ||||
|         return dealMnyMap.get(REDINVOICEMNYDEALFORSSC); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 检查是否存在已生成、发票未作废的开票申请;能否继续操作 | ||||
|      * | ||||
|      * @param billIds | ||||
|      * @return (true / 未不包含有效下游单据 , 可继续开票 , 或业务单据逆向操作 ; false / 为包含下游单据 , 业务领域控制不允许继续开票 , 或业务单据逆向操作 ;) | ||||
|      * @throws BusinessException | ||||
|      */ | ||||
|     private Map<String, Boolean> checkInvoiceStatus(String[] billIds) throws BusinessException { | ||||
|         if (ValueCheckUtil.isNullORZeroLength(billIds)) { | ||||
|             return new HashMap<String, Boolean>(); | ||||
|         } | ||||
|         if (!SysInitGroupQueryNcc.isEndable("1058")) { | ||||
|             return new HashMap<String, Boolean>(); | ||||
|         } | ||||
|         return ServiceLocator.find(ExchangeToIvAppService.class).checkApplicationStatus(billIds); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 查询交易类型开票时机 | ||||
|      * | ||||
|      * @param vos | ||||
|      * @throws BusinessException | ||||
|      */ | ||||
|     private Map<String, M32TranTypeVO> qryinvoicetime(SaleInvoiceVO[] vos) throws BusinessException { | ||||
|         Map<String, M32TranTypeVO> tranttypeMap = new HashMap<String, M32TranTypeVO>(); | ||||
|         List<String> trantypeids = new ArrayList<String>(); | ||||
|         // 查询发票交易类型的税务发票开票时机 | ||||
|         for (SaleInvoiceVO vo : vos) { | ||||
|             trantypeids.add(vo.getParentVO().getCtrantypeid()); | ||||
|         } | ||||
|         // 默认先审批通过后开票 | ||||
|         if (null != trantypeids && !trantypeids.isEmpty()) { | ||||
|             try { | ||||
|                 IM32TransTypeService service = ServiceLocator.find(IM32TransTypeService.class); | ||||
|                 tranttypeMap = service.queryM32TranType(trantypeids.toArray(new String[0])); | ||||
|             } catch (Exception e) { | ||||
|                 Log.info(e); | ||||
|                 ExceptionUtils.wrapException(e); | ||||
|             } | ||||
|         } | ||||
|         if (null != tranttypeMap && !tranttypeMap.isEmpty()) { | ||||
|             return tranttypeMap; | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 处理表体发票数据,根据税率分组 | ||||
|      * | ||||
|      * @param vos | ||||
|      * @return Map<String, List < Map < String, UFDouble>>>:Map<REDINVOICEMNYDEALFORSSC,List<Map<税率/税额/价税合计,UFDouble>>> | ||||
|      * @throws BusinessException | ||||
|      */ | ||||
|     private Map<String, List<Map<String, String>>> dealMnyForSSC(SaleInvoiceVO[] vos) { | ||||
|         Map<String, List<Map<String, String>>> mnyDealForSSCMap = new HashMap<String, List<Map<String, String>>>(); | ||||
|         Map<UFDouble, String> ntaxrateGroupMap = new HashMap<UFDouble, String>(); | ||||
|         for (SaleInvoiceVO vo : vos) { | ||||
|             SaleInvoiceBVO[] bvos = vo.getChildrenVO(); | ||||
|             for (SaleInvoiceBVO bvo : bvos) { | ||||
|                 // 税率 | ||||
|                 UFDouble ntaxrate = bvo.getNtaxrate(); | ||||
|                 // 税额 | ||||
|                 UFDouble ntax = bvo.getNtax(); | ||||
|                 // 价税合计 | ||||
|                 UFDouble norigtaxmny = bvo.getNorigtaxmny(); | ||||
|                 // 无税金额 | ||||
|                 UFDouble norigmny = bvo.getNorigmny(); | ||||
|                 if (ntaxrateGroupMap.containsKey(bvo.getNtaxrate())) { | ||||
|                     String dealmny = ntaxrateGroupMap.get(ntaxrate); | ||||
|                     String[] splitmny = dealmny.split(","); | ||||
|                     UFDouble oldntax = new UFDouble(Double.valueOf(splitmny[0])); | ||||
|                     UFDouble oldnorigtaxmny = new UFDouble(Double.valueOf(splitmny[1])); | ||||
|                     UFDouble oldnorigmny = new UFDouble(Double.valueOf(splitmny[2])); | ||||
|                     UFDouble ntaxsum = MathTool.add(ntax, oldntax); | ||||
|                     UFDouble norigtaxmnysum = MathTool.add(norigtaxmny, oldnorigtaxmny); | ||||
|                     UFDouble norigmnysum = MathTool.add(norigmny, oldnorigmny); | ||||
|                     ntaxrateGroupMap.put(ntaxrate, ntaxsum + "," + norigtaxmnysum + "," + norigmnysum); | ||||
|                 } else { | ||||
|                     ntaxrateGroupMap.put(ntaxrate, ntax + "," + norigtaxmny + "," + norigmny); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             List<Map<String, String>> mnyDealForSSCList = new ArrayList<Map<String, String>>(); | ||||
|             for (Entry<UFDouble, String> dealmny : ntaxrateGroupMap.entrySet()) { | ||||
|                 Map<String, String> mnyDealforSSCMap = new HashMap<String, String>(); | ||||
|                 UFDouble dealtaxrate = dealmny.getKey(); | ||||
|                 String[] splitdealmny = dealmny.getValue().split(","); | ||||
|                 UFDouble dealnatx = new UFDouble(Double.valueOf(splitdealmny[0])); | ||||
|                 dealnatx = ScaleUtils.adjustScale(dealnatx, 2); | ||||
|                 UFDouble dealnorigtaxmny = new UFDouble(Double.valueOf(splitdealmny[1])); | ||||
|                 dealnorigtaxmny = ScaleUtils.adjustScale(dealnorigtaxmny, 2); | ||||
|                 UFDouble dealnorigmny = new UFDouble(Double.valueOf(splitdealmny[2])); | ||||
|                 dealnorigmny = ScaleUtils.adjustScale(dealnorigmny, 2); | ||||
|                 // 税率 | ||||
|                 mnyDealforSSCMap.put(SL, dealtaxrate.toString()); | ||||
|                 // 税额合计 | ||||
|                 mnyDealforSSCMap.put(SESUM, dealnatx.toString()); | ||||
|                 // 价税合计 | ||||
|                 mnyDealforSSCMap.put(JSHJSUM, dealnorigtaxmny.toString()); | ||||
|                 // 无税金额合计 | ||||
|                 mnyDealforSSCMap.put(JESUM, dealnorigmny.toString()); | ||||
|                 mnyDealForSSCList.add(mnyDealforSSCMap); | ||||
|             } | ||||
|             mnyDealForSSCMap.put(REDINVOICEMNYDEALFORSSC, mnyDealForSSCList); | ||||
|         } | ||||
|         return mnyDealForSSCMap; | ||||
|     } | ||||
| } | ||||
|  | @ -5,7 +5,6 @@ import com.alibaba.fastjson.JSONObject; | |||
| import nc.bs.framework.common.InvocationInfoProxy; | ||||
| import nc.bs.framework.common.NCLocator; | ||||
| import nc.bs.logging.Logger; | ||||
| import nc.bs.trade.business.HYSuperDMO; | ||||
| import nc.itf.uap.IUAPQueryBS; | ||||
| import nc.jdbc.framework.processor.ColumnProcessor; | ||||
| import nc.jdbc.framework.processor.MapProcessor; | ||||
|  | @ -30,7 +29,9 @@ import nccloud.api.baseapp.exchange.convert.OpenApiConvertDataResult; | |||
| import nccloud.api.rest.utils.ResultMessageUtil; | ||||
| import nccloud.commons.lang.StringUtils; | ||||
| import nccloud.dto.scmpub.script.entity.SCMScriptResultDTO; | ||||
| import nccloud.itf.sscivm.ivsale.impl.IVApplicationServiceImpl; | ||||
| import nccloud.framework.core.exception.ExceptionUtils; | ||||
| import nccloud.framework.service.ServiceLocator; | ||||
| import nccloud.itf.sscivm.ivsale.service.IVApplicationInvoiceService; | ||||
| import nccloud.pubitf.riart.pflow.CloudPFlowContext; | ||||
| import nccloud.pubitf.riart.pflow.ICloudScriptPFlowService; | ||||
| import nccloud.pubitf.scmpub.commit.service.IBatchRunScriptService; | ||||
|  | @ -40,7 +41,6 @@ import nccloud.pubitf.ssctp.sscbd.lientage.ISSClientageMatchService; | |||
| import org.json.JSONString; | ||||
| 
 | ||||
| import java.math.BigDecimal; | ||||
| import java.math.RoundingMode; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
|  | @ -210,22 +210,12 @@ public class IAPISaleInvMaitainImpl { | |||
| 
 | ||||
|         /** | ||||
|          * 开票申请红冲逻辑: | ||||
|          *  1.根据销售发票号查询下游开票申请 | ||||
|          *  2.根据原开票申请生成新红冲 | ||||
|          *  生成开票申请的旧逻辑,走不通已废弃 1.根据销售发票号查询下游开票申请 2.根据原开票申请生成新红冲 | ||||
|          *  新逻辑:根据税务云的发票号查询蓝字发票,根据蓝字和已生成的红字发票共同生成红字的开票申请 | ||||
|          */ | ||||
|         String vBillcode = saleInvoiceVOs[0].getParentVO().getVbillcode(); | ||||
|         HYSuperDMO dmo = new HYSuperDMO(); | ||||
|         // 开票申请单主表 | ||||
|         IVApplicationHeadVO[] iVApplicationHeadVO = (IVApplicationHeadVO[]) dmo.queryByWhereClause(IVApplicationHeadVO.class, "src_billno='" + vBillcode + "' and dr=0 "); | ||||
|         String pk_ivapplication = iVApplicationHeadVO[0].getPk_ivapplication(); // 开票申请id | ||||
|         // 开票申请单子表 | ||||
|         IVApplicationBodyVO[] iVApplicationBodyVOs = (IVApplicationBodyVO[]) dmo.queryByWhereClause(IVApplicationBodyVO.class, "pk_ivapplication='" + pk_ivapplication + "' and dr=0 "); | ||||
|         // 调用函数封装开票申请红冲VO | ||||
|         IVApplicationAggVO iVApplicationAggVO = makeNewRedRushIVApplicationAggVO(iVApplicationHeadVO[0], iVApplicationBodyVOs, bject, redVos); | ||||
|         // 生成红冲的开票申请 | ||||
|         IVApplicationServiceImpl serviceImpl = new IVApplicationServiceImpl(); | ||||
|         IVApplicationAggVO returnSaveIVApplicationAggVO = serviceImpl.save(iVApplicationAggVO); | ||||
|         IVApplicationAggVO returnSaveIVApplicationAggVO = saveIVApplication(bject, redVos); | ||||
|         if (returnSaveIVApplicationAggVO != null) { | ||||
|             Logger.error("inv-redApply = " + JSONArray.toJSONString(returnSaveIVApplicationAggVO)); | ||||
|             // 查询红冲发票信息返回给调用方 | ||||
|             return ResultMessageUtil.toJSON(redVos, "接口调用成功"); | ||||
|         } else { | ||||
|  | @ -661,7 +651,8 @@ public class IAPISaleInvMaitainImpl { | |||
|             newivApplicationHeadVO.setSrc_tradetype(rpSaleInvoiceHVO.getCtrantypeid());  // 来源交易类型 | ||||
|             newivApplicationHeadVO.setSrc_pkbusibill(rpSaleInvoiceHVO.getCsaleinvoiceid());  // 来源单据id | ||||
|             newivApplicationHeadVO.setSrc_billno(rpSaleInvoiceHVO.getVbillcode());  // 来源单据编号 | ||||
|             newivApplicationHeadVO.setHcyy("2");  // 红冲原因:2(开票有误) | ||||
|             // 红冲原因:1=销货退回; 2=开票有误; 3=服务中止; 4=销售折让; | ||||
|             newivApplicationHeadVO.setHcyy("1"); | ||||
| 
 | ||||
|             // 组装VO | ||||
|             applicationAggVO.setParentVO(newivApplicationHeadVO); | ||||
|  | @ -672,6 +663,36 @@ public class IAPISaleInvMaitainImpl { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public IVApplicationAggVO saveIVApplication(JSONObject bject, SaleInvoiceVO[] redVos) throws Exception { | ||||
|         // 获取 红字发票传开票申请的数据 | ||||
|         ApplicationRedInvoiceService applicationRedInvoiceService = new ApplicationRedInvoiceService(); | ||||
|         List<Map<String, String>> jeMap = applicationRedInvoiceService.getData(redVos); | ||||
| 
 | ||||
|         IVApplicationAggVO applyVo = null; | ||||
| 
 | ||||
|         String invId = bject.getOrDefault("vdef40", "") + ""; | ||||
| 
 | ||||
|         // 查询蓝字发票号对应的税务云开出的发票号 | ||||
|         String invCode = getSaleInvCode(invId); | ||||
|         if (StringUtils.isBlank(invCode) || "null".equals(invCode)) { | ||||
|             ExceptionUtils.wrapBusinessException("税务云的发票号不能为空"); | ||||
|         } | ||||
|         IVApplicationInvoiceService ivService = ServiceLocator.find(IVApplicationInvoiceService.class); | ||||
|         JSONObject jsonObject1 = new JSONObject(); | ||||
|         // 查询对应的蓝字发票 | ||||
|         IVApplicationAggVO[] blueVos = ivService.getRedInvoice("", invCode, jsonObject1); | ||||
|         Logger.error("saveIVApplication-jsonObject1 = " + jsonObject1); | ||||
|         JSONObject jsonObject = new JSONObject(); | ||||
|         // 红字发票生成开票申请动作 | ||||
|         IVApplicationAggVO[] ivApplicationVOs = ivService.makeRedInvoice(blueVos, jsonObject, jeMap); | ||||
|         if (ivApplicationVOs != null && ivApplicationVOs.length > 0) { | ||||
|             applyVo = ivApplicationVOs[0]; | ||||
|         } | ||||
|         Logger.error("saveIVApplication-msg = " + jsonObject); | ||||
|         return applyVo; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private Map<String, Object> getSaleOrderInfo(String csaleorderbid) throws BusinessException { | ||||
|         IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class); | ||||
|         String sql = " select s.vbillcode,s.csaleorderid, s.corigcurrencyid," + | ||||
|  | @ -684,6 +705,22 @@ public class IAPISaleInvMaitainImpl { | |||
|         return (Map<String, Object>) queryBS.executeQuery(sql, new MapProcessor()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 根据税务云单号查询发票的单号 | ||||
|      * | ||||
|      * @param invId | ||||
|      * @return | ||||
|      * @throws BusinessException | ||||
|      */ | ||||
|     private String getSaleInvCode(String invId) throws BusinessException { | ||||
|         IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class); | ||||
|         String sql = " select nvl(vdef13, '') vdef13" + | ||||
|                 " from so_saleinvoice" + | ||||
|                 " where nvl(dr,0) = 0 and csaleinvoiceid = '" + invId + "' "; | ||||
|         Map<String, String> resMap = (Map<String, String>) queryBS.executeQuery(sql, new MapProcessor()); | ||||
|         return resMap.getOrDefault("vbillcode", ""); | ||||
|     } | ||||
| 
 | ||||
|     private String getString_TrimAsNull(Object value) { | ||||
|         if ((value == null) || (value.toString().trim().isEmpty())) { | ||||
|             return ""; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue