123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- package com.pj.api.invoice.service;
- import cn.hutool.core.bean.BeanUtil;
- import cn.hutool.core.codec.Base64;
- import cn.hutool.core.date.DateUtil;
- import cn.hutool.core.lang.Snowflake;
- import cn.hutool.core.util.IdUtil;
- import cn.hutool.core.util.StrUtil;
- import cn.hutool.http.HttpUtil;
- import cn.hutool.json.JSON;
- import cn.hutool.json.JSONArray;
- import cn.hutool.json.JSONObject;
- import cn.hutool.json.JSONUtil;
- import com.pj.api.invoice.bo.InvoiceApply;
- import com.pj.api.invoice.bo.InvoiceApplyCallBackSub;
- import com.pj.api.invoice.bo.InvoiceApplySub;
- import com.pj.api.invoice.bo.InvoiceApplySubDetail;
- import com.pj.api.invoice.utils.InvoiceUtils;
- import com.pj.api.wx.bo.Attach;
- import com.pj.api.wx.bo.PriceBO;
- import com.pj.current.config.InvoiceConfig;
- import com.pj.project.tb_fee_details.TbFeeDetails;
- import com.pj.project.tb_fee_details.TbFeeDetailsService;
- import com.pj.project.tb_fee_statistics.TbFeeStatistics;
- import com.pj.project.tb_invoice_details.TbInvoiceDetails;
- import com.pj.project.tb_invoice_details.TbInvoiceDetailsService;
- import com.pj.project.tb_invoice_info.TbInvoiceInfo;
- import com.pj.project.tb_invoice_info.TbInvoiceInfoService;
- import com.pj.project.tb_invoice_info.dto.FeeDeatilsGroup;
- import com.pj.project.tb_invoice_order.TbInvoiceOrder;
- import com.pj.project.tb_invoice_order.TbInvoiceOrderService;
- import com.pj.project.tb_order.TbOrder;
- import com.pj.project.tb_order.TbOrderService;
- import com.pj.project4sp.global.BusinessException;
- import com.pj.utils.sg.AjaxError;
- import com.pj.utils.so.SoMap;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.scheduling.annotation.Async;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import javax.annotation.Resource;
- import java.math.BigDecimal;
- import java.util.*;
- import java.util.stream.Collectors;
- /**
- * Created with IntelliJ IDEA.
- *
- * @Auther: lzm
- * @Date: 2022/08/09/14:51
- * @Description:
- */
- @Service
- @Transactional
- @Slf4j
- public class InvoiceApplyService {
- @Resource
- TbInvoiceDetailsService tbInvoiceDetailsService;
- @Resource
- TbInvoiceInfoService tbInvoiceInfoService;
- @Resource
- TbInvoiceOrderService tbInvoiceOrderService;
- @Resource
- TbFeeDetailsService tbFeeDetailsService;
- @Resource
- InvoiceConfig invoiceConfig;
- public String applyInvoice(String infoId) {
- String code = this.preApply(infoId);
- if (!StrUtil.equals("200", code)) {
- throw new BusinessException("开票申请推送失败!");
- }
- return code;
- }
- public String preApply(String infoId) {
- Date now = new Date();
- Map<String, String> param = new HashMap<>();
- param.put("action", invoiceConfig.getApplyAction());
- param.put("appid", invoiceConfig.getAppId());
- param.put("timestamp", InvoiceUtils.date2StrByInt(now, "yyyyMMddHHmmssFFF"));
- param.put("transid", InvoiceUtils.genTransId());
- String sign = InvoiceUtils.createSign(InvoiceUtils.getSortedMap(param), invoiceConfig.getAppSecret());
- param.put("sign", sign);
- //拼装请求url
- String url = InvoiceUtils.getUrl(invoiceConfig.getApplyUrl(), param);
- TbInvoiceInfo info = tbInvoiceInfoService.getById(infoId);
- List<TbInvoiceDetails> invoiceDetails = tbInvoiceDetailsService.findByInfoId(infoId);
- //开始组装接口参数
- InvoiceApply invoiceApply = new InvoiceApply();
- invoiceApply.setRequestId(now.getTime() + "")
- .setBusinessSystemCode("SW_TEST")
- .setInterfaceCode("BILL.PUSH");
- List<InvoiceApplySub> applys = new ArrayList<>();
- for (TbInvoiceDetails invoiceDetail : invoiceDetails) {
- InvoiceApplySub apply = new InvoiceApplySub();
- apply.setBillNo(invoiceDetail.getId()).setPayType("微信支付")
- .setBillDate(DateUtil.format(now, "yyyy-MM-dd"))
- .setTotalAmount(invoiceDetail.getMoney()).setIncludeTaxFlag(1)
- .setAutoInvoice(1).setAutoMerge(1)
- .setInvoiceType("026")
- .setBuyerName(info.getEntityName()).setBuyerTaxpayerId(info.getTaxIdNo())
- .setBuyerRecipientMail(info.getEmail())
- .setBuyerProperty(0)
- .setBuyerBankAndAccount(info.getBank() + info.getBankNo())
- .setTextField1(info.getCustomerName())
- .setSellerName(invoiceConfig.getSellerName())
- .setSellerTaxpayerId(invoiceConfig.getSellerTaxpayerId())
- .setTaxationStyle(0)
- .setDrawer(invoiceConfig.getDrawer())
- .setPayee(invoiceConfig.getPayee()).setReviewer(invoiceConfig.getReviewer());
- //将所有开票订单的收费明细放在一个集合中,并对其分组
- List<TbInvoiceOrder> orders = tbInvoiceOrderService.findByDetailId(invoiceDetail.getId());
- List<FeeDeatilsGroup> feeDetailsGroupList = grouping(orders);
- List<InvoiceApplySubDetail> applyDetails = new ArrayList<>();
- Snowflake snowflake = IdUtil.getSnowflake(1, 1);
- for (FeeDeatilsGroup group : feeDetailsGroupList) {
- String detailId = snowflake.nextIdStr();
- InvoiceApplySubDetail applyDetail = new InvoiceApplySubDetail();
- applyDetail.setAmount(group.getItemPrice())
- .setDetailId(detailId)
- .setGoodsName(group.getItemTypeName())
- .setLineProperty(2)
- .setQuantity(group.getNum())
- .setPrice(group.getUnitPrice())
- .setTaxRate(group.getTaxRate().toString());
- if (StrUtil.equals("0.09", applyDetail.getTaxRate())) {
- applyDetail.setRevenueCode(invoiceConfig.getCarTaxRateCode());
- } else {
- applyDetail.setRevenueCode(invoiceConfig.getBusinessTaxRateCode());
- }
- applyDetails.add(applyDetail);
- }
- apply.setBillDetail(applyDetails);
- applys.add(apply);
- }
- log.info("invoice apply url:" + url);
- String applysJson = JSONUtil.toJsonStr(applys);
- log.info("invoice apply data:" + applysJson);
- String applysBase64 = Base64.encode(applysJson);
- invoiceApply.setData(applysBase64);
- String paramStr = JSONUtil.toJsonStr(invoiceApply);
- log.info("invoice apply paramStr:" + paramStr);
- String result = HttpUtil.createPost(url).header("Content-Type", "application/json").body(paramStr).execute().body();
- log.info("invoice apply result:" + result);
- JSONObject jsonResult = JSONUtil.parseObj(result);
- if (StrUtil.equals("0", jsonResult.getStr("code"))) {
- info.setApplyAble(1).setStatus(2);
- tbInvoiceInfoService.updateById(info);
- return "200";
- } else {
- throw new AjaxError("开票失败");
- }
- }
- private List<FeeDeatilsGroup> grouping(List<TbInvoiceOrder> invoiceOrderList) {
- List<TbFeeDetails> feeDetailsList = new ArrayList<>();
- for (TbInvoiceOrder invoiceOrder : invoiceOrderList) {
- List<TbFeeDetails> detailsList = tbFeeDetailsService.findByTransactionId(invoiceOrder.getTransactionId());
- feeDetailsList.addAll(detailsList);
- }
- List<FeeDeatilsGroup> list = new ArrayList<>();
- for (TbFeeDetails detail : feeDetailsList) {
- FeeDeatilsGroup group = new FeeDeatilsGroup();
- BeanUtil.copyProperties(detail, group);
- String hash = (detail.getItemTypeName() + detail.getUnitPrice()).hashCode() + "";
- group.setGroupHash(hash);
- list.add(group);
- }
- Map<String, List<FeeDeatilsGroup>> collect = list.stream()
- .collect(Collectors.groupingBy(FeeDeatilsGroup::getGroupHash));
- List<FeeDeatilsGroup> completeGroups = new ArrayList<>();
- for (String key : collect.keySet()) {
- List<FeeDeatilsGroup> partGroups = collect.get(key);
- FeeDeatilsGroup realGroup = new FeeDeatilsGroup();
- realGroup.setItemTypeName(partGroups.get(0).getItemTypeName())
- .setUnitPrice(partGroups.get(0).getUnitPrice())
- .setTaxRate(partGroups.get(0).getTaxRate());
- for (FeeDeatilsGroup partGroup : partGroups) {
- realGroup.setItemPrice(realGroup.getItemPrice().add(partGroup.getItemPrice()))
- .setNoTaxPrice(realGroup.getNoTaxPrice().add(partGroup.getNoTaxPrice()))
- .setTaxPrice(realGroup.getTaxPrice().add(partGroup.getTaxPrice()))
- .setNum(realGroup.getNum() + partGroup.getNum());
- }
- completeGroups.add(realGroup);
- }
- return completeGroups;
- }
- public synchronized Map<String, Object> callBack(String sub) {
- log.info("进入开票回调:");
- Map<String, Object> map = new LinkedHashMap<>();
- JSONObject jsonObject = JSONUtil.parseObj(sub);
- InvoiceApplyCallBackSub callBackSub = JSONUtil.toBean(jsonObject, InvoiceApplyCallBackSub.class);
- TbInvoiceDetails invoiceDetail = tbInvoiceDetailsService.getById(callBackSub.getBillNo());
- if (invoiceDetail == null) {
- log.info("开票信息子记录{}不存在:", callBackSub.getBillNo());
- map.put("code", 500);
- map.put("message", "失败,开票信息数据异常");
- return map;
- }
- if (invoiceDetail.getIsApply() == 2) {
- log.info("重复回调,开票信息子记录{}已开票成功:", callBackSub.getBillNo());
- } else {
- invoiceDetail.setIsApply(2).setInvoiceNo(callBackSub.getInvoiceNum())
- .setInvoiceCode(callBackSub.getInvoiceCode())
- .setFileUrl(callBackSub.getInvoiceFileUrl()).setImageUrl(callBackSub.getInvoiceImageUrl());
- tbInvoiceDetailsService.updateById(invoiceDetail);
- TbInvoiceInfo info = tbInvoiceInfoService.getById(invoiceDetail.getInfoId());
- // List<TbInvoiceDetails> infoAllDetails = tbInvoiceDetailsService.findByInfoId(info.getId());
- // String newInvoiceNo = "";
- // for (TbInvoiceDetails detail : infoAllDetails) {
- // newInvoiceNo = StrUtil.isEmpty(newInvoiceNo) ?
- // detail.getInvoiceNo() : newInvoiceNo+","+detail.getInvoiceNo();
- // }
- String status = callBackSub.getInvoiceStatus();
- if ("0".equals(status)) {
- //开票成功
- info.setStatus(1);
- info.setIsApply(2);
- } else if ("".equals(status)){
- info.setStatus(Integer.parseInt(status));
- }
- tbInvoiceInfoService.updateById(info);
- String oldInvoiceNo = info.getInvoiceNo();
- String newInvoiceNo = StrUtil.isEmpty(oldInvoiceNo) ?
- callBackSub.getInvoiceNum() : oldInvoiceNo + "," + callBackSub.getInvoiceNum();
- SoMap so = new SoMap();
- so.put("id", info.getId());
- so.put("invoiceTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
- so.put("invoiceNo", newInvoiceNo);
- tbInvoiceInfoService.complete(so);
- }
- map.put("code", 200);
- map.put("message", "成功");
- return map;
- }
- }
|