chenjiahe
2023-06-16 949373691bb795099503ec2d9a9d8cffd8d2669c
提交 | 用户 | age
a88f94 1 package com.hx.phip.tool.user;
C 2
3 import com.hx.common.service.CommonService;
78d1e8 4 import com.hx.exception.TipsException;
a88f94 5 import com.hx.mybatisTool.SqlSentence;
a036dc 6 import com.hx.phiappt.common.UserProjectConstants;
a88f94 7 import com.hx.phiappt.model.cardItem.CardEquity;
C 8 import com.hx.phiappt.model.cardItem.CardItemInfo;
78d1e8 9 import com.hx.phiappt.model.consume.ConsumePayItem;
C 10 import com.hx.phiappt.model.order.OrderItem;
11 import com.hx.phiappt.model.order.OrdersTotal;
a036dc 12 import com.hx.phiappt.model.refund.RefundRecordItem;
a88f94 13 import com.hx.phiappt.model.user.UserCard;
C 14 import com.hx.phiappt.model.user.UserCardUsed;
a036dc 15 import com.hx.phip.dao.mapper.*;
78d1e8 16 import com.hx.phip.tool.order.OrderTool;
a036dc 17 import com.hx.phip.tool.refund.PaymentCountTool;
C 18 import com.hx.phip.tool.refund.RefundTool;
19 import com.hx.phip.vo.order.payment.PayMethodVo;
20 import com.hx.phip.vo.order.refund.DistributionRedundVo;
a88f94 21 import com.hx.phip.vo.user.UserCardItemInfoVo;
C 22
78d1e8 23 import java.math.BigDecimal;
C 24 import java.math.RoundingMode;
a88f94 25 import java.util.*;
78d1e8 26 import java.util.stream.Collectors;
a88f94 27
C 28 /**
29  *用户卡包处理工具
30  * @author CJH
31  */
32 public class UserCardTool {
33
34     /**计算使用次数
35      * @param buyNumber 购买数量
36      * @param cardItemInfo 卡项条目
37      * @param cardEquity 卡项权益
38      * @return 计算得出抵扣次数
39      */
40     public static int countUsedNumber(int buyNumber, CardItemInfo cardItemInfo,CardEquity cardEquity){
41         int userdNum ;
42         if(CardEquity.EQUITY_TYPE_TIME_CARD.equals(cardEquity.getEquityType())){
43             //次卡,权益有总次数,所有条目使用的总次数不能大于权益的总次数
44             userdNum = buyNumber*cardItemInfo.getEveryDrawNum();
45         }else if(CardEquity.EQUITY_TYPE_N_M.equals(cardEquity.getEquityType())){
46             //N选M
47             userdNum = buyNumber;
48         }else{
49             //固定或者其他
50             userdNum = buyNumber;
51         }
52         return userdNum;
53     }
54
55
56     /**获取卡包-卡项条目剩余次数
57      * @param userCard 用户卡包
58      * @param cardItemInfo 卡项条目
59      * @param cardEquity 卡项权益
60      * @param commonService 映射
61      * @return 数据结构
62      */
63     public static UserCardItemInfoVo getSurplusNumber(UserCard userCard, CardItemInfo cardItemInfo,CardEquity cardEquity, CommonService commonService){
64
65         SqlSentence sqlSentence = new SqlSentence();
66         Map<String,Object> values = new HashMap<>();
67
68         //获取使用记录,注意:是根据权益,不是卡项条目查询
69         values.put("cardEquityId",cardEquity.getId());
70         values.put("userCardId",userCard.getId());
32cb2e 71         values.put("isDel",UserCardUsed.NO);
a88f94 72         sqlSentence.sqlSentence("SELECT * FROM user_card_used WHERE cardEquityId = #{m.cardEquityId} AND userCardId = #{m.userCardId} AND isDel = #{m.isDel}",values);
C 73         //根据cardItemIfo标识查询用户使用记录
74         List<UserCardUsed> userCardUsedList = commonService.selectList(UserCardUsedMapper.class, sqlSentence);
75
76         //已使用的条目标识集合
77         Set<String> cardItemInfoIds = new HashSet<>();
78         //每个条目使用总次数Map
79         Map<String,Integer> cardItemInfoUseMap = new HashMap<>();
80         //计算所有条目已使用总次数
81         Integer usedGeneral = 0;
82
83         Integer num;
84         for(UserCardUsed userCardUsed:userCardUsedList){
85             //计算所有条目已使用总次数
86             usedGeneral = usedGeneral+userCardUsed.getUsedNum();
87             //已使用的条目标识集合
88             cardItemInfoIds.add(userCardUsed.getCardItemInfoId());
89             //每个条目使用总参数Map
90             num = cardItemInfoUseMap.computeIfAbsent(userCardUsed.getCardItemInfoId(),k->0);
91             num = num + userCardUsed.getUsedNum();
92             cardItemInfoUseMap.put(userCardUsed.getCardItemInfoId(),num);
93         }
94
95         //返回结构
96         UserCardItemInfoVo userCardItemInfoVo = new UserCardItemInfoVo();
97
98         if(CardEquity.EQUITY_TYPE_TIME_CARD.equals(cardEquity.getEquityType())){
99             //次卡,权益有总次数,所有条目使用的总次数不能大于权益的总次数
100             if(usedGeneral < cardEquity.getValue()){
101                 //是否设置了最大的抵扣次数
36e260 102                 int surplusNum = cardEquity.getValue() - usedGeneral;
a88f94 103                 if(cardItemInfo.getMaxNum() != null && cardItemInfo.getMaxNum() != 0){
C 104                     userCardItemInfoVo.setSurplusNum(cardItemInfo.getMaxNum() - cardItemInfoUseMap.computeIfAbsent(cardItemInfo.getId(),k->0));
36e260 105                     if(userCardItemInfoVo.getSurplusNum() > surplusNum){
C 106                         userCardItemInfoVo.setSurplusNum(surplusNum);
107                     }
a88f94 108                 }else{
36e260 109                     userCardItemInfoVo.setSurplusNum(surplusNum);
a88f94 110                 }
C 111             }else{
112                 userCardItemInfoVo.setSurplusNum(0);
113             }
114         }else if(CardEquity.EQUITY_TYPE_N_M.equals(cardEquity.getEquityType())){
115             //N选M,每个条目都有自己的可抵扣总次数
116             if(cardItemInfoIds.contains(cardItemInfo.getId())){
117                 //已经使用条目集合包含当前条目
118                 userCardItemInfoVo.setSurplusNum(cardItemInfo.getMaxNum() - cardItemInfoUseMap.get(cardItemInfo.getId()));
119             }else{
120                 //已经使用条目集合没有包含当前条目
121                 if(cardItemInfoIds.size() >= cardEquity.getValue()){
122                     //已经选择满条目数量了
123                     userCardItemInfoVo.setSurplusNum(0);
124                     //不符合
125                     userCardItemInfoVo.setNumByNum(false);
126                 }else{
127                     //没有选择满条目数量
128                     userCardItemInfoVo.setSurplusNum(cardItemInfo.getMaxNum());
129                 }
130             }
131         }else{
132             //固定或者其他
133             userCardItemInfoVo.setSurplusNum(cardItemInfo.getMaxNum() - cardItemInfoUseMap.computeIfAbsent(cardItemInfo.getId(),k->0));
134         }
135         //使用次数
136         userCardItemInfoVo.setUsedNum(cardItemInfoUseMap.computeIfAbsent(cardItemInfo.getId(),k->0));
137
138         return userCardItemInfoVo;
139     }
140
141     /**卡包- 创建用户卡包使用记录
142      * @param usedNum 当前需要抵扣的次数
143      * @param orderId 订单标识
144      * @param sourceType 来源类型
145      * @param sourceId 来源标识
146      * @param userCard 用户卡包
147      * @param cardItemInfo 卡项条目
148      * @param cardEquity 卡项权益
149      * @param commonService 映射
150      * @return 用户卡包使用记录
151      */
152     public static UserCardUsed insertUserCardUsed(Integer usedNum,String orderId,Integer sourceType,String sourceId, UserCard userCard
153             , CardItemInfo cardItemInfo, CardEquity cardEquity,CommonService commonService) {
154         UserCardUsed userCardUsed=new UserCardUsed();
155
156         userCardUsed.setEquityType(cardEquity.getEquityType());
157         userCardUsed.setGroupName(cardEquity.getGroupName());
158         userCardUsed.setCommonId(cardItemInfo.getCommonId());
159         userCardUsed.setCommonName(cardItemInfo.getCommonName());
160         userCardUsed.setCommonType(cardItemInfo.getCommonType());
161         userCardUsed.setPrice(cardItemInfo.getPrice());
162         userCardUsed.setUsedGeneral(usedNum);
163         userCardUsed.setUsedNum(usedNum);
164         userCardUsed.setCancelNum(0);
165         userCardUsed.setEmResultsNum(cardItemInfo.getEmResultsNum());
166         userCardUsed.setShareMoney(cardItemInfo.getShareMoney());
167         userCardUsed.setEveryDrawNum(cardItemInfo.getEveryDrawNum());
168         userCardUsed.setEveryShareMoney(cardItemInfo.getEveryShareMoney());
169         userCardUsed.setUserCardCode(userCard.getCode());
170         userCardUsed.setUserCardId(userCard.getId());
171         userCardUsed.setSourceType(sourceType);
172         userCardUsed.setSourceId(sourceId);
173         userCardUsed.setOrderId(orderId);
174         userCardUsed.setCardEquityId(cardEquity.getId());
175         userCardUsed.setCardItemInfoId(cardItemInfo.getId());
176         commonService.insert(UserCardUsedMapper.class,userCardUsed);
177         return userCardUsed;
178     }
179
78d1e8 180     /**计算用户卡包购买时候的金额分摊方式-订单*/
a036dc 181     public static DistributionRedundVo userCardPay(UserCard userCard,OrderItem orderItem, CommonService commonService, RefundMapper refundMapper){
C 182         DistributionRedundVo distributionRedundVo = new DistributionRedundVo();
78d1e8 183         //不是订单购买的卡包,跳出循环
C 184         if(UserCard.SOURCE_TYPE_ORDER_ONE != userCard.getSourceType()){
a036dc 185             return distributionRedundVo;
78d1e8 186         }
C 187
188         //通过购买这个卡项的订单来算单卡的钱是多少
189         //查询已经退了多少钱,避免退超了支付方式金额
190
a036dc 191         if(orderItem == null){
C 192             orderItem = commonService.selectOneByKey(OrderItemMapper.class,userCard.getSourceId());
193         }
78d1e8 194         if(orderItem == null){
C 195             throw new TipsException("获取订单子信息失败[895]");
196         }
197         if(orderItem.getBuyNum().compareTo(0) < 1){
198             throw new TipsException("获取订单子信息购买数量错误!");
199         }
200
a036dc 201         //获取未退款的卡包
C 202         List<UserCard> userCardList = getNotRefundCard(orderItem.getId(),commonService);
78d1e8 203
a036dc 204         //获取该子单的支付方式,相同的支付方式求和返回
C 205         List<PayMethodVo> payMethodVoList = refundMapper.getConsumePayOneGroupByNumberNo(orderItem.getId());
206         //获取该子单已退的总金额
207         RefundRecordItem refundRecordItem = RefundTool.getOneAlreadyRefundTotal(orderItem.getId(),orderItem.getType(),commonService);
208         //计算退款方式金额
209         distributionRedundVo = PaymentCountTool.countMakeWay(orderItem.getId(),orderItem.getActualTotal(),refundRecordItem.getOccupyRefundTotal()
210                 ,refundRecordItem.getOccupyRefundIntegral(),orderItem.getBuyNum(),userCardList.size(),null,1,payMethodVoList,commonService);
949373 211         distributionRedundVo.setGoodsType(orderItem.getType());
C 212         distributionRedundVo.setGoodsName(orderItem.getGoodsName());
78d1e8 213
a036dc 214         return distributionRedundVo;
78d1e8 215     }
C 216
a036dc 217     /**获取未退款的卡项数量
C 218      * @param sourceId 订单子单标识
219      * @return 可退款的用户卡项
220      */
221     public static List<UserCard> getNotRefundCard(String sourceId,CommonService commonService){
222         SqlSentence sqlSentence = new SqlSentence();
223         Map<String,Object> sqlMap = new HashMap<>();
224         //获取用户卡项
225         sqlMap.put("sourceId",sourceId);
226         sqlMap.put("effectiveStatus", UserProjectConstants.EFF_STATUS_CANCEL);
949373 227         sqlSentence.sqlSentence("SELECT * FROM user_card WHERE isDel = 0 AND sourceId = #{m.sourceId} AND effectiveStatus != #{m.effectiveStatus} AND turnAddId IS NULL",sqlMap);
C 228         List<UserCard> userCardList = commonService.selectList(UserCardMapper.class,sqlSentence);
229         if(userCardList.size() == 0){
230             return userCardList;
231         }
232         //获取已经部分退的用户卡包数量
233         List<RefundRecordItem> refundRecordItemList = RefundTool.findRefundUserCard(sourceId,null,commonService);
234         //过滤掉没有使用但有部分退款
235         if(refundRecordItemList.size() == 0){
236             return userCardList;
237         }
238
239         Map<String,UserCard> userCardMap = new HashMap<>();
240         for(UserCard userCard:userCardList){
241             userCardMap.put(userCard.getId(),userCard);
242         }
243         //去除掉参与部分退款的用户卡包
244         for(RefundRecordItem refundRecordItem:refundRecordItemList){
245             userCardMap.remove(refundRecordItem.getUserCardId());
246         }
247         userCardList = new ArrayList<>();
248         for (Map.Entry<String,UserCard> entry : userCardMap.entrySet()) {
249             userCardList.add(entry.getValue());
250         }
251
252         return userCardList;
a036dc 253     }
C 254
255     /**计算卡包条目单次抵扣的金额
256      * 保留20位小数
257      * @param cardItemInfo 卡项条目
258      * @return 单次抵扣的金额
259      */
260     public static BigDecimal countOneMoney(CardItemInfo cardItemInfo){
261         //卡项明细分摊金额
262         BigDecimal sumCardBagMoney = cardItemInfo.getShareMoney()==null?cardItemInfo.getEveryShareMoney():cardItemInfo.getShareMoney();
263         //卡项明细分摊次数
264         Integer num = cardItemInfo.getMaxNum()==null?cardItemInfo.getEveryDrawNum():cardItemInfo.getMaxNum();
265         //求出单次的单价
266         if(num != null && num > 0){
267             return sumCardBagMoney.divide(BigDecimal.valueOf(num),20,RoundingMode.HALF_UP);
268         }else{
269             return BigDecimal.ZERO;
270         }
271     }
272
949373 273     /**获取卡项的权益数量*/
C 274     public static int getCardEquityCount(String cardId,CommonService commonService){
275         SqlSentence sqlSentence = new SqlSentence();
276         Map<String,Object> values = new HashMap<>();
277
278         values.put("cardItemId",cardId);
279         sqlSentence.sqlSentence("SELECT * FROM card_equity WHERE isDel = 0 AND cardItemId = #{m.cardItemId}" +
280                 " AND equityType != 4",values);
281
282         return commonService.selectCountSql(CardEquityMapper.class,sqlSentence);
283     }
284
a036dc 285
a88f94 286 }