package com.hx.phip.tool.user;
|
|
import com.hx.common.service.CommonService;
|
import com.hx.exception.TipsException;
|
import com.hx.mybatisTool.SqlSentence;
|
import com.hx.phiappt.common.UserProjectConstants;
|
import com.hx.phiappt.model.cardItem.CardEquity;
|
import com.hx.phiappt.model.cardItem.CardItemInfo;
|
import com.hx.phiappt.model.consume.ConsumePayItem;
|
import com.hx.phiappt.model.order.OrderItem;
|
import com.hx.phiappt.model.order.OrdersTotal;
|
import com.hx.phiappt.model.refund.RefundRecordItem;
|
import com.hx.phiappt.model.user.UserCard;
|
import com.hx.phiappt.model.user.UserCardUsed;
|
import com.hx.phip.dao.mapper.*;
|
import com.hx.phip.tool.order.OrderTool;
|
import com.hx.phip.tool.refund.PaymentCountTool;
|
import com.hx.phip.tool.refund.RefundTool;
|
import com.hx.phip.vo.order.payment.PayMethodVo;
|
import com.hx.phip.vo.order.refund.DistributionRedundVo;
|
import com.hx.phip.vo.user.UserCardItemInfoVo;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
*用户卡包处理工具
|
* @author CJH
|
*/
|
public class UserCardTool {
|
|
/**计算使用次数
|
* @param buyNumber 购买数量
|
* @param cardItemInfo 卡项条目
|
* @param cardEquity 卡项权益
|
* @return 计算得出抵扣次数
|
*/
|
public static int countUsedNumber(int buyNumber, CardItemInfo cardItemInfo,CardEquity cardEquity){
|
int userdNum ;
|
if(CardEquity.EQUITY_TYPE_TIME_CARD.equals(cardEquity.getEquityType())){
|
//次卡,权益有总次数,所有条目使用的总次数不能大于权益的总次数
|
userdNum = buyNumber*cardItemInfo.getEveryDrawNum();
|
}else if(CardEquity.EQUITY_TYPE_N_M.equals(cardEquity.getEquityType())){
|
//N选M
|
userdNum = buyNumber;
|
}else{
|
//固定或者其他
|
userdNum = buyNumber;
|
}
|
return userdNum;
|
}
|
|
|
/**获取卡包-卡项条目剩余次数
|
* @param userCard 用户卡包
|
* @param cardItemInfo 卡项条目
|
* @param cardEquity 卡项权益
|
* @param commonService 映射
|
* @return 数据结构
|
*/
|
public static UserCardItemInfoVo getSurplusNumber(UserCard userCard, CardItemInfo cardItemInfo,CardEquity cardEquity, CommonService commonService){
|
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
//获取使用记录,注意:是根据权益,不是卡项条目查询
|
values.put("cardEquityId",cardEquity.getId());
|
values.put("userCardId",userCard.getId());
|
values.put("isDel",UserCardUsed.NO);
|
sqlSentence.sqlSentence("SELECT * FROM user_card_used WHERE cardEquityId = #{m.cardEquityId} AND userCardId = #{m.userCardId} AND isDel = #{m.isDel}",values);
|
//根据cardItemIfo标识查询用户使用记录
|
List<UserCardUsed> userCardUsedList = commonService.selectList(UserCardUsedMapper.class, sqlSentence);
|
|
//已使用的条目标识集合
|
Set<String> cardItemInfoIds = new HashSet<>();
|
//每个条目使用总次数Map
|
Map<String,Integer> cardItemInfoUseMap = new HashMap<>();
|
//计算所有条目已使用总次数
|
Integer usedGeneral = 0;
|
|
Integer num;
|
for(UserCardUsed userCardUsed:userCardUsedList){
|
//计算所有条目已使用总次数
|
usedGeneral = usedGeneral+userCardUsed.getUsedNum();
|
//已使用的条目标识集合
|
cardItemInfoIds.add(userCardUsed.getCardItemInfoId());
|
//每个条目使用总参数Map
|
num = cardItemInfoUseMap.computeIfAbsent(userCardUsed.getCardItemInfoId(),k->0);
|
num = num + userCardUsed.getUsedNum();
|
cardItemInfoUseMap.put(userCardUsed.getCardItemInfoId(),num);
|
}
|
|
//返回结构
|
UserCardItemInfoVo userCardItemInfoVo = new UserCardItemInfoVo();
|
|
if(CardEquity.EQUITY_TYPE_TIME_CARD.equals(cardEquity.getEquityType())){
|
//次卡,权益有总次数,所有条目使用的总次数不能大于权益的总次数
|
if(usedGeneral < cardEquity.getValue()){
|
//是否设置了最大的抵扣次数
|
int surplusNum = cardEquity.getValue() - usedGeneral;
|
if(cardItemInfo.getMaxNum() != null && cardItemInfo.getMaxNum() != 0){
|
userCardItemInfoVo.setSurplusNum(cardItemInfo.getMaxNum() - cardItemInfoUseMap.computeIfAbsent(cardItemInfo.getId(),k->0));
|
if(userCardItemInfoVo.getSurplusNum() > surplusNum){
|
userCardItemInfoVo.setSurplusNum(surplusNum);
|
}
|
}else{
|
userCardItemInfoVo.setSurplusNum(surplusNum);
|
}
|
}else{
|
userCardItemInfoVo.setSurplusNum(0);
|
}
|
}else if(CardEquity.EQUITY_TYPE_N_M.equals(cardEquity.getEquityType())){
|
//N选M,每个条目都有自己的可抵扣总次数
|
if(cardItemInfoIds.contains(cardItemInfo.getId())){
|
//已经使用条目集合包含当前条目
|
userCardItemInfoVo.setSurplusNum(cardItemInfo.getMaxNum() - cardItemInfoUseMap.get(cardItemInfo.getId()));
|
}else{
|
//已经使用条目集合没有包含当前条目
|
if(cardItemInfoIds.size() >= cardEquity.getValue()){
|
//已经选择满条目数量了
|
userCardItemInfoVo.setSurplusNum(0);
|
//不符合
|
userCardItemInfoVo.setNumByNum(false);
|
}else{
|
//没有选择满条目数量
|
userCardItemInfoVo.setSurplusNum(cardItemInfo.getMaxNum());
|
}
|
}
|
}else{
|
//固定或者其他
|
userCardItemInfoVo.setSurplusNum(cardItemInfo.getMaxNum() - cardItemInfoUseMap.computeIfAbsent(cardItemInfo.getId(),k->0));
|
}
|
//使用次数
|
userCardItemInfoVo.setUsedNum(cardItemInfoUseMap.computeIfAbsent(cardItemInfo.getId(),k->0));
|
|
return userCardItemInfoVo;
|
}
|
|
/**卡包- 创建用户卡包使用记录
|
* @param usedNum 当前需要抵扣的次数
|
* @param orderId 订单标识
|
* @param sourceType 来源类型
|
* @param sourceId 来源标识
|
* @param userCard 用户卡包
|
* @param cardItemInfo 卡项条目
|
* @param cardEquity 卡项权益
|
* @param commonService 映射
|
* @return 用户卡包使用记录
|
*/
|
public static UserCardUsed insertUserCardUsed(Integer usedNum,String orderId,Integer sourceType,String sourceId, UserCard userCard
|
, CardItemInfo cardItemInfo, CardEquity cardEquity,CommonService commonService) {
|
UserCardUsed userCardUsed=new UserCardUsed();
|
|
userCardUsed.setEquityType(cardEquity.getEquityType());
|
userCardUsed.setGroupName(cardEquity.getGroupName());
|
userCardUsed.setCommonId(cardItemInfo.getCommonId());
|
userCardUsed.setCommonName(cardItemInfo.getCommonName());
|
userCardUsed.setCommonType(cardItemInfo.getCommonType());
|
userCardUsed.setPrice(cardItemInfo.getPrice());
|
userCardUsed.setUsedGeneral(usedNum);
|
userCardUsed.setUsedNum(usedNum);
|
userCardUsed.setCancelNum(0);
|
userCardUsed.setEmResultsNum(cardItemInfo.getEmResultsNum());
|
userCardUsed.setShareMoney(cardItemInfo.getShareMoney());
|
userCardUsed.setEveryDrawNum(cardItemInfo.getEveryDrawNum());
|
userCardUsed.setEveryShareMoney(cardItemInfo.getEveryShareMoney());
|
userCardUsed.setUserCardCode(userCard.getCode());
|
userCardUsed.setUserCardId(userCard.getId());
|
userCardUsed.setSourceType(sourceType);
|
userCardUsed.setSourceId(sourceId);
|
userCardUsed.setOrderId(orderId);
|
userCardUsed.setCardEquityId(cardEquity.getId());
|
userCardUsed.setCardItemInfoId(cardItemInfo.getId());
|
commonService.insert(UserCardUsedMapper.class,userCardUsed);
|
return userCardUsed;
|
}
|
|
/**计算用户卡包购买时候的金额分摊方式-订单*/
|
public static DistributionRedundVo userCardPay(UserCard userCard,OrderItem orderItem, CommonService commonService, RefundMapper refundMapper){
|
DistributionRedundVo distributionRedundVo = new DistributionRedundVo();
|
//不是订单购买的卡包,跳出循环
|
if(UserCard.SOURCE_TYPE_ORDER_ONE != userCard.getSourceType()){
|
return distributionRedundVo;
|
}
|
|
//通过购买这个卡项的订单来算单卡的钱是多少
|
//查询已经退了多少钱,避免退超了支付方式金额
|
|
if(orderItem == null){
|
orderItem = commonService.selectOneByKey(OrderItemMapper.class,userCard.getSourceId());
|
}
|
if(orderItem == null){
|
throw new TipsException("获取订单子信息失败[895]");
|
}
|
if(orderItem.getBuyNum().compareTo(0) < 1){
|
throw new TipsException("获取订单子信息购买数量错误!");
|
}
|
|
//获取未退款的卡包
|
List<UserCard> userCardList = getNotRefundCard(orderItem.getId(),commonService);
|
|
//获取该子单的支付方式,相同的支付方式求和返回
|
List<PayMethodVo> payMethodVoList = refundMapper.getConsumePayOneGroupByNumberNo(orderItem.getId());
|
//获取该子单已退的总金额
|
RefundRecordItem refundRecordItem = RefundTool.getOneAlreadyRefundTotal(orderItem.getId(),orderItem.getType(),commonService);
|
//计算退款方式金额
|
distributionRedundVo = PaymentCountTool.countMakeWay(orderItem.getId(),orderItem.getActualTotal(),refundRecordItem.getOccupyRefundTotal()
|
,refundRecordItem.getOccupyRefundIntegral(),orderItem.getBuyNum(),userCardList.size(),null,1,payMethodVoList,commonService);
|
distributionRedundVo.setGoodsType(orderItem.getType());
|
distributionRedundVo.setGoodsName(orderItem.getGoodsName());
|
|
return distributionRedundVo;
|
}
|
|
/**获取未退款的卡项数量
|
* @param sourceId 订单子单标识
|
* @return 可退款的用户卡项
|
*/
|
public static List<UserCard> getNotRefundCard(String sourceId,CommonService commonService){
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> sqlMap = new HashMap<>();
|
//获取用户卡项
|
sqlMap.put("sourceId",sourceId);
|
sqlMap.put("effectiveStatus", UserProjectConstants.EFF_STATUS_CANCEL);
|
sqlSentence.sqlSentence("SELECT * FROM user_card WHERE isDel = 0 AND sourceId = #{m.sourceId} AND effectiveStatus != #{m.effectiveStatus} AND turnAddId IS NULL",sqlMap);
|
List<UserCard> userCardList = commonService.selectList(UserCardMapper.class,sqlSentence);
|
if(userCardList.size() == 0){
|
return userCardList;
|
}
|
//获取已经部分退的用户卡包数量
|
List<RefundRecordItem> refundRecordItemList = RefundTool.findRefundUserCard(sourceId,null,commonService);
|
//过滤掉没有使用但有部分退款
|
if(refundRecordItemList.size() == 0){
|
return userCardList;
|
}
|
|
Map<String,UserCard> userCardMap = new HashMap<>();
|
for(UserCard userCard:userCardList){
|
userCardMap.put(userCard.getId(),userCard);
|
}
|
//去除掉参与部分退款的用户卡包
|
for(RefundRecordItem refundRecordItem:refundRecordItemList){
|
userCardMap.remove(refundRecordItem.getUserCardId());
|
}
|
userCardList = new ArrayList<>();
|
for (Map.Entry<String,UserCard> entry : userCardMap.entrySet()) {
|
userCardList.add(entry.getValue());
|
}
|
|
return userCardList;
|
}
|
|
/**计算卡包条目单次抵扣的金额
|
* 保留20位小数
|
* @param cardItemInfo 卡项条目
|
* @return 单次抵扣的金额
|
*/
|
public static BigDecimal countOneMoney(CardItemInfo cardItemInfo){
|
//卡项明细分摊金额
|
BigDecimal sumCardBagMoney = cardItemInfo.getShareMoney()==null?cardItemInfo.getEveryShareMoney():cardItemInfo.getShareMoney();
|
//卡项明细分摊次数
|
Integer num = cardItemInfo.getMaxNum()==null?cardItemInfo.getEveryDrawNum():cardItemInfo.getMaxNum();
|
//求出单次的单价
|
if(num != null && num > 0){
|
return sumCardBagMoney.divide(BigDecimal.valueOf(num),20,RoundingMode.HALF_UP);
|
}else{
|
return BigDecimal.ZERO;
|
}
|
}
|
|
/**获取卡项的权益数量*/
|
public static int getCardEquityCount(String cardId,CommonService commonService){
|
SqlSentence sqlSentence = new SqlSentence();
|
Map<String,Object> values = new HashMap<>();
|
|
values.put("cardItemId",cardId);
|
sqlSentence.sqlSentence("SELECT * FROM card_equity WHERE isDel = 0 AND cardItemId = #{m.cardItemId}" +
|
" AND equityType != 4",values);
|
|
return commonService.selectCountSql(CardEquityMapper.class,sqlSentence);
|
}
|
|
|
}
|