新增开票接口

This commit is contained in:
2024-08-16 04:32:36 +08:00
parent e17c5c538b
commit 7198cf3332
13 changed files with 442 additions and 16 deletions
@@ -1,22 +1,32 @@
package com.gxwebsoft.think.controller;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.think.service.ThinkInvoiceService;
import com.gxwebsoft.think.entity.ThinkInvoice;
import com.gxwebsoft.think.param.ThinkInvoiceParam;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gxwebsoft.common.core.utils.JSONUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.think.entity.*;
import com.gxwebsoft.think.param.ThinkInvoiceParam;
import com.gxwebsoft.think.service.ThinkInvoiceService;
import com.gxwebsoft.think.service.ThinkOrderInfoService;
import com.gxwebsoft.think.service.ThinkOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import nuonuo.open.sdk.NNOpenSDK;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
/**
* 控制器
@@ -30,6 +40,10 @@ import java.util.List;
public class ThinkInvoiceController extends BaseController {
@Resource
private ThinkInvoiceService thinkInvoiceService;
@Resource
private ThinkOrderService thinkOrderService;
@Resource
private ThinkOrderInfoService thinkOrderInfoService;
@ApiOperation("分页查询")
@GetMapping("/page")
@@ -107,4 +121,125 @@ public class ThinkInvoiceController extends BaseController {
return fail("删除失败");
}
@ApiOperation("开具发票")
@PostMapping("/doInvoice")
public ApiResult<?> doInvoice(@RequestBody ThinkInvoice thinkInvoice) {
System.out.println("thinkInvoice = " + thinkInvoice);
final Integer oid = thinkInvoice.getOid();
final ThinkOrder thinkOrder = thinkOrderService.getById(thinkInvoice.getOid());
System.out.println("thinkOrder = " + thinkOrder);
final List<ThinkOrderInfo> orderInfos = thinkOrderInfoService.list(new LambdaQueryWrapper<ThinkOrderInfo>().eq(ThinkOrderInfo::getOid,thinkInvoice.getOid()));
// 开票接口
NNOpenSDK sdk = NNOpenSDK.getIntance();
String taxnum = "339901999999142";//ISV下授权商户税号,自用型应用置""即可
String appKey = "SD56531018";
String appSecret = "SD3C429B318C485E";
String method = "nuonuo.OpeMplatform.requestBillingNew";//API方法名
String token = NNOpenSDK.getIntance().getMerchantToken("SD56531018", "SD3C429B318C485E"); //访问令牌
final NuoNuo nuoNuo = new NuoNuo();
final NuoNuoOrder order = new NuoNuoOrder();
order.setBuyerName(thinkInvoice.getName());
order.setBuyerTaxNum(thinkInvoice.getCode());
// order.setBuyerPhone(thinkInvoice.getPhone());
// order.setSalerTaxNum(invoice.getInvoiceCode());
// order.setSalerTel(invoice.getPhone());
order.setSalerTaxNum("339901999999142"); // 91450100737617400R
order.setSalerTel("339901999999142");
order.setOrderNo(thinkOrder.getOrderNum());
order.setInvoiceDate(DateUtil.now());
order.setClerk("赵裕璐");
order.setPayee("班嘉良");
order.setChecker("蓝蕙孚");
order.setBuyerPhone(thinkInvoice.getPhone());
order.setInvoiceType(String.valueOf(thinkInvoice.getInvoicetype()));
order.setRemark("不动产地址:广西壮族自治区南宁市良庆区五象大道西段669号广西体育中心综合馆;(市)标志:否;");
final NuoNuoGoods goods = new NuoNuoGoods();
goods.setGoodsName("场地费");
goods.setGoodsCode("3040502029902000000");
goods.setWithTaxFlag("0");
if (!CollectionUtils.isEmpty(orderInfos)) {
final ThinkOrderInfo thinkOrderInfo = orderInfos.get(0);
if (thinkOrderInfo != null) {
goods.setDField1(thinkOrderInfo.getDateTime());
}
}
goods.setDField2("无");
goods.setDField3("无");
goods.setDField4("无");
goods.setDField5("无");
goods.setTaxRate(new BigDecimal("0.05").toString());
final BigDecimal taxExcludedAmount = thinkOrder.getTotalPrice().divide(new BigDecimal("1.05"), 4, RoundingMode.HALF_UP);
final BigDecimal tax = taxExcludedAmount.multiply(new BigDecimal("0.05")).setScale(4,RoundingMode.HALF_EVEN);
goods.setTax(tax.toString());
goods.setTaxExcludedAmount(taxExcludedAmount.toString());
goods.setTaxIncludedAmount(thinkOrder.getTotalPrice().toString());
order.setInvoiceDetail(goods);
System.out.println("税额 = " + tax);
System.out.println("不含税金额 = " + taxExcludedAmount);
System.out.println("含税金额 = " + thinkOrder.getTotalPrice());
nuoNuo.setOrder(order);
String content = JSONUtil.toJSONString(nuoNuo);//API私有请求参数
String url = "https://sandbox.nuonuocs.cn/open/v1/services"; //SDK请求地址
String senid = UUID.randomUUID().toString(); // 唯一标识,由企业自己生成32位随机码
String json = sdk.sendPostSyncRequest(url, senid, appKey, appSecret, token, taxnum, method, content); // 请求API
System.out.println("json = " + json);
if (StrUtil.isNotBlank(json)) {
final JSONObject jsonObject = JSONObject.parseObject(json);
final String code = jsonObject.getString("code");
final String result = jsonObject.getString("result");
System.out.println("jsonObject = " + jsonObject);
if (code.equals("E0000")) {
final JSONObject resNo = JSONObject.parseObject(result);
final String invoiceSerialNum = resNo.getString("invoiceSerialNum");
thinkOrder.setIsInvoice(1);
thinkOrderService.updateById(thinkOrder);
System.out.println("invoiceSerialNum = " + invoiceSerialNum);
thinkInvoice.setId(null);
thinkInvoice.setIncoiveNum(invoiceSerialNum);
thinkInvoice.setIncoiveCode("339901999999142");
thinkInvoice.setUid(thinkOrder.getUid());
thinkInvoice.setCreateTime(System.currentTimeMillis()/1000);
thinkInvoiceService.save(thinkInvoice);
return success("发票开具成功", json);
}
}
return fail("发票开具失败");
}
@ApiOperation("根据id查询发票")
@GetMapping("/showInvoice/{orderId}")
public ApiResult<?> showInvoice(@PathVariable("orderId") Integer orderId) {
final ThinkInvoice thinkInvoice = thinkInvoiceService.getOne(new LambdaQueryWrapper<ThinkInvoice>().eq(ThinkInvoice::getOid,orderId));
System.out.println("thinkInvoice = " + thinkInvoice);
NNOpenSDK sdk = NNOpenSDK.getIntance();
String taxnum = "339901999999142";//ISV下授权商户税号,自用型应用置""即可
String appKey = "SD56531018";
String appSecret = "SD3C429B318C485E";
String method = "nuonuo.OpeMplatform.queryInvoiceResult";//API方法名
String token = NNOpenSDK.getIntance().getMerchantToken("SD56531018", "SD3C429B318C485E"); //访问令牌
HashMap<String, Object> map = new HashMap<>();
// map.put("invoiceCode",invoiceNo);
map.put("serialNos", thinkInvoice.getIncoiveNum());
// map.put("inTaxAmount", order.getPayPrice().subtract(order.getPayPrice().multiply(new BigDecimal("0.06")))); // 含税金额
// map.put("exTaxAmount", order.getPayPrice()); // 不含税金额
System.out.println("map = " + map);
String content = JSONUtil.toJSONString(map);//API私有请求参数
String url = "https://sandbox.nuonuocs.cn/open/v1/services"; //SDK请求地址
String senid = UUID.randomUUID().toString(); // 唯一标识,由企业自己生成32位随机码
String result = sdk.sendPostSyncRequest(url, senid, appKey, appSecret, token, taxnum, method, content);
System.out.println("result = " + result);
final JSONObject jsonObject = JSONObject.parseObject(result);
final String code = jsonObject.getString("code");
final String body = jsonObject.getString("result");
if (code.equals("E0000")) {
return success("查询成功", body);
}
return success("查询失败", result);
}
}
@@ -0,0 +1,26 @@
package com.gxwebsoft.think.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 发票
*
* @author 科技小王子
* @since 2024-05-25 17:20:15
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "NuoNuo开票对象", description = "开票对象")
public class NuoNuo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "订单信息")
@TableField(exist = false)
private NuoNuoOrder order;
}
@@ -0,0 +1,71 @@
package com.gxwebsoft.think.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 发票
*
* @author 科技小王子
* @since 2024-05-25 17:20:15
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "NuoNuo开票对象", description = "开票对象")
public class NuoNuoGoods implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "商品名称")
@TableField(exist = false)
private String goodsName;
@ApiModelProperty(value = "服务分类")
@TableField(exist = false)
private String goodsCode;
@ApiModelProperty(value = "单价含税标志:0:不含税,1:含税")
@TableField(exist = false)
private String withTaxFlag;
@ApiModelProperty(value = "税额")
@TableField(exist = false)
private String tax;
@ApiModelProperty(value = "税率,注:1、纸票清单红票存在为null的情况;2、二手车发票税率为null或者0")
@TableField(exist = false)
private String taxRate;
@ApiModelProperty(value = "不含税金额")
@TableField(exist = false)
private String taxExcludedAmount;
@ApiModelProperty(value = "含税金额")
@TableField(exist = false)
private String taxIncludedAmount;
@ApiModelProperty(value = "业务方明细自定义字段1,本应用只作保存")
@TableField(exist = false)
private String dField1;
@ApiModelProperty(value = "业务方明细自定义字段1,本应用只作保存")
@TableField(exist = false)
private String dField2;
@ApiModelProperty(value = "业务方明细自定义字段1,本应用只作保存")
@TableField(exist = false)
private String dField3;
@ApiModelProperty(value = "业务方明细自定义字段1,本应用只作保存")
@TableField(exist = false)
private String dField4;
@ApiModelProperty(value = "业务方明细自定义字段1,本应用只作保存")
@TableField(exist = false)
private String dField5;
}
@@ -0,0 +1,90 @@
package com.gxwebsoft.think.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 发票
*
* @author 科技小王子
* @since 2024-05-25 17:20:15
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "NuoNuo开票对象", description = "开票对象")
@TableName("booking_user_invoice")
public class NuoNuoOrder implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "购方名称")
@TableField(exist = false)
private String buyerName;
@ApiModelProperty(value = "购方税号")
@TableField(exist = false)
private String buyerTaxNum;
@ApiModelProperty(value = "销方税号号(使用沙箱环境请求时消息体参数salerTaxNum和消息头参数userTax填写339902999999789113)")
@TableField(exist = false)
private String salerTaxNum;
@ApiModelProperty(value = "销方电话")
@TableField(exist = false)
private String salerTel;
@ApiModelProperty(value = "销方地址")
@TableField(exist = false)
private String salerAddress;
@ApiModelProperty(value = "订单编号")
@TableField(exist = false)
private String orderNo;
@ApiModelProperty(value = "订单时间")
@TableField(exist = false)
private String invoiceDate;
@ApiModelProperty(value = "开票员")
@TableField(exist = false)
private String clerk;
@ApiModelProperty(value = "收款人")
@TableField(exist = false)
private String payee;
@ApiModelProperty(value = "复核人")
@TableField(exist = false)
private String checker;
@ApiModelProperty(value = "备注信息")
@TableField(exist = false)
private String remark;
@ApiModelProperty(value = "购方手机号")
@TableField(exist = false)
private String buyerPhone;
@ApiModelProperty(value = "推送邮箱")
@TableField(exist = false)
private String email;
@ApiModelProperty(value = "开票类型:1:蓝票;2:红票 (数电票冲红请对接数电快捷冲红接口)")
@TableField(exist = false)
private String invoiceType;
@ApiModelProperty(value = "开票明细")
@TableField(exist = false)
private NuoNuoGoods invoiceDetail;
@ApiModelProperty(value = "完整字段名invoiceTractorAndCombineHarvester,开具拖拉机和联合收割机特定要素的数电票才需要传specificFactor =13)")
@TableField(exist = false)
private String invoiceTractorAndCombineH;
}
@@ -0,0 +1,34 @@
package com.gxwebsoft.think.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 发票
*
* @author 科技小王子
* @since 2024-05-25 17:20:15
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "NuoNuo开票对象", description = "开票对象")
public class NuoNuoResult implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "编码")
@TableField(exist = false)
private String code;
@ApiModelProperty(value = "描述")
@TableField(exist = false)
private String describe;
@ApiModelProperty(value = "返回结果")
@TableField(exist = false)
private String result;
}
@@ -0,0 +1,26 @@
package com.gxwebsoft.think.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
* 发票
*
* @author 科技小王子
* @since 2024-05-25 17:20:15
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "NuoNuo开票对象", description = "开票对象")
public class NuoNuoResultNo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "发票流水号")
@TableField(exist = false)
private String invoiceSerialNum;
}
@@ -80,9 +80,9 @@ public class ThinkInvoice implements Serializable {
@ApiModelProperty(value = "发票类型:1场地发票,2vip卡发票,3ic卡发票")
private Integer itype;
private Integer createTime;
private Long createTime;
private Integer updateTime;
private Long updateTime;
@ApiModelProperty(value = "1.普票,2是专票")
@TableField("InvoiceType")
@@ -103,6 +103,7 @@ public class ThinkOrder implements Serializable {
private String qrcode;
@ApiModelProperty(value = "优惠说明")
@TableField("`desc`")
private String desc;
@ApiModelProperty(value = "vip月卡年卡、ic月卡年卡回退次数")
@@ -126,7 +126,7 @@
AND a.check_bill = #{param.checkBill}
</if>
<if test="param.keywords != null">
AND (a.name LIKE CONCAT('%', #{param.keywords}, '%')
AND (a.name = #{param.keywords}
OR a.id = #{param.keywords}
OR a.order_num = #{param.keywords}
OR a.phone = #{param.keywords}
@@ -33,6 +33,12 @@
<if test="param.createTimeEnd != null">
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
<if test="param.timeStart != null">
AND a.create_time &gt;= #{param.timeStart}
</if>
<if test="param.timeEnd != null">
AND a.create_time &lt;= #{param.timeEnd}
</if>
<if test="param.vid != null">
AND a.vid = #{param.vid}
</if>
@@ -43,9 +49,13 @@
AND a.check_bill = #{param.checkBill}
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
AND (a.wechat_order = #{param.keywords}
OR a.order_num = #{param.keywords}
OR b.phone = #{param.keywords}
OR b.truename = #{param.keywords}
OR a.vid = #{param.keywords}
)
</if>
</where>
</sql>
@@ -1,15 +1,23 @@
package com.gxwebsoft.think.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.think.entity.ThinkSite;
import com.gxwebsoft.think.mapper.ThinkRechargeLogMapper;
import com.gxwebsoft.think.service.ThinkRechargeLogService;
import com.gxwebsoft.think.entity.ThinkRechargeLog;
import com.gxwebsoft.think.param.ThinkRechargeLogParam;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.think.service.ThinkSiteService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Service实现
@@ -19,12 +27,28 @@ import java.util.List;
*/
@Service
public class ThinkRechargeLogServiceImpl extends ServiceImpl<ThinkRechargeLogMapper, ThinkRechargeLog> implements ThinkRechargeLogService {
@Resource
private ThinkSiteService thinkSiteService;
@Override
public PageResult<ThinkRechargeLog> pageRel(ThinkRechargeLogParam param) {
PageParam<ThinkRechargeLog, ThinkRechargeLogParam> page = new PageParam<>(param);
page.setDefaultOrder("create_time desc");
List<ThinkRechargeLog> list = baseMapper.selectPageRel(page, param);
final List<ThinkSite> sites = thinkSiteService.list(new LambdaQueryWrapper<ThinkSite>().select(ThinkSite::getId,ThinkSite::getName));
final Map<Integer, List<ThinkSite>> collect = sites.stream().collect(Collectors.groupingBy(ThinkSite::getId));
list.forEach(d -> {
final ArrayList<String> siteNames = new ArrayList<>();
final String sid = d.getSid();
final String[] split = sid.split(",");
for(String siteId : split){
final List<ThinkSite> thinkSites = collect.get(Integer.valueOf(siteId));
if (!CollectionUtils.isEmpty(thinkSites)) {
final String name = thinkSites.get(0).getName();
siteNames.add(name);
}
}
d.setSiteNames(String.join(",",siteNames));
});
return new PageResult<>(list, page.getTotal());
}