Subversion Repositories SmartDukaan

Rev

Rev 27877 | Rev 28001 | Go to most recent revision | View as "text/plain" | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.spice.profitmandi.service.offers;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.gson.Gson;
import com.spice.profitmandi.common.exception.ProfitMandiBusinessException;
import com.spice.profitmandi.dao.entity.catalog.ItemCriteria;
import com.spice.profitmandi.dao.entity.catalog.Offer;
import com.spice.profitmandi.dao.entity.catalog.TargetSlab;
import com.spice.profitmandi.dao.model.CreateOfferRequest;
import com.spice.profitmandi.dao.model.ItemCriteriaPayout;
import com.spice.profitmandi.dao.repository.catalog.ItemCriteriaRepository;
import com.spice.profitmandi.dao.repository.catalog.ItemRepository;
import com.spice.profitmandi.dao.repository.catalog.OfferRepository;
import com.spice.profitmandi.dao.repository.catalog.OfferTargetSlabRepository;
import com.spice.profitmandi.service.user.RetailerService;

@Component
public class OfferServiceImpl implements OfferService {

        @Autowired
        private Gson gson;

        @Autowired
        private OfferRepository offerRepository;

        @Autowired
        private RetailerService retailerService;

        @Autowired
        private ItemCriteriaRepository itemCriteriaRepository;

        @Autowired
        private ItemRepository itemRepository;

        @Autowired
        private OfferTargetSlabRepository targetSlabRepository;

        private static final Logger LOGGER = LogManager.getLogger(OfferServiceImpl.class);

        @Override
        public void addOfferService(CreateOfferRequest createOfferRequest) throws ProfitMandiBusinessException {
                this.createOffer(createOfferRequest);
                this.createTargetSlabs(createOfferRequest);
        }

        private void createOffer(CreateOfferRequest createOfferRequest) {
                Offer offer = new Offer();
                offer.setName(createOfferRequest.getName());
                offer.setTargetType(createOfferRequest.getTargetType());
                offer.setPayoutType(createOfferRequest.getPayoutType());
                offer.setSchemeType(createOfferRequest.getSchemeType());
                offer.setEndDate(createOfferRequest.getEndDate());
                offer.setStartDate(createOfferRequest.getStartDate());
                offer.setBrandSharePercentage(createOfferRequest.getBrandShareTerms());
                offer.setSellinPercentage(createOfferRequest.getSellinPercentage());
                offer.setOfferNotes(createOfferRequest.getOfferNotes());
                offer.setActivationBrands(createOfferRequest.getActivationBrands());
                offer.setTerms(createOfferRequest.getTerms());
                offer.setItemCriteria(gson.toJson(createOfferRequest.getItemCriteria()));
                offer.setPartnerCriteria(gson.toJson(createOfferRequest.getPartnerCriteria()));
                offerRepository.persist(offer);
                createOfferRequest.setId(offer.getId());
        }

        @Override
        public List<CreateOfferRequest> getPublishedOffers(int fofoId, YearMonth yearMonth) {
                List<Offer> publishedOffers = offerRepository
                                .selectAllPublishedMapByPartner(YearMonth.from(LocalDateTime.now())).get(fofoId);
                List<CreateOfferRequest> createOfferRequests = new ArrayList<>();
                if (publishedOffers != null) {
                        for (Offer offer : publishedOffers) {
                                List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = targetSlabRepository
                                                .getByOfferId(offer.getId());
                                CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
                                createOfferRequest.getItemCriteria();
                                createOfferRequest.setTargetSlabs(targetSlabs);
                                createOfferRequests.add(createOfferRequest);

                        }
                        for (CreateOfferRequest createOfferRequest : createOfferRequests) {
                                double amount = offerRepository.getPartnerWiseSalesSum(createOfferRequest).get(fofoId) == null ? 0
                                                : offerRepository.getPartnerWiseSalesSum(createOfferRequest).get(fofoId);

                                com.spice.profitmandi.dao.model.TargetSlab currentSlab = createOfferRequest.getTargetSlabs().stream()
                                                .filter(x -> x.getOnwardsAmount() <= amount)
                                                .max(Comparator.comparing(x -> x.getOnwardsAmount())).orElse(null);

                                com.spice.profitmandi.dao.model.TargetSlab nextSlab = createOfferRequest.getTargetSlabs().stream()
                                                .filter(x -> x.getOnwardsAmount() > amount).min(Comparator.comparing(x -> x.getOnwardsAmount()))
                                                .orElse(null);
                                createOfferRequest.setNextTargetSlab(nextSlab);
                                createOfferRequest.setCurrentTargetSlab(currentSlab);
                                createOfferRequest.setEligibleSale((int) amount);

                        }
                }
                return createOfferRequests;
        }

        @Override
        public List<CreateOfferRequest> getAllOffers(YearMonth yearMonth) {
                List<Offer> allOffers = offerRepository.selectAll(yearMonth, false);
                List<CreateOfferRequest> createOfferRequests = new ArrayList<>();
                for (Offer offer : allOffers) {
                        CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
                        createOfferRequests.add(createOfferRequest);
                }
                return createOfferRequests;
        }

        @Override
        public CreateOfferRequest getOffer(int offerId) {
                Offer offer = offerRepository.selectById(offerId);
                CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
                return createOfferRequest;
        }

        private CreateOfferRequest getCreateOfferRequest(Offer fromOffer) {
                CreateOfferRequest createOfferRequest = new CreateOfferRequest();
                createOfferRequest.setName(fromOffer.getName());
                createOfferRequest.setTargetType(fromOffer.getTargetType());
                createOfferRequest.setPayoutType(fromOffer.getPayoutType());
                createOfferRequest.setSchemeType(fromOffer.getSchemeType());
                createOfferRequest.setActivationBrands(fromOffer.getActivationBrands());
                createOfferRequest.setEndDate(fromOffer.getEndDate());
                createOfferRequest.setStartDate(fromOffer.getStartDate());
                createOfferRequest.setActive(fromOffer.isActive());
                createOfferRequest.setSellinPercentage(fromOffer.getSellinPercentage());
                createOfferRequest.setBrandShareTerms(fromOffer.getBrandSharePercentage());
                createOfferRequest.setOfferNotes(fromOffer.getOfferNotes());
                createOfferRequest.setTerms(fromOffer.getTerms());
                createOfferRequest.setItemCriteria(
                                gson.fromJson(fromOffer.getItemCriteria(), com.spice.profitmandi.service.offers.ItemCriteria.class));
                createOfferRequest.setPartnerCriteria(gson.fromJson(fromOffer.getPartnerCriteria(), PartnerCriteria.class));
                createOfferRequest.setId(fromOffer.getId());
                createOfferRequest.setCreatedOn(fromOffer.getCreatedTimestamp());
                createOfferRequest.setItemCriteriaString(
                                itemCriteriaRepository.getItemCriteriaDescription(createOfferRequest.getItemCriteria()));
                List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = targetSlabRepository
                                .getByOfferId(fromOffer.getId());
                createOfferRequest.setPartnerCriteriaString(
                                retailerService.getPartnerCriteriaString(createOfferRequest.getPartnerCriteria()));
                createOfferRequest.setTargetSlabs(targetSlabs);
                LOGGER.info("createOfferRequest {}", createOfferRequest);
                return createOfferRequest;

        }

        private void createTargetSlabs(CreateOfferRequest createOfferRequest) throws ProfitMandiBusinessException {
                List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = createOfferRequest.getTargetSlabs().stream()
                                .filter(x -> x.validate()).collect(Collectors.toList());
                if (targetSlabs.size() >= 0) {
                        Collections.sort(targetSlabs);
                        for (com.spice.profitmandi.dao.model.TargetSlab targetSlab : targetSlabs) {
                                if (targetSlab.validate()) {
                                        List<ItemCriteriaPayout> itemCriteriaPayouts = targetSlab.getItemCriteriaPayouts();
                                        for (ItemCriteriaPayout itemCriteriaPayout : itemCriteriaPayouts) {
                                                String itemCriteriaJson = gson.toJson(itemCriteriaPayout.getItemCriteria());
                                                ItemCriteria itemCriteria = itemCriteriaRepository.selectByCriteria(itemCriteriaJson);
                                                // ItemCriteria Only once
                                                if (itemCriteria == null) {
                                                        itemCriteria = new ItemCriteria();
                                                        itemCriteria.setCriteria(gson.toJson(itemCriteriaPayout.getItemCriteria()));
                                                        itemCriteriaRepository.persist(itemCriteria);
                                                }
                                                for (PayoutSlab payoutSlab : itemCriteriaPayout.getPayoutSlabs()) {
                                                        TargetSlab targetSlab1 = new TargetSlab();
                                                        targetSlab1.setOfferId(createOfferRequest.getId());
                                                        targetSlab1.setOnwardsTarget(targetSlab.getOnwardsAmount());
                                                        targetSlab1.setTargetDescription(targetSlab.getTargetDescription());
                                                        targetSlab1.setPayoutTarget(payoutSlab.getOnwardsAmount());
                                                        targetSlab1.setPayoutValue(payoutSlab.getPayoutAmount());
                                                        targetSlab1.setItemCriteriaId(itemCriteria.getId());
                                                        targetSlab1.setAmountType(itemCriteriaPayout.getAmountType());
                                                        targetSlabRepository.persist(targetSlab1);
                                                }
                                        }
                                }
                        }

                } else {
                        throw new ProfitMandiBusinessException("Invalid Target Slabs", "Invalid Target", "");
                }

        }

        @Override
        public List<CreateOfferRequest> getPublishedOffers(LocalDate date, int fofoId, int itemId) {
                List<Offer> publishedOffers = offerRepository.selectAllPublishedMapByPartner(YearMonth.from(date)).get(fofoId);
                List<CreateOfferRequest> createOfferRequests = new ArrayList<>();
                if (publishedOffers != null) {
                        for (Offer offer : publishedOffers) {
                                List<com.spice.profitmandi.dao.model.TargetSlab> targetSlabs = targetSlabRepository
                                                .getByOfferId(offer.getId());
                                CreateOfferRequest createOfferRequest = this.getCreateOfferRequest(offer);
                                createOfferRequest.getItemCriteria();
                                createOfferRequest.setTargetSlabs(targetSlabs);
                                createOfferRequests.add(createOfferRequest);
                                Set<com.spice.profitmandi.service.offers.ItemCriteria> itemCriteriaSet = targetSlabs.stream()
                                                .flatMap(x -> x.getItemCriteriaPayouts().stream()).map(x -> x.getItemCriteria()).distinct()
                                                .filter(x -> itemRepository.containsItem(x, itemId)).collect(Collectors.toSet());

                                for (com.spice.profitmandi.dao.model.TargetSlab targetSlab : targetSlabs) {
                                        targetSlab.setItemCriteriaPayouts(targetSlab.getItemCriteriaPayouts().stream()
                                                        .filter(x -> itemCriteriaSet.contains(x.getItemCriteria())).collect(Collectors.toList()));
                                }
                        }
                }
                return createOfferRequests;
        }

}