Ver código fonte

发票详情导出

skyline 2 anos atrás
pai
commit
bc8a7445d3

+ 4 - 5
admin/src/main/java/com/kym/admin/controller/FinanceController.java

@@ -139,17 +139,16 @@ public class FinanceController {
      * @return 导出发票列表
      */
     @GetMapping("/export/invoiceList")
-    void exportInvoiceList(@ModelAttribute InvoiceQueryParam params, HttpServletRequest request, HttpServletResponse response) {
-       ExcelWriter writer = invoiceService.exportInvoiceList(params);
-//        response.setContentType("application/octet-stream;charset=utf-8");
+    void exportInvoiceList(@ModelAttribute InvoiceDetailQueryParam params, HttpServletRequest request, HttpServletResponse response) {
+        ExcelWriter writer = invoiceDetailService.exportInvoiceDetail(params);
         response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
-        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("发票列表", StandardCharsets.UTF_8) + ".xlsx");
+        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode("发票详情列表", StandardCharsets.UTF_8) + ".xlsx");
         ServletOutputStream excelOut = null;
         try {
             excelOut = response.getOutputStream();
             writer.flush(excelOut, true);
         } catch (Exception e) {
-         logger.error("exportInvoiceList error",e);
+            logger.error("exportInvoiceList error", e);
         } finally {
             writer.close();
         }

+ 2 - 1
entity/src/main/java/com/kym/entity/admin/InvoiceDetail.java

@@ -15,6 +15,7 @@ import lombok.Setter;
 import lombok.experimental.Accessors;
 
 import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * <p>
@@ -103,7 +104,7 @@ public class InvoiceDetail extends BaseEntity {
      * 发票明细
      */
     @TableField(typeHandler = JacksonTypeHandler.class)
-    private Object items;
+    private List<FapiaoApplications.FapiaoItem> items;
 
     /**
      * 备注

+ 30 - 0
entity/src/main/java/com/kym/entity/typehandle/InvoiceDetailItemsTypeHandle.java

@@ -0,0 +1,30 @@
+package com.kym.entity.typehandle;
+
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.kym.entity.wechat.FaPiao;
+import com.kym.entity.wechat.FapiaoApplications;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author skyline
+ * @description 发票中发票行
+ * https://github.com/baomidou/mybatis-plus-samples/blob/master/mybatis-plus-sample-typehandler/src/main/java/com/baomidou/mybatisplus/samples/typehandler/WalletListTypeHandler.java
+ */
+public class InvoiceDetailItemsTypeHandle extends JacksonTypeHandler {
+    public InvoiceDetailItemsTypeHandle(Class<?> type) {
+        super(type);
+    }
+
+    @Override
+    protected Object parse(String json) {
+        try {
+            return getObjectMapper().readValue(json, new TypeReference<List<FapiaoApplications.FapiaoItem>>() {
+            });
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

+ 2 - 1
mapper/src/main/java/com/kym/mapper/admin/InvoiceDetailMapper.java

@@ -1,5 +1,6 @@
 package com.kym.mapper.admin;
 
+import com.github.yulichang.base.MPJBaseMapper;
 import com.kym.entity.admin.InvoiceDetail;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 
@@ -11,6 +12,6 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  * @author skyline
  * @since 2024-03-19
  */
-public interface InvoiceDetailMapper extends BaseMapper<InvoiceDetail> {
+public interface InvoiceDetailMapper extends MPJBaseMapper<InvoiceDetail> {
 
 }

+ 1 - 1
mapper/src/main/resources/mappers/admin/InvoiceDetailMapper.xml

@@ -17,7 +17,7 @@
         <result column="seller_information" property="sellerInformation" typeHandler="com.kym.entity.typehandle.InvoiceDetailSellerInformationTypeHandle" />
         <result column="buyer_information" property="buyerInformation" typeHandler="com.kym.entity.typehandle.InvoiceDetailBuyerInformationTypeHandle" />
         <result column="extra_information" property="extraInformation" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
-        <result column="items" property="items" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
+        <result column="items" property="items" typeHandler="com.kym.entity.typehandle.InvoiceDetailItemsTypeHandle" />
         <result column="remark" property="remark" />
         <result column="create_time" property="createTime" />
         <result column="update_time" property="updateTime" />

+ 4 - 0
service/src/main/java/com/kym/service/admin/InvoiceDetailService.java

@@ -1,5 +1,6 @@
 package com.kym.service.admin;
 
+import cn.hutool.poi.excel.ExcelWriter;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.kym.entity.admin.InvoiceDetail;
 import com.kym.entity.admin.queryParams.InvoiceDetailQueryParam;
@@ -16,4 +17,7 @@ import com.kym.entity.common.PageBean;
 public interface InvoiceDetailService extends IService<InvoiceDetail> {
 
     PageBean<InvoiceDetail> listInvoiceDetail(InvoiceDetailQueryParam params);
+
+
+    ExcelWriter exportInvoiceDetail(InvoiceDetailQueryParam params);
 }

+ 82 - 2
service/src/main/java/com/kym/service/admin/impl/InvoiceDetailServiceImpl.java

@@ -1,15 +1,28 @@
 package com.kym.service.admin.impl;
 
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.poi.excel.ExcelUtil;
+import cn.hutool.poi.excel.ExcelWriter;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
 import com.github.pagehelper.PageHelper;
+import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.kym.common.utils.CommUtil;
 import com.kym.entity.admin.InvoiceDetail;
 import com.kym.entity.admin.queryParams.InvoiceDetailQueryParam;
 import com.kym.entity.common.PageBean;
+import com.kym.entity.miniapp.DataDict;
+import com.kym.entity.miniapp.Invoice;
+import com.kym.entity.wechat.FapiaoApplications;
 import com.kym.mapper.admin.InvoiceDetailMapper;
 import com.kym.service.admin.InvoiceDetailService;
+import com.kym.service.miniapp.DataDictService;
 import org.springframework.stereotype.Service;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
 /**
  * <p>
  * 发票详情表 服务实现类
@@ -19,7 +32,14 @@ import org.springframework.stereotype.Service;
  * @since 2024-03-19
  */
 @Service
-public class InvoiceDetailServiceImpl extends ServiceImpl<InvoiceDetailMapper, InvoiceDetail> implements InvoiceDetailService {
+public class InvoiceDetailServiceImpl extends MPJBaseServiceImpl<InvoiceDetailMapper, InvoiceDetail> implements InvoiceDetailService {
+
+    private final DataDictService dataDictService;
+
+    public InvoiceDetailServiceImpl(DataDictService dataDictService) {
+        this.dataDictService = dataDictService;
+    }
+
 
     @Override
     public PageBean<InvoiceDetail> listInvoiceDetail(InvoiceDetailQueryParam params) {
@@ -30,4 +50,64 @@ public class InvoiceDetailServiceImpl extends ServiceImpl<InvoiceDetailMapper, I
                 .list();
         return new PageBean<>(res);
     }
+
+    @Override
+    public ExcelWriter exportInvoiceDetail(InvoiceDetailQueryParam params) {
+        var invoiceDetailList = lambdaQuery()
+                .eq(CommUtil.isNotEmptyAndNull(params.getApplyId()), InvoiceDetail::getApplyId, params.getApplyId())
+                .orderByDesc(InvoiceDetail::getFapiaoTime)
+                .list();
+        ExcelWriter writer = ExcelUtil.getWriter();
+
+        // excel 行信息
+        List<Map<String, Object>> rows = new ArrayList<>();
+
+        // 单张发票若发票行有多行,则每项单独一行
+        invoiceDetailList.forEach(invoiceDetail -> {
+            var items = JSON.parseArray(JSON.toJSONString(invoiceDetail.getItems()), FapiaoApplications.FapiaoItem.class);
+            items.forEach(item -> {
+                var row = new HashMap<String, Object>();
+                // 发票基本信息
+                row.put("blue_fapiao.fapiao_time", invoiceDetail.getFapiaoTime());
+                row.put("blue_fapiao.fapiao_code", invoiceDetail.getBlueFapiao().getFapiao_code());
+                row.put("blue_fapiao.fapiao_number", invoiceDetail.getBlueFapiao().getFapiao_number());
+                row.put("buyer_information.type", Invoice.TYPE_企业.equals(invoiceDetail.getBuyerInformation().getType()) ? "企业" : "个人");
+                row.put("buyer_information.name", invoiceDetail.getBuyerInformation().getName());
+                row.put("buyer_information.taxpayer_id", invoiceDetail.getBuyerInformation().getTaxpayer_id());
+                row.put("fapiao_information.status", "否"); // invoiceDetail.getStatus()
+
+                row.putAll(Map.of(
+                        "goods_name", item.getGoods_name(),
+//             "specification",item.getSpecification(),
+//             "unit",item.getUnit(),
+                        "quantity", item.getQuantity() / 100000000,
+                        "amount", NumberUtil.decimalFormat("#.##", item.getAmount() / 100f),
+                        "tax_amount", NumberUtil.decimalFormat("#.##", item.getTax_amount() / 100f),
+                        "tax_rate", NumberUtil.decimalFormat("#.##", item.getTax_rate() / 10000f)
+                ));
+
+                rows.add(row);
+            });
+        });
+
+        writer.addHeaderAlias("blue_fapiao.fapiao_code", "发票代码");
+        writer.addHeaderAlias("blue_fapiao.fapiao_number", "发票号码");
+        writer.addHeaderAlias("blue_fapiao.fapiao_time", "开票日期");
+        writer.addHeaderAlias("goods_name", "货物、应税劳务及服务");
+        writer.addHeaderAlias("specification", "规格型号");
+        writer.addHeaderAlias("quantity", "数量");
+        writer.addHeaderAlias("unit", "单位");
+        writer.addHeaderAlias("amount", "金额");
+        writer.addHeaderAlias("tax_rate", "税率");
+        writer.addHeaderAlias("tax_amount", "税额");
+        writer.addHeaderAlias("fapiao_information.status", "是否作废");
+        writer.addHeaderAlias("buyer_information.type", "购买方类型");
+        writer.addHeaderAlias("buyer_information.name", "购方单位名称");
+        writer.addHeaderAlias("buyer_information.taxpayer_id", "购方识别号");
+
+        writer.write(rows, true);
+
+        return writer;
+
+    }
 }

+ 0 - 2
service/src/main/java/com/kym/service/miniapp/InvoiceService.java

@@ -29,6 +29,4 @@ public interface InvoiceService extends MPJBaseService<Invoice> {
 
     void cancelApplyInvoice(String invoiceId);
 
-
-    ExcelWriter exportInvoiceList(InvoiceQueryParam param);
 }

+ 2 - 92
service/src/main/java/com/kym/service/miniapp/impl/InvoiceServiceImpl.java

@@ -57,8 +57,8 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic
     private final WxPayService wxPayService;
     private final DataDictService dataDictService;
 
-    public InvoiceServiceImpl(ChargeOrderService chargeOrderService, @Lazy WxPayService wxPayService,@Lazy DataDictService dataDictService) {
-        this.dataDictService =dataDictService;
+    public InvoiceServiceImpl(ChargeOrderService chargeOrderService, @Lazy WxPayService wxPayService, @Lazy DataDictService dataDictService) {
+        this.dataDictService = dataDictService;
         this.chargeOrderService = chargeOrderService;
         this.wxPayService = wxPayService;
     }
@@ -156,38 +156,6 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic
         return new PageBean<>(list);
     }
 
-    void invoiceExport(InvoiceQueryParam params) {
-        MPJLambdaWrapper<Invoice> wrapper = JoinWrappers.lambda(Invoice.class)
-                .selectAsClass(Invoice.class, InvoiceVo.class)
-                .selectAll(Invoice.class)
-                .select(User::getMobilePhone)
-                .leftJoin(User.class, User::getId, Invoice::getUserId)
-                .like(CommUtil.isNotEmptyAndNull(params.getPhone()), User::getMobilePhone, params.getPhone())
-                .like(CommUtil.isNotEmptyAndNull(params.getInvoiceTitle()), Invoice::getInvoiceTitle, params.getInvoiceTitle())
-                .like(CommUtil.isNotEmptyAndNull(params.getBiller()), Invoice::getBiller, params.getBiller())
-                .like(CommUtil.isNotEmptyAndNull(params.getTaxId()), Invoice::getTaxId, params.getTaxId())
-                .like(CommUtil.isNotEmptyAndNull(params.getInvoiceType()), Invoice::getInvoiceType, params.getInvoiceType())
-                .like(CommUtil.isNotEmptyAndNull(params.getEmail()), Invoice::getEmail, params.getEmail())
-                .eq(params.getStatus() != null, Invoice::getStatus, params.getStatus())
-                .orderByDesc(Invoice::getId);
-        var list = selectJoinList(InvoiceVo.class, wrapper);
-
-        // 通过工具类创建writer,默认创建xls格式
-        ExcelWriter writer = ExcelUtil.getWriter();
-
-        //自定义标题别名
-        writer.addHeaderAlias("", "发票号码");
-        writer.addHeaderAlias("", "开票日期");
-        writer.addHeaderAlias("", "货物、应税劳务及服务");
-        writer.addHeaderAlias("", "金额");
-        writer.addHeaderAlias("", "税率");
-        writer.addHeaderAlias("", "税额");
-        writer.addHeaderAlias("", "购方识别号");
-        writer.addHeaderAlias("", "购方单位名称");
-
-
-    }
-
     @Override
     public List<Invoice> listInvoiceForApp(Integer status) {
         return lambdaQuery().eq(Invoice::getUserId, StpUtil.getLoginIdAsLong()).eq(status != null, Invoice::getStatus, status).list();
@@ -206,62 +174,4 @@ public class InvoiceServiceImpl extends MPJBaseServiceImpl<InvoiceMapper, Invoic
         }
     }
 
-    @Override
-    public ExcelWriter exportInvoiceList(InvoiceQueryParam params) {
-        MPJLambdaWrapper<Invoice> wrapper = JoinWrappers.lambda(Invoice.class)
-                .selectAsClass(Invoice.class, InvoiceVo.class)
-                .selectAll(Invoice.class)
-                .select(User::getMobilePhone)
-                .leftJoin(User.class, User::getId, Invoice::getUserId)
-                .like(CommUtil.isNotEmptyAndNull(params.getPhone()), User::getMobilePhone, params.getPhone())
-                .like(CommUtil.isNotEmptyAndNull(params.getInvoiceTitle()), Invoice::getInvoiceTitle, params.getInvoiceTitle())
-                .like(CommUtil.isNotEmptyAndNull(params.getBiller()), Invoice::getBiller, params.getBiller())
-                .like(CommUtil.isNotEmptyAndNull(params.getTaxId()), Invoice::getTaxId, params.getTaxId())
-                .like(CommUtil.isNotEmptyAndNull(params.getInvoiceType()), Invoice::getInvoiceType, params.getInvoiceType())
-                .like(CommUtil.isNotEmptyAndNull(params.getEmail()), Invoice::getEmail, params.getEmail())
-                .eq(params.getStatus() != null, Invoice::getStatus, params.getStatus())
-                .orderByDesc(Invoice::getId);
-        var list = selectJoinList(InvoiceVo.class, wrapper);
-        ExcelWriter writer = ExcelUtil.getWriter();
-//设置要导出到的sheet
-//自定义excel标题和列名
-        writer.addHeaderAlias("status", "发票状态");
-        writer.addHeaderAlias("mobilePhone", "用户手机号");
-        writer.addHeaderAlias("invoiceTitle", "发票抬头");
-        writer.addHeaderAlias("taxId", "公司税号");
-        writer.addHeaderAlias("email", "接收发票邮箱");
-        writer.addHeaderAlias("invoiceType", "发票类型");
-        writer.addHeaderAlias("address", "公司地址");
-        writer.addHeaderAlias("telephone", "购买方电话");
-        writer.addHeaderAlias("bankName", "开户银行");
-        writer.addHeaderAlias("bankAccount", "银行账户");
-        writer.addHeaderAlias("biller", "开票人");
-        writer.addHeaderAlias("invoiceAmount", "发票金额(元)");
-        writer.addHeaderAlias("totalPower", "累积充电量(度)");
-        writer.addHeaderAlias("totalMoney", "累积总金额(元)");
-        writer.addHeaderAlias("elecMoney", "累积电费(元)");
-        writer.addHeaderAlias("serviceMoney", "累积服务费(元)");
-        writer.addHeaderAlias("serviceMoneyDiscount", "服务费优惠金额(元)");
-
-        List<DataDict> dataDicts = dataDictService.lambdaQuery().list();
-        Map<String, String> dictMap = dataDicts.stream().collect(Collectors.toMap(k -> k.getCode() + ":" + k.getValue(), DataDict::getName));
-//一次性写出内容,使用默认样式,强制输出标题
-        List<Map<String, Object>> rows = new ArrayList<>();
-        list.forEach(k -> {
-            Map<String, Object> m = BeanUtil.beanToMap(k,"mobilePhone","invoiceTitle","taxId","email",
-                    "address","telephone","bankName","bankAccount","biller","totalPower");
-            m.put("invoiceType", dictMap.getOrDefault("Invoice.type:"+k.getInvoiceType(),""));
-            m.put("invoiceAmount", NumberUtil.decimalFormat("#.##",k.getInvoiceAmount()/100f));
-            m.put("totalMoney",NumberUtil.decimalFormat("#.##",k.getTotalMoney()/100f));
-            m.put("elecMoney", NumberUtil.decimalFormat("#.##",k.getElecMoney()/100f));
-            m.put("serviceMoney", NumberUtil.decimalFormat("#.##",k.getServiceMoney()/100f));
-            m.put("serviceMoneyDiscount",NumberUtil.decimalFormat("#.##",k.getServiceMoneyDiscount()/100f));
-            m.put("status", dictMap.getOrDefault("Invoice.status:"+k.getStatus(),""));
-            rows.add(m);
-        });
-        writer.write(rows, true);
-
-        return writer;
-    }
-
 }