private async Task<ImportValidationResultInfo> MapAndValidate(RouteDTO dto, int index)
        {
            return await Task.Run(() =>
            {
                if (dto == null) return null;
                var entity = _mappingService.Map(dto);
                var exist = _ctx.tblRoutes.FirstOrDefault(p => p.Name.ToLower() == dto.Name.ToLower()||p.Code !=null &&p.Code.ToLower()==dto.Code.ToLower());

                entity.Id = exist == null ? Guid.NewGuid() : exist.RouteID;

                var res = _repository.Validate(entity);
                var vResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description =
                        string.Format("Row-{0} name or code=>{1}", index,
                                      entity.Name ?? entity.Code),
                    Entity = entity
                };
               
                return vResult;

            });


        }
        private async Task<ImportValidationResultInfo> MapAndValidate(CommodityOwnerTypeDTO dto, int index)
        {
            return await Task.Run(() =>
            {
                var entity = _mappingService.Map(dto);
                var exist =
                    _ctx.tblCommodityOwnerType.FirstOrDefault(
                        p =>
                        p.Name.ToLower() == dto.Name.ToLower() ||
                        p.Code != null && p.Code.Equals(dto.Code, StringComparison.CurrentCultureIgnoreCase));

                entity.Id = exist == null ? Guid.NewGuid() : exist.Id;

                var res = _repository.Validate(entity);
                var vResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description =
                        string.Format("Row-{0} name or code=>{1}", index,
                                      entity.Name ?? entity.Code),
                    Entity = entity
                };
                return vResult;

            });


        }
        private async Task<ImportValidationResultInfo> MapAndValidate(TerritoryDTO dto,int index)
        {
            return await Task.Run(() =>
                                      {
                                          if (dto == null) return null;
                                          var territory = _mappingService.Map(dto);
                                          var exist =
                                              _existingteritories.FirstOrDefault(
                                                  p => p.Name.ToLower() == territory.Name.ToLower());
                                          territory.Id = exist == null ? Guid.NewGuid() : exist.Id;

                                          var res = _territoryRepository.Validate(territory);
                                          var vResult = new ImportValidationResultInfo()
                                                            {
                                                                Results = res.Results,
                                                                Description =
                                                                    string.Format("Row-{0} code or name=>{1}", index,
                                                                                  territory.Name),
                                                                Entity =territory
                                                            };
                                          return vResult;

                                      });


        }
      public IList<ImportValidationResultInfo> Validate(List<DistributorSalesmanImport> entities)
      {
          IList<ImportValidationResultInfo> results = new List<ImportValidationResultInfo>();
          int count = 1;
          foreach (var item in ConstructDomainEntities(entities))
          {
              var res = _costCentreRepository.Validate(item);

              var importValidationResult = new ImportValidationResultInfo()
              {
                  Results = res.Results,
                  Description = "Row-" + count,
                  Entity = item,
                  EntityNameOrCode=item.CostCentreCode??item.Name
              };
              results.Add(importValidationResult);

              count++;

          }
          return results;
      }
        public IList<ImportValidationResultInfo> Validate(List<ShipToAddressImport> entities)
        {
           IList<ImportValidationResultInfo> results = new List<ImportValidationResultInfo>();
            int count = 1;
            foreach (var domainentity in ConstructDomainEntities(entities))
            {
                var res = _costCentreRepository.Validate(domainentity);

                var importValidationResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description = "Row-" + count,
                    Entity = domainentity
                };
                results.Add(importValidationResult);


                count++;

            }
            return results;
        }
 public async Task<IList<ImportValidationResultInfo>> ValidateAsync(List<CommodityOwnerTypeImport> entities)
 {
     return await Task.Run(async () =>
     {
         var results = new List<ImportValidationResultInfo>();
         var commodityTypes = await ConstructCommodityownerTypes(entities);
         int count = 0;
         foreach (var product in commodityTypes)
         {
             var res = await ValidateCommodityOwnerTypeAsync(product);
             var importValidationResult = new ImportValidationResultInfo()
             {
                 Results = res.Results,
                 Description = "Row-" + count,
                 Entity = product
             };
             results.Add(importValidationResult);
             count++;
         }
         return results;
     });
 }
        private ImportValidationResultInfo[] MapAndValidate(IEnumerable<ProductPricingDTO> dtos)
        {
            var result = new List<ImportValidationResultInfo>();
            int index = 0;
            foreach (var dto in dtos)
            {
                index++;
                var entity = ObjectFactory.Container.GetNestedContainer().GetInstance<IDTOToEntityMapping>().Map(dto);
                var exist =
                    ObjectFactory.Container.GetNestedContainer().GetInstance<CokeDataContext>().tblPricing.
                        FirstOrDefault(
                            p =>
                            p.ProductRef != null && p.ProductRef == dto.ProductMasterId &&
                            p.Tier == dto.ProductPricingTierMasterId);

                entity.Id = exist == null ? Guid.NewGuid() : exist.id;
                if (!HasProductPricingChanged(entity)) continue;
                var res =
                    ObjectFactory.Container.GetNestedContainer()
                        .GetInstance<IProductPricingRepository>().Validate(entity);
                var vResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description ="Pricing item",
                    Entity = entity
                };
                result.Add(vResult);
            }
            return result.ToArray();
        }
        public IList<ImportValidationResultInfo> Validate(List<ProductDiscountGroupImport> entities)
        {
            IList<ImportValidationResultInfo> results = new List<ImportValidationResultInfo>();
            int count = 1;
            foreach (var domainentity in ConstructDomainEntities(entities))
            {
                var res = _productDiscountGroupRepository.Validate(domainentity);

                var importValidationResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description = "Row-" + count,
                    Entity = domainentity,
                    EntityNameOrCode = domainentity.GroupDiscount !=null? domainentity.GroupDiscount.Code ?? domainentity.GroupDiscount.Name: ""
                };
                results.Add(importValidationResult);
                count++;
            }
            return results;
        }
        private async Task<ImportValidationResultInfo> MapAndValidate(DistributorSalesmanDTO dto, int index)
        {
            return await Task.Run(() =>
            {
                var entity = _mappingService.Map(dto);
                var exist = _ctx.tblCostCentre.FirstOrDefault(p => p.Cost_Centre_Code.ToLower() == dto.CostCentreCode.ToLower() && p.CostCentreType==(int)CostCentreType.DistributorSalesman);

                entity.Id = exist == null ? Guid.NewGuid() : exist.Id;

                var res = _repository.Validate(entity);
                var vResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description =string.Format("Row-{0} name or code=>{1}", index,
                                      entity.Name ?? entity.CostCentreCode),
                    Entity = entity
                };
                return vResult;

            });


        }
 public async Task<IList<ImportValidationResultInfo>> ValidateUsers(List<DistributorSalesmanImport> entities)
 {
     return await Task.Run(async () =>
     {
         var results = new List<ImportValidationResultInfo>();
         var users = await ConstructSalesmanUsers(entities);
         int count = 0;
         foreach (var user in users)
         {
             var res = await ValidateEntityAsync(user);
             var importValidationResult = new ImportValidationResultInfo()
             {
                 Results = res.Results,
                 Description =string.Format("Row-{0}=>{1}",count,user.Code),
                 Entity = user
             };
             results.Add(importValidationResult);
             count++;
         }
         return results;
     });
 }
        public IList<ImportValidationResultInfo> Validate(List<PricingImport> entities)
        {
            IList<ImportValidationResultInfo> results = new List<ImportValidationResultInfo>();
            int count = 1;
            foreach (var domainentity in ConstructDomainEntities(entities))
            {
                var res = ObjectFactory.GetInstance<IProductPricingRepository>().Validate(domainentity);

                var importValidationResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description = "Row-" + count,
                    Entity = domainentity
                    
                };
                results.Add(importValidationResult);

                count++;

            }
            return results;
        }
        private ImportValidationResultInfo[] MapAndValidate(IEnumerable<CommodityDTO> dtos)
        {
            var result = new List<ImportValidationResultInfo>();
            int index = 0;

            Parallel.ForEach(dtos, dto =>
                                       {
                                           var entity = ObjectFactory.GetInstance<IDTOToEntityMapping>().Map(dto);
                                           var exist = ObjectFactory.GetInstance
                                               <CokeDataContext>().tblCommodityType.FirstOrDefault(
                                                   p =>
                                                   p.Name.ToLower() == dto.Name.ToLower() ||
                                                   p.Code != null &&
                                                   p.Code.Equals(dto.Code, StringComparison.CurrentCultureIgnoreCase));

                                           entity.Id = exist == null ? Guid.NewGuid() : exist.Id;
                                           entity._SetStatus(EntityStatus.Active);
                                           var res =
                                               ObjectFactory.GetInstance
                                                   <ICommodityRepository>().Validate(entity);
                                           var vResult = new ImportValidationResultInfo()
                                           {
                                               Results = res.Results,
                                               Description =
                                                   string.Format("Row-{0} name or code=>{1}", index,
                                                                 entity.Name ?? entity.Code),
                                               Entity = entity
                                           };
                                           result.Add(vResult);
                                       });
            return result.ToArray();
        }
        private ImportValidationResultInfo[] MapAndValidate(IEnumerable<ProductBrandDTO> dtos)
        {
            var result = new List<ImportValidationResultInfo>();
            int index = 0;
            foreach (var dto in dtos)
            {
                index++;
                var entity = ObjectFactory.Container.GetNestedContainer().GetInstance<IDTOToEntityMapping>().Map(dto);
                var exist =ObjectFactory.Container.GetNestedContainer().GetInstance<CokeDataContext>().tblProductBrand.FirstOrDefault(p => p.name.ToLower() == dto.Name.ToLower()||
                    p.code !=null&& p.code.ToLower() == dto.Code.ToLower());

                entity.Id = exist == null ? Guid.NewGuid() : exist.id;

                var res =
                    ObjectFactory.Container.GetNestedContainer()
                    .GetInstance<IProductBrandRepository>().Validate(entity);
                var vResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description =
                        string.Format("Row-{0} name or code=>{1}", index,
                                      entity.Name ?? entity.Code),
                    Entity = entity
                };
                result.Add(vResult);
            }
            return result.ToArray();
        }
      public IList<ImportValidationResultInfo> ValidateUsers(List<DistributorSalesmanImport> entities)
      {
          IList<ImportValidationResultInfo> results = new List<ImportValidationResultInfo>();
          int count = 1;
          foreach (var user in ConstructSalesmanUsers(entities))
          {
              var res = _userRepository.Validate(user);

              var importValidationResult = new ImportValidationResultInfo()
              {
                  Results = res.Results,
                  Description = "Row-" + count,
                  Entity = user
              };
              results.Add(importValidationResult);

              count++;

          }
          return results;
      }
 public IList<ImportValidationResultInfo> Validate(List<ProductImport> entities)
 {
      IList<ImportValidationResultInfo> results=new List<ImportValidationResultInfo>();
     int count = 1;
     foreach (var product in ConstructProducts(entities))
     {
         var res = ObjectFactory.GetInstance<IProductRepository>().Validate(product);
        
             var importValidationResult = new ImportValidationResultInfo()
                                              {
                                                  Results = res.Results,
                                                  Description = "Row-"+count,
                                                  Entity = product,
                                                  EntityNameOrCode = product.ProductCode ?? product.Description
                                              };
             results.Add(importValidationResult);
            
       
         count++;
        
     }
     return results;
 }
        private async Task<ImportValidationResultInfo> MapAndValidate(DistributorDTO dto, int index)
        {
            return await Task.Run(() =>
            {
                if (dto == null) return null;
                var entity = _mappingService.Map(dto);
                var exist = _ctx.tblCostCentre.FirstOrDefault(p => p.Cost_Centre_Code == dto.CostCentreCode.ToLower()||
                    p.Name.ToLower()==dto.Name.ToLower() && p.CostCentreType==(int)CostCentreType.Distributor);
                var producer = ObjectFactory.GetInstance<IProducerRepository>().GetProducer();
                if (exist == null)
                {
                    var groupId = AddUserGroup("admin");
                   
                    entity.Id = Guid.NewGuid();
                    entity.ASM = AddUser("ASM", producer.Id, UserType.ASM, groupId);
                    entity.SalesRep = AddUser("SalesRep", producer.Id, UserType.SalesRep, groupId);
                    entity.Surveyor = AddUser("Surveyor", producer.Id, UserType.Surveyor, groupId);
                }
                else
                {
                    var groupId = AddUserGroup("admin");
                    var  test= ObjectFactory.GetInstance<ICostCentreRepository>().GetById(exist.Id) as Distributor;
                    entity.ASM = AddUser("ASM", producer.Id, UserType.ASM, groupId);
                    entity.SalesRep = AddUser("SalesRep", producer.Id, UserType.SalesRep, groupId);
                    entity.Surveyor = AddUser("Surveyor", producer.Id, UserType.Surveyor, groupId);
                    entity.Id = test.Id;

                }
                entity.ParentCostCentre = new CostCentreRef() {Id = producer.Id};
                var res = _repository.Validate(entity);
                var vResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description =string.Format("Row-{0} name or code=>{1}", index,
                                      entity.Name ?? entity.CostCentreCode),
                    Entity = entity
                };
                return vResult;

            });


        }
        private OutletDTO[] ConstructDtOs(IEnumerable<ImportEntity> entities)
        {
            var items = new List<OutletDTO>();
            var vris = new List<ImportValidationResultInfo>();
            items.AddRange(entities.Select(n => n.Fields).Select(row =>
            {
                var outletCode = SetFieldValue(row, 1);
                var name = SetFieldValue(row, 2);
                var distributrCode = SetFieldValue(row, 3);
                var routeCode = SetFieldValue(row, 4);
                var outletCategory = SetFieldValue(row, 5);
                var outletype = SetFieldValue(row, 6);
                var discountGroupCode = SetFieldValue(row, 7);
                var productPricingTierCode = SetFieldValue(row, 8);
                var vatClassCode = SetFieldValue(row, 9);
                var specialPricingTierCode = SetFieldValue(row, 10);
                var lat = SetFieldValue(row, 11);
                var longt = SetFieldValue(row, 12);
                if (string.IsNullOrEmpty(outletCode) || string.IsNullOrEmpty(name))
                {
                    var res = new List<ValidationResult>
                                      {
                                          new ValidationResult(
                                              string.Format("Outlet name or code is null"))
                                      };
                    var vri = new ImportValidationResultInfo()
                                  {
                                      Results = res
                                  };
                    vris.Add(vri);
                    return null;
                }
                if (string.IsNullOrEmpty(distributrCode))
                {
                    var res = new List<ValidationResult>
                                      {
                                          new ValidationResult(
                                              string.Format("Distributr Code is required for salesman {0}",distributrCode))
                                      };
                   vris.Add(new ImportValidationResultInfo()
                    {
                        Results = res
                    });
                    return null;
                }

                if (string.IsNullOrEmpty(routeCode))
                {
                    var res = new List<ValidationResult>
                                      {
                                          new ValidationResult(
                                              string.Format(
                                                  "Route code is empty or null"))
                                      };
                    
                    vris.Add(new ImportValidationResultInfo()
                    {
                        Results = res
                    });
                    return null;

                }

                var distributr = GetDistributr(distributrCode);
                if (distributr == null)
                {
                    var res = new List<ValidationResult>
                                  {
                                      new ValidationResult(
                                          string.Format(
                                              "Distributor with code={0} not found",
                                              distributrCode))
                                  };
                    vris.Add(new ImportValidationResultInfo()
                    {
                        Results = res
                    });
                    return null;
                }

                var route = GetRoute(routeCode);
                if (route == null)
                {
                    var res = new List<ValidationResult>
                                      {
                                          new ValidationResult(
                                              string.Format(
                                                  "Route with code={0} not found",routeCode))
                                      };
                    vris.Add(new ImportValidationResultInfo()
                                 {
                                     Results = res
                                 });
                    return null;
                }
                var category = GetOutletCategory(outletCategory);
                var type = GetOutletType(outletype);
                var vatclass = GetVATClass(vatClassCode);
                var pricingtier = GetPricingTier(productPricingTierCode);
                var specialTier = GetPricingTier(specialPricingTierCode);
                var discountGroup = GetDiscountGroup(discountGroupCode);
                return new OutletDTO()
                {
                   CostCentreCode = outletCode,
                   DiscountGroupMasterId = discountGroup !=null?discountGroup.id:default(Guid),
                   Name = name,
                   ParentCostCentreId = distributr.Id,
                   RouteMasterId = route.RouteID,
                   OutletCategoryMasterId = category.id,
                   OutletProductPricingTierMasterId = pricingtier != null ? pricingtier.id : default(Guid),
                   OutletTypeMasterId = type.id,
                   VatClassMasterId =vatclass!=null? vatclass.id:Guid.Empty,
                   SpecialPricingTierMasterId = specialTier != null ? specialTier.id : default(Guid),
                   Latitude = lat,
                   Longitude = longt,
                   CostCentreTypeId = (int)CostCentreType.Outlet,
                   IsApproved = true,
                   StatusId = (int)EntityStatus.Active

                };
            }));
            //In the class scope:
            Object lockMe = new Object();

            //In the function
            lock (lockMe)
            {
                validationResultInfos.AddRange(vris);
            }
           
          
            return items.Where(p=>p !=null).ToArray();

        }
        private ImportValidationResultInfo[] MapAndValidate(List<OutletDTO> dtos)
        {
            var result = new List<ImportValidationResultInfo>();
            int index = 0;
            foreach (var dto in dtos)
            {
                index++;
                var entity = ObjectFactory.Container.GetNestedContainer().GetInstance<IDTOToEntityMapping>().Map(dto);
                var exist =
                    ObjectFactory.Container.GetNestedContainer().GetInstance<CokeDataContext>().tblCostCentre.
                        FirstOrDefault(p =>
                                       p.Cost_Centre_Code != null &&
                                       p.Cost_Centre_Code.ToLower().Trim() == dto.CostCentreCode.ToLower().Trim() &&
                                       p.CostCentreType == (int) CostCentreType.Outlet);

                entity.Id = exist == null ? Guid.NewGuid() : exist.Id;
                if (OutletHasChanged(entity))
                {
                    var res =
                    ObjectFactory.Container.GetNestedContainer()
                        .GetInstance<ICostCentreRepository>().Validate(entity);
                    var vResult = new ImportValidationResultInfo()
                    {
                        Results = res.Results,
                        Description =
                            string.Format("Row-{0} Description or code=>{1}", index,
                                          entity.Name ?? entity.CostCentreCode),
                        Entity = entity
                    };
                    result.Add(vResult);
                }
                
            }
            return result.ToArray();
        }
       public async Task<IList<ImportValidationResultInfo>> ValidateAsync(List<ProductImport> entities)
       {
           var task = Task.Run(async () =>
                                               {
                                                   var results = new List<ImportValidationResultInfo>();
                                                   var products = ConstructProducts(entities);
                                                   int count = 0;
                                                   foreach (var product in products)
                                                   {
                                                       var res = await ValidateProductAsync(product);
                                                       var importValidationResult = new ImportValidationResultInfo()
                                                       {
                                                           Results = res.Results,
                                                           Description = "Row-" + count,
                                                           Entity = product,
                                                           EntityNameOrCode = product.ProductCode ?? product.Description
                                                       };
                                                       results.Add(importValidationResult);
                                                       count++;
                                                   }
                                                   return results;
                                               });
           return await task;

       }
        private ImportValidationResultInfo[] MapAndValidate(IEnumerable<CommodityOwnerDTO> dtos)
        {
            var result = new List<ImportValidationResultInfo>();
            int index = 0;

            Parallel.ForEach(dtos, dto =>
            {
                var entity = ObjectFactory.GetInstance<IDTOToEntityMapping>().Map(dto);
                var exist = ObjectFactory.GetInstance
                    <CokeDataContext>().tblCommodityOwner.FirstOrDefault(
                        p =>
                        p.IdNo.ToLower() == dto.IdNo.ToLower());

                entity.Id = exist == null ? Guid.NewGuid() : exist.Id;
               var res =
                    ObjectFactory.GetInstance
                        <ICommodityOwnerRepository>().Validate(entity);
                var vResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description =
                        string.Format("Row-{0} name or code=>{1}", index,
                                      entity.FirstName ?? entity.Code),
                    Entity = entity
                };
                result.Add(vResult);
            });
            return result.ToArray();
        }
        private ImportValidationResultInfo[] MapAndValidate(IEnumerable<ProductGroupDiscountDTO> dtos)
        {
            var result = new List<ImportValidationResultInfo>();
            int index = 0;
            foreach (var dto in dtos)
            {
                index++;
                var entity = ObjectFactory.Container.GetNestedContainer().GetInstance<IDTOToEntityMapping>().Map(dto);
                var exist =
                    ObjectFactory.Container.GetNestedContainer().GetInstance<CokeDataContext>().tblProductDiscountGroup.
                        FirstOrDefault(p =>p.DiscountGroup ==dto.DiscountGroupMasterId && p.tblProductDiscountGroupItem.Any(n=>n.ProductRef==dto.ProductMasterId));

                entity.Id = exist == null ? Guid.NewGuid() : exist.id;
                if (!HasChanged(entity)) continue;
                var res =
                    ObjectFactory.Container.GetNestedContainer()
                        .GetInstance<IProductDiscountGroupRepository>().Validate(entity);
                var vResult = new ImportValidationResultInfo()
                {
                    Results = res.Results,
                    Description =
                        string.Format("Row-{0} Description or code=>{1}", index,
                                      "product discount group item"),
                    Entity = entity
                };
                result.Add(vResult);
            }
            return result.ToArray();
        }
       public async Task<IList<ImportValidationResultInfo>> ValidateAsync(List<AfcoProductPricingImport> entities)
       {
           return await Task.Run(async () =>
                                           {
                                               IList<ImportValidationResultInfo> results =
                                                   new List<ImportValidationResultInfo>();
                                               int count = 1;
                                               var pricings = await ConstructPricingDomainEntities(entities);
                                               foreach (var domainentity in pricings)
                                               {
                                                   var res =await ValidatePricingAsync(domainentity);

                                                   var importValidationResult = new ImportValidationResultInfo()
                                                                                    {
                                                                                        Results = res.Results,
                                                                                        Description = "Row-" + count,
                                                                                        Entity = domainentity
                                                                                    };
                                                   results.Add(importValidationResult);

                                                   count++;

                                               }
                                               return results;
                                           });
       }