chenjiahe
2023-06-16 949373691bb795099503ec2d9a9d8cffd8d2669c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
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);
    }
 
 
}