Subversion Repositories SmartDukaan

Rev

Rev 35394 | Rev 35667 | 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;
33030 amit.gupta 6
import com.spice.profitmandi.common.model.CustomRetailer;
29683 amit.gupta 7
import com.spice.profitmandi.common.model.PartnerTargetModel;
8
import com.spice.profitmandi.common.model.ProfitMandiConstants;
33999 tejus.loha 9
import com.spice.profitmandi.common.util.FileUtil;
35205 amit 10
import com.spice.profitmandi.common.util.FormattingUtils;
31920 amit.gupta 11
import com.spice.profitmandi.common.util.Utils;
27877 amit.gupta 12
import com.spice.profitmandi.dao.entity.catalog.ItemCriteria;
13
import com.spice.profitmandi.dao.entity.catalog.Offer;
29783 amit.gupta 14
import com.spice.profitmandi.dao.entity.catalog.TagListing;
31903 amit.gupta 15
import com.spice.profitmandi.dao.entity.catalog.TargetSlabEntity;
31920 amit.gupta 16
import com.spice.profitmandi.dao.entity.fofo.FofoLineItem;
17
import com.spice.profitmandi.dao.entity.fofo.FofoOrderItem;
31205 amit.gupta 18
import com.spice.profitmandi.dao.entity.fofo.InventoryItem;
19
import com.spice.profitmandi.dao.entity.fofo.OfferPayout;
31920 amit.gupta 20
import com.spice.profitmandi.dao.entity.transaction.LineItem;
21
import com.spice.profitmandi.dao.entity.transaction.Order;
31747 amit.gupta 22
import com.spice.profitmandi.dao.entity.transaction.UserWalletHistory;
31920 amit.gupta 23
import com.spice.profitmandi.dao.entity.warehouse.WarehouseInventoryItem;
24
import com.spice.profitmandi.dao.entity.warehouse.WarehouseScan;
25
import com.spice.profitmandi.dao.enumuration.catalog.AchievementType;
29783 amit.gupta 26
import com.spice.profitmandi.dao.enumuration.catalog.AmountType;
29499 amit.gupta 27
import com.spice.profitmandi.dao.enumuration.catalog.OfferSchemeType;
31205 amit.gupta 28
import com.spice.profitmandi.dao.enumuration.transaction.SchemePayoutStatus;
35394 amit 29
import com.spice.profitmandi.dao.model.*;
30066 amit.gupta 30
import com.spice.profitmandi.dao.repository.catalog.*;
35205 amit 31
import com.spice.profitmandi.dao.repository.dtr.FofoStoreRepository;
31920 amit.gupta 32
import com.spice.profitmandi.dao.repository.fofo.ActivatedImeiRepository;
33
import com.spice.profitmandi.dao.repository.fofo.InventoryItemRepository;
31205 amit.gupta 34
import com.spice.profitmandi.dao.repository.fofo.OfferPayoutRepository;
31920 amit.gupta 35
import com.spice.profitmandi.dao.repository.transaction.LineItemImeisRepository;
33087 amit.gupta 36
import com.spice.profitmandi.dao.repository.warehouse.AgeingSummaryModel;
31920 amit.gupta 37
import com.spice.profitmandi.dao.repository.warehouse.WarehouseInventoryItemRepository;
38
import com.spice.profitmandi.dao.repository.warehouse.WarehouseScanRepository;
35205 amit 39
import com.spice.profitmandi.service.NotificationService;
31920 amit.gupta 40
import com.spice.profitmandi.service.pricecircular.PriceCircularService;
41
import com.spice.profitmandi.service.scheme.InventoryPayoutModel;
27877 amit.gupta 42
import com.spice.profitmandi.service.user.RetailerService;
31205 amit.gupta 43
import com.spice.profitmandi.service.wallet.WalletService;
35205 amit 44
import com.spice.profitmandi.service.whatsapp.WhatsappMessageType;
31205 amit.gupta 45
import in.shop2020.model.v1.order.WalletReferenceType;
33999 tejus.loha 46
import org.apache.commons.io.output.ByteArrayOutputStream;
30066 amit.gupta 47
import org.apache.logging.log4j.LogManager;
48
import org.apache.logging.log4j.Logger;
49
import org.apache.poi.ss.usermodel.Cell;
50
import org.apache.poi.ss.usermodel.CellType;
51
import org.apache.poi.ss.usermodel.Row;
52
import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
53
import org.apache.poi.xssf.usermodel.XSSFRow;
54
import org.apache.poi.xssf.usermodel.XSSFSheet;
55
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
56
import org.springframework.beans.factory.annotation.Autowired;
57
import org.springframework.cache.CacheManager;
58
import org.springframework.cache.annotation.Cacheable;
59
import org.springframework.stereotype.Component;
27877 amit.gupta 60
 
30066 amit.gupta 61
import java.io.IOException;
62
import java.io.InputStream;
63
import java.time.LocalDate;
31205 amit.gupta 64
import java.time.LocalDateTime;
30066 amit.gupta 65
import java.time.YearMonth;
66
import java.util.*;
67
import java.util.stream.Collectors;
68
 
27877 amit.gupta 69
@Component
70
public class OfferServiceImpl implements OfferService {
71
 
35394 amit 72
    private static final Logger LOGGER = LogManager.getLogger(OfferServiceImpl.class);
29499 amit.gupta 73
 
35394 amit 74
    // Constants
75
    private static final List<String> TARGETS = Arrays.asList("Target 1", "Target 2", "Target 3", "Target 4", "Target 5");
76
    private static final int STOCK_AGEING_THRESHOLD_DAYS = 300;
77
 
78
    // Dependencies - Core
31747 amit.gupta 79
    @Autowired
80
    private Gson gson;
27877 amit.gupta 81
 
31747 amit.gupta 82
    @Autowired
35394 amit 83
    private CacheManager oneDayCacheManager;
35205 amit 84
 
35394 amit 85
    // Dependencies - Repositories
35205 amit 86
    @Autowired
31747 amit.gupta 87
    private OfferRepository offerRepository;
27877 amit.gupta 88
 
31747 amit.gupta 89
    @Autowired
35394 amit 90
    private OfferPayoutRepository offerPayoutRepository;
27877 amit.gupta 91
 
31747 amit.gupta 92
    @Autowired
35394 amit 93
    private OfferTargetSlabRepository offerTargetSlabRepository;
31205 amit.gupta 94
 
31747 amit.gupta 95
    @Autowired
96
    private ItemCriteriaRepository itemCriteriaRepository;
27877 amit.gupta 97
 
31747 amit.gupta 98
    @Autowired
99
    private ItemRepository itemRepository;
27877 amit.gupta 100
 
31747 amit.gupta 101
    @Autowired
102
    private TagListingRepository tagListingRepository;
29783 amit.gupta 103
 
31747 amit.gupta 104
    @Autowired
35205 amit 105
    private FofoStoreRepository fofoStoreRepository;
30684 amit.gupta 106
 
31747 amit.gupta 107
    @Autowired
35394 amit 108
    private ActivatedImeiRepository activatedImeiRepository;
27877 amit.gupta 109
 
31920 amit.gupta 110
    @Autowired
111
    private WarehouseScanRepository warehouseScanRepository;
112
 
113
    @Autowired
114
    private WarehouseInventoryItemRepository warehouseInventoryItemRepository;
115
 
116
    @Autowired
117
    private LineItemImeisRepository lineItemImeisRepository;
35394 amit 118
 
31920 amit.gupta 119
    @Autowired
120
    private InventoryItemRepository inventoryItemRepository;
121
 
35394 amit 122
    @Autowired
123
    private OfferEligibleImeiRepository offerEligibleImeiRepository;
124
 
125
    // Dependencies - Services
126
    @Autowired
127
    private NotificationService notificationService;
128
 
129
    @Autowired
130
    private RetailerService retailerService;
131
 
132
    @Autowired
133
    private PriceCircularService priceCircularService;
134
 
135
    @Autowired
136
    private WalletService walletService;
137
 
31747 amit.gupta 138
    @Override
139
    public void addOfferService(CreateOfferRequest createOfferRequest) throws ProfitMandiBusinessException {
140
        LOGGER.info("createOfferRequest  -- {}", createOfferRequest);
141
        this.createOffer(createOfferRequest);
142
        this.createTargetSlabs(createOfferRequest);
143
    }
27877 amit.gupta 144
 
31747 amit.gupta 145
    private void createOffer(CreateOfferRequest createOfferRequest) {
146
        Offer offer = new Offer();
147
        offer.setName(createOfferRequest.getName());
148
        offer.setTargetType(createOfferRequest.getTargetType());
149
        offer.setBooster(createOfferRequest.isBooster());
150
        offer.setPayoutType(createOfferRequest.getPayoutType());
151
        offer.setSchemeType(createOfferRequest.getSchemeType());
152
        offer.setBaseCriteia(createOfferRequest.isBaseCriteria());
153
        offer.setEndDate(createOfferRequest.getEndDate());
154
        offer.setStartDate(createOfferRequest.getStartDate());
155
        offer.setBrandSharePercentage(createOfferRequest.getBrandShareTerms());
156
        offer.setSellinPercentage(createOfferRequest.getSellinPercentage());
157
        offer.setOfferNotes(createOfferRequest.getOfferNotes());
158
        offer.setActivationBrands(createOfferRequest.getActivationBrands());
159
        offer.setTerms(createOfferRequest.getTerms());
160
        offer.setItemCriteria(gson.toJson(createOfferRequest.getItemCriteria()));
161
        offer.setPartnerCriteria(gson.toJson(createOfferRequest.getPartnerCriteria()));
32070 amit.gupta 162
        offer.setDiscount(createOfferRequest.isDiscount());
31747 amit.gupta 163
        offerRepository.persist(offer);
164
        createOfferRequest.setId(offer.getId());
165
    }
27877 amit.gupta 166
 
31747 amit.gupta 167
    @Override
35595 amit 168
    @Cacheable(value = "publishedOffersWithAchievement", cacheManager = "redisShortCacheManager")
33247 ranu 169
    public List<CreateOfferRequest> getPublishedOffers(int fofoId, YearMonth yearMonth) throws ProfitMandiBusinessException {
35394 amit 170
        Map<Integer, List<Offer>> publishedMapByPartner = offerRepository.selectAllPublishedMapByPartner(yearMonth);
171
        List<Offer> publishedOffers = publishedMapByPartner != null ? publishedMapByPartner.get(fofoId) : null;
31747 amit.gupta 172
        List<CreateOfferRequest> createOfferRequests = new ArrayList<>();
173
        if (publishedOffers != null) {
174
            for (Offer offer : publishedOffers) {
175
                CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
176
                createOfferRequests.add(createOfferRequest);
177
                setCriteriaPayoutAchieved(fofoId, createOfferRequest);
27877 amit.gupta 178
 
31747 amit.gupta 179
            }
180
        }
181
        return createOfferRequests;
182
    }
27877 amit.gupta 183
 
31747 amit.gupta 184
    private void setCriteriaPayoutAchieved(int fofoId, CreateOfferRequest createOfferRequest) {
185
        Map<Integer, Long> criteriaTransactionMap = null;
186
        if (createOfferRequest.getSchemeType().equals(OfferSchemeType.SELLIN)) {
35394 amit 187
            Map<Integer, Map<Integer, Long>> partnerWiseMap = offerRepository.getPartnerWisePurchaseSum(createOfferRequest);
188
            criteriaTransactionMap = partnerWiseMap != null ? partnerWiseMap.get(fofoId) : null;
31747 amit.gupta 189
        } else {
35394 amit 190
            Map<Integer, Map<Integer, Long>> partnerWiseMap = offerRepository.getPartnerWiseSalesSum(createOfferRequest);
191
            criteriaTransactionMap = partnerWiseMap != null ? partnerWiseMap.get(fofoId) : null;
31747 amit.gupta 192
        }
193
        LOGGER.info("I am here ------- {}", createOfferRequest.getId());
194
        List<com.spice.profitmandi.dao.model.ItemCriteriaPayout> itemCriteriaPayouts = createOfferRequest
195
                .getTargetSlabs().get(0).getItemCriteriaPayouts();
27877 amit.gupta 196
 
31747 amit.gupta 197
        for (com.spice.profitmandi.dao.model.ItemCriteriaPayout itemCriteriaPayout : itemCriteriaPayouts) {
198
            itemCriteriaPayout.setNextSlab(null);
199
            LOGGER.info("I am here --- {}", itemCriteriaPayout.getPayoutSlabs());
200
            long saleAmount = 0;
201
            if (criteriaTransactionMap != null
202
                    && criteriaTransactionMap.containsKey(itemCriteriaPayout.getItemCriteria().getId())) {
31853 amit.gupta 203
                saleAmount = criteriaTransactionMap.containsKey(0) ? criteriaTransactionMap.get(0) : criteriaTransactionMap.get(itemCriteriaPayout.getItemCriteria().getId());
31747 amit.gupta 204
            }
205
            itemCriteriaPayout.setAchievedValue(saleAmount);
206
            List<com.spice.profitmandi.service.offers.PayoutSlab> payoutSlabs = itemCriteriaPayout.getPayoutSlabs();
207
            for (int i = 0; i < payoutSlabs.size(); i++) {
208
                com.spice.profitmandi.service.offers.PayoutSlab beginSlab = payoutSlabs.get(i);
209
                com.spice.profitmandi.service.offers.PayoutSlab endSlab = null;
210
                if (payoutSlabs.size() - 1 > i) {
211
                    endSlab = payoutSlabs.get(i + 1);
212
                }
213
                if (beginSlab.getOnwardsAmount() > saleAmount) {
214
                    itemCriteriaPayout.setShortValue(beginSlab.getOnwardsAmount() - saleAmount);
215
                    itemCriteriaPayout.setNextSlab(beginSlab);
216
                    LOGGER.info("I am here");
217
                    break;
218
                }
219
                if (endSlab != null) {
220
                    if (beginSlab.getOnwardsAmount() <= saleAmount && endSlab.getOnwardsAmount() > saleAmount) {
221
                        itemCriteriaPayout.setCurrentSlab(beginSlab);
222
                        beginSlab.setSelected(true);
223
                        itemCriteriaPayout.setNextSlab(endSlab);
224
                        itemCriteriaPayout.setShortValue(endSlab.getOnwardsAmount() - saleAmount);
225
                        LOGGER.info("I am here");
226
                        break;
227
                    }
228
                    // Last loop
229
                } else {
230
                    beginSlab.setSelected(true);
231
                    itemCriteriaPayout.setCurrentSlab(beginSlab);
232
                    LOGGER.info("I am here");
233
                }
234
            }
235
            LOGGER.info("I am here --- {}", itemCriteriaPayout);
236
        }
29783 amit.gupta 237
 
31747 amit.gupta 238
    }
27877 amit.gupta 239
 
31747 amit.gupta 240
    @Override
32868 amit.gupta 241
    @Cacheable(value = "allOffers", cacheManager = "oneDayCacheManager")
33247 ranu 242
    public Map<Integer, CreateOfferRequest> getAllOffers(YearMonth yearMonth) throws ProfitMandiBusinessException {
31747 amit.gupta 243
        List<Offer> allOffers = offerRepository.selectAll(yearMonth, false);
244
        List<CreateOfferRequest> createOfferRequests = new ArrayList<>();
245
        for (Offer offer : allOffers) {
246
            CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
247
            createOfferRequests.add(createOfferRequest);
248
        }
249
        return createOfferRequests.stream().collect(Collectors.toMap(CreateOfferRequest::getId, x -> x));
250
    }
27877 amit.gupta 251
 
31747 amit.gupta 252
    @Override
253
    @Cacheable(value = "partnerOffers", cacheManager = "thirtyMinsTimeOutCacheManager")
33247 ranu 254
    public CreateOfferRequest getOffer(int fofoId, int offerId) throws ProfitMandiBusinessException {
31747 amit.gupta 255
        Offer offer = offerRepository.selectById(offerId);
256
        CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
257
        if (fofoId > 0) {
35394 amit 258
            createOfferRequest.setCriteriaQtyAmountModel(this.getCriteriaQtyAmounModelMap(createOfferRequest, fofoId));
31747 amit.gupta 259
        }
29783 amit.gupta 260
 
31747 amit.gupta 261
        return createOfferRequest;
262
    }
27877 amit.gupta 263
 
31747 amit.gupta 264
    @Override
33247 ranu 265
    public CreateOfferRequest getCreateOfferRequest(Offer fromOffer) throws ProfitMandiBusinessException {
31747 amit.gupta 266
        CreateOfferRequest createOfferRequest = new CreateOfferRequest();
267
        createOfferRequest.setName(fromOffer.getName());
32023 amit.gupta 268
        createOfferRequest.setDiscount(fromOffer.isDiscount());
31747 amit.gupta 269
        createOfferRequest.setTargetType(fromOffer.getTargetType());
270
        createOfferRequest.setPayoutType(fromOffer.getPayoutType());
271
        createOfferRequest.setSchemeType(fromOffer.getSchemeType());
272
        createOfferRequest.setActivationBrands(fromOffer.getActivationBrands());
273
        createOfferRequest.setEndDate(fromOffer.getEndDate());
274
        createOfferRequest.setProcessTimestamp(fromOffer.getProcessedTimestamp());
275
        createOfferRequest.setStartDate(fromOffer.getStartDate());
276
        createOfferRequest.setBooster(fromOffer.isBooster());
277
        createOfferRequest.setActive(fromOffer.isActive());
278
        createOfferRequest.setSellinPercentage(fromOffer.getSellinPercentage());
279
        createOfferRequest.setBrandShareTerms(fromOffer.getBrandSharePercentage());
280
        createOfferRequest.setOfferNotes(fromOffer.getOfferNotes());
281
        createOfferRequest.setTerms(fromOffer.getTerms());
282
        createOfferRequest.setBaseCriteria(fromOffer.isBaseCriteia());
283
        createOfferRequest.setItemCriteria(
284
                gson.fromJson(fromOffer.getItemCriteria(), com.spice.profitmandi.service.offers.ItemCriteria.class));
285
        createOfferRequest.setPartnerCriteria(gson.fromJson(fromOffer.getPartnerCriteria(), PartnerCriteria.class));
286
        createOfferRequest.setId(fromOffer.getId());
287
        createOfferRequest.setCreatedOn(fromOffer.getCreatedTimestamp());
288
        createOfferRequest.setItemCriteriaString(
289
                itemCriteriaRepository.getItemCriteriaDescription(createOfferRequest.getItemCriteria()));
290
        List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = offerTargetSlabRepository
291
                .getByOfferId(fromOffer.getId());
292
        createOfferRequest.setPartnerCriteriaString(
33030 amit.gupta 293
                this.getPartnerCriteriaString(createOfferRequest.getPartnerCriteria()));
31747 amit.gupta 294
        createOfferRequest.setTargetSlabs(targetSlabs);
295
        for (com.spice.profitmandi.dao.model.ItemCriteriaPayout itemCriteriaPayout : createOfferRequest.getTargetSlabs()
296
                .get(0).getItemCriteriaPayouts()) {
297
            itemCriteriaPayout.setNextSlab(itemCriteriaPayout.getPayoutSlabs().get(0));
298
        }
299
        return createOfferRequest;
300
    }
27877 amit.gupta 301
 
31747 amit.gupta 302
    @Override
33613 amit.gupta 303
    public void reverseAdditionalSelloutSchemes(List<InventoryItem> inventoryItems, String reversalReason) throws ProfitMandiBusinessException {
304
        Map<Integer, List<InventoryItem>> fofoInventoryItemsMap = inventoryItems.stream().collect(Collectors.groupingBy(x -> x.getFofoId()));
305
        for (Map.Entry<Integer, List<InventoryItem>> fofoInventoryItemsEntry : fofoInventoryItemsMap.entrySet()) {
306
            int fofoId = fofoInventoryItemsEntry.getKey();
307
            List<InventoryItem> partnerInventoryItems = fofoInventoryItemsEntry.getValue();
308
            List<OfferPayout> offerPayouts = new ArrayList<>();
309
            LOGGER.info("Reversing schemes for fofoId {}, InventoryItems {}", fofoId, inventoryItems);
310
            //As of now we are not handling non-serialised items
35394 amit 311
            List<InventoryItem> serializedItems = partnerInventoryItems.stream().filter(x -> x.getSerialNumber() != null).collect(Collectors.toList());
312
            if (serializedItems.size() > 0) {
313
                // Batch fetch: collect all serial numbers and fetch in one call per fofoId
314
                Set<String> serialNumbers = serializedItems.stream().map(InventoryItem::getSerialNumber).collect(Collectors.toSet());
315
                offerPayouts = offerPayoutRepository.selectAllBySerialNumbers(fofoId, serialNumbers)
316
                        .stream()
317
                        .filter(x -> x.getRejectTimestamp() == null)
318
                        .collect(Collectors.toList());
33613 amit.gupta 319
                for (OfferPayout offerPayout : offerPayouts) {
320
                    offerPayout.setStatus(SchemePayoutStatus.REJECTED);
321
                    offerPayout.setRejectTimestamp(LocalDateTime.now());
322
                }
323
                Map<Long, Double> offerPayoutAmountMap = offerPayouts.stream().collect(Collectors.groupingBy(x -> x.getOfferId(), Collectors.summingDouble(x -> x.getAmount())));
324
                for (Map.Entry<Long, Double> offerPayoutEntry : offerPayoutAmountMap.entrySet()) {
325
                    List<UserWalletHistory> histories = walletService.getAllByReference(fofoId, offerPayoutEntry.getKey().intValue(), WalletReferenceType.ADDITIONAL_SCHEME);
326
                    if (histories.size() > 0) {
31750 amit.gupta 327
 
33613 amit.gupta 328
                        walletService.rollbackAmountFromWallet(fofoId, offerPayoutEntry.getValue().floatValue(), offerPayoutEntry.getKey().intValue(),
329
                                WalletReferenceType.ADDITIONAL_SCHEME, reversalReason, LocalDateTime.now());
330
                    }
31750 amit.gupta 331
                }
332
            }
31747 amit.gupta 333
        }
334
    }
30684 amit.gupta 335
 
31747 amit.gupta 336
    private void createTargetSlabs(CreateOfferRequest createOfferRequest) throws ProfitMandiBusinessException {
337
        List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = createOfferRequest.getTargetSlabs().stream()
338
                .filter(x -> x.validate()).collect(Collectors.toList());
35394 amit 339
        if (!targetSlabs.isEmpty()) {
31747 amit.gupta 340
            Collections.sort(targetSlabs);
341
            for (com.spice.profitmandi.dao.model.TargetSlab targetSlab : targetSlabs) {
342
                if (targetSlab.validate()) {
343
                    List<ItemCriteriaPayout> itemCriteriaPayouts = targetSlab.getItemCriteriaPayouts();
344
                    for (ItemCriteriaPayout itemCriteriaPayout : itemCriteriaPayouts) {
345
                        ItemCriteria itemCriteria = itemCriteriaRepository.selectById(itemCriteriaPayout.getItemCriteria().getId());
346
                        if (itemCriteriaPayout.getItemCriteria().getId() > 0) {
347
                            itemCriteriaPayout.getItemCriteria().setId(0);
348
                        } else {
27877 amit.gupta 349
 
31747 amit.gupta 350
                            String itemCriteriaJson = gson.toJson(itemCriteriaPayout.getItemCriteria());
351
                            itemCriteria = itemCriteriaRepository.selectByCriteria(itemCriteriaJson);
352
                            // ItemCriteria Only once
353
                            if (itemCriteria == null) {
354
                                itemCriteria = new ItemCriteria();
355
                                itemCriteria.setCriteria(gson.toJson(itemCriteriaPayout.getItemCriteria()));
356
                                itemCriteriaRepository.persist(itemCriteria);
357
                            }
358
                        }
359
                        for (PayoutSlab payoutSlab : itemCriteriaPayout.getPayoutSlabs()) {
31903 amit.gupta 360
                            TargetSlabEntity targetSlabEntity = new TargetSlabEntity();
361
                            targetSlabEntity.setOfferId(createOfferRequest.getId());
362
                            targetSlabEntity.setOnwardsTarget(targetSlab.getOnwardsAmount());
363
                            targetSlabEntity.setTargetDescription(targetSlab.getTargetDescription());
364
                            targetSlabEntity.setPayoutTarget(payoutSlab.getOnwardsAmount());
365
                            targetSlabEntity.setPayoutValue(payoutSlab.getPayoutAmount());
366
                            targetSlabEntity.setItemCriteriaId(itemCriteria.getId());
367
                            targetSlabEntity.setAmountType(itemCriteriaPayout.getAmountType());
32979 amit.gupta 368
                            targetSlabEntity.setStartDate(itemCriteriaPayout.getStartDate());
369
                            targetSlabEntity.setEndDate(itemCriteriaPayout.getEndDate());
31903 amit.gupta 370
                            offerTargetSlabRepository.persist(targetSlabEntity);
31747 amit.gupta 371
                        }
372
                    }
373
                }
374
            }
27877 amit.gupta 375
 
31747 amit.gupta 376
        } else {
377
            throw new ProfitMandiBusinessException("Invalid Target Slabs", "Invalid Target", "");
378
        }
27877 amit.gupta 379
 
31747 amit.gupta 380
    }
27877 amit.gupta 381
 
31747 amit.gupta 382
    @Override
33247 ranu 383
    public List<CreateOfferRequest> getPublishedOffers(LocalDate date, int fofoId, int catalogId) throws ProfitMandiBusinessException {
35394 amit 384
        Map<Integer, List<Offer>> publishedMapByPartner = offerRepository.selectAllPublishedMapByPartner(YearMonth.from(date));
385
        List<Offer> publishedOffers = publishedMapByPartner != null ? publishedMapByPartner.get(fofoId) : null;
31747 amit.gupta 386
        List<CreateOfferRequest> createOfferRequests = new ArrayList<>();
387
        if (publishedOffers != null) {
388
            for (Offer offer : publishedOffers) {
389
                boolean found = false;
390
                List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = offerTargetSlabRepository
391
                        .getByOfferId(offer.getId());
392
                CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
393
                createOfferRequest.setTargetSlabs(targetSlabs);
394
                this.setCriteriaPayoutAchieved(fofoId, createOfferRequest);
395
                Set<com.spice.profitmandi.service.offers.ItemCriteria> itemCriteriaSet = targetSlabs.stream()
396
                        .flatMap(x -> x.getItemCriteriaPayouts().stream()).map(x -> x.getItemCriteria()).distinct()
397
                        .filter(x -> itemRepository.containsModel(x, catalogId)).collect(Collectors.toSet());
29499 amit.gupta 398
 
31747 amit.gupta 399
                for (com.spice.profitmandi.dao.model.TargetSlab targetSlab : targetSlabs) {
400
                    targetSlab.setItemCriteriaPayouts(targetSlab.getItemCriteriaPayouts().stream()
401
                            .filter(x -> itemCriteriaSet.contains(x.getItemCriteria())).collect(Collectors.toList()));
402
                    if (targetSlab.getItemCriteriaPayouts().size() > 0) {
403
                        found = true;
404
                    }
405
                }
406
                if (found) {
407
                    createOfferRequests.add(createOfferRequest);
408
                }
409
            }
410
        }
29783 amit.gupta 411
 
31747 amit.gupta 412
        return createOfferRequests;
413
    }
29783 amit.gupta 414
 
31747 amit.gupta 415
    @Override
416
    public void createOffers(InputStream fileInputStream) throws Exception {
417
        Map<CreateOfferRequest, List<PartnerTargetModel>> offerPartnerTargetMap = this.parseFromExcel(fileInputStream);
32868 amit.gupta 418
        Set<YearMonth> ymListToEvict = new HashSet<>();
31747 amit.gupta 419
        for (Map.Entry<CreateOfferRequest, List<PartnerTargetModel>> partnerTargetEntry : offerPartnerTargetMap
420
                .entrySet()) {
421
            CreateOfferRequest createOfferRequest = partnerTargetEntry.getKey();
422
            Map<List<Integer>, List<Integer>> targetPartnerMap = partnerTargetEntry.getValue().stream()
423
                    .collect(Collectors.groupingBy(PartnerTargetModel::getTargets,
424
                            Collectors.mapping(PartnerTargetModel::getFofoId, Collectors.toList())));
425
            for (Map.Entry<List<Integer>, List<Integer>> targetPartnersEntry : targetPartnerMap.entrySet()) {
426
                List<Integer> fofoIds = createOfferRequest.getPartnerCriteria().getFofoIds();
427
                List<Integer> filterFofoIds = targetPartnersEntry.getValue().stream().filter(x -> !fofoIds.contains(x))
428
                        .collect(Collectors.toList());
429
                LOGGER.info("FofoIds {}", filterFofoIds);
430
                List<Integer> targets = targetPartnersEntry.getKey();
431
                LOGGER.info("Targets  {}", targets);
29806 amit.gupta 432
 
31747 amit.gupta 433
                createOfferRequest.getPartnerCriteria().setFofoIds(filterFofoIds);
434
                int counter = 0;
435
                List<ItemCriteriaPayout> itemCriteriaPayouts = createOfferRequest.getTargetSlabs().get(0)
436
                        .getItemCriteriaPayouts();
437
                List<PayoutSlab> payoutSlabs = itemCriteriaPayouts.stream().flatMap(x -> x.getPayoutSlabs().stream()).collect(Collectors.toList());
438
                for (PayoutSlab payoutSlab : payoutSlabs) {
439
                    payoutSlab.setOnwardsAmount(targets.get(counter));
440
                    counter++;
441
                }
442
                this.addOfferService(createOfferRequest);
443
            }
32868 amit.gupta 444
            ymListToEvict.add(YearMonth.from(createOfferRequest.getStartDate()));
31747 amit.gupta 445
        }
32868 amit.gupta 446
        for (YearMonth ymToEvict : ymListToEvict) {
447
            oneDayCacheManager.getCache("allOffers").evict(ymToEvict);
448
        }
27877 amit.gupta 449
 
31747 amit.gupta 450
    }
29783 amit.gupta 451
 
31747 amit.gupta 452
    private Map<CreateOfferRequest, List<PartnerTargetModel>> parseFromExcel(InputStream inputStream)
453
            throws ProfitMandiBusinessException {
29783 amit.gupta 454
 
31747 amit.gupta 455
        Map<CreateOfferRequest, List<PartnerTargetModel>> offerPartnerTargetMap = new HashMap<>();
456
        XSSFWorkbook myWorkBook = null;
457
        try {
458
            myWorkBook = new XSSFWorkbook(inputStream);
459
            myWorkBook.setMissingCellPolicy(MissingCellPolicy.RETURN_BLANK_AS_NULL);
460
            for (int i = 0; i < myWorkBook.getNumberOfSheets(); i++) {
29683 amit.gupta 461
 
31747 amit.gupta 462
                XSSFSheet mySheet = myWorkBook.getSheetAt(i);
463
                int offerId = Integer.parseInt(mySheet.getSheetName());
464
                CreateOfferRequest existingOffer = this.getOffer(0, offerId);
465
                List<PartnerTargetModel> partnerTargetModels = new ArrayList<>();
466
                offerPartnerTargetMap.put(existingOffer, partnerTargetModels);
467
                this.printIterator(mySheet);
468
                LOGGER.info("rowCellNum {}", mySheet.getLastRowNum());
469
                for (int rowNumber = 1; rowNumber <= mySheet.getLastRowNum(); rowNumber++) {
470
                    XSSFRow row = mySheet.getRow(rowNumber);
471
                    LOGGER.info("row {}", row);
472
                    PartnerTargetModel partnerTargetModel = new PartnerTargetModel();
29783 amit.gupta 473
 
31747 amit.gupta 474
                    if (row.getCell(0) != null && row.getCell(0).getCellTypeEnum() == CellType.NUMERIC) {
475
                        partnerTargetModel.setFofoId((int) row.getCell(0).getNumericCellValue());
476
                    } else {
477
                        ProfitMandiBusinessException profitMandiBusinessException = new ProfitMandiBusinessException(
478
                                "FOFO ID", row.getCell(0).toString(), "TGLSTNG_VE_1010");
479
                        LOGGER.error("Excel file parse error : ", profitMandiBusinessException);
480
                        throw profitMandiBusinessException;
481
                    }
482
                    List<Integer> targets = new ArrayList<>();
483
                    long targetsSize = existingOffer.getTargetSlabs().get(0).getItemCriteriaPayouts().stream().flatMap(x -> x.getPayoutSlabs().stream()).collect(Collectors.counting());
484
                    for (int cellNumber = 1; cellNumber <= targetsSize; cellNumber++) {
485
                        if (row.getCell(cellNumber) != null
486
                                && row.getCell(cellNumber).getCellTypeEnum() == CellType.NUMERIC) {
487
                            targets.add((int) row.getCell(cellNumber).getNumericCellValue());
488
                        } else {
489
                            ProfitMandiBusinessException profitMandiBusinessException = new ProfitMandiBusinessException(
490
                                    "Target Column issue at " + rowNumber + ", " + cellNumber, row.getCell(cellNumber),
491
                                    "Invalid target");
492
                            LOGGER.error("Excel file parse error : ", profitMandiBusinessException);
493
                            throw profitMandiBusinessException;
494
                        }
495
                    }
496
                    partnerTargetModel.setTargets(targets);
497
                    partnerTargetModels.add(partnerTargetModel);
498
                }
499
            }
500
            myWorkBook.close();
501
        } catch (ProfitMandiBusinessException pbse) {
502
            throw pbse;
503
        } catch (IOException ioException) {
504
            ioException.printStackTrace();
505
            throw new ProfitMandiBusinessException(ProfitMandiConstants.EXCEL_FILE, ioException.getMessage(),
506
                    "EXL_VE_1000");
507
        } finally {
508
            if (myWorkBook != null) {
509
                try {
510
                    myWorkBook.close();
511
                } catch (IOException e) {
512
                    // TODO Auto-generated catch block
513
                    e.printStackTrace();
514
                }
515
            }
516
        }
517
        LOGGER.info("offerPartnerTargetMap {}", offerPartnerTargetMap);
518
        return offerPartnerTargetMap;
519
    }
29783 amit.gupta 520
 
31747 amit.gupta 521
    private void printIterator(XSSFSheet sheet) {
522
        Iterator<Row> rowIterator = sheet.iterator();
523
        while (rowIterator.hasNext()) {
524
            Row row = rowIterator.next();
35394 amit 525
            StringBuilder rowContent = new StringBuilder();
31747 amit.gupta 526
            Iterator<Cell> cellIterator = row.cellIterator();
29683 amit.gupta 527
 
31747 amit.gupta 528
            while (cellIterator.hasNext()) {
529
                Cell cell = cellIterator.next();
530
                switch (cell.getCellType()) {
531
                    case Cell.CELL_TYPE_NUMERIC:
35394 amit 532
                        rowContent.append(cell.getNumericCellValue()).append("\t");
31747 amit.gupta 533
                        break;
534
                    case Cell.CELL_TYPE_STRING:
35394 amit 535
                        rowContent.append(cell.getStringCellValue()).append("\t");
31747 amit.gupta 536
                        break;
537
                }
538
            }
35394 amit 539
            LOGGER.debug("Row content: {}", rowContent);
31747 amit.gupta 540
        }
541
    }
29683 amit.gupta 542
 
31747 amit.gupta 543
    @Override
544
    public Map<Integer, CreateOfferRequest> getPublishedOffers(LocalDate date, int fofoId, String brand) {
545
        // TODO Auto-generated method stub
546
        return null;
547
    }
30684 amit.gupta 548
 
31747 amit.gupta 549
    @Override
32043 amit.gupta 550
    @Cacheable(value = "slabPayoutMap1", cacheManager = "oneDayCacheManager")
33247 ranu 551
    public Map<Integer, Map<Integer, Long>> getSlabPayoutMap(CreateOfferRequest createOfferRequest) throws ProfitMandiBusinessException {
31747 amit.gupta 552
        Map<Integer, Map<Integer, Long>> catalogSlabPayoutMap = new HashMap<>();
553
        com.spice.profitmandi.dao.model.TargetSlab targetSlab = createOfferRequest.getTargetSlabs().get(0);
554
        List<ItemCriteriaPayout> payouts = targetSlab.getItemCriteriaPayouts();
29783 amit.gupta 555
 
31747 amit.gupta 556
        for (ItemCriteriaPayout itemCriteriaPayout : payouts) {
557
            com.spice.profitmandi.service.offers.ItemCriteria itemCriteria = itemCriteriaPayout.getItemCriteria();
558
            List<Integer> catalogIds = itemRepository.getCatalogIds(itemCriteria);
559
            for (PayoutSlab payoutSlab : Lists.reverse(itemCriteriaPayout.getPayoutSlabs())) {
560
                if (itemCriteriaPayout.getAmountType().equals(AmountType.FIXED)) {
561
                    for (Integer catalogId : catalogIds) {
562
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
563
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
564
                        }
565
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
566
                                (long) payoutSlab.getPayoutAmount());
567
                    }
568
                } else if (itemCriteriaPayout.getAmountType().equals(AmountType.SLAB_FIXED)) {
569
                    for (Integer catalogId : catalogIds) {
570
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
571
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
572
                        }
573
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
574
                                (long) (payoutSlab.getPayoutAmount() / payoutSlab.getOnwardsAmount()));
575
                    }
576
                } else if (itemCriteriaPayout.getAmountType().equals(AmountType.PERCENTAGE)) {
577
                    Map<Integer, TagListing> tagListingsMap = tagListingRepository.selectAllByCatalogIds(catalogIds);
578
                    for (Map.Entry<Integer, TagListing> tagListingEntry : tagListingsMap.entrySet()) {
579
                        TagListing tagListing = tagListingEntry.getValue();
580
                        if (!catalogSlabPayoutMap.containsKey(tagListingEntry.getKey())) {
581
                            catalogSlabPayoutMap.put(tagListingEntry.getKey(), new LinkedHashMap<>());
582
                        }
583
                        catalogSlabPayoutMap.get(tagListingEntry.getKey()).put(payoutSlab.getOnwardsAmount(),
584
                                (long) (tagListing.getSellingPrice() * payoutSlab.getPayoutAmount() / 100));
585
                    }
586
                }
587
            }
588
        }
589
        return catalogSlabPayoutMap;
590
    }
591
 
31903 amit.gupta 592
    @Override
593
    @Cacheable(value = "slabPayoutMap", cacheManager = "oneDayCacheManager")
594
    public Map<Integer, Map<Integer, AmountModel>> getSlabPayoutMapNew(CreateOfferRequest createOfferRequest) {
595
        Map<Integer, Map<Integer, AmountModel>> catalogSlabPayoutMap = new HashMap<>();
596
        com.spice.profitmandi.dao.model.TargetSlab targetSlab = createOfferRequest.getTargetSlabs().get(0);
597
        List<ItemCriteriaPayout> payouts = targetSlab.getItemCriteriaPayouts();
598
 
599
        for (ItemCriteriaPayout itemCriteriaPayout : payouts) {
600
            com.spice.profitmandi.service.offers.ItemCriteria itemCriteria = itemCriteriaPayout.getItemCriteria();
601
            List<Integer> catalogIds = itemRepository.getCatalogIds(itemCriteria);
602
            for (PayoutSlab payoutSlab : Lists.reverse(itemCriteriaPayout.getPayoutSlabs())) {
603
                if (itemCriteriaPayout.getAmountType().equals(AmountType.FIXED)) {
604
                    for (Integer catalogId : catalogIds) {
605
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
606
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
607
                        }
608
                        AmountModel amountModel = new AmountModel();
609
                        amountModel.setAmountType(AmountType.FIXED);
610
                        amountModel.setAmount(payoutSlab.getPayoutAmount());
32021 amit.gupta 611
                        amountModel.setDiscount(createOfferRequest.isDiscount());
31903 amit.gupta 612
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
613
                                amountModel);
614
                    }
615
                } else if (itemCriteriaPayout.getAmountType().equals(AmountType.SLAB_FIXED)) {
616
                    for (Integer catalogId : catalogIds) {
617
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
618
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
619
                        }
620
 
621
                        AmountModel amountModel = new AmountModel();
622
                        amountModel.setAmountType(AmountType.FIXED);
32021 amit.gupta 623
                        amountModel.setDiscount(createOfferRequest.isDiscount());
31903 amit.gupta 624
                        amountModel.setAmount(payoutSlab.getPayoutAmount() / payoutSlab.getOnwardsAmount());
625
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
626
                                amountModel);
627
                    }
628
                } else if (itemCriteriaPayout.getAmountType().equals(AmountType.PERCENTAGE)) {
629
                    for (Integer catalogId : catalogIds) {
630
                        if (!catalogSlabPayoutMap.containsKey(catalogId)) {
631
                            catalogSlabPayoutMap.put(catalogId, new LinkedHashMap<>());
632
                        }
633
                        AmountModel amountModel = new AmountModel();
634
                        amountModel.setAmountType(AmountType.PERCENTAGE);
635
                        amountModel.setAmount(payoutSlab.getPayoutAmount());
32021 amit.gupta 636
                        amountModel.setDiscount(createOfferRequest.isDiscount());
31903 amit.gupta 637
                        catalogSlabPayoutMap.get(catalogId).put(payoutSlab.getOnwardsAmount(),
638
                                amountModel);
639
                    }
640
                }
641
            }
642
        }
643
        return catalogSlabPayoutMap;
644
    }
645
 
31920 amit.gupta 646
 
647
    private double getAmount(InventoryPayoutModel inventoryPayoutModel, AmountModel amountModel) {
648
        double rollout = 0;
649
        if (amountModel.getAmountType().equals(AmountType.PERCENTAGE)) {
650
            double effectiveDp = inventoryPayoutModel.getDp() - inventoryPayoutModel.getFixedAmount();
651
            double totalPercentage = inventoryPayoutModel.getPercentageAmount() + amountModel.getAmount();
652
            rollout = effectiveDp * (totalPercentage / (100 + totalPercentage) - (inventoryPayoutModel.getPercentageAmount() / (100 + inventoryPayoutModel.getPercentageAmount())));
653
        } else {
654
            rollout = amountModel.getAmount() * (100 / (100 + inventoryPayoutModel.getPercentageAmount()));
655
        }
656
        return rollout;
657
    }
658
 
35394 amit 659
    @Override
660
    public Map<Integer, QtyAmountModel> getCriteriaQtyAmounModelMap(CreateOfferRequest createOfferRequest, int fofoId) throws ProfitMandiBusinessException {
661
        final Map<String, LocalDateTime> activatedImeisActivationDateMap;
662
        Map<Integer, QtyAmountModel> qtyAmountMap;
663
        if (createOfferRequest.getSchemeType().equals(OfferSchemeType.SELLIN)) {
664
            qtyAmountMap = getCriteriaQtyAmountModelMapForSellin(createOfferRequest, fofoId);
665
        } else {
666
            qtyAmountMap = getCriteriaQtyAmountModelMapForSelloutAndActivation(createOfferRequest, fofoId);
667
        }
668
        LOGGER.info("Qty Amount Map {}", qtyAmountMap);
669
        return qtyAmountMap;
670
    }
34217 amit.gupta 671
 
35394 amit 672
    private Map<Integer, QtyAmountModel> getCriteriaQtyAmountModelMapForSellin(CreateOfferRequest createOfferRequest, int fofoId) throws ProfitMandiBusinessException {
673
        Map<Integer, QtyAmountModel> criteriaQtyAmountMap = new HashMap<>();
674
        List<ItemCriteriaPayout> itemCriteriaPayouts = createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts();
675
        Map<Integer, ItemCriteriaPayout> itemCriteriaPayoutMap = itemCriteriaPayouts.stream().collect(Collectors.toMap(x -> x.getItemCriteria().getId(), x -> x));
676
 
677
        Map<Integer, List<Order>> criteriaOrdersMap = offerRepository.getPartnerWiseSellin(fofoId, createOfferRequest, true);
678
 
679
 
680
        List<Order> baseCriteriaOrders = null;
681
        if (criteriaOrdersMap.get(0) != null && criteriaOrdersMap.get(0).size() > 0) {
682
            baseCriteriaOrders = criteriaOrdersMap.get(0);
683
        }
684
 
685
 
686
        Integer userBaseQty = null;
687
        Integer userBaseValue = null;
688
        if (baseCriteriaOrders != null) {
689
            userBaseQty = baseCriteriaOrders.stream().collect(Collectors.summingInt(x -> (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty())));
690
            userBaseValue = baseCriteriaOrders.stream().collect(Collectors.summingInt(x ->
691
                    Math.round(x.getLineItem().getUnitPrice() * (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty()))
692
            ));
693
            criteriaQtyAmountMap.put(0, new QtyAmountModel(userBaseQty, userBaseValue));
694
 
695
        }
696
 
697
        LOGGER.info("Processing sellin");
698
        for (ItemCriteriaPayout itemCriteriaPayout : createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts()) {
699
            int criteriaId = itemCriteriaPayout.getItemCriteria().getId();
700
 
701
            QtyAmountModel qtyAmountModel = new QtyAmountModel(0, 0);
702
            criteriaQtyAmountMap.put(itemCriteriaPayout.getItemCriteria().getId(), qtyAmountModel);
703
 
704
            List<Order> orders = criteriaOrdersMap.get(criteriaId);
705
            int totalQty = orders.stream().collect(Collectors.summingInt(x -> (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty())));
706
            int totalValue = orders.stream().collect(Collectors.summingInt(x -> Math.round(x.getLineItem().
707
                    getUnitPrice() * (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty()))));
708
            int totalBaseQty = totalQty;
709
            int totalBaseValue = totalValue;
710
            criteriaQtyAmountMap.put(0, new QtyAmountModel(userBaseQty==null? 0 : userBaseQty, userBaseValue==null?0 : userBaseValue));
711
            if (userBaseQty != null) {
712
                totalBaseQty = userBaseQty;
713
                totalBaseValue = userBaseValue;
714
            }
715
 
716
            int purchasedValue;
717
            if (createOfferRequest.getTargetType().equals(AchievementType.VALUE)) {
718
                purchasedValue = totalBaseValue;
719
            } else {
720
                purchasedValue = totalBaseQty;
721
            }
722
            qtyAmountModel.setQty(totalBaseQty);
723
            qtyAmountModel.setAmount(totalBaseValue);
724
 
725
            PayoutSlab eligibleSlab = null;
726
 
727
            for (PayoutSlab payoutSlab : itemCriteriaPayout.getPayoutSlabs()) {
728
                if (payoutSlab.getOnwardsAmount() <= purchasedValue) {
729
                    eligibleSlab = payoutSlab;
730
                } else {
731
                    break;
732
                }
733
            }
734
            double finalPayout = 0;
735
            if(eligibleSlab != null) {
736
                eligibleSlab.setSelected(true);
737
                float eligiblePayoutValue = eligibleSlab.getPayoutAmount();
738
                if (AmountType.PERCENTAGE.equals(itemCriteriaPayout.getAmountType())) {
739
                    finalPayout = (eligiblePayoutValue * purchasedValue) / 100;
740
                } else if (AmountType.FIXED.equals(itemCriteriaPayout.getAmountType())) {
741
                    finalPayout = eligiblePayoutValue * purchasedValue;
742
                } else {
743
                    finalPayout = eligiblePayoutValue;
744
                }
745
            }
746
            qtyAmountModel.setFinalPayout(finalPayout);
747
            createOfferRequest.setCriteriaQtyAmountModel(criteriaQtyAmountMap);
748
        }
749
        return criteriaQtyAmountMap;
750
    }
751
 
752
    private Map<Integer, QtyAmountModel> getCriteriaQtyAmountModelMapForSelloutAndActivation(CreateOfferRequest createOfferRequest, int fofoId) {
753
        Map<Integer, Map<Integer, List<FofoOrderItem>>> criteriaPartnerwiseTertiary = offerRepository.getCriteriaWisePartnerTertiary(createOfferRequest, fofoId);
754
        Map<Integer, QtyAmountModel> qtyAmountMap;
755
        final Map<String, LocalDateTime> activatedImeisActivationDateMap;
756
        qtyAmountMap = new HashMap<>();
757
        if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
758
            //All Serialnumbers for all eligible retailers
759
            List<String> serialNumbers = criteriaPartnerwiseTertiary.entrySet().stream().flatMap(x -> x.getValue().entrySet().stream().flatMap(foiList -> foiList.getValue().stream()))
760
                    .flatMap(y -> y.getFofoLineItems().stream()).filter(fli -> fli.getSerialNumber() != null)
761
                    .map(x -> x.getSerialNumber()).collect(Collectors.toList());
762
            if (serialNumbers.size() > 0) {
763
            /*if (imeisAllowedManually != null) {
764
                serialNumbers = serialNumbers.stream().filter(x -> imeisAllowedManually.contains(x)).collect(Collectors.toList());
765
            }*/
766
                activatedImeisActivationDateMap = activatedImeiRepository.selectBySerialNumbers(serialNumbers).stream()
767
                        .filter(x -> createOfferRequest.isWithinRange(x.getActivationTimestamp()))
768
                        .collect(Collectors.toMap(x -> x.getSerialNumber(), x -> x.getActivationTimestamp()));
769
            } else {
770
                activatedImeisActivationDateMap = null;
771
            }
772
        } else {
773
            activatedImeisActivationDateMap = null;
774
        }
775
 
776
        QtyAmountModel qtyAmountModel = null;
777
        if (createOfferRequest.isBaseCriteria()) {
778
            List<FofoOrderItem> fofoOrderItems = criteriaPartnerwiseTertiary.get(0).get(fofoId);
779
            int totalBaseQty = fofoOrderItems == null ? 0 : fofoOrderItems.stream().filter(x->createOfferRequest.isWithinRange(x.getCreateTimestamp())).collect(Collectors.summingInt(x -> (x.getQuantity())));
780
            int totalBaseValue = fofoOrderItems == null ? 0 : fofoOrderItems.stream().filter(x->createOfferRequest.isWithinRange(x.getCreateTimestamp())).mapToInt(x -> (Math.round(x.getDp())) * x.getQuantity()).sum();
781
            qtyAmountModel = new QtyAmountModel(totalBaseQty, totalBaseValue);
782
            if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
783
                Map<Integer, Integer> inventoryItemValueMap = new HashMap<>();
784
                for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
785
                    fofoOrderItem.getFofoLineItems().stream().filter(x -> x.getSerialNumber() != null).forEach(
786
                            lineItem -> {
787
                                if (activatedImeisActivationDateMap == null || activatedImeisActivationDateMap.containsKey(lineItem.getSerialNumber())) {
788
                                    inventoryItemValueMap.put(lineItem.getInventoryItemId(), (int) fofoOrderItem.getDp());
789
                                }
790
                            }
791
                    );
792
                }
793
                qtyAmountModel.setActivationQty(inventoryItemValueMap.size());
794
                qtyAmountModel.setActivationAmount(inventoryItemValueMap.entrySet().stream().collect(Collectors.summingInt(x -> x.getValue())));
795
                qtyAmountMap.put(0, qtyAmountModel);
796
            }
797
        }
798
 
799
        //As of now eligible sale is considered to be without special criteria like brand/
800
        //CriteriaPayoutWise
801
        for (ItemCriteriaPayout itemCriteriaPayout : createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts()) {
802
            int criteriaId = itemCriteriaPayout.getItemCriteria().getId();
803
            Map<Integer, List<FofoOrderItem>> ordersMap = criteriaPartnerwiseTertiary.get(criteriaId);
804
            //Partywise iteration
805
            QtyAmountModel qtyAmountModel1 = new QtyAmountModel(0, 0);
806
            qtyAmountMap.put(criteriaId, qtyAmountModel1);
807
            List<FofoOrderItem> fofoOrderItems = ordersMap.get(fofoId) == null ? null : ordersMap.get(fofoId);
808
            if (fofoOrderItems != null && fofoOrderItems.size() > 0) {
809
                int totalQty = fofoOrderItems.stream().collect(Collectors.summingInt(x -> (x.getQuantity())));
810
                int totalValue = fofoOrderItems.stream().collect(Collectors.summingInt(x -> Math.round(x.getDp()) * (x.getQuantity())));
811
                int eligibleQty = totalQty;
812
                int eligibleValue = totalValue;
813
                qtyAmountModel1.setQty(totalQty);
814
                qtyAmountModel1.setAmount(totalValue);
815
                Map<FofoLineItem, Integer> lineItemValueMap = new HashMap<>();
816
                if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
817
                    for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
818
                        fofoOrderItem.getFofoLineItems().stream().filter(x -> x.getSerialNumber() != null).forEach(
819
                                lineItem -> {
820
                                    if (activatedImeisActivationDateMap == null) {
821
                                        lineItemValueMap.put(lineItem, (int) fofoOrderItem.getDp());
822
 
823
                                    } else if (activatedImeisActivationDateMap.containsKey(lineItem.getSerialNumber())) {
824
                                        if (itemCriteriaPayout.isWithinRange(activatedImeisActivationDateMap.get(lineItem.getSerialNumber()))) {
825
                                            lineItemValueMap.put(lineItem, (int) fofoOrderItem.getDp());
826
                                        }
827
                                    }
828
                                }
829
                        );
830
                    }
831
                    eligibleQty = lineItemValueMap.size();
832
                    eligibleValue = lineItemValueMap.entrySet().stream().collect(Collectors.summingInt(x -> x.getValue()));
833
                    qtyAmountModel1.setActivationQty(eligibleQty);
834
                    qtyAmountModel1.setActivationAmount(eligibleValue);
835
                }
836
                qtyAmountMap.put(criteriaId, qtyAmountModel1);
837
 
838
                int eligibleBaseQty = eligibleQty;
839
                int eligibleBaseValue = eligibleValue;
840
                if (createOfferRequest.isBaseCriteria()) {
841
                    eligibleBaseQty = qtyAmountModel.getActivationQty();
842
                    eligibleBaseValue = (int) qtyAmountModel.getActivationAmount();
843
                }
844
 
845
 
846
                int eligibleSale = eligibleBaseValue;
847
                int eligibleCriteriaSale = eligibleValue;
848
                int eligibleCriteriaSaleDp = eligibleValue;
849
 
850
                if (createOfferRequest.getTargetType().equals(AchievementType.QUANTITY)) {
851
                    eligibleSale = eligibleBaseQty;
852
                    eligibleCriteriaSale = eligibleQty;
853
                }
854
 
855
                float eligiblePayoutValue = 0;
856
                double finalPayout = 0;
857
 
858
                PayoutSlab eligibleSlab = null;
859
                for (PayoutSlab slab : itemCriteriaPayout.getPayoutSlabs()) {
860
                    if (slab.getOnwardsAmount() <= eligibleSale) {
861
                        eligibleSlab = slab;
862
                    } else {
863
                        break;            // slabs beyond this don't qualify
864
                    }
865
                }
866
                if(eligibleSlab != null) {
867
                    eligibleSlab.setSelected(true);
868
                    LOGGER.info("Eligible Slab {}", eligibleSlab);
869
                }
870
 
871
                if (AmountType.PERCENTAGE.equals(itemCriteriaPayout.getAmountType())) {
872
                    finalPayout = (eligiblePayoutValue * eligibleCriteriaSaleDp) / 100;
873
                } else if (AmountType.FIXED.equals(itemCriteriaPayout.getAmountType())) {
874
                    finalPayout = eligiblePayoutValue * eligibleCriteriaSale;
875
                } else {
876
                    finalPayout = eligiblePayoutValue;
877
                }
878
                qtyAmountModel1.setFinalPayout(finalPayout);
879
                LOGGER.info("Final Payout - {}", finalPayout);
880
            }
881
 
882
 
883
        }
884
        return qtyAmountMap;
885
    }
886
 
31920 amit.gupta 887
    @Override
888
    public void processActivationtOffer(CreateOfferRequest createOfferRequest) throws ProfitMandiBusinessException {
889
        List<OfferPayout> offerPayouts = offerPayoutRepository.selectAllByOfferId(createOfferRequest.getId());
890
        List<ItemCriteriaPayout> itemCriteriaPayouts = createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts();
891
        Map<Integer, ItemCriteriaPayout> itemCriteriaPayoutMap = itemCriteriaPayouts.stream().collect(Collectors.toMap(x -> x.getItemCriteria().getId(), x -> x));
31923 amit.gupta 892
        LOGGER.info("itemCriteriaPayoutMap {}", itemCriteriaPayoutMap);
893
        LOGGER.info("offerPayouts {}", offerPayouts);
31924 amit.gupta 894
        Map<Integer, Map<Integer, Double>> fixedSlabCriteriaPartnerMap = offerPayouts.stream().filter(x -> itemCriteriaPayoutMap.get((int) x.getCriteriaId()).getAmountType().equals(AmountType.SLAB_FIXED))
31920 amit.gupta 895
                .collect(Collectors.groupingBy(x -> (int) x.getCriteriaId(), Collectors.groupingBy(x -> (int) x.getFofoId(), Collectors.summingDouble(x -> x.getSlabAmount()))));
896
 
897
 
898
        Map<String, Double> serialNumberPaid = offerPayouts.stream().filter(x -> x.getRejectTimestamp() == null).collect(Collectors.groupingBy(x -> x.getSerialNumber(), Collectors.summingDouble(x -> x.getSlabAmount())));
899
        Map<Integer, Map<Integer, List<FofoOrderItem>>> criteriaPartnerwiseTertiary = offerRepository.getCriteriaWisePartnerTertiary(createOfferRequest);
900
 
33087 amit.gupta 901
        Map<String, AgeingSummaryModel> ageingSummaryModelsMap = null;
33662 amit.gupta 902
        final Map<String, LocalDateTime> activatedImeisActivationDateMap;
34217 amit.gupta 903
        //Find Only eligible imeis if any
904
        List<String> imeisAllowedManually = offerEligibleImeiRepository.selectEligibleImeisByOfferId(createOfferRequest.getId());
905
 
31920 amit.gupta 906
        if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
907
            //All Serialnumbers for all eligible retailers
908
            List<String> serialNumbers = criteriaPartnerwiseTertiary.entrySet().stream().flatMap(x -> x.getValue().entrySet().stream().flatMap(foiList -> foiList.getValue().stream()))
909
                    .flatMap(y -> y.getFofoLineItems().stream()).filter(fli -> fli.getSerialNumber() != null)
910
                    .map(x -> x.getSerialNumber()).collect(Collectors.toList());
911
            if (serialNumbers.size() > 0) {
34217 amit.gupta 912
                if (imeisAllowedManually != null) {
913
                    serialNumbers = serialNumbers.stream().filter(x -> imeisAllowedManually.contains(x)).collect(Collectors.toList());
914
                }
33662 amit.gupta 915
                activatedImeisActivationDateMap = activatedImeiRepository.selectBySerialNumbers(serialNumbers).stream()
31920 amit.gupta 916
                        .filter(x -> createOfferRequest.isWithinRange(x.getActivationTimestamp()))
33441 amit.gupta 917
                        .collect(Collectors.toMap(x -> x.getSerialNumber(), x -> x.getActivationTimestamp()));
33613 amit.gupta 918
                ageingSummaryModelsMap = warehouseInventoryItemRepository.findStockAgeingByFofoIdSerialNumbers(0, serialNumbers).stream().collect(Collectors.toMap(x -> x.getSerialNumber(), x -> x, (u, v) -> v));
31920 amit.gupta 919
            } else {
33662 amit.gupta 920
                activatedImeisActivationDateMap = null;
31920 amit.gupta 921
            }
922
        } else {
33662 amit.gupta 923
            activatedImeisActivationDateMap = null;
31920 amit.gupta 924
        }
925
 
926
        Map<Integer, Integer> userBaseQtyMap = new HashMap<>();
927
        Map<Integer, Integer> userBaseValueMap = new HashMap<>();
928
        Map<Integer, Integer> eligibleBaseQtyMap = new HashMap<>();
929
        Map<Integer, Integer> eligibleBaseValueMap = new HashMap<>();
930
 
931
        if (createOfferRequest.isBaseCriteria()) {
932
            Map<Integer, List<FofoOrderItem>> foiMap = criteriaPartnerwiseTertiary.get(0);
933
            for (Map.Entry<Integer, List<FofoOrderItem>> orderEntry : foiMap.entrySet()) {
934
                int fofoId = orderEntry.getKey();
935
                List<FofoOrderItem> fofoOrderItems = orderEntry.getValue();
936
                int totalBaseQty = fofoOrderItems.stream().collect(Collectors.summingInt(x -> (x.getQuantity())));
937
                int totalBaseValue = fofoOrderItems.stream().collect(Collectors.summingInt(x -> (Math.round(x.getDp())) * x.getQuantity()));
938
                userBaseQtyMap.put(fofoId, totalBaseQty);
939
                userBaseValueMap.put(fofoId, totalBaseValue);
940
                if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
941
                    Map<Integer, Integer> inventoryItemValueMap = new HashMap<>();
942
                    for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
943
                        fofoOrderItem.getFofoLineItems().stream().filter(x -> x.getSerialNumber() != null).forEach(
944
                                lineItem -> {
33662 amit.gupta 945
                                    if (activatedImeisActivationDateMap == null || activatedImeisActivationDateMap.containsKey(lineItem.getSerialNumber())) {
31920 amit.gupta 946
                                        inventoryItemValueMap.put(lineItem.getInventoryItemId(), (int) fofoOrderItem.getDp());
947
                                    }
948
                                }
949
                        );
950
                    }
951
                    eligibleBaseQtyMap.put(fofoId, inventoryItemValueMap.size());
952
                    eligibleBaseValueMap.put(fofoId, inventoryItemValueMap.entrySet().stream().collect(Collectors.summingInt(x -> x.getValue())));
953
                } else {
954
                    eligibleBaseQtyMap.put(fofoId, totalBaseQty);
955
                    eligibleBaseValueMap.put(fofoId, totalBaseValue);
956
 
957
                }
958
 
959
            }
960
        }
961
 
962
        //As of now eligible sale is considered to be without special criteria like brand/
33441 amit.gupta 963
        //CriteriaPayoutWise
31920 amit.gupta 964
        for (ItemCriteriaPayout itemCriteriaPayout : createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts()) {
965
            int criteriaId = itemCriteriaPayout.getItemCriteria().getId();
966
            Map<Integer, List<FofoOrderItem>> ordersMap = criteriaPartnerwiseTertiary.get(criteriaId);
33441 amit.gupta 967
            //Partywise iteration
31920 amit.gupta 968
            for (Map.Entry<Integer, List<FofoOrderItem>> orderEntry : ordersMap.entrySet()) {
31992 amit.gupta 969
                double totalRolloutAmount = 0;
31920 amit.gupta 970
                int fofoId = orderEntry.getKey();
971
                List<FofoOrderItem> fofoOrderItems = orderEntry.getValue();
972
                OfferRowModel offerRowModel = new OfferRowModel();
973
                int totalQty = fofoOrderItems.stream().collect(Collectors.summingInt(x -> (x.getQuantity())));
974
                int totalValue = fofoOrderItems.stream().collect(Collectors.summingInt(x -> Math.round(x.getDp()) * (x.getQuantity())));
975
                int eligibleQty = totalQty;
976
                int eligibleValue = totalValue;
977
                Map<FofoLineItem, Integer> lineItemValueMap = new HashMap<>();
978
                if (createOfferRequest.getSchemeType().equals(OfferSchemeType.ACTIVATION)) {
979
                    for (FofoOrderItem fofoOrderItem : fofoOrderItems) {
980
                        fofoOrderItem.getFofoLineItems().stream().filter(x -> x.getSerialNumber() != null).forEach(
981
                                lineItem -> {
33662 amit.gupta 982
                                    if (activatedImeisActivationDateMap == null) {
31920 amit.gupta 983
                                        lineItemValueMap.put(lineItem, (int) fofoOrderItem.getDp());
33441 amit.gupta 984
 
33662 amit.gupta 985
                                    } else if (activatedImeisActivationDateMap.containsKey(lineItem.getSerialNumber())) {
986
                                        if (itemCriteriaPayout.isWithinRange(activatedImeisActivationDateMap.get(lineItem.getSerialNumber()))) {
33441 amit.gupta 987
                                            lineItemValueMap.put(lineItem, (int) fofoOrderItem.getDp());
988
                                        }
31920 amit.gupta 989
                                    }
33441 amit.gupta 990
 
31920 amit.gupta 991
                                }
992
                        );
993
                    }
994
                    eligibleQty = lineItemValueMap.size();
995
                    eligibleValue = lineItemValueMap.entrySet().stream().collect(Collectors.summingInt(x -> x.getValue()));
996
                    offerRowModel.setEligibleImeis(lineItemValueMap.keySet().stream().map(x -> x.getSerialNumber()).collect(Collectors.toList()));
997
                }
998
 
999
                int totalBaseQty = totalQty;
1000
                int totalBaseValue = totalValue;
1001
                int eligibleBaseQty = eligibleQty;
1002
                int eligibleBaseValue = eligibleValue;
1003
                if (createOfferRequest.isBaseCriteria()) {
1004
                    totalBaseQty = userBaseQtyMap.get(fofoId) == null ? 0 : userBaseQtyMap.get(fofoId);
1005
                    totalBaseValue = userBaseValueMap.get(fofoId) == null ? 0 : userBaseValueMap.get(fofoId);
1006
                    eligibleBaseQty = eligibleBaseQtyMap.get(fofoId) == null ? 0 : eligibleBaseQtyMap.get(fofoId);
1007
                    eligibleBaseValue = eligibleBaseValueMap.get(fofoId) == null ? 0 : eligibleBaseValueMap.get(fofoId);
1008
                }
1009
 
1010
 
1011
                int totalSale = totalBaseValue;
1012
                int eligibleSale = eligibleBaseValue;
1013
                int eligibleCriteriaSale = eligibleValue;
1014
                int eligibleCriteriaSaleDp = eligibleValue;
1015
 
1016
                if (createOfferRequest.getTargetType().equals(AchievementType.QUANTITY)) {
1017
                    totalSale = totalBaseQty;
1018
                    eligibleSale = eligibleBaseQty;
1019
                    eligibleCriteriaSale = eligibleQty;
1020
                }
1021
 
1022
                offerRowModel.setTotalSale(totalSale);
1023
                offerRowModel.setEligibleSale(eligibleSale);
1024
                float eligiblePayoutValue = 0;
33662 amit.gupta 1025
                float previousPayoutValue = 0;
32345 amit.gupta 1026
                double finalPayout;
31920 amit.gupta 1027
                for (PayoutSlab payoutSlab : itemCriteriaPayout.getPayoutSlabs()) {
1028
                    if (payoutSlab.getOnwardsAmount() <= eligibleSale) {
32039 amit.gupta 1029
                        LOGGER.info("Eligible Sale {}", eligibleSale);
31920 amit.gupta 1030
                        offerRowModel.setPayoutTargetAchieved(payoutSlab.getOnwardsAmount());
1031
                        eligiblePayoutValue = payoutSlab.getPayoutAmount();
33662 amit.gupta 1032
                        previousPayoutValue = Math.min(eligiblePayoutValue, previousPayoutValue);
31920 amit.gupta 1033
                        offerRowModel.setPayoutValue(eligiblePayoutValue);
33662 amit.gupta 1034
                    } else {
1035
                        break;
31920 amit.gupta 1036
                    }
1037
                }
1038
                if (AmountType.PERCENTAGE.equals(itemCriteriaPayout.getAmountType())) {
1039
                    finalPayout = (eligiblePayoutValue * eligibleCriteriaSaleDp) / 100;
1040
                } else if (AmountType.FIXED.equals(itemCriteriaPayout.getAmountType())) {
1041
                    finalPayout = eligiblePayoutValue * eligibleCriteriaSale;
1042
                } else {
32039 amit.gupta 1043
                    Map<Integer, Double> fofoCriteriaMap = fixedSlabCriteriaPartnerMap.get(criteriaId);
1044
                    LOGGER.info("fofoCriteriaMap {}", fofoCriteriaMap);
31920 amit.gupta 1045
                    finalPayout = eligiblePayoutValue;
1046
                    if (fofoCriteriaMap != null) {
1047
                        if (fofoCriteriaMap.containsKey(fofoId)) {
33662 amit.gupta 1048
                            //double totalPayout = fofoCriteriaMap.get(fofoId);
1049
                            finalPayout = eligiblePayoutValue - previousPayoutValue;
32039 amit.gupta 1050
                            if (Math.abs(finalPayout) < Utils.DOUBLE_EPSILON) {
31920 amit.gupta 1051
                                finalPayout = 0;
32039 amit.gupta 1052
                            }
31920 amit.gupta 1053
                        }
1054
                    }
1055
                }
1056
 
32039 amit.gupta 1057
                LOGGER.info("Final Payout - {}", finalPayout);
1058
 
31920 amit.gupta 1059
                if (finalPayout > 0) {
1060
                    List<Integer> inventoryItemIds = lineItemValueMap.keySet().stream().map(x -> x.getInventoryItemId()).collect(Collectors.toList());
33662 amit.gupta 1061
                    int totalDpValue = lineItemValueMap.values().stream().collect(Collectors.summingInt(x -> x));
1062
                    LOGGER.info("Total DP Value {}", totalDpValue);
31920 amit.gupta 1063
                    Map<Integer, InventoryItem> inventoryItemsMap = inventoryItemRepository.selectAllByIds(inventoryItemIds).stream().collect(Collectors.toMap(x -> x.getId(), x -> x));
1064
                    for (Map.Entry<FofoLineItem, Integer> lineItemValueEntry : lineItemValueMap.entrySet()) {
33087 amit.gupta 1065
                        FofoLineItem fofoLineItem = lineItemValueEntry.getKey();
31920 amit.gupta 1066
                        double amount = 0;
1067
                        if (AmountType.SLAB_FIXED.equals(itemCriteriaPayout.getAmountType())) {
32039 amit.gupta 1068
                            amount = (eligiblePayoutValue * lineItemValueEntry.getValue()) / totalDpValue;
31920 amit.gupta 1069
                        } else {
33662 amit.gupta 1070
                            if (ageingSummaryModelsMap.containsKey(fofoLineItem.getSerialNumber())) {
35394 amit 1071
                                if (ageingSummaryModelsMap.get(fofoLineItem.getSerialNumber()).isAgedAbove(STOCK_AGEING_THRESHOLD_DAYS)) {
33662 amit.gupta 1072
                                    continue;
1073
                                }
1074
                            }
31920 amit.gupta 1075
                            amount = eligiblePayoutValue;
1076
                        }
33662 amit.gupta 1077
                        if (serialNumberPaid.containsKey(fofoLineItem.getSerialNumber())) {
1078
                            amount = amount - serialNumberPaid.get(fofoLineItem.getSerialNumber());
1079
                        }
32039 amit.gupta 1080
                        LOGGER.info("Amount - {}", amount);
31920 amit.gupta 1081
                        //ignore reasonably small
1082
                        if (amount < Utils.DOUBLE_EPSILON) continue;
1083
                        AmountModel amountModel = new AmountModel();
1084
                        amountModel.setAmountType(itemCriteriaPayout.getAmountType());
1085
                        amountModel.setAmount(amount);
32021 amit.gupta 1086
                        amountModel.setDiscount(createOfferRequest.isDiscount());
33087 amit.gupta 1087
                        InventoryPayoutModel inventoryPayoutModel = priceCircularService.getPayouts(inventoryItemsMap.get(fofoLineItem.getInventoryItemId()));
31920 amit.gupta 1088
                        double rolloutAmount = inventoryPayoutModel.getRolloutAmount(amountModel);
1089
                        totalRolloutAmount += rolloutAmount;
1090
 
33087 amit.gupta 1091
                        OfferPayout offerPayout = new OfferPayout(fofoId, createOfferRequest.getId(), criteriaId, amount, fofoLineItem.getSerialNumber(), rolloutAmount, SchemePayoutStatus.CREDITED, createOfferRequest.getDescription(), LocalDateTime.now());
33459 amit.gupta 1092
                        offerPayout.setInventoryItemId(fofoLineItem.getInventoryItemId());
31920 amit.gupta 1093
                        offerPayoutRepository.persist(offerPayout);
1094
                    }
32039 amit.gupta 1095
                    walletService.addAmountToWallet((int) fofoId, createOfferRequest.getId(), WalletReferenceType.ADDITIONAL_SCHEME, createOfferRequest.getDescription(), (float) totalRolloutAmount, LocalDateTime.now());
31920 amit.gupta 1096
                }
1097
            }
1098
        }
1099
        Offer offer = offerRepository.selectById(createOfferRequest.getId());
1100
        offer.setProcessedTimestamp(LocalDateTime.now());
1101
    }
1102
 
1103
    @Override
1104
    public void processSellin(CreateOfferRequest createOfferRequest) throws Exception {
1105
 
1106
        //List<OfferRowModel> offerRowModels = new ArrayList<>();
1107
        List<OfferPayout> offerPayouts = offerPayoutRepository.selectAllByOfferId(createOfferRequest.getId());
32345 amit.gupta 1108
        Map<String, Double> serialNumberPaid = offerPayouts.stream().filter(x -> x.getRejectTimestamp() == null).collect(Collectors.groupingBy(x -> x.getSerialNumber(), Collectors.summingDouble(x -> x.getSlabAmount())));
34072 ranu 1109
        LOGGER.info("serialNumberPaid {}", serialNumberPaid);
32345 amit.gupta 1110
        List<ItemCriteriaPayout> itemCriteriaPayouts = createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts();
1111
        Map<Integer, ItemCriteriaPayout> itemCriteriaPayoutMap = itemCriteriaPayouts.stream().collect(Collectors.toMap(x -> x.getItemCriteria().getId(), x -> x));
1112
        Map<Integer, Map<Integer, Double>> fixedSlabCriteriaPartnerMap = offerPayouts.stream().filter(x -> itemCriteriaPayoutMap.get((int) x.getCriteriaId()).getAmountType().equals(AmountType.SLAB_FIXED))
1113
                .collect(Collectors.groupingBy(x -> (int) x.getCriteriaId(), Collectors.groupingBy(x -> (int) x.getFofoId(), Collectors.summingDouble(x -> x.getSlabAmount()))));
31920 amit.gupta 1114
        Set<Long> fofoIds = offerPayouts.stream().map(x -> x.getFofoId()).collect(Collectors.toSet());
1115
 
1116
        Map<Integer, Map<Integer, List<Order>>> criteriaOrdersMap = offerRepository.getPartnerWiseSellin(createOfferRequest, true);
1117
 
32345 amit.gupta 1118
 
31920 amit.gupta 1119
        Map<Integer, List<Order>> userBaseCriteriaOrdersMap = null;
1120
        if (criteriaOrdersMap.get(0) != null && criteriaOrdersMap.get(0).size() > 0) {
1121
            userBaseCriteriaOrdersMap = criteriaOrdersMap.get(0).entrySet().stream()
1122
                    .filter(x -> !fofoIds.contains(x.getKey())).collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
1123
        }
1124
 
32345 amit.gupta 1125
 
31920 amit.gupta 1126
        Map<Integer, Integer> userBaseQtyMap = null;
1127
        Map<Integer, Integer> userBaseValueMap = null;
1128
        if (userBaseCriteriaOrdersMap != null) {
1129
            userBaseQtyMap = new HashMap<>();
1130
            userBaseValueMap = new HashMap<>();
1131
            for (Map.Entry<Integer, List<Order>> orderEntry : userBaseCriteriaOrdersMap.entrySet()) {
1132
                int fofoId = orderEntry.getKey();
1133
                List<Order> orders = orderEntry.getValue();
1134
                int totalBaseQty = orders.stream().collect(Collectors.summingInt(x -> (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty())));
1135
                int totalBaseValue = orders.stream().collect(Collectors.summingInt(x ->
1136
                        Math.round(x.getLineItem().getUnitPrice() * (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty()))
1137
                ));
1138
                userBaseQtyMap.put(fofoId, totalBaseQty);
1139
                userBaseValueMap.put(fofoId, totalBaseValue);
1140
            }
1141
        }
1142
        LOGGER.info("Base Qty Map - {}", userBaseQtyMap);
1143
        LOGGER.info("Base Value Map - {}", userBaseValueMap);
1144
 
1145
        LOGGER.info("Processing sellin");
1146
        List<OfferPayout> offerPayoutsNew = new ArrayList<>();
1147
        for (ItemCriteriaPayout itemCriteriaPayout : createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts()) {
1148
            int criteriaId = itemCriteriaPayout.getItemCriteria().getId();
1149
            Map<Integer, List<Order>> ordersMap = criteriaOrdersMap.get(criteriaId).entrySet().stream()
1150
                    .filter(x -> !fofoIds.contains(x.getKey())).collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
1151
            for (Map.Entry<Integer, List<Order>> orderEntry : ordersMap.entrySet()) {
1152
                int fofoId = orderEntry.getKey();
1153
                //CustomRetailer retailer = retailerService.getAllFofoRetailers().get(fofoId);
1154
                List<Order> orders = orderEntry.getValue();
32345 amit.gupta 1155
                //Set<String> returnedSerialNumbers = orders.stream().filter(x -> x.getSerialNumber() != null).flatMap(x -> x.getReturnedImeis().stream()).collect(Collectors.toSet());
31920 amit.gupta 1156
                int totalQty = orders.stream().collect(Collectors.summingInt(x -> (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty())));
1157
                int totalValue = orders.stream().collect(Collectors.summingInt(x -> Math.round(x.getLineItem().
1158
                        getUnitPrice() * (x.getLineItem().getQuantity() - x.getLineItem().getReturnQty()))));
1159
                int totalBaseQty = totalQty;
1160
                int totalBaseValue = totalValue;
1161
                if (userBaseCriteriaOrdersMap != null) {
1162
                    if (userBaseQtyMap.containsKey(fofoId)) {
1163
                        totalBaseQty = userBaseQtyMap.get(fofoId);
1164
                        totalBaseValue = userBaseValueMap.get(fofoId);
1165
                    } else {
1166
                        continue;
1167
                    }
1168
                }
1169
 
1170
                int purchasedValue;
1171
                if (createOfferRequest.getTargetType().equals(AchievementType.VALUE)) {
1172
                    purchasedValue = totalBaseValue;
1173
                } else {
1174
                    purchasedValue = totalBaseQty;
1175
                }
1176
 
33695 amit.gupta 1177
                PayoutSlab eligibleSlab = null;
33662 amit.gupta 1178
 
1179
                for (PayoutSlab payoutSlab : itemCriteriaPayout.getPayoutSlabs()) {
1180
                    if (payoutSlab.getOnwardsAmount() <= purchasedValue) {
1181
                        eligibleSlab = payoutSlab;
1182
                    } else {
1183
                        break;
1184
                    }
1185
                }
33695 amit.gupta 1186
                if (eligibleSlab == null) continue;
31920 amit.gupta 1187
                List<Integer> orderIds = orders.stream().map(x -> x.getId()).collect(Collectors.toList());
1188
                Map<Integer, LineItem> lineItemMap = orders.stream().collect(Collectors.toMap(x -> x.getLineItem().getId(), x -> x.getLineItem()));
1189
                List<WarehouseScan> warehouseScans = warehouseScanRepository.selectAllByOrderIds(orderIds);
32540 amit.gupta 1190
                LOGGER.info("Warehosue scans --> {}", warehouseScans);
32345 amit.gupta 1191
                List<Integer> warehouseInventoryItemIds = warehouseScans.stream().collect(Collectors.groupingBy(x -> x.getInventoryItemId())).entrySet()
31920 amit.gupta 1192
                        .stream().filter(x -> x.getValue().size() == 1).map(x -> x.getKey()).collect(Collectors.toList());
32795 amit.gupta 1193
 
1194
                List<OfferPayout> partnerPayouts = offerPayouts.stream().filter(x -> x.getFofoId() == fofoId).collect(Collectors.toList());
32868 amit.gupta 1195
                Set<String> serialNumbersRejected = partnerPayouts.stream().filter(x -> x.getStatus().equals(SchemePayoutStatus.REJECTED)).map(x -> x.getSerialNumber()).collect(Collectors.toSet());
32795 amit.gupta 1196
 
34092 amit.gupta 1197
                Set<String> billedNotCancelledSerialNumbers;
32345 amit.gupta 1198
                LOGGER.info("warehouseInventoryItemIds {}", warehouseInventoryItemIds);
1199
                if (warehouseInventoryItemIds.size() > 0) {
1200
                    List<WarehouseInventoryItem> warehouseInventoryItems = warehouseInventoryItemRepository.selectAllByIds(warehouseInventoryItemIds);
34092 amit.gupta 1201
                    billedNotCancelledSerialNumbers = warehouseInventoryItems.stream().map(x -> x.getSerialNumber()).collect(Collectors.toSet());
31920 amit.gupta 1202
                } else {
34092 amit.gupta 1203
                    billedNotCancelledSerialNumbers = new HashSet<>();
31920 amit.gupta 1204
                }
34092 amit.gupta 1205
                LOGGER.info("billedNotCancelledSerialNumbers {}", billedNotCancelledSerialNumbers);
1206
 
31920 amit.gupta 1207
                Map<String, LineItem> serialNumberMap = lineItemImeisRepository.selectByLineItemIds(new ArrayList<>(lineItemMap.keySet()))
32868 amit.gupta 1208
                        .stream().filter(x -> !serialNumbersRejected.contains(x.getSerialNumber())).collect(Collectors.toMap(x -> x.getSerialNumber(), x -> lineItemMap.get(x.getLineItemId()), (x1, x2) -> x1.getId() > x2.getId() ? x1 : x2));
31920 amit.gupta 1209
 
34226 amit.gupta 1210
                List<String> manuallyEligibleImeis = offerEligibleImeiRepository.selectEligibleImeisByOfferId(createOfferRequest.getId());
32795 amit.gupta 1211
 
34092 amit.gupta 1212
                serialNumberMap = serialNumberMap.entrySet().stream().filter(x -> billedNotCancelledSerialNumbers.contains(x.getKey())).collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
34231 amit.gupta 1213
 
1214
                //Just a validation need to revaluate this
1215
                Map<String, InventoryItem> serialNumberInventoryItemMap = this.getInventoryItemMap(fofoId, serialNumberMap);
1216
                if (serialNumberInventoryItemMap.size() < billedNotCancelledSerialNumbers.size()) continue;
1217
 
34623 amit.gupta 1218
                LOGGER.info("serialNumberMap {}", serialNumberMap);
34226 amit.gupta 1219
                if (manuallyEligibleImeis != null) {
34227 amit.gupta 1220
                    serialNumberMap = serialNumberMap.entrySet().stream().filter(x -> manuallyEligibleImeis.contains(x.getKey())).collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue()));
34624 amit.gupta 1221
                    if (serialNumberMap.size() == 0) continue;
34231 amit.gupta 1222
                    serialNumberInventoryItemMap = this.getInventoryItemMap(fofoId, serialNumberMap);
34226 amit.gupta 1223
                }
32543 amit.gupta 1224
                if (serialNumberMap.size() == 0) continue;
32064 amit.gupta 1225
                //Continue if all imeis havent been grned
1226
 
32345 amit.gupta 1227
 
33662 amit.gupta 1228
                float eligiblePayoutValue = eligibleSlab.getPayoutAmount();
32345 amit.gupta 1229
                double finalPayout;
1230
                if (AmountType.PERCENTAGE.equals(itemCriteriaPayout.getAmountType())) {
1231
                    finalPayout = (eligiblePayoutValue * purchasedValue) / 100;
1232
                } else if (AmountType.FIXED.equals(itemCriteriaPayout.getAmountType())) {
1233
                    finalPayout = eligiblePayoutValue * purchasedValue;
1234
                } else {
33695 amit.gupta 1235
                    Map<Integer, Double> fofoCriteriaPayoutMap = fixedSlabCriteriaPartnerMap.get(criteriaId);
1236
                    LOGGER.info("fofoCriteriaMap {}", fofoCriteriaPayoutMap);
32345 amit.gupta 1237
                    finalPayout = eligiblePayoutValue;
33695 amit.gupta 1238
                    if (fofoCriteriaPayoutMap != null && fofoCriteriaPayoutMap.containsKey(fofoId)) {
1239
                        finalPayout = eligiblePayoutValue - fofoCriteriaPayoutMap.get(fofoId);
1240
                        if (Math.abs(finalPayout) < Utils.DOUBLE_EPSILON) {
1241
                            finalPayout = 0;
32345 amit.gupta 1242
                        }
31920 amit.gupta 1243
                    }
1244
                }
32345 amit.gupta 1245
 
1246
                LOGGER.info("Or - {}", finalPayout);
1247
 
1248
                if (finalPayout > 0) {
1249
                    double totalRolloutAmount = 0;
1250
                    int totalDpValue = serialNumberInventoryItemMap.entrySet().stream().mapToInt(x -> (int) x.getValue().getUnitPrice()).sum();
1251
                    for (Map.Entry<String, InventoryItem> serialNumberInventoryItemEntry : serialNumberInventoryItemMap.entrySet()) {
1252
                        double amount = 0;
1253
                        LOGGER.info("Total DP Value {}", totalDpValue);
1254
                        if (AmountType.SLAB_FIXED.equals(itemCriteriaPayout.getAmountType())) {
1255
                            amount = (eligiblePayoutValue * serialNumberInventoryItemEntry.getValue().getUnitPrice()) / totalDpValue;
1256
                            LOGGER.info("Amount - {}", amount);
1257
                        } else {
1258
                            amount = eligiblePayoutValue;
1259
                            if (serialNumberPaid.containsKey(serialNumberInventoryItemEntry.getKey())) {
34073 ranu 1260
                                LOGGER.info("serial number slab amount {}", serialNumberPaid.get(serialNumberInventoryItemEntry.getKey()));
32345 amit.gupta 1261
                                amount = amount - serialNumberPaid.get(serialNumberInventoryItemEntry.getKey());
1262
                            }
1263
                        }
1264
                        LOGGER.info("Amount - {}", amount);
1265
                        //ignore reasonably small
33662 amit.gupta 1266
                        if (Math.abs(amount) < Utils.DOUBLE_EPSILON) continue;
32345 amit.gupta 1267
                        AmountModel amountModel = new AmountModel();
1268
                        amountModel.setAmountType(itemCriteriaPayout.getAmountType());
1269
                        amountModel.setAmount(amount);
1270
                        amountModel.setDiscount(createOfferRequest.isDiscount());
1271
                        InventoryPayoutModel inventoryPayoutModel = priceCircularService.getPayouts(serialNumberInventoryItemEntry.getValue());
1272
                        double rolloutAmount = inventoryPayoutModel.getRolloutAmount(amountModel);
1273
                        totalRolloutAmount += rolloutAmount;
1274
 
1275
                        OfferPayout offerPayout = new OfferPayout(fofoId, createOfferRequest.getId(), criteriaId, amount, serialNumberInventoryItemEntry.getKey(), rolloutAmount, SchemePayoutStatus.CREDITED, createOfferRequest.getDescription(), LocalDateTime.now());
33459 amit.gupta 1276
                        offerPayout.setInventoryItemId(serialNumberInventoryItemEntry.getValue().getId());
32345 amit.gupta 1277
                        offerPayoutRepository.persist(offerPayout);
1278
                    }
34623 amit.gupta 1279
                    walletService.addAmountToWallet(fofoId, createOfferRequest.getId(), WalletReferenceType.ADDITIONAL_SCHEME, createOfferRequest.getDescription(), (float) totalRolloutAmount, LocalDateTime.now());
32345 amit.gupta 1280
                }
31920 amit.gupta 1281
            }
1282
        }
1283
        Offer offer = offerRepository.selectById(createOfferRequest.getId());
1284
        offer.setProcessedTimestamp(LocalDateTime.now());
1285
    }
32064 amit.gupta 1286
 
33441 amit.gupta 1287
    private void rollbackPayout(int fofoId, int offerId, List<
1288
            OfferPayout> partnerPayouts, Set<String> returnedSerialNumbers) throws ProfitMandiBusinessException {
32795 amit.gupta 1289
        LOGGER.info("Rollback payout called for offerId {}", offerId);
1290
        float amountToRollback = 0;
1291
        int totalImeis = 0;
1292
        for (OfferPayout partnerPayout : partnerPayouts) {
1293
            LOGGER.info("serialNumberInventoryItemMap - {}", returnedSerialNumbers);
1294
            LOGGER.info("Serial Number - {}", partnerPayout.getSerialNumber());
1295
            if (returnedSerialNumbers.contains(partnerPayout.getSerialNumber()) && partnerPayout.getStatus().equals(SchemePayoutStatus.CREDITED)) {
1296
                partnerPayout.setRejectTimestamp(LocalDateTime.now());
1297
                partnerPayout.setStatus(SchemePayoutStatus.REJECTED);
1298
                amountToRollback += partnerPayout.getAmount();
1299
                totalImeis += 1;
1300
            }
1301
        }
1302
        if (amountToRollback > 0) {
1303
            LOGGER.info("Amount to Rollback - {}", amountToRollback);
1304
            walletService.rollbackAmountFromWallet(fofoId, amountToRollback, offerId, WalletReferenceType.ADDITIONAL_SCHEME, "Stock Returned, total " + totalImeis + "pc(s)", LocalDateTime.now());
1305
        }
1306
    }
1307
 
33441 amit.gupta 1308
    private Map<String, InventoryItem> getInventoryItemMap(int fofoId, Map<String, LineItem> serialNumberMap) throws
1309
            ProfitMandiBusinessException {
32064 amit.gupta 1310
        List<InventoryItem> inventoryItems = inventoryItemRepository.selectBySerialNumbers(serialNumberMap.keySet());
32345 amit.gupta 1311
        inventoryItems = inventoryItems.stream().filter(x -> x.getFofoId() == fofoId).collect(Collectors.toList());
1312
        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 1313
        return inventoryItemMap;
1314
    }
33030 amit.gupta 1315
 
1316
 
1317
    @Override
33247 ranu 1318
    public String getPartnerCriteriaString(PartnerCriteria partnerCriteria) throws ProfitMandiBusinessException {
33030 amit.gupta 1319
        StringBuilder sb = new StringBuilder();
1320
        if (partnerCriteria.getFofoIds().size() > 0) {
1321
            List<Integer> fofoIds = partnerCriteria.getFofoIds();
1322
            appendPartnerCodes(fofoIds, sb);
1323
 
1324
        } else {
1325
            sb.append("All");
1326
            if (partnerCriteria.getPartnerTypes().size() > 0) {
1327
                sb.append(" ").append(String.join(", ", partnerCriteria.getPartnerTypes().stream().map(x -> x.getValue()).collect(Collectors.toList())));
1328
            }
1329
            sb.append(" partners ");
1330
            if (partnerCriteria.getRegionIds().size() > 0) {
1331
                sb.append("from ");
1332
                sb.append(String.join(", ", partnerCriteria.getRegionIds().stream().map(x -> ProfitMandiConstants.WAREHOUSE_MAP.get(x)).collect(Collectors.toList())));
1333
            }
1334
            if (partnerCriteria.getExcludeFofoIds() != null && partnerCriteria.getExcludeFofoIds().size() > 0) {
35394 amit 1335
                sb.append("<b>excluding</b> ");
33030 amit.gupta 1336
                appendPartnerCodes(partnerCriteria.getExcludeFofoIds(), sb);
1337
            }
1338
        }
1339
        return sb.toString();
1340
    }
1341
 
33999 tejus.loha 1342
    @Override
1343
    public ByteArrayOutputStream createCSVOfferReport(CreateOfferRequest createOfferRequest) throws Exception {
1344
        List<List<?>> listOfRows = new ArrayList<>();
1345
        ByteArrayOutputStream baos = null;
1346
        Collection<OfferRowModel> offerRowModels = offerRepository.getOfferRows(createOfferRequest);
1347
        ItemCriteriaPayout itemCriteriaPayout = createOfferRequest.getTargetSlabs().get(0).getItemCriteriaPayouts().get(0);
35394 amit 1348
        // Batch fetch all retailers once to avoid N+1 queries
1349
        Map<Integer, CustomRetailer> allRetailers = retailerService.getAllFofoRetailers();
33999 tejus.loha 1350
        if (createOfferRequest.getSchemeType().equals(OfferSchemeType.SELLIN)) {
1351
            for (OfferRowModel offerRowModel : offerRowModels) {
35394 amit 1352
                CustomRetailer customRetailer = allRetailers.get(offerRowModel.getFofoId());
33999 tejus.loha 1353
                listOfRows.add(Arrays.asList(
1354
                        createOfferRequest.getId()
1355
                        , createOfferRequest.getName()
1356
                        , createOfferRequest.getTargetType()
1357
                        , createOfferRequest.getSchemeType()
1358
                        , itemCriteriaPayout.getStartDate()
1359
                        , itemCriteriaPayout.getEndDate()
1360
//                        , createOfferRequest.getBrandShareTerms()
1361
                        , createOfferRequest.getSellinPercentage()
1362
                        , "--"
1363
                        , createOfferRequest.getItemCriteriaString()
1364
                        , createOfferRequest.getStartDate()
1365
                        , createOfferRequest.getEndDate()
1366
                        , createOfferRequest.getCreatedOn()
1367
                        , customRetailer.getPartnerId()
1368
                        , customRetailer.getBusinessName()
1369
                        , customRetailer.getCode()
1370
                        , offerRowModel.getTotalBasePurchaseValue()
1371
                        , offerRowModel.getAchievedTarget()
1372
                        , offerRowModel.getPayoutPurchaseValue()
1373
                        , offerRowModel.getPayout()
1374
                        , offerRowModel.getPayoutType()
1375
                        , offerRowModel.getFinalPayout()
1376
                        , String.join(", ", offerRowModel.getEligibleImeis())));
1377
            }
1378
            baos = FileUtil.getCSVByteStream(
1379
                    Arrays.asList(
1380
                            "Id"
1381
                            , "Name"
1382
                            , "Target Type"
1383
                            , "Scheme Type"
1384
                            , "Payout Start"
1385
                            , "Payout End"
1386
//                            , "Brand %"
1387
                            , "Sellin %"
1388
                            , "Partner Criteria"
1389
                            , "Item Criteria"
1390
                            , "Start"
1391
                            , "End"
1392
                            , "Created"
1393
                            , "Partner Id"
1394
                            , "Partner Name"
1395
                            , "Partner Code"
1396
                            , "Base Purchase"
1397
                            , "Achieved Target"
1398
                            , "Eligible Purchase"
1399
                            , "Slab Amount"
1400
                            , "Slab Amount Type"
1401
                            , "Payout Value(Rs.)"
1402
                            , "Eligible IMEIs"
1403
                            , "Billing Pending Imeis"
1404
                    ), listOfRows);
1405
        } else {
1406
            for (OfferRowModel offerRowModel : offerRowModels) {
35394 amit 1407
                CustomRetailer customRetailer = allRetailers.get(offerRowModel.getFofoId());
33999 tejus.loha 1408
                listOfRows.add(Arrays.asList(
1409
                                createOfferRequest.getId()
1410
                                , createOfferRequest.getName()
1411
                                , createOfferRequest.getTargetType()
1412
                                , createOfferRequest.getSchemeType()
1413
                                , itemCriteriaPayout.getStartDate()
1414
                                , itemCriteriaPayout.getEndDate()
1415
//                                , createOfferRequest.getBrandShareTerms()
1416
                                , createOfferRequest.getSellinPercentage()
1417
                                , createOfferRequest.getPartnerCriteriaString()
1418
                                , createOfferRequest.getItemCriteriaString()
1419
                                , createOfferRequest.getStartDate()
1420
                                , createOfferRequest.getEndDate()
1421
                                , createOfferRequest.getCreatedOn()
1422
                                , customRetailer.getPartnerId()
1423
                                , customRetailer.getBusinessName()
1424
                                , customRetailer.getCode()
1425
                                , offerRowModel.getTotalSale()
1426
                                , offerRowModel.getEligibleSale()
1427
                                , offerRowModel.getPayoutTargetAchieved()
1428
                                , offerRowModel.getPayoutValue()
1429
                                , offerRowModel.getPayoutType()
1430
                                , offerRowModel.getPayoutValueDp()
1431
                                , offerRowModel.getFinalPayout()
1432
                                , String.join(", ", offerRowModel.getEligibleImeis())
1433
//                        ,String.join(", ", offerRowModel.getBaseCriteria())
1434
                        )
1435
                );
1436
            }
1437
            baos = FileUtil.getCSVByteStream(
1438
                    Arrays.asList(
1439
                            "Id"
1440
                            , "Name"
1441
                            , "Target Type"
1442
                            , "Scheme Type"
1443
                            , "Payout Start"
1444
                            , "Payout End"
1445
//                            , "Brand %"
1446
                            , "Sellin %"
1447
                            , "Partner Criteria"
1448
                            , "Item Criteria"
1449
                            , "Start"
1450
                            , "End"
1451
                            , "Created"
1452
                            , "Partner Id"
1453
                            , "Partner Name"
1454
                            , "Partner Code"
1455
                            , "Total Sale"
1456
                            , "Eligible Sale"
1457
                            , "Payout Target Achieved"
1458
                            , "Payout Amount"
1459
                            , "Payout Amount Type"
1460
                            , "Payout Value DP"
1461
                            , "Amount to be credited"
1462
                            , "Eligible Activated Imeis"
1463
                    ), listOfRows);
1464
        }
1465
        return baos;
1466
    }
1467
 
35205 amit 1468
    @Override
1469
    public void sendWhatsapp(Offer offer, List<Integer> fofoIds, String imageUrl) throws Exception {
1470
        if (fofoIds == null) {
1471
            fofoIds = fofoStoreRepository.selectActiveStores().stream().map(x -> x.getId()).collect(Collectors.toList());
1472
        }
1473
        final List<Integer> finalFofoIds = fofoIds;
1474
        //List<String> mobileNumbers = retailerService.getAllFofoRetailers().entrySet().stream().filter(x -> finalFofoIds.contains(x.getKey())).map(x -> x.getValue().getMobileNumber()).collect(Collectors.toList());
1475
        List<String> mobileNumbers = new ArrayList<>();
1476
        mobileNumbers.add("9911565032");
1477
        //mobileNumbers.add("9990381569");
1478
        //mobileNumbers.add("8383849914");
1479
        String message = "%s\n" +
1480
                "On %s of select models\n" +
1481
                "From %s to %s\n" +
1482
                "\n" +
1483
                "Happy Selling\n" +
1484
                "Team Smartdukaan";
1485
        //TV's mobile
1486
        for (String mobileNumber : mobileNumbers) {
1487
            notificationService.sendWhatsappMediaMessage(String.format(message, offer.getName(),
1488
                    offer.getSchemeType().toString(), FormattingUtils.formatDate(offer.getStartDate()),
1489
                    FormattingUtils.formatDate(offer.getEndDate())), mobileNumber, imageUrl, "offer-" + offer.getId() + ".png", WhatsappMessageType.IMAGE);
1490
        }
1491
    }
1492
 
33247 ranu 1493
    private void appendPartnerCodes(List<Integer> fofoIds, StringBuilder sb) throws ProfitMandiBusinessException {
33030 amit.gupta 1494
        Map<Integer, CustomRetailer> customRetailersMap = retailerService.getAllFofoRetailers();
33031 amit.gupta 1495
        List<String> businessNames = fofoIds.stream().map(x -> customRetailersMap.get(x)).filter(x -> x != null).map(x -> x.getBusinessName()).collect(Collectors.toList());
33030 amit.gupta 1496
        sb.append(String.join(", ", businessNames));
1497
    }
27877 amit.gupta 1498
}