Subversion Repositories SmartDukaan

Rev

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