/// <summary>
        /// Update the quota remaining values in the GMISampleQuotasObject
        /// </summary>
        /// <param name="GMISampleQuotasObject"></param>
        /// <param name="QuotasLiveObject"></param>
        public void UpdateQuotaRemaingValues(GMISampleQuotasObject gmiSampleQuotasObject, QuotasLiveObject quotasLiveObject)
        {
            if (quotasLiveObject.QuotasLiveList == null)
                return;

            foreach (QuotaLiveObject quotaLiveObject in quotasLiveObject.QuotasLiveList)
            {
                var quota = gmiSampleQuotasObject.GMIQuotasList.Where(p => p.InternalQuotaId == quotaLiveObject.InternalQuotaId).ToList();
                if (quota.Count > 0)
                    quota[0].QuotaRemaining = quotaLiveObject.QuotaRemaining;
            }
        }
        /// Fetches all the Quota remaining values from LiveMatch for a specific study
        /// </summary>
        /// <param name="studyId"></param>
        public QuotasLiveObject GetQuotaRemainingValues(int studyId)
        {
            var parameters = new Hashtable { { "data[study_id]", studyId }, { "data[quota_type]", "TP" } };
            QuotasLiveObject quotasLiveObject = new QuotasLiveObject();

            string service = "fetchMulti";
            LogUtil.CallingService(service, LogUtil.getHashtableString(parameters));

            try
            {
                var result = CallQuotaLiveService("fetchMulti", parameters);

                LogUtil.CallSuccess(service, result.ToString());

                quotasLiveObject = ProcessQuotaLiveResponse(result);
            }
            catch
            {
                LogUtil.CallFail(service);
                throw;
            }
            return quotasLiveObject;
        }
        private bool CreateQuotaCell(OfferObject offerObject, QuotasLiveObject quotasLiveObject)
        {
            LoggingUtility log = LoggerFactory.GetLogger();
            IQuotaExpressionRepository quotaExpressionRepository = new QuotaExpressionRepository();
            IQuotaMappingRepository quotaMappingRepository = new QuotaMappingRepository();
            ISampleMappingRepository sampleMappingRepository = new SampleMappingRepository();

            try
            {
                var parameters = new Dictionary<string, string>();
                var sampleId = offerObject.SampleId.Value;
                parameters.Add("SampleId", sampleId.ToString());
                // ensure quota related data in the database is purged for this sample
                quotaExpressionRepository.Delete(sampleId);
                sampleMappingRepository.Delete(sampleId);
                quotaMappingRepository.DeletebySampleId(sampleId);

                int studyId = Convert.ToInt32(offerObject.StudyId);
                log.Debug("Calling SteamService to get the attributes at the quota cell level for studyId: " + studyId + ", sample: " + sampleId);
                SteamStudyObject steamStudyObject = new SteamStudy().GetQuotasAttributes(studyId, sampleId);

                if (steamStudyObject.ExpressionsXML == null || steamStudyObject.ExpressionsXML.Contains(DocumentNotFound) || !steamStudyObject.ExpressionsXML.Contains("<data>"))
                {
                    log.Info(new ErrorObject(ErrorKey.ERR_INTERNAL_BACKEND_STEAM_UNAVAILABLE, parameters).Message);
                    return false;
                }
                // In order for the attributes names to be consistent with what is returned to suppliers on other services
                // like CodeBook and LiveOffers need to remove the prefix panelist_ from all attribute names (added by steam service)
                steamStudyObject.ExpressionsXML = steamStudyObject.ExpressionsXML.Replace("panelist_", null);

                log.Debug("Calling GMI GetSample service to get the mapping from internal to external ids for studyId: " + studyId + ", sample: " + sampleId);
                GMISampleQuotasObject gmiSampleQuotasObject = new GMIStudy().GetGMISamples(studyId, sampleId);
                if (gmiSampleQuotasObject == null || (gmiSampleQuotasObject.GMIQuotasList == null && gmiSampleQuotasObject.GMISampleQuotasList == null))
                {
                    log.Info(new ErrorObject(ErrorKey.ERR_INTERNAL_BACKEND_GET_SAMPLE_UNAVAILABLE, parameters).Message);
                    return false;
                }

                log.Debug("Calling fetchMulti service to get the Quota Remaining for studyId: " + studyId + ", sample: " + sampleId);
                new QuotaLiveMatch().UpdateQuotaRemaingValues(gmiSampleQuotasObject, quotasLiveObject);
                new SteamStudy().UpdateQuotaExpression(steamStudyObject, gmiSampleQuotasObject);

                steamStudyObject.OfferId = offerObject.Id;
                quotaExpressionRepository.Insert(steamStudyObject);

                foreach (GMIQuotaObject gmiQuotaObject in gmiSampleQuotasObject.GMIQuotasList)
                {
                    gmiQuotaObject.OfferId = offerObject.Id;
                    quotaMappingRepository.Insert(gmiQuotaObject);
                }

                foreach (GMISampleObject gmiSampleObject in gmiSampleQuotasObject.GMISampleQuotasList)
                {
                    gmiSampleObject.OfferId = offerObject.Id;
                    sampleMappingRepository.Insert(gmiSampleObject);
                }
            }
            catch (Exception e)
            {
                log.Error("An error occurred while trying to create the quota cells for offerId " + offerObject.Id.ToString(), e);
                throw;
            }
            return true;
        }
        private bool UpdateQuotaCell(OfferObject offerObject, SteamStudyObject steamStudyObject, QuotasLiveObject quotasLiveObject)
        {
            var sampleId = offerObject.SampleId.Value;
            LoggingUtility log = LoggerFactory.GetLogger();

            try
            {
                QuotaMappingRepository quotaMappingRepository = new QuotaMappingRepository();
                GMISampleObject sampleObject = new SampleMappingRepository().SelectByID(steamStudyObject.SampleId);

                List<GMISampleObject> GMISampleObjectList = new List<GMISampleObject>();
                GMISampleObjectList.Add((sampleObject != null) ? sampleObject : new GMISampleObject());
                List<GMIQuotaObject> GMIQuotasList = quotaMappingRepository.SelectBySampleID(steamStudyObject.SampleId).ToList();

                bool needUpdate = false;
                foreach (GMIQuotaObject gmiQuotaObject in GMIQuotasList)
                {
                    var quota = quotasLiveObject.QuotasLiveList.Where(p => p.InternalQuotaId == gmiQuotaObject.InternalQuotaId).Where(p => p.InternalSampleId == sampleObject.InternalSampleId).ToList();
                    if (quota.Count() > 0 && gmiQuotaObject.QuotaRemaining != quota[0].QuotaRemaining)
                    {
                        gmiQuotaObject.QuotaRemaining = quota[0].QuotaRemaining;
                        quotaMappingRepository.Update(gmiQuotaObject);
                        needUpdate = true;
                    }
                }

                if (needUpdate)
                {
                    // There was a change in quota remaining, update the quota expressions XML to reflect the new values
                    log.Debug("Update the quota remaining for sample: " + sampleId);
                    GMISampleQuotasObject gmiSampleQuotasObject = new GMISampleQuotasObject();
                    gmiSampleQuotasObject.GMIQuotasList = GMIQuotasList;
                    gmiSampleQuotasObject.GMISampleQuotasList = GMISampleObjectList;

                    new SteamStudy().UpdateQuotaExpression(steamStudyObject, gmiSampleQuotasObject);
                    new QuotaExpressionRepository().updateQuotaExpressionsXML(steamStudyObject);
                }
            }
            catch (Exception e)
            {
                log.Error("An error occurred while trying to update the quota cells for offerId " + offerObject.Id.ToString(), e);
                throw;
            }

            return true;
        }
        /// <summary>
        /// Get the quota remaining values from Live match 
        /// </summary>
        /// <param name="result"></param>
        /// <returns>QuotasLiveObject</returns>
        private QuotasLiveObject ProcessQuotaLiveResponse(XDocument result)
        {
            QuotasLiveObject quotasLiveObject = new QuotasLiveObject();

            try
            {
                quotasLiveObject = (from openSampleNode in result.Descendants("Data")
                                    select new QuotasLiveObject()
                                         {
                                             QuotasLiveList = (from QuotaLive in openSampleNode.Descendants("Item")
                                                               select new QuotaLiveObject()
                                                                   {
                                                                       InternalSampleId = XmlUtil.GetSafeIntegerNodeValue(QuotaLive.Element("SampleId")),
                                                                       InternalQuotaId = XmlUtil.GetSafeIntegerNodeValue(QuotaLive.Element("QuotaId")),
                                                                       QuotaRemaining = XmlUtil.GetSafeIntegerNodeValue(QuotaLive.Element("NumRemaining"))
                                                                   }).ToList()

                                         }).FirstOrDefault();

                if (quotasLiveObject == null)
                    return new QuotasLiveObject();

            }
            catch
            {
                throw;
            }

            return quotasLiveObject;
        }