package com.mns.intl.pigw.productcore.processor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mns.intl.pigw.productcore.aop.LogExecutionTime;
import com.mns.intl.pigw.productcore.constants.Constants;
import com.mns.intl.pigw.productcore.constants.FieldSubscriptionKeys;
import com.mns.intl.pigw.productcore.constants.FlatResponseKeys;
import com.mns.intl.pigw.productcore.constants.ProcessStatus;
import com.mns.intl.pigw.productcore.dto.request.ExtractorRequest;
import com.mns.intl.pigw.productcore.dto.request.PartnerExtractRequest;
import com.mns.intl.pigw.productcore.dto.request.ProductAuditReferenceRequest;
import com.mns.intl.pigw.productcore.dto.request.ProductWeightRequest;
import com.mns.intl.pigw.productcore.dto.request.SellingAttributesRequest;
import com.mns.intl.pigw.productcore.dto.response.AdminServiceResponse;
import com.mns.intl.pigw.productcore.dto.response.AttrServiceResponse;
import com.mns.intl.pigw.productcore.dto.response.Attributes;
import com.mns.intl.pigw.productcore.dto.response.Barcode;
import com.mns.intl.pigw.productcore.dto.response.CnhProductPackServiceResponse;
import com.mns.intl.pigw.productcore.dto.response.Color;
import com.mns.intl.pigw.productcore.dto.response.CooResponse;
import com.mns.intl.pigw.productcore.dto.response.Description;
import com.mns.intl.pigw.productcore.dto.response.PackDefinitionDTO;
import com.mns.intl.pigw.productcore.dto.response.PartnerFieldSubscriptionResponse;
import com.mns.intl.pigw.productcore.dto.response.ProductCoreSeason;
import com.mns.intl.pigw.productcore.dto.response.ProductDataResponse;
import com.mns.intl.pigw.productcore.dto.response.ProductDescriptions;
import com.mns.intl.pigw.productcore.dto.response.ProductPack;
import com.mns.intl.pigw.productcore.dto.response.ProductSeasonality;
import com.mns.intl.pigw.productcore.dto.response.ProductStagingResponse;
import com.mns.intl.pigw.productcore.dto.response.ProductVariant;
import com.mns.intl.pigw.productcore.dto.response.Products;
import com.mns.intl.pigw.productcore.dto.response.ResponseDTO;
import com.mns.intl.pigw.productcore.dto.response.Variant;
import com.mns.intl.pigw.productcore.entity.VariantCategoryDataEntity;
import com.mns.intl.pigw.productcore.exception.InternalServerError;
import com.mns.intl.pigw.productcore.exception.MandatoryFieldException;
import com.mns.intl.pigw.productcore.repository.VariantCategoryDataRepository;
import com.mns.intl.pigw.productcore.service.AdminService;
import com.mns.intl.pigw.productcore.service.CnhService;
import com.mns.intl.pigw.productcore.service.EsService;
import com.mns.intl.pigw.productcore.service.IBTService;
import com.mns.intl.pigw.productcore.service.MongoCoreService;
import com.mns.intl.pigw.productcore.service.SellingAttributeService;
import com.mns.intl.pigw.productcore.service.SubscriptionService;
import com.mns.intl.pigw.productcore.utils.CloudFileShareHelper;

@Component
public class ProductCoreProcessor {

	@Autowired
	CnhService cnhService;


	@Autowired
	EsService esService;

	@Autowired
	IBTService ibtService;

	@Autowired
	CloudFileShareHelper blobUtils;

	@Autowired
	SubscriptionService subscriptionService;

	@Autowired
	AdminService adminService;

	@Autowired
	MongoCoreService mongoCoreService;

	@Autowired
	SellingAttributeService sellingAttributeService;

	@Autowired
	VariantCategoryDataRepository variantCategoryDataRepository;

	@Value("${azure.storage.connectionstring.v2}")
	private String azureConnectionString;
	
	Map<Integer, List<ProductStagingResponse>> franchiseProductsMap = null;
	
	Map<Integer, List<CooResponse>> countryNumMap = null; 

	private static final Logger logger = LoggerFactory.getLogger(ProductCoreProcessor.class);

	/**
	 *triggerProcess Method - helps to map required data for a partner and will root the data to the destination 
	 */
	@LogExecutionTime
	public Boolean triggerProcess(List<ExtractorRequest> extractorRequest) throws JsonProcessingException {
		List<Integer> batchIdList = extractorRequest.stream().map(x -> x.getBatchId()).collect(Collectors.toList());

		franchiseProductsMap = new HashMap<>();
		countryNumMap = new HashMap<>();
		
		int count = 0;
		boolean  deletionService = false;
		List<String> invalidProductIds = new ArrayList<>();


		Map<String, List<String>> productVariantIdMap = new HashMap<>();

		List<AdminServiceResponse> adminServicePartnerDetailsList = adminService.getDetailsForExtract(batchIdList, extractorRequest);
		if (adminServicePartnerDetailsList == null || adminServicePartnerDetailsList.isEmpty()) {
			logger.info("No records in scheduler table");
			return false;
		}
		logger.info("The filename pattern and destination path" + adminServicePartnerDetailsList);
		Map<Integer, AdminServiceResponse> adminPartnerDetailsMap = new HashMap<>();
		for (AdminServiceResponse j : adminServicePartnerDetailsList) {
			adminPartnerDetailsMap.put(j.getFranchiseNumber(), j);
		}

		Map<Integer, ExtractorRequest> franchisenBatchIdMap = new HashMap<>();
		for (int i = 0; i < extractorRequest.size(); i++) {
			franchisenBatchIdMap.put(extractorRequest.get(i).getFranchiseNumber(), extractorRequest.get(i));
		}

		logger.info("franchisenBatchIdMap {}", franchisenBatchIdMap);
		
		Boolean cnhProductWeightIsActive = adminService.cnhProductWeightIsActive(batchIdList, extractorRequest);
		
		Map<Integer, List<ProductDataResponse>> finalResponseMap = getDataForExtract(invalidProductIds,
				 productVariantIdMap, extractorRequest,
				batchIdList, cnhProductWeightIsActive);
		
		if (finalResponseMap != null && !finalResponseMap.isEmpty()) {

			for (Map.Entry<Integer, List<ProductDataResponse>> entries : finalResponseMap.entrySet()) {

				// mapping the product core response for a individual partner
				Integer franchiseNumber = entries.getKey();
				ObjectMapper objectMapper = new ObjectMapper();
				objectMapper.setSerializationInclusion(Include.NON_NULL);
				
				List<String> configuredSeasonListForPartner = cnhService.getNextTwoSeasonFromCurrentSeason(adminPartnerDetailsMap.get(entries.getKey()).getNoOfSeasonsBackward(), adminPartnerDetailsMap.get(entries.getKey()).getNoOfSeasonsForward(), batchIdList, extractorRequest);
				Map<Integer, String> countryCodeMap = ibtService.getCountryCode(batchIdList, extractorRequest);
				Map<String, List<CooResponse>> countryNumProductLevelMap = null;
				if(countryNumMap.get(franchiseNumber)!=null && !countryNumMap.get(franchiseNumber).isEmpty())
				countryNumProductLevelMap = countryNumMap.get(franchiseNumber).stream().collect(Collectors.groupingBy(x->x.getProductId()));
				
				Map<String,List<ProductStagingResponse>> productStagingResponseMap = franchiseProductsMap.get(entries.getKey()).stream().collect(Collectors.groupingBy(x->x.getProductId()));
			
				List<ProductDataResponse> franchiseProductDataResponseList = new ArrayList<>();
				 for (ProductDataResponse originalProductData : entries.getValue()) {
				        try {
				            ProductDataResponse clonedProductData = originalProductData.clone();
				            
				            franchiseProductDataResponseList.add(clonedProductData);
				        } catch (CloneNotSupportedException e) {
				            logger.error("Error occurred while cloning the response",e);
				            }
				    }
				
				for (ProductDataResponse productData : franchiseProductDataResponseList) {
					if(franchisenBatchIdMap.get(entries.getKey()) != null) {
						
					productData.setBatchId(franchisenBatchIdMap.get(entries.getKey()).getBatchId());
					productData.setFranchiseNumber(franchisenBatchIdMap.get(entries.getKey()).getFranchiseNumber());
					}

					if (!adminPartnerDetailsMap.get(entries.getKey()).getLatestSeason()) {
						List<ProductCoreSeason> seasonBlockList = filterOrdervariantIds(productData,
								productStagingResponseMap,countryCodeMap,countryNumProductLevelMap);
						productData.setSeasons(seasonBlockList);
					} else {

						List<ProductCoreSeason> LatestSeasonBlockList = filterLatestSeasonandOrderdedVariants(
								productData, productStagingResponseMap,
								batchIdList, extractorRequest, configuredSeasonListForPartner,countryCodeMap,countryNumProductLevelMap);

						productData.setSeasons(LatestSeasonBlockList);
					}
				}
					
					Map<Integer, List<String>> subscribedFieldsForPartner = getSubscribedfieldMapforPartner(batchIdList,
							extractorRequest);
					if (subscribedFieldsForPartner.get(franchiseNumber) == null
							|| subscribedFieldsForPartner.get(franchiseNumber).isEmpty()) {

						logger.info("No field subscribed for partner with franchise number :{} and batchId:{} ",
								franchiseNumber, franchiseProductDataResponseList.get(0).getBatchId());
						logger.info(
								"It will consider all attributes as subscribed field for partner with franchise number : {} ",
								franchiseNumber);
						mongoCoreService.postProductCoreResponse(franchiseProductDataResponseList, batchIdList, extractorRequest);

						logger.info("Successfully updated mongo core collection {}:{}", franchiseNumber,
								franchiseProductDataResponseList.get(0).getBatchId());
					} else {
						List<ProductDataResponse> parterSubscribedContent = getsubscribedFieldByPartner(
								franchiseProductDataResponseList, subscribedFieldsForPartner.get(franchiseNumber),cnhProductWeightIsActive);
						logger.info("{} batchId {} franschise subscribed field been filtered",
								parterSubscribedContent.get(0).getBatchId(),
								parterSubscribedContent.get(0).getFranchiseNumber());
						mongoCoreService.postProductCoreResponse(parterSubscribedContent, batchIdList,
								extractorRequest);

						logger.info("Successfully updated mongo core collection {}:{}",
								parterSubscribedContent.get(0).getFranchiseNumber(),
								parterSubscribedContent.get(0).getBatchId());
					}

					// International Partner
					count++;

					deletionService = subscriptionService.deletingProducsByExtractIdFranchise(franchiseNumber,
							batchIdList, extractorRequest);
					logger.info("the deletion table status: " + deletionService);

				
			}
		}
		return (count == finalResponseMap.size()) ? true : false;

	}

	private List<ProductCoreSeason> filterLatestSeasonandOrderdedVariants(
			 ProductDataResponse productData,
			Map<String, List<ProductStagingResponse>> productStagingResponseMap,List<Integer> batchIdList, List<ExtractorRequest> extractorRequest, List<String> configuredSeasonListForPartner, Map<Integer, String> countryCodeMap, Map<String, List<CooResponse>> countryNumProductLevelMap) {
		List<ProductCoreSeason> seasonBlockList = new ArrayList<>();
		List<Variant> applicableSeasonOrderedList = new ArrayList<>();
		List<String> applicableSeasonList = productStagingResponseMap.get(productData.getProductId()).stream().map(x->x.getSeason()).collect(Collectors.toList());
		
		for(ProductCoreSeason seasonIteration : productData.getSeasons()) {
			if(applicableSeasonList.contains(seasonIteration.getSeasonName())) {
				
			List<String> stagedOrderVariantIdsList = productStagingResponseMap.get(productData.getProductId()).stream().filter(y->y.getSeason().equalsIgnoreCase(seasonIteration.getSeasonName()) && y.getVariantIds()!=null).flatMap(y->y.getVariantIds().stream()).collect(Collectors.toList());

			if(null!=stagedOrderVariantIdsList && !stagedOrderVariantIdsList.isEmpty()) {
			List<Variant> applicableEntrySeasonOrderedList = seasonIteration.getVariants().stream().filter(x->stagedOrderVariantIdsList.stream().anyMatch(id -> id.equals(x.getProductVariantId()))).map( data->{
			
			Variant variant = new Variant();
			variant = data;
			return variant;
			
			}).collect(Collectors.toList());
			applicableSeasonOrderedList.addAll(applicableEntrySeasonOrderedList);
		} else {
			applicableSeasonOrderedList.addAll(seasonIteration.getVariants());
		}
		}
		}
		applicableSeasonOrderedList = applicableSeasonOrderedList.stream().distinct().collect(Collectors.toList());
		
		if(productData.getSeasons().size()==1) {
			ProductCoreSeason seasonBlock = new ProductCoreSeason();
			seasonBlock.setSeasonName(productData.getSeasons().get(0).getSeasonName());
			seasonBlock.setHsn(productData.getSeasons().get(0).getHsn());
			if(countryNumProductLevelMap!=null && !countryNumProductLevelMap.isEmpty() && countryNumProductLevelMap.get(productData.getProductId())!=null && !countryNumProductLevelMap.get(productData.getProductId()).isEmpty()) {
				
				Optional<CooResponse> cooResponse = countryNumProductLevelMap.get(productData.getProductId()).stream().filter(x->x.getSeasonName().equalsIgnoreCase(productData.getSeasons().get(0).getSeasonName())).findAny();
				if(cooResponse.isPresent() && cooResponse.get().getCountryNum()!=null && countryCodeMap.get(cooResponse.get().getCountryNum())!=null) {
					
					seasonBlock.setCoo(countryCodeMap.get(cooResponse.get().getCountryNum()));
					}
				}	
			seasonBlock.setVariants(applicableSeasonOrderedList);
			seasonBlockList.add(seasonBlock);
			
		} else {
			
		int k = configuredSeasonListForPartner.size() - 1;
		while (k >= 0) {
		if(applicableSeasonList!=null && !applicableSeasonList.isEmpty() && applicableSeasonList.contains(configuredSeasonListForPartner.get(k))) {
			ProductCoreSeason seasonBlock = new ProductCoreSeason();
			seasonBlock.setSeasonName(configuredSeasonListForPartner.get(k));
			seasonBlock.setHsn(productData.getSeasons().get(0).getHsn());
			if (countryNumProductLevelMap!=null && !countryNumProductLevelMap.isEmpty() && countryNumProductLevelMap.get(productData.getProductId()) != null
					&& !countryNumProductLevelMap.get(productData.getProductId()).isEmpty()) {

				Optional<CooResponse> cooResponse = countryNumProductLevelMap.get(productData.getProductId()).stream()
						.filter(x -> x.getSeasonName()
								.equalsIgnoreCase(seasonBlock.getSeasonName()))
						.findAny();
				if(cooResponse.isPresent() && cooResponse.get().getCountryNum()!=null && countryCodeMap.get(cooResponse.get().getCountryNum())!=null) {
				
				seasonBlock.setCoo(countryCodeMap.get(cooResponse.get().getCountryNum()));
				}
			}
			seasonBlock.setVariants(applicableSeasonOrderedList);
			seasonBlockList.add(seasonBlock);
			break;
		}
		k--;
		}
	}
		return seasonBlockList;
	}

	private List<ProductCoreSeason> filterOrdervariantIds(ProductDataResponse productData, Map<String, List<ProductStagingResponse>> productStagingResponseMap, Map<Integer, String> countryCodeMap, Map<String, List<CooResponse>> countryNumProductLevelMap) {
	
		List<ProductCoreSeason> seasonBlockList = new ArrayList<>();
		
		List<String> applicableSeasonList = productStagingResponseMap.get(productData.getProductId()).stream().map(x->x.getSeason()).collect(Collectors.toList());
		
		
		for(ProductCoreSeason seasonIteration : productData.getSeasons()) {
			if(applicableSeasonList.contains(seasonIteration.getSeasonName())) {
			ProductCoreSeason seasonBlock = new ProductCoreSeason();
			seasonBlock.setSeasonName(seasonIteration.getSeasonName());
			seasonBlock.setHsn(seasonIteration.getHsn());
			if(countryNumProductLevelMap!=null && !countryNumProductLevelMap.isEmpty() && countryNumProductLevelMap.get(productData.getProductId())!=null && !countryNumProductLevelMap.get(productData.getProductId()).isEmpty()) {
			
			Optional<CooResponse> cooResponse = countryNumProductLevelMap.get(productData.getProductId()).stream().filter(x->x.getSeasonName().equalsIgnoreCase(seasonIteration.getSeasonName())).findAny();
			if (cooResponse.isPresent() && cooResponse.get().getCountryNum() != null
					&& countryCodeMap.get(cooResponse.get().getCountryNum()) != null) {

				seasonIteration.setCoo(countryCodeMap.get(cooResponse.get().getCountryNum()));
				seasonBlock.setCoo(countryCodeMap.get(cooResponse.get().getCountryNum()));
			}
			}	
			List<String> stagedOrderVariantIdsList = productStagingResponseMap.get(productData.getProductId()).stream().filter(y->y.getSeason().equalsIgnoreCase(seasonIteration.getSeasonName()) && y.getVariantIds()!=null).flatMap(y->y.getVariantIds().stream()).collect(Collectors.toList());
			if(null != stagedOrderVariantIdsList && !stagedOrderVariantIdsList.isEmpty()) {
			List<Variant> variants = seasonIteration.getVariants().stream().filter(x->stagedOrderVariantIdsList.stream().anyMatch(id -> id.equals(x.getProductVariantId()))).map( data->{
			
			Variant variant = new Variant();
			variant = data;
			return variant;
			
			}).collect(Collectors.toList());
			
			seasonBlock.setVariants(variants);
			seasonBlockList.add(seasonBlock);
		} else {
			seasonBlockList.add(seasonIteration);
		}
		}
		}
		
		return seasonBlockList;
	}

	private Map<Integer, List<String>> getSubscribedfieldMapforPartner(List<Integer> batchIdList,
			List<ExtractorRequest> extractorRequest) {
		Map<Integer, List<String>> subscribedFieldsMapForPartner = new HashMap<>();
//      Get Subscribed fields for partners for extract type
		List<PartnerFieldSubscriptionResponse> partnerFieldSubscriptionList = adminService
				.getSubscribeFieldsByExtractTypeId(Constants.PRODUCT_CORE_EXTRACT_TYPE_ID, batchIdList,
						extractorRequest);
		for (PartnerFieldSubscriptionResponse partnerFieldSubscriptionResponse : partnerFieldSubscriptionList) {
			subscribedFieldsMapForPartner.put(partnerFieldSubscriptionResponse.getFrachiseNumber(),
					partnerFieldSubscriptionResponse.getSubscribedFields());
		}
		return subscribedFieldsMapForPartner;
	}

	private List<ProductDataResponse> getsubscribedFieldByPartner(List<ProductDataResponse> productResponseList,
			List<String> listOfSubscribedFields, Boolean cnhProductWeightIsActive) {
		List<ProductDataResponse> productDataResponseList = new ArrayList<>();
		if (listOfSubscribedFields != null && !listOfSubscribedFields.isEmpty()) {
			ObjectMapper productDataResponseMapper = new ObjectMapper();
			for (ProductDataResponse productResponse : productResponseList) {
				Map<String, Object> productResponseMap = productDataResponseMapper.convertValue(productResponse,
						Map.class);
				Map<String, Object> partnerSubscribedResponseMap = new HashMap<>();

				for (String subscribedField : listOfSubscribedFields) {

					partnerSubscribedResponseMap.put(subscribedField, productResponseMap.get(subscribedField));

				}				
								
				
				ProductDataResponse structuredObject = productDataResponseMapper
						.convertValue(partnerSubscribedResponseMap, ProductDataResponse.class);
				Map<String, Object> responseMap = createSubscribedFieldJson(productResponseList,structuredObject,partnerSubscribedResponseMap,cnhProductWeightIsActive);
				ProductDataResponse finalObject = productDataResponseMapper
						.convertValue(responseMap, ProductDataResponse.class);
				finalObject.setProductId(productResponse.getProductId());
				finalObject.setBatchId(productResponse.getBatchId());
				finalObject.setFranchiseNumber(productResponse.getFranchiseNumber());
				productDataResponseList.add(finalObject);
			}

		}

		return productDataResponseList;
	}

	/**
	 * getDataForExtract Method - get the data from different source to assemble in the form of ProductDataResponse pojo class
	 * @param invalidProductIds - gives the list of unprocessed productId
	 * @param franchiseProductsMap 
	 * @param franchiseOrderedVarinatIds 
	 * @param channelVisorIsAcive 
	 * @param cnhProductWeightIsActive 
	 * @param estimatedServiceResponseMap - to populate the estimated delivery date field for all the partner 
	 * @return
	 */
	public Map<Integer, List<ProductDataResponse>> getDataForExtract(List<String> invalidProductIds,
			Map<String, List<String>> productVariantIdMap, List<ExtractorRequest> extractorRequest,
			List<Integer> batchIdList, Boolean cnhProductWeightIsActive) {

		Map<Integer, List<ProductDataResponse>> coreExtractResponse = new HashMap<>();
		List<ProductDataResponse> productResponseList = new ArrayList<>();
		try {

			List<ProductStagingResponse> responseList = subscriptionService.getProductsForExtract(batchIdList,
					extractorRequest);

			logger.info("the staging table response size is :" + responseList.size());

			if (responseList == null || responseList.isEmpty()) {
				logger.info("No records in staging to be extracted");
				return null;
			}

			List<String> productIdCollection = new ArrayList<>();
			for (ProductStagingResponse i : responseList) {
				productIdCollection.add(i.getProductId());
			}

			franchiseProductsMap = responseList.stream()
					.collect(Collectors.groupingBy(x -> x.getFranchiseNumber()));

			Map<String, List<String>> seasonProductsMap = new HashMap<>();
			Map<Integer, Map<String, List<String>>> franchiseSeasonProductsMap = new HashMap<>();
			List<String> stagingProductIds = new ArrayList<>();
			List<String> productIds = productIdCollection.stream().distinct().collect(Collectors.toList());
			List<String> seasons = new ArrayList<>();

			// to check the varinats count
			// List<String> stagedVariantIds = new ArrayList<>();

			for (Map.Entry<Integer, List<ProductStagingResponse>> eachEntry : franchiseProductsMap.entrySet()) {
				List<ProductStagingResponse> list = eachEntry.getValue();
				List<String> productNum = new ArrayList<>();
				List<String> orderedVariantIdList = new ArrayList<>();
				
				for (ProductStagingResponse eachRecord : list) {
					productNum.add(eachRecord.getProductId());
					// Forming franchiseSeasonProductsMap
					if (!stagingProductIds.contains(eachRecord.getProductId())) {
						stagingProductIds.add(eachRecord.getProductId());
					}
					if (!seasons.contains(eachRecord.getSeason())) {
						seasons.add(eachRecord.getSeason());
					}
					if (seasonProductsMap != null && !seasonProductsMap.isEmpty()
							&& seasonProductsMap.get(eachRecord.getSeason()) != null) {
						seasonProductsMap.get(eachRecord.getSeason()).add(eachRecord.getProductId());
					} else {
						List<String> products = new ArrayList<>();
						products.add(eachRecord.getProductId());
						seasonProductsMap.put(eachRecord.getSeason(), products);
					}
					// Creating the map to get the ordered products variantIds
					if (eachRecord.getVariantIds() != null && !eachRecord.getVariantIds().isEmpty()) {
						if (!productVariantIdMap.containsKey(eachRecord.getProductId())) {
							productVariantIdMap.put(eachRecord.getProductId(), eachRecord.getVariantIds());
							orderedVariantIdList.addAll(eachRecord.getVariantIds());
						} else {
							productVariantIdMap.get(eachRecord.getProductId()).addAll(eachRecord.getVariantIds());
							orderedVariantIdList.addAll(eachRecord.getVariantIds());
						}
					}
				}
								
				franchiseSeasonProductsMap.put(eachEntry.getKey(), seasonProductsMap);
				
			}


			List<ProductSeasonality> productSeasonalityResponseList = cnhService
					.getSeasonalityCollection(seasonProductsMap, batchIdList, extractorRequest);

			if (productSeasonalityResponseList == null || productSeasonalityResponseList.isEmpty()) {
				logger.info("No records from product seasonality service");
				return null;
			}

			logger.info(
					"the finalised productSeasonalityResponseList size is :" + productSeasonalityResponseList.size());
			
			Map<String, List<ProductSeasonality>> productSeasonalityMap = new HashMap<>();
			Map<String, String> primarySizeDescMap = cnhService.getPrimarySizeData(batchIdList, extractorRequest);
			Map<String, String> secondarySizeDescMap = cnhService.getSecondarySizeData(batchIdList, extractorRequest);
			Map<String, PackDefinitionDTO> weaVariantPackDefinitionMap = new HashMap<>();
			
			//IBT Service to get the plan A Raw material Attribute
			Map<String, AttrServiceResponse> attrMap = cnhService.getAttributes(productIds, batchIdList, extractorRequest);
			
			//Generate productVariantWeightDimensionMap
			if(cnhProductWeightIsActive) {
			weaVariantPackDefinitionMap = generateProductVariantWeightDimensionMap(productIds, weaVariantPackDefinitionMap);
			}
			countryNumMap = ibtService.getCOOForPartners(batchIdList, extractorRequest, franchiseSeasonProductsMap);
			
			// ES service calling
			List<String> variantId = new ArrayList<>();
			Map<String, String> primarySizeDescIndexMap = new HashMap<>();
			Map<String, String> variantGtinMap = new HashMap<>();
			Map<String, String> secondarySizeDescIndexMap = new HashMap<>();
			if (productSeasonalityResponseList != null && !productSeasonalityResponseList.isEmpty()) {
				productSeasonalityMap = productSeasonalityResponseList.stream()
						.collect(Collectors.groupingBy(x -> x.getProductId()));

				logger.info("the finalised product list size is :" + productIds.size());

				for (String Id : productIds) {
					List<ProductSeasonality> variant = productSeasonalityMap.get(Id);
					if (variant != null && !variant.isEmpty()) {
						Map<String, ProductSeasonality> variantSeasonDataMap = variant.stream().distinct()
								.collect(Collectors.toMap(x -> x.getSeason().getSeasonName(), x -> x));

						for (String oneSeason : seasons) {

							ProductSeasonality prductSeasonlity = variantSeasonDataMap.get(oneSeason);
							if (variantSeasonDataMap.get(oneSeason) != null) {
								for (int i = 0; i < prductSeasonlity.getProductVariants().size(); i++) {
									if (prductSeasonlity.getProductVariants() != null
											&& !prductSeasonlity.getProductVariants().isEmpty()) {
										if (prductSeasonlity.getProductVariants().get(i).getActiveIndicator() == null
												|| prductSeasonlity.getProductVariants().get(i)
														.getActiveIndicator() == 1) {
											variantId.add(prductSeasonlity.getProductVariants().get(i).getVariantId());
											String priValues = prductSeasonlity.getProductVariants().get(i)
													.getPrimarySizeIndex() + "-"
													+ prductSeasonlity.getProductVariants().get(i)
															.getPrimarySizeRange();
											if (priValues.charAt(0) == '0') {
												priValues = priValues.substring(1);
											}
											if (!primarySizeDescIndexMap.containsKey(
													prductSeasonlity.getProductVariants().get(i).getVariantId())) {
												primarySizeDescIndexMap.put(
														prductSeasonlity.getProductVariants().get(i).getVariantId(),
														primarySizeDescMap.get(priValues));
											}
											String secValues = prductSeasonlity.getProductVariants().get(i)
													.getSecondarySizeIndex() + "-"
													+ prductSeasonlity.getProductVariants().get(i)
															.getSecondarySizeRange();
											if (prductSeasonlity.getProductVariants().get(i).getSecondarySizeIndex()
													.length() != 1 && secValues.charAt(0) == '0') {
												secValues = secValues.substring(1);
											}
											if (!secondarySizeDescIndexMap.containsKey(
													prductSeasonlity.getProductVariants().get(i).getVariantId())) {
												secondarySizeDescIndexMap.put(
														prductSeasonlity.getProductVariants().get(i).getVariantId(),
														secondarySizeDescMap.get(secValues));
											}
											if (!variantGtinMap.containsKey(
													prductSeasonlity.getProductVariants().get(i).getVariantId())) {
												variantGtinMap.put(
														prductSeasonlity.getProductVariants().get(i).getVariantId(),
														prductSeasonlity.getProductVariants().get(i).getGtinNo());
											}
										}
									}

								}

							}
						}

					} else {
						invalidProductIds.add(Id);
					}
				}
				logger.info("variantGtinMap size is " + variantGtinMap.size());
				logger.info(invalidProductIds + " invalidProductIds found in table");
			}

			List<String> variantIds = variantId.stream().distinct().collect(Collectors.toList());

			List<Products> esSeriveResponse = esService.getVariantCollection(variantIds, batchIdList, extractorRequest);
			Map<String, List<Products>> esSeriveResponseMap = new HashMap<>();
			if (esSeriveResponse != null && !esSeriveResponse.isEmpty()) {
				esSeriveResponseMap = esSeriveResponse.stream().collect(Collectors.groupingBy(x -> x.getProductId()));
			}

			logger.info("esSeriveResponseMap size is: " + esSeriveResponseMap.size());
			

			if (productSeasonalityResponseList != null && !productSeasonalityResponseList.isEmpty()) {

				mapProductDataResponse(productSeasonalityMap, productIds, seasons, variantIds, productResponseList,
						esSeriveResponseMap, primarySizeDescIndexMap, secondarySizeDescIndexMap, variantGtinMap, attrMap,
						batchIdList, extractorRequest, weaVariantPackDefinitionMap,cnhProductWeightIsActive);
			}
			

			Map<Integer, List<String>> franchiseProductIdMap = new HashMap<>();

			for (ProductStagingResponse response : responseList) {
				List<String> prductIds = new ArrayList<>();
				if (!franchiseProductIdMap.containsKey(response.getFranchiseNumber())) {
					prductIds.add(response.getProductId());

					franchiseProductIdMap.put(response.getFranchiseNumber(), prductIds);
				} else {
					if (!franchiseProductIdMap.get(response.getFranchiseNumber()).contains(response.getProductId())) {
						franchiseProductIdMap.get(response.getFranchiseNumber()).add(response.getProductId());
					}
				}
			}

			if (productResponseList != null && !productResponseList.isEmpty()) {

				for (Map.Entry<Integer, List<String>> map : franchiseProductIdMap.entrySet()) {

					List<ProductDataResponse> productDataList = new ArrayList();

					List<String> productList = map.getValue();

					for (int i = 0; i < productList.size(); i++) {
						for (int j = 0; j < productResponseList.size(); j++) {
							if (productResponseList.get(j).getProductId().equalsIgnoreCase(productList.get(i))
									&& productResponseList.get(j) != null) {
								productDataList.add(productResponseList.get(j));

							}
						}
					}
					if (productDataList != null && !productDataList.isEmpty()) {
						coreExtractResponse.put(map.getKey(), productDataList);
					}
				}

			}

		} catch (Exception e) {
			logger.error("Error occured while mapping the response", e);
			throw new InternalServerError("Internal Server Error");

		}

		return coreExtractResponse;

	}

	private Map<String, PackDefinitionDTO> generateProductVariantWeightDimensionMap(List<String> productIdList, Map<String, PackDefinitionDTO> weaVariantPackDefinitionMap) {

		for (int i=0;i<productIdList.size();i+=Constants.PRODUCT_WEIGHT_RECORD_PER_REQUEST) {
			// Calling CnhProductPackService for getting weight and dimensions
			int subIndex = (i + Constants.PRODUCT_WEIGHT_RECORD_PER_REQUEST) > productIdList.size() ? productIdList.size()
					: (i + Constants.PRODUCT_WEIGHT_RECORD_PER_REQUEST);
			List<String> productIdSubList =   productIdList.subList(i, subIndex);
			
			ProductWeightRequest productWeightRequest = new ProductWeightRequest();
			productWeightRequest.setProductIds(productIdSubList);
			
			CnhProductPackServiceResponse cnhProductPackServiceResponseList = cnhService
					.getProductWehightProductPackService(productWeightRequest);
			
			if(cnhProductPackServiceResponseList != null && cnhProductPackServiceResponseList.getResponse()!=null) {
				for(ResponseDTO cnhProductPackServiceResponse : cnhProductPackServiceResponseList.getResponse() )
				{
						weaVariantPackDefinitionMap.putAll(cnhProductPackServiceResponse.getPackDetails().stream()
							.filter(packDetail -> "WEA".equals(packDetail.getPackType()))
							.flatMap(packDetail -> packDetail.getPackDefinition().stream()).collect(Collectors
									.toMap(PackDefinitionDTO::getVariantArticleNumber, packDefinition -> packDefinition)));
				}
			}else {
				logger.error("Article Variant does not have weight and dimension details {}", productIdSubList);
			}
						
		}

		return weaVariantPackDefinitionMap;

	}

	/**
	 * Final Response to be mapped from ES, CNH and IBT Service data
	 * 
	 * @param productSeasonalityMap
	 * @param productIds
	 * @param seasons
	 * @param attrMap 
	 * @param extractorRequest
	 * @param batchIdList
	 * @param cnhProductWeightIsActive 
	 * @param estimatedServiceResponseMap 
	 * @throws MandatoryFieldException
	 */
	private void mapProductDataResponse(Map<String, List<ProductSeasonality>> productSeasonalityMap,
			List<String> productIds, List<String> seasons, List<String> variantIds,
			List<ProductDataResponse> productResponseList, Map<String, List<Products>> esSeriveResponseMap,
			Map<String, String> primarySizeDescIndexMap, Map<String, String> secondarySizeDescIndexMap,
			Map<String, String> variantGtinMap, Map<String, AttrServiceResponse> attrMap, List<Integer> batchIdList, List<ExtractorRequest> extractorRequest, Map<String, PackDefinitionDTO> weaVariantPackDefinitionMap, Boolean cnhProductWeightIsActive)
			throws MandatoryFieldException {

		for (String productId : productIds) {
			if (productSeasonalityMap != null && productSeasonalityMap.get(productId) != null) {
				ProductDataResponse productData = new ProductDataResponse();
				List<ProductSeasonality> products = productSeasonalityMap.get(productId);
				Map<String, ProductSeasonality> seasonDataMap = products.stream().distinct()
						.collect(Collectors.toMap(x -> x.getSeason().getSeasonName(), x -> x));
				
				//Adding product Level data 
				productData.setProductId(productId);
				productData.setDept(products.get(0).getDepartment());
				productData.setPrimSizeRange(products.get(0).getPrimarySizeRange());
				productData.setSecSizeRange(products.get(0).getSecondarySizeRange());
				productData.setMerchandCategory(products.get(0).getMerchandiseCat());
				productData.setStrokeNo(products.get(0).getStrokeNum());
				productData.setItem(products.get(0).getHierarchy().getValue());
				Color colour = new Color();
				colour.setColourCode(products.get(0).getColour().getColourCode());
				colour.setColourDesc(products.get(0).getColour().getColourDescription());
				productData.setColour(colour);				
				
				List<ProductDescriptions> productDescription = new ArrayList<>();
				List<Description> description = new ArrayList<>();
				ProductDescriptions pc = new ProductDescriptions();
				pc.setLanguage(Constants.LANGUAGE);
				Description desc1 = new Description();
				desc1.setDescType(Constants.SHORT);
				desc1.setDesc(products.get(0).getProductDescription().getShortDesc());
				description.add(desc1);
				Description desc2 = new Description();
				desc2.setDescType(Constants.LONG);
				desc2.setDesc(products.get(0).getProductDescription().getLongDesc());
				description.add(desc2);
				pc.setDescriptions(description);
				productDescription.add(pc);
				productData.setProductDesc(productDescription);
				for(Attributes attEntry : products.get(0).getAttributes()) {
					if(attEntry.getAttTypeDesc().equalsIgnoreCase("PRODUCT TYPE (C)")) {
						productData.setProductTypeC(attEntry.getAttDesc());
						break;
					}
				}
				if(attrMap != null && !attrMap.isEmpty() && attrMap.get(productId) != null) {
					if(attrMap.get(productId).getPlanARawMaterial() != null
							&& !attrMap.get(productId).getPlanARawMaterial().isEmpty() && !attrMap.get(productId).getPlanARawMaterial().equalsIgnoreCase("NA")) {
					productData.setPlanARawMaterial(attrMap.get(productId).getPlanARawMaterial());
				}
					if(attrMap.get(productId).getProductShapeEcom() != null
						&& !attrMap.get(productId).getProductShapeEcom().isEmpty() && !attrMap.get(productId).getProductShapeEcom().equalsIgnoreCase("NA")) {
						productData.setProductShapeEcom(attrMap.get(productId).getProductShapeEcom());
					}
			}
				
		
				mapSeasonaldata(productData,seasonDataMap,esSeriveResponseMap, primarySizeDescIndexMap, secondarySizeDescIndexMap, weaVariantPackDefinitionMap,cnhProductWeightIsActive);
				productResponseList.add(productData);
				
				
		}

		}
		

	}

	private void mapSeasonaldata(ProductDataResponse productData, Map<String, ProductSeasonality> seasonDataMap, Map<String, List<Products>> esSeriveResponseMap, Map<String, String> primarySizeDescIndexMap, Map<String, String> secondarySizeDescIndexMap,
			Map<String, PackDefinitionDTO> weaVariantPackDefinitionMap, Boolean cnhProductWeightIsActive) {
		// TODO Auto-generated method stub
		List<ProductCoreSeason> seasonBlockDataList = new ArrayList<>();
		List<String> missingGtinsVariantId = new ArrayList<>();
		for(Map.Entry<String, ProductSeasonality> seasonLevelEntry: seasonDataMap.entrySet()) {
			ProductCoreSeason seasonBlockData = new ProductCoreSeason();
			
			
			seasonBlockData.setSeasonName(seasonLevelEntry.getKey());
			List<Variant> activeVariantList = new ArrayList<>();
			for(ProductVariant entry: seasonLevelEntry.getValue().getProductVariants()) {
				if(entry.getActiveIndicator()== null || entry.getActiveIndicator()==1) {
					Variant activeVariant = new Variant();
				activeVariant.setProductVariantId(entry.getVariantId());
				activeVariant.setPrimSizeDesc(primarySizeDescIndexMap.get(entry.getVariantId()));
				activeVariant.setSecSizeDesc(secondarySizeDescIndexMap.get(entry.getVariantId()));
				
				if (cnhProductWeightIsActive && weaVariantPackDefinitionMap.containsKey(entry.getVariantId())) {
				    PackDefinitionDTO packDefinition = weaVariantPackDefinitionMap.get(entry.getVariantId());
				    ProductPack productPack = new ProductPack();
				    productPack.setProductWeight(packDefinition.getGrossWeight());
				    productPack.setLength(packDefinition.getLength());
				    productPack.setWidth(packDefinition.getWidth());
				    productPack.setHeight(packDefinition.getHeight());
				    productPack.setUnitOfDimension(packDefinition.getUnitOfDimension());
				    productPack.setUnitOfWeight(packDefinition.getUnitOfWeight());
				    activeVariant.setProductPack(productPack);
				}
				
				List<Barcode> barcodesList = new ArrayList<>();
				Barcode barcodes = new Barcode();
				barcodes.setCategory(Constants.CATEGORY_GTIN);
				barcodes.setType(Constants.TYPE_GTIN);
				if(entry.getGtinNo()!= null) {
				barcodes.setValue(entry.getGtinNo());
				} else {
						// adding the productId to get missing Gtins
						missingGtinsVariantId.add(entry.getVariantId());
					}
				barcodesList.add(barcodes);
				
				if (null !=esSeriveResponseMap && !esSeriveResponseMap.isEmpty() && null != esSeriveResponseMap.get(entry.getVariantId())) {
					if(null!=esSeriveResponseMap.get(entry.getVariantId()).get(0).getCustoms() && null!=esSeriveResponseMap.get(entry.getVariantId()).get(0).getCustoms().getCommodityCode() && !esSeriveResponseMap.get(entry.getVariantId()).get(0).getCustoms().getCommodityCode().isEmpty()) {
					seasonBlockData.setHsn(
							esSeriveResponseMap.get(entry.getVariantId()).get(0).getCustoms().getCommodityCode());
					}
					
					for (int j = 0; j < esSeriveResponseMap.get(entry.getVariantId()).get(0).getVersion().size(); j++) {
						if (0 == esSeriveResponseMap.get(entry.getVariantId()).get(0).getVersion().get(j).getVersion()) {

							Barcode barcodes1 = new Barcode();
							barcodes1.setCategory(Constants.CATEGORY_UPC);
							barcodes1.setType(Constants.TYPE_UPC);
							if (esSeriveResponseMap.get(entry.getVariantId()).get(0).getVersion().get(j)
									.getBarcodes() != null
									&& esSeriveResponseMap.get(entry.getVariantId()).get(0).getVersion().get(j).getBarcodes()
											.getUPC() != null
									&& !esSeriveResponseMap.get(entry.getVariantId()).get(0).getVersion().get(j)
											.getBarcodes().getUPC().isEmpty()) {
								barcodes1.setValue(esSeriveResponseMap.get(entry.getVariantId()).get(0).getVersion().get(j)
										.getBarcodes().getUPC().get(0));
								barcodesList.add(barcodes1);
							}

						}

					}
				}
				activeVariant.setBarcodes(barcodesList);						
				activeVariantList.add(activeVariant);
				}
			}
			seasonBlockData.setVariants(activeVariantList);
			seasonBlockDataList.add(seasonBlockData);
		}
		productData.setSeasons(seasonBlockDataList);
		
		try {
			if (missingGtinsVariantId.size() > 0) {

				List<String> missingGtinNVariantId = missingGtinsVariantId.stream().distinct()
						.collect(Collectors.toList());
				throw new Exception("Gtins Missing " + missingGtinNVariantId);

			}
		} catch (Exception e) {
			MandatoryFieldException mandatoryFieldException = new MandatoryFieldException(e);
			mandatoryFieldException.logErrorMessage();
		}
	}

	public Map<String, Object> createSubscribedFieldJson(List<ProductDataResponse> productDataResponse,
			ProductDataResponse structuredObject, Map<String, Object> PartnerSubscribedResponseMap, Boolean cnhProductWeightIsActive) {

		Map<String, Object> responseMap = new HashMap<>();
		ProductDataResponse productData = new ProductDataResponse();
		List<ProductDataResponse> productDataList = new ArrayList<>();

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.STROKENO)) {
			productData.setStrokeNo(structuredObject.getStrokeNo());
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.DEPT)) {
			productData.setDept(structuredObject.getDept());
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.PRIMSIZERANGE)) {
			productData.setPrimSizeRange(structuredObject.getPrimSizeRange());
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.SECSIZERANGE)) {
			productData.setSecSizeRange(structuredObject.getSecSizeRange());
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.ITEM)) {
			productData.setItem(structuredObject.getItem());
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.MERCHANTCATEGORY)) {
			productData.setMerchandCategory(structuredObject.getMerchandCategory());
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.PRODUCTTYPEC)) {
			productData.setProductTypeC(structuredObject.getProductTypeC());
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.PLANARAWMATERIAL)) {
			productData.setPlanARawMaterial(structuredObject.getPlanARawMaterial());
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.PRODUCTSHAPEECOM)) {
			productData.setProductShapeEcom(structuredObject.getProductShapeEcom());
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.COLOUR)) {
			Color colour = new Color();
			if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.COLOURCODE)) {
				colour.setColourCode(structuredObject.getColour().getColourCode().toString());
			}
			if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.COLOURDESC)) {
				colour.setColourDesc(structuredObject.getColour().getColourDesc().toString());
			}
			productData.setColour(colour);
		}

		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.PRODUCTDESC)) {
			ProductDescriptions productdesc = new ProductDescriptions();
			List<ProductDescriptions> productdescList = new ArrayList<>();
			List<Description> descList = new ArrayList<>();
			if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.LANGUAGE)) {
				productdesc.setLanguage(structuredObject.getProductDesc().get(0).getLanguage());
			}
			if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.DESCRIPTIONS)) {
				for (Description descResponse : structuredObject.getProductDesc().get(0).getDescriptions()) {
					Description desc = new Description();

					if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.DESCTYPE)) {
						desc.setDescType(descResponse.getDescType());
					}
					if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.DESC)) {
						desc.setDesc(descResponse.getDesc());
					}
					descList.add(desc);
				}
			}
			productdesc.setDescriptions(descList);
			productdescList.add(productdesc);
			productData.setProductDesc(productdescList);
		}

		List<ProductCoreSeason> seasonList = new ArrayList<>();
		if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.SEASONS)) {
			for (ProductCoreSeason seasonResponse : structuredObject.getSeasons()) {

				ProductCoreSeason seasons = new ProductCoreSeason();

				if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.SEASONNAME)) {
					seasons.setSeasonName(seasonResponse.getSeasonName());
				}
				if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.HSN)) {
					seasons.setHsn(seasonResponse.getHsn());
				}
				if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.COO)) {
					seasons.setCoo(seasonResponse.getCoo());
				}
				List<Variant> variantList = new ArrayList<>();
				if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.VARIANTS)) {
					for (Variant variantResponse : seasonResponse.getVariants()) {

						Variant var = new Variant();

						List<Barcode> barcodeList = new ArrayList<>();
						
						ProductPack productPack = new ProductPack();

						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.PRODUCTVARIANTID)) {
							var.setProductVariantId(variantResponse.getProductVariantId());
						}
						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.PRIMSIZEDESC)) {
							var.setPrimSizeDesc(variantResponse.getPrimSizeDesc());
						}
						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.SECSIZEDESC)) {
							var.setSecSizeDesc(variantResponse.getSecSizeDesc());
						}
						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.PRODUCTWEIGHT)) {
							productPack.setProductWeight(variantResponse.getProductPack().getProductWeight());
						}
						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.LENGTH)) {
							productPack.setLength(variantResponse.getProductPack().getLength());
						}
						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.WIDTH)) {
							productPack.setWidth(variantResponse.getProductPack().getWidth());
						}
						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.HEIGHT)) {
							productPack.setHeight(variantResponse.getProductPack().getHeight());
						}
						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.UNIT_OF_DIMENSION)) {
							productPack.setUnitOfDimension(variantResponse.getProductPack().getUnitOfDimension());
						}
						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.UNIT_OF_WEIGHT)) {
							productPack.setUnitOfWeight(variantResponse.getProductPack().getUnitOfWeight());
						}
						if(cnhProductWeightIsActive!=null && cnhProductWeightIsActive) {
						var.setProductPack(productPack);
						}
						
						if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.BARCODES)) {
							for (Barcode barcode : variantResponse.getBarcodes()) {
								Barcode barcodes = new Barcode();
								if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.CATEGORY)) {
									barcodes.setCategory(barcode.getCategory());
								}
								if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.TYPE)) {
									barcodes.setType(barcode.getType());
								}
								if (PartnerSubscribedResponseMap.containsKey(FieldSubscriptionKeys.VALUE)) {
									barcodes.setValue(barcode.getValue());
								}
								barcodeList.add(barcodes);
							}

							var.setBarcodes(barcodeList);
						}
						variantList.add(var);

					}

				}
				seasons.setVariants(variantList);
				seasonList.add(seasons);

			}
			productData.setSeasons(seasonList);

		}
		productDataList.add(productData);
		ObjectMapper productDataResponseMapper = new ObjectMapper();
		for (ProductDataResponse productResponse : productDataList) {
			responseMap = productDataResponseMapper.convertValue(productResponse, Map.class);
		}

		return responseMap;
	}
	
	private void addSellingAttrIfAny(Map<String, String> flatJsonResponse, Map<String, String> sellingAttr) {
		sellingAttr.entrySet().removeIf(x -> Constants.SUBSCRIBED_FIELD_PRODUCT_ID.equalsIgnoreCase(x.getKey()));
		sellingAttr.entrySet().removeIf(x -> Constants.SUBSCRIBED_FIELD_PARENT_PRODUCT_ID.equalsIgnoreCase(x.getKey()));
		sellingAttr.entrySet()
				.removeIf(x -> Constants.SUBSCRIBED_FIELD_PRODUCT_DEFINITION.equalsIgnoreCase(x.getKey()));
		sellingAttr.entrySet().removeIf(x -> Constants.SUBSCRIBED_FIELD_SHAPEORCUT.equalsIgnoreCase(x.getKey()));
		sellingAttr.entrySet().removeIf(x -> Constants.SUBSCRIBED_FIELD_COMPOSITION_LIST.equalsIgnoreCase(x.getKey()));
		sellingAttr.entrySet().removeIf(x -> Constants.SUBSCRIBED_FIELD_FOOTWEARSOLE.equalsIgnoreCase(x.getKey()));

		if (sellingAttr.get(Constants.SUBSCRIBED_FIELD_HEELHEIGHT) != null) {
			flatJsonResponse.put(FlatResponseKeys.HEELHEIGHT, sellingAttr.get(Constants.SUBSCRIBED_FIELD_HEELHEIGHT));
			sellingAttr.entrySet().removeIf(x -> Constants.SUBSCRIBED_FIELD_HEELHEIGHT.equalsIgnoreCase(x.getKey()));
		}

		if (sellingAttr.get(Constants.SUBSCRIBED_FIELD_MULTIPACKS) != null) {
			flatJsonResponse.put(FlatResponseKeys.MULTIPACKS, sellingAttr.get(Constants.SUBSCRIBED_FIELD_MULTIPACKS));
			sellingAttr.entrySet().removeIf(x -> Constants.SUBSCRIBED_FIELD_MULTIPACKS.equalsIgnoreCase(x.getKey()));
		}

		if (sellingAttr.get(Constants.SUBSCRIBED_FIELD_MASTER_PRODUCT_DESCRIPTION) != null) {
			flatJsonResponse.put(FlatResponseKeys.PDT_LONG_DESC,
					sellingAttr.get(Constants.SUBSCRIBED_FIELD_MASTER_PRODUCT_DESCRIPTION));
			sellingAttr.entrySet()
					.removeIf(x -> Constants.SUBSCRIBED_FIELD_MASTER_PRODUCT_DESCRIPTION.equalsIgnoreCase(x.getKey()));
		}

		flatJsonResponse.putAll(sellingAttr);
	}

	private void splittingFootWearSole(String[] footWearSoleArr, Map<String, String> flatJsonResponse,
			String articleVariantId) {
		if (footWearSoleArr != null && footWearSoleArr.length > 0) {
			for (int j = 0; j < footWearSoleArr.length; j++) {

				String[] footWearSplitStrArray = footWearSoleArr[j].split(":");
				if (footWearSplitStrArray != null && footWearSplitStrArray.length > 0) {
					if (Constants.UPPER.equalsIgnoreCase(StringUtils.trim(footWearSplitStrArray[0]))) {
						flatJsonResponse.put(FlatResponseKeys.MAIN_COMPOSITION,
								StringUtils.trim(footWearSplitStrArray[1]));
					}
					if (Constants.LINING_SOCK.equalsIgnoreCase(StringUtils.trim(footWearSplitStrArray[0]))) {
						flatJsonResponse.put(FlatResponseKeys.SECONDARY_COMPOSITION,
								StringUtils.trim(footWearSplitStrArray[1]));
					}
					if (Constants.OUTSOLE.equalsIgnoreCase(StringUtils.trim(footWearSplitStrArray[0]))) {
						flatJsonResponse.put(FlatResponseKeys.TERTIARY_COMPOSITION,
								StringUtils.trim(footWearSplitStrArray[1]));
					}
				} else {
					logger.info("Unable to split the Footwear_Sole with colon {} for articleVariantId {}",
							footWearSoleArr[j], articleVariantId);
				}

			}

		} else {
			logger.info("Unable to split the footwear_sole with new line char {}", articleVariantId);
		}
	}
	
	
	private void createFlatJson(List<ProductDataResponse> productDataResponse,
			List<Map<String, String>> productDataFlatResponse) {

		Map<String, String> variantIdnCategoryMap = new HashMap<>();

		Map<String, String> deptnCategoryMap = adminService.getCategoryMapping(Constants.ZALANDO_FRANCHISE_NUMBER);
		List<VariantCategoryDataEntity> variantLevelCategory = variantCategoryDataRepository
				.findByFranchiseNumber(Constants.ZALANDO_FRANCHISE_NUMBER);

		if (variantLevelCategory != null && !variantLevelCategory.isEmpty()) {
			variantIdnCategoryMap = variantLevelCategory.stream().collect(Collectors
					.toMap(VariantCategoryDataEntity::getProductVariantId, VariantCategoryDataEntity::getCategory));
		}

		// Calling estimated delivery date service
//		Map<String, List<ProductDataResponse>> estimatedDeliveryReqSeasonGroupMap = productDataResponse.stream()
//				.collect(Collectors.groupingBy(x -> x.getSeason()));
//
//		Map<String, List<String>> estimatedDeliveryServiceMap = new HashMap<>();
//		for (Map.Entry<String, List<ProductDataResponse>> entries : estimatedDeliveryReqSeasonGroupMap.entrySet()) {
//			List<String> entriesPdtId = new ArrayList<>();
//			for (int i = 0; i < entries.getValue().size(); i++) {
//				entriesPdtId.add(entries.getValue().get(i).getProductId());
//
//			}
//			estimatedDeliveryServiceMap.put(entries.getKey(), entriesPdtId);
//		}
//
//		Map<String, String> pdtEstimatedDeliveryMap = ibtService.getEstimatedDeliveryDate(estimatedDeliveryServiceMap);
//		<<<<<<<<< End of estimated service response fetching>>>>>>>>>

//		List<String> productIds = new ArrayList<>(productVariantIdMap.keySet());
//		Map<String, AttrServiceResponse> attrMap = cnhService.getAttributes(productIds);

//        Get selling attributes    
		logger.info("Start : fetch selling attribute  from Selling Attr Extract with batch size : {}",
				Constants.RECORD_PER_REQUEST);

		Map<String, List<ProductDataResponse>> departmentNStrokeMap = productDataResponse.stream()
				.collect(Collectors.groupingBy(x -> x.getDept() + x.getStrokeNo()));

		List<String> departmentNStrokeIds = new ArrayList<>();
		for (Map.Entry<String, List<ProductDataResponse>> entry : departmentNStrokeMap.entrySet()) {
			departmentNStrokeIds.add(entry.getKey());
		}

		Map<String, Map<String, String>> sellingAttributesMap = new HashMap<>();

		for (int i = 0; i < departmentNStrokeIds.size();) {
			int subIndex = (i + Constants.RECORD_PER_REQUEST) > departmentNStrokeIds.size()
					? departmentNStrokeIds.size()
					: (i + Constants.RECORD_PER_REQUEST);

			List<String> strokeIds = departmentNStrokeIds.subList(i, subIndex);
			SellingAttributesRequest sellingAttributesRequest = new SellingAttributesRequest();
			sellingAttributesRequest.setFranchiseNumber(Constants.ZALANDO_FRANCHISE_NUMBER);
			sellingAttributesRequest.setStrokeIds(strokeIds);

			Map<String, Map<String, String>> sellingAttributesPartMap = sellingAttributeService
					.getSellingAttributeMap(sellingAttributesRequest);

			if (sellingAttributesPartMap != null && !sellingAttributesPartMap.isEmpty()) {
				sellingAttributesMap.putAll(sellingAttributesPartMap);
			}

			i = i + Constants.RECORD_PER_REQUEST;
		}
		logger.info("End : fetch selling attribute  from Selling Attr Extract:");
//        End

		for (ProductDataResponse response : productDataResponse) {
			for (Variant variant : response.getSeasons().get(0).getVariants()) {
				String flag = "false";


					Map<String, String> flatJsonResponse = new LinkedHashMap<>();
					Map<String, String> sellingAttr = new HashMap<>();
					String categoryData = null;
					if (sellingAttributesMap != null && !sellingAttributesMap.isEmpty()) {
						sellingAttr = sellingAttributesMap.get(variant.getProductVariantId());
					}

					flatJsonResponse.put(FlatResponseKeys.PRODUCT_VARIANT_ID, variant.getProductVariantId());
					flatJsonResponse.put(FlatResponseKeys.PRODUCT_ID, response.getProductId());
					flatJsonResponse.put(FlatResponseKeys.PARENT_ID, response.getDept() + "-" + response.getStrokeNo());
					flatJsonResponse.put(FlatResponseKeys.SEASON, response.getSeasons().get(0).getSeasonName());
					flatJsonResponse.put(FlatResponseKeys.PRODUCT_TYPE, Constants.PDT_TYPE);
					flatJsonResponse.put(FlatResponseKeys.BRAND, Constants.BRAND);
					flatJsonResponse.put(FlatResponseKeys.PRIMARY_SIZE_DESC, variant.getPrimSizeDesc());
					flatJsonResponse.put(FlatResponseKeys.SECONDARY_SIZE_DESC, variant.getSecSizeDesc());
					flatJsonResponse.put(FlatResponseKeys.COLOR_DESCRIPTION, response.getColour().getColourDesc());

//					if (pdtEstimatedDeliveryMap != null && !pdtEstimatedDeliveryMap.isEmpty()
//							&& pdtEstimatedDeliveryMap.get(response.getProductId()) != null)
//					if(response.getEstimatedDeliveryDate()!= null)
//						flatJsonResponse.put(FlatResponseKeys.ESTIMATED_DELIVERY_DATE,
//								response.getEstimatedDeliveryDate());

					flatJsonResponse.put(FlatResponseKeys.PRODUCT_VARIATION, Constants.PDT_VARIATION);

					if (response.getPlanARawMaterial() != null
							&& !response.getPlanARawMaterial().isEmpty()) {
						flatJsonResponse.put(FlatResponseKeys.PLAN_A_RAW_MATERIAL,
								response.getPlanARawMaterial());
					}

					for (Barcode barcode : variant.getBarcodes()) {
						if (barcode.getCategory().equals(Constants.CATEGORY_GTIN)) {
							flatJsonResponse.put(FlatResponseKeys.EAN13, barcode.getValue());
						}
					}

					if (sellingAttr != null && !sellingAttr.isEmpty()) {
						if (deptnCategoryMap.get(response.getDept()) != null) {
							if (sellingAttr.get(Constants.SUBSCRIBED_FIELD_PRODUCT_DEFINITION) != null
									&& !sellingAttr.get(Constants.SUBSCRIBED_FIELD_PRODUCT_DEFINITION).isEmpty()) {

								categoryData = (deptnCategoryMap.get(response.getDept()) + Constants.ANGLE_BRACEKET
										+ sellingAttr.get(Constants.SUBSCRIBED_FIELD_PRODUCT_DEFINITION)).toLowerCase();

								if (sellingAttr.get(Constants.SUBSCRIBED_FIELD_SHAPEORCUT) != null
										&& !sellingAttr.get(Constants.SUBSCRIBED_FIELD_SHAPEORCUT).isEmpty()) {

									categoryData = categoryData + (Constants.ANGLE_BRACEKET
											+ sellingAttr.get(Constants.SUBSCRIBED_FIELD_SHAPEORCUT)).toLowerCase();
								}
							}
						}
						if (sellingAttr.get(Constants.FOOTWEAR_SOLE) != null) {
							String footWearSole = sellingAttr.get(Constants.FOOTWEAR_SOLE);

							footWearSole = footWearSole.replace("\n", "/");

							String[] footWearSoleArr = footWearSole.split("/");

							splittingFootWearSole(footWearSoleArr, flatJsonResponse, variant.getProductVariantId());

						} else {
							if (sellingAttr.get(Constants.SUBSCRIBED_FIELD_COMPOSITION_LIST) != null) {
								flatJsonResponse.put(FlatResponseKeys.MAIN_COMPOSITION,
										sellingAttr.get(Constants.SUBSCRIBED_FIELD_COMPOSITION_LIST));
							}
						}

						addSellingAttrIfAny(flatJsonResponse, sellingAttr);
						flag = "true";
					}

					if (!variantIdnCategoryMap.containsKey(variant.getProductVariantId())) {
						if (categoryData != null && !categoryData.isEmpty()) {
							flatJsonResponse.put(FlatResponseKeys.SELLING_HIERARCHY, categoryData);
						} else {
							
								if (deptnCategoryMap.get(response.getDept()) != null && response.getProductTypeC()!= null) {
									categoryData = (deptnCategoryMap.get(response.getDept()) + Constants.ANGLE_BRACEKET
											+ response.getProductTypeC()).toLowerCase();
									if (null != response.getProductShapeEcom() && !response.getProductShapeEcom().isEmpty()) {
										categoryData = categoryData + (Constants.ANGLE_BRACEKET
												+ response.getProductShapeEcom())
														.toLowerCase();

									}
									flatJsonResponse.put(FlatResponseKeys.SELLING_HIERARCHY, categoryData);
								}

							
						}
					} else {
						flatJsonResponse.put(FlatResponseKeys.SELLING_HIERARCHY,
								variantIdnCategoryMap.get(variant.getProductVariantId()));
					}
					// check FlatMap Has empty Field if so map from seasonality
					if (flatJsonResponse.get("Product_Title") == null) {
						for (Description description : response.getProductDesc().get(0).getDescriptions()) {
							if (description.getDescType().equals(Constants.LONG)) {
								flatJsonResponse.put(FlatResponseKeys.PDT_LONG_DESC, description.getDesc());
							}
						}

					}

					flatJsonResponse.put(FlatResponseKeys.IS_ENRICHED_ATTRIBUTE_ACTIVE, flag);

					productDataFlatResponse.add(flatJsonResponse);
					try {
						if (flatJsonResponse.get(FlatResponseKeys.SELLING_HIERARCHY) == null) {
							throw new Exception("Selling Hierarchy missed" + variant.getProductVariantId());

						}

					} catch (Exception e) {
						MandatoryFieldException mandatoryFieldException = new MandatoryFieldException(e);
						mandatoryFieldException.logErrorMessage();
						logger.error("Selling Hierarchy missed", variant.getProductVariantId());
					}
			}
		}
	}

}
update below test code based on above class so that ....this is populuated activeVariant.setPrimSizeDesc(primarySizeDescIndexMap.get(entry.getVariantId()));
				activeVariant.setSecSizeDesc(secondarySizeDescIndexMap.get(entry.getVariantId()));
				
@Test
public void processProductDetailsTestForInternationalPartner() throws JsonProcessingException {
	List<Integer> batchIdList = new ArrayList<Integer>();
	batchIdList.add(8196);
	List<ExtractorRequest> requestList = new ArrayList<>();
	ExtractorRequest request = new ExtractorRequest();
	request.setBatchId(123);
	request.setFranchiseNumber(8196);
	requestList.add(request);
	
	List<ProductDataResponse> productResponseList = new ArrayList<>();
	List<String> productIds = new ArrayList<>();
	productIds.add("000000000060292784");
	List<String> seasons = new ArrayList<>();
	seasons.add("WN21");
	Map<String, List<String>> productSeasonalityRequest = new HashMap<>();
	productSeasonalityRequest.put(seasons.get(0), productIds);

	Mockito.when(adminService.cnhProductWeightIsActive(Mockito.anyList(), Mockito.anyList())).thenReturn(true);
	Map<String, List<ProductSeasonality>> productSeasonalityMap = new HashMap<>();

	List<ProductSeasonality> productSeasonalityResponseList = new ArrayList<>();
	ProductSeasonality productSeasonalty = new ProductSeasonality();
	productSeasonalty.setProductId("000000000060292784");
	productSeasonalty.setProductType("Z001");
	productSeasonalty.setStrokeNum("1400v");
	productSeasonalty.setActiveVariantsCount(2);
	productSeasonalty.setDepartment("T11");
	productSeasonalty.setPrimarySizeRange("ZS");
	productSeasonalty.setSecondarySizeRange("");
	productSeasonalty.setMerchandiseCat("A42030101");
	productSeasonalty.setProductVariantsCount(2);
	Colour colour = new Colour();
	colour.setColourCode("Z0");
	colour.setColourDescription("White");
	productSeasonalty.setColour(colour);
	ProductDescription productDescription = new ProductDescription();
	productDescription.setLongDesc("10P Plain Briefs White");
	productDescription.setShortDesc("10P Plain Briefs");
	productSeasonalty.setProductDescription(productDescription);
	Hierarchy hierarchy = new Hierarchy();
	hierarchy.setLevel("08");
	hierarchy.setValue("G8-T0657");
	productSeasonalty.setHierarchy(hierarchy);
	Seasons season = new Seasons();
	season.setSeasonName("WN21");
	season.setSeasonYear("2021");
	productSeasonalty.setSeason(season);
	List<Attributes> AttList = new ArrayList<>();
	Attributes att = new Attributes();
	att.setAttDesc("M S BRAND");
	att.setAttTypeDesc("BRANDS");
	att.setAttDesc("jeans");
	att.setAttTypeDesc("PRODUCT TYPE (C)");
	AttList.add(att);
	productSeasonalty.setAttributes(AttList);
	List<ProductVariant> pvList = new ArrayList<>();
	ProductVariant pv = new ProductVariant();
	pv.setVariantId("000000060292784002");
	pv.setPrimarySizeIndex("7");
	pv.setPrimarySizeRange("ZS");
	pv.setSecondarySizeIndex("01");
	pv.setSecondarySizeRange("SZ");
	pv.setActiveIndicator(1);
	pvList.add(pv);
	ProductVariant pv1 = new ProductVariant();
	pv1.setVariantId("000000060292784004");
	pv1.setPrimarySizeIndex("5");
	pv1.setPrimarySizeRange("ZS");
	pv1.setSecondarySizeIndex("01");
	pv1.setSecondarySizeRange("SA");
	pv1.setActiveIndicator(1);
	pvList.add(pv1);
	productSeasonalty.setProductVariants(pvList);
	productSeasonalityResponseList.add(productSeasonalty);
	Mockito.when(cnhService.getSeasonalityCollection(Mockito.any(),Mockito.anyList(), Mockito.anyList()))
			.thenReturn(productSeasonalityResponseList);

	Map<String, String> primarySizeDescMap = new HashMap<>();
	primarySizeDescMap.put("000000060292784002", "2-3y");
	primarySizeDescMap.put("000000060292784004", "4-9y");
	Mockito.when(cnhService.getPrimarySizeData(Mockito.anyList(), Mockito.anyList())).thenReturn(primarySizeDescMap);

	Map<String, String> secondarySizeDescMap = new HashMap<>();
	secondarySizeDescMap.put("000000060292784002", "32");
	secondarySizeDescMap.put("000000060292784004", "34");
	
	
	Mockito.when(cnhService.getSecondarySizeData(Mockito.anyList(), Mockito.anyList())).thenReturn(secondarySizeDescMap);
	
	AttrServiceResponse attrServiceResponse = new AttrServiceResponse();
	attrServiceResponse.setPlanARawMaterial("Cotton");
	attrServiceResponse.setProductShapeEcom("FitJeans");
	Map<String, AttrServiceResponse> pdtIdnStyleEcomMap = new HashMap<>();
	pdtIdnStyleEcomMap.put("000000000060292784", attrServiceResponse);
	Mockito.when(cnhService.getAttributes(Mockito.anyList(), Mockito.anyList(), Mockito.anyList())).thenReturn(pdtIdnStyleEcomMap);

	Map<Integer,String> countryCodeMap = new HashMap<>();
	countryCodeMap.put(75, "DE");

	Mockito.when(ibtService.getCountryCode(Mockito.anyList(), Mockito.anyList())).thenReturn(countryCodeMap);
	List<CooResponse> cooResponseList = new ArrayList<>();
	CooResponse cooResponse = new CooResponse();
	cooResponse.setCountryNum(75);
	cooResponse.setFranchiseNumber(8196);
	cooResponse.setProductId("000000000060292784");
	cooResponse.setSeasonName("WN21");
	cooResponseList.add(cooResponse);
	
	Map<Integer, List<CooResponse>> cooResponseMap = new HashMap<>();
	cooResponseMap.put(8196, cooResponseList);
	Mockito.when(ibtService.getCOOForPartners(Mockito.anyList(), Mockito.anyList(), Mockito.anyMap())).thenReturn(cooResponseMap) ;
	ProductWeightRequest productWeightRequest = new ProductWeightRequest();
	productWeightRequest.setProductIds(productIds);
	Mockito.when(cnhService.getProductWehightProductPackService(productWeightRequest)).thenReturn(generateCnhProductPackServiceResponse());

	List<String> variantId = new ArrayList<>();
	variantId.add("000000060292784002");
	variantId.add("000000060292784004");
	productSeasonalityMap.put("000000000060292784", productSeasonalityResponseList);
	// calling ES Service
	List<ProductSeasonality> variant = productSeasonalityMap.get(productIds);
	Map<String, ProductSeasonality> variantSeasonDataMap = new HashMap<>();
	variantSeasonDataMap.put("000000000060292784", productSeasonalty);
	ProductSeasonality prductSeasonlity = variantSeasonDataMap.get(seasons);
	List<String> variantIds = new ArrayList<>();
	variantIds.add("000000060292784002");
	variantIds.add("000000060292784004");
	List<Products> esSeriveResponse = new ArrayList<>();
	Products product = new Products();
	product.setParentProductId("000000000060292784");
	product.setProductId("000000060292784002");
	List<StrokeDescription> strokeDesc = new ArrayList<>();
	StrokeDescription sd = new StrokeDescription();
	sd.setDescription("10P Plain Briefs");
	strokeDesc.add(sd);
	product.setStrokeDesc(strokeDesc);
	List<Version> version = new ArrayList<>();
	Version versin = new Version();
	versin.setVersion(0);
	Barcodes barcodes = new Barcodes();
	List<String> UPC = new ArrayList<>();
	UPC.add("23456");
	barcodes.setUPC(UPC);
	List<String> EAN13 = new ArrayList<>();
	EAN13.add("123456");
	barcodes.setEAN13(EAN13);
	versin.setBarcodes(barcodes);
	version.add(versin);
	product.setVersion(version);
	Customs customs = new Customs();
	customs.setCommodityCode("hsn");
	product.setCustoms(customs);
	esSeriveResponse.add(product);
	
	
	Mockito.when(esService.getVariantCollection(Mockito.any(),Mockito.anyList(), Mockito.anyList())).thenReturn(esSeriveResponse);
	
	List<AdminServiceResponse> list1 = new ArrayList<>();
	AdminServiceResponse objt = new AdminServiceResponse();
	objt.setDestinationPath("absb");
	objt.setFileNamePattern("filename");
	objt.setFranchiseNumber(8196);
	objt.setLatestSeason(false);
	objt.setNoOfSeasonsBackward(0);
	objt.setNoOfSeasonsForward(0);
	objt.setQualifier("ordering");
	list1.add(objt);
	Mockito.when(cnhService.getNextTwoSeasonFromCurrentSeason(Mockito.anyInt(),Mockito.anyInt(),Mockito.anyList(),Mockito.anyList())).thenReturn(seasons);
	

	Mockito.when(adminService.getDetailsForExtract(Mockito.anyList(), Mockito.anyList())).thenReturn(list1);

	Map<Integer, List<ProductDataResponse>> finalResponseMap = new HashMap<>();
	finalResponseMap.put(8196, productResponseList);
	List<ProductStagingResponse> stageTableList = new ArrayList<>();
	ProductStagingResponse response = new ProductStagingResponse();
	response.setFranchiseNumber(8196);
	response.setProductId("000000000060292784");
	response.setVariantIds(variantId);
	response.setSeason("WN21");
	stageTableList.add(response);
	Mockito.when(subscriptionService.getProductsForExtract(Mockito.anyList(), Mockito.anyList())).thenReturn(stageTableList);

	Map<String, String> deptnCat = new HashMap<>();
	deptnCat.put("T11", "KIDSWEAR");
	
	Map<String,List<String>> requestMap = new HashMap<>();
	requestMap.put("WN21", productIds);

	Mockito.lenient().when(adminService.getCategoryMapping(Constants.ZALANDO_FRANCHISE_NUMBER)).thenReturn(deptnCat);

	List<VariantCategoryDataEntity> variantLevelCategory = new ArrayList<>();
	VariantCategoryDataEntity variantCategoryDataEntity = new VariantCategoryDataEntity();
	variantCategoryDataEntity.setCategory("womens>clothing>jeans>FitJeans");
	variantCategoryDataEntity.setProductVariantId("000000060292784004");
	variantCategoryDataEntity.setFranchiseNumber(8196);
	variantLevelCategory.add(variantCategoryDataEntity);
	Mockito.lenient().when(variantCategoryDataRepository.findByFranchiseNumber(Constants.ZALANDO_FRANCHISE_NUMBER))
			.thenReturn(variantLevelCategory);

	//doubt
	Map<String, Map<String, String>> sellingAttrMap = new HashMap<>();
	Map<String, String> attrMap = new HashMap<String, String>();
	attrMap.put(Constants.SUBSCRIBED_FIELD_PRODUCT_ID, "000000000060292784");
	attrMap.put("CareInstruction", "Machine washable\\nTumble dry");
	attrMap.put("Footwear_Sole", "Upper: Leather\\nLining and Sock: Textile\\nOutsole: Other materials");
	sellingAttrMap.put("000000060292784002", attrMap);
	
	Mockito.lenient().when(sellingAttributeService.getSellingAttributeMap(Mockito.any(SellingAttributesRequest.class)))
			.thenReturn(sellingAttrMap);

	Mockito.lenient().when(
			blobUtils.uploadToFileShare(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any()))
			.thenReturn(true);
	
	
	List<PartnerFieldSubscriptionResponse> list = new ArrayList<>();
	PartnerFieldSubscriptionResponse partnerFieldSubscription = new PartnerFieldSubscriptionResponse();
	partnerFieldSubscription.setFrachiseNumber(8196);
	partnerFieldSubscription.setSubscribedFields(Arrays.asList("strokeNo","dept","primSizeRange","secSizeRange","item","merchandCategory","productTypeC","planARawMaterial","productShapeEcom","colour","colourCode","colourDesc","productDesc","language","descriptions","descType","desc","seasons","seasonName","hsn","coo","variants","productVariantId","primSizeDesc","secSizeDesc","barcodes","Category","type","value","length","width","height","unitOfDimension","unitOfWeight","productWeight"));
	list.add(partnerFieldSubscription);
	List<ExtractorRequest> batchRequestList = new ArrayList<>();
	ExtractorRequest batchRequest = new ExtractorRequest();
	batchRequest.setBatchId(123);
	batchRequest.setFranchiseNumber(8196);
	batchRequestList.add(batchRequest);
	List<Integer> franchiseList = new ArrayList<Integer>();
	franchiseList.add(8196);
	Mockito.lenient()
			.when(adminService.getSubscribeFieldsByExtractTypeId(Mockito.anyInt(), Mockito.any(), Mockito.any()))
			.thenReturn(list);
	

	boolean flagCount = processor.triggerProcess(requestList);

	Assertions.assertTrue(flagCount);
}