Commit f56e95cf authored by hanfeng's avatar hanfeng

开票

parent 2840ae43
......@@ -113,9 +113,15 @@ public class Invoice {
*/
private String salerTaxCode;
/**
* 销售方地址电话
* 销售方地址
*/
private String salerAddressPhone;
private String salerAddress;
/**
* 销售方电话
*/
private String salerPhone;
/**
* 销售方银行及账户
*/
......
package com.xxfc.platform.universal.entity;
import lombok.Data;
import javax.persistence.Table;
import java.util.Date;
/**
* 发票最终查询结果,错误记录表
* @author Administrator
*/
@Data
@Table(name = "invoice_query_error")
public class InvoiceQueryError {
private Integer id;
private Integer invoiceId;
private String invoiceSerialNum;
private Integer status;
private Date creTime;
}
......@@ -20,7 +20,7 @@ public class OrderData {
*/
private Integer num;
/**
* 是否含税价格
* 是否含税价格 0:不含税,1:含税
*/
private Integer withTaxFlag=1;
/**
......@@ -30,7 +30,7 @@ public class OrderData {
/**
* 税率
*/
private Double taxRate;
private BigDecimal taxRate;
/**
* 单位
......
package com.xxfc.platform.universal.biz;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.xxfc.platform.universal.entity.InvoiceQueryError;
import com.xxfc.platform.universal.mapper.InvoiceQueryErrorMapper;
/**
* @Auther: Administrator
* @Date: 2020/1/8 10:48
* @Description:
*/
public class InvoiceQueryErrorBiz extends BaseBiz<InvoiceQueryErrorMapper, InvoiceQueryError> {
}
......@@ -51,7 +51,7 @@ public class InvoiceController extends BaseController<InvoiceBiz, Invoice> {
@GetMapping("/result")
public ObjectRestResponse invoiceResult(@RequestParam("invoiceSerialNum")String invoiceSerialNum){
String result= baseBiz.invoiceResult(invoiceSerialNum);
List<Map<String,Object>> result= baseBiz.invoiceResult(invoiceSerialNum);
return ObjectRestResponse.succ(result);
}
}
package com.xxfc.platform.universal.mapper;
import com.xxfc.platform.universal.entity.InvoiceQueryError;
import tk.mybatis.mapper.common.Mapper;
/**
* @author Administrator
* @Date: 2020/1/8 10:49
* @Description:
*/
public interface InvoiceQueryErrorMapper extends Mapper<InvoiceQueryError> {
}
package com.xxfc.platform.universal.service;
import com.alibaba.druid.sql.visitor.functions.If;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.auth.client.config.UserAuthConfig;
import com.github.wxiaoqi.security.auth.client.jwt.UserAuthUtil;
import com.github.wxiaoqi.security.auth.common.util.jwt.IJWTInfo;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.xxfc.platform.order.feign.OrderFeign;
import com.xxfc.platform.universal.biz.InvoiceQueryErrorBiz;
import com.xxfc.platform.universal.constant.InvoiceStatusEum;
import com.xxfc.platform.universal.entity.Invoice;
import com.xxfc.platform.universal.entity.InvoiceQueryError;
import com.xxfc.platform.universal.entity.OrderData;
import com.xxfc.platform.universal.entity.vo.InvoiceVo;
import com.xxfc.platform.universal.mapper.InvoiceMapper;
......@@ -17,8 +21,11 @@ import com.xxfc.platform.universal.utils.NumberToCN;
import com.xxfc.platform.universal.utils.SnowflakeIdWorker;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
......@@ -45,29 +52,37 @@ public class InvoiceBiz extends BaseBiz<InvoiceMapper, Invoice> {
private final UserAuthConfig userAuthConfig;
private final HttpServletRequest request;
private final UserAuthUtil userAuthUtil;
private final SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(0,0);
private final ThreadPoolTaskExecutor taskExecutor;
private final InvoiceQueryErrorBiz invoiceQueryErrorBiz;
private final OrderFeign orderFeign;
private static final SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(0, 0);
private static final String salerName = "欣新房车网络科技(广东)股份有限公司";
//正式
// private static final String salerTaxNum="91441900MA53C6713X";
@Value("${invoice.salerName}")
private String salerName;
@Value("${invoice.salerTel}")
private String salerTel;
@Value("${invoice.salerTaxNum}")
private String salerTaxNum;
@Value("${invoice.salerAddress}")
private String salerAddress;
@Value("${invoice.salerAccount}")
private String salerAccount;
/**
* 收款人
*/
@Value("${invoice.payee}")
private String payee;
/**
* 复核人
*/
@Value("${invoice.checker}")
private String checker;
/**
* 测试
* 开票人
*/
private static final String salerTaxNum = "339901999999142";
private static final String salerTel = "13926892766";
private static final String salerAddress = "广东省东莞市松山湖园区科汇路1号1栋801室13926892766";
private static final String salerAccount = "中国建设银行股份有限公司东莞虎门连升支行44050110140900000777";
//收款人
private static final String payee = "郑超";
//复核人
private static final String checker = "邹冬梅";
//开票人
private static final String clerk = "郑超";
@Value("${invoice.clerk}")
private String clerk;
/**
* 推送方式:-1,不推送;0,邮箱;1,手机(默认);2,邮箱、手机
......@@ -75,16 +90,34 @@ public class InvoiceBiz extends BaseBiz<InvoiceMapper, Invoice> {
private static final Integer pushMode = 2;
private static final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(8);
/**
* 通过公司代码获取公司税号
*
* @param code
* @return
*/
public String getDutyParagraphByCode(String code) {
return invoiceDao.getDutyParagraphByCode(code);
}
/**
* 通过公司名获取公司全名和公司代码
*
* @param name
* @return
*/
public List<Map<String, String>> corporateName(String name) {
return invoiceDao.corporateName(name);
}
/**
* 开票
*
* @param invoiceVo
* @return
* @throws Exception
*/
public String Invoicing(InvoiceVo invoiceVo) throws Exception {
IJWTInfo infoFromToken = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request));
Invoice invoice = new Invoice();
long on = snowflakeIdWorker.nextId();
......@@ -92,7 +125,8 @@ public class InvoiceBiz extends BaseBiz<InvoiceMapper, Invoice> {
invoice.setOrderNo(String.valueOf(on));
invoice.setSalerName(salerName);
invoice.setSalerTaxCode(salerTaxNum);
invoice.setSalerAddressPhone(salerAddress);
invoice.setSalerAddress(salerAddress);
invoice.setSalerPhone(salerTel);
invoice.setSalerAccountBank(salerAccount);
invoice.setPayee(payee);
invoice.setReviewer(checker);
......@@ -101,61 +135,139 @@ public class InvoiceBiz extends BaseBiz<InvoiceMapper, Invoice> {
Date invoiceDate = new Date();
invoice.setCreateTime(invoiceDate);
invoice.setInvoiceDate(invoiceDate);
invoice.setCreateBy(infoFromToken.getName());
List<OrderData> orders = invoiceVo.getOrders();
//调用第三方开票
String invoiceSerialNum = invoiceDao.Invoicing(invoice, orders);
invoice.setInvoiceSerialNum(invoiceSerialNum);
insertInvoic(invoice, invoiceSerialNum, orders);
return invoiceSerialNum;
}
/**
* 保存发票信息
*
* @param invoice
* @param invoiceSerialNum
* @param orders
* @throws Exception
*/
public void insertInvoic(Invoice invoice, String invoiceSerialNum, List<OrderData> orders) throws Exception {
IJWTInfo infoFromToken = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request));
invoice.setUserId(Integer.valueOf(infoFromToken.getId()));
invoice.setCreateBy(infoFromToken.getName());
invoice.setInvoiceSerialNum(invoiceSerialNum);
BigDecimal taxExcludedAmount = BigDecimal.ZERO;
BigDecimal taxIncludedAmount = BigDecimal.ZERO;
for (OrderData order : orders) {
if (order.getWithTaxFlag()==1) {
//含价税合计
BigDecimal taxIncluded = order.getPrice();
//税率
BigDecimal taxRate = order.getTaxRate();
//不含税单价
BigDecimal TaxFree = taxIncluded.divide(taxRate.add(new BigDecimal(1)));
taxExcludedAmount=taxExcludedAmount.add(TaxFree);
taxIncludedAmount=taxIncludedAmount.add(taxIncluded);
}else {
//不含税单价
BigDecimal taxFree = order.getPrice();
//税率
BigDecimal taxRate = order.getTaxRate();
//含税单价
BigDecimal taxIncluded = taxFree.multiply(taxRate.add(new BigDecimal(1)));
taxExcludedAmount=taxExcludedAmount.add(taxFree);
taxIncludedAmount=taxIncludedAmount.add(taxIncluded);
}
}
invoice.setInvoiceAmount(taxExcludedAmount);
invoice.setTaxAmount(taxIncludedAmount.subtract(taxExcludedAmount));
invoice.setInvoiceSummaryAmount(taxIncludedAmount);
invoice.setInvoiceSummaryAmountText(NumberToCN.number2CNMontrayUnit(taxIncludedAmount));
//保存到数据库
mapper.insert(invoice);
//异步查询开票结果
executorService.schedule(() -> {
queryInvoiceResult(invoiceSerialNum, invoice.getId(), 0);
}, 10, TimeUnit.SECONDS);
schedule(invoiceSerialNum, invoice.getId(),invoice.getOrderId(),null, 0, 5,TimeUnit.SECONDS);
return invoiceSerialNum;
}
public String invoiceResult(String invoiceSerialNum) {
return invoiceDao.invoiceResult(invoiceSerialNum);
/**
* 或去查询结果
* @param invoiceSerialNum 发票流水号
* @param id 发票id
* @param orderId 订单id
* @param lastStatus 上一次产需到的开票状态
* @param count 已经查询过的次数
*/
public void queryInvoiceResult(String invoiceSerialNum, Integer id,String orderId,Integer lastStatus,Integer count) {
if (count==2){
InvoiceQueryError invoiceQueryError = new InvoiceQueryError();
invoiceQueryError.setInvoiceId(id);
invoiceQueryError.setInvoiceSerialNum(invoiceSerialNum);
invoiceQueryError.setCreTime(new Date());
invoiceQueryError.setStatus(lastStatus);
invoiceQueryErrorBiz.insertSelectiveRe(invoiceQueryError);
return;
}
public void queryInvoiceResult(String invoiceSerialNum, Integer id, Integer type) {
String result = invoiceResult(invoiceSerialNum);
JSONObject jsonObject = JSON.parseObject(result);
List<Map<String, Object>> mapList = (List<Map<String, Object>>) jsonObject.get("result");
Map<String, Object> data = mapList.get(0);
try {
List<Map<String, Object>> result = invoiceResult(invoiceSerialNum);
if (result==null){
schedule(invoiceSerialNum, id,orderId,null, ++count, 2,TimeUnit.HOURS);
return;
}
log.info("查询到的开票结果={}",result);
Map<String, Object> data = result.get(0);
Integer status = (Integer) data.get("status");
// if (type == 0) {
// status = InvoiceStatusEum.ONGOING.getCode();
// }
if (InvoiceStatusEum.ONGOING.getCode().equals(status) && InvoiceStatusEum.ONGOING.getCode().equals(status)) {
executorService.schedule(() -> {
queryInvoiceResult(invoiceSerialNum, id, 1);
}, 2, TimeUnit.HOURS);
} else {
String invoiceFileUrl = (String) data.get("invoiceFileUrl");
String invoiceCode = (String) data.get("invoiceCode");
String invoiceNum = (String) data.get("invoiceNum");
String taxIncludedAmountStr = (String) data.get("taxIncludedAmount");
String taxExcludedAmountStr = (String) data.get("taxExcludedAmount");
Invoice invoice = new Invoice();
invoice.setId(id);
invoice.setStatus(status);
invoice.setInvoiceCode(String.valueOf(data.get("invoiceCode")));
invoice.setInvoiceNo(String.valueOf(data.get("invoiceNum")));
invoice.setInvoiceAmount(BigDecimal.valueOf(Double.valueOf(String.valueOf(data.get("taxExcludedAmount")))));
invoice.setTaxAmount(BigDecimal.valueOf(Double.valueOf(String.valueOf(data.get("taxIncludedAmount")))).subtract(BigDecimal.valueOf(Double.valueOf(String.valueOf(data.get("taxExcludedAmount"))))));
invoice.setInvoiceSummaryAmount(BigDecimal.valueOf(Double.valueOf(String.valueOf(data.get("taxIncludedAmount")))));
invoice.setInvoiceSummaryAmountText(NumberToCN.number2CNMontrayUnit(BigDecimal.valueOf(Double.valueOf(String.valueOf(data.get("taxIncludedAmount"))))));
invoice.setPictureUrl(String.valueOf(data.get("invoiceFileUrl")));
invoice.setUpdateTime(new Date());
if (StringUtils.isNotBlank(taxExcludedAmountStr)&&StringUtils.isNotBlank(taxIncludedAmountStr)) {
BigDecimal taxExcludedAmount = new BigDecimal(taxExcludedAmountStr);
BigDecimal taxIncludedAmount = new BigDecimal(taxIncludedAmountStr);
invoice.setInvoiceAmount(taxExcludedAmount);
invoice.setTaxAmount(taxIncludedAmount.subtract(taxExcludedAmount));
invoice.setInvoiceSummaryAmount(taxIncludedAmount);
invoice.setInvoiceSummaryAmountText(NumberToCN.number2CNMontrayUnit(taxIncludedAmount));
}
if (InvoiceStatusEum.ONGOING.getCode().equals(status) || InvoiceStatusEum.UNBILLED.getCode().equals(status)) {
schedule(invoiceSerialNum, id,orderId,status, ++count, 2,TimeUnit.HOURS);
}else if (InvoiceStatusEum.SUCCESS.getCode().equals(status)){
invoice.setInvoiceCode(invoiceCode);
invoice.setInvoiceNo(invoiceNum);
invoice.setPictureUrl(invoiceFileUrl);
orderFeign
}
mapper.updateByPrimaryKeySelective(invoice);
}
} catch (Exception e) {
log.error("查询开票结果={}", e.toString());
e.printStackTrace();
public void schedule(String invoiceSerialNum, Integer id,String orderId,Integer lastStatus, int count, int time,TimeUnit timeUnit) {
executorService.schedule(() -> {
queryInvoiceResult(invoiceSerialNum, id,orderId,lastStatus, count);
}, time, timeUnit);
}
/**
* 获取开票结果
*
* @param invoiceSerialNum
* @return
*/
public List<Map<String, Object>> invoiceResult(String invoiceSerialNum) {
return invoiceDao.invoiceResult(invoiceSerialNum);
}
}
......@@ -18,5 +18,5 @@ public interface InvoiceDao {
String Invoicing(Invoice invoice, List<OrderData> orders);
String invoiceResult(String invoiceSerialNum);
List<Map<String,Object>> invoiceResult(String invoiceSerialNum);
}
......@@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j;
import nuonuo.open.sdk.NNOpenSDK;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
......@@ -35,26 +36,31 @@ public class InvoiceDaoImpl implements InvoiceDao {
/**
* 诺诺-极速开票
*/
private static final String taxnum = "91441900MA53C6713X";
private static final String appKey = "80653463";
private static final String appSecret = "EA55B47A6D0A4560";
@Value("${invoice.nuonuo.js.taxnum}")
private String taxnum;
@Value("${invoice.nuonuo.js.appKey}")
private String appKey;
@Value("${invoice.nuonuo.js.appSecret}")
private String appSecret;
/**
* 诺诺-诺诺发票
*/
private static final String taxnum2 = "91441900MA53C6713X";
//沙箱
private static final String appKey2 = "SD26345711";
private static final String appSecret2 = "SD1B543442BF41A1";
@Value("${invoice.nuonuo.nn.taxnum}")
private String taxnum2;
@Value("${invoice.nuonuo.nn.appKey}")
private String appKey2;
@Value("${invoice.nuonuo.nn.appSecret}")
private String appSecret2;
// //正式
// private static final String appKey2 = "26345711";
// private static final String appSecret2 = "901B543442BF41A1";
/**
* 给定的部分名获取税号
*
* @param name
* @return
*/
......@@ -82,6 +88,7 @@ public class InvoiceDaoImpl implements InvoiceDao {
/**
* 根据开票代码,调用第三方接口获取税号
*
* @param code
* @return
*/
......@@ -105,7 +112,6 @@ public class InvoiceDaoImpl implements InvoiceDao {
}
@Override
public String Invoicing(Invoice invoice, List<OrderData> orders) {
......@@ -123,7 +129,7 @@ public class InvoiceDaoImpl implements InvoiceDao {
HashMap<String, Map<String, Object>> orderMap = new HashMap<>();
orderMap.put("order", map);
//购方信息
map.put("buyerName",invoice.getPurchaserName());
map.put("buyerName", invoice.getPurchaserName());
map.put("buyerTaxNum", invoice.getPurchaserTaxCode());
// map.put("buyerTel", invoice.getPurchaserPhone());
map.put("buyerAddress", invoice.getPurchaserAddressPhone());
......@@ -134,18 +140,19 @@ public class InvoiceDaoImpl implements InvoiceDao {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//销方信息
map.put("orderNo", invoice.getOrderNo());
map.put("invoiceDate",dateFormat.format(invoice.getInvoiceDate()));
map.put("invoiceDate", dateFormat.format(invoice.getInvoiceDate()));
map.put("salerName", invoice.getSalerName());
map.put("salerTaxNum", invoice.getSalerTaxCode());
map.put("salerAddress", invoice.getSalerAddressPhone());
map.put("salerAccount",invoice.getSalerAccountBank());
map.put("salerTel", invoice.getSalerPhone());
map.put("salerAddress", invoice.getSalerAddress());
map.put("salerAccount", invoice.getSalerAccountBank());
map.put("clerk", invoice.getIssuer());
map.put("payee", invoice.getPayee());
map.put("checker", invoice.getReviewer());
//其他设置
map.put("pushMode", String.valueOf(invoice.getPushMode()));
map.put("invoiceType",String.valueOf(invoice.getInvoiceType()));
map.put("invoiceType", String.valueOf(invoice.getInvoiceType()));
//订单信息
......@@ -154,40 +161,41 @@ public class InvoiceDaoImpl implements InvoiceDao {
for (OrderData order : orders) {
HashMap<String, String> mx = new HashMap<>();
mx.put("goodsName", invoice.getContent());
mx.put("num",String.valueOf(order.getNum()) );
mx.put("num", String.valueOf(order.getNum()));
//单价含税标志,0:不含税,1:含税
mx.put("withTaxFlag", String.valueOf(order.getWithTaxFlag()));
mx.put("price", String.valueOf(order.getPrice()));
mx.put("taxRate", String.valueOf(order.getTaxRate()));
mx.put("unit", order.getUnit());
mx.put("specType",order.getOrderName());
mx.put("specType", order.getOrderName());
arrayList.add(mx);
}
String token = getTokenFP();
String jsonString = JSON.toJSONString(orderMap);
//调用第三方接口
String result = sdk.sendPostSyncRequest(url, senid, appKey2, appSecret2,token , taxnum2, method, jsonString);
log.info("result={}",result);
String result = sdk.sendPostSyncRequest(url, senid, appKey2, appSecret2, token, taxnum2, method, jsonString);
log.info("result={}", result);
//把字符串json数据转换为map
JSONObject jsonObject = JSON.parseObject(result);
Map<String,String> data = (Map<String, String>) jsonObject.get("result");
Map<String, String> data = (Map<String, String>) jsonObject.get("result");
String invoiceSerialNum = data.get("invoiceSerialNum");
if (StringUtils.isBlank(invoiceSerialNum)){
log.error("失败原因={}",result);
if (StringUtils.isBlank(invoiceSerialNum)) {
log.error("失败原因={}", result);
throw new BaseException("开票失败");
}
return invoiceSerialNum;
}
@Override
public String invoiceResult(String invoiceSerialNum) {
public List<Map<String, Object>> invoiceResult(String invoiceSerialNum) {
NNOpenSDK sdk = NNOpenSDK.getIntance();
// API方法名
String method = "nuonuo.electronInvoice.CheckEInvoice";
HashMap<String, List<String>> map = new HashMap<>();
ArrayList<String> arrayList = Lists.newArrayList();
arrayList.add(invoiceSerialNum);
map.put("invoiceSerialNum",arrayList);
map.put("invoiceSerialNum", arrayList);
String content = JSON.toJSONString(map);
// SDK请求地址
//沙箱
......@@ -197,16 +205,30 @@ public class InvoiceDaoImpl implements InvoiceDao {
// 唯一标识,由企业自己生成32位随机码
String senid = UUID.randomUUID().toString().replace("-", "");
String result = sdk.sendPostSyncRequest(url, senid, appKey2, appSecret2, getTokenFP(), taxnum2, method, content);
System.out.println(result);
return result;
String data = null;
try {
data = sdk.sendPostSyncRequest(url, senid, appKey2, appSecret2, getTokenFP(), taxnum2, method, content);
} catch (Exception e) {
e.printStackTrace();
}
if (data!=null){
try {
JSONObject jsonObject = JSON.parseObject(data);
List<Map<String, Object>> mapList = (List<Map<String, Object>>) jsonObject.get("result");
return mapList;
} catch (Exception e) {
throw new BaseException("发票请求流水号错误");
}
}
return null;
}
/**
* 获取极速开票token
*/
private String getTokenJS() {
return getToken(appKey, appSecret);
}
......@@ -220,7 +242,6 @@ public class InvoiceDaoImpl implements InvoiceDao {
}
private String getToken(String appKey, String appSecret) {
String token = (String) redisTemplate.opsForValue().get(appKey);
if (StringUtils.isBlank(token)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment