From a46c3275c1605675ea3fc80b84368a19248912da Mon Sep 17 00:00:00 2001 From: mzr <1562242162@qq.com> Date: Tue, 4 Mar 2025 18:03:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A5=E6=94=B6BIP=E5=BC=80=E7=A5=A8?= =?UTF-8?q?=E7=94=B3=E8=AF=B7=E7=94=9F=E6=88=90=E9=94=80=E5=94=AE=E5=8F=91?= =?UTF-8?q?=E7=A5=A8-=E6=B1=87=E7=8E=87=E5=8F=8A=E5=B8=81=E7=A7=8D?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../operator/saveCommitAction.java | 422 ++++++++++++++++++ 1 file changed, 422 insertions(+) diff --git a/so/src/public/nccloud/api/so/saleinvoice/operator/saveCommitAction.java b/so/src/public/nccloud/api/so/saleinvoice/operator/saveCommitAction.java index e69de29..22687b0 100644 --- a/so/src/public/nccloud/api/so/saleinvoice/operator/saveCommitAction.java +++ b/so/src/public/nccloud/api/so/saleinvoice/operator/saveCommitAction.java @@ -0,0 +1,422 @@ +package nccloud.api.so.saleinvoice.operator; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import nc.bs.framework.common.InvocationInfoProxy; +import nc.bs.framework.common.NCLocator; +import nc.bs.framework.core.util.ObjectCreator; +import nc.itf.uap.IUAPQueryBS; +import nc.jdbc.framework.processor.ColumnProcessor; +import nc.jdbc.framework.processor.MapProcessor; +import nc.pubitf.so.m32.api.ISaleinvoiceQueryAPI; +import nc.vo.pub.BusinessException; +import nc.vo.pub.lang.UFDouble; +import nc.vo.pubapp.pattern.model.entity.bill.AbstractBill; +import nc.vo.pubapp.pflow.PfUserObject; +import nc.vo.so.m32.entity.SaleInvoiceHVO; +import nc.vo.so.m32.entity.SaleInvoiceVO; +import nccloud.api.baseapp.exchange.convert.IExchangeForService; +import nccloud.api.baseapp.exchange.convert.OpenApiConvertDataObject; +import nccloud.api.baseapp.exchange.convert.OpenApiConvertDataResult; +import nccloud.api.rest.utils.ResultMessageUtil; +import nccloud.dto.scmpub.script.entity.SCMScriptResultDTO; +import nccloud.dto.scmpub.tax.entity.TaxInvoiceType; +import nccloud.pubitf.riart.pflow.CloudPFlowContext; +import nccloud.pubitf.scmpub.commit.service.IBatchRunScriptService; +import nccloud.pubitf.scmpub.ssc.service.ISSCService; +import nccloud.pubitf.ssctp.sscbd.lientage.ISSClientageMatchService.BusiUnitTypeEnum; +import nccloud.ws.rest.resource.AbstractNCCRestResource; +import org.json.JSONString; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Map; + + +@Path("so/saleinvoice/operator") +public class saveCommitAction extends AbstractNCCRestResource { + + public static String fplxStr = "";// 开票申请发票类型 + + public saveCommitAction() { + + } + + public OpenApiConvertDataResult changeToExchangeData(OpenApiConvertDataObject openApiConvertDataObject) + throws Exception { + return getPFxxEJBService().changeToExchangeData(openApiConvertDataObject); + } + + public static IExchangeForService getPFxxEJBService() { + IExchangeForService exchangeForService = (IExchangeForService) ObjectCreator.newInstance("ufesbexpress", + "nccloud.pubimpl.pfxx.convert.ExchangeForServiceImpl"); + return exchangeForService; + } + + @Override + public String getModule() { + return "so"; + } + + @POST + @Path("/saveCommit") + @Consumes({"application/json"}) + @Produces({"application/json"}) + public JSONString saveCommit(JSONString json) throws Exception { + JSONObject jobject = JSONObject.parseObject(json.toJSONString()); + if (jobject == null) { + return ResultMessageUtil.exceptionToJSON(new NullPointerException("JSONString:null")); + } else { + JSONObject bject = jobject.getJSONObject("billhead"); + if (bject == null) { + return ResultMessageUtil.exceptionToJSON(new NullPointerException("billhead:null")); + } else { + + JSONObject ufinterfaceObj = jsonObjectAss(jobject); + String tsType = ufinterfaceObj.getString("tsType"); + if (tsType != null && tsType.equals("1")) { + Exception e = new NullPointerException("销售订单查询关联失败!"); + return ResultMessageUtil.exceptionToJSON(e); + } + JSONObject bjects = ufinterfaceObj.getJSONObject("ufinterface"); + String billtype = bjects.getString("billtype"); + String account = bjects.getString("account"); + String omscode = bjects.getString("orgcode"); + String groupcode = bjects.getString("groupcode"); + + if (billtype != null && account != null && groupcode != null && "32".equals(billtype)) { + OpenApiConvertDataObject openApiconvertData0bject = new OpenApiConvertDataObject(); + openApiconvertData0bject.setAccount(account); + openApiconvertData0bject.setBilltype(billtype); + openApiconvertData0bject.setGroupcode(groupcode); + openApiconvertData0bject.setOpenApiJsonData(ufinterfaceObj); + try { + OpenApiJsonConvertToExChangeXmlService oService = new OpenApiJsonConvertToExChangeXmlService(); + OpenApiConvertDataResult r = oService.changeToExchangeData(openApiconvertData0bject); + JSONObject returnJson = r.getDesc(); + String content = ""; + // 逐层解析 JSON 数据 + JSONObject ufinterface = returnJson.getJSONObject("ufinterface"); + if (ufinterface != null) { + JSONArray sendResultArray = ufinterface.getJSONArray("sendresult"); + if (sendResultArray != null && sendResultArray.size() > 0) { + // 提取 content 字段 + content = sendResultArray.getJSONObject(0).getString("content"); + } + } + if (content == null || content.equals("")) { + return r != null + ? ResultMessageUtil.toJSON(r.getDesc(), "0") + : ResultMessageUtil.exceptionToJSON(new NullPointerException("未知异常")); + } + String[] ids = {content}; + SaleInvoiceVO[] saleInvoiceVO = NCLocator.getInstance().lookup(ISaleinvoiceQueryAPI.class) + .queryVOByIDs(ids); + SaleInvoiceVO saleInvoiceVO22 = saleInvoiceVO[0]; + SaleInvoiceHVO saleInvoiceHVO = saleInvoiceVO22.getParentVO(); + // 销售发票审核开始 + InvocationInfoProxy.getInstance().setUserId(saleInvoiceHVO.getApprover()); + CloudPFlowContext context = new CloudPFlowContext(); + context.setBillType("32"); + context.setBillVos(new SaleInvoiceVO[]{saleInvoiceVO[0]}); + ISSCService sscService = (ISSCService) NCLocator.getInstance().lookup(ISSCService.class); + String[] actionNames = sscService.isStartSSCWorkFlow( + (AbstractBill[]) ((AbstractBill[]) context.getBillVos()), BusiUnitTypeEnum.SO); + context.setActionName("APPROVE"); + context.setTrantype("32-02"); + context.setBatch(false); + context.setBatchUserObj(new PfUserObject[]{new PfUserObject()}); + IBatchRunScriptService service = (IBatchRunScriptService) NCLocator.getInstance() + .lookup(IBatchRunScriptService.class); + SCMScriptResultDTO result = service.runBacth(context, SaleInvoiceVO.class); + // 销售发票审核结束 + TaxInvoiceType typeObj = TaxInvoiceType.SpecialInvoice; + SaleInvoiceToTaxInvServiceImpl saleInvoiceToTaxInvService = new SaleInvoiceToTaxInvServiceImpl(); + saleInvoiceToTaxInvService.issueTaxInvoice(saleInvoiceVO, typeObj); + + return r != null + ? ResultMessageUtil.toJSON(r.getDesc(), "0") + : ResultMessageUtil.exceptionToJSON(new NullPointerException("未知异常")); + } catch (Exception e) { + return ResultMessageUtil.exceptionToJSON(e); + } + } else { + Exception e = new NullPointerException( + "billtype:" + billtype + ",account:" + account + ",groupcode:" + groupcode); + return ResultMessageUtil.exceptionToJSON(e); + } + + } + } + } + + public static JSONObject jsonObjectAss(JSONObject originalJson) throws Exception { + try { + // 构建目标 JSON 格式 + JSONObject resultJson = new JSONObject(); + // 添加 ufinterface 字段 + JSONObject ufinterface = new JSONObject(); + ufinterface.put("billtype", "32"); + ufinterface.put("sender", "BIP_NC"); + ufinterface.put("level", "0"); + ufinterface.put("replace", "Y"); + ufinterface.put("roottag", "bill"); + ufinterface.put("isexchange", "Y"); + ufinterface.put("account", "01"); + ufinterface.put("groupcode", "00"); + // 处理 bill 数组 + JSONArray billArray = new JSONArray(); + JSONObject bill = new JSONObject(); + // billhead 结构 + JSONObject billhead = new JSONObject(); + billhead = originalJson.getJSONObject("billhead");// 传入JSON对象 + billhead.put("pk_org_v", originalJson.getJSONObject("billhead").getString("pk_org"));// 开票组织版本=开票组织 + billhead.put("pk_group", "00");// 集团 + fplxStr = originalJson.getJSONObject("billhead").getString("vdef22"); + billhead.put("vtrantypecode", "32-02");// 发票类型编码 + billhead.put("cbiztypeid", "SO01");// 业务流程 + billhead.put("approver", "BIP");// 审批人 + billhead.put("fstatusflag", 1);// 单据状态 + billhead.put("billmaker", "BIP");// 制单人 + billhead.put("csendcountryid", "CN");// 发货国家 + billhead.put("crececountryid", "CN");// 收货国家 + billhead.put("ctaxcountryid", "CN");// 报税国家 + // 2025-2-8付业要求修改,根据发票类型Q(自定义档案)对照发票类型 + String ctrantypeidStr = "32-02";// 默认普通发票 + if (fplxStr != null && fplxStr.equals("31")) { + ctrantypeidStr = "32-01"; + } else if (fplxStr != null && fplxStr.equals("32")) { + ctrantypeidStr = "32-02"; + } else if (fplxStr != null && fplxStr.equals("36")) { + ctrantypeidStr = "32-Cxx-03"; + } + billhead.put("ctrantypeid", ctrantypeidStr);// 发票类型 + // billhead.put("ctrantypeid", "32-02");//发票类型 + billhead.put("fbuysellflag", "1");// 购销类型 + billhead.put("creator", "BIP");// 创建人 + billhead.put("ccurrencyid", "CNY");// 本位币 + billhead.put("corigcurrencyid", "CNY");// 币种 + billhead.put("nexchangerate", 1);// 折本汇率 + billhead.put("btriatradeflag", 0);// 三角贸易 + JSONObject newItem = new JSONObject(); + JSONObject otherJson = new JSONObject(); + JSONArray csaleinvoicebid = new JSONArray(); + // 遍历原始数据中的 csaleinvoicebid 数组 + for (int i = 0; i < originalJson.getJSONObject("billhead").getJSONArray("csaleinvoicebid").size(); i++) { + JSONObject item = originalJson.getJSONObject("billhead").getJSONArray("csaleinvoicebid") + .getJSONObject(i); + + JSONObject itemDetails = new JSONObject(); + itemDetails = item; + itemDetails.put("carorgid", originalJson.getJSONObject("billhead").getString("pk_org"));// 应收组织 + itemDetails.put("csendstockorgid", + originalJson.getJSONObject("billhead").getString("pk_org"));// 库存组织原始版本 + itemDetails.put("cmaterialid", item.getString("cmaterialvid"));// 物料编码 + Map value2 = getSaleorderVo(item.getString("csrcbid")); + if (value2 == null) { + resultJson = new JSONObject(); + resultJson.put("tsType", "1"); + return resultJson; + } + itemDetails.put("vfirsttype", "30");// 源头单据类型 + itemDetails.put("vfirstcode", value2.get("vbillcode"));// 源头单据号 + itemDetails.put("blargessflag", value2.get("blargessflag"));// 赠品 + itemDetails.put("vfirsttrantype", "30-01");// 源头交易类型 + itemDetails.put("vfirstrowno", value2.get("crowno"));// 源头单据行号 + itemDetails.put("cfirstid", item.getString("csrcid"));// 源头单据主表 + itemDetails.put("cfirstbid", item.getString("csrcbid"));// 源头单据子表 + itemDetails.put("vsrctype", "30");// 来源单据类型 + itemDetails.put("vsrccode", value2.get("vbillcode"));// 来源单据号 + itemDetails.put("vsrctrantype", "30-01");// 来源交易类型 + itemDetails.put("vsrcrowno", value2.get("crowno"));// 来源单据行号 + // 通过 ntaxrate 获取 taxcode + String taxcodeStr = getTaxcode(item.getString("ntaxrate")); + // 将 taxcodeStr 放入 bodyMap + itemDetails.put("ctaxcodeid", taxcodeStr);// 税码 + itemDetails.put("nnum", item.getString("nastnum"));// 主数量 + itemDetails.put("ftaxtypeflag", 1);// 扣税类别 + itemDetails.put("pk_group", "00");// 集团 + itemDetails.put("pk_org", originalJson.getJSONObject("billhead").getString("pk_org"));// 开票组织 + itemDetails.put("cunitid", item.getString("castunitid"));// 主单位 + +// double nastnum = Double.parseDouble(item.getString("nastnum"));//数量 +// double nqtorigtaxprice = Double.parseDouble(item.getString("nqtorigtaxprice"));//含税单价 +// double ntaxrate = Double.parseDouble(item.getString("ntaxrate"));//税率 +// +// double nqtorigprice = +// Math.round(nqtorigtaxprice / (1 + ntaxrate) * 100.0) / 100.0;//不含税单价、无税单价(含税单价/(1+税率)) +// double norigmny = Math.round(nqtorigprice * nastnum * 100.0) / 100.0;//无税金额(不含税单价*数量) +// double norigtaxmny = Math.round(nastnum * nqtorigtaxprice * 100.0) / 100.0;//价税合计、含税金额(数量*含税单价) +// double norigtaxprice = Math.round(nqtorigtaxprice * 100.0) / 100.0;//主含税单价(含税单价) +// double norignetprice = nqtorigprice;//主无税净价(不含税单价) +// double ntax = Math.round(norigtaxmny / (1 + ntaxrate) * ntaxrate * 100.0) / 100.0;//税额(含税金额/(1+税率)*税率) +// double ncaltaxmny = norigmny;//计税金额(无税金额) +// double norigtaxnetprice = norigtaxprice;//主含税净价(主含税单价) + +// BigDecimal nastnum = new BigDecimal(item.getString("nastnum"));//数量 +// BigDecimal nqtorigtaxprice = new BigDecimal(item.getString("nqtorigtaxprice"));//含税单价 +// BigDecimal ntaxrate = new BigDecimal(item.getString("ntaxrate"));//税率 +// +// // 1. 计算不含税单价 +// BigDecimal nqtorigprice = nqtorigtaxprice.divide(BigDecimal.ONE.add(ntaxrate), 4, RoundingMode.HALF_UP); +// // 2. 计算无税金额 = 不含税单价 * 数量 +// BigDecimal norigmny = nqtorigprice.multiply(nastnum).setScale(4, RoundingMode.HALF_UP); +// // 3. 计算税额 = 无税金额 * 税率 +// BigDecimal ntax = norigmny.multiply(ntaxrate).setScale(4, RoundingMode.HALF_UP); +// // 4. 计算含税金额 = 无税金额 + 税额 +// BigDecimal norigtaxmny = norigmny.add(ntax).setScale(4, RoundingMode.HALF_UP); +// // 主含税单价(即含税单价) +// BigDecimal norigtaxprice = nqtorigtaxprice.setScale(4, RoundingMode.HALF_UP); +// // 主无税净价(即不含税单价) +// BigDecimal norignetprice = nqtorigprice; +// // 计税金额 = 无税金额 +// BigDecimal ncaltaxmny = norigmny; +// // 主含税净价 = 含税单价(原始) +// BigDecimal norigtaxnetprice = norigtaxprice; + + // 输入参数:从你的 item 获取各个字段 + BigDecimal nastnum = new BigDecimal(item.getString("nastnum")); // 数量 + nastnum = nastnum.setScale(4, RoundingMode.HALF_UP); + BigDecimal nqtorigtaxprice = new BigDecimal(item.getString("nqtorigtaxprice")); // 含税单价 + nqtorigtaxprice = nqtorigtaxprice.setScale(4, RoundingMode.HALF_UP); + BigDecimal ntaxrate = new BigDecimal(item.getString("ntaxrate")).divide(new BigDecimal("100")); // 税率 + ntaxrate = ntaxrate.setScale(4, RoundingMode.HALF_UP); + + // 含税净价 + BigDecimal norigtaxnetprice = nqtorigtaxprice; + // 1. 计算价税合计(含税金额) + BigDecimal norigtaxmny = nastnum.multiply(norigtaxnetprice).setScale(2, RoundingMode.HALF_UP); + // 2. 计算折扣额 + BigDecimal discountAmount = nastnum.multiply(nqtorigtaxprice).subtract(norigtaxmny) + .setScale(4, RoundingMode.HALF_UP); + // 3. 计算税额(两种方法:应税外加税和应税内含税) + BigDecimal ntax = norigtaxmny.multiply(ntaxrate) + .divide(BigDecimal.ONE.add(ntaxrate), 2, RoundingMode.HALF_UP); // 应税外加税 + BigDecimal taxInclusiveInner = norigtaxmny.multiply(ntaxrate) + .setScale(4, RoundingMode.HALF_UP); // 应税内含税 + // 4. 计算无税金额 + BigDecimal norigmny = norigtaxmny.subtract(ntax).setScale(2, RoundingMode.HALF_UP); + // 4. 计算无税单价(nqtorigprice = 无税金额 / 数量) + BigDecimal nqtorigprice = norigmny.divide(nastnum, 4, RoundingMode.HALF_UP); + // 计税金额 = 无税金额 + BigDecimal ncaltaxmny = norigmny; + // 主含税单价(即含税单价) + BigDecimal norigtaxprice = nqtorigtaxprice.setScale(4, RoundingMode.HALF_UP); + // 主无税净价(即不含税单价) + BigDecimal norignetprice = nqtorigprice; + + // 从销售订单中获取币种 + String corigcurrencyid = getString_TrimAsNull(value2.get("corigcurrencyid")); + otherJson.put("corigcurrencyid", "".equals(corigcurrencyid) ? "CNY" : corigcurrencyid); + // 从销售订单中获取折本汇率 + BigDecimal nexchangerate = getUFDouble_NullAsZero(value2.get("nexchangerate")).toBigDecimal(); + otherJson.put("nexchangerate", nexchangerate); + // 单价和金额*汇率 + nqtorigprice = nqtorigprice.multiply(nexchangerate); + norigmny = norigmny.multiply(nexchangerate); + norigtaxmny = norigtaxmny.multiply(nexchangerate); + norigtaxprice = norigtaxprice.multiply(nexchangerate); + norignetprice = norignetprice.multiply(nexchangerate); + nqtorigtaxprice = nqtorigtaxprice.multiply(nexchangerate); + norigtaxnetprice = norigtaxnetprice.multiply(nexchangerate); + + + itemDetails.put("nqtorigprice", nqtorigprice);// 无税单价 + itemDetails.put("norigprice", nqtorigprice);// 主无税单价 + itemDetails.put("norigmny", norigmny);// 无税金额 + itemDetails.put("nmny", norigmny);// 本币无税金额 + itemDetails.put("norigtaxmny", norigtaxmny);// 价税合计 + itemDetails.put("norigtaxprice", norigtaxprice);// 主含税单价 + itemDetails.put("norignetprice", norignetprice);// 主无税净价 + itemDetails.put("nqtorigtaxprice", nqtorigtaxprice);// 含税单价 + itemDetails.put("ntax", ntax);// 税额 + itemDetails.put("ncaltaxmny", ncaltaxmny);// 计税金额 + itemDetails.put("norigtaxnetprice", norigtaxnetprice);// 主含税净价 + itemDetails.put("nnetprice", norignetprice);// 主本币无税净价 + itemDetails.put("ntaxmny", norigtaxmny);// 本币价税合计 + csaleinvoicebid.add(itemDetails); + + + } + newItem.put("item", csaleinvoicebid); + billhead.put("csaleinvoicebid", newItem); + if (otherJson != null && !otherJson.isEmpty()) { + // 查询销售订单中的币种和汇率 + billhead.put("corigcurrencyid", otherJson.get("corigcurrencyid"));// 币种 + billhead.put("nexchangerate", otherJson.get("nexchangerate"));// 折本汇率 + } + bill.put("billhead", billhead); + bill.put("id", ""); + // 将 bill 数组添加到 ufinterface 中 + billArray.add(bill); + ufinterface.put("bill", billArray); + // 将 ufinterface 添加到最终的 resultJson 中 + resultJson.put("ufinterface", ufinterface); + return resultJson; + } catch (Exception e) { + return (JSONObject) ResultMessageUtil.exceptionToJSON(e); + } + } + + + // 方法:检查必填项并返回转化后的Map + public static String checkRequiredFields(JSONObject data) throws Exception { + String returnStr = ""; + // 2. 检查必填字段 pk_org + String pkOrg = (String) data.getOrDefault("pk_org", ""); + if (pkOrg.isEmpty()) { + return "字段pk_org缺失或为空!"; + } + // 2. 检查必填字段 pk_org + String vbillcode = (String) data.getOrDefault("vbillcode", ""); + if (vbillcode.isEmpty()) { + return "字段vbillcode缺失或为空!"; + } + return returnStr; + } + + private static String getTaxcode(String taxrateStr) throws BusinessException { + IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class); + String sql = + " select code FROM bd_taxrate tt inner join bd_taxcode tc on tt.pk_taxcode=tc.pk_taxcode where taxrate='" + + taxrateStr + "' AND ROWNUM = 1 "; + String taxcodeStr = (String) queryBS.executeQuery(sql, new ColumnProcessor()); + return taxcodeStr; + } + + private static Map getSaleorderVo(String csourcebillbidStr) throws BusinessException { + IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class); + String sql = " select s.vbillcode,s.csaleorderid,sb.csaleorderbid,sb.crowno,sb.blargessflag,sb.nexchangerate,s.corigcurrencyid from so_saleorder_b sb\n" + + "inner join so_saleorder s on sb.csaleorderid=s.csaleorderid\n" + + "where sb.csaleorderbid='" + csourcebillbidStr + "' "; + Map value2 = (Map) queryBS.executeQuery(sql, new MapProcessor()); + return value2; + } + + private static String getString_TrimAsNull(Object value) { + if ((value == null) || (value.toString().trim().isEmpty())) { + return ""; + } + return value.toString().trim(); + } + + private static UFDouble getUFDouble_NullAsZero(Object value) { + if ((value == null) || (value.toString().trim().isEmpty()) || (value.toString().trim().equals("~"))) + return UFDouble.ONE_DBL; + if ((value instanceof UFDouble)) + return (UFDouble) value; + if ((value instanceof BigDecimal)) { + return new UFDouble((BigDecimal) value); + } + return new UFDouble(value.toString().trim()); + } + + public IUAPQueryBS getQueryService() { + return NCLocator.getInstance().lookup(IUAPQueryBS.class); + } + +} \ No newline at end of file