Subversion Repositories SmartDukaan

Rev

Rev 32542 | Rev 32795 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
27877 amit.gupta 1
package com.spice.profitmandi.service.offers;
2
 
29783 amit.gupta 3
import com.google.common.collect.Lists;
27877 amit.gupta 4
import com.google.gson.Gson;
5
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
29683 amit.gupta 6
import com.spice.profitmandi.common.model.PartnerTargetModel;
7
import com.spice.profitmandi.common.model.ProfitMandiConstants;
31920 amit.gupta 8
import com.spice.profitmandi.common.util.Utils;
27877 amit.gupta 9
import com.spice.profitmandi.dao.entity.catalog.ItemCriteria;
10
import com.spice.profitmandi.dao.entity.catalog.Offer;
29783 amit.gupta 11
import com.spice.profitmandi.dao.entity.catalog.TagListing;
31903 amit.gupta 12
import com.spice.profitmandi.dao.entity.catalog.TargetSlabEntity;
31920 amit.gupta 13
import com.spice.profitmandi.dao.entity.fofo.FofoLineItem;
14
import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;
31205 amit.gupta 15
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
16
import com.spice.profitmandi.dao.entity.fofo.OfferPayout;
31920 amit.gupta 17
import com.spice.profitmandi.dao.entity.transaction.LineItem;
18
import com.spice.profitmandi.dao.entity.transaction.Order;
31747 amit.gupta 19
import com.spice.profitmandi.dao.entity.transaction.UserWalletHistory;
31920 amit.gupta 20
import com.spice.profitmandi.dao.entity.warehouse.WarehouseInventoryItem;
21
import com.spice.profitmandi.dao.entity.warehouse.WarehouseScan;
22
import com.spice.profitmandi.dao.enumuration.catalog.AchievementType;
29783 amit.gupta 23
import com.spice.profitmandi.dao.enumuration.catalog.AmountType;
29499 amit.gupta 24
import com.spice.profitmandi.dao.enumuration.catalog.OfferSchemeType;
31205 amit.gupta 25
import com.spice.profitmandi.dao.enumuration.transaction.SchemePayoutStatus;
31903 amit.gupta 26
import com.spice.profitmandi.dao.model.AmountModel;
27877 amit.gupta 27
import com.spice.profitmandi.dao.model.CreateOfferRequest;
28
import com.spice.profitmandi.dao.model.ItemCriteriaPayout;
31920 amit.gupta 29
import com.spice.profitmandi.dao.model.OfferRowModel;
30066 amit.gupta 30
import com.spice.profitmandi.dao.repository.catalog.*;
31920 amit.gupta 31
import com.spice.profitmandi.dao.repository.fofo.ActivatedImeiRepository;
32
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
31205 amit.gupta 33
import com.spice.profitmandi.dao.repository.fofo.OfferPayoutRepository;
31920 amit.gupta 34
import com.spice.profitmandi.dao.repository.transaction.LineItemImeisRepository;
35
import com.spice.profitmandi.dao.repository.warehouse.WarehouseInventoryItemRepository;
36
import com.spice.profitmandi.dao.repository.warehouse.WarehouseScanRepository;
37
import com.spice.profitmandi.service.pricecircular.PriceCircularService;
38
import com.spice.profitmandi.service.scheme.InventoryPayoutModel;
27877 amit.gupta 39
import com.spice.profitmandi.service.user.RetailerService;
31205 amit.gupta 40
import com.spice.profitmandi.service.wallet.WalletService;
41
import in.shop2020.model.v1.order.WalletReferenceType;
30066 amit.gupta 42
import org.apache.logging.log4j.LogManager;
43
import org.apache.logging.log4j.Logger;
44
import org.apache.poi.ss.usermodel.Cell;
45
import org.apache.poi.ss.usermodel.CellType;
46
import org.apache.poi.ss.usermodel.Row;
47
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
48
import org.apache.poi.xssf.usermodel.XSSFRow;
49
import org.apache.poi.xssf.usermodel.XSSFSheet;
50
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
51
import org.springframework.beans.factory.annotation.Autowired;
52
import org.springframework.cache.CacheManager;
53
import org.springframework.cache.annotation.Cacheable;
54
import org.springframework.stereotype.Component;
27877 amit.gupta 55
 
30066 amit.gupta 56
import java.io.IOException;
57
import java.io.InputStream;
58
import java.time.LocalDate;
31205 amit.gupta 59
import java.time.LocalDateTime;
30066 amit.gupta 60
import java.time.YearMonth;
61
import java.util.*;
62
import java.util.stream.Collectors;
63
 
27877 amit.gupta 64
@Component
65
public class OfferServiceImpl implements OfferService {
66
 
31747 amit.gupta 67
    private static final List<String> targets = Arrays.asList("Target 1", "Target 2", "Target 3", "Target 4",
68
            "Target 5");
29499 amit.gupta 69
 
31747 amit.gupta 70
    @Autowired
71
    private Gson gson;
27877 amit.gupta 72
 
31747 amit.gupta 73
    @Autowired
74
    private OfferRepository offerRepository;
27877 amit.gupta 75
 
31747 amit.gupta 76
    @Autowired
77
    private RetailerService retailerService;
31920 amit.gupta 78
    @Autowired
79
    PriceCircularService priceCircularService;
27877 amit.gupta 80
 
31747 amit.gupta 81
    @Autowired
82
    OfferPayoutRepository offerPayoutRepository;
31205 amit.gupta 83
 
31747 amit.gupta 84
    @Autowired
85
    private ItemCriteriaRepository itemCriteriaRepository;
27877 amit.gupta 86
 
31747 amit.gupta 87
    @Autowired
88
    private ItemRepository itemRepository;
27877 amit.gupta 89
 
31747 amit.gupta 90
    @Autowired
91
    private TagListingRepository tagListingRepository;
29783 amit.gupta 92
 
31747 amit.gupta 93
    @Autowired
94
    private OfferTargetSlabRepository offerTargetSlabRepository;
30684 amit.gupta 95
 
31747 amit.gupta 96
    @Autowired
97
    CacheManager thirtyMinsTimeOutCacheManager;
27877 amit.gupta 98
 
29806 amit.gupta 99
 
31747 amit.gupta 100
    private static final Logger LOGGER = LogManager.getLogger(OfferServiceImpl.class);
27877 amit.gupta 101
 
31920 amit.gupta 102
    @Autowired
103
    private ActivatedImeiRepository activatedImeiRepository;
104
    @Autowired
105
    private WarehouseScanRepository warehouseScanRepository;
106
 
107
    @Autowired
108
    private WarehouseInventoryItemRepository warehouseInventoryItemRepository;
109
 
110
    @Autowired
111
    private LineItemImeisRepository lineItemImeisRepository;
112
    @Autowired
113
    private InventoryItemRepository inventoryItemRepository;
114
 
31747 amit.gupta 115
    @Override
116
    public void addOfferService(CreateOfferRequest createOfferRequest) throws ProfitMandiBusinessException {
117
        LOGGER.info("createOfferRequest  -- {}", createOfferRequest);
118
        this.createOffer(createOfferRequest);
119
        this.createTargetSlabs(createOfferRequest);
120
    }
27877 amit.gupta 121
 
31747 amit.gupta 122
    private void createOffer(CreateOfferRequest createOfferRequest) {
123
        Offer offer = new Offer();
124
        offer.setName(createOfferRequest.getName());
125
        offer.setTargetType(createOfferRequest.getTargetType());
126
        offer.setBooster(createOfferRequest.isBooster());
127
        offer.setPayoutType(createOfferRequest.getPayoutType());
128
        offer.setSchemeType(createOfferRequest.getSchemeType());
129
        offer.setBaseCriteia(createOfferRequest.isBaseCriteria());
130
        offer.setEndDate(createOfferRequest.getEndDate());
131
        offer.setStartDate(createOfferRequest.getStartDate());
132
        offer.setBrandSharePercentage(createOfferRequest.getBrandShareTerms());
133
        offer.setSellinPercentage(createOfferRequest.getSellinPercentage());
134
        offer.setOfferNotes(createOfferRequest.getOfferNotes());
135
        offer.setActivationBrands(createOfferRequest.getActivationBrands());
136
        offer.setTerms(createOfferRequest.getTerms());
137
        offer.setItemCriteria(gson.toJson(createOfferRequest.getItemCriteria()));
138
        offer.setPartnerCriteria(gson.toJson(createOfferRequest.getPartnerCriteria()));
32070 amit.gupta 139
        offer.setDiscount(createOfferRequest.isDiscount());
31747 amit.gupta 140
        offerRepository.persist(offer);
141
        createOfferRequest.setId(offer.getId());
142
    }
27877 amit.gupta 143
 
31747 amit.gupta 144
    @Override
145
    public List<CreateOfferRequest> getPublishedOffers(int fofoId, YearMonth yearMonth) {
146
        List<Offer> publishedOffers = offerRepository.selectAllPublishedMapByPartner(yearMonth).get(fofoId);
147
        List<CreateOfferRequest> createOfferRequests = new ArrayList<>();
148
        if (publishedOffers != null) {
149
            for (Offer offer : publishedOffers) {
150
                CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
151
                createOfferRequests.add(createOfferRequest);
152
                setCriteriaPayoutAchieved(fofoId, createOfferRequest);
27877 amit.gupta 153
 
31747 amit.gupta 154
            }
155
        }
156
        return createOfferRequests;
157
    }
27877 amit.gupta 158
 
31747 amit.gupta 159
    private void setCriteriaPayoutAchieved(int fofoId, CreateOfferRequest createOfferRequest) {
160
        Map<Integer, Long> criteriaTransactionMap = null;
161
        if (createOfferRequest.getSchemeType().equals(OfferSchemeType.SELLIN)) {
162
            criteriaTransactionMap = offerRepository.getPartnerWisePurchaseSum(createOfferRequest).get(fofoId);
163
        } else {
164
            criteriaTransactionMap = offerRepository.getPartnerWiseSalesSum(createOfferRequest).get(fofoId);
165
        }
166
        LOGGER.info("I am here ------- {}", createOfferRequest.getId());
167
        List<com.spice.profitmandi.dao.model.ItemCriteriaPayout> itemCriteriaPayouts = createOfferRequest
168
                .getTargetSlabs().get(0).getItemCriteriaPayouts();
27877 amit.gupta 169
 
31747 amit.gupta 170
        for (com.spice.profitmandi.dao.model.ItemCriteriaPayout itemCriteriaPayout : itemCriteriaPayouts) {
171
            itemCriteriaPayout.setNextSlab(null);
172
            LOGGER.info("I am here --- {}", itemCriteriaPayout.getPayoutSlabs());
173
            long saleAmount = 0;
174
            if (criteriaTransactionMap != null
175
                    && criteriaTransactionMap.containsKey(itemCriteriaPayout.getItemCriteria().getId())) {
31853 amit.gupta 176
                saleAmount = criteriaTransactionMap.containsKey(0) ? criteriaTransactionMap.get(0) : criteriaTransactionMap.get(itemCriteriaPayout.getItemCriteria().getId());
31747 amit.gupta 177
            }
178
            itemCriteriaPayout.setAchievedValue(saleAmount);
179
            List<com.spice.profitmandi.service.offers.PayoutSlab> payoutSlabs = itemCriteriaPayout.getPayoutSlabs();
180
            for (int i = 0; i < payoutSlabs.size(); i++) {
181
                com.spice.profitmandi.service.offers.PayoutSlab beginSlab = payoutSlabs.get(i);
182
                com.spice.profitmandi.service.offers.PayoutSlab endSlab = null;
183
                if (payoutSlabs.size() - 1 > i) {
184
                    endSlab = payoutSlabs.get(i + 1);
185
                }
186
                if (beginSlab.getOnwardsAmount() > saleAmount) {
187
                    itemCriteriaPayout.setShortValue(beginSlab.getOnwardsAmount() - saleAmount);
188
                    itemCriteriaPayout.setNextSlab(beginSlab);
189
                    LOGGER.info("I am here");
190
                    break;
191
                }
192
                if (endSlab != null) {
193
                    if (beginSlab.getOnwardsAmount() <= saleAmount && endSlab.getOnwardsAmount() > saleAmount) {
194
                        itemCriteriaPayout.setCurrentSlab(beginSlab);
195
                        beginSlab.setSelected(true);
196
                        itemCriteriaPayout.setNextSlab(endSlab);
197
                        itemCriteriaPayout.setShortValue(endSlab.getOnwardsAmount() - saleAmount);
198
                        LOGGER.info("I am here");
199
                        break;
200
                    }
201
                    // Last loop
202
                } else {
203
                    beginSlab.setSelected(true);
204
                    itemCriteriaPayout.setCurrentSlab(beginSlab);
205
                    LOGGER.info("I am here");
206
                }
207
            }
208
            LOGGER.info("I am here --- {}", itemCriteriaPayout);
209
        }
29783 amit.gupta 210
 
31747 amit.gupta 211
    }
27877 amit.gupta 212
 
31747 amit.gupta 213
    @Override
214
    @Cacheable(value = "allOffers", cacheManager = "thirtyMinsTimeOutCacheManager")
215
    public Map<Integer, CreateOfferRequest> getAllOffers(YearMonth yearMonth) {
216
        List<Offer> allOffers = offerRepository.selectAll(yearMonth, false);
217
        List<CreateOfferRequest> createOfferRequests = new ArrayList<>();
218
        for (Offer offer : allOffers) {
219
            CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
220
            createOfferRequests.add(createOfferRequest);
221
        }
222
        return createOfferRequests.stream().collect(Collectors.toMap(CreateOfferRequest::getId, x -> x));
223
    }
27877 amit.gupta 224
 
31747 amit.gupta 225
    @Override
226
    @Cacheable(value = "partnerOffers", cacheManager = "thirtyMinsTimeOutCacheManager")
227
    public CreateOfferRequest getOffer(int fofoId, int offerId) {
228
        Offer offer = offerRepository.selectById(offerId);
229
        CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
230
        if (fofoId > 0) {
231
            this.setCriteriaPayoutAchieved(fofoId, createOfferRequest);
232
        }
29783 amit.gupta 233
 
31747 amit.gupta 234
        return createOfferRequest;
235
    }
27877 amit.gupta 236
 
31747 amit.gupta 237
    @Override
238
    public CreateOfferRequest getCreateOfferRequest(Offer fromOffer) {
239
        CreateOfferRequest createOfferRequest = new CreateOfferRequest();
240
        createOfferRequest.setName(fromOffer.getName());
32023 amit.gupta 241
        createOfferRequest.setDiscount(fromOffer.isDiscount());
31747 amit.gupta 242
        createOfferRequest.setTargetType(fromOffer.getTargetType());
243
        createOfferRequest.setPayoutType(fromOffer.getPayoutType());
244
        createOfferRequest.setSchemeType(fromOffer.getSchemeType());
245
        createOfferRequest.setActivationBrands(fromOffer.getActivationBrands());
246
        createOfferRequest.setEndDate(fromOffer.getEndDate());
247
        createOfferRequest.setProcessTimestamp(fromOffer.getProcessedTimestamp());
248
        createOfferRequest.setStartDate(fromOffer.getStartDate());
249
        createOfferRequest.setBooster(fromOffer.isBooster());
250
        createOfferRequest.setActive(fromOffer.isActive());
251
        createOfferRequest.setSellinPercentage(fromOffer.getSellinPercentage());
252
        createOfferRequest.setBrandShareTerms(fromOffer.getBrandSharePercentage());
253
        createOfferRequest.setOfferNotes(fromOffer.getOfferNotes());
254
        createOfferRequest.setTerms(fromOffer.getTerms());
255
        createOfferRequest.setBaseCriteria(fromOffer.isBaseCriteia());
256
        createOfferRequest.setItemCriteria(
257
                gson.fromJson(fromOffer.getItemCriteria(), com.spice.profitmandi.service.offers.ItemCriteria.class));
258
        createOfferRequest.setPartnerCriteria(gson.fromJson(fromOffer.getPartnerCriteria(), PartnerCriteria.class));
259
        createOfferRequest.setId(fromOffer.getId());
260
        createOfferRequest.setCreatedOn(fromOffer.getCreatedTimestamp());
261
        createOfferRequest.setItemCriteriaString(
262
                itemCriteriaRepository.getItemCriteriaDescription(createOfferRequest.getItemCriteria()));
263
        List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = offerTargetSlabRepository
264
                .getByOfferId(fromOffer.getId());
265
        createOfferRequest.setPartnerCriteriaString(
266
                retailerService.getPartnerCriteriaString(createOfferRequest.getPartnerCriteria()));
267
        createOfferRequest.setTargetSlabs(targetSlabs);
268
        for (com.spice.profitmandi.dao.model.ItemCriteriaPayout itemCriteriaPayout : createOfferRequest.getTargetSlabs()
269
                .get(0).getItemCriteriaPayouts()) {
270
            itemCriteriaPayout.setNextSlab(itemCriteriaPayout.getPayoutSlabs().get(0));
271
        }
272
        return createOfferRequest;
27877 amit.gupta 273
 
31747 amit.gupta 274
    }
27877 amit.gupta 275
 
31747 amit.gupta 276
    @Autowired
277
    private WalletService walletService;
31205 amit.gupta 278
 
31747 amit.gupta 279
    @Override
280
    public void reverseAdditionalSelloutSchemes(int fofoId, List<InventoryItem> inventoryItems) throws ProfitMandiBusinessException {
281
        List<OfferPayout> offerPayouts = new ArrayList<>();
31748 amit.gupta 282
        LOGGER.info("Reversing schemes for fofoId {}, InventoryItems {}", fofoId, inventoryItems);
31747 amit.gupta 283
        //As of now we are not handling non-serialised items
284
        inventoryItems = inventoryItems.stream().filter(x -> x.getSerialNumber() != null).collect(Collectors.toList());
31750 amit.gupta 285
        if (inventoryItems.size() > 0) {
31205 amit.gupta 286
 
31750 amit.gupta 287
            for (InventoryItem inventoryItem : inventoryItems) {
288
                offerPayouts.addAll(offerPayoutRepository.selectAllBySerialNumber(inventoryItem.getFofoId(), inventoryItem.getSerialNumber())
289
                        .stream()
290
                        .filter(x -> x.getRejectTimestamp() == null)
291
                        .collect(Collectors.toList()));
31747 amit.gupta 292
            }
31750 amit.gupta 293
            for (OfferPayout offerPayout : offerPayouts) {
294
                offerPayout.setStatus(SchemePayoutStatus.REJECTED);
295
                offerPayout.setRejectTimestamp(LocalDateTime.now());
296
            }
297
            Map<Long, Double> offerPayoutAmountMap = offerPayouts.stream().collect(Collectors.groupingBy(x -> x.getOfferId(), Collectors.summingDouble(x -> x.getAmount())));
298
            for (Map.Entry<Long, Double> offerPayoutEntry : offerPayoutAmountMap.entrySet()) {
299
                List<UserWalletHistory> histories = walletService.getAllByReference(fofoId, offerPayoutEntry.getKey().intValue(), WalletReferenceType.ADDITIONAL_SCHEME);
300
                if (histories.size() > 0) {
301
 
302
                    walletService.rollbackAmountFromWallet(fofoId, offerPayoutEntry.getValue().floatValue(), offerPayoutEntry.getKey().intValue(),
303
                            WalletReferenceType.ADDITIONAL_SCHEME, "Models/Imeis for corresponding schemes were returned", LocalDateTime.now());
304
                }
305
            }
31747 amit.gupta 306
        }
307
    }
30684 amit.gupta 308
 
31747 amit.gupta 309
    private void createTargetSlabs(CreateOfferRequest createOfferRequest) throws ProfitMandiBusinessException {
310
        List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = createOfferRequest.getTargetSlabs().stream()
311
                .filter(x -> x.validate()).collect(Collectors.toList());
312
        if (targetSlabs.size() >= 0) {
313
            Collections.sort(targetSlabs);
314
            for (com.spice.profitmandi.dao.model.TargetSlab targetSlab : targetSlabs) {
315
                if (targetSlab.validate()) {
316
                    List<ItemCriteriaPayout> itemCriteriaPayouts = targetSlab.getItemCriteriaPayouts();
317
                    for (ItemCriteriaPayout itemCriteriaPayout : itemCriteriaPayouts) {
318
                        ItemCriteria itemCriteria = itemCriteriaRepository.selectById(itemCriteriaPayout.getItemCriteria().getId());
319
                        if (itemCriteriaPayout.getItemCriteria().getId() > 0) {
320
                            itemCriteriaPayout.getItemCriteria().setId(0);
321
                        } else {
27877 amit.gupta 322
 
31747 amit.gupta 323
                            String itemCriteriaJson = gson.toJson(itemCriteriaPayout.getItemCriteria());
324
                            itemCriteria = itemCriteriaRepository.selectByCriteria(itemCriteriaJson);
325
                            // ItemCriteria Only once
326
                            if (itemCriteria == null) {
327
                                itemCriteria = new ItemCriteria();
328
                                itemCriteria.setCriteria(gson.toJson(itemCriteriaPayout.getItemCriteria()));
329
                                itemCriteriaRepository.persist(itemCriteria);
330
                            }
331
                        }
332
                        for (PayoutSlab payoutSlab : itemCriteriaPayout.getPayoutSlabs()) {
31903 amit.gupta 333
                            TargetSlabEntity targetSlabEntity = new TargetSlabEntity();
334
                            targetSlabEntity.setOfferId(createOfferRequest.getId());
335
                            targetSlabEntity.setOnwardsTarget(targetSlab.getOnwardsAmount());
336
                            targetSlabEntity.setTargetDescription(targetSlab.getTargetDescription());
337
                            targetSlabEntity.setPayoutTarget(payoutSlab.getOnwardsAmount());
338
                            targetSlabEntity.setPayoutValue(payoutSlab.getPayoutAmount());
339
                            targetSlabEntity.setItemCriteriaId(itemCriteria.getId());
340
                            targetSlabEntity.setAmountType(itemCriteriaPayout.getAmountType());
341
                            offerTargetSlabRepository.persist(targetSlabEntity);
31747 amit.gupta 342
                        }
343
                    }
344
                }
345
            }
27877 amit.gupta 346
 
31747 amit.gupta 347
        } else {
348
            throw new ProfitMandiBusinessException("Invalid Target Slabs", "Invalid Target", "");
349
        }
27877 amit.gupta 350
 
31747 amit.gupta 351
    }
27877 amit.gupta 352
 
31747 amit.gupta 353
    @Override
354
    public List<CreateOfferRequest> getPublishedOffers(LocalDate date, int fofoId, int catalogId) {
355
        List<Offer> publishedOffers = offerRepository.selectAllPublishedMapByPartner(YearMonth.from(date)).get(fofoId);
356
        List<CreateOfferRequest> createOfferRequests = new ArrayList<>();
357
        if (publishedOffers != null) {
358
            for (Offer offer : publishedOffers) {
359
                boolean found = false;
360
                List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = offerTargetSlabRepository
361
                        .getByOfferId(offer.getId());
362
                CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
363
                createOfferRequest.setTargetSlabs(targetSlabs);
364
                this.setCriteriaPayoutAchieved(fofoId, createOfferRequest);
365
                Set<com.spice.profitmandi.service.offers.ItemCriteria> itemCriteriaSet = targetSlabs.stream()
366
                        .flatMap(x -> x.getItemCriteriaPayouts().stream()).map(x -> x.getItemCriteria()).distinct()
367
                        .filter(x -> itemRepository.containsModel(x, catalogId)).collect(Collectors.toSet());
29499 amit.gupta 368
 
31747 amit.gupta 369
                for (com.spice.profitmandi.dao.model.TargetSlab targetSlab : targetSlabs) {
370
                    targetSlab.setItemCriteriaPayouts(targetSlab.getItemCriteriaPayouts().stream()
371
                            .filter(x -> itemCriteriaSet.contains(x.getItemCriteria())).collect(Collectors.toList()));
372
                    if (targetSlab.getItemCriteriaPayouts().size() > 0) {
373
                        found = true;
374
                    }
375
                }
376
                if (found) {
377
                    createOfferRequests.add(createOfferRequest);
378
                }
379
            }
380
        }
29783 amit.gupta 381
 
31747 amit.gupta 382
        return createOfferRequests;
383
    }
29783 amit.gupta 384
 
31747 amit.gupta 385
    @Override
386
    public void createOffers(InputStream fileInputStream) throws Exception {
387
        Map<CreateOfferRequest, List<PartnerTargetModel>> offerPartnerTargetMap = this.parseFromExcel(fileInputStream);
388
        for (Map.Entry<CreateOfferRequest, List<PartnerTargetModel>> partnerTargetEntry : offerPartnerTargetMap
389
                .entrySet()) {
390
            CreateOfferRequest createOfferRequest = partnerTargetEntry.getKey();
391
            Map<List<Integer>, List<Integer>> targetPartnerMap = partnerTargetEntry.getValue().stream()
392
                    .collect(Collectors.groupingBy(PartnerTargetModel::getTargets,
393
                            Collectors.mapping(PartnerTargetModel::getFofoId, Collectors.toList())));
394
            for (Map.Entry<List<Integer>, List<Integer>> targetPartnersEntry : targetPartnerMap.entrySet()) {
395
                List<Integer> fofoIds = createOfferRequest.getPartnerCriteria().getFofoIds();
396
                List<Integer> filterFofoIds = targetPartnersEntry.getValue().stream().filter(x -> !fofoIds.contains(x))
397
                        .collect(Collectors.toList());
398
                LOGGER.info("FofoIds {}", filterFofoIds);
399
                List<Integer> targets = targetPartnersEntry.getKey();
400
                LOGGER.info("Targets  {}", targets);
29806 amit.gupta 401
 
31747 amit.gupta 402
                createOfferRequest.getPartnerCriteria().setFofoIds(filterFofoIds);
403
                int counter = 0;
404
                List<ItemCriteriaPayout> itemCriteriaPayouts = createOfferRequest.getTargetSlabs().get(0)
405
                        .getItemCriteriaPayouts();
406
                List<PayoutSlab> payoutSlabs = itemCriteriaPayouts.stream().flatMap(x -> x.getPayoutSlabs().stream()).collect(Collectors.toList());
407
                for (PayoutSlab payoutSlab : payoutSlabs) {
408
                    payoutSlab.setOnwardsAmount(targets.get(counter));
409
                    counter++;
410
                }
411
                this.addOfferService(createOfferRequest);
412
            }
413
        }
414
        thirtyMinsTimeOutCacheManager.getCache("allOffers").evict(YearMonth.now());
27877 amit.gupta 415
 
31747 amit.gupta 416
    }
29783 amit.gupta 417
 
31747 amit.gupta 418
    private Map<CreateOfferRequest, List<PartnerTargetModel>> parseFromExcel(InputStream inputStream)
419
            throws ProfitMandiBusinessException {
29783 amit.gupta 420
 
31747 amit.gupta 421
        Map<CreateOfferRequest, List<PartnerTargetModel>> offerPartnerTargetMap = new HashMap<>();
422
        XSSFWorkbook myWorkBook = null;
423
        try {
424
            myWorkBook = new XSSFWorkbook(inputStream);
425
            myWorkBook.setMissingCellPolicy(MissingCellPolicy.RETURN_BLANK_AS_NULL);
426
            for (int i = 0; i < myWorkBook.getNumberOfSheets(); i++) {
29683 amit.gupta 427
 
31747 amit.gupta 428
                XSSFSheet mySheet = myWorkBook.getSheetAt(i);
429
                int offerId = Integer.parseInt(mySheet.getSheetName());
430
                CreateOfferRequest existingOffer = this.getOffer(0, offerId);
431
                List<PartnerTargetModel> partnerTargetModels = new ArrayList<>();
432
                offerPartnerTargetMap.put(existingOffer, partnerTargetModels);
433
                this.printIterator(mySheet);
434
                LOGGER.info("rowCellNum {}", mySheet.getLastRowNum());
435
                for (int rowNumber = 1; rowNumber <= mySheet.getLastRowNum(); rowNumber++) {
436
                    XSSFRow row = mySheet.getRow(rowNumber);
437
                    LOGGER.info("row {}", row);
438
                    PartnerTargetModel partnerTargetModel = new PartnerTargetModel();
29783 amit.gupta 439
 
31747 amit.gupta 440
                    if (row.getCell(0) != null && row.getCell(0).getCellTypeEnum() == CellType.NUMERIC) {
441
                        partnerTargetModel.setFofoId((int) row.getCell(0).getNumericCellValue());
442
                    } else {
443
                        ProfitMandiBusinessException profitMandiBusinessException = new ProfitMandiBusinessException(
444
                                "FOFO ID", row.getCell(0).toString(), "TGLSTNG_VE_1010");
445
                        LOGGER.error("Excel file parse error : ", profitMandiBusinessException);
446
                        throw profitMandiBusinessException;
447
                    }
448
                    List<Integer> targets = new ArrayList<>();
449
                    long targetsSize = existingOffer.getTargetSlabs().get(0).getItemCriteriaPayouts().stream().flatMap(x -> x.getPayoutSlabs().stream()).collect(Collectors.counting());
450
                    for (int cellNumber = 1; cellNumber <= targetsSize; cellNumber++) {
451
                        if (row.getCell(cellNumber) != null
452
                                && row.getCell(cellNumber).getCellTypeEnum() == CellType.NUMERIC) {
453
                            targets.add((int) row.getCell(cellNumber).getNumericCellValue());
454
                        } else {
455
                            ProfitMandiBusinessException profitMandiBusinessException = new ProfitMandiBusinessException(
456
                                    "Target Column issue at " + rowNumber + ", " + cellNumber, row.getCell(cellNumber),
457
                                    "Invalid target");
458
                            LOGGER.error("Excel file parse error : ", profitMandiBusinessException);
459
                            throw profitMandiBusinessException;
460
                        }
461
                    }
462
                    partnerTargetModel.setTargets(targets);
463
                    partnerTargetModels.add(partnerTargetModel);
464
                }
465
            }
466
            myWorkBook.close();
467
        } catch (ProfitMandiBusinessException pbse) {
468
            throw pbse;
469
        } catch (IOException ioException) {
470
            ioException.printStackTrace();
471
            throw new ProfitMandiBusinessException(ProfitMandiConstants.EXCEL_FILE, ioException.getMessage(),
472
                    "EXL_VE_1000");
473
        } finally {
474
            if (myWorkBook != null) {
475
                try {
476
                    myWorkBook.close();
477
                } catch (IOException e) {
478
                    // TODO Auto-generated catch block
479
                    e.printStackTrace();
480
                }
481
            }
482
        }
483
        LOGGER.info("offerPartnerTargetMap {}", offerPartnerTargetMap);
484
        return offerPartnerTargetMap;
485
    }
29783 amit.gupta 486
 
31747 amit.gupta 487
    private void printIterator(XSSFSheet sheet) {
488
        Iterator<Row> rowIterator = sheet.iterator();
489
        while (rowIterator.hasNext()) {
490
            Row row = rowIterator.next();
491
            // For each row, iterate through all the columns
492
            Iterator<Cell> cellIterator = row.cellIterator();
29683 amit.gupta 493
 
31747 amit.gupta 494
            while (cellIterator.hasNext()) {
495
                Cell cell = cellIterator.next();
496
                // Check the cell type and format accordingly
497
                switch (cell.getCellType()) {
498
                    case Cell.CELL_TYPE_NUMERIC:
499
                        System.out.print(cell.getNumericCellValue() + "t");
500
                        break;
501
                    case Cell.CELL_TYPE_STRING:
502
                        System.out.print(cell.getStringCellValue() + "t");
503
                        break;
504
                }
505
            }
506
            System.out.println("");
507
        }
508
    }
29683 amit.gupta 509
 
31747 amit.gupta 510
    @Override
511
    public Map<Integer, CreateOfferRequest> getPublishedOffers(LocalDate date, int fofoId, String brand) {
512
        // TODO Auto-generated method stub
513
        return null;
514
    }
30684 amit.gupta 515
 
31747 amit.gupta 516
    @Override
32043 amit.gupta 517
    @Cacheable(value = "slabPayoutMap1", cacheManager = "oneDayCacheManager")
31747 amit.gupta 518
    public Map<Integer, Map<Integer, Long>> getSlabPayoutMap(CreateOfferRequest createOfferRequest) {
519
        Map<Integer, Map<Integer, Long>> catalogSlabPayoutMap = new HashMap<>();
520
        com.spice.profitmandi.dao.model.TargetSlab targetSlab = createOfferRequest.getTargetSlabs().get(0);
521
        List<ItemCriteriaPayout> payouts = targetSlab.getItemCriteriaPayouts();
29783 amit.gupta 522
 
31747 amit.gupta 523
        for (ItemCriteriaPayout itemCriteriaPayout : payouts) {
524
            com.spice.profitmandi.service.offers.ItemCriteria itemCriteria = itemCriteriaPayout.getItemCriteria();
525
            List<Integer> catalogIds = itemRepository.getCatalogIds(itemCriteria);
526
            for (PayoutSlab payoutSlab : Lists.reverse(itemCriteriaPayout.getPayoutSlabs())) {
527
                if (itemCriteriaPayout.getAmountType().equals(AmountType.FIXED)) {
528
                    for (Integer catalogId : catalogIds) {
529
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
530
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
531
                        }
532
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
533
                                (long) payoutSlab.getPayoutAmount());
534
                    }
535
                } else if (itemCriteriaPayout.getAmountType().equals(AmountType.SLAB_FIXED)) {
536
                    for (Integer catalogId : catalogIds) {
537
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
538
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
539
                        }
540
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
541
                                (long) (payoutSlab.getPayoutAmount() / payoutSlab.getOnwardsAmount()));
542
                    }
543
                } else if (itemCriteriaPayout.getAmountType().equals(AmountType.PERCENTAGE)) {
544
                    Map<Integer, TagListing> tagListingsMap = tagListingRepository.selectAllByCatalogIds(catalogIds);
545
                    for (Map.Entry<Integer, TagListing> tagListingEntry : tagListingsMap.entrySet()) {
546
                        TagListing tagListing = tagListingEntry.getValue();
547
                        if (!catalogSlabPayoutMap.containsKey(tagListingEntry.getKey())) {
548
                            catalogSlabPayoutMap.put(tagListingEntry.getKey(), new LinkedHashMap<>());
549
                        }
550
                        catalogSlabPayoutMap.get(tagListingEntry.getKey()).put(payoutSlab.getOnwardsAmount(),
551
                                (long) (tagListing.getSellingPrice() * payoutSlab.getPayoutAmount() / 100));
552
                    }
553
                }
554
            }
555
        }
556
        return catalogSlabPayoutMap;
557
    }
558
 
31903 amit.gupta 559
    @Override
560
    @Cacheable(value = "slabPayoutMap", cacheManager = "oneDayCacheManager")
561
    public Map<Integer, Map<Integer, AmountModel>> getSlabPayoutMapNew(CreateOfferRequest createOfferRequest) {
562
        Map<Integer, Map<Integer, AmountModel>> catalogSlabPayoutMap = new HashMap<>();
563
        com.spice.profitmandi.dao.model.TargetSlab targetSlab = createOfferRequest.getTargetSlabs().get(0);
564
        List<ItemCriteriaPayout> payouts = targetSlab.getItemCriteriaPayouts();
565
 
566
        for (ItemCriteriaPayout itemCriteriaPayout : payouts) {
567
            com.spice.profitmandi.service.offers.ItemCriteria itemCriteria = itemCriteriaPayout.getItemCriteria();
568
            List<Integer> catalogIds = itemRepository.getCatalogIds(itemCriteria);
569
            for (PayoutSlab payoutSlab : Lists.reverse(itemCriteriaPayout.getPayoutSlabs())) {
570
                if (itemCriteriaPayout.getAmountType().equals(AmountType.FIXED)) {
571
                    for (Integer catalogId : catalogIds) {
572
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
573
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
574
                        }
575
                        AmountModel amountModel = new AmountModel();
576
                        amountModel.setAmountType(AmountType.FIXED);
577
                        amountModel.setAmount(payoutSlab.getPayoutAmount());
32021 amit.gupta 578
                        amountModel.setDiscount(createOfferRequest.isDiscount());
31903 amit.gupta 579
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
580
                                amountModel);
581
                    }
582
                } else if (itemCriteriaPayout.getAmountType().equals(AmountType.SLAB_FIXED)) {
583
                    for (Integer catalogId : catalogIds) {
584
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
585
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
586
                        }
587
 
588
                        AmountModel amountModel = new AmountModel();
589
                        amountModel.setAmountType(AmountType.FIXED);
32021 amit.gupta 590
                        amountModel.setDiscount(createOfferRequest.isDiscount());
31903 amit.gupta 591
                        amountModel.setAmount(payoutSlab.getPayoutAmount() / payoutSlab.getOnwardsAmount());
592
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
593
                                amountModel);
594
                    }
595
                } else if (itemCriteriaPayout.getAmountType().equals(AmountType.PERCENTAGE)) {
596
                    for (Integer catalogId : catalogIds) {
597
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
598
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
599
                        }
600
                        AmountModel amountModel = new AmountModel();
601
                        amountModel.setAmountType(AmountType.PERCENTAGE);
602
                        amountModel.setAmount(payoutSlab.getPayoutAmount());
32021 amit.gupta 603
                        amountModel.setDiscount(createOfferRequest.isDiscount());
31903 amit.gupta 604
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
605
                                amountModel);
606
                    }
607
                }
608
            }
609
        }
610
        return catalogSlabPayoutMap;
611
    }
612
 
31920 amit.gupta 613
 
614
    private double getAmount(InventoryPayoutModel inventoryPayoutModel, AmountModel amountModel) {
615
        double rollout = 0;
616
        if (amountModel.getAmountType().equals(AmountType.PERCENTAGE)) {
617
            double effectiveDp = inventoryPayoutModel.getDp() - inventoryPayoutModel.getFixedAmount();
618
            double totalPercentage = inventoryPayoutModel.getPercentageAmount() + amountModel.getAmount();
619
            rollout = effectiveDp * (totalPercentage / (100 + totalPercentage) - (inventoryPayoutModel.getPercentageAmount() / (100 + inventoryPayoutModel.getPercentageAmount())));
620
        } else {
621
            rollout = amountModel.getAmount() * (100 / (100 + inventoryPayoutModel.getPercentageAmount()));
622
        }
623
        return rollout;
624
    }
625
 
626
    @Override
627
    public void processActivationtOffer(CreateOfferRequest createOfferRequest) throws ProfitMandiBusinessException {
628
        List<OfferPayout> offerPayouts = offerPayoutRepository.selectAllByOfferId(createOfferRequest.getId());
629
        List<ItemCriteriaPayout> itemCriteriaPayouts = createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts();
630
        Map<Integer, ItemCriteriaPayout> itemCriteriaPayoutMap = itemCriteriaPayouts.stream().collect(Collectors.toMap(x -> x.getItemCriteria().getId(), x -> x));
31923 amit.gupta 631
        LOGGER.info("itemCriteriaPayoutMap {}", itemCriteriaPayoutMap);
632
        LOGGER.info("offerPayouts {}", offerPayouts);
31924 amit.gupta 633
        Map<Integer, Map<Integer, Double>> fixedSlabCriteriaPartnerMap = offerPayouts.stream().filter(x -> itemCriteriaPayoutMap.get((int) x.getCriteriaId()).getAmountType().equals(AmountType.SLAB_FIXED))
31920 amit.gupta 634
                .collect(Collectors.groupingBy(x -> (int) x.getCriteriaId(), Collectors.groupingBy(x -> (int) x.getFofoId(), Collectors.summingDouble(x -> x.getSlabAmount()))));
635
 
636
 
637
        Map<String, Double> serialNumberPaid = offerPayouts.stream().filter(x -> x.getRejectTimestamp() == null).collect(Collectors.groupingBy(x -> x.getSerialNumber(), Collectors.summingDouble(x -> x.getSlabAmount())));
638
        Map<Integer, Map<Integer, List<FofoOrderItem>>> criteriaPartnerwiseTertiary = offerRepository.getCriteriaWisePartnerTertiary(createOfferRequest);
639
 
640
 
641
        final Set<String> activatedImeis;
642
        if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
643
            //All Serialnumbers for all eligible retailers
644
            List<String> serialNumbers = criteriaPartnerwiseTertiary.entrySet().stream().flatMap(x -> x.getValue().entrySet().stream().flatMap(foiList -> foiList.getValue().stream()))
645
                    .flatMap(y -> y.getFofoLineItems().stream()).filter(fli -> fli.getSerialNumber() != null)
646
                    .map(x -> x.getSerialNumber()).collect(Collectors.toList());
647
            if (serialNumbers.size() > 0) {
648
                activatedImeis = activatedImeiRepository.selectBySerialNumbers(serialNumbers).stream()
649
                        .filter(x -> createOfferRequest.isWithinRange(x.getActivationTimestamp()))
650
                        .map(x -> x.getSerialNumber()).collect(Collectors.toSet());
651
            } else {
652
                activatedImeis = null;
653
            }
654
        } else {
655
            activatedImeis = null;
656
        }
657
 
658
        Map<Integer, Integer> userBaseQtyMap = new HashMap<>();
659
        Map<Integer, Integer> userBaseValueMap = new HashMap<>();
660
        Map<Integer, Integer> eligibleBaseQtyMap = new HashMap<>();
661
        Map<Integer, Integer> eligibleBaseValueMap = new HashMap<>();
662
 
663
        if (createOfferRequest.isBaseCriteria()) {
664
            Map<Integer, List<FofoOrderItem>> foiMap = criteriaPartnerwiseTertiary.get(0);
665
            for (Map.Entry<Integer, List<FofoOrderItem>> orderEntry : foiMap.entrySet()) {
666
                int fofoId = orderEntry.getKey();
667
                List<FofoOrderItem> fofoOrderItems = orderEntry.getValue();
668
                int totalBaseQty = fofoOrderItems.stream().collect(Collectors.summingInt(x -> (x.getQuantity())));
669
                int totalBaseValue = fofoOrderItems.stream().collect(Collectors.summingInt(x -> (Math.round(x.getDp())) * x.getQuantity()));
670
                userBaseQtyMap.put(fofoId, totalBaseQty);
671
                userBaseValueMap.put(fofoId, totalBaseValue);
672
                if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
673
                    Map<Integer, Integer> inventoryItemValueMap = new HashMap<>();
674
                    for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
675
                        fofoOrderItem.getFofoLineItems().stream().filter(x -> x.getSerialNumber() != null).forEach(
676
                                lineItem -> {
677
                                    if (activatedImeis == null || activatedImeis.contains(lineItem.getSerialNumber())) {
678
                                        inventoryItemValueMap.put(lineItem.getInventoryItemId(), (int) fofoOrderItem.getDp());
679
                                    }
680
                                }
681
                        );
682
                    }
683
                    eligibleBaseQtyMap.put(fofoId, inventoryItemValueMap.size());
684
                    eligibleBaseValueMap.put(fofoId, inventoryItemValueMap.entrySet().stream().collect(Collectors.summingInt(x -> x.getValue())));
685
                } else {
686
                    eligibleBaseQtyMap.put(fofoId, totalBaseQty);
687
                    eligibleBaseValueMap.put(fofoId, totalBaseValue);
688
 
689
                }
690
 
691
            }
692
        }
693
 
694
        //As of now eligible sale is considered to be without special criteria like brand/
695
        for (ItemCriteriaPayout itemCriteriaPayout : createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts()) {
696
            int criteriaId = itemCriteriaPayout.getItemCriteria().getId();
697
            Map<Integer, List<FofoOrderItem>> ordersMap = criteriaPartnerwiseTertiary.get(criteriaId);
698
            for (Map.Entry<Integer, List<FofoOrderItem>> orderEntry : ordersMap.entrySet()) {
31992 amit.gupta 699
                double totalRolloutAmount = 0;
31920 amit.gupta 700
                int fofoId = orderEntry.getKey();
701
                List<FofoOrderItem> fofoOrderItems = orderEntry.getValue();
702
                OfferRowModel offerRowModel = new OfferRowModel();
703
                int totalQty = fofoOrderItems.stream().collect(Collectors.summingInt(x -> (x.getQuantity())));
704
                int totalValue = fofoOrderItems.stream().collect(Collectors.summingInt(x -> Math.round(x.getDp()) * (x.getQuantity())));
705
                int eligibleQty = totalQty;
706
                int eligibleValue = totalValue;
707
                Map<FofoLineItem, Integer> lineItemValueMap = new HashMap<>();
708
                if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
709
                    for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
710
                        fofoOrderItem.getFofoLineItems().stream().filter(x -> x.getSerialNumber() != null).forEach(
711
                                lineItem -> {
712
                                    if (activatedImeis == null || activatedImeis.contains(lineItem.getSerialNumber())) {
713
                                        lineItemValueMap.put(lineItem, (int) fofoOrderItem.getDp());
714
                                    }
715
                                }
716
                        );
717
                    }
718
                    eligibleQty = lineItemValueMap.size();
719
                    eligibleValue = lineItemValueMap.entrySet().stream().collect(Collectors.summingInt(x -> x.getValue()));
720
                    offerRowModel.setEligibleImeis(lineItemValueMap.keySet().stream().map(x -> x.getSerialNumber()).collect(Collectors.toList()));
721
                }
722
 
723
                int totalBaseQty = totalQty;
724
                int totalBaseValue = totalValue;
725
                int eligibleBaseQty = eligibleQty;
726
                int eligibleBaseValue = eligibleValue;
727
                if (createOfferRequest.isBaseCriteria()) {
728
                    totalBaseQty = userBaseQtyMap.get(fofoId) == null ? 0 : userBaseQtyMap.get(fofoId);
729
                    totalBaseValue = userBaseValueMap.get(fofoId) == null ? 0 : userBaseValueMap.get(fofoId);
730
                    eligibleBaseQty = eligibleBaseQtyMap.get(fofoId) == null ? 0 : eligibleBaseQtyMap.get(fofoId);
731
                    eligibleBaseValue = eligibleBaseValueMap.get(fofoId) == null ? 0 : eligibleBaseValueMap.get(fofoId);
732
                }
733
 
734
 
735
                int totalSale = totalBaseValue;
736
                int eligibleSale = eligibleBaseValue;
737
                int criteriaSale = totalValue;
738
                int eligibleCriteriaSale = eligibleValue;
739
                int eligibleCriteriaSaleDp = eligibleValue;
740
 
741
                if (createOfferRequest.getTargetType().equals(AchievementType.QUANTITY)) {
742
                    totalSale = totalBaseQty;
743
                    eligibleSale = eligibleBaseQty;
744
                    criteriaSale = totalQty;
745
                    eligibleCriteriaSale = eligibleQty;
746
                }
747
 
748
                offerRowModel.setTotalSale(totalSale);
749
                offerRowModel.setEligibleSale(eligibleSale);
750
                float eligiblePayoutValue = 0;
32345 amit.gupta 751
                double finalPayout;
31920 amit.gupta 752
                for (PayoutSlab payoutSlab : itemCriteriaPayout.getPayoutSlabs()) {
753
                    if (payoutSlab.getOnwardsAmount() <= eligibleSale) {
32039 amit.gupta 754
                        LOGGER.info("Eligible Sale {}", eligibleSale);
31920 amit.gupta 755
                        offerRowModel.setPayoutTargetAchieved(payoutSlab.getOnwardsAmount());
756
                        eligiblePayoutValue = payoutSlab.getPayoutAmount();
757
                        offerRowModel.setPayoutValue(eligiblePayoutValue);
758
                    }
759
                }
760
                if (AmountType.PERCENTAGE.equals(itemCriteriaPayout.getAmountType())) {
761
                    finalPayout = (eligiblePayoutValue * eligibleCriteriaSaleDp) / 100;
762
                } else if (AmountType.FIXED.equals(itemCriteriaPayout.getAmountType())) {
763
                    finalPayout = eligiblePayoutValue * eligibleCriteriaSale;
764
                } else {
32039 amit.gupta 765
                    Map<Integer, Double> fofoCriteriaMap = fixedSlabCriteriaPartnerMap.get(criteriaId);
766
                    LOGGER.info("fofoCriteriaMap {}", fofoCriteriaMap);
31920 amit.gupta 767
                    finalPayout = eligiblePayoutValue;
768
                    if (fofoCriteriaMap != null) {
769
                        if (fofoCriteriaMap.containsKey(fofoId)) {
770
                            double totalPayout = fofoCriteriaMap.get(fofoId);
32039 amit.gupta 771
                            finalPayout = eligiblePayoutValue - totalPayout;
772
                            if (Math.abs(finalPayout) < Utils.DOUBLE_EPSILON) {
31920 amit.gupta 773
                                finalPayout = 0;
32039 amit.gupta 774
                            }
31920 amit.gupta 775
                        }
776
                    }
777
                }
778
 
32039 amit.gupta 779
                LOGGER.info("Final Payout - {}", finalPayout);
780
 
31920 amit.gupta 781
                if (finalPayout > 0) {
782
                    List<Integer> inventoryItemIds = lineItemValueMap.keySet().stream().map(x -> x.getInventoryItemId()).collect(Collectors.toList());
783
                    Map<Integer, InventoryItem> inventoryItemsMap = inventoryItemRepository.selectAllByIds(inventoryItemIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
784
                    for (Map.Entry<FofoLineItem, Integer> lineItemValueEntry : lineItemValueMap.entrySet()) {
785
                        double amount = 0;
32039 amit.gupta 786
                        int totalDpValue = lineItemValueMap.values().stream().collect(Collectors.summingInt(x -> x));
787
                        LOGGER.info("Total DP Value {}", totalDpValue);
31920 amit.gupta 788
                        if (AmountType.SLAB_FIXED.equals(itemCriteriaPayout.getAmountType())) {
32039 amit.gupta 789
                            amount = (eligiblePayoutValue * lineItemValueEntry.getValue()) / totalDpValue;
790
                            LOGGER.info("Amount - {}", amount);
31920 amit.gupta 791
                            //Fixed slab should be treated as fixed after payout
792
                        } else {
793
                            amount = eligiblePayoutValue;
32039 amit.gupta 794
                            //Fixed slab has already taken care of that amount;
795
                            if (serialNumberPaid.containsKey(lineItemValueEntry.getKey().getSerialNumber())) {
796
                                amount = amount - serialNumberPaid.get(lineItemValueEntry.getKey().getSerialNumber());
797
                            }
31920 amit.gupta 798
                        }
32039 amit.gupta 799
                        LOGGER.info("Amount - {}", amount);
31920 amit.gupta 800
                        //ignore reasonably small
801
                        if (amount < Utils.DOUBLE_EPSILON) continue;
802
                        AmountModel amountModel = new AmountModel();
803
                        amountModel.setAmountType(itemCriteriaPayout.getAmountType());
804
                        amountModel.setAmount(amount);
32021 amit.gupta 805
                        amountModel.setDiscount(createOfferRequest.isDiscount());
31920 amit.gupta 806
                        InventoryPayoutModel inventoryPayoutModel = priceCircularService.getPayouts(inventoryItemsMap.get(lineItemValueEntry.getKey().getInventoryItemId()));
807
                        double rolloutAmount = inventoryPayoutModel.getRolloutAmount(amountModel);
808
                        totalRolloutAmount += rolloutAmount;
809
 
810
                        OfferPayout offerPayout = new OfferPayout(fofoId, createOfferRequest.getId(), criteriaId, amount, lineItemValueEntry.getKey().getSerialNumber(), rolloutAmount, SchemePayoutStatus.CREDITED, createOfferRequest.getDescription(), LocalDateTime.now());
811
                        //offerPayout.setInventoryItemId(inventoryItemSaleModelsMap.get(lineItemValueEntry.getKey().getInventoryItemId()));
812
                        offerPayoutRepository.persist(offerPayout);
813
                    }
32039 amit.gupta 814
                    walletService.addAmountToWallet((int) fofoId, createOfferRequest.getId(), WalletReferenceType.ADDITIONAL_SCHEME, createOfferRequest.getDescription(), (float) totalRolloutAmount, LocalDateTime.now());
31920 amit.gupta 815
                }
816
            }
817
        }
818
        Offer offer = offerRepository.selectById(createOfferRequest.getId());
819
        offer.setProcessedTimestamp(LocalDateTime.now());
820
    }
821
 
32064 amit.gupta 822
    private void extracted(CreateOfferRequest createOfferRequest, Map<String, Double> serialNumberPaid, ItemCriteriaPayout itemCriteriaPayout, int criteriaId, double totalRolloutAmount, int fofoId, Map<FofoLineItem, Integer> lineItemValueMap, float eligiblePayoutValue) throws ProfitMandiBusinessException {
823
        List<Integer> inventoryItemIds = lineItemValueMap.keySet().stream().map(x -> x.getInventoryItemId()).collect(Collectors.toList());
824
        Map<Integer, InventoryItem> inventoryItemsMap = inventoryItemRepository.selectAllByIds(inventoryItemIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
825
        for (Map.Entry<FofoLineItem, Integer> lineItemValueEntry : lineItemValueMap.entrySet()) {
826
            double amount = 0;
827
            int totalDpValue = lineItemValueMap.values().stream().collect(Collectors.summingInt(x -> x));
828
            LOGGER.info("Total DP Value {}", totalDpValue);
829
            if (AmountType.SLAB_FIXED.equals(itemCriteriaPayout.getAmountType())) {
830
                amount = (eligiblePayoutValue * lineItemValueEntry.getValue()) / totalDpValue;
831
                LOGGER.info("Amount - {}", amount);
832
                //Fixed slab should be treated as fixed after payout
833
            } else {
834
                amount = eligiblePayoutValue;
835
                //Fixed slab has already taken care of that amount;
836
                if (serialNumberPaid.containsKey(lineItemValueEntry.getKey().getSerialNumber())) {
837
                    amount = amount - serialNumberPaid.get(lineItemValueEntry.getKey().getSerialNumber());
838
                }
839
            }
840
            LOGGER.info("Amount - {}", amount);
841
            //ignore reasonably small
842
            if (amount < Utils.DOUBLE_EPSILON) continue;
843
            AmountModel amountModel = new AmountModel();
844
            amountModel.setAmountType(itemCriteriaPayout.getAmountType());
845
            amountModel.setAmount(amount);
846
            amountModel.setDiscount(createOfferRequest.isDiscount());
847
            InventoryPayoutModel inventoryPayoutModel = priceCircularService.getPayouts(inventoryItemsMap.get(lineItemValueEntry.getKey().getInventoryItemId()));
848
            double rolloutAmount = inventoryPayoutModel.getRolloutAmount(amountModel);
849
            totalRolloutAmount += rolloutAmount;
850
 
851
            OfferPayout offerPayout = new OfferPayout(fofoId, createOfferRequest.getId(), criteriaId, amount, lineItemValueEntry.getKey().getSerialNumber(), rolloutAmount, SchemePayoutStatus.CREDITED, createOfferRequest.getDescription(), LocalDateTime.now());
852
            //offerPayout.setInventoryItemId(inventoryItemSaleModelsMap.get(lineItemValueEntry.getKey().getInventoryItemId()));
853
            offerPayoutRepository.persist(offerPayout);
854
        }
855
        walletService.addAmountToWallet((int) fofoId, createOfferRequest.getId(), WalletReferenceType.ADDITIONAL_SCHEME, createOfferRequest.getDescription(), (float) totalRolloutAmount, LocalDateTime.now());
856
    }
857
 
31920 amit.gupta 858
    @Override
859
    public void processSellin(CreateOfferRequest createOfferRequest) throws Exception {
860
 
861
        //List<OfferRowModel> offerRowModels = new ArrayList<>();
862
        List<OfferPayout> offerPayouts = offerPayoutRepository.selectAllByOfferId(createOfferRequest.getId());
32345 amit.gupta 863
        Map<String, Double> serialNumberPaid = offerPayouts.stream().filter(x -> x.getRejectTimestamp() == null).collect(Collectors.groupingBy(x -> x.getSerialNumber(), Collectors.summingDouble(x -> x.getSlabAmount())));
864
 
865
        List<ItemCriteriaPayout> itemCriteriaPayouts = createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts();
866
        Map<Integer, ItemCriteriaPayout> itemCriteriaPayoutMap = itemCriteriaPayouts.stream().collect(Collectors.toMap(x -> x.getItemCriteria().getId(), x -> x));
867
        Map<Integer, Map<Integer, Double>> fixedSlabCriteriaPartnerMap = offerPayouts.stream().filter(x -> itemCriteriaPayoutMap.get((int) x.getCriteriaId()).getAmountType().equals(AmountType.SLAB_FIXED))
868
                .collect(Collectors.groupingBy(x -> (int) x.getCriteriaId(), Collectors.groupingBy(x -> (int) x.getFofoId(), Collectors.summingDouble(x -> x.getSlabAmount()))));
31920 amit.gupta 869
        Set<Long> fofoIds = offerPayouts.stream().map(x -> x.getFofoId()).collect(Collectors.toSet());
870
 
871
        Map<Integer, Map<Integer, List<Order>>> criteriaOrdersMap = offerRepository.getPartnerWiseSellin(createOfferRequest, true);
872
 
32345 amit.gupta 873
 
31920 amit.gupta 874
        Map<Integer, List<Order>> userBaseCriteriaOrdersMap = null;
875
        if (criteriaOrdersMap.get(0) != null && criteriaOrdersMap.get(0).size() > 0) {
876
            userBaseCriteriaOrdersMap = criteriaOrdersMap.get(0).entrySet().stream()
877
                    .filter(x -> !fofoIds.contains(x.getKey())).collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
878
        }
879
 
32345 amit.gupta 880
 
31920 amit.gupta 881
        Map<Integer, Integer> userBaseQtyMap = null;
882
        Map<Integer, Integer> userBaseValueMap = null;
883
        if (userBaseCriteriaOrdersMap != null) {
884
            userBaseQtyMap = new HashMap<>();
885
            userBaseValueMap = new HashMap<>();
886
            for (Map.Entry<Integer, List<Order>> orderEntry : userBaseCriteriaOrdersMap.entrySet()) {
887
                int fofoId = orderEntry.getKey();
888
                List<Order> orders = orderEntry.getValue();
889
                int totalBaseQty = orders.stream().collect(Collectors.summingInt(x -> (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty())));
890
                int totalBaseValue = orders.stream().collect(Collectors.summingInt(x ->
891
                        Math.round(x.getLineItem().getUnitPrice() * (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty()))
892
                ));
893
                userBaseQtyMap.put(fofoId, totalBaseQty);
894
                userBaseValueMap.put(fofoId, totalBaseValue);
895
            }
896
        }
897
        LOGGER.info("Base Qty Map - {}", userBaseQtyMap);
898
        LOGGER.info("Base Value Map - {}", userBaseValueMap);
899
 
900
        LOGGER.info("Processing sellin");
901
        List<OfferPayout> offerPayoutsNew = new ArrayList<>();
902
        for (ItemCriteriaPayout itemCriteriaPayout : createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts()) {
903
            int criteriaId = itemCriteriaPayout.getItemCriteria().getId();
904
            Map<Integer, List<Order>> ordersMap = criteriaOrdersMap.get(criteriaId).entrySet().stream()
905
                    .filter(x -> !fofoIds.contains(x.getKey())).collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
906
            for (Map.Entry<Integer, List<Order>> orderEntry : ordersMap.entrySet()) {
907
                int fofoId = orderEntry.getKey();
908
                //CustomRetailer retailer = retailerService.getAllFofoRetailers().get(fofoId);
909
                List<Order> orders = orderEntry.getValue();
32345 amit.gupta 910
                //Set<String> returnedSerialNumbers = orders.stream().filter(x -> x.getSerialNumber() != null).flatMap(x -> x.getReturnedImeis().stream()).collect(Collectors.toSet());
31920 amit.gupta 911
                int totalQty = orders.stream().collect(Collectors.summingInt(x -> (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty())));
912
                int totalValue = orders.stream().collect(Collectors.summingInt(x -> Math.round(x.getLineItem().
913
                        getUnitPrice() * (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty()))));
914
                int totalBaseQty = totalQty;
915
                int totalBaseValue = totalValue;
916
                if (userBaseCriteriaOrdersMap != null) {
917
                    if (userBaseQtyMap.containsKey(fofoId)) {
918
                        totalBaseQty = userBaseQtyMap.get(fofoId);
919
                        totalBaseValue = userBaseValueMap.get(fofoId);
920
                    } else {
921
                        continue;
922
                    }
923
                }
924
 
925
                int purchasedValue;
926
                if (createOfferRequest.getTargetType().equals(AchievementType.VALUE)) {
927
                    purchasedValue = totalBaseValue;
928
                } else {
929
                    purchasedValue = totalBaseQty;
930
                }
931
                PayoutSlab currentSlab = itemCriteriaPayout.getPayoutSlabs().stream()
932
                        .filter(x -> x.getOnwardsAmount() <= purchasedValue).max(Comparator.comparing(x
933
                                -> x.getOnwardsAmount())).orElse(null);
934
 
935
                //TODO-- payouts handling is here
936
                if (currentSlab == null) continue;
937
                List<Integer> orderIds = orders.stream().map(x -> x.getId()).collect(Collectors.toList());
938
                Map<Integer, LineItem> lineItemMap = orders.stream().collect(Collectors.toMap(x -> x.getLineItem().getId(), x -> x.getLineItem()));
939
                List<WarehouseScan> warehouseScans = warehouseScanRepository.selectAllByOrderIds(orderIds);
32540 amit.gupta 940
                LOGGER.info("Warehosue scans --> {}", warehouseScans);
32345 amit.gupta 941
                List<Integer> warehouseInventoryItemIds = warehouseScans.stream().collect(Collectors.groupingBy(x -> x.getInventoryItemId())).entrySet()
31920 amit.gupta 942
                        .stream().filter(x -> x.getValue().size() == 1).map(x -> x.getKey()).collect(Collectors.toList());
943
                Set<String> serialNumbers;
32345 amit.gupta 944
                LOGGER.info("warehouseInventoryItemIds {}", warehouseInventoryItemIds);
945
                if (warehouseInventoryItemIds.size() > 0) {
946
                    List<WarehouseInventoryItem> warehouseInventoryItems = warehouseInventoryItemRepository.selectAllByIds(warehouseInventoryItemIds);
31920 amit.gupta 947
                    serialNumbers = warehouseInventoryItems.stream().map(x -> x.getSerialNumber()).collect(Collectors.toSet());
948
                } else {
949
                    serialNumbers = new HashSet<>();
950
                }
951
                LOGGER.info("SerialNumbers {}", serialNumbers);
952
                Map<String, Long> serialNumberCountMap = lineItemImeisRepository.selectByLineItemIds(new ArrayList<>(lineItemMap.keySet()))
953
                        .stream().collect(Collectors.groupingBy(x -> x.getSerialNumber(), Collectors.counting()));
954
                LOGGER.info("SerialNumbers Count Map {}", serialNumberCountMap);
955
                Map<String, LineItem> serialNumberMap = lineItemImeisRepository.selectByLineItemIds(new ArrayList<>(lineItemMap.keySet()))
956
                        .stream().collect(Collectors.toMap(x -> x.getSerialNumber(), x -> lineItemMap.get(x.getLineItemId()), (x1, x2) -> x1.getId() > x2.getId() ? x1 : x2));
957
 
958
                serialNumberMap = serialNumberMap.entrySet().stream().filter(x -> serialNumbers.contains(x.getKey())).collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
32542 amit.gupta 959
                LOGGER.info("serialNumberMap {}", serialNumberMap);
32543 amit.gupta 960
                if (serialNumberMap.size() == 0) continue;
32064 amit.gupta 961
                Map<String, InventoryItem> serialNumberInventoryItemMap = this.getInventoryItemMap(fofoId, serialNumberMap);
962
                //Continue if all imeis havent been grned
32345 amit.gupta 963
                if (serialNumberInventoryItemMap.size() < serialNumberCountMap.size()) continue;
32064 amit.gupta 964
 
32345 amit.gupta 965
 
966
                float eligiblePayoutValue = currentSlab.getPayoutAmount();
967
                double finalPayout;
968
                if (AmountType.PERCENTAGE.equals(itemCriteriaPayout.getAmountType())) {
969
                    finalPayout = (eligiblePayoutValue * purchasedValue) / 100;
970
                } else if (AmountType.FIXED.equals(itemCriteriaPayout.getAmountType())) {
971
                    finalPayout = eligiblePayoutValue * purchasedValue;
972
                } else {
973
                    Map<Integer, Double> fofoCriteriaMap = fixedSlabCriteriaPartnerMap.get(criteriaId);
974
                    LOGGER.info("fofoCriteriaMap {}", fofoCriteriaMap);
975
                    finalPayout = eligiblePayoutValue;
976
                    if (fofoCriteriaMap != null) {
977
                        if (fofoCriteriaMap.containsKey(fofoId)) {
978
                            double totalPayout = fofoCriteriaMap.get(fofoId);
979
                            finalPayout = eligiblePayoutValue - totalPayout;
980
                            if (Math.abs(finalPayout) < Utils.DOUBLE_EPSILON) {
981
                                finalPayout = 0;
982
                            }
983
                        }
31920 amit.gupta 984
                    }
985
                }
32345 amit.gupta 986
 
987
                LOGGER.info("Or - {}", finalPayout);
988
 
989
                if (finalPayout > 0) {
990
                    double totalRolloutAmount = 0;
991
                    int totalDpValue = serialNumberInventoryItemMap.entrySet().stream().mapToInt(x -> (int) x.getValue().getUnitPrice()).sum();
992
                    for (Map.Entry<String, InventoryItem> serialNumberInventoryItemEntry : serialNumberInventoryItemMap.entrySet()) {
993
                        double amount = 0;
994
                        LOGGER.info("Total DP Value {}", totalDpValue);
995
                        if (AmountType.SLAB_FIXED.equals(itemCriteriaPayout.getAmountType())) {
996
                            amount = (eligiblePayoutValue * serialNumberInventoryItemEntry.getValue().getUnitPrice()) / totalDpValue;
997
                            LOGGER.info("Amount - {}", amount);
998
                            //Fixed slab should be treated as fixed after payout
999
                        } else {
1000
                            amount = eligiblePayoutValue;
1001
                            //Fixed slab has already taken care of that amount;
1002
                            if (serialNumberPaid.containsKey(serialNumberInventoryItemEntry.getKey())) {
1003
                                amount = amount - serialNumberPaid.get(serialNumberInventoryItemEntry.getKey());
1004
                            }
1005
                        }
1006
                        LOGGER.info("Amount - {}", amount);
1007
                        //ignore reasonably small
1008
                        if (amount < Utils.DOUBLE_EPSILON) continue;
1009
                        AmountModel amountModel = new AmountModel();
1010
                        amountModel.setAmountType(itemCriteriaPayout.getAmountType());
1011
                        amountModel.setAmount(amount);
1012
                        amountModel.setDiscount(createOfferRequest.isDiscount());
1013
                        InventoryPayoutModel inventoryPayoutModel = priceCircularService.getPayouts(serialNumberInventoryItemEntry.getValue());
1014
                        double rolloutAmount = inventoryPayoutModel.getRolloutAmount(amountModel);
1015
                        totalRolloutAmount += rolloutAmount;
1016
 
1017
                        OfferPayout offerPayout = new OfferPayout(fofoId, createOfferRequest.getId(), criteriaId, amount, serialNumberInventoryItemEntry.getKey(), rolloutAmount, SchemePayoutStatus.CREDITED, createOfferRequest.getDescription(), LocalDateTime.now());
1018
                        offerPayoutRepository.persist(offerPayout);
1019
                    }
1020
                    walletService.addAmountToWallet((int) fofoId, createOfferRequest.getId(), WalletReferenceType.ADDITIONAL_SCHEME, createOfferRequest.getDescription(), (float) totalRolloutAmount, LocalDateTime.now());
1021
                }
31920 amit.gupta 1022
            }
1023
        }
1024
        Offer offer = offerRepository.selectById(createOfferRequest.getId());
1025
        offer.setProcessedTimestamp(LocalDateTime.now());
1026
    }
32064 amit.gupta 1027
 
1028
    private Map<String, InventoryItem> getInventoryItemMap(int fofoId, Map<String, LineItem> serialNumberMap) {
1029
        List<InventoryItem> inventoryItems = inventoryItemRepository.selectBySerialNumbers(serialNumberMap.keySet());
32345 amit.gupta 1030
        inventoryItems = inventoryItems.stream().filter(x -> x.getFofoId() == fofoId).collect(Collectors.toList());
1031
        Map<String, InventoryItem> inventoryItemMap = inventoryItems.stream().collect(Collectors.toMap(x -> x.getSerialNumber(), x -> x, (u, v) -> v.getCreateTimestamp().isAfter(u.getCreateTimestamp()) ? v : u));
32064 amit.gupta 1032
        return inventoryItemMap;
1033
    }
27877 amit.gupta 1034
}