| 
					
				 | 
			
			
				@@ -0,0 +1,154 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package com.kmall.admin.utils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.kmall.admin.entity.GoodsEntity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import com.kmall.manager.manager.express.sf.ServiceException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.apache.commons.lang3.StringUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.slf4j.Logger; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.slf4j.LoggerFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.math.BigDecimal; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * xwh 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 2020年12月7日14:57:04 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class CalculateTax { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final Logger logger = LoggerFactory.getLogger(CalculateTax.class); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 计算税费,包括消费税和增值税。公式如下: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 订单该商品总税费 = (商品消费税 + 商品增值税)* 0.7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static final BigDecimal calculateTax(GoodsEntity goodsEntity, BigDecimal actualPaymentAmount) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 该商品消费税 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal grandConsumerTax = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 该商品增值税 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal grandValueAddTax = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String hsCode = goodsEntity.getHsCode();// 海关商品编码 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        String hsCodeName = goodsEntity.getHsCodeName();// 海关商品编码名称 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 消费税税率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        final BigDecimal impConsumTaxRate = goodsEntity.getImpConsumTaxRate(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 增值税税率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        final BigDecimal valueAddedTaxRate = goodsEntity.getValueAddedTaxRate(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 计算某类产品的消费税 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            final BigDecimal subConsumerTax = calculateConsumerTax(actualPaymentAmount, impConsumTaxRate, hsCodeName, goodsEntity, actualPaymentAmount); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 计算某类产品的增值税 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            final BigDecimal subValueAddTax = calculateValueAddTax(actualPaymentAmount, valueAddedTaxRate, subConsumerTax); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 计算总的消费税 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            grandConsumerTax = grandConsumerTax.add(subConsumerTax); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 计算总的增值税 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            grandValueAddTax = grandValueAddTax.add(subValueAddTax); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (final RuntimeException e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (logger.isErrorEnabled()) logger.error("计算税费出错!请检查产品的分类数据,以及产品类别的税率数据!", e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            throw new IllegalStateException("计算税费出错!请检查产品的分类数据,以及产品类别的税率数据!", e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 按照公式,打7折 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        final BigDecimal tax = grandConsumerTax.add(grandValueAddTax).multiply(new BigDecimal("0.7")).setScale(2, BigDecimal.ROUND_HALF_UP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return tax; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 计算消费税,公式如下: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 消费税 = (明细商品总价 / (1-消费税税率)) * 消费税税率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param productSubTotal  订单中的某类商品总价(单价 * 数量) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param impConsumTaxRate 进口从价消费税率,百分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param goodsEntity    商品备案信息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param productUnitPrice 产品销售单价 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 消费税 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final BigDecimal calculateConsumerTax(final BigDecimal productSubTotal, final BigDecimal impConsumTaxRate, final String cusGoodsName, GoodsEntity goodsEntity, final BigDecimal productUnitPrice) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 消费税税率为0,不做计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (impConsumTaxRate.compareTo(BigDecimal.ZERO) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal taxRate = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //计算化妆品, 需要计算单价 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal unit1Price = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal unit2Price = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal qty1 = goodsEntity.getLegalUnit1Qty(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal qty2 = goodsEntity.getLegalUnit2Qty(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (StringUtils.isNotBlank(cusGoodsName) && (cusGoodsName.contains("“片”") || cusGoodsName.contains("“张”") || cusGoodsName.contains("\"片\"") || cusGoodsName.contains("\"张\""))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //片、张的单价 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (qty2 != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                unit2Price = productUnitPrice.divide(qty2, 5, BigDecimal.ROUND_HALF_UP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            //毫升、克的单价 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (qty1 != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                BigDecimal gramOrMl = qty1.multiply(new BigDecimal(1000)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                unit1Price = productUnitPrice.divide(gramOrMl, 5, BigDecimal.ROUND_HALF_UP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 每单位价格 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 如果有片、张的单价,按片、张;如果没有则按毫升、克 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal gramOrMlUnitPrice = (unit2Price != null) ? unit2Price : unit1Price; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //获取化妆品阀值 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        BigDecimal cosmThresholdValue = goodsEntity.getCosmThresholdValue(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (cosmThresholdValue != null && cosmThresholdValue.compareTo(BigDecimal.ZERO) > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (gramOrMlUnitPrice != null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                //完税法定单位单价大于阈值采用第一档消费税率,否则消费税率为0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (gramOrMlUnitPrice.compareTo(cosmThresholdValue) >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    taxRate = impConsumTaxRate.divide(new BigDecimal("100"), 10, BigDecimal.ROUND_HALF_UP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    taxRate = BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                String message = "【" + goodsEntity.getSku() + "】缺少法定单价"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                logger.error(message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                throw new ServiceException(message); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 每单位价格小于化妆品阀值,不做计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (taxRate.compareTo(BigDecimal.ZERO) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        final BigDecimal tax = productSubTotal.divide(BigDecimal.ONE.subtract(taxRate), 10, BigDecimal.ROUND_HALF_UP).multiply(taxRate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return tax; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 计算增值税,公式如下: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 增值税 = (明细商品总价 + 消费税) * 增值税税率 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param productSubTotal   订单中的某类商品总价(单价 * 数量) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param valueAddedTaxRate 增值税率,百分数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @param consumerTax       订单中的某类商品总的消费税 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @return 增值税 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static final BigDecimal calculateValueAddTax(final BigDecimal productSubTotal, final BigDecimal valueAddedTaxRate, final BigDecimal consumerTax) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        final BigDecimal taxRate = valueAddedTaxRate.divide(new BigDecimal("100"), 10, BigDecimal.ROUND_HALF_UP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 免税,不做计算 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (taxRate.compareTo(BigDecimal.ZERO) == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return BigDecimal.ZERO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        final BigDecimal tax = productSubTotal.add(consumerTax).multiply(taxRate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return tax; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |