demand: TMS系统 - 客户账单管理 - 航信开票记录 - 新增加“定制导出” 详细查看附件。
committer: heyu
This commit is contained in:
parent
2a0888cfec
commit
40a30b5cb8
@ -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<EmisSettleInvoiceChRecord> list = emisSettleInvoiceChRecordService.selectEmisSettleInvoiceChRecordList(emisSettleInvoiceChRecord);
|
||||
ExcelUtil<EmisSettleInvoiceChRecord> util = new ExcelUtil<EmisSettleInvoiceChRecord>(EmisSettleInvoiceChRecord.class);
|
||||
util.exportExcel(response, list, "渠道开票记录表数据");
|
||||
public void export(HttpServletResponse response, EmisSettleInvoiceChRecord emisSettleInvoiceChRecord) {
|
||||
List<EmisSettleInvoiceChRecord> list = emisSettleInvoiceChRecordService
|
||||
.selectEmisSettleInvoiceChRecordList(emisSettleInvoiceChRecord);
|
||||
List<EmisSettleInvoiceChRecordExportVO> 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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -134,5 +134,7 @@ public class EmisSettleInvoiceChRecord extends BaseEntity
|
||||
private String openBillRemark;
|
||||
// 付款天数
|
||||
private String payDays;
|
||||
// 付款日期
|
||||
private String exportPayDays;
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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<String, Map<Integer, String>> COMPANY_TYPE_MAP = new HashMap<>();
|
||||
static {
|
||||
// 江苏探路者国际物流有限公司
|
||||
Map<Integer, String> jstlz = new HashMap<>();
|
||||
jstlz.put(1, "探路者电子专用发票");
|
||||
jstlz.put(2, "探路者电子发票");
|
||||
jstlz.put(3, "探路者纸质发票");
|
||||
jstlz.put(4, "探路者纸质专用发票");
|
||||
COMPANY_TYPE_MAP.put("江苏探路者国际物流有限公司", jstlz);
|
||||
// 广西陆陆达国际物流有限公司
|
||||
Map<Integer, String> gxll = new HashMap<>();
|
||||
gxll.put(1, "广西陆陆达电子专用发票");
|
||||
gxll.put(2, "广西陆陆达电子发票");
|
||||
gxll.put(3, "广西陆陆达纸质发票");
|
||||
gxll.put(4, "广西陆陆达纸质专用发票");
|
||||
COMPANY_TYPE_MAP.put("广西陆陆达国际物流有限公司", gxll);
|
||||
// 探路供应链(上海)有限公司
|
||||
Map<Integer, String> tls = new HashMap<>();
|
||||
tls.put(1, "探路供应链(上海)电子专用发票");
|
||||
tls.put(2, "探路供应链(上海)电子发票");
|
||||
tls.put(3, "探路供应链(上海)纸质发票");
|
||||
tls.put(4, "探路供应链(上海)纸质专用发票");
|
||||
COMPANY_TYPE_MAP.put("探路供应链(上海)有限公司", tls);
|
||||
// 探路供应链(江苏)有限公司
|
||||
Map<Integer, String> 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<String, Map<Integer, String>> 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();
|
||||
}
|
||||
}
|
||||
@ -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<EmisSettleInvoiceChRecordExportVO> 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();
|
||||
}
|
||||
}
|
||||
@ -47,6 +47,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="settleType" column="settle_type" />
|
||||
<result property="openBillRemark" column="open_bill_remark" />
|
||||
<result property="payDays" column="pay_days" />
|
||||
<result property="exportPayDays" column="export_pay_days" />
|
||||
|
||||
<association property="billMonth" column="apply_seq_no" select="com.xdadan.erp.emis.mapper.EmisBaseMapper.selectBillMonthByApplySeqNo"/>
|
||||
<association property="billCode" column="apply_seq_no" select="com.xdadan.erp.emis.mapper.EmisBaseMapper.selectBillCodeByApplySeqNo"/>
|
||||
@ -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
|
||||
<where>
|
||||
del_flag='0'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user