销售发票接口代码合并,用2个Resource会提示:resource notfound,please check path

This commit is contained in:
mzr 2025-04-17 15:41:26 +08:00
parent 99abe02779
commit 6e7f80cab5
6 changed files with 722 additions and 835 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding='gb2312'?>
<module>
<rest>
<resource classname="nccloud.api.so.saleinvoice.operator.saveCommitAction" exinfo="根据销售订单号、业务单元生成销售发票、开票申请 "/>
<resource classname="nccloud.api.so.saleinvoice.operator.SaleInvResource" exinfo="销售发票相关接口"/>
</rest>
</module>

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding='gb2312'?>
<module>
<rest>
<resource classname="nccloud.api.so.saleinvoice.operator.BillSaveAction" exinfo="销售发票及其下游单据开票申请修改红冲逻辑"/>
</rest>
</module>

View File

@ -1,397 +0,0 @@
package nccloud.api.so.saleinvoice.operator;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.core.util.ObjectCreator;
import nc.bs.logging.Logger;
import nc.bs.trade.business.HYSuperDMO;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.MapProcessor;
import nc.pubitf.so.m32.api.ISaleinvoiceQueryAPI;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.calculator.HslParseUtil;
import nc.vo.pubapp.pattern.tool.performance.DeepCloneTool;
import nc.vo.scmpub.res.billtype.SOBillType;
import nc.vo.so.m32.entity.SaleInvoiceBVO;
import nc.vo.so.m32.entity.SaleInvoiceHVO;
import nc.vo.so.m32.entity.SaleInvoiceVO;
import nc.vo.sscivm.ivsale.IVApplicationAggVO;
import nc.vo.sscivm.ivsale.IVApplicationBodyVO;
import nc.vo.sscivm.ivsale.IVApplicationHeadVO;
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.commons.lang.StringUtils;
import nccloud.itf.sscivm.ivsale.impl.IVApplicationServiceImpl;
import nccloud.pubitf.riart.pflow.CloudPFlowContext;
import nccloud.pubitf.riart.pflow.ICloudScriptPFlowService;
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.util.List;
import java.util.Map;
/**
* 销售发票红冲接口
*
* @author lj
* @date 2025/03/14
* @update 20250415 mzr修改
*/
@Path("so/saleinvoice/operator")
public class BillSaveAction extends AbstractNCCRestResource {
public static String fplxStr = "";// 开票申请发票类型
public static DeepCloneTool deepCloneTool;
public static DeepCloneTool getCloneTool() {
if (deepCloneTool == null) {
deepCloneTool = new DeepCloneTool();
}
return deepCloneTool;
}
public BillSaveAction() {
}
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("/billSaveRp")
@Consumes({"application/json"})
@Produces({"application/json"})
public JSONString billSaveRp(JSONString json) throws Exception {
/**
* 销售发票红冲
* 1.根据bip传参中的销售发票主表id查询erp的销售发票VO
* 2.根据查询的销售发票VO生成红冲的销售发票
*/
JSONObject jobject = JSONObject.parseObject(json.toJSONString());
if (jobject == null) {
return ResultMessageUtil.exceptionToJSON(new NullPointerException("JSONString:null"));
}
JSONObject bject = jobject.getJSONObject("billhead");
if (bject == null) {
return ResultMessageUtil.exceptionToJSON(new NullPointerException("billhead:null"));
}
// 销售发票id
String csaleinvoiceid = bject.getString("vdef40");
// 根据销售发票主实体id查询销售发票
String[] ids = {csaleinvoiceid};
SaleInvoiceVO[] saleInvoiceVOs = NCLocator.getInstance().lookup(ISaleinvoiceQueryAPI.class)
.queryVOByIDs(ids);
if (saleInvoiceVOs == null || saleInvoiceVOs.length <= 0) {
return ResultMessageUtil.exceptionToJSON(new NullPointerException("未在系统中查询到对应的销售发票"));
}
try {
// 调用函数根据原销售发票组装新红冲发票
SaleInvoiceVO saleInvoiceRedRushVO = makeNewRedRushSaleInvoice(saleInvoiceVOs[0], bject);
// 生成红冲发票
ICloudScriptPFlowService flowService = NCLocator.getInstance().lookup(ICloudScriptPFlowService.class);
CloudPFlowContext context = new CloudPFlowContext();
context.setBillType("32");
context.setBillVos(new SaleInvoiceVO[]{saleInvoiceRedRushVO});
context.setActionName("WRITE");
SaleInvoiceVO[] returnSaveSaleInvoiceVOs = (SaleInvoiceVO[]) flowService.exeScriptPFlow(context);
Logger.error("=========================inv-save============== ");
if (returnSaveSaleInvoiceVOs != null && returnSaveSaleInvoiceVOs.length > 0) {
Logger.error("inv-save = " + JSONArray.toJSONString(returnSaveSaleInvoiceVOs));
// 生成红冲发票成功后执行销售发票审批动作
context.setBillType("32");
context.setBillVos(returnSaveSaleInvoiceVOs);
context.setActionName("APPROVE");
SaleInvoiceVO[] returnApproveSaleInvoiceVOs = (SaleInvoiceVO[]) flowService.exeScriptPFlow(context);
if (returnApproveSaleInvoiceVOs == null || returnApproveSaleInvoiceVOs.length <= 0) {
throw new BusinessException("生成销售发票审核失败");
}
Logger.error("=========================inv-audit============== ");
Logger.error("inv-audit = " + JSONArray.toJSONString(returnApproveSaleInvoiceVOs));
/**
* 开票申请红冲逻辑
* 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, returnApproveSaleInvoiceVOs);
// 生成红冲的开票申请
IVApplicationServiceImpl serviceImpl = new IVApplicationServiceImpl();
IVApplicationAggVO returnSaveIVApplicationAggVO = serviceImpl.save(iVApplicationAggVO);
if (returnSaveIVApplicationAggVO != null) {
return ResultMessageUtil.toJSON(returnApproveSaleInvoiceVOs, "接口调用成功");
} else {
Exception e = new Exception("接口调用失败");
return ResultMessageUtil.exceptionToJSON(e);
}
} else {
Exception e = new Exception("接口调用失败");
return ResultMessageUtil.exceptionToJSON(e);
}
} catch (Exception e) {
Logger.error("billSaveRp-exp: ", e);
return ResultMessageUtil.exceptionToJSON(e);
}
}
/**
* 构造红冲发票VO
*
* @param originalVO
* @param bject
* @return
* @throws Exception
*/
public static SaleInvoiceVO makeNewRedRushSaleInvoice(SaleInvoiceVO originalVO, JSONObject bject) throws Exception {
try {
SaleInvoiceVO saleInvoiceVO = new SaleInvoiceVO();
// 发票主实体
SaleInvoiceHVO saleInvoiceHVO = originalVO.getParentVO();
// 发票子实体数组
SaleInvoiceBVO[] saleInvoiceBVOs = originalVO.getChildrenVO();
// 发票新主实体
SaleInvoiceHVO newSaleInvoiceHVO = new SaleInvoiceHVO();
// 单据日期
UFDate dbilldate = new UFDate(bject.getString("dbilldate"));
// 制单日期
UFDate dmakedate = new UFDate(bject.getString("creationtime"));
// 子实体属性赋值
UFDouble sumNum = new UFDouble(); // 合计数量
UFDouble sumNtax = new UFDouble(); // 合计税额
UFDouble sumNcaltaxmny = new UFDouble(); // 合计计税金额
UFDouble sumNorigmny = new UFDouble(); // 合计无税金额
UFDouble sumNorigtaxmny = new UFDouble(); // 合计价税合计
int i = 0;
// 参数子实体数组
com.alibaba.fastjson.JSONArray bvoJsonArr = (com.alibaba.fastjson.JSONArray) bject.get("csaleinvoicebid");
List<JSONObject> bvoList = bvoJsonArr.toJavaList(JSONObject.class);
SaleInvoiceBVO[] newSaleInvoiceBVOs = new SaleInvoiceBVO[bvoList.size()]; // 新子实体
for (SaleInvoiceBVO saleInvoiceBVO : saleInvoiceBVOs) {
String csaleinvoicebid = saleInvoiceBVO.getCsaleinvoicebid(); // 子表id
// 筛选参数红冲的子表集合
List<JSONObject> newBvoArr = bvoList.stream().filter(item -> {
String parCsaleinvoicebid = item.getString("vbdef15") + ""; // 子表id
return csaleinvoicebid.equals(parCsaleinvoicebid);
}).toList();
if (newBvoArr.size() <= 0) {
continue;
}
JSONObject bipBvoJson = newBvoArr.get(0); // 参数子表
SaleInvoiceBVO newInvBVO = new SaleInvoiceBVO();
// 克隆取值原子表销售发票
newInvBVO = (SaleInvoiceBVO) getCloneTool().deepClone(saleInvoiceBVO);
// 赋值之后修改子实体红冲时字段
newInvBVO.setCsaleinvoicebid(null); // 发票子实体id
newInvBVO.setDbilldate(dbilldate); // 开票日期
String vchangerate = "1/1"; // 换算率
Map<String, Object> soMap = getSaleOrderInfo(bipBvoJson.getString("csrcbid"));
if (soMap != null && StringUtils.isNotEmpty(soMap.getOrDefault("vchangerate", "") + "")) {
vchangerate = soMap.get("vchangerate") + ""; // 销售订单的换算率
}
newInvBVO.setVchangerate(vchangerate); // 换算率
UFDouble[] vchangerateNums = HslParseUtil.parseHsl(vchangerate);
UFDouble vchangerateNum = UFDouble.ONE_DBL;
if (null != vchangerateNums && vchangerateNums.length != 0) {
vchangerateNum = vchangerateNums[0].div(vchangerateNums[1]).setScale(2, 4);
}
// BIP合同平台的数量对应BIP2312的主数量BIP2312的 数量=主数量*换算关系
UFDouble nastnum = new UFDouble(bipBvoJson.getString("nastnum"));
newInvBVO.setNastnum(nastnum.multiply(vchangerateNum).setScale(2, 4)); // 数量
newInvBVO.setNnum(nastnum); // 主数量
newInvBVO.setNtax(new UFDouble(bipBvoJson.getString("ntax"))); // 税额
newInvBVO.setNmny(new UFDouble(bipBvoJson.getString("nmny"))); // 本币无税金额
newInvBVO.setNtaxmny(new UFDouble(bipBvoJson.getString("ntaxmny"))); // 本币价税合计
newInvBVO.setNcaltaxmny(new UFDouble(bipBvoJson.getString("ncaltaxmny"))); // 计税金额
newInvBVO.setNorigmny(new UFDouble(bipBvoJson.getString("norigmny"))); // 无税金额
newInvBVO.setNorigtaxmny(new UFDouble(bipBvoJson.getString("norigtaxmny"))); // 价税合计
newInvBVO.setCopposesrcbid(bipBvoJson.getString("vbdef15")); // 对冲来源子表id
newInvBVO.setNqtunitnum(null); // 报价数量
newInvBVO.setCsaleinvoiceid(null); // 发票关联主表id
newInvBVO.setNtotalcostnum(null); // 累计成本结算数量
newInvBVO.setNtotalincomemny(null); // 累计确认应收金额
newInvBVO.setNtotalincomenum(null); // 累计确认应收数量
newSaleInvoiceBVOs[i++] = newInvBVO;
sumNum = sumNum.add(new UFDouble(bipBvoJson.getString("nnum")));
sumNtax = sumNtax.add(new UFDouble(bipBvoJson.getString("ntax")));
sumNcaltaxmny = sumNcaltaxmny.add(new UFDouble(bipBvoJson.getString("ncaltaxmny")));
sumNorigmny = sumNorigmny.add(new UFDouble(bipBvoJson.getString("norigmny")));
sumNorigtaxmny = sumNorigtaxmny.add(new UFDouble(bipBvoJson.getString("norigtaxmny")));
}
// 克隆取值原子表销售发票
newSaleInvoiceHVO = (SaleInvoiceHVO) getCloneTool().deepClone(saleInvoiceHVO);
// 赋值之后修改主实体红冲时字段
newSaleInvoiceHVO.setCsaleinvoiceid(null); // 发票主实体id
newSaleInvoiceHVO.setVbillcode(null); // 发票号
newSaleInvoiceHVO.setDbilldate(dbilldate); // 开票日期
newSaleInvoiceHVO.setDmakedate(dmakedate); // 制单日期
newSaleInvoiceHVO.setBsubunitflag(UFBoolean.TRUE); // 冲抵标记
newSaleInvoiceHVO.setFopposeflag(2); // 对冲标记 2对冲生成
newSaleInvoiceHVO.setFstatusflag(1); // 单据状态 1自由态
newSaleInvoiceHVO.setNtotalastnum(null); // 总数量
newSaleInvoiceHVO.setNtotalorigsubmny(null); // 冲抵金额
newSaleInvoiceHVO.setNtotalorigmny(null); // 价税合计
newSaleInvoiceHVO.setVopposesrccode(saleInvoiceHVO.getVbillcode()); // 对冲来源发票号
newSaleInvoiceHVO.setCopposesrcid(saleInvoiceHVO.getCsaleinvoiceid()); // 对冲来源发票id
newSaleInvoiceHVO.setApprover(null); // 审批人
newSaleInvoiceHVO.setTaudittime(null); // 审批日期
// 组装VO
saleInvoiceVO.setParentVO(newSaleInvoiceHVO);
saleInvoiceVO.setChildrenVO(newSaleInvoiceBVOs);
return saleInvoiceVO;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
/**
* 构造红冲开票申请VO
*
* @param applyHeadVO 原开票申请主实体
* @param ivApplicationBodyVOS 原开票申请子实体
* @param bject bip参数
* @param returnApproveSaleInvoiceVOs 新生成的红冲销售发票实体
* @return
* @throws Exception
*/
public static IVApplicationAggVO makeNewRedRushIVApplicationAggVO(IVApplicationHeadVO applyHeadVO, IVApplicationBodyVO[] ivApplicationBodyVOS, JSONObject bject, SaleInvoiceVO[] returnApproveSaleInvoiceVOs) throws Exception {
try {
IVApplicationAggVO applicationAggVO = new IVApplicationAggVO();
IVApplicationHeadVO newivApplicationHeadVO = new IVApplicationHeadVO(); // 新主实体
// 取新生成红冲发票的主实体数据
String csaleinvoiceid = returnApproveSaleInvoiceVOs[0].getParentVO().getCsaleinvoiceid();
String[] ids = {csaleinvoiceid};
SaleInvoiceVO[] rpSaleInvoiceVOs = NCLocator.getInstance().lookup(ISaleinvoiceQueryAPI.class)
.queryVOByIDs(ids);
SaleInvoiceHVO rpSaleInvoiceHVO = rpSaleInvoiceVOs[0].getParentVO();
// 主实体属性赋值
// 克隆取值原子表开票申请
newivApplicationHeadVO = (IVApplicationHeadVO) getCloneTool().deepClone(applyHeadVO);
// 根据参数判断是否为部分红冲
boolean isPartHCFlag = false;
UFDouble paramNtotalorigmny = new UFDouble(bject.getString("ntotalorigmny")); // 参数价税合计主表红冲金额
UFDouble ntotalorigmny = applyHeadVO.getJshj(); // 原开票申请主表价税合计
// 红冲金额与开票申请源价税合计比较如果和值大于零则为部分红冲
if (ntotalorigmny.add(paramNtotalorigmny).compareTo(UFDouble.ZERO_DBL) > 0) {
isPartHCFlag = true;
}
UFDouble sumXmsl = new UFDouble(); // 合计数量
UFDouble sumXmje = new UFDouble(); // 合计金额
UFDouble sumXmjshj = new UFDouble(); // 合计价税合计
UFDouble sumBchcje = new UFDouble(); // 合计本次红冲金额
UFDouble sumSe = new UFDouble(); // 合计税额
// 子实体属性赋值
int i = 0;
// 参数子实体数组
com.alibaba.fastjson.JSONArray bvoJsonArr = (com.alibaba.fastjson.JSONArray) bject.get("csaleinvoicebid");
List<JSONObject> bvoList = bvoJsonArr.toJavaList(JSONObject.class);
IVApplicationBodyVO[] newivApplicationBodyVOS = new IVApplicationBodyVO[bvoList.size()]; // 新子实体
for (IVApplicationBodyVO ivApplicationBodyVO : ivApplicationBodyVOS) {
String src_pkdetail = ivApplicationBodyVO.getSrc_pkdetail(); // 来源单据行id
// 筛选参数红冲的子表集合
List<JSONObject> newBvoArr = bvoList.stream().filter(item -> {
String parCsaleinvoicebid = item.getString("vbdef15") + ""; // 子表id
return src_pkdetail.equals(parCsaleinvoicebid);
}).toList();
if (newBvoArr.size() <= 0) {
continue;
}
JSONObject bipBvoJson = newBvoArr.get(0); // 参数子表
IVApplicationBodyVO newivApplicationBodyVO = new IVApplicationBodyVO();
// BeanUtil.copyProperties(ivApplicationBodyVO,newivApplicationBodyVO, CopyOptions.create().setIgnoreNullValue(true));
// 克隆取值原子表开票申请
newivApplicationBodyVO = (IVApplicationBodyVO) getCloneTool().deepClone(ivApplicationBodyVO);
// 赋值之后修改子实体红冲时字段
newivApplicationBodyVO.setPk_ivappdetail(null); // 开票申请子实体id
newivApplicationBodyVO.setBillno(null); // 开票申请子实体单据号
newivApplicationBodyVO.setSe(new UFDouble(bipBvoJson.getString("ntax"))); // 税额
newivApplicationBodyVO.setXmsl(new UFDouble(bipBvoJson.getString("nnum"))); // 数量
newivApplicationBodyVO.setXmje(new UFDouble(bipBvoJson.getString("norigmny"))); // 金额
newivApplicationBodyVO.setXmjshj(new UFDouble(bipBvoJson.getString("norigtaxmny"))); // 价税合计
// 本次红冲金额 = 本次参数红冲金额
newivApplicationBodyVO.setBchcje(new UFDouble(bipBvoJson.getString("norigtaxmny")).multiply(new UFDouble(-1)));
newivApplicationBodyVOS[i++] = newivApplicationBodyVO;
sumSe = sumSe.add(new UFDouble(bipBvoJson.getString("ntax")));
sumXmsl = sumXmsl.add(new UFDouble(bipBvoJson.getString("nnum")));
sumXmje = sumXmje.add(new UFDouble(bipBvoJson.getString("norigmny")));
sumXmjshj = sumXmjshj.add(new UFDouble(bipBvoJson.getString("norigtaxmny")));
sumBchcje = sumBchcje.add(new UFDouble(bipBvoJson.getString("norigtaxmny")).multiply(new UFDouble(-1)));
}
// 赋值之后修改主实体红冲时字段
newivApplicationHeadVO.setPk_ivapplication(null); // 开票申请单主实体id
newivApplicationHeadVO.setBillno(null); // 单据号
newivApplicationHeadVO.setPreparedate(new UFDate(bject.getString("dbilldate"))); // 单据日期
newivApplicationHeadVO.setJshj(sumXmjshj); // 价税合计
newivApplicationHeadVO.setHjje(sumXmje); // 合计金额
newivApplicationHeadVO.setHjse(sumSe); // 合计税额
newivApplicationHeadVO.setBchcje(sumBchcje); // 本次红冲金额
newivApplicationHeadVO.setHzfp(UFBoolean.TRUE); // 红字发票
newivApplicationHeadVO.setSrc_billtype(SOBillType.Invoice.getCode()); // 来源单据类型
newivApplicationHeadVO.setSrc_tradetype(rpSaleInvoiceHVO.getCtrantypeid()); // 来源交易类型
newivApplicationHeadVO.setTranstypecode(rpSaleInvoiceHVO.getVtrantypecode()); // 来源交易类型编码
newivApplicationHeadVO.setSrc_pkbusibill(rpSaleInvoiceHVO.getCsaleinvoiceid()); // 来源单据id
newivApplicationHeadVO.setSrc_billno(rpSaleInvoiceHVO.getVbillcode()); // 来源单据编号
newivApplicationHeadVO.setHcyy("2"); // 红冲原因2开票有误
// 组装VO
applicationAggVO.setParentVO(newivApplicationHeadVO);
applicationAggVO.setChildrenVO(newivApplicationBodyVOS);
return applicationAggVO;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
public IUAPQueryBS getQueryService() {
return NCLocator.getInstance().lookup(IUAPQueryBS.class);
}
private static Map<String, Object> getSaleOrderInfo(String csaleorderbid) throws BusinessException {
IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class);
String sql = " select s.vbillcode,s.csaleorderid, s.corigcurrencyid," +
" sb.csaleorderbid,sb.crowno,sb.blargessflag,sb.nexchangerate," +
" nvl(sb.vchangerate, '1/1') vchangerate, bdc.code currencycode" +
" from so_saleorder_b sb" +
" inner join so_saleorder s on sb.csaleorderid=s.csaleorderid" +
" left join bd_currtype bdc on s.corigcurrencyid=bdc.pk_currtype" +
" where sb.csaleorderbid='" + csaleorderbid + "' ";
return (Map<String, Object>) queryBS.executeQuery(sql, new MapProcessor());
}
}

View File

@ -0,0 +1,645 @@
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.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;
import nc.pubitf.so.m32.api.ISaleinvoiceQueryAPI;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.calculator.HslParseUtil;
import nc.vo.pubapp.pattern.model.entity.bill.AbstractBill;
import nc.vo.pubapp.pattern.tool.performance.DeepCloneTool;
import nc.vo.pubapp.pflow.PfUserObject;
import nc.vo.scmpub.res.billtype.SOBillType;
import nc.vo.so.m32.entity.SaleInvoiceBVO;
import nc.vo.so.m32.entity.SaleInvoiceHVO;
import nc.vo.so.m32.entity.SaleInvoiceVO;
import nc.vo.sscivm.ivsale.IVApplicationAggVO;
import nc.vo.sscivm.ivsale.IVApplicationBodyVO;
import nc.vo.sscivm.ivsale.IVApplicationHeadVO;
import nccloud.api.baseapp.exchange.convert.OpenApiConvertDataObject;
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.pubitf.riart.pflow.CloudPFlowContext;
import nccloud.pubitf.riart.pflow.ICloudScriptPFlowService;
import nccloud.pubitf.scmpub.commit.service.IBatchRunScriptService;
import nccloud.pubitf.scmpub.ssc.service.ISSCService;
import nccloud.pubitf.so.saleinvoice.service.ISaleInvoiceToTaxInvService;
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;
public class IAPISaleInvMaitainImpl {
public static String fplxStr = "";// 开票申请发票类型
public static DeepCloneTool deepCloneTool;
public static DeepCloneTool getCloneTool() {
if (deepCloneTool == null) {
deepCloneTool = new DeepCloneTool();
}
return deepCloneTool;
}
public JSONString saveBlue(JSONObject jobject) throws Exception {
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);
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.isEmpty()) {
// 提取 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()), ISSClientageMatchService.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);
// 销售发票审核结束
ISaleInvoiceToTaxInvService invoiceService = NCLocator.getInstance()
.lookup(ISaleInvoiceToTaxInvService.class);
// 数电票(增值税专用发票)=31,数电票(普通发票)=32,数电纸质发票(机动车销售统一发票)=36,数电纸质发票(增值税专用发票)=33,数电纸质发票(普通发票)=34,
// 增值税电子普通发票=1,增值税电子专用发票=2,增值税普通发票=3,增值税专用发票=4,增值税电子普通发票成品油=8,成品油普通发票(卷式)=9,
// 成品油普通发票=10,成品油专用发票=11,增值税普通发票(卷式)=12,增值税专用发票(机动车)=99
invoiceService.issueTaxInvoice(saleInvoiceVO, fplxStr);
JSONObject desc = r.getDesc();
if (desc != null) {
// 发票的全部信息都返回给合同平台
desc.put("vos", saleInvoiceVO);
}
return ResultMessageUtil.toJSON(desc, "0");
} else {
Exception e = new NullPointerException(
"billtype:" + billtype + ",account:" + account + ",groupcode:" + groupcode);
return ResultMessageUtil.exceptionToJSON(e);
}
}
public JSONString saveRed(JSONObject jobject) throws Exception {
/**
* 销售发票红冲
* 1.根据bip传参中的销售发票主表id查询erp的销售发票VO
* 2.根据查询的销售发票VO生成红冲的销售发票
*/
JSONObject bject = jobject.getJSONObject("billhead");
if (bject == null) {
return ResultMessageUtil.exceptionToJSON(new NullPointerException("billhead:null"));
}
// 销售发票id
String csaleinvoiceid = bject.getString("vdef40");
// 根据销售发票主实体id查询销售发票
String[] ids = {csaleinvoiceid};
SaleInvoiceVO[] saleInvoiceVOs = NCLocator.getInstance().lookup(ISaleinvoiceQueryAPI.class)
.queryVOByIDs(ids);
if (saleInvoiceVOs == null || saleInvoiceVOs.length <= 0) {
return ResultMessageUtil.exceptionToJSON(new NullPointerException("未在系统中查询到对应的销售发票"));
}
// 调用函数根据原销售发票组装新红冲发票
SaleInvoiceVO saleInvoiceRedRushVO = makeNewRedRushSaleInvoice(saleInvoiceVOs[0], bject);
// 生成红冲发票
ICloudScriptPFlowService flowService = NCLocator.getInstance().lookup(ICloudScriptPFlowService.class);
CloudPFlowContext context = new CloudPFlowContext();
context.setBillType("32");
context.setBillVos(new SaleInvoiceVO[]{saleInvoiceRedRushVO});
context.setActionName("WRITE");
SaleInvoiceVO[] returnSaveSaleInvoiceVOs = (SaleInvoiceVO[]) flowService.exeScriptPFlow(context);
Logger.error("=========================inv-save============== ");
if (returnSaveSaleInvoiceVOs != null && returnSaveSaleInvoiceVOs.length > 0) {
Logger.error("inv-save = " + JSONArray.toJSONString(returnSaveSaleInvoiceVOs));
// 生成红冲发票成功后执行销售发票审批动作
context.setBillType("32");
context.setBillVos(returnSaveSaleInvoiceVOs);
context.setActionName("APPROVE");
SaleInvoiceVO[] returnApproveSaleInvoiceVOs = (SaleInvoiceVO[]) flowService.exeScriptPFlow(context);
if (returnApproveSaleInvoiceVOs == null || returnApproveSaleInvoiceVOs.length <= 0) {
throw new BusinessException("生成销售发票审核失败");
}
Logger.error("=========================inv-audit============== ");
Logger.error("inv-audit = " + JSONArray.toJSONString(returnApproveSaleInvoiceVOs));
/**
* 开票申请红冲逻辑
* 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, returnApproveSaleInvoiceVOs);
// 生成红冲的开票申请
IVApplicationServiceImpl serviceImpl = new IVApplicationServiceImpl();
IVApplicationAggVO returnSaveIVApplicationAggVO = serviceImpl.save(iVApplicationAggVO);
if (returnSaveIVApplicationAggVO != null) {
return ResultMessageUtil.toJSON(returnApproveSaleInvoiceVOs, "接口调用成功");
} else {
Exception e = new Exception("接口调用失败");
return ResultMessageUtil.exceptionToJSON(e);
}
} else {
Exception e = new Exception("接口调用失败");
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<String, Object> 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"));// 主单位
itemDetails.put("vchangerate", value2.getOrDefault("vchangerate", "1/1") + "");// 换算率
// 从销售订单中获取币种
String currencycode = getString_TrimAsNull(value2.get("currencycode"));
otherJson.put("corigcurrencyid", currencycode.isEmpty() ? "CNY" : currencycode);
// 从销售订单中获取折本汇率
BigDecimal nexchangerate = getUFDouble_NullAsZero(value2.get("nexchangerate")).toBigDecimal();
otherJson.put("nexchangerate", nexchangerate);
// 输入参数从你的 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;
// 本币(人民币)需要处理汇率金额保留两位小数单价保留4位小数
// 本币无税金额
BigDecimal nmny = norigmny.multiply(nexchangerate).setScale(2, RoundingMode.HALF_UP);
// 主本币无税净价
BigDecimal nnetprice = norignetprice.multiply(nexchangerate).setScale(4, RoundingMode.HALF_UP);
// 本币价税合计 价税合计*汇率
BigDecimal ntaxmny = norigtaxmny.multiply(nexchangerate).setScale(2, RoundingMode.HALF_UP);
// 税额
ntax = ntaxmny.subtract(nmny).setScale(2, RoundingMode.HALF_UP);
itemDetails.put("nqtorigprice", nqtorigprice);// 无税单价
itemDetails.put("norigprice", nqtorigprice);// 主无税单价
itemDetails.put("norigmny", norigmny);// 无税金额
itemDetails.put("nmny", nmny);// 本币无税金额
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", nnetprice);// 主本币无税净价
itemDetails.put("ntaxmny", ntaxmny);// 本币价税合计
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);
}
}
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<String, Object> getSaleorderVo(String csourcebillbidStr) throws BusinessException {
IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class);
String sql = " select s.vbillcode,s.csaleorderid, s.corigcurrencyid," +
" sb.csaleorderbid,sb.crowno,sb.blargessflag,sb.nexchangerate,sb.vchangerate," +
" bdc.code currencycode" +
" from so_saleorder_b sb" +
" inner join so_saleorder s on sb.csaleorderid=s.csaleorderid" +
" left join bd_currtype bdc on s.corigcurrencyid=bdc.pk_currtype" +
" where sb.csaleorderbid='" + csourcebillbidStr + "' ";
Map<String, Object> value2 = (Map<String, Object>) 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());
}
/**
* 构造红冲发票VO
*
* @param originalVO
* @param bject
* @return
* @throws Exception
*/
public static SaleInvoiceVO makeNewRedRushSaleInvoice(SaleInvoiceVO originalVO, JSONObject bject) throws Exception {
try {
SaleInvoiceVO saleInvoiceVO = new SaleInvoiceVO();
// 发票主实体
SaleInvoiceHVO saleInvoiceHVO = originalVO.getParentVO();
// 发票子实体数组
SaleInvoiceBVO[] saleInvoiceBVOs = originalVO.getChildrenVO();
// 发票新主实体
SaleInvoiceHVO newSaleInvoiceHVO = new SaleInvoiceHVO();
// 单据日期
UFDate dbilldate = new UFDate(bject.getString("dbilldate"));
// 制单日期
UFDate dmakedate = new UFDate(bject.getString("creationtime"));
// 子实体属性赋值
UFDouble sumNum = new UFDouble(); // 合计数量
UFDouble sumNtax = new UFDouble(); // 合计税额
UFDouble sumNcaltaxmny = new UFDouble(); // 合计计税金额
UFDouble sumNorigmny = new UFDouble(); // 合计无税金额
UFDouble sumNorigtaxmny = new UFDouble(); // 合计价税合计
int i = 0;
// 参数子实体数组
com.alibaba.fastjson.JSONArray bvoJsonArr = (com.alibaba.fastjson.JSONArray) bject.get("csaleinvoicebid");
List<JSONObject> bvoList = bvoJsonArr.toJavaList(JSONObject.class);
SaleInvoiceBVO[] newSaleInvoiceBVOs = new SaleInvoiceBVO[bvoList.size()]; // 新子实体
for (SaleInvoiceBVO saleInvoiceBVO : saleInvoiceBVOs) {
String csaleinvoicebid = saleInvoiceBVO.getCsaleinvoicebid(); // 子表id
// 筛选参数红冲的子表集合
List<JSONObject> newBvoArr = bvoList.stream().filter(item -> {
String parCsaleinvoicebid = item.getString("vbdef15") + ""; // 子表id
return csaleinvoicebid.equals(parCsaleinvoicebid);
}).toList();
if (newBvoArr.size() <= 0) {
continue;
}
JSONObject bipBvoJson = newBvoArr.get(0); // 参数子表
SaleInvoiceBVO newInvBVO = new SaleInvoiceBVO();
// 克隆取值原子表销售发票
newInvBVO = (SaleInvoiceBVO) getCloneTool().deepClone(saleInvoiceBVO);
// 赋值之后修改子实体红冲时字段
newInvBVO.setCsaleinvoicebid(null); // 发票子实体id
newInvBVO.setDbilldate(dbilldate); // 开票日期
String vchangerate = "1/1"; // 换算率
Map<String, Object> soMap = getSaleOrderInfo(bipBvoJson.getString("csrcbid"));
if (soMap != null && StringUtils.isNotEmpty(soMap.getOrDefault("vchangerate", "") + "")) {
vchangerate = soMap.get("vchangerate") + ""; // 销售订单的换算率
}
newInvBVO.setVchangerate(vchangerate); // 换算率
UFDouble[] vchangerateNums = HslParseUtil.parseHsl(vchangerate);
UFDouble vchangerateNum = UFDouble.ONE_DBL;
if (null != vchangerateNums && vchangerateNums.length != 0) {
vchangerateNum = vchangerateNums[0].div(vchangerateNums[1]).setScale(2, 4);
}
// BIP合同平台的数量对应BIP2312的主数量BIP2312的 数量=主数量*换算关系
UFDouble nastnum = new UFDouble(bipBvoJson.getString("nastnum"));
newInvBVO.setNastnum(nastnum.multiply(vchangerateNum).setScale(2, 4)); // 数量
newInvBVO.setNnum(nastnum); // 主数量
newInvBVO.setNtax(new UFDouble(bipBvoJson.getString("ntax"))); // 税额
newInvBVO.setNmny(new UFDouble(bipBvoJson.getString("nmny"))); // 本币无税金额
newInvBVO.setNtaxmny(new UFDouble(bipBvoJson.getString("ntaxmny"))); // 本币价税合计
newInvBVO.setNcaltaxmny(new UFDouble(bipBvoJson.getString("ncaltaxmny"))); // 计税金额
newInvBVO.setNorigmny(new UFDouble(bipBvoJson.getString("norigmny"))); // 无税金额
newInvBVO.setNorigtaxmny(new UFDouble(bipBvoJson.getString("norigtaxmny"))); // 价税合计
newInvBVO.setCopposesrcbid(bipBvoJson.getString("vbdef15")); // 对冲来源子表id
newInvBVO.setNqtunitnum(null); // 报价数量
newInvBVO.setCsaleinvoiceid(null); // 发票关联主表id
newInvBVO.setNtotalcostnum(null); // 累计成本结算数量
newInvBVO.setNtotalincomemny(null); // 累计确认应收金额
newInvBVO.setNtotalincomenum(null); // 累计确认应收数量
newSaleInvoiceBVOs[i++] = newInvBVO;
sumNum = sumNum.add(new UFDouble(bipBvoJson.getString("nnum")));
sumNtax = sumNtax.add(new UFDouble(bipBvoJson.getString("ntax")));
sumNcaltaxmny = sumNcaltaxmny.add(new UFDouble(bipBvoJson.getString("ncaltaxmny")));
sumNorigmny = sumNorigmny.add(new UFDouble(bipBvoJson.getString("norigmny")));
sumNorigtaxmny = sumNorigtaxmny.add(new UFDouble(bipBvoJson.getString("norigtaxmny")));
}
// 克隆取值原子表销售发票
newSaleInvoiceHVO = (SaleInvoiceHVO) getCloneTool().deepClone(saleInvoiceHVO);
// 赋值之后修改主实体红冲时字段
newSaleInvoiceHVO.setCsaleinvoiceid(null); // 发票主实体id
newSaleInvoiceHVO.setVbillcode(null); // 发票号
newSaleInvoiceHVO.setDbilldate(dbilldate); // 开票日期
newSaleInvoiceHVO.setDmakedate(dmakedate); // 制单日期
newSaleInvoiceHVO.setBsubunitflag(UFBoolean.TRUE); // 冲抵标记
newSaleInvoiceHVO.setFopposeflag(2); // 对冲标记 2对冲生成
newSaleInvoiceHVO.setFstatusflag(1); // 单据状态 1自由态
newSaleInvoiceHVO.setNtotalastnum(null); // 总数量
newSaleInvoiceHVO.setNtotalorigsubmny(null); // 冲抵金额
newSaleInvoiceHVO.setNtotalorigmny(null); // 价税合计
newSaleInvoiceHVO.setVopposesrccode(saleInvoiceHVO.getVbillcode()); // 对冲来源发票号
newSaleInvoiceHVO.setCopposesrcid(saleInvoiceHVO.getCsaleinvoiceid()); // 对冲来源发票id
newSaleInvoiceHVO.setApprover(null); // 审批人
newSaleInvoiceHVO.setTaudittime(null); // 审批日期
// 组装VO
saleInvoiceVO.setParentVO(newSaleInvoiceHVO);
saleInvoiceVO.setChildrenVO(newSaleInvoiceBVOs);
return saleInvoiceVO;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
/**
* 构造红冲开票申请VO
*
* @param applyHeadVO 原开票申请主实体
* @param ivApplicationBodyVOS 原开票申请子实体
* @param bject bip参数
* @param returnApproveSaleInvoiceVOs 新生成的红冲销售发票实体
* @return
* @throws Exception
*/
public static IVApplicationAggVO makeNewRedRushIVApplicationAggVO(IVApplicationHeadVO applyHeadVO, IVApplicationBodyVO[] ivApplicationBodyVOS, JSONObject bject, SaleInvoiceVO[] returnApproveSaleInvoiceVOs) throws Exception {
try {
IVApplicationAggVO applicationAggVO = new IVApplicationAggVO();
IVApplicationHeadVO newivApplicationHeadVO = new IVApplicationHeadVO(); // 新主实体
// 取新生成红冲发票的主实体数据
String csaleinvoiceid = returnApproveSaleInvoiceVOs[0].getParentVO().getCsaleinvoiceid();
String[] ids = {csaleinvoiceid};
SaleInvoiceVO[] rpSaleInvoiceVOs = NCLocator.getInstance().lookup(ISaleinvoiceQueryAPI.class)
.queryVOByIDs(ids);
SaleInvoiceHVO rpSaleInvoiceHVO = rpSaleInvoiceVOs[0].getParentVO();
// 主实体属性赋值
// 克隆取值原子表开票申请
newivApplicationHeadVO = (IVApplicationHeadVO) getCloneTool().deepClone(applyHeadVO);
// 根据参数判断是否为部分红冲
boolean isPartHCFlag = false;
UFDouble paramNtotalorigmny = new UFDouble(bject.getString("ntotalorigmny")); // 参数价税合计主表红冲金额
UFDouble ntotalorigmny = applyHeadVO.getJshj(); // 原开票申请主表价税合计
// 红冲金额与开票申请源价税合计比较如果和值大于零则为部分红冲
if (ntotalorigmny.add(paramNtotalorigmny).compareTo(UFDouble.ZERO_DBL) > 0) {
isPartHCFlag = true;
}
UFDouble sumXmsl = new UFDouble(); // 合计数量
UFDouble sumXmje = new UFDouble(); // 合计金额
UFDouble sumXmjshj = new UFDouble(); // 合计价税合计
UFDouble sumBchcje = new UFDouble(); // 合计本次红冲金额
UFDouble sumSe = new UFDouble(); // 合计税额
// 子实体属性赋值
int i = 0;
// 参数子实体数组
com.alibaba.fastjson.JSONArray bvoJsonArr = (com.alibaba.fastjson.JSONArray) bject.get("csaleinvoicebid");
List<JSONObject> bvoList = bvoJsonArr.toJavaList(JSONObject.class);
IVApplicationBodyVO[] newivApplicationBodyVOS = new IVApplicationBodyVO[bvoList.size()]; // 新子实体
for (IVApplicationBodyVO ivApplicationBodyVO : ivApplicationBodyVOS) {
String src_pkdetail = ivApplicationBodyVO.getSrc_pkdetail(); // 来源单据行id
// 筛选参数红冲的子表集合
List<JSONObject> newBvoArr = bvoList.stream().filter(item -> {
String parCsaleinvoicebid = item.getString("vbdef15") + ""; // 子表id
return src_pkdetail.equals(parCsaleinvoicebid);
}).toList();
if (newBvoArr.size() <= 0) {
continue;
}
JSONObject bipBvoJson = newBvoArr.get(0); // 参数子表
IVApplicationBodyVO newivApplicationBodyVO = new IVApplicationBodyVO();
// BeanUtil.copyProperties(ivApplicationBodyVO,newivApplicationBodyVO, CopyOptions.create().setIgnoreNullValue(true));
// 克隆取值原子表开票申请
newivApplicationBodyVO = (IVApplicationBodyVO) getCloneTool().deepClone(ivApplicationBodyVO);
// 赋值之后修改子实体红冲时字段
newivApplicationBodyVO.setPk_ivappdetail(null); // 开票申请子实体id
newivApplicationBodyVO.setBillno(null); // 开票申请子实体单据号
newivApplicationBodyVO.setSe(new UFDouble(bipBvoJson.getString("ntax"))); // 税额
newivApplicationBodyVO.setXmsl(new UFDouble(bipBvoJson.getString("nnum"))); // 数量
newivApplicationBodyVO.setXmje(new UFDouble(bipBvoJson.getString("norigmny"))); // 金额
newivApplicationBodyVO.setXmjshj(new UFDouble(bipBvoJson.getString("norigtaxmny"))); // 价税合计
// 本次红冲金额 = 本次参数红冲金额
newivApplicationBodyVO.setBchcje(new UFDouble(bipBvoJson.getString("norigtaxmny")).multiply(new UFDouble(-1)));
newivApplicationBodyVOS[i++] = newivApplicationBodyVO;
sumSe = sumSe.add(new UFDouble(bipBvoJson.getString("ntax")));
sumXmsl = sumXmsl.add(new UFDouble(bipBvoJson.getString("nnum")));
sumXmje = sumXmje.add(new UFDouble(bipBvoJson.getString("norigmny")));
sumXmjshj = sumXmjshj.add(new UFDouble(bipBvoJson.getString("norigtaxmny")));
sumBchcje = sumBchcje.add(new UFDouble(bipBvoJson.getString("norigtaxmny")).multiply(new UFDouble(-1)));
}
// 赋值之后修改主实体红冲时字段
newivApplicationHeadVO.setPk_ivapplication(null); // 开票申请单主实体id
newivApplicationHeadVO.setBillno(null); // 单据号
newivApplicationHeadVO.setPreparedate(new UFDate(bject.getString("dbilldate"))); // 单据日期
newivApplicationHeadVO.setJshj(sumXmjshj); // 价税合计
newivApplicationHeadVO.setHjje(sumXmje); // 合计金额
newivApplicationHeadVO.setHjse(sumSe); // 合计税额
newivApplicationHeadVO.setBchcje(sumBchcje); // 本次红冲金额
newivApplicationHeadVO.setHzfp(UFBoolean.TRUE); // 红字发票
newivApplicationHeadVO.setSrc_billtype(SOBillType.Invoice.getCode()); // 来源单据类型
newivApplicationHeadVO.setSrc_tradetype(rpSaleInvoiceHVO.getCtrantypeid()); // 来源交易类型
newivApplicationHeadVO.setTranstypecode(rpSaleInvoiceHVO.getVtrantypecode()); // 来源交易类型编码
newivApplicationHeadVO.setSrc_pkbusibill(rpSaleInvoiceHVO.getCsaleinvoiceid()); // 来源单据id
newivApplicationHeadVO.setSrc_billno(rpSaleInvoiceHVO.getVbillcode()); // 来源单据编号
newivApplicationHeadVO.setHcyy("2"); // 红冲原因2开票有误
// 组装VO
applicationAggVO.setParentVO(newivApplicationHeadVO);
applicationAggVO.setChildrenVO(newivApplicationBodyVOS);
return applicationAggVO;
} catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
private static Map<String, Object> getSaleOrderInfo(String csaleorderbid) throws BusinessException {
IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class);
String sql = " select s.vbillcode,s.csaleorderid, s.corigcurrencyid," +
" sb.csaleorderbid,sb.crowno,sb.blargessflag,sb.nexchangerate," +
" nvl(sb.vchangerate, '1/1') vchangerate, bdc.code currencycode" +
" from so_saleorder_b sb" +
" inner join so_saleorder s on sb.csaleorderid=s.csaleorderid" +
" left join bd_currtype bdc on s.corigcurrencyid=bdc.pk_currtype" +
" where sb.csaleorderbid='" + csaleorderbid + "' ";
return (Map<String, Object>) queryBS.executeQuery(sql, new MapProcessor());
}
}

View File

@ -0,0 +1,76 @@
package nccloud.api.so.saleinvoice.operator;
import com.alibaba.fastjson.JSONObject;
import nc.bs.logging.Logger;
import nccloud.api.rest.utils.ResultMessageUtil;
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;
/**
* 销售发票接口适配2005代码
* zhangxinah
*/
@Path("so/saleinvoice/operator")
public class SaleInvResource extends AbstractNCCRestResource {
public SaleInvResource() {
}
@Override
public String getModule() {
return "so";
}
@POST
@Path("saveCommit")
@Consumes({"application/json"})
@Produces({"application/json"})
public JSONString saveCommit(JSONString json) {
try {
JSONObject jobject = JSONObject.parseObject(json.toJSONString());
if (jobject == null) {
return ResultMessageUtil.exceptionToJSON(new NullPointerException("JSONString:null"));
}
JSONObject bject = jobject.getJSONObject("billhead");
if (bject == null) {
return ResultMessageUtil.exceptionToJSON(new NullPointerException("billhead:null"));
}
IAPISaleInvMaitainImpl service = new IAPISaleInvMaitainImpl();
return service.saveBlue(jobject);
} catch (Exception e) {
Logger.error("saveCommit-exp: ", e);
return ResultMessageUtil.exceptionToJSON(e);
}
}
/**
* 销售发票红冲接口
*
* @author lj
* @date 2025/03/14
* @update 20250415 mzr修改
*/
@POST
@Path("billSaveRp")
@Consumes({"application/json"})
@Produces({"application/json"})
public JSONString billSaveRp(JSONString json) {
try {
JSONObject jobject = JSONObject.parseObject(json.toJSONString());
if (jobject == null) {
return ResultMessageUtil.exceptionToJSON(new NullPointerException("JSONString:null"));
}
IAPISaleInvMaitainImpl service = new IAPISaleInvMaitainImpl();
return service.saveRed(jobject);
} catch (Exception e) {
Logger.error("billSaveRp-exp: ", e);
return ResultMessageUtil.exceptionToJSON(e);
}
}
}

View File

@ -1,431 +0,0 @@
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.pubitf.riart.pflow.CloudPFlowContext;
import nccloud.pubitf.scmpub.commit.service.IBatchRunScriptService;
import nccloud.pubitf.scmpub.ssc.service.ISSCService;
import nccloud.pubitf.so.saleinvoice.service.ISaleInvoiceToTaxInvService;
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;
/**
* 销售发票接口适配2005代码
* zhangxinah
*/
@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);
// 销售发票审核结束
ISaleInvoiceToTaxInvService invoiceService = NCLocator.getInstance()
.lookup(ISaleInvoiceToTaxInvService.class);
// 数电票(增值税专用发票)=31,数电票(普通发票)=32,数电纸质发票(机动车销售统一发票)=36,数电纸质发票(增值税专用发票)=33,数电纸质发票(普通发票)=34,
// 增值税电子普通发票=1,增值税电子专用发票=2,增值税普通发票=3,增值税专用发票=4,增值税电子普通发票成品油=8,成品油普通发票(卷式)=9,
// 成品油普通发票=10,成品油专用发票=11,增值税普通发票(卷式)=12,增值税专用发票(机动车)=99
invoiceService.issueTaxInvoice(saleInvoiceVO, fplxStr);
JSONObject desc = r.getDesc();
if (desc != null) {
// 发票的全部信息都返回给合同平台
desc.put("vos", saleInvoiceVO);
}
return ResultMessageUtil.toJSON(desc, "0");
} 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<String, Object> 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"));// 主单位
itemDetails.put("vchangerate", value2.getOrDefault("vchangerate", "1/1") + "");// 换算率
// 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;
// 从销售订单中获取币种
String currencycode = getString_TrimAsNull(value2.get("currencycode"));
otherJson.put("corigcurrencyid", currencycode.isEmpty() ? "CNY" : currencycode);
// 从销售订单中获取折本汇率
BigDecimal nexchangerate = getUFDouble_NullAsZero(value2.get("nexchangerate")).toBigDecimal();
otherJson.put("nexchangerate", nexchangerate);
// 输入参数从你的 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;
// 本币(人民币)需要处理汇率金额保留两位小数单价保留4位小数
// 本币无税金额
BigDecimal nmny = norigmny.multiply(nexchangerate).setScale(2, RoundingMode.HALF_UP);
// 主本币无税净价
BigDecimal nnetprice = norignetprice.multiply(nexchangerate).setScale(4, RoundingMode.HALF_UP);
// 本币价税合计 价税合计*汇率
BigDecimal ntaxmny = norigtaxmny.multiply(nexchangerate).setScale(2, RoundingMode.HALF_UP);
// 税额
ntax = ntaxmny.subtract(nmny).setScale(2, RoundingMode.HALF_UP);
itemDetails.put("nqtorigprice", nqtorigprice);// 无税单价
itemDetails.put("norigprice", nqtorigprice);// 主无税单价
itemDetails.put("norigmny", norigmny);// 无税金额
itemDetails.put("nmny", nmny);// 本币无税金额
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", nnetprice);// 主本币无税净价
itemDetails.put("ntaxmny", ntaxmny);// 本币价税合计
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<String, Object> getSaleorderVo(String csourcebillbidStr) throws BusinessException {
IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class);
String sql = " select s.vbillcode,s.csaleorderid, s.corigcurrencyid," +
" sb.csaleorderbid,sb.crowno,sb.blargessflag,sb.nexchangerate,sb.vchangerate," +
" bdc.code currencycode" +
" from so_saleorder_b sb" +
" inner join so_saleorder s on sb.csaleorderid=s.csaleorderid" +
" left join bd_currtype bdc on s.corigcurrencyid=bdc.pk_currtype" +
" where sb.csaleorderbid='" + csourcebillbidStr + "' ";
Map<String, Object> value2 = (Map<String, Object>) 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);
}
}