Subversion Repositories SmartDukaan

Rev

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