diff --git a/pom.xml b/pom.xml index 5c1bb14a2..8dabbb902 100644 --- a/pom.xml +++ b/pom.xml @@ -219,6 +219,28 @@ org.projectlombok lombok + + + com.itextpdf + itextpdf + 5.5.13 + + + com.itextpdf.tool + xmlworker + 5.5.13 + + + com.itextpdf + itext-asian + 5.2.0 + + + org.xhtmlrenderer + flying-saucer-pdf + 9.0.3 + + diff --git a/src/main/java/au/com/royalpay/payment/manage/tradelog/core/impls/TradeLogServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/tradelog/core/impls/TradeLogServiceImpl.java index 8d06b70dc..07e2124c1 100644 --- a/src/main/java/au/com/royalpay/payment/manage/tradelog/core/impls/TradeLogServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/tradelog/core/impls/TradeLogServiceImpl.java @@ -60,6 +60,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.ui.Model; +import org.thymeleaf.context.Context; +import org.thymeleaf.spring5.SpringTemplateEngine; +import org.xhtmlrenderer.pdf.ITextFontResolver; +import org.xhtmlrenderer.pdf.ITextRenderer; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; @@ -130,6 +134,9 @@ public class TradeLogServiceImpl implements TradeLogService { @Resource private Locker locker; + @Resource + private SpringTemplateEngine thymeleaf; + // @Value("classpath:/jasper/trans_flow.jasper") // @Value("classpath:/jasper/trans_flow_new.jasper") @Value("classpath:/jasper/partner_invoice_gst.jasper") @@ -677,11 +684,89 @@ public class TradeLogServiceImpl implements TradeLogService { return "Credit".equals(log.getString("transaction_type")) || "Settlement".equals(log.getString("channel")) ? BigDecimal.ONE : BigDecimal.valueOf(-1); } + // @Override +// public void exportTransFlow(TradeLogQuery query, JSONObject partner, HttpServletResponse response) throws Exception { +// JSONObject transFlow = listPartnerTransFlow(query, partner); +// JSONObject analysis = transFlow.getJSONObject("analysis"); +// JSONObject client = clientManager.getClientInfo(partner.getIntValue("client_id")); +// if (!transFlow.getJSONArray("data").isEmpty()) { +// try { +// List dataList = transFlow.getJSONArray("data").toJavaList(JSONObject.class); +// JSONObject parmerters = new JSONObject(); +// parmerters.put("dateFrom", StringUtils.isNotBlank(query.getDatefrom()) +// ? DateFormatUtils.format(DateUtils.parseDate(query.getDatefrom(), "yyyyMMdd"), "dd/MM/yyyy") : ""); +// parmerters.put("dateTo", +// StringUtils.isNotBlank(query.getDateto()) +// ? DateFormatUtils.format(DateUtils.parseDate(query.getDateto(), "yyyyMMdd"), "dd/MM/yyyy") +// : DateFormatUtils.format(new Date(), "dd/MM/yyyy")); +// parmerters.put("dateRange", (StringUtils.isNotBlank(parmerters.getString("dateFrom")) ? parmerters.getString("dateFrom") : "") + "~" +// + parmerters.getString("dateTo")); +// parmerters.put("partnerCode", client.getString("client_moniker")); +// parmerters.put("clientName", client.getString("company_name")); +// parmerters.put("clientAddress", client.getString("address")); +// parmerters.put("balance", analysis.getDoubleValue("balance")); +// parmerters.put("logo", logo.getInputStream()); +// parmerters.put("actual_fee", takeDecimalOrDefault(analysis, "actual_fee", BigDecimal.ZERO)); +// parmerters.put("totalSettledAmount", takeDecimalOrDefault(analysis, "total_settle_amount", BigDecimal.ZERO)); +// parmerters.put("royalpay_charge", takeDecimalOrDefault(analysis, "total_royal_surcharge", BigDecimal.ZERO)); +// parmerters.put("total_fee", takeDecimalOrDefault(analysis, "total_surcharge", BigDecimal.ZERO)); +// parmerters.put("alipay_fee", takeDecimalOrDefault(analysis, "alipay_fee", BigDecimal.ZERO)); +// parmerters.put("wechat_fee", takeDecimalOrDefault(analysis, "wechat_fee", BigDecimal.ZERO)); +// parmerters.put("bestpay_fee", takeDecimalOrDefault(analysis, "bestpay_fee", BigDecimal.ZERO)); +// parmerters.put("jd_fee", takeDecimalOrDefault(analysis, "jd_fee", BigDecimal.ZERO)); +// parmerters.put("alipay_online_fee", takeDecimalOrDefault(analysis, "alipay_online_fee", BigDecimal.ZERO)); +// parmerters.put("gst", takeDecimalOrDefault(analysis, "tax_amount", BigDecimal.ZERO)); +// parmerters.put("royalpay_fee", takeDecimalOrDefault(analysis, "total_royalpay_fee", BigDecimal.ZERO)); +// parmerters.put("incremental_fee", takeDecimalOrDefault(analysis, "total_incremental_surcharge", BigDecimal.ZERO)); +// parmerters.put("incremental_gst", takeDecimalOrDefault(analysis, "total_incremental_tax", BigDecimal.ZERO)); +// parmerters.put("royalpay_gst", analysis.getBigDecimal("tax_amount").subtract(analysis.getBigDecimal("total_incremental_tax")).setScale(2,RoundingMode.HALF_UP)); +// +// dataList.parallelStream().forEach(item -> { +// BigDecimal incrementalSurcharge = item.containsKey("incremental_surcharge") ? item.getBigDecimal("incremental_surcharge") : BigDecimal.ZERO; +// BigDecimal taxAmount = item.containsKey("tax_amount") ? item.getBigDecimal("tax_amount") : BigDecimal.ZERO; +// BigDecimal royalpaySurhcarge = item.containsKey("royal_surcharge") ? item.getBigDecimal("royal_surcharge") : BigDecimal.ZERO; +// BigDecimal surhcargeBack = item.containsKey("surcharge_cashback") ? item.getBigDecimal("surcharge_cashback") : BigDecimal.ZERO; +// BigDecimal channelSurcharge = item.containsKey("channel_surcharge") ? item.getBigDecimal("channel_surcharge") : BigDecimal.ZERO; +// BigDecimal incrementalTax = incrementalSurcharge.divide(new BigDecimal(10), 2, RoundingMode.HALF_UP); +// BigDecimal royalpayTax = taxAmount.subtract(incrementalTax); +// BigDecimal realRoyalpayCharge = royalpaySurhcarge +// .add(surhcargeBack) +// .add(channelSurcharge) +// .add(royalpayTax); +// item.put("incremental_surcharge", incrementalSurcharge.add(incrementalTax).setScale(2, RoundingMode.HALF_UP)); +// item.put("real_royalpay_surcharge", realRoyalpayCharge.setScale(2, RoundingMode.HALF_UP)); +// scaleDecimalVal(item, "display_amount", item.getString("currency")); +// String platformCurrency = PlatformEnvironment.getEnv().getForeignCurrency(); +// scaleDecimalVal(item, "clearing_amount", platformCurrency); +// scaleDecimalVal(item, "settle_amount", platformCurrency); +// scaleDecimalVal(item, "total_surcharge", platformCurrency); +// }); +// JRDataSource jrDataSource = new JRBeanCollectionDataSource(dataList); +// response.setContentType("application/pdf"); +// String fileName = client.getString("client_moniker") + "_" + parmerters.getString("dateRange").replaceAll("/", ""); +// response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".pdf"); +// OutputStream outs = response.getOutputStream(); +// JSONObject clientIncrement = clientIncrementalMapper.findByClinetIdAndChannel(client.getIntValue("client_id"), "RP跨境商城"); +// InputStream jasper = clientIncrement == null ? trans_flow.getInputStream() : incremental_trans_flow.getInputStream(); +// byte[] bytes = JasperRunManager.runReportToPdf(jasper, parmerters, jrDataSource); +// outs.write(bytes, 0, bytes.length); +// outs.flush(); +// outs.close(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// } +// } @Override public void exportTransFlow(TradeLogQuery query, JSONObject partner, HttpServletResponse response) throws Exception { JSONObject transFlow = listPartnerTransFlow(query, partner); JSONObject analysis = transFlow.getJSONObject("analysis"); JSONObject client = clientManager.getClientInfo(partner.getIntValue("client_id")); + Context ctx = new Context(); + +// JSONObject manager = managerMapper.findById(device.getString("manager_id")); +// ctx.setVariable("firstname","lu"); if (!transFlow.getJSONArray("data").isEmpty()) { try { List dataList = transFlow.getJSONArray("data").toJavaList(JSONObject.class); @@ -712,7 +797,7 @@ public class TradeLogServiceImpl implements TradeLogService { parmerters.put("royalpay_fee", takeDecimalOrDefault(analysis, "total_royalpay_fee", BigDecimal.ZERO)); parmerters.put("incremental_fee", takeDecimalOrDefault(analysis, "total_incremental_surcharge", BigDecimal.ZERO)); parmerters.put("incremental_gst", takeDecimalOrDefault(analysis, "total_incremental_tax", BigDecimal.ZERO)); - parmerters.put("royalpay_gst", analysis.getBigDecimal("tax_amount").subtract(analysis.getBigDecimal("total_incremental_tax")).setScale(2,RoundingMode.HALF_UP)); + parmerters.put("royalpay_gst", analysis.getBigDecimal("tax_amount").subtract(analysis.getBigDecimal("total_incremental_tax")).setScale(2, RoundingMode.HALF_UP)); dataList.parallelStream().forEach(item -> { BigDecimal incrementalSurcharge = item.containsKey("incremental_surcharge") ? item.getBigDecimal("incremental_surcharge") : BigDecimal.ZERO; @@ -733,18 +818,74 @@ public class TradeLogServiceImpl implements TradeLogService { scaleDecimalVal(item, "clearing_amount", platformCurrency); scaleDecimalVal(item, "settle_amount", platformCurrency); scaleDecimalVal(item, "total_surcharge", platformCurrency); + String debit = item.getString("transaction_type").equals("Debit") ? item.getBigDecimal("clearing_amount").toString() + : "-"; + String credit = item.getString("transaction_type").equals("Credit") ? item.getBigDecimal("clearing_amount").toString() + : "-"; + item.put("debit", debit); + item.put("credit", credit); + + }); + ctx.setVariable("parmerters",parmerters); + ctx.setVariable("dataList",dataList); + final String html = thymeleaf.process("app/invoice.html", ctx); + JRDataSource jrDataSource = new JRBeanCollectionDataSource(dataList); response.setContentType("application/pdf"); String fileName = client.getString("client_moniker") + "_" + parmerters.getString("dateRange").replaceAll("/", ""); response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".pdf"); OutputStream outs = response.getOutputStream(); JSONObject clientIncrement = clientIncrementalMapper.findByClinetIdAndChannel(client.getIntValue("client_id"), "RP跨境商城"); - InputStream jasper = clientIncrement == null ? trans_flow.getInputStream() : incremental_trans_flow.getInputStream(); - byte[] bytes = JasperRunManager.runReportToPdf(jasper, parmerters, jrDataSource); +// InputStream jasper = clientIncrement == null ? trans_flow.getInputStream() : incremental_trans_flow.getInputStream(); +// byte[] bytes = JasperRunManager.runReportToPdf(jasper, parmerters, jrDataSource); + System.out.println("------>content:"+html); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + ITextRenderer renderer = new ITextRenderer(); + ITextFontResolver fontResolver = (ITextFontResolver) renderer.getSharedContext().getFontResolver(); + //添加字体库 begin +// File f = new File(fontDir); +// if (f.isDirectory()) { +// File[] files = f.listFiles(new FilenameFilter() { +// public boolean accept(File dir, String name) { +// String lower = name.toLowerCase(); +// return lower.endsWith(".otf") || lower.endsWith(".ttf") ; +// } +// }); +// for (int i = 0; i < files.length; i++) { +// fontResolver.addFont(files[i].getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); +// } +// } + //添加字体库end + renderer.setDocumentFromString(html); + renderer.layout(); + renderer.createPDF(os); + renderer.finishPDF(); + byte[] bytes = os.toByteArray(); outs.write(bytes, 0, bytes.length); outs.flush(); outs.close(); + +// final String html = thymeleaf.process("invoice.html", ctx); + +// response.setContentType("application/pdf"); +// String fileName = client.getString("client_moniker") + "_" + parmerters.getString("dateRange").replaceAll("/", ""); +// response.setHeader("Content-Disposition", "attachment;fileName=123.pdf"); +// OutputStream outs = null; +// try { +// outs = response.getOutputStream(); +//// JSONObject clientIncrement = clientIncrementalMapper.findByClinetIdAndChannel(client.getIntValue("client_id"), "RP跨境商城"); +//// InputStream jasper = clientIncrement == null ? trans_flow.getInputStream() : incremental_trans_flow.getInputStream(); +//// byte[] bytes = JasperRunManager.runReportToPdf(jasper, parmerters, jrDataSource); +// outs.write(buff, 0, buff.length); +// outs.flush(); +// outs.close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } + + } catch (Exception e) { e.printStackTrace(); } @@ -761,30 +902,29 @@ public class TradeLogServiceImpl implements TradeLogService { if (client == null) { throw new InvalidShortIdException(); } - partner.put("client_id",client.getIntValue("client_id")); - partner.put("client",client); + partner.put("client_id", client.getIntValue("client_id")); + partner.put("client", client); long internal = 0; - try{ + try { SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd"); long start = formatter.parse(query.getDatefrom()).getTime(); - long end= formatter.parse(query.getDateto()).getTime(); - internal = (end-start)/(1000*60*60*24); - }catch (Exception e){ + long end = formatter.parse(query.getDateto()).getTime(); + internal = (end - start) / (1000 * 60 * 60 * 24); + } catch (Exception e) { throw new ServerErrorException("查询参数格式不正确"); } - if(internal > 90){ - throw new ServerErrorException("最大查询区间为90天,请确认查询区间"); - } + if (internal > 90) { + throw new ServerErrorException("最大查询区间为90天,请确认查询区间"); + } - try{ + try { if (!locker.lock(clientKey, 300_000)) { throw new ServerErrorException("其他Invoice正在生成中,请稍后再试"); } - exportTransFlow( query, partner, response); - } - finally { + exportTransFlow(query, partner, response); + } finally { locker.unlock(clientKey); } } @@ -883,7 +1023,7 @@ public class TradeLogServiceImpl implements TradeLogService { row.createCell(17, Cell.CELL_TYPE_STRING).setCellValue(data.getString("trans_type")); row.createCell(18, Cell.CELL_TYPE_STRING).setCellValue(data.getString("clear_status")); row.createCell(19, Cell.CELL_TYPE_STRING).setCellValue(data.getString("gateway")); - row.createCell(20, Cell.CELL_TYPE_STRING).setCellValue(data.containsKey("order_detail")&&!"".equals(data.getString("order_detail"))?data.getString("order_detail"):data.getString("remark")); + row.createCell(20, Cell.CELL_TYPE_STRING).setCellValue(data.containsKey("order_detail") && !"".equals(data.getString("order_detail")) ? data.getString("order_detail") : data.getString("remark")); row.createCell(21, Cell.CELL_TYPE_STRING).setCellValue(data.getString("dev_id")); } @@ -988,7 +1128,7 @@ public class TradeLogServiceImpl implements TradeLogService { String credit = dataItem.getString("transaction_type").equals("Credit") ? dataItem.getBigDecimal("clearing_amount").toString() : "-"; HSSFRichTextString text3 = new HSSFRichTextString(credit); - HSSFRichTextString text4 = new HSSFRichTextString(dataItem.containsKey("order_detail")?dataItem.getString("order_detail"):dataItem.getString("remark")); + HSSFRichTextString text4 = new HSSFRichTextString(dataItem.containsKey("order_detail") ? dataItem.getString("order_detail") : dataItem.getString("remark")); cell0.setCellValue(text0); cell1.setCellValue(text1); cell2.setCellValue(text2); @@ -1787,7 +1927,7 @@ public class TradeLogServiceImpl implements TradeLogService { String[] clientIds = query.getClient_ids(); List clientIdList = new ArrayList<>(); clientIdList.add("ALL"); - if (clientIds!=null && clientIds.length >= 2) { + if (clientIds != null && clientIds.length >= 2) { clientIdList.addAll(Arrays.asList(clientIds)); } HSSFSheet sheet = null; diff --git a/src/main/resources/templates/app/invoice.html b/src/main/resources/templates/app/invoice.html new file mode 100644 index 000000000..26514111e --- /dev/null +++ b/src/main/resources/templates/app/invoice.html @@ -0,0 +1,185 @@ + + + + + + Invoice + + + + + + + + Tunnel Show Pty Ltd trading as RoyalPay + ABN 16 601 619 685 Representative of AFSL 448066 + + + + + + Tax Invoice + Merchant code + + Statement + + Issue Date + + Current + + + + + + Your Statement + + + + + Date/Time + + + + Transaction ID + + + + Debit + + + + Credit + + + + Service Fee for RoyalPay (GST inclu) + + + + Service fee for Mini Program(GST Inclu) + + + + Settlement Amount + + + + + + + + + + + + + + + + + Credit + + + + + + + + + + + + + + + + + + + + \ No newline at end of file