Authored by chenchao

add attributes

add cal buyer cancel penalty
1 package com.yohoufo.dal.order.model; 1 package com.yohoufo.dal.order.model;
2 2
  3 +import lombok.Getter;
  4 +import lombok.Setter;
  5 +import lombok.ToString;
  6 +
3 import java.math.BigDecimal; 7 import java.math.BigDecimal;
4 8
  9 +@ToString
5 public class BuyerOrder { 10 public class BuyerOrder {
6 private Integer id; 11 private Integer id;
7 12
@@ -35,6 +40,9 @@ public class BuyerOrder { @@ -35,6 +40,9 @@ public class BuyerOrder {
35 40
36 private Integer sellerOrderStatus; 41 private Integer sellerOrderStatus;
37 42
  43 + @Getter@Setter
  44 + private Integer attributes;
  45 +
38 public Integer getId() { 46 public Integer getId() {
39 return id; 47 return id;
40 } 48 }
@@ -18,10 +18,12 @@ @@ -18,10 +18,12 @@
18 <result column="buyer_order_status" jdbcType="INTEGER" property="buyerOrderStatus" /> 18 <result column="buyer_order_status" jdbcType="INTEGER" property="buyerOrderStatus" />
19 <result column="seller_order_status" jdbcType="INTEGER" property="sellerOrderStatus" /> 19 <result column="seller_order_status" jdbcType="INTEGER" property="sellerOrderStatus" />
20 <result column="channel_no" jdbcType="VARCHAR" property="channelNo" /> 20 <result column="channel_no" jdbcType="VARCHAR" property="channelNo" />
  21 +
  22 + <result column="attributes" jdbcType="INTEGER" property="attributes" />
21 </resultMap> 23 </resultMap>
22 <sql id="Base_Column_List"> 24 <sql id="Base_Column_List">
23 id, uid, order_code, seller_uid, client_type, payment, payment_type, is_cancel, amount, 25 id, uid, order_code, seller_uid, client_type, payment, payment_type, is_cancel, amount,
24 - ship_fee, status, create_time, update_time, buyer_order_status, seller_order_status, channel_no 26 + ship_fee, status, create_time, update_time, buyer_order_status, seller_order_status, channel_no, attributes
25 </sql> 27 </sql>
26 28
27 29
@@ -137,12 +139,13 @@ @@ -137,12 +139,13 @@
137 client_type, payment, payment_type, 139 client_type, payment, payment_type,
138 is_cancel, amount, ship_fee, 140 is_cancel, amount, ship_fee,
139 status, create_time, update_time, 141 status, create_time, update_time,
140 - buyer_order_status, seller_order_status, channel_no) 142 + buyer_order_status, seller_order_status, channel_no, attributes)
141 values (#{uid,jdbcType=INTEGER}, #{orderCode,jdbcType=BIGINT}, #{sellerUid,jdbcType=INTEGER}, 143 values (#{uid,jdbcType=INTEGER}, #{orderCode,jdbcType=BIGINT}, #{sellerUid,jdbcType=INTEGER},
142 #{clientType,jdbcType=INTEGER}, #{payment,jdbcType=INTEGER}, #{paymentType,jdbcType=TINYINT}, 144 #{clientType,jdbcType=INTEGER}, #{payment,jdbcType=INTEGER}, #{paymentType,jdbcType=TINYINT},
143 #{isCancel,jdbcType=TINYINT}, #{amount,jdbcType=DECIMAL}, #{shipFee,jdbcType=DECIMAL}, 145 #{isCancel,jdbcType=TINYINT}, #{amount,jdbcType=DECIMAL}, #{shipFee,jdbcType=DECIMAL},
144 #{status,jdbcType=INTEGER}, #{createTime,jdbcType=INTEGER}, #{updateTime,jdbcType=INTEGER}, 146 #{status,jdbcType=INTEGER}, #{createTime,jdbcType=INTEGER}, #{updateTime,jdbcType=INTEGER},
145 - #{buyerOrderStatus,jdbcType=INTEGER}, #{sellerOrderStatus,jdbcType=INTEGER}, #{channelNo,jdbcType=VARCHAR}) 147 + #{buyerOrderStatus,jdbcType=INTEGER}, #{sellerOrderStatus,jdbcType=INTEGER}, #{channelNo,jdbcType=VARCHAR},
  148 + #{attributes,jdbcType=INTEGER})
146 </insert> 149 </insert>
147 <insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.yohoufo.dal.order.model.BuyerOrder" useGeneratedKeys="true"> 150 <insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.yohoufo.dal.order.model.BuyerOrder" useGeneratedKeys="true">
148 insert into buyer_order 151 insert into buyer_order
@@ -192,6 +195,10 @@ @@ -192,6 +195,10 @@
192 <if test="channelNo != null"> 195 <if test="channelNo != null">
193 channel_no, 196 channel_no,
194 </if> 197 </if>
  198 +
  199 + <if test="attributes != null">
  200 + attributes,
  201 + </if>
195 </trim> 202 </trim>
196 <trim prefix="values (" suffix=")" suffixOverrides=","> 203 <trim prefix="values (" suffix=")" suffixOverrides=",">
197 <if test="uid != null"> 204 <if test="uid != null">
@@ -239,6 +246,9 @@ @@ -239,6 +246,9 @@
239 <if test="channelNo != null"> 246 <if test="channelNo != null">
240 #{channelNo,jdbcType=VARCHAR}, 247 #{channelNo,jdbcType=VARCHAR},
241 </if> 248 </if>
  249 + <if test="attributes != null">
  250 + #{attributes,jdbcType=INTEGER},
  251 + </if>
242 </trim> 252 </trim>
243 </insert> 253 </insert>
244 <update id="updateByPrimaryKeySelective" parameterType="com.yohoufo.dal.order.model.BuyerOrder"> 254 <update id="updateByPrimaryKeySelective" parameterType="com.yohoufo.dal.order.model.BuyerOrder">
@@ -23,4 +23,8 @@ public interface MetaKey { @@ -23,4 +23,8 @@ public interface MetaKey {
23 * 预支付成功记录的appPayRequest 23 * 预支付成功记录的appPayRequest
24 */ 24 */
25 String APP_PAY_REQUEST = "app_pay_request"; 25 String APP_PAY_REQUEST = "app_pay_request";
  26 + /**
  27 + * 买家取消罚款
  28 + */
  29 + String BUYER_CANCEL_PENALTY = "cancel_penalty";
26 } 30 }
  1 +package com.yohoufo.order.model.dto;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +import lombok.experimental.Builder;
  7 +
  8 +import java.math.BigDecimal;
  9 +
  10 +/**
  11 + * Created by chao.chen on 2019/1/4.
  12 + */
  13 +@Data
  14 +@Builder
  15 +@AllArgsConstructor
  16 +@NoArgsConstructor
  17 +public class BuyerPenaltyCalResult {
  18 + private Integer uid;
  19 + private Long orderCode;
  20 + private BigDecimal orderActualAmount;
  21 + private BigDecimal penaltyAmount;
  22 + private BigDecimal leftAmount;
  23 + private BigDecimal penaltyRate;
  24 +}
  1 +package com.yohoufo.order.model.request;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.math.BigDecimal;
  6 +
  7 +/**
  8 + * 单笔转账 最核心的数据
  9 + * Created by chao.chen on 2019/1/4.
  10 + */
  11 +@Data
  12 +public class TranseferCellNode {
  13 + /**
  14 + * 转账金额
  15 + */
  16 + BigDecimal amount;
  17 + /**
  18 + * yoho uid
  19 + */
  20 + Integer uid;
  21 +}
@@ -14,6 +14,8 @@ import lombok.experimental.Builder; @@ -14,6 +14,8 @@ import lombok.experimental.Builder;
14 @NoArgsConstructor 14 @NoArgsConstructor
15 @ToString 15 @ToString
16 public class TransferMoneyRequest { 16 public class TransferMoneyRequest {
  17 +
  18 + private TranseferCellNode transeferCellNode;
17 19
18 private long buyerOrderCode; 20 private long buyerOrderCode;
19 21
1 package com.yohoufo.order.service.impl; 1 package com.yohoufo.order.service.impl;
2 2
  3 +import com.yoho.error.ServiceError;
  4 +import com.yoho.error.exception.ServiceException;
3 import com.yohobuy.ufo.model.order.bo.MerchantOrderAttachInfo; 5 import com.yohobuy.ufo.model.order.bo.MerchantOrderAttachInfo;
4 -import com.yohobuy.ufo.model.order.common.OrderStatus;  
5 -import com.yohobuy.ufo.model.order.common.SellerOrderStatus;  
6 -import com.yohobuy.ufo.model.order.common.SkupStatus;  
7 -import com.yohobuy.ufo.model.order.common.TabType; 6 +import com.yohobuy.ufo.model.order.common.*;
8 import com.yohoufo.common.alarm.EventBusPublisher; 7 import com.yohoufo.common.alarm.EventBusPublisher;
9 import com.yohoufo.common.alarm.SmsAlarmEvent; 8 import com.yohoufo.common.alarm.SmsAlarmEvent;
  9 +import com.yohoufo.common.exception.UfoServiceException;
  10 +import com.yohoufo.common.utils.BigDecimalHelper;
10 import com.yohoufo.common.utils.DateUtil; 11 import com.yohoufo.common.utils.DateUtil;
11 -import com.yohoufo.dal.order.BuyerOrderMapper;  
12 -import com.yohoufo.dal.order.OrderCouponMapper;  
13 -import com.yohoufo.dal.order.SellerOrderGoodsMapper;  
14 -import com.yohoufo.dal.order.SellerOrderMapper; 12 +import com.yohoufo.dal.order.*;
15 import com.yohoufo.dal.order.model.*; 13 import com.yohoufo.dal.order.model.*;
16 import com.yohoufo.order.common.BillTradeStatus; 14 import com.yohoufo.order.common.BillTradeStatus;
17 import com.yohoufo.order.common.RefundCase; 15 import com.yohoufo.order.common.RefundCase;
@@ -22,7 +20,10 @@ import com.yohoufo.order.event.BillLogEvent; @@ -22,7 +20,10 @@ import com.yohoufo.order.event.BillLogEvent;
22 import com.yohoufo.order.event.ErpBuyerOrderEvent; 20 import com.yohoufo.order.event.ErpBuyerOrderEvent;
23 import com.yohoufo.order.model.PayRefundBo; 21 import com.yohoufo.order.model.PayRefundBo;
24 import com.yohoufo.order.model.bo.CouponBo; 22 import com.yohoufo.order.model.bo.CouponBo;
  23 +import com.yohoufo.order.model.dto.BuyerPenalty;
  24 +import com.yohoufo.order.model.dto.BuyerPenaltyCalResult;
25 import com.yohoufo.order.model.request.PaymentRequest; 25 import com.yohoufo.order.model.request.PaymentRequest;
  26 +import com.yohoufo.order.model.request.TranseferCellNode;
26 import com.yohoufo.order.model.request.TransferMoneyRequest; 27 import com.yohoufo.order.model.request.TransferMoneyRequest;
27 import com.yohoufo.order.service.IPaymentService; 28 import com.yohoufo.order.service.IPaymentService;
28 import com.yohoufo.order.service.cache.CacheCleaner; 29 import com.yohoufo.order.service.cache.CacheCleaner;
@@ -40,6 +41,8 @@ import org.springframework.stereotype.Service; @@ -40,6 +41,8 @@ import org.springframework.stereotype.Service;
40 import javax.annotation.Resource; 41 import javax.annotation.Resource;
41 import java.math.BigDecimal; 42 import java.math.BigDecimal;
42 import java.util.Arrays; 43 import java.util.Arrays;
  44 +import java.util.Collection;
  45 +import java.util.Objects;
43 import java.util.concurrent.Callable; 46 import java.util.concurrent.Callable;
44 import java.util.concurrent.Future; 47 import java.util.concurrent.Future;
45 48
@@ -83,6 +86,111 @@ public class BuyerOrderCancelService { @@ -83,6 +86,111 @@ public class BuyerOrderCancelService {
83 @Autowired 86 @Autowired
84 private SellerService sellerService; 87 private SellerService sellerService;
85 88
  89 + @Autowired
  90 + private MetaConfigService metaConfigService;
  91 +
  92 + @Autowired
  93 + private OrdersPayMapper ordersPayMapper;
  94 +
  95 + /**
  96 + *
  97 + * @param buyerUid
  98 + * @param orderActualAmount 订单实付金额
  99 + * @return
  100 + */
  101 + public BuyerPenaltyCalResult calBuyerPenalty(Integer buyerUid, Long orderCode, OrderStatus orderStatus,
  102 + BigDecimal orderActualAmount,
  103 + OrderAttributes orderAttributes
  104 + ){
  105 + if (Objects.isNull(orderAttributes)){
  106 + logger.warn("in calBuyerPenalty order Attributes illegal buyerUid {} orderCode {} orderAttributes {}", buyerUid, orderCode, orderAttributes);
  107 + throw new UfoServiceException(501, "order Attributes illegal");
  108 + }
  109 + BuyerPenalty buyerPenalty = metaConfigService.getBuyerPenalty();
  110 + if (Objects.isNull(buyerPenalty)){
  111 + logger.warn("in calBuyerPenalty order buyerPenalty config illegal buyerUid {} orderCode {} orderAttributes {}", buyerUid, orderCode, orderAttributes);
  112 + throw new UfoServiceException(501, "buyerPenalty config missed");
  113 + }
  114 + BuyerPenalty.Fee mfee = null;
  115 + //common order
  116 + if (Objects.equals(orderAttributes.getCode(), OrderAttributes.COMMON_IN_STOCK.getCode())){
  117 + OrdersPay ordersPay = ordersPayMapper.selectOrdersPay(orderCode, buyerUid);
  118 + Integer payTime;
  119 + if(Objects.isNull(ordersPay) || Objects.isNull(payTime = ordersPay.getCreateTime())){
  120 + logger.warn("in calBuyerPenalty not exist paid record.orderCode {}", orderCode);
  121 + throw new ServiceException(ServiceError.ORDER_HAS_NOT_PAID);
  122 + }
  123 + int currentTime = DateUtil.getCurrentTimeSecond();
  124 + int diffTime = currentTime - payTime;
  125 +
  126 + //before seller deliver
  127 + if (Objects.equals(orderStatus.getCode(), OrderStatus.BUYER_CANCEL_BEFORE_SELLER_DELIVER.getCode())){
  128 + Collection<BuyerPenalty.Fee> fees = buyerPenalty.getStockCaseMap().get("goodsInStock")
  129 + .getTriggerCaseMap().get("beforeSellerDeliver").getStagedCollection();
  130 + mfee = findByTimeCompared(fees, diffTime, orderCode);
  131 + }
  132 + //after seller deliver
  133 +
  134 + if (Objects.equals(orderStatus.getCode(), OrderStatus.BUYER_CANCEL_BEFORE_DEPOT_RECEIVE.getCode())){
  135 + Collection<BuyerPenalty.Fee> fees = buyerPenalty.getStockCaseMap().get("goodsInStock")
  136 + .getTriggerCaseMap().get("beforeDepotReceive").getStagedCollection();
  137 + mfee = fees.iterator().next();
  138 + }
  139 +
  140 + if (Objects.isNull(mfee)){
  141 + logger.warn("in calBuyerPenalty can not match feeRate.orderCode {} diffTime {} buyerPenalty {}",
  142 + orderCode, diffTime, buyerPenalty);
  143 + throw new UfoServiceException(501, "not match calFee");
  144 + }
  145 + }
  146 + //TODO quick deliver
  147 + BuyerPenaltyCalResult bpcr = calBuyerPenalty( mfee,buyerUid, orderCode, orderActualAmount);
  148 + return bpcr;
  149 + }
  150 +
  151 + public BuyerPenaltyCalResult calBuyerPenalty(BuyerPenalty.Fee mfee,Integer buyerUid, Long orderCode,
  152 + BigDecimal orderActualAmount){
  153 + BigDecimal penaltyRate = mfee.getRate();
  154 + BigDecimal penaltyAmount = BigDecimalHelper.halfUp(orderActualAmount.multiply(penaltyRate));
  155 + BuyerPenalty.Range moneyRange = mfee.getMoneyRange();
  156 + if (penaltyAmount.compareTo(moneyRange.getMin()) < 0){
  157 + penaltyAmount = moneyRange.getMin();
  158 + }
  159 + BigDecimal leftAmount = orderActualAmount.subtract(penaltyAmount);
  160 +
  161 + BuyerPenaltyCalResult bpcr = BuyerPenaltyCalResult.builder().uid(buyerUid).orderCode(orderCode)
  162 + .orderActualAmount(orderActualAmount).penaltyRate(penaltyRate)
  163 + .penaltyAmount(penaltyAmount).leftAmount(leftAmount).build();
  164 + logger.info("calBuyerPenalty mfee {} BuyerPenaltyCalResult {}", mfee, bpcr);
  165 + return bpcr;
  166 + }
  167 +
  168 + private BuyerPenalty.Fee findByTimeCompared(Collection<BuyerPenalty.Fee> fees, int diffTime, Long orderCode){
  169 + BuyerPenalty.Fee mfee = null;
  170 + for(BuyerPenalty.Fee fee : fees){
  171 + BuyerPenalty.Range timeRange = fee.getTimeRange();
  172 + BigDecimal min = timeRange.getMin();
  173 + BigDecimal max = timeRange.getMax();
  174 + boolean isgt = false;
  175 + if (Objects.nonNull(min)){
  176 + isgt = diffTime > min.intValue();
  177 + }
  178 + //可以不设置最大值,没有就默认为无穷大,所以默认为满足小于最大值
  179 + boolean islt = true;
  180 + if (Objects.nonNull(max)){
  181 + islt = diffTime <= max.intValue();
  182 + }
  183 +
  184 + if (isgt && islt){
  185 + mfee = fee;
  186 + logger.info("findByTimeCompared orderCode {} diffTime {} mfee {}", orderCode, diffTime, mfee);
  187 + break;
  188 + }
  189 +
  190 + }
  191 + return mfee;
  192 + }
  193 +
86 194
87 public void cancel(BeforeSellerDeliverEvent bsdEvent){ 195 public void cancel(BeforeSellerDeliverEvent bsdEvent){
88 OrderDynamicConfig.BuyerCancelCompensateNode compensate = orderDynamicConfig.getBeforeSellerDeliverBCCN(); 196 OrderDynamicConfig.BuyerCancelCompensateNode compensate = orderDynamicConfig.getBeforeSellerDeliverBCCN();
@@ -93,9 +93,6 @@ public class PaymentServiceImpl implements IPaymentService { @@ -93,9 +93,6 @@ public class PaymentServiceImpl implements IPaymentService {
93 AlipayOuyinService alipayService; 93 AlipayOuyinService alipayService;
94 94
95 @Autowired 95 @Autowired
96 - OrdersPayMapper ordersPayDao;  
97 -  
98 - @Autowired  
99 OrdersPayMapper ordersPayMapper; 96 OrdersPayMapper ordersPayMapper;
100 97
101 @Autowired 98 @Autowired
@@ -134,12 +131,9 @@ public class PaymentServiceImpl implements IPaymentService { @@ -134,12 +131,9 @@ public class PaymentServiceImpl implements IPaymentService {
134 @Autowired 131 @Autowired
135 private BuyerCancelCompensateComputeHandler buyerCancelCompensateComputeHandler; 132 private BuyerCancelCompensateComputeHandler buyerCancelCompensateComputeHandler;
136 133
137 -  
138 @Autowired 134 @Autowired
139 OrdersPrePayMapper ordersPrePayMapper; 135 OrdersPrePayMapper ordersPrePayMapper;
140 -  
141 136
142 -  
143 /** 137 /**
144 * 获取主场的订单service 138 * 获取主场的订单service
145 * @param codeMeta 139 * @param codeMeta
@@ -347,7 +341,7 @@ public class PaymentServiceImpl implements IPaymentService { @@ -347,7 +341,7 @@ public class PaymentServiceImpl implements IPaymentService {
347 attach.put("order_type", orderType); 341 attach.put("order_type", orderType);
348 ordersPay.setAttach(attach.toJSONString()); 342 ordersPay.setAttach(attach.toJSONString());
349 343
350 - ordersPayDao.insertSelective(ordersPay); 344 + ordersPayMapper.insertSelective(ordersPay);
351 return ordersPay; 345 return ordersPay;
352 } 346 }
353 347
@@ -582,10 +576,7 @@ public class PaymentServiceImpl implements IPaymentService { @@ -582,10 +576,7 @@ public class PaymentServiceImpl implements IPaymentService {
582 record.setTradeStatus(0); 576 record.setTradeStatus(0);
583 record.setCreateTime(now); 577 record.setCreateTime(now);
584 578
585 - logger.info("transferMon参数检查成功!");  
586 -  
587 -  
588 - logger.info("transferMon插入初始化转账信息成功,接下来计算费用"); 579 + logger.info("transferMon参数检查成功!插入初始化转账信息成功,接下来计算费用");
589 // 算费 580 // 算费
590 BigDecimal transferAmount = calcTransferAmount(sellerOrder.getUid(), sellerOrder.getSkup(), transferCase); 581 BigDecimal transferAmount = calcTransferAmount(sellerOrder.getUid(), sellerOrder.getSkup(), transferCase);
591 logger.info("transferMon计算费用结果为 {}", transferAmount); 582 logger.info("transferMon计算费用结果为 {}", transferAmount);
  1 +package com.yohoufo.order.service;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.yohobuy.ufo.model.order.common.OrderAttributes;
  5 +import com.yohobuy.ufo.model.order.common.OrderStatus;
  6 +import com.yohoufo.dal.order.BuyerOrderMapper;
  7 +import com.yohoufo.dal.order.model.BuyerOrder;
  8 +import com.yohoufo.order.BaseWebTest;
  9 +import com.yohoufo.order.model.dto.BuyerPenaltyCalResult;
  10 +import com.yohoufo.order.service.impl.BuyerOrderCancelService;
  11 +import org.junit.Test;
  12 +import org.springframework.beans.factory.annotation.Autowired;
  13 +
  14 +import java.math.BigDecimal;
  15 +
  16 +/**
  17 + * Created by chao.chen on 2019/1/4.
  18 + */
  19 +public class BuyerOrderCancelServiceTest extends BaseWebTest {
  20 +
  21 + @Autowired
  22 + private BuyerOrderCancelService buyerOrderCancelService;
  23 +
  24 + @Autowired
  25 + private BuyerOrderMapper buyerOrderMapper;
  26 +
  27 + @Test
  28 + public void testCalBuyerPenalty(){
  29 + Long orderCode = 9832641421313L;
  30 + BuyerOrder buyerOrder = buyerOrderMapper.selectByOrderCode(orderCode);
  31 + Integer buyerUid = buyerOrder.getUid();
  32 + OrderStatus orderStatus = OrderStatus.getOrderStatus(buyerOrder.getStatus());
  33 + BigDecimal orderActualAmount = buyerOrder.getAmount().subtract(buyerOrder.getShipFee());
  34 + OrderAttributes orderAttributes = OrderAttributes.getOrderAttributes(buyerOrder.getAttributes());
  35 + BuyerPenaltyCalResult bpcr = buyerOrderCancelService.calBuyerPenalty(buyerUid, orderCode, orderStatus, orderActualAmount, orderAttributes);
  36 + System.out.println(JSONObject.toJSONString(bpcr));
  37 + }
  38 +}