Browse Source

发票打印相关

609324174@qq.com 4 years ago
parent
commit
f02982cf97

+ 403 - 0
smart-city-platform/src/main/java/com/bz/smart_city/commom/util/DESDZFP.java

@@ -0,0 +1,403 @@
+package com.bz.smart_city.commom.util;
+
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+
+/**
+ * 功能描述
+ * 加密常用类
+ */
+public class DESDZFP {
+	// 密钥是16位长度的byte[]进行Base64转换后得到的字符串
+	public static String key = "LmMGStGtOpF4xNyvYt54EQ==";
+
+	/**
+	 * <li>
+	 * 方法名称:encrypt</li> <li>
+	 * 加密方法
+	 * @param xmlStr
+	 *            需要加密的消息字符串
+	 * @return 加密后的字符串
+	 */
+	public static String encrypt(String xmlStr) {
+		byte[] encrypt = {};
+
+		try {
+			// 取需要加密内容的utf-8编码。
+			if(xmlStr != null){
+				encrypt = xmlStr.getBytes("utf-8");
+			}
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		}
+		// 取MD5Hash码,并组合加密数组
+		byte[] md5Hasn = null;
+		try {
+			md5Hasn = DESDZFP.MD5Hash(encrypt, 0, encrypt.length);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		// 组合消息体
+		byte[] totalByte = DESDZFP.addMD5(md5Hasn, encrypt);
+
+		// 取密钥和偏转向量
+		byte[] key = new byte[8];
+		byte[] iv = new byte[8];
+		getKeyIV(DESDZFP.key, key, iv);
+		SecretKeySpec deskey = new SecretKeySpec(key, "DES");
+		IvParameterSpec ivParam = new IvParameterSpec(iv);
+
+		// 使用DES算法使用加密消息体
+		byte[] temp = null;
+		try {
+			temp = DESDZFP.DES_CBC_Encrypt(totalByte, deskey, ivParam);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// 使用Base64加密后返回
+		return new BASE64Encoder().encode(temp);
+	}
+
+	/**
+	 * <li>
+	 * 方法名称:encrypt</li> <li>
+	 * 功能描述:
+	 * 
+	 * <pre>
+	 * 解密方法
+	 * </pre>
+	 * 
+	 * </li>
+	 * 
+	 * @param xmlStr
+	 *            需要解密的消息字符串
+	 * @return 解密后的字符串
+	 * @throws Exception
+	 */
+	public static String decrypt(String xmlStr) throws Exception {
+		// base64解码
+		BASE64Decoder decoder = new BASE64Decoder();
+		byte[] encBuf = null;
+		try {
+			if(xmlStr != null){
+				xmlStr = xmlStr.replaceAll(" ", "+");//解决URL里加号变空格
+			}
+			encBuf = decoder.decodeBuffer(xmlStr);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		// 取密钥和偏转向量
+		byte[] key = new byte[8];
+		byte[] iv = new byte[8];
+		getKeyIV(DESDZFP.key, key, iv);
+
+		SecretKeySpec deskey = new SecretKeySpec(key, "DES");
+		IvParameterSpec ivParam = new IvParameterSpec(iv);
+
+		// 使用DES算法解密
+		byte[] temp = null;
+		try {
+			temp = DESDZFP.DES_CBC_Decrypt(encBuf, deskey, ivParam);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// 进行解密后的md5Hash校验
+		byte[] md5Hash = null;
+		try {
+			md5Hash = DESDZFP.MD5Hash(temp, 16, temp.length - 16);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		// 进行解密校检
+		for (int i = 0; i < md5Hash.length; i++) {
+			if (md5Hash[i] != temp[i]) {
+				// System.out.println(md5Hash[i] + "MD5校验错误。" + temp[i]);
+				throw new Exception("MD5校验错误。");
+			}
+		}
+
+		// 返回解密后的数组,其中前16位MD5Hash码要除去。
+		return new String(temp, 16, temp.length - 16, "utf-8");
+	}
+
+	/**
+	 * <li>
+	 * 方法名称:TripleDES_CBC_Encrypt</li> <li>
+	 * 功能描述:
+	 * 
+	 * <pre>
+	 * 经过封装的三重DES/CBC加密算法,如果包含中文,请注意编码。
+	 * </pre>
+	 * 
+	 * </li>
+	 * 
+	 * @param sourceBuf
+	 *            需要加密内容的字节数组。
+	 * @param deskey
+	 *            KEY 由24位字节数组通过SecretKeySpec类转换而成。
+	 * @param ivParam
+	 *            IV偏转向量,由8位字节数组通过IvParameterSpec类转换而成。
+	 * @return 加密后的字节数组
+	 * @throws Exception
+	 */
+	public static byte[] TripleDES_CBC_Encrypt(byte[] sourceBuf,
+			SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
+		byte[] cipherByte;
+		// 使用DES对称加密算法的CBC模式加密
+		Cipher encrypt = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
+
+		encrypt.init(Cipher.ENCRYPT_MODE, deskey, ivParam);
+
+		cipherByte = encrypt.doFinal(sourceBuf, 0, sourceBuf.length);
+		// 返回加密后的字节数组
+		return cipherByte;
+	}
+
+	/**
+	 * <li>
+	 * 方法名称:TripleDES_CBC_Decrypt</li> <li>
+	 * 功能描述:
+	 * 
+	 * <pre>
+	 * 经过封装的三重DES / CBC解密算法
+	 * </pre>
+	 * 
+	 * </li>
+	 * 
+	 * @param sourceBuf
+	 *            需要解密内容的字节数组
+	 * @param deskey
+	 *            KEY 由24位字节数组通过SecretKeySpec类转换而成。
+	 * @param ivParam
+	 *            IV偏转向量,由6位字节数组通过IvParameterSpec类转换而成。
+	 * @return 解密后的字节数组
+	 * @throws Exception
+	 */
+	public static byte[] TripleDES_CBC_Decrypt(byte[] sourceBuf,
+			SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
+
+		byte[] cipherByte;
+		// 获得Cipher实例,使用CBC模式。
+		Cipher decrypt = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
+		// 初始化加密实例,定义为解密功能,并传入密钥,偏转向量
+		decrypt.init(Cipher.DECRYPT_MODE, deskey, ivParam);
+
+		cipherByte = decrypt.doFinal(sourceBuf, 0, sourceBuf.length);
+		// 返回解密后的字节数组
+		return cipherByte;
+	}
+
+	/**
+	 * <li>
+	 * 方法名称:DES_CBC_Encrypt</li> <li>
+	 * 功能描述:
+	 * 
+	 * <pre>
+	 * 经过封装的DES/CBC加密算法,如果包含中文,请注意编码。
+	 * </pre>
+	 * 
+	 * </li>
+	 * 
+	 * @param sourceBuf
+	 *            需要加密内容的字节数组。
+	 * @param deskey
+	 *            KEY 由8位字节数组通过SecretKeySpec类转换而成。
+	 * @param ivParam
+	 *            IV偏转向量,由8位字节数组通过IvParameterSpec类转换而成。
+	 * @return 加密后的字节数组
+	 * @throws Exception
+	 */
+	public static byte[] DES_CBC_Encrypt(byte[] sourceBuf,
+			SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
+		byte[] cipherByte;
+		// 使用DES对称加密算法的CBC模式加密
+		Cipher encrypt = Cipher.getInstance("DES/CBC/PKCS5Padding");
+
+		encrypt.init(Cipher.ENCRYPT_MODE, deskey, ivParam);
+
+		cipherByte = encrypt.doFinal(sourceBuf, 0, sourceBuf.length);
+		// 返回加密后的字节数组
+		return cipherByte;
+	}
+
+	/**
+	 * <li>
+	 * 方法名称:DES_CBC_Decrypt</li> <li>
+	 * 功能描述:
+	 * 
+	 * <pre>
+	 * 经过封装的DES/CBC解密算法。
+	 * </pre>
+	 * 
+	 * </li>
+	 * 
+	 * @param sourceBuf
+	 *            需要解密内容的字节数组
+	 * @param deskey
+	 *            KEY 由8位字节数组通过SecretKeySpec类转换而成。
+	 * @param ivParam
+	 *            IV偏转向量,由6位字节数组通过IvParameterSpec类转换而成。
+	 * @return 解密后的字节数组
+	 * @throws Exception
+	 */
+	public static byte[] DES_CBC_Decrypt(byte[] sourceBuf,
+			SecretKeySpec deskey, IvParameterSpec ivParam) throws Exception {
+
+		byte[] cipherByte;
+		// 获得Cipher实例,使用CBC模式。
+		Cipher decrypt = Cipher.getInstance("DES/CBC/PKCS5Padding");
+		// 初始化加密实例,定义为解密功能,并传入密钥,偏转向量
+		decrypt.init(Cipher.DECRYPT_MODE, deskey, ivParam);
+
+		cipherByte = decrypt.doFinal(sourceBuf, 0, sourceBuf.length);
+		// 返回解密后的字节数组
+		return cipherByte;
+	}
+
+	/**
+	 * <li>
+	 * 方法名称:MD5Hash</li> <li>
+	 * 功能描述:
+	 * 
+	 * <pre>
+	 * MD5,进行了简单的封装,以适用于加,解密字符串的校验。
+	 * </pre>
+	 * 
+	 * </li>
+	 * 
+	 * @param buf
+	 *            需要MD5加密字节数组。
+	 * @param offset
+	 *            加密数据起始位置。
+	 * @param length
+	 *            需要加密的数组长度。
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] MD5Hash(byte[] buf, int offset, int length)
+			throws Exception {
+		MessageDigest md = MessageDigest.getInstance("MD5");
+		md.update(buf, offset, length);
+		return md.digest();
+	}
+
+	/**
+	 * <li>
+	 * 方法名称:byte2hex</li> <li>
+	 * 功能描述:
+	 * 
+	 * <pre>
+	 * 字节数组转换为二行制表示
+	 * </pre>
+	 * 
+	 * </li>
+	 * 
+	 * @param inStr
+	 *            需要转换字节数组。
+	 * @return 字节数组的二进制表示。
+	 */
+	public static String byte2hex(byte[] inStr) {
+		String stmp;
+		StringBuffer out = new StringBuffer(inStr.length * 2);
+
+		for (int n = 0; n < inStr.length; n++) {
+			// 字节做"与"运算,去除高位置字节 11111111
+			stmp = Integer.toHexString(inStr[n] & 0xFF);
+			if (stmp.length() == 1) {
+				// 如果是0至F的单位字符串,则添加0
+				out.append("0" + stmp);
+			} else {
+				out.append(stmp);
+			}
+		}
+		return out.toString();
+	}
+
+	/**
+	 * <li>
+	 * 方法名称:addMD5</li> <li>
+	 * 功能描述:
+	 * 
+	 * <pre>
+	 * MD校验码 组合方法,前16位放MD5Hash码。 把MD5验证码byte[],加密内容byte[]组合的方法。
+	 * </pre>
+	 * 
+	 * </li>
+	 * 
+	 * @param md5Byte
+	 *            加密内容的MD5Hash字节数组。
+	 * @param bodyByte
+	 *            加密内容字节数组
+	 * @return 组合后的字节数组,比加密内容长16个字节。
+	 */
+	public static byte[] addMD5(byte[] md5Byte, byte[] bodyByte) {
+		int length = bodyByte.length + md5Byte.length;
+		byte[] resutlByte = new byte[length];
+
+		// 前16位放MD5Hash码
+		for (int i = 0; i < length; i++) {
+			if (i < md5Byte.length) {
+				resutlByte[i] = md5Byte[i];
+			} else {
+				resutlByte[i] = bodyByte[i - md5Byte.length];
+			}
+		}
+
+		return resutlByte;
+	}
+
+	/**
+	 * <li>
+	 * 方法名称:getKeyIV</li> <li>
+	 * 功能描述:
+	 * 
+	 * <pre>
+	 * 
+	 * </pre>
+	 * </li>
+	 * 
+	 * @param encryptKey
+	 * @param key
+	 * @param iv
+	 */
+	public static void getKeyIV(String encryptKey, byte[] key, byte[] iv) {
+		// 密钥Base64解密
+		BASE64Decoder decoder = new BASE64Decoder();
+		byte[] buf = null;
+		try {
+			buf = decoder.decodeBuffer(encryptKey);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		// 前8位为key
+		int i;
+		for (i = 0; i < key.length; i++) {
+			key[i] = buf[i];
+		}
+		// 后8位为iv向量
+		for (i = 0; i < iv.length; i++) {
+			iv[i] = buf[i + 8];
+		}
+	}
+	
+	public static void main(String[] args) throws Exception {
+		String str="{\"identity\":\"B8FB14CA1C6D7C93D9154E2262FF0F9DD796B180A2A7690A\",\"order\":{\"orderno\":\"No.20160308151221\",\"saletaxnum\":\"110101MXB6CK9Q6\",\"saleaddress\":\"万塘路30号\",\"salephone\":\"0571-1234567\",\"saleaccount\":\"工商银行6222222222222\",\"clerk\":\"sa\",\"payee\":\"sa\",\"checker\":\"sa\",\"invoicedate\":\"2016-03-08 15:12:21\",\"ordertotal\":\"8.00\",\"kptype\":\"1\",\"taxtotal\":\"1.16\",\"bhtaxtotal\":\"6.84\",\"address\":\"浙江杭州 0571-123456789\",\"phone\":\"0571-123456789\",\"taxnum\":\"339900000000004\",\"buyername\":\"浙江爱信诺航天信息有限公司\",\"account\":\"工商-123456789浙江爱信诺航天信息有限公司\",\"message\":\"浙江爱信诺航天信息有限公司\",\"fpdm\":\"\",\"fphm\":\"\",\"detail\":[{\"goodsname\":\"1\",\"spec\":\"1\",\"unit\":\"1\",\"hsbz\":\"1\",\"num\":\"1\",\"price\":\"4\",\"taxrate\":\"0.17\"},{\"goodsname\":\"2\",\"spec\":\"2\",\"unit\":\"2\",\"hsbz\":\"1\",\"num\":\"1\",\"price\":\"4\",\"taxrate\":\"0.17\"}]}}";
+		str=encrypt(str);
+		System.out.println(str);
+		str=decrypt(str);
+		System.out.println(str);
+	}
+}

+ 47 - 0
smart-city-platform/src/main/java/com/bz/smart_city/commom/util/RandomUtil.java

@@ -0,0 +1,47 @@
+package com.bz.smart_city.commom.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Random;
+
+/**
+ * @ClassName RandomUtil
+ * @Description: 随机数
+ * @Author :WYY
+ * @Date 2020/8/10
+ * @Version V1.0
+ **/
+public class RandomUtil {
+    /**
+     * 获取6-10 的随机位数数字
+     *
+     * @param length 想要生成的长度
+     * @return result
+     */
+    public static String getRandom620(Integer length) {
+        String result = "";
+        Random rand = new Random();
+        int n = 20;
+        if (null != length && length > 0) {
+            n = length;
+        }
+        int randInt = 0;
+        for (int i = 0; i < n; i++) {
+            randInt = rand.nextInt(10);
+            result += randInt;
+        }
+        return result;
+    }
+
+    public static String getRandomString() {
+        //格式化当前时间
+        SimpleDateFormat sfDate = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+        String strDate = sfDate.format(new Date());
+        //为了防止高并发重复,再获取3个随机数
+        String random = getRandom620(3);
+
+        //最后得到20位订单编号。
+        return (strDate + random);
+
+    }
+}

+ 31 - 0
smart-city-platform/src/main/java/com/bz/smart_city/controller/pay/PayPrintInvoiceController.java

@@ -0,0 +1,31 @@
+package com.bz.smart_city.controller.pay;
+
+import com.bz.smart_city.service.pay.IssueElectronicInvoiceService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @ClassName PayPrintInvoiceController
+ * @Description: TODO
+ * @Author :WYY
+ * @Date 2020/8/7
+ * @Version V1.0
+ **/
+@RestController
+@RequestMapping(value = "printinvoice")
+@Api(tags = "计费系统-收费管理-发票管理")
+public class PayPrintInvoiceController {
+    @Autowired
+    private IssueElectronicInvoiceService issueElectronicInvoiceService;
+
+    @ApiOperation(value = "请求打印")
+    @GetMapping(value = "/printRequest")
+    public void printInoice()
+    {
+        issueElectronicInvoiceService.requestPrint("1","0460000003","C046000000301200522155950402");
+    }
+}

+ 2 - 0
smart-city-platform/src/main/java/com/bz/smart_city/dao/pay/archives/PayBaseCustomerandmeterrelaMapper.java

@@ -97,4 +97,6 @@ public interface PayBaseCustomerandmeterrelaMapper {
     public Integer queryMeterState( @Param("customerId")Integer customerId,@Param("accountId")BigInteger accountId);
 
     public Organization getParentOfficeId( @Param("siteId")Integer siteId,@Param("id")Integer id,@Param("name") String name);
+
+    public PayBaseCustomerandmeterrela findAccountByAccountNumber(@Param("siteId") Integer siteId, @Param("customerId")Integer customerId,@Param("accountnumber")String accountnumber);
 }

+ 2 - 0
smart-city-platform/src/main/java/com/bz/smart_city/dto/pay/PayInvoiceOrderDto.java

@@ -1,5 +1,6 @@
 package com.bz.smart_city.dto.pay;
 
+import com.alibaba.fastjson.annotation.JSONField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -34,6 +35,7 @@ public class PayInvoiceOrderDto {
     private String orderno;
     @ApiModelProperty(name = "开票时间",notes = "必填")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    @JSONField(format="yyyy-MM-dd HH:mm:ss")
     private LocalDateTime invoicedate;
     @ApiModelProperty(name = "开票员",notes = "必填,最大长度20")
     private String clerk;

+ 54 - 29
smart-city-platform/src/main/java/com/bz/smart_city/service/impl/pay/IssueElectronicInvoiceServiceImpl.java

@@ -1,22 +1,26 @@
 package com.bz.smart_city.service.impl.pay;
 
+import com.alibaba.fastjson.JSON;
 import com.bz.smart_city.commom.model.Pagination;
+import com.bz.smart_city.commom.util.DESDZFP;
+import com.bz.smart_city.commom.util.HttpClientUtils;
+import com.bz.smart_city.commom.util.RandomUtil;
 import com.bz.smart_city.commom.util.UserUtil;
 import com.bz.smart_city.dto.LoginUser;
 import com.bz.smart_city.dto.pay.*;
 import com.bz.smart_city.entity.pay.PayBaseAccount;
 import com.bz.smart_city.entity.pay.PayInvoiceParam;
 import com.bz.smart_city.entity.pay.archives.PayBaseCustomerandmeterrela;
-import com.bz.smart_city.service.pay.PayBaseAccountService;
-import com.bz.smart_city.service.pay.PayBaseConfigService;
-import com.bz.smart_city.service.pay.PayInvoiceParamService;
-import com.bz.smart_city.service.pay.PayPayReceivedService;
+import com.bz.smart_city.service.pay.*;
+import com.bz.smart_city.service.pay.archives.PayBaseCustomerandmeterrelaService;
+import com.google.gson.JsonObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.time.LocalDateTime;
 import java.util.*;
 
 /**
@@ -27,7 +31,7 @@ import java.util.*;
  * @Version V1.0
  **/
 @Service
-public class IssueElectronicInvoiceServiceImpl {
+public class IssueElectronicInvoiceServiceImpl implements IssueElectronicInvoiceService {
     @Autowired
     PayBaseConfigService payBaseConfigService;
     @Autowired
@@ -36,6 +40,8 @@ public class IssueElectronicInvoiceServiceImpl {
     PayBaseAccountService payBaseAccountService;
     @Autowired
     PayPayReceivedService payPayReceivedService;
+    @Autowired
+    PayBaseCustomerandmeterrelaService payBaseCustomerandmeterrelaService;
 
     private Map<String, String> getPrintParam() {
         Map<String, String> map = new HashMap<>();
@@ -43,7 +49,7 @@ public class IssueElectronicInvoiceServiceImpl {
         Pagination<PayBaseConfigDto> payBaseConfigDtoPagination = payBaseConfigService.getAll("PRINT_", 1, 15);
         List<PayBaseConfigDto> payBaseConfigDtos = payBaseConfigDtoPagination.getList();
         for (PayBaseConfigDto item : payBaseConfigDtos) {
-            switch (item.getName()) {
+            switch (item.getName().trim()) {
                 case "PRINT_INVOICE_ADDRESS":
                     map.put("saleAddress", item.getValue());
                     break;
@@ -78,14 +84,17 @@ public class IssueElectronicInvoiceServiceImpl {
         }
         return map;
     }
-    public BigDecimal saveTwoDecimal(BigDecimal d){
-        BigDecimal a =d.setScale(2,BigDecimal.ROUND_HALF_UP);
+
+    public BigDecimal saveTwoDecimal(BigDecimal d) {
+        BigDecimal a = d.setScale(2, BigDecimal.ROUND_HALF_UP);
         return a;
     }
-    public BigDecimal saveEightDecimal(BigDecimal d){
-        BigDecimal a =d.setScale(8,BigDecimal.ROUND_HALF_UP);
+
+    public BigDecimal saveEightDecimal(BigDecimal d) {
+        BigDecimal a = d.setScale(8, BigDecimal.ROUND_HALF_UP);
         return a;
     }
+
     /**
      * @MethodName:
      * @Description: TODO
@@ -94,8 +103,7 @@ public class IssueElectronicInvoiceServiceImpl {
      * @Author:
      * @Date: 2020/7/28
      **/
-    @Async
-    public void requestPrint(String kpType,String userCode,String payseriesno) {
+    public void requestPrint(String kpType, String userCode, String payseriesno) {
         LoginUser loginUser = UserUtil.getCurrentUser();
         String name = loginUser.getName();//操作员姓名
         BigInteger siteId = BigInteger.valueOf(loginUser.getSiteId());
@@ -113,12 +121,18 @@ public class IssueElectronicInvoiceServiceImpl {
         payInvoiceOrderDto.setSaleaddress(invoiceParam.get("saleAddress"));//销方地址
         payInvoiceOrderDto.setSaletaxnum(invoiceParam.get("saleCode"));//销方税号
         payInvoiceOrderDto.setChecker(invoiceParam.get("saleChecker"));//复核人
-        payInvoiceOrderDto.setClerk(name);//开票人
-        payInvoiceOrderDto.setPayee(name);//收款人
+        if(name.length()>4) {
+            name = "*" + name.substring(name.length() - 3, name.length());
+            payInvoiceOrderDto.setClerk(name);//开票人
+            payInvoiceOrderDto.setPayee(name);//收款人
+        }
+
         payInvoiceOrderDto.setKptype(kpType);//开票类型
         payInvoiceOrderDto.setTsfs("2");//推送方式
+        payInvoiceOrderDto.setInvoicedate(LocalDateTime.now());
+        payInvoiceOrderDto.setOrderno(RandomUtil.getRandomString());
         //查询购方相关信息
-        PayBaseCustomerandmeterrela payBaseAccount = new PayBaseCustomerandmeterrela();
+        PayBaseCustomerandmeterrela payBaseAccount = payBaseCustomerandmeterrelaService.findAccountByAccountNumber(userCode);
         payInvoiceOrderDto.setBuyername(payBaseAccount.getAccountname());//购方名称
         payInvoiceOrderDto.setPhone(payBaseAccount.getTelephone());//电话
         payInvoiceOrderDto.setAddress(payBaseAccount.getAddress());//地址
@@ -127,9 +141,9 @@ public class IssueElectronicInvoiceServiceImpl {
 
         List<PayInvoiceOrderDetailDto> orderDetailDtos = new ArrayList<>();
         //循环加入明细
-        List<PayReceivedInvoiceDto> payReceivedInvoiceDtos = payPayReceivedService.findInvoiceReceivedByPayseriesno(payseriesno,loginUser.getSiteId(),loginUser.getCustomerId());
+        List<PayReceivedInvoiceDto> payReceivedInvoiceDtos = payPayReceivedService.findInvoiceReceivedByPayseriesno(payseriesno, loginUser.getSiteId(), loginUser.getCustomerId());
         //将水费分开,其他类型水费合并todo
-        for (PayReceivedInvoiceDto item:payReceivedInvoiceDtos) {
+        for (PayReceivedInvoiceDto item : payReceivedInvoiceDtos) {
             PayInvoiceOrderDetailDto orderDetailDto = new PayInvoiceOrderDetailDto();
             PayInvoiceParam payInvoiceParam = invoiceMap.get(item.getFeetype());
             orderDetailDto.setGoodsname(item.getFeetypename());
@@ -138,22 +152,22 @@ public class IssueElectronicInvoiceServiceImpl {
             //含税标志为0 不含税,税额=round((数量*不含税单价)*税率),2),含税金额=不含税金额+税额
             BigDecimal taxAmount = new BigDecimal(0);//税额
             BigDecimal receAmount = item.getReceivedamount();//实收金额
-            BigDecimal rate =new BigDecimal(payInvoiceParam.getTaxrate());//税率
-            if(payInvoiceParam.getPricetax().equals("1"))
-            {
-                taxAmount = saveTwoDecimal(receAmount.multiply(rate).divide(rate.add(BigDecimal.valueOf(1))));
-
-            }else
-            {
+            BigDecimal rate = new BigDecimal(payInvoiceParam.getTaxrate());//税率
+            if (payInvoiceParam.getPricetax().equals("1")) {
+                taxAmount = saveTwoDecimal(receAmount.multiply(rate).divide(rate.add(BigDecimal.valueOf(1)),2, BigDecimal.ROUND_HALF_UP));
+                orderDetailDto.setTax(String.valueOf(saveTwoDecimal(taxAmount)));//税额
+                orderDetailDto.setTaxfreeamt(String.valueOf(saveTwoDecimal(receAmount.subtract(taxAmount))));//不含税金额
+            } else {
                 taxAmount = saveTwoDecimal(receAmount.multiply(rate));
+                orderDetailDto.setTax(String.valueOf(saveTwoDecimal(taxAmount)));//税额
+                orderDetailDto.setTaxfreeamt(String.valueOf(saveTwoDecimal(receAmount.add(taxAmount))));//不含税金额
             }
-            orderDetailDto.setTax(String.valueOf(saveTwoDecimal(taxAmount)));//税额
-            orderDetailDto.setTaxfreeamt(String.valueOf(saveTwoDecimal(receAmount.subtract(taxAmount))));//不含税金额
-            if(item.getPrice()!=null) {
+
+            if (item.getPrice() != null) {
                 orderDetailDto.setPrice(String.valueOf(saveTwoDecimal(item.getPrice())));
-                orderDetailDto.setNum(String.valueOf(saveEightDecimal(receAmount.subtract(taxAmount).divide(saveTwoDecimal(item.getPrice())))));
+                orderDetailDto.setNum(String.valueOf(receAmount.divide(saveTwoDecimal(item.getPrice()), 8, BigDecimal.ROUND_HALF_UP)));
             }
-            if(!payInvoiceParam.getZerotax().equals("0")) {
+            if (!payInvoiceParam.getZerotax().equals("0")) {
                 orderDetailDto.setLslbs(payInvoiceParam.getZerotax());//零税率标志
             }
             orderDetailDto.setZzstsgl(payInvoiceParam.getOthermanger());//增值税特殊管理
@@ -170,6 +184,17 @@ public class IssueElectronicInvoiceServiceImpl {
             orderDetailDtos.add(orderDetailDto);
         }
         payInvoiceOrderDto.setDetail(orderDetailDtos);
+        payInvoiceOrderDto.setEmail("wangyangyang@hxiswater.com");
         payEleInvoiceDto.setOrder(payInvoiceOrderDto);
+        //发送开票请求
+        String jsonsString = DESDZFP.encrypt(JSON.toJSONString(payEleInvoiceDto));
+        Map<String, String> map = new HashMap<String, String>();
+        map.put("order", jsonsString);
+        try {
+            String returnString = HttpClientUtils.doPost("http://nnfpbox.nuonuocs.cn/shop/buyer/allow/cxfKp/cxfServerKpOrderSync.action", map);
+            System.out.println("returnString:" + returnString);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
     }
 }

+ 12 - 0
smart-city-platform/src/main/java/com/bz/smart_city/service/pay/IssueElectronicInvoiceService.java

@@ -0,0 +1,12 @@
+package com.bz.smart_city.service.pay;
+
+/**
+ * @ClassName IssueElectronicInvoiceService
+ * @Description: TODO
+ * @Author :WYY
+ * @Date 2020/8/7
+ * @Version V1.0
+ **/
+public interface IssueElectronicInvoiceService {
+    void requestPrint(String kpType, String userCode, String payseriesno);
+}

+ 2 - 1
smart-city-platform/src/main/java/com/bz/smart_city/service/pay/archives/PayBaseCustomerandmeterrelaService.java

@@ -6,6 +6,7 @@ import com.bz.smart_city.dto.pay.PayCustomerDto;
 import com.bz.smart_city.dto.pay.PaySaveCustomerDto;
 import com.bz.smart_city.entity.pay.PayPayRechargeaccount;
 import com.bz.smart_city.entity.pay.archives.*;
+import org.apache.ibatis.annotations.Param;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
@@ -53,5 +54,5 @@ public interface PayBaseCustomerandmeterrelaService {
     public Pagination<CustomerListInfo> selectAccountnumberList(String accountnumber,int pageNum, int pageSize);
 
     public List<PayBaseCustomerandmeterrelaDto> getResetLadderList(Integer siteId,Integer customerId);
-
+    public PayBaseCustomerandmeterrela findAccountByAccountNumber(String accountnumber);
 }

+ 6 - 0
smart-city-platform/src/main/java/com/bz/smart_city/service/pay/archives/impl/PayBaseCustomerandmeterrelaServiceImpl.java

@@ -160,6 +160,12 @@ public class PayBaseCustomerandmeterrelaServiceImpl implements PayBaseCustomeran
         return payBaseCustomerandmeterrelaMapper.getResetLadderList(siteId,customerId);
     }
 
+    @Override
+    public PayBaseCustomerandmeterrela findAccountByAccountNumber(String accountnumber) {
+        LoginUser loginUser = UserUtil.getCurrentUser();
+        return payBaseCustomerandmeterrelaMapper.findAccountByAccountNumber(loginUser.getSiteId(),loginUser.getCustomerId(),accountnumber);
+    }
+
     /**
      * 水表档案号搜索
      * @return

+ 25 - 0
smart-city-platform/src/main/resources/mapper/PayBaseCustomerandmeterrelaMapper.xml

@@ -606,4 +606,29 @@
     <select id="getParentOfficeId" resultType="com.bz.smart_city.entity.Organization">
         select id from sc_organization where site_id =#{siteId} and parent_id =#{id} and name =#{name}
     </select>
+    <select id="findAccountByAccountNumber" resultType="com.bz.smart_city.entity.pay.archives.PayBaseCustomerandmeterrela">
+        select
+        account.id as "accountId",
+        account.accountnumber as "accountnumber",
+        account.name as "accountname",
+        customer.invoicetitle as "invoicetitle",
+        account.telephone as "telephone",
+        account.address as "address",
+        customer.vatno as "vatno",
+        customer.bankaccount as "bankaccount"
+        from pay_base_customerandmeterrela customer
+        left join pay_base_account account on customer.account_id = account.id
+        <where>
+            <if test="siteId != null">
+                and customer.site_id = #{siteId}
+            </if>
+            <if test="customerId != null">
+                and  customer.customer_id = #{customerId}
+            </if>
+            <if test="accountnumber != null">
+                and  customer.accountnumber = #{accountnumber}
+            </if>
+        </where>
+        limit 1
+    </select>
 </mapper>

+ 4 - 5
smart-city-platform/src/main/resources/mapper/pay/PayPayReceivedMapper.xml

@@ -328,20 +328,19 @@
             rece.payseriesno as "payseriesno",
             rece.create_date as "createDate",
             rece.ladderlevel as "ladderlevel",
-            rece.payway as "payway",
-            dict2.label as "paywayname",
             sum(rece.receivedamount) as "receivedamount",
             rece.price as "price",
             rece.feetype as "feetype" ,
             dict.label as "feetypename"
         from pay_pay_received rece
         inner join pay_sys_dict dict on dict.type="收费类型" and dict.`value`= rece.feetype
-        inner join pay_sys_dict dict2 on dict2.type="支付方式" and dict2.`value`= rece.payway
+               and dict.site_id = #{siteId}
+               and dict.customer_id = #{customerId}
         where rece.canceledrecord_id is null and rece.iscanceled =0 and rece.receivedamount>0
-              #and rece.payseriesno= #{payseriesno}
+              and rece.payseriesno= #{payseriesno}
               and rece.site_id = #{siteId}
               and rece.customer_id = #{customerId}
-        group by rece.payseriesno,rece.create_date,rece.ladderlevel,rece.payway,dict2.label,rece.price,rece.feetype,dict.label
+        group by rece.payseriesno,rece.create_date,rece.ladderlevel,rece.price,rece.feetype,dict.label
 
     </select>
 </mapper>