Authored by wujiexiang

使用优惠券

... ... @@ -74,5 +74,9 @@
<groupId>com.yoho.service.model</groupId>
<artifactId>message-service-model</artifactId>
</dependency>
<dependency>
<groupId>com.yoho.ufo.model</groupId>
<artifactId>promotion-ufo-model</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
... ...
package com.yohoufo.order.charge;
import com.yohoufo.order.charge.model.ChargeGoods;
import com.yohoufo.order.charge.model.ChargeParam;
import com.yohoufo.order.charge.model.ChargeResult;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Builder;
/**
* Created by jiexiang.wu on 2018/11/19.
* 算费上下文
*/
@Data
@ToString
@Builder
public class ChargeContext {
//--------------input ------------//
private ChargeParam chargeParam;
private ChargeGoods chargeGoods;
//--------------output ------------//
private ChargeResult chargeResult;
}
... ...
package com.yohoufo.order.charge;
import com.yoho.core.common.utils.YHMath;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yohobuy.ufo.model.promotion.UserCouponsBo;
import com.yohoufo.order.charge.model.*;
import com.yohoufo.order.service.proxy.CouponProxyService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by jiexiang.wu on 2018/11/19.
*/
@Component
public class ChargeService {
private final Logger logger = LoggerFactory.getLogger(getClass());
/**
* 运费
*/
@Value("${buyer.delivery.way.cost.sf:15}")
private double delivery_way_sf_cost;
@Autowired
private CouponProxyService couponProxyService;
@Autowired
private CouponRuleMatcher couponRuleMatcher;
/**
* 算费
*
* @param chargeContext
*/
public void charge(ChargeContext chargeContext) {
doCharge(chargeContext);
}
private void doCharge(ChargeContext chargeContext) {
initCharge(chargeContext);
//1.计算商品金额
calculateGoodsAmount(chargeContext);
//2.计算运费
calculateExpressDeliveryAmount(chargeContext);
//3.计算优惠券
calculateCouponIfNeed(chargeContext);
}
private void initCharge(ChargeContext chargeContext) {
logger.info("[{}] init charge,charge param:{},charge goods:{}",
chargeContext.getChargeParam().getUid(),
chargeContext.getChargeParam(),
chargeContext.getChargeGoods());
ChargeResult chargeResult = new ChargeResult();
chargeContext.setChargeResult(chargeResult);
}
/**
* 计算商品金额
*
* @param chargeContext
*/
private void calculateGoodsAmount(ChargeContext chargeContext) {
//算费商品
ChargeGoods chargeGoods = chargeContext.getChargeGoods();
chargeContext.getChargeResult().setGoodsAmount(chargeGoods.getGoodsAmount().doubleValue());
chargeContext.getChargeResult().setFinalAmount(chargeGoods.getGoodsAmount().doubleValue());
logger.info("[{}] STEP goods charge,goodsPrice:{},goodsAmount:{},amount:{}",
chargeContext.getChargeParam().getUid(),
chargeGoods.getGoodsPrice(),
chargeContext.getChargeResult().getGoodsAmount(),
chargeContext.getChargeResult().getFinalAmount());
}
/**
* 计算运费
*
* @param chargeContext
*/
private void calculateExpressDeliveryAmount(ChargeContext chargeContext) {
//运费
chargeContext.getChargeResult().setExpressDeliveryAmount(delivery_way_sf_cost);
ChargeResult chargeResult = chargeContext.getChargeResult();
double oldFinalAmount = chargeResult.getFinalAmount();
//包括运费
double newFinalAmount = YHMath.add(oldFinalAmount, delivery_way_sf_cost);
chargeResult.setFinalAmount(newFinalAmount);
logger.info("[{}] STEP express charge,sfExpressAmount:{},oldFinalAmount:{},newFinalAmount:{}",
chargeContext.getChargeParam().getUid(),
chargeResult.getExpressDeliveryAmount(),
oldFinalAmount,
chargeResult.getFinalAmount());
}
/**
* 计算优惠券
*
* @param chargeContext
*/
private void calculateCouponIfNeed(ChargeContext chargeContext) {
if (CollectionUtils.isEmpty(chargeContext.getChargeParam().getCouponCodes())) {
return;
}
ChargeResult chargeResult = chargeContext.getChargeResult();
/**
* 目前只能使用一个券
*/
UserCouponsBo userCouponsBo = getOneUsableUserCouponBo(chargeContext);
//券金额 取最小
double couponPayAmount = Math.min(chargeContext.getChargeGoods().getGoodsAmount().doubleValue(), userCouponsBo.getCouponAmount().doubleValue());
double oldFinalAmount = chargeResult.getFinalAmount();
double newFinalAmount = YHMath.sub(oldFinalAmount, couponPayAmount);
chargeResult.setFinalAmount(newFinalAmount);
CouponPayResult couponPayResult = CouponPayResult.builder().couponCode(userCouponsBo.getCouponCode())
.couponAmount(couponPayAmount).couponTitle(userCouponsBo.getCouponName()).build();
chargeResult.setCouponPayResult(couponPayResult);
logger.info("[{}] STEP coupon charge,oldFinalAmount:{},newFinalAmount:{},couponPayResult:{}",
chargeContext.getChargeParam().getUid(),
couponPayAmount, oldFinalAmount, chargeResult.getFinalAmount(), chargeResult.getCouponPayResult());
}
private UserCouponsBo getOneUsableUserCouponBo(ChargeContext chargeContext) {
ChargeParam chargeParam = chargeContext.getChargeParam();
List<UserCouponsBo> couponsBos = couponProxyService.checkUseCouponsAndGet(chargeParam.getUid(), chargeParam.getCouponCodes());
if (CollectionUtils.isEmpty(couponsBos)) {
logger.info("[{}] not find any coupons by couponCodes:{}", chargeParam.getUid(), chargeParam.getCouponCodes());
throw new ServiceException(ServiceError.PROMOTION_COUPON_IS_NOT_VAILD);
}
//对券规则进行匹配
List<CouponMatchResult> couponMatchResults = couponRuleMatcher.match(couponsBos, chargeContext);
//找到可用的券
List<UserCouponsBo> usableCoupons = couponMatchResults.stream().filter(result -> result.isUsable()).map(result -> result.getUserCouponsBo()).collect(Collectors.toList());
if (CollectionUtils.isEmpty(usableCoupons) || usableCoupons.size() != 1) {
logger.info("[{}] get coupons by couponCodes:{} is invalid", chargeParam.getUid(), chargeParam.getCouponCodes());
throw new ServiceException(ServiceError.PROMOTION_COUPON_IS_NOT_VAILD);
}
return usableCoupons.get(0);
}
}
... ...
package com.yohoufo.order.charge;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.promotion.UserCouponsBo;
import com.yohobuy.ufo.model.promotion.constant.CouponProductLimitTypeEnum;
import com.yohobuy.ufo.model.promotion.constant.CouponUseLimitTypeEnum;
import com.yohoufo.order.charge.model.ChargeGoods;
import com.yohoufo.order.charge.model.CouponMatchResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;
/**
* Created by jiexiang.wu on 2018/11/19.
* 券匹配
*/
@Component
public class CouponRuleMatcher {
private final Logger logger = LoggerFactory.getLogger(getClass());
private static List<IRuleMatcher> RULE_MATCHERS = new LinkedList<>();
static {
//商品匹配
RULE_MATCHERS.add(new ProductLimitRuleMatcher());
//金额匹配
RULE_MATCHERS.add(new UseLimitRuleMatcher());
}
/**
* 匹配
*
* @param couponsBos
* @param chargeContext
* @return
*/
public List<CouponMatchResult> match(List<UserCouponsBo> couponsBos, ChargeContext chargeContext) {
List<CouponMatchResult> couponMatchResults = Lists.newArrayList();
for (UserCouponsBo userCouponsBo : couponsBos) {
couponMatchResults.add(this.match(userCouponsBo, chargeContext));
}
return couponMatchResults;
}
private CouponMatchResult match(UserCouponsBo userCouponsBo, ChargeContext chargeContext) {
logger.info("[{}] CouponRuleMatcher Condition <<< {}", chargeContext.getChargeParam().getUid(), userCouponsBo);
CouponMatchResult matchResult = new CouponMatchResult(userCouponsBo);
ChargeGoods chargeGoods = chargeContext.getChargeGoods();
boolean isMatch = true;
for (IRuleMatcher matcher : RULE_MATCHERS) {
if (!matcher.match(chargeGoods, userCouponsBo)) {
isMatch = false;
//不匹配
matchResult.addUnMatchRuleName(matcher.ruleName());
break;
}
}
matchResult.setUsable(isMatch);
logger.info("[{}] CouponRuleMatcher Result >>> couponCode:{},isUsable:{},unMatchRules:{}",
chargeContext.getChargeParam().getUid(),
matchResult.getUserCouponsBo().getCouponCode(),
matchResult.isUsable(),
matchResult.getUnMatchRules());
return matchResult;
}
private interface IRuleMatcher {
/**
* 规则名称
*
* @return
*/
String ruleName();
/**
* 匹配结果
*
* @param chargeGoods
* @param couponsBo
* @return
*/
boolean match(ChargeGoods chargeGoods, UserCouponsBo couponsBo);
}
private static class ProductLimitRuleMatcher implements IRuleMatcher {
@Override
public String ruleName() {
return "ProductLimit";
}
@Override
public boolean match(ChargeGoods chargeGoods, UserCouponsBo couponsBo) {
final CouponProductLimitTypeEnum limitTypeEnum = CouponProductLimitTypeEnum.of(couponsBo.getProductLimitType()).orElse(null);
if (limitTypeEnum == CouponProductLimitTypeEnum.SPECIFIC_PRODUCT) {
return couponsBo.getSknInclude().contains(chargeGoods.getProductId());
} else {
return true;
}
}
}
private static class UseLimitRuleMatcher implements IRuleMatcher {
@Override
public String ruleName() {
return "UseLimit";
}
@Override
public boolean match(ChargeGoods chargeGoods, UserCouponsBo couponsBo) {
final CouponUseLimitTypeEnum limitTypeEnum = CouponUseLimitTypeEnum.of(couponsBo.getUseLimitType()).orElse(null);
if (limitTypeEnum == CouponUseLimitTypeEnum.NON_LIMIT) {
//无限制
return true;
} else if (limitTypeEnum == CouponUseLimitTypeEnum.AMOUNT_LIMIT) {
//金额
return chargeGoods.getGoodsAmount().compareTo(BigDecimal.valueOf(Double.parseDouble(couponsBo.getUseLimitValue()))) >= 0;
} else {
//不应该存在
return false;
}
}
}
}
... ...
package com.yohoufo.order.charge.model;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Builder;
import java.math.BigDecimal;
/**
* Created by jiexiang.wu on 2018/11/19.
*/
@Data
@ToString
@Builder
public class ChargeGoods {
private int productId;
private int skup;
/**
* 商品金额
*/
private BigDecimal goodsPrice;
/**
* 商品金额
*
* @return
*/
public BigDecimal getGoodsAmount() {
return goodsPrice;
}
}
... ...
package com.yohoufo.order.charge.model;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Builder;
import java.util.List;
/**
* Created by jiexiang.wu on 2018/11/19.
* 算费参数
*/
@Data
@ToString
@Builder
public class ChargeParam {
private int uid;
private List<String> couponCodes;
}
... ...
package com.yohoufo.order.charge.model;
import lombok.Data;
import lombok.ToString;
/**
* Created by jiexiang.wu on 2018/11/19.
* 算费结果
*/
@Data
@ToString
public class ChargeResult {
/**
* 商品金额
*/
private double goodsAmount;
/**
* 快递金额
*/
private double expressDeliveryAmount;
/**
* 优惠券支付结果
*/
private CouponPayResult couponPayResult;
/**
* 最终实付金额
*/
private double finalAmount;
}
... ...
package com.yohoufo.order.charge.model;
import com.yohobuy.ufo.model.promotion.UserCouponsBo;
import lombok.Data;
import lombok.ToString;
import java.util.ArrayList;
import java.util.List;
/**
* Created by jiexiang.wu on 2018/11/19.
*/
@Data
@ToString
public class CouponMatchResult {
private boolean isUsable;
private UserCouponsBo userCouponsBo;
/**
* 不匹配的规则名称
*/
private List<String> unMatchRules;
public CouponMatchResult(UserCouponsBo userCouponsBo) {
this.isUsable = false;
this.userCouponsBo = userCouponsBo;
this.unMatchRules = new ArrayList<>();
}
public void addUnMatchRuleName(String ruleName) {
unMatchRules.add(ruleName);
}
}
... ...
package com.yohoufo.order.charge.model;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Builder;
import java.util.Set;
/**
* Created by jiexiang.wu on 2018/11/19.
*/
@Data
@ToString
@Builder
public class CouponPayResult {
/**
* 优惠券码
*
* @var string
*/
private String couponCode = "";
/**
* 优惠券名称
*
* @var string
*/
private String couponTitle = "";
/**
* 优惠券支付金额 <= 优惠券实际的面额
*/
private double couponAmount = 0;
}
... ...
... ... @@ -15,7 +15,7 @@ public class ComputeResponse {
/**
* 券使用结果
*/
CouponUseResult couponUseResult;
CouponInfo couponInfo;
/**
* 费用列表
... ...
... ... @@ -3,13 +3,15 @@ package com.yohoufo.order.model.response;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.Builder;
/**
* Created by jiexiang.wu on 2018/11/19.
*/
@Data
@ToString
public class CouponUseResult {
@Builder
public class CouponInfo {
@JSONField(name = "coupon_code")
private String couponCode;
@JSONField(name = "coupon_title")
... ...
... ... @@ -12,6 +12,12 @@ import com.yohobuy.ufo.model.order.common.OrderCodeType;
import com.yohobuy.ufo.model.order.common.SkupStatus;
import com.yohobuy.ufo.model.order.common.TabType;
import com.yohobuy.ufo.model.order.constants.OrderConstant;
import com.yohoufo.order.charge.ChargeContext;
import com.yohoufo.order.charge.ChargeService;
import com.yohoufo.order.charge.CouponRuleMatcher;
import com.yohoufo.order.charge.model.ChargeGoods;
import com.yohoufo.order.charge.model.ChargeParam;
import com.yohoufo.order.charge.model.ChargeResult;
import com.yohoufo.order.event.BuyerCancelEvent;
import com.yohoufo.order.event.NotPaidNoticeEvent;
import com.yohoufo.order.model.AddressInfo;
... ... @@ -22,11 +28,13 @@ import com.yohoufo.order.model.response.*;
import com.yohoufo.order.service.ISubmitOrderService;
import com.yohoufo.order.service.IShoppingService;
import com.yohoufo.order.service.cache.CacheCleaner;
import com.yohoufo.order.service.proxy.CouponProxyService;
import com.yohoufo.order.service.proxy.InBoxFacade;
import com.yohoufo.order.service.proxy.UserProxyService;
import com.yohoufo.order.service.support.ShoppingSupport;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import com.yohoufo.order.utils.AddressHelper;
import com.yohoufo.order.utils.MathUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -34,8 +42,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
... ... @@ -60,9 +66,9 @@ public class ShoppingServiceImpl implements IShoppingService {
@Autowired
private UserProxyService userProxyService;
@Value("${buyer.delivery.way.cost.sf:15}")
private double delivery_way_sf_cost;
//
// @Value("${buyer.delivery.way.cost.sf:15}")
// private double delivery_way_sf_cost;
@Autowired
... ... @@ -73,6 +79,16 @@ public class ShoppingServiceImpl implements IShoppingService {
@Autowired
private CacheCleaner cacheCleaner;
@Autowired
private ChargeService chargeService;
@Autowired
private CouponProxyService couponProxyService;
@Autowired
private CouponRuleMatcher couponRuleMatcher;
/**
* 结算页数据
* @param request
... ... @@ -89,13 +105,19 @@ public class ShoppingServiceImpl implements IShoppingService {
// 检查 商品sku是否可售
SellerOrderGoods skupGood = checkSkupSellOrNot(request.getSkup());
//构建算费
ChargeContext chargeContext = buildChargeContext(request, skupGood);
//算费
chargeService.charge(chargeContext);
//算费结果
ChargeResult chargeResult = chargeContext.getChargeResult();
PaymentResponse response = new PaymentResponse();
response.setPaymentWay(shoppingSupport.getPaymentWay());
response.setDeliveryWay(shoppingSupport.getDeliverWay());
response.setGood(shoppingSupport.getGoodsInfo(skupGood));
response.setPromotionFormulaList(shoppingSupport.getPromotionFormula(skupGood));
response.setAmount(skupGood.getGoodsPrice().add(new BigDecimal(delivery_way_sf_cost))
.setScale(2,BigDecimal.ROUND_HALF_UP).toPlainString());
response.setPromotionFormulaList(shoppingSupport.getPromotionFormula(chargeResult));
response.setAmount(MathUtils.formatStr(chargeResult.getFinalAmount()));
BigDecimal ompensate = sellerFeeService.computeBuyerCompensate(skup);
//赔偿金计算
... ... @@ -121,6 +143,11 @@ public class ShoppingServiceImpl implements IShoppingService {
return skupGood;
}
private ChargeContext buildChargeContext(ShoppingRequest request, SellerOrderGoods skupInfo) {
return ChargeContext.builder()
.chargeParam(ChargeParam.builder().uid(request.getUid()).couponCodes(request.getCouponCodes()).build())
.chargeGoods(ChargeGoods.builder().goodsPrice(skupInfo.getGoodsPrice()).productId(skupInfo.getProductId()).skup(skupInfo.getId()).build()).build();
}
@Override
public ShoppingCouponListResp selectCoupon(ShoppingRequest request) {
... ... @@ -145,15 +172,27 @@ public class ShoppingServiceImpl implements IShoppingService {
ShoppingCouponListResp resp = new ShoppingCouponListResp();
resp.setCoupons(Lists.newArrayList(coupon1, coupon2));
return resp;
// if ((request.getSkup()) < 0 || request.getUid() < 0) {
// logger.warn("compute uid or skup is null");
// throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
// }
//
// // 检查 商品sku是否可售
// SellerOrderGoods skupGood = checkSkupSellOrNot(request.getSkup());
//
// //构建算费
// ChargeContext chargeContext = buildChargeContext(request, skupGood);
//
// List<UserCouponsBo> userCouponsBos = couponProxyService.getUserAvailableCoupons(chargeContext.getChargeParam().getUid());
// List<CouponMatchResult> couponMatchResults = couponRuleMatcher.match(userCouponsBos,chargeContext);
//todo
}
@Override
public ComputeResponse compute(ShoppingRequest request) {
CouponUseResult result = new CouponUseResult();
result.setCouponCode("a123456");
result.setCouponAmountStr("¥50.00");
result.setCouponTitle("test");
result.setCouponCount(1);
CouponInfo result = CouponInfo.builder().couponCode("a123456").couponAmountStr("¥50.00").couponTitle("test").couponCount(1).build();
PromotionFormula formula1 = new PromotionFormula();
... ... @@ -162,7 +201,7 @@ public class ShoppingServiceImpl implements IShoppingService {
PromotionFormula formula2 = new PromotionFormula();
formula2.setPromotion(OrderConstant.DELIVERY_DESC);
formula2.setPromotionAmount(OrderConstant.PLUS_SIGN + OrderConstant.MONEY_SIGN + delivery_way_sf_cost);
formula2.setPromotionAmount(OrderConstant.PLUS_SIGN + OrderConstant.MONEY_SIGN + 25);
PromotionFormula formula3 = new PromotionFormula();
... ... @@ -178,11 +217,33 @@ public class ShoppingServiceImpl implements IShoppingService {
ComputeResponse response = new ComputeResponse();
response.setCouponUseResult(result);
response.setCouponInfo(result);
response.setPromotionFormulaList(formulaList);
response.setAmount("425.00");
return response;
// 入口参数检查
// if ((request.getSkup()) < 0 || request.getUid() < 0) {
// logger.warn("compute uid or skup is null");
// throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
// }
//
// // 检查 商品sku是否可售
// SellerOrderGoods skupGood = checkSkupSellOrNot(request.getSkup());
// //构建算费
// ChargeContext chargeContext = buildChargeContext(request, skupGood);
// //算费
// chargeService.charge(chargeContext);
// //算费结果
// ChargeResult chargeResult = chargeContext.getChargeResult();
//
// ComputeResponse response = new ComputeResponse();
// response.setCouponInfo(shoppingSupport.getCouponInfo(chargeResult));
// response.setPromotionFormulaList(shoppingSupport.getPromotionFormula(chargeResult));
// response.setAmount(MathUtils.formatStr(chargeResult.getFinalAmount()));
//
// return response;
}
/**
... ... @@ -216,13 +277,20 @@ public class ShoppingServiceImpl implements IShoppingService {
shoppingRequest.getSkup(), shoppingRequest.getAddressId());
throw new ServiceException(ServiceError.ORDER_ADDRESS_NEED_UPDATE);
}
//算费
ChargeContext chargeContext = buildChargeContext(shoppingRequest,skup);
chargeService.charge(chargeContext);
//算费结果
ChargeResult chargeResult = chargeContext.getChargeResult();
// 生成订单号
long orderCode = orderCodeGenerator.generate(OrderCodeType.BUYER_TYPE);
AddressInfo hiddenAddress = userProxyService.getHiddenAddressInfo(shoppingRequest.getUid(), addressId);
// 减库存,skup更新成不可售,入库
BigDecimal shipFee = new BigDecimal(delivery_way_sf_cost);
//BigDecimal shipFee = new BigDecimal(delivery_way_sf_cost);
int uid;
OrderBuilder orderBuilder = OrderBuilder.builder()
.uid(uid=shoppingRequest.getUid())
... ... @@ -232,8 +300,8 @@ public class ShoppingServiceImpl implements IShoppingService {
.paymentType(OrderConstant.PAYMENT_ONLINE)
.deliverWay(OrderConstant.DELIVERY_WAY_SF)
.channelNo(shoppingRequest.getChannelNo())
.amount(skup.getGoodsPrice().add(shipFee))
.shipFee(shipFee)
.amount(BigDecimal.valueOf(chargeResult.getFinalAmount()))
.shipFee(BigDecimal.valueOf(chargeResult.getExpressDeliveryAmount()))
.hiddenAddressInfo(hiddenAddress)
.addressInfo(addressInfo)
.clientType(shoppingRequest.getClientType())
... ...
package com.yohoufo.order.service.proxy;
import com.google.common.collect.Lists;
import com.yohobuy.ufo.model.promotion.UserCouponsBo;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.List;
/**
* Created by jiexiang.wu on 2018/11/19.
*/
@Service
public class CouponProxyService {
/**
* 查询用户可以使用的券
*
* @param uid
* @return
*/
public List<UserCouponsBo> getUserAvailableCoupons(int uid) {
//todo
return Lists.newArrayList();
}
public List<UserCouponsBo> checkUseCouponsAndGet(int uid, List<String> couponCodes) {
UserCouponsBo userCouponsBo = new UserCouponsBo();
userCouponsBo.setCouponAmount(BigDecimal.valueOf(20));
userCouponsBo.setUseLimitType("2");
userCouponsBo.setUseLimitValue("299");
userCouponsBo.setProductLimitType("1");
userCouponsBo.setSknInclude(Lists.newArrayList(88888900));
return Lists.newArrayList(userCouponsBo);
}
}
... ...
package com.yohoufo.order.service.support;
import com.yohobuy.ufo.model.promotion.UserCouponsBo;
import com.yohoufo.order.charge.model.CouponMatchResult;
import com.yohoufo.order.model.response.ShoppingCoupon;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by jiexiang.wu on 2018/11/19.
*/
public class CouponSupport {
public List<ShoppingCoupon> getUsableCoupons(List<CouponMatchResult> couponMatchResults) {
//找到可用的券
List<UserCouponsBo> usableCoupons = couponMatchResults.stream().filter(result -> result.isUsable()).map(result -> result.getUserCouponsBo()).collect(Collectors.toList());
//todo
return null;
}
}
... ...
package com.yohoufo.order.service.support;
import com.fasterxml.jackson.databind.deser.DataFormatReaders;
import com.google.common.collect.Lists;
import com.yohoufo.common.helper.ImageUrlAssist;
import com.yohoufo.common.utils.BigDecimalHelper;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohobuy.ufo.model.order.constants.OrderConstant;
import com.yohoufo.order.charge.ChargeContext;
import com.yohoufo.order.charge.model.ChargeResult;
import com.yohoufo.order.charge.model.CouponPayResult;
import com.yohoufo.order.model.response.CouponInfo;
import com.yohoufo.order.model.response.CouponInfo;
import com.yohoufo.order.model.response.GoodsInfo;
import com.yohoufo.order.model.response.PaymentResponse;
import com.yohoufo.order.model.response.PromotionFormula;
import com.yohoufo.order.utils.MathUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
... ... @@ -67,24 +75,44 @@ public class ShoppingSupport {
/**
* 付款信息
* @param skup
* @param chargeResult
* @return
*/
public List<PromotionFormula> getPromotionFormula(SellerOrderGoods skup) {
PromotionFormula formula1 = new PromotionFormula();
formula1.setPromotion(OrderConstant.GOODS_PRICE);
formula1.setPromotionAmount(OrderConstant.MONEY_SIGN + skup.getGoodsPrice());
public List<PromotionFormula> getPromotionFormula(ChargeResult chargeResult) {
List<PromotionFormula> formulas = Lists.newArrayList();
//商品金额
PromotionFormula goodsFormula = new PromotionFormula();
goodsFormula.setPromotion(OrderConstant.GOODS_PRICE);
goodsFormula.setPromotionAmount(MathUtils.formatCurrencyStr(chargeResult.getGoodsAmount()));
formulas.add(goodsFormula);
//运费
PromotionFormula expressFormula = new PromotionFormula();
expressFormula.setPromotion(OrderConstant.DELIVERY_DESC);
expressFormula.setPromotionAmount(OrderConstant.PLUS_SIGN + MathUtils.formatCurrencyStr(chargeResult.getExpressDeliveryAmount()));
formulas.add(expressFormula);
PromotionFormula formula2 = new PromotionFormula();
formula2.setPromotion(OrderConstant.DELIVERY_DESC);
formula2.setPromotionAmount(OrderConstant.PLUS_SIGN + OrderConstant.MONEY_SIGN + delivery_way_sf_cost);
//优惠券
CouponPayResult couponPayResult = chargeResult.getCouponPayResult();
if (couponPayResult != null) {
PromotionFormula couponFormula = new PromotionFormula();
couponFormula.setPromotion(OrderConstant.COUPON_DESC);
couponFormula.setPromotionAmount(OrderConstant.SUB_SIGN + MathUtils.formatCurrencyStr(couponPayResult.getCouponAmount()));
formulas.add(couponFormula);
}
//最终金额
PromotionFormula finalAmountFormula = new PromotionFormula();
finalAmountFormula.setPromotion(OrderConstant.GOODS_REAL_PRICE);
finalAmountFormula.setPromotionAmount(MathUtils.formatCurrencyStr(chargeResult.getFinalAmount()));
PromotionFormula formula3 = new PromotionFormula();
formula3.setPromotion(OrderConstant.GOODS_REAL_PRICE);
BigDecimal amount = BigDecimalHelper.halfUp(skup.getGoodsPrice().add(new BigDecimal(delivery_way_sf_cost)));
formula3.setPromotionAmount(OrderConstant.MONEY_SIGN + amount);
return Arrays.asList(formula1, formula2, formula3);
formulas.add(finalAmountFormula);
return formulas;
}
... ... @@ -105,4 +133,17 @@ public class ShoppingSupport {
return damagesDesc.toString();
}
public CouponInfo getCouponInfo(ChargeResult chargeResult) {
CouponPayResult couponPayResult = chargeResult.getCouponPayResult();
if (couponPayResult == null) {
return null;
}
return CouponInfo.builder().couponCode(couponPayResult.getCouponCode())
.couponTitle(couponPayResult.getCouponTitle())
.couponAmountStr(MathUtils.formatCurrencyStr(couponPayResult.getCouponAmount()))
.couponCount(1)
.build();
}
}
... ...
package com.yohoufo.order.utils;
import com.yohobuy.ufo.model.order.constants.OrderConstant;
import com.yohoufo.common.utils.BigDecimalHelper;
import java.math.BigDecimal;
import java.text.DecimalFormat;
/**
* Created by jiexiang.wu on 2018/11/19.
*/
public class MathUtils {
public static String formatStr(double d) {
DecimalFormat df = new DecimalFormat("#####0.00");
return df.format(roundPrice(d));
}
public static String formatCurrencyStr(double d) {
DecimalFormat df = new DecimalFormat("#####0.00");
return OrderConstant.MONEY_SIGN + df.format(roundPrice(d));
}
/**
* 获取价格后的后2位小数点
*
* @param price
* @return
*/
public static double roundPrice(double price) {
return BigDecimalHelper.round(BigDecimal.valueOf(price));
}
}
... ...
... ... @@ -18,7 +18,7 @@
<properties>
<qiniu.version>7.0.5</qiniu.version>
<project-name>yohoufo-fore</project-name>
<model.version>1.0-SNAPSHOT</model.version>
<model.version>2.0-SNAPSHOT</model.version>
</properties>
<dependencyManagement>
... ... @@ -101,6 +101,16 @@
<artifactId>user-ufo-model</artifactId>
<version>${model.version}</version>
</dependency>
<dependency>
<groupId>com.yoho.ufo.model</groupId>
<artifactId>order-ufo-model</artifactId>
<version>${model.version}</version>
</dependency>
<dependency>
<groupId>com.yoho.ufo.model</groupId>
<artifactId>promotion-ufo-model</artifactId>
<version>${model.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
... ...
package com.yohoufo.promotion.controller;
import com.yoho.core.rest.annotation.ServiceDesc;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yohobuy.ufo.model.promotion.request.CouponCancelUseReq;
import com.yohobuy.ufo.model.promotion.request.CouponUseReq;
import com.yohobuy.ufo.model.promotion.request.UserCouponListReq;
import com.yohobuy.ufo.model.promotion.UserCouponsListBo;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* Created by jiexiang.wu on 2018/11/19.
* 内部接口
*/
@Controller
@RequestMapping("/userCoupon")
@ServiceDesc(value = "promotion")
public class UserCouponController {
private static Logger logger = LoggerFactory.getLogger(UserCouponController.class);
/**
* 新获取可用的优惠券接口,包括基本信息,以及优惠规则。(供购物车使用)
*
* @param req 包含用户id的请求
* @return
* @see [类、类#方法、类#成员]
*/
@RequestMapping(value = "/getUserAvailableCoupons")
@ResponseBody
public UserCouponsListBo getUserAvailableCoupons(@RequestBody UserCouponListReq req) {
logger.info("queryUserNoUsedCoupons request is {}", req);
if (req == null || (req.getUid() <= 0)) {
logger.warn("queryUserNoUsedCoupons RequestBody is wrong , the request is {} ", req);
throw new ServiceException(ServiceError.PROMOTION_REQUEST_PAREMENT_ERROR);
}
//todo
return null;
}
/**
* 查询并校验优惠券是否能用
* 提供给order模块调用判断优惠券是否可以使用
* 订单使用前调用校验优惠券是否可用
*
* @param req
* @return
*/
@RequestMapping(value = "/checkUseCouponsAndGet")
@ResponseBody
public UserCouponsListBo checkUseCouponsAndGet(@RequestBody UserCouponListReq req) {
logger.info("checkUseCouponsAndGet req is:{}", req);
if (req == null || req.getUid() <= 0 || CollectionUtils.isEmpty(req.getCouponCodes())) {
throw new ServiceException(ServiceError.PROMOTION_REQUEST_PAREMENT_ERROR);
}
//todo
return null;
}
/**
* 订单使用优惠券(订单中心调用)
*
* @param useReq
* @return
*/
@RequestMapping(value = "/orderUseCoupon")
@ResponseBody
public Boolean orderUseCoupon(@RequestBody CouponUseReq useReq) {
logger.info("use coupon request is {}", useReq);
if (useReq.getUid() <= 0 || CollectionUtils.isEmpty(useReq.getCouponCodes()) || useReq.getOrderCode() <= 0) {
logger.info("use coupon request params error {}", useReq);
throw new ServiceException(ServiceError.PROMOTION_REQUEST_PAREMENT_ERROR);
}
// UseCouponBo useCouponBo = new UseCouponBo(useReq.getUid(), useReq.getOrderCode(), useReq.getCouponCodes());
// return iCouponService.useCoupons(useCouponBo);
//todo
return null;
}
/**
* 取消订单优惠券的使用
*
* @param couponOrderCancelUseReq
* @return
*/
@RequestMapping(value = "/cancelCouponUse")
@ResponseBody
public boolean cancelOrderUseCoupon(@RequestBody CouponCancelUseReq couponOrderCancelUseReq) {
int uid = couponOrderCancelUseReq.getUid();
long orderCode = couponOrderCancelUseReq.getOrderCode();
List<String> couponCodes = couponOrderCancelUseReq.getCouponCodes();
if (uid <= 0 || orderCode <= 0 || CollectionUtils.isEmpty(couponCodes)) {
logger.warn("cancel order use coupons req param err:{}", couponOrderCancelUseReq);
throw new ServiceException(ServiceError.PROMOTION_REQUEST_PAREMENT_ERROR);
}
// CancelUseCouponBo cancelUseCouponBo = new CancelUseCouponBo(uid, orderCode, couponCodes);
// return iCouponService.cancelOrderUseCoupon(cancelUseCouponBo);
//todo
return false;
}
}
... ...