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 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 userCardUsedList = commonService.selectList(UserCardUsedMapper.class, sqlSentence); //已使用的条目标识集合 Set cardItemInfoIds = new HashSet<>(); //每个条目使用总次数Map Map 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 userCardList = getNotRefundCard(orderItem.getId(),commonService); //获取该子单的支付方式,相同的支付方式求和返回 List 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 getNotRefundCard(String sourceId,CommonService commonService){ SqlSentence sqlSentence = new SqlSentence(); Map 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 userCardList = commonService.selectList(UserCardMapper.class,sqlSentence); if(userCardList.size() == 0){ return userCardList; } //获取已经部分退的用户卡包数量 List refundRecordItemList = RefundTool.findRefundUserCard(sourceId,null,commonService); //过滤掉没有使用但有部分退款 if(refundRecordItemList.size() == 0){ return userCardList; } Map 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 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 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); } }