diff --git a/jianshui-admin/src/main/resources/application-dev.yml b/jianshui-admin/src/main/resources/application-dev.yml index d064e07..2e437a6 100644 --- a/jianshui-admin/src/main/resources/application-dev.yml +++ b/jianshui-admin/src/main/resources/application-dev.yml @@ -94,7 +94,7 @@ elephant_invoice_file: http://127.0.0.1:8081/invoice/fileUrl/ # 德才定制 放到数据库 #elephant_invoice_file_dc: http://127.0.0.1:8088/sdFile/ # 大象V6数电对应平台地址 -ele_url_v6: https://js.ele12.com/order-api1111 +ele_url_v6: https://js.ele12.com/order-api #ele_url_v6: http://192.168.3.60:18108/order-api #ele_url_v6: http://127.0.0.1:18108/order-api # 大象纸票服务对应平台地址 diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java index 0c7ee90..e8d07de 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/service/impl/adapter/request/AisinoInvoiceRequestAdapterImpl.java @@ -108,7 +108,7 @@ public class AisinoInvoiceRequestAdapterImpl implements IInvoiceRequestService { // 平台解密 try { // TODO: 2023/9/20 - order = JianshuiInvoiceDecryptUtil.decrypt(order, JKey); +// order = JianshuiInvoiceDecryptUtil.decrypt(order, JKey); } catch (Exception e) { e.printStackTrace(); throw new JianshuiParamErrorException(ErrorCode.DECRYPT_ERROR, companyservice, "invoice"); @@ -216,7 +216,7 @@ public class AisinoInvoiceRequestAdapterImpl implements IInvoiceRequestService { if (StringUtils.isBlank(billInfo.getSellerAccount())){ billInfo.setSellerAccount(json.getString("xsfyhzh")); } - if (StringUtils.equals(serviceKey, "add")){ + /*if (StringUtils.equals(serviceKey, "add")){ Environment environment = SpringUtils.getBean(Environment.class); String nsrsbhs = environment.getProperty("billing.limit.nsrsbh"); List shList = Arrays.asList(nsrsbhs.split(",")); @@ -253,7 +253,7 @@ public class AisinoInvoiceRequestAdapterImpl implements IInvoiceRequestService { } } } - } + }*/ json = (JSONObject) JSONObject.toJSON(billInfo); } diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillDetailFormatInspurUtil.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillDetailFormatInspurUtil.java index e69de29..9a4e579 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillDetailFormatInspurUtil.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillDetailFormatInspurUtil.java @@ -0,0 +1,508 @@ +package com.jianshui.invoice.utils; + +import com.alibaba.fastjson.JSONObject; +import com.jianshui.common.core.domain.AjaxResult; +import com.jianshui.invoice.domain.BillDetail; + +import java.math.BigDecimal; + +/** + * @Description 用来将含税金额、不含税金额、税额等进行计算 + * @Author 巩权林 + * @Date 2021-09-29 19:49 + **/ +public class BillDetailFormatInspurUtil { + + /** + * 计算明细的税额、含税金额、不含税金额 + * + * @param billDetail + * @return + */ + public static BillDetail format(BillDetail billDetail) { + Integer fphxz = billDetail.getFphxz(); + // 如果是被折扣行,直接返回 + if (fphxz != null && fphxz == 1) { + return billDetail; + } + //如果单价或数量为空,直接返回 + if ((billDetail.getPrice().equals("") || billDetail.getPrice() == null) || (billDetail.getNum().equals("") || billDetail.getNum() == null)) { + return billDetail; + } + // 如果存在扣除额,直接返回 + BigDecimal kce = billDetail.getKce(); + // 如果当前行存在扣除额 + if (kce != null && kce.compareTo(new BigDecimal(0)) != 0) { + return billDetail; + } + + Integer hsbz = billDetail.getHsbz(); + BigDecimal taxPrice = null; // 含税单价 + BigDecimal taxfreePrice = null; // 不含税单价 + BigDecimal tax = null; // 税额 + BigDecimal taxRate = billDetail.getTaxrate(); // 税率 + BigDecimal num = billDetail.getNum(); // 商品数量 + BigDecimal taxAmt = null; // 含税价格 + BigDecimal taxFreeAmt = null; // 不含税价格 + + if (hsbz == 1) { + taxPrice = billDetail.getPrice(); // 含税单价 + taxfreePrice = taxPrice.divide((new BigDecimal("1")).add(taxRate), 8, BigDecimal.ROUND_DOWN); // 计算不含税单价 + // 诺诺的文档公式如下,但是实际上开出来的票额和这个不一致: 在确认含税单价或者含税金额的情况下,含税标志为 1 含税,税额=round((数量*含税单价)*税率/(1+税率)),2),不含税金额=含税金额-税额。 + // 需要先将含税单价转换为不含税单价,不含税单价进行计算,得到的结果才与票面一直 + // taxAmt = taxPrice.multiply(num); + // tax = ((taxAmt.multiply(taxRate)).divide((new BigDecimal("1")).multiply(taxRate))).setScale(2, BigDecimal.ROUND_HALF_UP); + // taxFreeAmt = taxPrice.subtract(tax); + } else { + taxfreePrice = (billDetail.getPrice()).setScale(8, BigDecimal.ROUND_DOWN); // 不含税单价 + // taxPrice = taxfreePrice.multiply((new BigDecimal("1")).add(taxRate)).setScale(9, BigDecimal.ROUND_HALF_UP); // 计算含税单价 + // 在确认不含税单价或者不含税金额的情况下,含税标志为 0 不含税,税额=round((数量*不含 税单价)*税率),2),含税金额=不含税金额+税额。 + // tax = (taxfreePrice.multiply(num).multiply(taxRate)).setScale(2, BigDecimal.ROUND_HALF_UP); // 计算税额 + // taxAmt = taxFreeAmt.add(tax); // 计算含税金额 + } + // 同一更新为不含税单价 + // TODO 如果税额和不含税金额使用ROUND_DOWN,最红结果会比用户结果小;如果为ROUND_HALF_UP,结果会比用户结果大;山钢项目要求开票税额要比他们的数据小,这里应该用ROUND_DOWN + taxFreeAmt = (taxfreePrice.multiply(num)).setScale(8, BigDecimal.ROUND_HALF_UP); + tax = (taxFreeAmt.multiply(taxRate)).setScale(2, BigDecimal.ROUND_HALF_UP); // 计算税额 + taxFreeAmt = taxFreeAmt.setScale(2, BigDecimal.ROUND_HALF_UP); + taxAmt = taxFreeAmt.add(tax); // 计算含税金额 + billDetail.setHsbz(0); + billDetail.setPrice(taxfreePrice); + billDetail.setTaxamt(taxAmt); + billDetail.setTaxfreeamt(taxFreeAmt); + billDetail.setTax(tax); + return billDetail; + } + + /** + * 计算明细的税额、含税金额、不含税金额 + * + * @param billDetailRaw + * @return + */ + public static BillDetail formats(BillDetail billDetailRaw) { + BillDetail billDetail = JSONObject.parseObject(JSONObject.toJSONString(billDetailRaw), BillDetail.class); + Integer fphxz = billDetail.getFphxz(); + // 如果是被折扣行,直接返回 + if (fphxz == 1) { + return billDetail; + } + //如果单价或数量为空,直接返回 + if (billDetail.getPrice() == null || billDetail.getNum() == null) { + return billDetail; + } + // 如果存在扣除额,直接返回 + BigDecimal kce = billDetail.getKce(); + // 如果当前行存在扣除额 + if (kce != null && kce.compareTo(new BigDecimal(0)) != 0) { + return billDetail; + } + + Integer hsbz = billDetail.getHsbz(); + BigDecimal taxPrice = null; // 含税单价 + BigDecimal taxfreePrice = null; // 不含税单价 + BigDecimal tax = null; // 税额 + BigDecimal taxRate = billDetail.getTaxrate(); // 税率 + BigDecimal num = billDetail.getNum(); // 商品数量 + BigDecimal taxAmt = null; // 含税金额 + BigDecimal taxFreeAmt = null; // 不含税金额 + + if (hsbz != null && hsbz == 1) { + //通过含税单价计算税额、含税金额、不含税金额 + taxPrice = billDetail.getPrice(); // 含税单价 + taxAmt = taxPrice.multiply(num).setScale(2, BigDecimal.ROUND_HALF_UP); + BigDecimal taxRateS = new BigDecimal("1").add(taxRate); + tax = num.multiply(taxPrice).multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + taxFreeAmt = taxAmt.subtract(tax); + // 诺诺的文档公式如下,但是实际上开出来的票额和这个不一致: 在确认含税单价或者含税金额的情况下,含税标志为 1 含税,税额=round((数量*含税单价)*税率/(1+税率)),2),不含税金额=含税金额-税额。 + // 需要先将含税单价转换为不含税单价,不含税单价进行计算,得到的结果才与票面一直 + // taxAmt = taxPrice.multiply(num); + // tax = ((taxAmt.multiply(taxRate)).divide((new BigDecimal("1")).multiply(taxRate))).setScale(2, BigDecimal.ROUND_HALF_UP); + // taxFreeAmt = taxPrice.subtract(tax); + } else { + //通过不含税单价计算税额、含税金额、不含税金额 + taxfreePrice = (billDetail.getPrice()).setScale(8, BigDecimal.ROUND_DOWN); // 不含税单价 + taxFreeAmt = taxfreePrice.multiply(num).setScale(2, BigDecimal.ROUND_HALF_UP); + tax = num.multiply(taxfreePrice).multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + taxAmt = taxFreeAmt.add(tax); + // taxPrice = taxfreePrice.multiply((new BigDecimal("1")).add(taxRate)).setScale(9, BigDecimal.ROUND_HALF_UP); // 计算含税单价 + // 在确认不含税单价或者不含税金额的情况下,含税标志为 0 不含税,税额=round((数量*不含 税单价)*税率),2),含税金额=不含税金额+税额。 + // tax = (taxfreePrice.multiply(num).multiply(taxRate)).setScale(2, BigDecimal.ROUND_HALF_UP); // 计算税额 + // taxAmt = taxFreeAmt.add(tax); // 计算含税金额 + } + + billDetail.setTaxamt(taxAmt); + billDetail.setTaxfreeamt(taxFreeAmt); + billDetail.setTax(tax); + return billDetail; + } + + /** + * 计算单据明细规则 + */ + public static AjaxResult detailFormat(BillDetail billDetailRaw) { + BillDetail billDetail = JSONObject.parseObject(JSONObject.toJSONString(billDetailRaw), BillDetail.class); + Integer fphxz = billDetail.getFphxz(); + // TODO: 2023/11/16 这里被折扣行开票有问题,开票不传taxamt的话 + // 如果是被折扣行,直接返回 + /*if (fphxz != null && fphxz == 1) { + return AjaxResult.error(300, "明细行为被折扣行"); + }*/ + //如果税率为空,直接返回 + if (billDetail.getTaxrate() == null) { + return AjaxResult.error("税率为空", billDetail); + } + //如果单价或数量为空,直接返回 + /*if(billDetail.getPrice() == null && billDetail.getNum() == null){ + return AjaxResult.error("单价和数量均为空",billDetail); + }*/ + // 如果存在扣除额,直接返回 + BigDecimal kce = billDetail.getKce(); + // 如果当前行存在扣除额 + if (kce != null && !"".equals(kce) && !"0".equals(kce)) { + return AjaxResult.error(300, "明细行存在扣除额"); + } + + //如果不含税金额、税额、含税金额存在则校验是否相等 + if (billDetail.getTaxamt() != null && billDetail.getTaxfreeamt() != null && billDetail.getTax() != null) { + BigDecimal dqce = billDetail.getTaxamt().subtract(billDetail.getTaxfreeamt()).subtract(billDetail.getTax());//当前差额 + if (dqce.compareTo(new BigDecimal("0")) != 0) { + return AjaxResult.error("明细行含税金额与不含税金额、税额的和不相等", billDetail); + } + } + + BigDecimal ce6 = new BigDecimal("0.06");//差额6分钱 + //BigDecimal ce1 = new BigDecimal("0.01");//差额6分钱 + BigDecimal ce0 = new BigDecimal("0.00");//差额0分钱 + BigDecimal taxRate = billDetail.getTaxrate(); // 税率 + BigDecimal taxRateS = new BigDecimal("1").add(taxRate); + Integer hsbz = null; + BigDecimal price = null; // 单价 + BigDecimal tax = null; // 税额 + BigDecimal taxs = null;//计算出的税额 + BigDecimal num = null; // 商品数量 + BigDecimal taxAmt = null; // 含税金额 + BigDecimal taxFreeAmt = null; // 不含税金额 + /**单价、数量、含税金额、不含税金额、税额存在 校验值是否大于6分钱 */ + if (billDetail.getPrice() != null && billDetail.getNum() != null && billDetail.getTaxamt() != null + && billDetail.getTaxfreeamt() != null && billDetail.getTax() != null) { + if (billDetail.getHsbz() == null) { + return AjaxResult.error("单价、数量都存在时,含税标志不能为空", billDetail); + } + + hsbz = billDetail.getHsbz(); + BigDecimal amt = billDetail.getPrice().multiply(billDetail.getNum()); + if (hsbz == 0) { + taxs = billDetail.getTaxfreeamt().multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行不含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + //不含税金额校验 + BigDecimal dqce = billDetail.getTaxfreeamt().subtract(amt); + dqce = dqce.compareTo(new BigDecimal("0")) > 0 ? dqce : dqce.multiply(new BigDecimal("-1")); + // dqce 大于 ce6时 进入 + if (dqce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行不含税单价、数量积与不含税金额差额大于6分钱", billDetail); + } + } + if (hsbz == 1) { + num = billDetail.getNum(); + price = billDetail.getPrice(); + taxs = billDetail.getTaxamt().multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + //taxs = num.multiply(price).multiply(taxRate).divide(taxRateS).setScale(2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + } + return AjaxResult.success(billDetail); + } + /**数量存在单价不存在 计算单价及其他金额(判断含税金额存在、或不含税金额存在,优先含税)*/ + else if (billDetail.getNum() != null && billDetail.getPrice() == null) { + //含税金额、税额存在 + if (billDetail.getTaxamt() != null && billDetail.getTax() != null) { +// price = billDetail.getTaxamt().divide(billDetail.getNum(), 8, BigDecimal.ROUND_HALF_UP); + taxs = billDetail.getTaxamt().multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + taxFreeAmt = billDetail.getTaxamt().subtract(billDetail.getTax()); +// billDetail.setPrice(price); + billDetail.setHsbz(1); + billDetail.setTaxfreeamt(taxFreeAmt); + } + //不含税金额、税额存在 + else if (billDetail.getTaxfreeamt() != null && billDetail.getTax() != null) { +// price = billDetail.getTaxfreeamt().divide(billDetail.getNum(), 8, BigDecimal.ROUND_HALF_UP); + taxs = billDetail.getTaxfreeamt().multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行不含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + taxAmt = billDetail.getTaxfreeamt().add(billDetail.getTax()); +// billDetail.setPrice(price); + billDetail.setHsbz(0); + billDetail.setTaxamt(taxAmt); + } + //含税金额、不含税金额存在 + else if (billDetail.getTaxamt() != null && billDetail.getTaxfreeamt() != null) { +// price = billDetail.getTaxamt().divide(billDetail.getNum(), 8, BigDecimal.ROUND_HALF_UP); + taxs = billDetail.getTaxamt().multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTaxamt().subtract(billDetail.getTaxfreeamt()); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税金额使用公式计算出的税额与传入含税金额减去不含税金额计算出的税额差额大于6分钱", billDetail); + } +// billDetail.setPrice(price); + billDetail.setHsbz(1); + billDetail.setTax(tax); + } else { + return AjaxResult.error("没有匹配的计算规则", billDetail); + } + return AjaxResult.success(billDetail); + } + /**单价存在数量不存在 计算数量及其他金额*/ + else if (billDetail.getPrice() != null && billDetail.getNum() == null) { + if (billDetail.getHsbz() == null) { + return AjaxResult.error("单价存在数量不存在时,含税标志不能为空", billDetail); + } + //含税标志为含税:含税金额、税额存在 + if (billDetail.getHsbz() == 1 && billDetail.getTaxamt() != null && billDetail.getTax() != null) { + num = billDetail.getTaxamt().divide(billDetail.getPrice(), 8, BigDecimal.ROUND_HALF_UP); + taxs = billDetail.getTaxamt().multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + taxFreeAmt = billDetail.getTaxamt().subtract(billDetail.getTax()); + billDetail.setNum(num); + billDetail.setTaxfreeamt(taxFreeAmt); + } + //含税标志为含税:不含税金额、税额存在 + else if (billDetail.getHsbz() == 1 && billDetail.getTaxfreeamt() != null && billDetail.getTax() != null) { + taxs = billDetail.getTaxfreeamt().multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行不含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + taxAmt = billDetail.getTaxfreeamt().add(billDetail.getTax()); + num = taxAmt.divide(billDetail.getPrice(), 8, BigDecimal.ROUND_HALF_UP); + billDetail.setNum(num); + billDetail.setTaxamt(taxAmt); + } + //含税标志为不含税:含税金额、税额存在 + else if (billDetail.getHsbz() == 0 && billDetail.getTaxamt() != null && billDetail.getTax() != null) { + taxs = billDetail.getTaxamt().multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + taxFreeAmt = billDetail.getTaxamt().subtract(billDetail.getTax()); + num = taxFreeAmt.divide(billDetail.getPrice(), 8, BigDecimal.ROUND_HALF_UP); + billDetail.setNum(num); + billDetail.setTaxfreeamt(taxFreeAmt); + } + //含税标志为不含税:不含税金额、税额存在 + else if (billDetail.getHsbz() == 0 && billDetail.getTaxfreeamt() != null && billDetail.getTax() != null) { + taxs = billDetail.getTaxfreeamt().multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行不含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + num = billDetail.getTaxfreeamt().divide(billDetail.getPrice(), 8, BigDecimal.ROUND_HALF_UP); + taxAmt = billDetail.getTaxfreeamt().add(billDetail.getTax()); + billDetail.setNum(num); + billDetail.setTaxamt(taxAmt); + } else { + return AjaxResult.error("没有匹配的计算规则", billDetail); + } + return AjaxResult.success(billDetail); + } + /**数量、单价存在 计算各类金额*/ + else if (billDetail.getPrice() != null && billDetail.getNum() != null) { + if (billDetail.getHsbz() == null) { + return AjaxResult.error("单价、数量都存在时,含税标志不能为空", billDetail); + } + hsbz = billDetail.getHsbz(); + num = billDetail.getNum(); + price = billDetail.getPrice(); + BigDecimal amt = price.multiply(num); + //含税金额、税额、不含税金额均不存在 存在误差、差额 + if (billDetail.getTaxamt() == null && billDetail.getTaxfreeamt() == null && billDetail.getTax() == null) { + if (billDetail.getHsbz() == 1) { + taxAmt = amt.setScale(2, BigDecimal.ROUND_HALF_UP); + tax = amt.multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + taxFreeAmt = taxAmt.subtract(tax); + billDetail.setTaxamt(taxAmt); + billDetail.setTax(tax); + billDetail.setTaxfreeamt(taxFreeAmt); + return AjaxResult.success(billDetail); + } else if (billDetail.getHsbz() == 0) { + taxFreeAmt = amt.setScale(2, BigDecimal.ROUND_HALF_UP); + tax = taxFreeAmt.multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + taxAmt = taxFreeAmt.add(tax); + billDetail.setTaxamt(taxAmt); + billDetail.setTax(tax); + billDetail.setTaxfreeamt(taxFreeAmt); + return AjaxResult.success(billDetail); + } + } + //含税金额存在 存在差额 + else if (billDetail.getTaxamt() != null) { + if (hsbz == 1) {//含税标志为 1 含税,税额=round((数量*含税单价)*税率/(1+税率)),2),不含税金额=含税金额-税额。 + BigDecimal dqce = billDetail.getTaxamt().subtract(amt); + //是否相等 + if (dqce.compareTo(ce0) != 0) { + return AjaxResult.error("明细行含税单价、数量积不等于含税金额", billDetail); + } + taxAmt = billDetail.getTaxamt(); + tax = taxAmt.multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + taxFreeAmt = taxAmt.subtract(tax); + billDetail.setTaxamt(taxAmt); + billDetail.setTax(tax); + billDetail.setTaxfreeamt(taxFreeAmt); + return AjaxResult.success(billDetail); + } else if (hsbz == 0) {//含税标志为 0 不含税,税额=round((数量*不含税单价)*税率),2),含税金额=不含税金额+税额。 + taxAmt = billDetail.getTaxamt(); + taxFreeAmt = amt.setScale(2, BigDecimal.ROUND_HALF_UP); + tax = taxAmt.subtract(taxFreeAmt); + taxs = taxAmt.multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税金额使用公式计算出的税额与传入含税金额减去不含税金额(不含税单价、数量积)计算出的税额差额大于6分钱", billDetail); + } + billDetail.setTaxamt(taxAmt); + billDetail.setTax(tax); +// billDetail.setTax(taxs); + billDetail.setTaxfreeamt(taxFreeAmt); + return AjaxResult.success(billDetail); + } + } + //不含税金额存在 存在差额 + else if (billDetail.getTaxfreeamt() != null) { + if (hsbz == 0) {//含税标志为 0 不含税,税额=round((数量*不含税单价)*税率),2),含税金额=不含税金额+税额。 + BigDecimal dqce = billDetail.getTaxfreeamt().subtract(amt); + //是否相等 + if (dqce.compareTo(ce0) != 0) { + return AjaxResult.error("明细行不含税单价、数量积不等于不含税金额", billDetail); + } + dqce = dqce.compareTo(new BigDecimal("0")) > 0 ? dqce : dqce.multiply(new BigDecimal("-1")); + taxFreeAmt = billDetail.getTaxfreeamt(); + tax = taxFreeAmt.multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + taxAmt = taxFreeAmt.add(tax); + billDetail.setTaxamt(taxAmt); + billDetail.setTax(tax); + billDetail.setTaxfreeamt(taxFreeAmt); + return AjaxResult.success(billDetail); + } else if (hsbz == 1) {//含税标志为 1 含税,税额=round((数量*含税单价)*税率/(1+税率)),2),不含税金额=含税金额-税额。 + taxFreeAmt = billDetail.getTaxfreeamt(); + taxAmt = amt.setScale(2, BigDecimal.ROUND_HALF_UP); + tax = taxAmt.subtract(taxFreeAmt); + taxs = taxFreeAmt.multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税金额使用公式计算出的税额与传入含税金额(含税单价、数量积)减去不含税金额计算出的税额差额大于6分钱", billDetail); + } + billDetail.setTaxamt(taxAmt); + billDetail.setTax(tax); + billDetail.setTaxfreeamt(taxFreeAmt); + return AjaxResult.success(billDetail); + } + } + //税额存在 存在差额 + else if (billDetail.getTax() != null) { + tax = billDetail.getTax(); + if (hsbz == 1) {//含税标志为 1 含税,税额=round((数量*含税单价)*税率/(1+税率)),2),不含税金额=含税金额-税额。 + taxAmt = amt.setScale(2, BigDecimal.ROUND_HALF_UP); + taxs = taxAmt.multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税单价、数量使用公式计算出的税额与传入税额差额大于6分钱", billDetail); + } + taxFreeAmt = taxAmt.subtract(tax); + billDetail.setTaxamt(taxAmt); + billDetail.setTax(tax); + billDetail.setTaxfreeamt(taxFreeAmt); + return AjaxResult.success(billDetail); + } else if (hsbz == 0) {//含税标志为 0 不含税,税额=round((数量*不含税单价)*税率),2),含税金额=不含税金额+税额。 + taxFreeAmt = amt.setScale(2, BigDecimal.ROUND_HALF_UP); + taxs = taxFreeAmt.multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行不含税单价、数量使用公式计算出的税额与传入税额差额大于6分钱", billDetail); + } + taxAmt = taxFreeAmt.add(tax); + billDetail.setTaxamt(taxAmt); + billDetail.setTax(tax); + billDetail.setTaxfreeamt(taxFreeAmt); + return AjaxResult.success(billDetail); + } + } + } + /**数量、单价不存在 计算各类金额*/ + else if (billDetail.getNum() == null && billDetail.getPrice() == null) { + //含税金额、税额存在 + if (billDetail.getTaxamt() != null && billDetail.getTax() != null) { + taxs = billDetail.getTaxamt().multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + taxFreeAmt = billDetail.getTaxamt().subtract(billDetail.getTax()); + billDetail.setTaxfreeamt(taxFreeAmt); + } + //含税金额、不含税金额存在 + else if (billDetail.getTaxamt() != null && billDetail.getTaxfreeamt() != null) { + taxs = billDetail.getTaxamt().multiply(taxRate).divide(taxRateS, 2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTaxamt().subtract(billDetail.getTaxfreeamt()); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + billDetail.setTax(tax); + } + //不含税金额、税额存在 + else if (billDetail.getTaxfreeamt() != null && billDetail.getTax() != null) { + taxs = billDetail.getTaxfreeamt().multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP); + tax = billDetail.getTax(); + BigDecimal taxce = tax.subtract(taxs); + taxce = taxce.compareTo(new BigDecimal("0")) > 0 ? taxce : taxce.multiply(new BigDecimal("-1")); + if (taxce.compareTo(ce6) > 0) { + return AjaxResult.error("明细行不含税金额计算出的税额与传入税额差额大于6分钱", billDetail); + } + taxAmt = billDetail.getTaxfreeamt().add(billDetail.getTax()); + billDetail.setTaxamt(taxAmt); + } else { + return AjaxResult.error("没有匹配的计算规则", billDetail); + } + return AjaxResult.success(billDetail); + } + return AjaxResult.error("没有匹配的计算规则", billDetail); + } +} diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillDetailInspurUtils.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillDetailInspurUtils.java index e69de29..99de813 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillDetailInspurUtils.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillDetailInspurUtils.java @@ -0,0 +1,54 @@ +package com.jianshui.invoice.utils; + +import com.jianshui.common.core.domain.AjaxResult; +import com.jianshui.common.core.domain.entity.Companyservice; +import com.jianshui.common.exception.jianshui.JianshuiParamErrorException; +import com.jianshui.common.utils.ValidateUtils; +import com.jianshui.common.utils.bean.BeanUtils; +import com.jianshui.invoice.domain.BillDetail; + +/** + * @Description 发票订单工具类 + * @Author 巩权林 + * @Date 2022-03-21 16:58 + **/ +public class BillDetailInspurUtils { + + + /** + * 验证billInfo + * + * @param validateDetailfoClazz 要校验的目标bill类型 + * @param billDetail 原始billinfo + * @param + * @throws IllegalAccessException + * @throws InstantiationException + */ + public static void validate(Class validateDetailfoClazz, BillDetail billDetail, Companyservice companyservice, String serviceKey) throws IllegalAccessException, InstantiationException { + T validateBillDetail = validateDetailfoClazz.newInstance(); + BeanUtils.copyProperties(billDetail, validateBillDetail); + ValidateUtils.validate(validateBillDetail, companyservice, serviceKey); + } + + + /** + * 预处理 + * + * @param billDetail + * @param companyservice + * @return + */ + public static BillDetail preprocessing(BillDetail billDetail, Companyservice companyservice) { + BillDetail detail = billDetail; + AjaxResult formatResult = BillDetailFormatInspurUtil.detailFormat(billDetail); + if (formatResult.isError()) { + int code = formatResult.getCode(); + if (code == AjaxResult.error().getCode()) { + throw new JianshuiParamErrorException(formatResult.getMsg(), companyservice, "invoice"); + } + } else { + detail = formatResult.getJsonData(BillDetail.class); + } + return detail; + } +} diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillInfoInspurUtils.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillInfoInspurUtils.java index cf3ebb7..014b2f8 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillInfoInspurUtils.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/BillInfoInspurUtils.java @@ -109,9 +109,11 @@ public class BillInfoInspurUtils { if(taxAmDetail.compareTo(zero) > 0){ detail.setHsbz(0); taxfreeamt = taxfreeamt.add(NumberUtil.sub(taxAmDetail,taxDetail)); + taxamt = taxamt.add(taxAmDetail); }else if(taxFreeAmtDetail.compareTo(zero) > 0 ){ detail.setHsbz(0); taxfreeamt = taxfreeamt.add(taxFreeAmtDetail); + taxamt = taxamt.add(NumberUtil.add(taxFreeAmtDetail,taxDetail) ); }else{ String errorMsg = StringUtils.format("发票第{}条明细,含税金额为空,无法开票", i); throw new JianshuiBillInfoCalucateException(errorMsg, companyservice, JSONObject.toJSONString(billInfo)); @@ -265,8 +267,8 @@ public class BillInfoInspurUtils { BillDetail tempDetail = originDetail.get(i); // tempDetail.setBillInfoId(billInfo.getId()); try { - tempDetail = BillDetailUtils.preprocessing(tempDetail, companyservice); - BillDetailUtils.validate(AddDetailValidateDTO.class, tempDetail, companyservice, "invoice"); + tempDetail = BillDetailInspurUtils.preprocessing(tempDetail, companyservice); + BillDetailInspurUtils.validate(AddDetailValidateDTO.class, tempDetail, companyservice, "invoice"); } catch (JianshuiParamErrorException e) { throw new JianshuiParamErrorException("第" + (i + 1 )+ "行明细:" + e.getMessage(), companyservice, "invoice"); } diff --git a/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/InvoiceTest.java b/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/InvoiceTest.java index 89b4973..d2fb020 100644 --- a/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/InvoiceTest.java +++ b/jianshui-invoice/src/main/java/com/jianshui/invoice/utils/InvoiceTest.java @@ -2112,6 +2112,72 @@ public class InvoiceTest { " }\n" + " ]\n" + "}"; + + + + order = "{ \"taxnum\": \"91150100MA0Q130L6R\", \"buyername\": \"内蒙古国大医药有限公司\", \"address\": \"内蒙古自治区呼和浩特市土默特左旗金山开发区新能源汽车产业园动力总成办公楼2203、2204号 3393701\", \"buyerBank\": \"兴业银行股份有限公司呼和浩特通道街支行 592070100100087247\", \"account\": \"\", \"telephone\": \"\", \"orderno\": \"76e1e06442604754a099ecf1e2b8397e\", \"invoicedate\": \"2024-05-24\", \"saletaxnum\": \"913706006134130784\", \"saleaddress\": \"中国(山东)自由贸易试验区烟台片区烟台开发区北京中路56号\", \"salephone\": \"0535-6383098\", \"saleaccount\": \"中国建设银行股份有限公司烟台长江路支行 37050166666109555555\", \"kptype\": \"1\", \"message\": \"\", \"clerk\": \"原金霖\", \"checker\": \"\", \"payee\": \"\", \"invoiceLine\": \"81\", \"xsfkhh\": \"中国建设银行股份有限公司烟台长江路支行\", \"xsflxdh\": \"0535-6383098\", \"xsfmc\": \"烟台荣昌制药股份有限公司\", \"xsfnsrsbh\": \"913706006134130784\", \"xsfyhzh\": \"37050166666109555555\", \"email\": \"864822706@qq.com\", \"phone\": \"\", \"tsfs\": \"2\", \"dkbz\": \"0\", \"deptid\": \"\", \"clerkid\": \"\", \"fpdm\": \"\", \"fphm\": \"\", \"fjh\": \"\", \"terminalNumber\": \"\", \"jqbh\": \"\", \"productOilFlag\": \"0\", \"billInfono\": \"\", \"qdbz\": \"0\", \"qdxmmc\": \"\", \"detail\": [ { \"fphxz\": \"0\", \"goodsname\": \"银杏叶片\", \"spec\": \"24片*400盒\", \"unit\": \"盒\", \"num\": \"2000\", \"price\": \"\", \"hsbz\": \"1\", \"taxamt\": \"19600.00\", \"taxrate\": \"0.13\", \"tax\": \"2254.87\", \"spbm\": \"1070304040000000000\", \"zsbm\": \"\", \"yhzcbs\": \"0\", \"zzstsgl\": \"\", \"lslbs\": \"\", \"kce\": \"\" } ]}"; + + + order = "{\n" + + " \"taxnum\": \"91150100MA0Q130L6R\",\n" + + " \"buyername\": \"内蒙古国大医药有限公司\",\n" + + " \"address\": \"内蒙古自治区呼和浩特市土默特左旗金山开发区新能源汽车产业园动力总成办公楼2203、2204号 3393701\",\n" + + " \"buyerBank\": \"兴业银行股份有限公司呼和浩特通道街支行 592070100100087247\",\n" + + " \"account\": \"\",\n" + + " \"telephone\": \"\",\n" + + " \"orderno\": \"76e1e06442604754a099ecf1e2b8397e\",\n" + + " \"invoicedate\": \"2024-05-24\",\n" + + " \"saletaxnum\": \"92370214MACAAEK16E\",\n" + + " \"saleaddress\": \"中国(山东)自由贸易试验区烟台片区烟台开发区北京中路56号\",\n" + + " \"salephone\": \"0535-6383098\",\n" + + " \"saleaccount\": \"中国建设银行股份有限公司烟台长江路支行 37050166666109555555\",\n" + + " \"kptype\": \"1\",\n" + + " \"message\": \"\",\n" + + " \"clerk\": \"原金霖\",\n" + + " \"checker\": \"\",\n" + + " \"payee\": \"\",\n" + + " \"invoiceLine\": \"81\",\n" + + " \"xsfkhh\": \"中国建设银行股份有限公司烟台长江路支行\",\n" + + " \"xsflxdh\": \"0535-6383098\",\n" + + " \"xsfmc\": \"城阳区兴顺通制冷设备维修服务部\",\n" + + " \"xsfnsrsbh\": \"92370214MACAAEK16E\",\n" + + " \"xsfyhzh\": \"37050166666109555555\",\n" + + " \"email\": \"864822706@qq.com\",\n" + + " \"phone\": \"\",\n" + + " \"tsfs\": \"2\",\n" + + " \"dkbz\": \"0\",\n" + + " \"deptid\": \"\",\n" + + " \"clerkid\": \"\",\n" + + " \"fpdm\": \"\",\n" + + " \"fphm\": \"\",\n" + + " \"fjh\": \"\",\n" + + " \"terminalNumber\": \"\",\n" + + " \"jqbh\": \"\",\n" + + " \"productOilFlag\": \"0\",\n" + + " \"billInfono\": \"\",\n" + + " \"qdbz\": \"0\",\n" + + " \"qdxmmc\": \"\",\n" + + " \"detail\": [\n" + + " {\n" + + " \"fphxz\": \"0\",\n" + + " \"goodsname\": \"维修费\",\n" + + " \"spec\": \"24片*400盒\",\n" + + " \"unit\": \"盒\",\n" + + " \"num\": \"2000\",\n" + + " \"price\": \"\",\n" + + " \"hsbz\": \"1\",\n" + + " \"taxamt\": \"19600.00\",\n" + + " \"taxrate\": \"0.13\",\n" + + " \"tax\": \"2254.87\",\n" + + " \"spbm\": \"\",\n" + + " \"zsbm\": \"\",\n" + + " \"yhzcbs\": \"0\",\n" + + " \"zzstsgl\": \"\",\n" + + " \"lslbs\": \"\",\n" + + " \"kce\": \"\"\n" + + " }\n" + + " ]\n" + + "}"; System.out.println(JianshuiInvoiceDecryptUtil.encrypt(order,key)); System.out.println("========================");