Browse Source

发票明细导入、模板下载

lizhenhao 2 years ago
parent
commit
f416c5b322

+ 103 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/finance/invoice/controller/FinanceInvoiceController.java

@@ -2,18 +2,30 @@ package com.jeeplus.test.finance.invoice.controller;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeeplus.aop.demo.annotation.DemoMode;
 import com.jeeplus.aop.logging.annotation.ApiLog;
 import com.jeeplus.common.utils.ResponseUtil;
+import com.jeeplus.core.excel.utils.EasyPoiUtil;
 import com.jeeplus.sys.constant.enums.LogTypeEnum;
+import com.jeeplus.sys.domain.Office;
 import com.jeeplus.sys.utils.StringUtils;
 import com.jeeplus.test.finance.invoice.domain.FinanceInvoice;
+import com.jeeplus.test.finance.invoice.domain.FinanceInvoiceDetail;
 import com.jeeplus.test.finance.invoice.service.FinanceInvoiceService;
 import com.jeeplus.test.finance.invoice.service.dto.FinanceDTO;
 import com.jeeplus.test.finance.invoice.service.dto.FinanceInvoiceDTO;
+import com.jeeplus.test.finance.invoice.service.dto.FinanceInvoiceDetailDTO;
 import com.jeeplus.test.finance.invoice.service.dto.FinanceInvoiceReceivablesDTO;
+import com.jeeplus.test.jobPosion.domain.JobPosition;
+import com.jeeplus.test.jobPosion.domain.Position;
+import com.jeeplus.test.jobPosion.enums.PositionTypeEnum;
+import com.jeeplus.test.jobPosion.service.dto.JobPositionDTO;
+import com.jeeplus.test.jobPosion.service.dto.PositionLogDTO;
+import com.jeeplus.test.jobPosion.service.mapstruct.JobPositionWrapper;
 import com.jeeplus.test.program.configuration.fileDict.domain.ProgramFileDict;
 import com.jeeplus.test.program.configuration.fileDict.service.ProgramFileDictService;
 import com.jeeplus.test.program.configuration.fileDict.service.dto.ProgramFileDictDTO;
@@ -23,12 +35,23 @@ import io.swagger.annotations.ApiOperation;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.stream.Collectors;
 
+import static com.jeeplus.test.jobPosion.utils.BeanUtils.objectCheckIsNull;
+
 @Api("财务管理-发票")
 @RestController
 @RequestMapping(value = "/finance/invoice")
@@ -166,4 +189,84 @@ public class FinanceInvoiceController {
         String s = financeInvoiceService.isReceivables(dto);
         return ResponseEntity.ok(s);
     }
+
+    /**
+     * 下载发票明细导入模板
+     *
+     * @param response
+     * @return
+     */
+    @GetMapping("/importDetail/template")
+    @ApiOperation(value = "下载模板")
+    public void importFileTemplate(HttpServletResponse response, HttpServletRequest request) {
+        try {
+            InputStream inputStream = this.getClass().getResourceAsStream("/dot/发票明细导入模板.xlsx");
+            //强制下载不打开
+            response.setContentType("application/force-download");
+            OutputStream out = response.getOutputStream();
+            //使用URLEncoder来防止文件名乱码或者读取错误
+            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("finance_invoice_detail_template.xlsx", "UTF-8"));
+            int b = 0;
+            byte[] buffer = new byte[1000000];
+            while (b != -1) {
+                b = inputStream.read(buffer);
+                if (b != -1) out.write(buffer, 0, b);
+            }
+            inputStream.close();
+            out.close();
+            out.flush();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 导入发票明细数据
+     *
+     * @return
+     */
+    @DemoMode
+    @PostMapping("/importDetail")
+    @ApiLog(value = "导入发票明细数据excel", type = LogTypeEnum.IMPORT)
+    public ResponseEntity importDetail(MultipartFile file, HttpServletRequest request) throws IOException {
+
+        ArrayList<FinanceInvoiceDetailDTO> arrayList = new ArrayList<>();
+        HashMap<String,String> hashMap = new HashMap<>();
+
+        List<FinanceInvoiceDetailDTO> listA = new ArrayList<>();
+        //获取sheet
+        listA = EasyPoiUtil.importExcel(file, 0, 1, FinanceInvoiceDetailDTO.class);
+        //去除excel中的空行
+        listA = getExcelList(listA);
+        //导入前检测数据
+        String resultA = financeInvoiceService.importDecide(listA, arrayList, hashMap);
+        if(StringUtils.isNotBlank(resultA)){
+            //有返回值,说明导入的数据不正确。向用户抛提示
+            return ResponseEntity.badRequest().body  (resultA);
+        }
+        //判断文件中是否有重复的发票号
+        if(hashMap.size() != listA.size()){
+            return ResponseEntity.badRequest().body  ("文件中存在重复的发票号");
+        }
+
+        return ResponseEntity.ok(arrayList);
+    }
+
+    /**
+     * 去除excel中的空行
+     * @param list
+     * @return
+     */
+    public ArrayList<FinanceInvoiceDetailDTO> getExcelList(List<FinanceInvoiceDetailDTO> list){
+
+        ArrayList<FinanceInvoiceDetailDTO> financeInvoiceDetailDTOS = new ArrayList<>();
+
+        list.stream().forEach(item->{
+            if(objectCheckIsNull(item)){
+                financeInvoiceDetailDTOS.add(item);
+            }
+        });
+
+        return financeInvoiceDetailDTOS;
+    }
 }

+ 208 - 23
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/finance/invoice/service/FinanceInvoiceService.java

@@ -2,6 +2,7 @@ package com.jeeplus.test.finance.invoice.service;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -9,6 +10,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
 import com.jeeplus.core.query.QueryWrapperGenerator;
+import com.jeeplus.sys.domain.Office;
 import com.jeeplus.sys.service.dto.UserDTO;
 import com.jeeplus.sys.utils.StringUtils;
 import com.jeeplus.sys.utils.UserUtils;
@@ -19,24 +21,25 @@ import com.jeeplus.test.finance.invoice.service.dto.FinanceInvoiceDTO;
 import com.jeeplus.test.finance.invoice.service.dto.FinanceInvoiceDetailDTO;
 import com.jeeplus.test.finance.invoice.service.dto.FinanceInvoiceReceivablesDTO;
 import com.jeeplus.test.finance.invoice.service.mapstruct.*;
+import com.jeeplus.test.jobPosion.domain.JobPosition;
+import com.jeeplus.test.jobPosion.domain.Position;
+import com.jeeplus.test.jobPosion.service.mapstruct.JobPositionWrapper;
 import com.jeeplus.test.mould.service.SerialnumTplService;
 import com.jeeplus.test.oss.domain.WorkAttachment;
 import com.jeeplus.test.oss.mapper.OssServiceMapper;
-import com.jeeplus.test.rank.domain.Rank;
 import com.jeeplus.test.workContract.mapper.WorkContractInfoMapper;
 import com.jeeplus.test.workContract.service.dto.WorkAttachmentDto;
 import org.flowable.editor.language.json.converter.util.CollectionUtils;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.RequestBody;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 @Service
 @Transactional
@@ -59,64 +62,187 @@ public class FinanceInvoiceService extends ServiceImpl<FinanceInvoiceMapper, Fin
     @Resource
     private WorkContractInfoMapper workContractInfoMapper;
 
+    public List<String> getSearchList(ArrayList<String> searchIdList, List<String> ids) {
+        List<String> newSearchIdList = searchIdList.stream().filter(item -> {
+            AtomicInteger num = new AtomicInteger();
+            ids.stream().forEach(id -> {
+                if (item.equals(id)) {
+                    num.getAndIncrement();
+                }
+            });
+            if (num.get() > 0) {
+                return true;
+            }
+            return false;
+        }).collect(Collectors.toList());
+        return newSearchIdList;
+    }
+
     public IPage<FinanceInvoiceDTO> findList(Page<FinanceInvoiceDTO> page, FinanceInvoiceDTO financeInvoiceDTO) throws Exception{
         QueryWrapper<FinanceInvoice> queryWrapper = QueryWrapperGenerator.buildQueryCondition ( FinanceInvoiceWrapper.INSTANCE.toEntity(financeInvoiceDTO), FinanceInvoice.class );
         queryWrapper.eq("fi.del_flag","0");
         ArrayList<String> searchIdList = new ArrayList<>();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        AtomicInteger checkNum = new AtomicInteger();
         if (ObjectUtil.isNotEmpty(financeInvoiceDTO)) {
             if (StringUtils.isNotBlank(financeInvoiceDTO.getNumber())) {
                 List<FinanceInvoiceDetail> financeInvoiceDetails = financeInvoiceDetailMapper.selectList(new LambdaQueryWrapper<FinanceInvoiceDetail>().like(FinanceInvoiceDetail::getNumber, financeInvoiceDTO.getNumber()));
                 List<String> ids = financeInvoiceDetails.stream().distinct().map(FinanceInvoiceDetail::getInvoiceId).collect(Collectors.toList());
-                ids.stream().forEach(item->{
-                    searchIdList.add(item);
-                });
+                if(CollectionUtil.isEmpty(ids)) {
+                    return new Page<FinanceInvoiceDTO>();
+                }else{
+                    if (CollectionUtil.isNotEmpty(searchIdList)){
+                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
+                        searchIdList = new ArrayList<String>();
+                        for (String item : newSearchIdList) {
+                            searchIdList.add(item);
+                        }
+                    }else{
+                        if (checkNum.get() > 0){
+                            return new Page<FinanceInvoiceDTO>();
+                        }else{
+                            for (String item : ids) {
+                                searchIdList.add(item);
+                            }
+                        }
+                    }
+                    checkNum.getAndIncrement();
+                }
             }
             if (StringUtils.isNotBlank(financeInvoiceDTO.getAccountBegin())&&StringUtils.isNotBlank(financeInvoiceDTO.getAccountEnd())) {
                 List<FinanceInvoice> financeInvoices = financeInvoiceMapper.selectList(new LambdaQueryWrapper<FinanceInvoice>()
-                        .between(FinanceInvoice::getAccount, financeInvoiceDTO.getAccountBegin(), financeInvoiceDTO.getAccountEnd()));
+                        .between(FinanceInvoice::getAccount, new BigDecimal(financeInvoiceDTO.getAccountBegin()), new BigDecimal(financeInvoiceDTO.getAccountEnd())));
                 List<String> ids = financeInvoices.stream().distinct().map(FinanceInvoice::getId).collect(Collectors.toList());
-                ids.stream().forEach(item->{
-                    searchIdList.add(item);
-                });
+                if(CollectionUtil.isEmpty(ids)) {
+                    return new Page<FinanceInvoiceDTO>();
+                }else{
+                    if (CollectionUtil.isNotEmpty(searchIdList)){
+                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
+                        searchIdList = new ArrayList<String>();
+                        for (String item : newSearchIdList) {
+                            searchIdList.add(item);
+                        }
+                    }else{
+                        if (checkNum.get() > 0){
+                            return new Page<FinanceInvoiceDTO>();
+                        }else{
+                            for (String item : ids) {
+                                searchIdList.add(item);
+                            }
+                        }
+                    }
+                    checkNum.getAndIncrement();
+                }
             }
             if (StringUtils.isNotBlank(financeInvoiceDTO.getBillingDateBegin())&&StringUtils.isNotBlank(financeInvoiceDTO.getBillingDateEnd())) {
                 List<FinanceInvoice> financeInvoices = financeInvoiceMapper.selectList(new LambdaQueryWrapper<FinanceInvoice>()
                         .between(FinanceInvoice::getBillingDate, sdf.parse(financeInvoiceDTO.getBillingDateBegin()), sdf.parse(financeInvoiceDTO.getBillingDateEnd())));
                 List<String> ids = financeInvoices.stream().distinct().map(FinanceInvoice::getId).collect(Collectors.toList());
-                ids.stream().forEach(item->{
-                    searchIdList.add(item);
-                });
+                if(CollectionUtil.isEmpty(ids)) {
+                    return new Page<FinanceInvoiceDTO>();
+                }else{
+                    if (CollectionUtil.isNotEmpty(searchIdList)){
+                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
+                        searchIdList = new ArrayList<String>();
+                        for (String item : newSearchIdList) {
+                            searchIdList.add(item);
+                        }
+                    }else{
+                        if (checkNum.get() > 0){
+                            return new Page<FinanceInvoiceDTO>();
+                        }else{
+                            for (String item : ids) {
+                                searchIdList.add(item);
+                            }
+                        }
+                    }
+                    checkNum.getAndIncrement();
+                }
             }
             if (StringUtils.isNotBlank(financeInvoiceDTO.getRemittanceDateBegin())&&StringUtils.isNotBlank(financeInvoiceDTO.getRemittanceDateEnd())) {
                 List<FinanceInvoice> financeInvoices = financeInvoiceMapper.selectList(new LambdaQueryWrapper<FinanceInvoice>()
                         .between(FinanceInvoice::getReceivablesDate, sdf.parse(financeInvoiceDTO.getRemittanceDateBegin()), sdf.parse(financeInvoiceDTO.getRemittanceDateEnd())));
                 List<String> ids = financeInvoices.stream().distinct().map(FinanceInvoice::getId).collect(Collectors.toList());
-                ids.stream().forEach(item->{
-                    searchIdList.add(item);
-                });
+                if(CollectionUtil.isEmpty(ids)) {
+                    return new Page<FinanceInvoiceDTO>();
+                }else{
+                    if (CollectionUtil.isNotEmpty(searchIdList)){
+                        List<String> newSearchIdList = getSearchList(searchIdList,ids);
+                        searchIdList = new ArrayList<String>();
+                        for (String item : newSearchIdList) {
+                            searchIdList.add(item);
+                        }
+                    }else{
+                        if (checkNum.get() > 0){
+                            return new Page<FinanceInvoiceDTO>();
+                        }else{
+                            for (String item : ids) {
+                                searchIdList.add(item);
+                            }
+                        }
+                    }
+                    checkNum.getAndIncrement();
+                }
             }
             if (StringUtils.isNotBlank(financeInvoiceDTO.getProgramId())||StringUtils.isNotBlank(financeInvoiceDTO.getProgramName())) {
                 if (StringUtils.isNotBlank(financeInvoiceDTO.getProgramId())){
                     List<FinanceInvoiceBase> financeInvoiceBaseList = financeInvoiceBaseMapper.selectList(new LambdaQueryWrapper<FinanceInvoiceBase>()
                             .eq(FinanceInvoiceBase::getProgramId,financeInvoiceDTO.getProgramId()));
                     List<String> ids = financeInvoiceBaseList.stream().distinct().map(FinanceInvoiceBase::getInvoiceId).collect(Collectors.toList());
-                    ids.stream().forEach(item->{
-                        searchIdList.add(item);
-                    });
+                    if(CollectionUtil.isEmpty(ids)) {
+                        return new Page<FinanceInvoiceDTO>();
+                    }else{
+                        if (CollectionUtil.isNotEmpty(searchIdList)){
+                            List<String> newSearchIdList = getSearchList(searchIdList,ids);
+                            searchIdList = new ArrayList<String>();
+                            for (String item : newSearchIdList) {
+                                searchIdList.add(item);
+                            }
+                        }else{
+                            if (checkNum.get() > 0){
+                                return new Page<FinanceInvoiceDTO>();
+                            }else{
+                                for (String item : ids) {
+                                    searchIdList.add(item);
+                                }
+                            }
+                        }
+                        checkNum.getAndIncrement();
+                    }
                 }else{
                     List<FinanceInvoiceBase> financeInvoiceBaseList = financeInvoiceBaseMapper.selectList(new LambdaQueryWrapper<FinanceInvoiceBase>()
-                            .eq(FinanceInvoiceBase::getProgramName,financeInvoiceDTO.getProgramName()));
+                            .like(FinanceInvoiceBase::getProgramName,financeInvoiceDTO.getProgramName()));
                     List<String> ids = financeInvoiceBaseList.stream().distinct().map(FinanceInvoiceBase::getInvoiceId).collect(Collectors.toList());
-                    ids.stream().forEach(item->{
-                        searchIdList.add(item);
-                    });
+                    if(CollectionUtil.isEmpty(ids)) {
+                        return new Page<FinanceInvoiceDTO>();
+                    }else{
+                        if (CollectionUtil.isNotEmpty(searchIdList)){
+                            List<String> newSearchIdList = getSearchList(searchIdList,ids);
+                            searchIdList = new ArrayList<String>();
+                            for (String item : newSearchIdList) {
+                                searchIdList.add(item);
+                            }
+                        }else{
+                            if (checkNum.get() > 0){
+                                return new Page<FinanceInvoiceDTO>();
+                            }else{
+                                for (String item : ids) {
+                                    searchIdList.add(item);
+                                }
+                            }
+                        }
+                        checkNum.getAndIncrement();
+                    }
                 }
             }
         }
         if (CollectionUtil.isNotEmpty(searchIdList)){
             List<String> ids = searchIdList.stream().distinct().collect(Collectors.toList());
             queryWrapper.in("fi.id",ids);
+        } else{
+            if (checkNum.get() > 0) {
+                return new Page<FinanceInvoiceDTO>();
+            }
         }
         return financeInvoiceMapper.findList(page,queryWrapper);
     }
@@ -148,6 +274,12 @@ public class FinanceInvoiceService extends ServiceImpl<FinanceInvoiceMapper, Fin
                 //发票编号生成
                 String serialNum = serialnumTplService.genSerialNum(userDTO.getCompanyDTO().getId(), FinanceInvoiceDTO.BIZ_CODE);
                 financeInvoice.setNo(serialNum);
+                if (StringUtils.isBlank(financeInvoice.getInvalidStatus())){
+                    financeInvoice.setInvalidStatus("0");
+                }
+                if (StringUtils.isBlank(financeInvoice.getReceivablesStatus())){
+                    financeInvoice.setReceivablesStatus("0");
+                }
             }
         }
         this.saveOrUpdate(financeInvoice);
@@ -360,4 +492,57 @@ public class FinanceInvoiceService extends ServiceImpl<FinanceInvoiceMapper, Fin
         financeInvoiceMapper.update(financeInvoice, new QueryWrapper<FinanceInvoice>().lambda().eq(FinanceInvoice::getId, financeInvoice.getId()));
         return "操作成功";
     }
+
+    public String importDecide(List<FinanceInvoiceDetailDTO> list, ArrayList<FinanceInvoiceDetailDTO> arrayList, HashMap<String,String> hashMap){
+        for (FinanceInvoiceDetailDTO financeInvoiceDetailDTO : list) {
+            if(ObjectUtil.isEmpty(financeInvoiceDetailDTO)){
+                continue;
+            }
+
+            if(StringUtils.isBlank(financeInvoiceDetailDTO.getNumber())){
+                return "文件中有发票号为空,请重新填写";
+            }
+            if(StringUtils.isNotBlank(financeInvoiceDetailDTO.getNumber())){
+                try {
+                    Integer integer = new Integer(financeInvoiceDetailDTO.getNumber());
+                    if (integer < 0) {
+                        return "文件中有发票号填写不正确,请重新填写";
+                    }
+                }catch (Exception e){
+                    return "文件中有发票号填写不正确,请重新填写";
+                }
+                List<FinanceInvoiceDetail> financeInvoiceDetailList = financeInvoiceDetailMapper.selectList(new QueryWrapper<FinanceInvoiceDetail>().eq("number", financeInvoiceDetailDTO.getNumber()));
+                if(CollectionUtil.isNotEmpty(financeInvoiceDetailList)){
+                    return "文件中有发票号已在系统中存在,请重新填写";
+                }
+            }
+//            if (StringUtils.isBlank(financeInvoiceDetailDTO.getRate())) {
+//                return "文件中有税率为空,请重新填写";
+//            }
+            if (StringUtils.isNotBlank(financeInvoiceDetailDTO.getRate())) {
+                try {
+                    if ((new BigDecimal(financeInvoiceDetailDTO.getRate())).compareTo(new BigDecimal(0)) == -1
+                            || (new BigDecimal(financeInvoiceDetailDTO.getRate())).compareTo(new BigDecimal(100)) == 1) {
+                        return "文件中有税率填写不正确,请重新填写";
+                    }
+                }catch (Exception e){
+                    return "文件中有税率填写不正确,请重新填写";
+                }
+            }
+            if (StringUtils.isBlank(financeInvoiceDetailDTO.getAccount())) {
+                return "文件中有开票金额为空,请重新填写";
+            } else {
+                try {
+                    financeInvoiceDetailDTO.setAccount(new BigDecimal(financeInvoiceDetailDTO.getAccount()).toString());
+                }catch (Exception e){
+                    return "文件中有开票金额填写不正确,请重新填写";
+                }
+            }
+
+            hashMap.put(financeInvoiceDetailDTO.getNumber(),null);
+
+            arrayList.add(financeInvoiceDetailDTO);
+        }
+        return null;
+    }
 }

+ 11 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/finance/invoice/service/dto/FinanceInvoiceDetailDTO.java

@@ -1,5 +1,6 @@
 package com.jeeplus.test.finance.invoice.service.dto;
 
+import cn.afterturn.easypoi.excel.annotation.Excel;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.jeeplus.core.domain.BaseEntity;
 import com.jeeplus.core.service.dto.BaseDTO;
@@ -27,21 +28,25 @@ public class FinanceInvoiceDetailDTO extends BaseDTO {
     /**
      * 发票代码
      */
+    @Excel(name = "发票代码",width = 25)
     private String code;
 
     /**
      * 发票号
      */
+    @Excel(name = "发票号",width = 25)
     private String number;
 
     /**
      * 开票金额(元)
      */
+    @Excel(name = "开票金额(元)",width = 25)
     private String account;
 
     /**
      * 税率
      */
+    @Excel(name = "税率(%)",width = 25)
     private String rate;
 
     /**
@@ -59,5 +64,11 @@ public class FinanceInvoiceDetailDTO extends BaseDTO {
      */
     private String allAmount;
 
+    /**
+     * 纳税人识别号
+     */
+    @Excel(name = "纳税人识别号",width = 25)
+    private String taxpayerIdentificationNo;
+
     private static final long serialVersionUID = 1L;
 }