package com.api.aiyh_kafang.service; import aiyh.utils.Util; import aiyh.utils.sqlUtil.sqlResult.impl.BatchSqlResultImpl; import aiyh.utils.zwl.common.ToolUtil; import com.api.aiyh_kafang.dao.InvoiceMapping; import com.api.aiyh_kafang.entity.UfInvoiceConfigDTO; import com.engine.fna.util.FnaInvoiceUploadUtil; import com.sun.image.codec.jpeg.JPEGCodec; import com.weaver.general.TimeUtil; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache.commons.io.IOUtils; import org.h2.util.StringUtils; import weaver.conn.RecordSet; import weaver.file.ImageFileManager; import weaver.fna.invoice.utils.HttpUtil; import weaver.fna.invoice.utils.ImageUtil; import weaver.formmode.data.ModeDataIdUpdate; import weaver.formmode.setup.ModeRightInfo; import weaver.hrm.User; import javax.imageio.IIOException; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.*; /** * @author EBU7-dev1-ayh * @create 2021/11/2 0002 15:17 * 检查发票 */ public class InvoiceService { private final InvoiceMapping invoiceMapping = new InvoiceMapping(); private final ModeDataIdUpdate mdu = ModeDataIdUpdate.getInstance(); private final RecordSet rs = new RecordSet(); private final ToolUtil toolUtil = new ToolUtil(); private final String ModeTable = "uf_fpyzjb"; private final String ModeDetailTable = "uf_fpyzjb_dt1"; private final String ModeDetailTableErr = "uf_fpyzjb_dt3"; private String formModeId = "17"; private final String invoiceTable = "fnainvoiceledger"; public InvoiceService() { String formModeId = toolUtil.getSystemParamValue("formModeId"); if(!StringUtils.isNullOrEmpty(formModeId)){ this.formModeId = formModeId; } } /** * 查询发票信息,OCR识别 * * @param user * @param fileId * @return * @throws IOException */ public JSONObject getInvoiceInfo(User user, int fileId) throws Exception { // 方法一 /* InputStream inputStreamById = ImageFileManager.getInputStreamById(fileId); byte[] bytes; bytes = IOUtils.toByteArray(inputStreamById); JSONObject jsonObject = HttpUtil.postImage(bytes, user);*/ // 方法二 /* String fileData = FnaInvoiceUploadUtil.changeFileTobase64(fileId); byte[] imageBytes = ImageUtil.transformImage(fileData); JSONObject jsonObject = HttpUtil.postImage(imageBytes, user);*/ // 方法三 try { InputStream inputStreamById = ImageFileManager.getInputStreamById(fileId); BufferedImage imageBuffer = ImageIO.read(inputStreamById); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); boolean jpeg = ImageIO.write(imageBuffer, "jpeg", byteArrayOutputStream); if(!jpeg){ toolUtil.writeErrorLog("图片转化转化失败!"); } byte[] bytes = byteArrayOutputStream.toByteArray(); // toolUtil.writeErrorLog(jsonObject.toString()); return HttpUtil.postImage(bytes, user); }catch (IIOException e){ InputStream inputStreamById = ImageFileManager.getInputStreamById(fileId); BufferedImage imageBuffer = JPEGCodec.createJPEGDecoder(inputStreamById).decodeAsBufferedImage(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); boolean jpeg = ImageIO.write(imageBuffer, "jpeg", byteArrayOutputStream); if(!jpeg){ toolUtil.writeErrorLog("图片转化转化失败!"); } byte[] bytes = byteArrayOutputStream.toByteArray(); // toolUtil.writeErrorLog(jsonObject.toString()); return HttpUtil.postImage(bytes, user); } } /** * 对比合同信息 */ public Map contrastInvoiceInfo(Map params) { // 获取到流程表中的明细数据,对比建模表中的发票信息,查验数量是否一致以及发票的钱 // List fileIdList = (List) params.get("fileIdList"); String requestId = Util.null2String(params.get("requestId")); String workflowId = Util.null2String(params.get("workflowId")); // 查询建模表数据 String mainId = invoiceMapping.getMainId(requestId); List> modeData = invoiceMapping.selectModeInfo(mainId); // 查询配置表信息 UfInvoiceConfigDTO configInfo = invoiceMapping.getConfigInfo(workflowId); // 查询流程中的发票数据 List> workflowData = invoiceMapping.selectWorkflowData(workflowId, requestId, configInfo); // 对比合同信息,查询出相差的发票 List> priceNotEqual = new ArrayList<>(); List> workflowDataRm = new ArrayList<>(); List> modeDataRm = new ArrayList<>(); if (configInfo.getInvoiceBrowse() == 1) { // 属于浏览框 for (Map workflowDatum : workflowData) { String workflowCodeId = Util.null2String(workflowDatum.get(configInfo.getInvoiceField())); String workflowCode = ""; String workflowInvoicePrice = Util.null2String(workflowDatum.get(configInfo.getInvoicePrice())); try { workflowCode = invoiceMapping.getWorkflowCode(workflowCodeId, invoiceTable); workflowDatum.put(configInfo.getInvoiceField(),workflowCode); workflowDatum.put("fphm2",workflowCode); } catch (Exception e) { e.printStackTrace(); toolUtil.writeErrorLog("发票不存在:" + e); } for (Map modeDatum : modeData) { String modeCode = Util.null2String(modeDatum.get("fphm2")); String modePrice = Util.null2String(modeDatum.get("fpje")); if (workflowCode.equals(modeCode)) { // 发票号码相等,校验发票金额 if (!workflowInvoicePrice.equals(modePrice)) { // 金额不相等 // 添加校验失败数据到数组中 priceNotEqual.add(modeDatum); } // 求差集 workflowDataRm.add(workflowDatum); modeDataRm.add(modeDatum); break; } } } // 求差 // 建模表中多余的发票信息 modeData.removeAll(modeDataRm); // 流程中有但是建模表中没有的发票信息 workflowData.removeAll(workflowDataRm); } else { // 不属于浏览框 for (Map workflowDatum : workflowData) { String workflowCode = Util.null2String(workflowDatum.get(configInfo.getInvoiceField())); String workflowInvoicePrice = Util.null2String(workflowDatum.get(configInfo.getInvoicePrice())); for (Map modeDatum : modeData) { String modeCode = Util.null2String(modeDatum.get("fphm2")); String modePrice = Util.null2String(modeDatum.get("fpje")); if (workflowCode.equals(modeCode)) { // 发票号码相等,校验发票金额 if (!workflowInvoicePrice.equals(modePrice)) { // 金额不相等 // 添加校验失败数据到数组中 priceNotEqual.add(modeDatum); } // 求差集 workflowDataRm.add(workflowDatum); modeDataRm.add(modeDatum); break; } } } // 求差 // 建模表中多余的发票信息 modeData.removeAll(modeDataRm); // 流程中有但是建模表中没有的发票信息 workflowData.removeAll(workflowDataRm); } List> insertList = new ArrayList<>(); // 将价格不一样的数据保存到建模表明细3中,并标识错误原因为价格不一致 for (Map map : priceNotEqual) { LinkedHashMap data = new LinkedHashMap<>(); data.put("fphm1", map.get("fphm2")); data.put("sbyy","流程发票明细信息表中的发票与扫描识别发票的发票金额不一致!"); data.put("mainid", mainId); insertList.add(data); } // 将建模表多的发票保存到建模表明细3中,并标识错误原因为流程中不存在改发票信息 for (Map map : modeData) { LinkedHashMap data = new LinkedHashMap<>(); data.put("fphm1", map.get("fphm2")); data.put("sbyy", "流程中不存在该发票信息,但扫描发票中存在改发票!"); data.put("mainid", mainId); insertList.add(data); } // 将流程中多的发票保存到建模表明细3中,并标识错误原因为,扫描发票中不存在改发票信息 for (Map map : workflowData) { LinkedHashMap data = new LinkedHashMap<>(); data.put("fphm1", Util.null2String(map.get(configInfo.getInvoiceField()))); data.put("sbyy", "流程中存在改发票,但是扫描发票中没有发现该发票信息!"); data.put("mainid", mainId); insertList.add(data); } RecordSet rs = new RecordSet(); BatchSqlResultImpl batchSqlResult = Util.createSqlBuilder().insertBatchSql(ModeDetailTableErr, insertList); toolUtil.writeErrorLog("SQL:" + batchSqlResult.getSqlStr() + " ---->参数:" + batchSqlResult.getBatchList()); System.out.println("SQL:" + batchSqlResult.getSqlStr() + " ---->参数:" + batchSqlResult.getBatchList()); /* for (List list : batchSqlResult.getBatchList()) { rs.executeUpdate(batchSqlResult.getSqlStr(),list); }*/ try{ rs.executeBatchSql(batchSqlResult.getSqlStr(), batchSqlResult.getBatchList()); }catch(Exception e){ e.printStackTrace(); } Map result = new HashMap<>(); result.put("priceNotEqual", priceNotEqual); result.put("workflowData", workflowData); result.put("modeData", modeData); return result; } /** * 获取配置信息 * * @param workflowId * @return */ public UfInvoiceConfigDTO getConfigInfo(String workflowId) { return invoiceMapping.getConfigInfo(workflowId); } /** * 保存合同信息 * * @param invoiceInfo * @param requestId */ public void saveInvoiceInfo(JSONObject invoiceInfo, String requestId) { // TODO 查询是否已经存在,不存在则新增,存在则更新 String query = "select * from " + ModeTable + " where lc = ?"; rs.executeQuery(query, requestId); if (rs.next()) { // 存在,往明细表中添加数据 saveInvoiceDetail(invoiceInfo, requestId, rs.getString("id")); return; } // 添加主表数据,并且添加明细 int dataId = mdu.getModeDataNewId(ModeTable, Util.getIntValue(formModeId, -1), 1, 0, TimeUtil.getCurrentDateString(), TimeUtil.getOnlyCurrentTimeString()); // TODO 插入数据库信息 invoiceMapping.saveInvoiceInfo(dataId, ModeTable, requestId); saveInvoiceDetail(invoiceInfo, requestId, String.valueOf(dataId)); ModeRightInfo mri = new ModeRightInfo(); mri.rebuildModeDataShareByEdit(1, Util.getIntValue(formModeId, -1), dataId); } /** * 保存发票信息到建模明细表 * * @param invoiceInfo * @param requestId * @param mainId */ public void saveInvoiceDetail(JSONObject invoiceInfo, String requestId, String mainId) { String main = mainId; if (StringUtils.isNullOrEmpty(main)) { // 查询主表数据 String query = "select * from " + ModeTable + " where lc = ?"; rs.executeQuery(query, requestId); rs.next(); main = rs.getString("id"); } // 保存明细表数据 JSONObject returnInfo = (JSONObject) invoiceInfo.get("returnInfo"); toolUtil.writeErrorLog("returnInfo:" + returnInfo); if(returnInfo == null){ throw new RuntimeException("发票数据获取失败:" + invoiceInfo); } JSONObject response = (JSONObject) returnInfo.get("response"); JSONObject data = (JSONObject) response.get("data"); JSONArray identifyResults = (JSONArray) data.get("identify_results"); for (int i = 0; i < identifyResults.size(); i++) { JSONObject item = (JSONObject) identifyResults.get(i); JSONObject details = (JSONObject) item.get("details"); // 查询是否存在该发票,不存在则添加 if(invoiceMapping.selectExist(main,Util.null2String(details.get("number")))){ return; } // 明细表数据 Map insert = Util.createUtilHashMap() // 发票号码 .uPut("fphm2", details.get("number")) // 费用日期 .uPut("fyrq", details.get("date")) // 服务内容 .uPut("fwnr", details.get("item_names")) // 发票金额 .uPut("fpje", details.get("total")) .uPut("mainid", main); toolUtil.writeErrorLog("insert:" + insert); invoiceMapping.saveInvoiceDetail(insert, ModeDetailTable); } } }