diff --git a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisSettleInvoiceChRecordController.java b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisSettleInvoiceChRecordController.java index be47e378d..0482b5484 100644 --- a/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisSettleInvoiceChRecordController.java +++ b/emis-biz-web/src/main/java/com/xdadan/erp/web/emis/EmisSettleInvoiceChRecordController.java @@ -1,4 +1,3 @@ - /** * @Project: emis * @Title: EmisSettleInvoiceChRecordController.java @@ -11,15 +10,21 @@ package com.xdadan.erp.web.emis; +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletResponse; import com.alibaba.fastjson.JSONObject; import com.xdadan.erp.emis.domain.EmisSettleInvoiceChRecord; +import com.xdadan.erp.emis.domain.EmisSettleInvoiceChRecordExportVO; import com.xdadan.erp.emis.domain.EmisSettleInvoiceRecord; import com.xdadan.erp.emis.domain.EmisWaybill; import com.xdadan.erp.emis.domain.exception.EmisBizError; import com.xdadan.erp.emis.service.IEmisSettleInvoiceChRecordService; +import com.xdadan.erp.emis.service.excelCellStrategy.InvoiceExportHelper; +import com.xdadan.erp.emis.service.excelCellStrategy.InvoicePoiExportUtil; import com.xdadan.erp.emis.utils.WaybillHelper; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -93,11 +98,47 @@ public class EmisSettleInvoiceChRecordController extends BaseController @PreAuthorize("@ss.hasPermi('emis:emisSettleInvoiceChRecord:export')") @Log(title = "渠道开票记录表", businessType = BusinessType.EXPORT) @PostMapping("/export") - public void export(HttpServletResponse response, EmisSettleInvoiceChRecord emisSettleInvoiceChRecord) - { - List list = emisSettleInvoiceChRecordService.selectEmisSettleInvoiceChRecordList(emisSettleInvoiceChRecord); - ExcelUtil util = new ExcelUtil(EmisSettleInvoiceChRecord.class); - util.exportExcel(response, list, "渠道开票记录表数据"); + public void export(HttpServletResponse response, EmisSettleInvoiceChRecord emisSettleInvoiceChRecord) { + List list = emisSettleInvoiceChRecordService + .selectEmisSettleInvoiceChRecordList(emisSettleInvoiceChRecord); + List exportList = new ArrayList<>(); + for (EmisSettleInvoiceChRecord record : list) { + EmisSettleInvoiceChRecordExportVO vo = new EmisSettleInvoiceChRecordExportVO(); + // 开票日期 + if (record.getCreateTime() != null) { + vo.setInvoiceDate(new SimpleDateFormat("M月d日").format(record.getCreateTime())); + } + // 公司抬头 + vo.setCompanyTitle(InvoiceExportHelper.cleanCompanyTitle(record.getCompanyName())); + // 发票号 + vo.setInvoiceNo(record.getInvoiceNo()); + // 时间 + vo.setSendMonth(record.getSendMonth()); + // 开票金额 + vo.setOpenMoney(record.getOpenMoney().stripTrailingZeros().toPlainString()); + // 开票公司 + vo.setInvoiceCompany(InvoiceExportHelper.mapInvoiceCompany(record.getSalerCompanyName())); + // 备注 + vo.setRemark(InvoiceExportHelper.processRemark(record)); + // 付款日期 + vo.setPayDate(InvoiceExportHelper.processPayDate(record.getExportPayDays())); + // 业务员 + vo.setSalesmen(record.getSalesmen()); + // 快递公司 + vo.setExpressCompany(record.getSalesmen()); + // 面单单号 + vo.setBillCode("1".equals(record.getSettleType()) ? record.getBillCode() : ""); + // 结算类型 + vo.setSettleType(record.getSettleType()); + // 申请备注 + vo.setApplyRemark(record.getApplyRemark()); + exportList.add(vo); + } + try { + InvoicePoiExportUtil.export(response, exportList); + } catch (Exception e) { + e.printStackTrace(); + } } /** diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceChRecord.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceChRecord.java index e5aecb4d9..6bfd67e06 100644 --- a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceChRecord.java +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceChRecord.java @@ -134,5 +134,7 @@ public class EmisSettleInvoiceChRecord extends BaseEntity private String openBillRemark; // 付款天数 private String payDays; + // 付款日期 + private String exportPayDays; } diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceChRecordExportVO.java b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceChRecordExportVO.java new file mode 100644 index 000000000..524c567e3 --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/domain/EmisSettleInvoiceChRecordExportVO.java @@ -0,0 +1,40 @@ +package com.xdadan.erp.emis.domain; + +import lombok.Data; +import java.math.BigDecimal; + +@Data +public class EmisSettleInvoiceChRecordExportVO { + // 开票日期(如5月15日) + private String invoiceDate; + // 公司抬头(去除有限公司/有限责任公司/Co/LTD等) + private String companyTitle; + // 发票号 + private String invoiceNo; + // 时间(sendMonth) + private String sendMonth; + // 开票金额 + private String openMoney; + // 折让 + private BigDecimal discount; + // 赔偿等杂费 + private BigDecimal compensation; + // 实际运费 + private BigDecimal actualFreight; + // 开票公司(映射) + private String invoiceCompany; + // 备注 + private String remark; + // 付款日期 + private String payDate; + // 业务员 + private String salesmen; + // 快递公司 + private String expressCompany; + // 面单单号 + private String billCode; + // 结算类型 + private String settleType; + // 申请备注 + private String applyRemark; +} \ No newline at end of file diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/InvoiceExportHelper.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/InvoiceExportHelper.java new file mode 100644 index 000000000..7b7fdef6e --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/InvoiceExportHelper.java @@ -0,0 +1,188 @@ +package com.xdadan.erp.emis.service.excelCellStrategy; + +import com.xdadan.erp.emis.domain.EmisSettleInvoiceChRecord; + +import java.math.BigDecimal; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.HashMap; +import java.util.Map; + +public class InvoiceExportHelper { + + // 公司抬头处理 + public static String cleanCompanyTitle(String companyName) { + if (companyName == null) + return ""; + // 去除结尾的 Co., CO., LTD, Ltd, co., CO, co, ltd, LTD 等 + String result = companyName.replaceAll( + "(?i)[,,\u3001.。;\\s]*(co\\.?|ltd\\.?|co|ltd)[,,\u3001.。;\\s]*(co\\.?|ltd\\.?|co|ltd)?[,,\u3001.。;\\s]*$", + "").trim(); + // 去除有限公司和有限责任公司 + result = result.replaceAll("(有限公司|有限责任公司)$", "").trim(); + return result; + } + + // 金额提取 + public static BigDecimal extractAmount(String remark, String... keys) { + if (remark == null) + return null; + for (String key : keys) { + Pattern p = Pattern.compile(key + "([\\d\\.]+)"); + Matcher m = p.matcher(remark); + if (m.find()) { + try { + BigDecimal val = new BigDecimal(m.group(1)); + if (val.compareTo(BigDecimal.ZERO) == 0) + return null; + return val; + } catch (Exception e) { + // ignore + } + } + } + return null; + } + + // 开票公司映射(支持不同发票类型) + // 外层key为公司名,内层key为发票类型(1-4),value为开票公司 + private static final Map> COMPANY_TYPE_MAP = new HashMap<>(); + static { + // 江苏探路者国际物流有限公司 + Map jstlz = new HashMap<>(); + jstlz.put(1, "探路者电子专用发票"); + jstlz.put(2, "探路者电子发票"); + jstlz.put(3, "探路者纸质发票"); + jstlz.put(4, "探路者纸质专用发票"); + COMPANY_TYPE_MAP.put("江苏探路者国际物流有限公司", jstlz); + // 广西陆陆达国际物流有限公司 + Map gxll = new HashMap<>(); + gxll.put(1, "广西陆陆达电子专用发票"); + gxll.put(2, "广西陆陆达电子发票"); + gxll.put(3, "广西陆陆达纸质发票"); + gxll.put(4, "广西陆陆达纸质专用发票"); + COMPANY_TYPE_MAP.put("广西陆陆达国际物流有限公司", gxll); + // 探路供应链(上海)有限公司 + Map tls = new HashMap<>(); + tls.put(1, "探路供应链(上海)电子专用发票"); + tls.put(2, "探路供应链(上海)电子发票"); + tls.put(3, "探路供应链(上海)纸质发票"); + tls.put(4, "探路供应链(上海)纸质专用发票"); + COMPANY_TYPE_MAP.put("探路供应链(上海)有限公司", tls); + // 探路供应链(江苏)有限公司 + Map tlj = new HashMap<>(); + tlj.put(1, "探路供应链(江苏)电子专用发票"); + tlj.put(2, "探路供应链(江苏)电子发票"); + tlj.put(3, "探路供应链(江苏)纸质发票"); + tlj.put(4, "探路供应链(江苏)纸质专用发票"); + COMPANY_TYPE_MAP.put("探路供应链(江苏)有限公司", tlj); + } + + /** + * 根据开票主体和发票类型返回开票公司 + * + * @param salerCompanyName 开票主体 + * @param invoiceType 发票类型(1-4) + * @return 开票公司 + */ + public static String mapInvoiceCompany(String salerCompanyName, int invoiceType) { + if (salerCompanyName == null) + return ""; + for (Map.Entry> entry : COMPANY_TYPE_MAP.entrySet()) { + if (salerCompanyName.contains(entry.getKey())) { + String mapped = entry.getValue().get(invoiceType); + if (mapped != null) + return mapped; + } + } + return salerCompanyName; + } + + /** + * 兼容旧逻辑,默认按普通发票(数电)类型(2)处理 + */ + public static String mapInvoiceCompany(String salerCompanyName) { + return mapInvoiceCompany(salerCompanyName, 2); + } + + // 处理备注 + public static String processRemark(EmisSettleInvoiceChRecord record) { + String remark = record.getOpenBillRemark(); + String applyRemark = record.getApplyRemark(); + if (remark == null) { + return ""; + } + + // 只去除与 LTD 直接相邻的符号 + String finalResult = remark.replaceAll( + "(?i)([,,\u3001.。;\\s]*(co\\.?|ltd\\.?|co|ltd)(?![,,\u3001.。;\\s]*$)[,,\u3001.。;\\s]*(co\\.?|ltd\\.?|co|ltd)?[,,\u3001.。;\\s]*)|(?i)\\s+(co\\.?|ltd\\.?|co|ltd)(?![,,\u3001.。;\\s]*$)[,,\u3001.。;\\s]*(co\\.?|ltd\\.?|co|ltd)?[,,\u3001.。;\\s]*|(?i)\\s+(co\\.?|ltd\\.?|co|ltd)$", + "").trim(); + // 处理 CO., LTD 这样的组合 + finalResult = finalResult.replaceAll("(?i)(CO\\.?\\s*,\\s*LTD\\.?)", "").trim(); + finalResult = finalResult.replaceAll("(有限公司|有限责任公司)$", "").trim(); + + if("2".equals(record.getSettleType())){ + return finalResult.replaceAll("-", ",").replaceAll("(\\d+)\\s+", "$1").trim(); + } + + // 处理多个日期的情况 + String[] dateParts = finalResult.split("-"); + if (dateParts.length > 0) { + String lastPart = dateParts[dateParts.length - 1].trim(); + // 去除日期和公司名之间的空格 + lastPart = lastPart.replaceAll("(\\d+)\\s+", "$1"); + finalResult = "现金-" + lastPart; + // 只有当applyRemark不为空时才拼接 + if (applyRemark != null && !applyRemark.trim().isEmpty()) { + finalResult += "-" + applyRemark; + } + } + + return finalResult; + } + + // 处理付款日期 + public static String processPayDate(String payDate) { + if (payDate == null) { + return ""; + } + + StringBuilder result = new StringBuilder(); + String[] parts = payDate.split(","); + + for (int i = 0; i < parts.length; i++) { + String part = parts[i].trim(); + String[] dateAndAmount = part.split("-"); + + if (dateAndAmount.length == 2) { + String datePart = dateAndAmount[0]; + String amountPart = dateAndAmount[1]; + + try { + // 使用BigDecimal去除多余的0 + BigDecimal amount = new BigDecimal(amountPart); + amount = amount.stripTrailingZeros(); + + if (i > 0) { + result.append(","); + } + result.append(datePart).append("-").append(amount.toPlainString()); + } catch (NumberFormatException e) { + // 如果金额解析失败,保持原样 + if (i > 0) { + result.append(","); + } + result.append(part); + } + } else { + // 如果没有金额部分,保持原样 + if (i > 0) { + result.append(","); + } + result.append(part); + } + } + + return result.toString(); + } +} \ No newline at end of file diff --git a/emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/InvoicePoiExportUtil.java b/emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/InvoicePoiExportUtil.java new file mode 100644 index 000000000..46a04e40c --- /dev/null +++ b/emis-biz/src/main/java/com/xdadan/erp/emis/service/excelCellStrategy/InvoicePoiExportUtil.java @@ -0,0 +1,76 @@ +package com.xdadan.erp.emis.service.excelCellStrategy; + +import com.xdadan.erp.emis.domain.EmisSettleInvoiceChRecordExportVO; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import javax.servlet.http.HttpServletResponse; +import java.io.OutputStream; +import java.util.List; + +public class InvoicePoiExportUtil { + + public static void export(HttpServletResponse response, List data) + throws Exception { + Workbook wb = new XSSFWorkbook(); + Sheet sheet = wb.createSheet("渠道开票记录表"); + + // 设置行高、字体、边框 + CellStyle style = wb.createCellStyle(); + Font font = wb.createFont(); + font.setFontName("宋体"); + font.setFontHeightInPoints((short) 10); + style.setFont(font); + style.setBorderTop(BorderStyle.THIN); + style.setBorderBottom(BorderStyle.THIN); + style.setBorderLeft(BorderStyle.THIN); + style.setBorderRight(BorderStyle.THIN); + + // 表头 + String[] headers = { "开票日期", "公司抬头", "发票号", "时间", "开票金额", "开票公司", "备注", "付款日期", "业务员", "快递公司", "面单单号" }; + Row headRow = sheet.createRow(0); + headRow.setHeightInPoints(30); + for (int i = 0; i < headers.length; i++) { + Cell cell = headRow.createCell(i); + cell.setCellValue(headers[i]); + cell.setCellStyle(style); + } + + // 设置列宽 + double[] columnWidths = { 8.38, 31, 34.5, 9.13, 8.75, 22.75, 90.5, 29.13, 8.38, 8.38, 41.5 }; + for (int i = 0; i < columnWidths.length; i++) { + sheet.setColumnWidth(i, (int) (columnWidths[i] * 256)); + } + + // 数据 + int rowIdx = 1; + for (EmisSettleInvoiceChRecordExportVO vo : data) { + Row row = sheet.createRow(rowIdx++); + row.setHeightInPoints(30); + int col = 0; + row.createCell(col++).setCellValue(vo.getInvoiceDate()); + row.createCell(col++).setCellValue(vo.getCompanyTitle()); + row.createCell(col++).setCellValue(vo.getInvoiceNo()); + row.createCell(col++).setCellValue(vo.getSendMonth()); + row.createCell(col++).setCellValue(vo.getOpenMoney() == null ? "" : vo.getOpenMoney().toString()); + row.createCell(col++).setCellValue(vo.getInvoiceCompany()); + row.createCell(col++).setCellValue(vo.getRemark()); + row.createCell(col++).setCellValue(vo.getPayDate()); + row.createCell(col++).setCellValue(vo.getSalesmen()); + row.createCell(col++).setCellValue(vo.getExpressCompany()); + row.createCell(col++).setCellValue(vo.getBillCode()); + + for (int i = 0; i < headers.length; i++) { + row.getCell(i).setCellStyle(style); + } + } + + // 输出 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setHeader("Content-Disposition", "attachment;filename=invoice_export.xlsx"); + OutputStream os = response.getOutputStream(); + wb.write(os); + os.flush(); + wb.close(); + } +} \ No newline at end of file diff --git a/emis-biz/src/main/resources/mapper/EmisSettleInvoiceChRecordMapper.xml b/emis-biz/src/main/resources/mapper/EmisSettleInvoiceChRecordMapper.xml index cfa020150..e78952a03 100644 --- a/emis-biz/src/main/resources/mapper/EmisSettleInvoiceChRecordMapper.xml +++ b/emis-biz/src/main/resources/mapper/EmisSettleInvoiceChRecordMapper.xml @@ -47,6 +47,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -87,7 +88,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" CONCAT( CONCAT(SUBSTRING(DATE_FORMAT(w.send_date, '%Y'), 3, 2), DATE_FORMAT(w.send_date, '%m ')), b.cust_name - ) + ) SEPARATOR '-' ) FROM emis_waybill w INNER JOIN emis_settle_invoice_rel ir ON w.bill_code = ir.bill_no @@ -100,7 +101,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" CONCAT( DATE_FORMAT(w.send_date, '%m%d '), w.send_company - ) + ) SEPARATOR '-' ) FROM emis_waybill w INNER JOIN emis_settle_invoice_rel ir ON w.bill_code = ir.bill_no @@ -126,7 +127,46 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" FROM emis_settle_pay_record pr INNER JOIN emis_settle_pay_bill_rel pbr ON pr.pay_id = pbr.pay_id INNER JOIN emis_settle_invoice_bill_rel ibr ON ibr.settle_bill_no = pbr.settle_bill_no - WHERE ibr.apply_seq_no = a.apply_seq_no) as pay_days + WHERE ibr.apply_seq_no = a.apply_seq_no) as pay_days, + (SELECT + CASE + WHEN COUNT(*) = 1 THEN + CONCAT( + DATE_FORMAT(pr.trade_date, '%m/%d'), + '已付', + CASE pr.pay_type + WHEN '1' THEN '企业微信' + WHEN '2' THEN '对公' + WHEN '3' THEN '微信支付' + WHEN '4' THEN '支付宝' + WHEN '5' THEN '其他' + WHEN '6' THEN '招行付款' + ELSE pr.pay_type + END + ) + ELSE + GROUP_CONCAT(DISTINCT + CONCAT( + DATE_FORMAT(pr.trade_date, '%m/%d'), + '已付', + CASE pr.pay_type + WHEN '1' THEN '企业微信' + WHEN '2' THEN '对公' + WHEN '3' THEN '微信支付' + WHEN '4' THEN '支付宝' + WHEN '5' THEN '其他' + WHEN '6' THEN '招行付款' + ELSE pr.pay_type + END, + '-', + pr.pay_money + ) + ) + END + FROM emis_settle_pay_record pr + INNER JOIN emis_settle_pay_bill_rel pbr ON pr.pay_id = pbr.pay_id + INNER JOIN emis_settle_invoice_bill_rel ibr ON ibr.settle_bill_no = pbr.settle_bill_no + WHERE ibr.apply_seq_no = a.apply_seq_no) as export_pay_days FROM emis_settle_invoice_ch_record a del_flag='0'