public void SaveGeoTargetingAds(int customerFK, CampaignSetupModel model, CampaignSetupModel oldModel)
        {
            using (var dbcontext = new SemplestModel.Semplest())
            {
                var queryProd = (from c in dbcontext.ProductGroups
                                 where
                                     c.CustomerFK == customerFK &&
                                     c.ProductGroupName == model.ProductGroup.ProductGroupName
                                 select c).Single();
                var promo = GetPromotionFromProductGroup(queryProd, model.ProductGroup.ProductPromotionName);

                List<PromotionAd> addAds;
                List<int> updateAds;
                List<int> deleteAds;
                GoogleViolation[] gv;
                var shouldscheduleAds = AddPromotionAdsToPromotion(promo, model, customerFK, oldModel,
                                                   out addAds, out updateAds, out deleteAds);
                if (shouldscheduleAds)
                {
                    List<GoogleAddAdRequest> verifyAds =
                      model.AdModelProp.Ads.Where(t => !t.Delete).Select(pad => new GoogleAddAdRequest
                      {
                          promotionAdID = promo.PromotionPK,
                          headline = pad.AdTitle,
                          description1 =
                              pad.AdTextLine1,
                          description2 =
                              pad.AdTextLine2
                      }).ToList();
                    gv = ValidateAds(model.AdModelProp.LandingUrl,
                                                                           model.AdModelProp.DisplayUrl, verifyAds);
                    if (gv.Length > 0)
                        throw new Exception(gv.First().shortFieldPath + ": " + gv.First().errorMessage);
                }
                var shouldUpdateGeoTargeting = AddGeoTargetingToPromotion(promo, model, customerFK, oldModel,
           ((IObjectContextAdapter)dbcontext).ObjectContext);
                if (shouldUpdateGeoTargeting)
                {
                    var gtos = SerializeToGeoTargetObjectArray(model);
                    if (gtos.Any())
                    {
                        gv = ValidateGeotargeting(gtos);
                        if (gv.Length > 0)
                            throw new Exception(gv.First().shortFieldPath + ": " + gv.First().errorMessage);
                        var op = new System.Data.Objects.ObjectParameter("totalSize", typeof(int));
                        string valueDelimiter = ",";
                        string listDelimiter = ";";
                        dbcontext.GetMSNGeoLocation(null, SerializeToCommaDlimitedString(model.AdModelProp.Addresses, valueDelimiter, listDelimiter), valueDelimiter, listDelimiter, op);
                        if ((int)op.Value > 250)
                            throw new Exception("geotarget limit");
                    }
                }
                promo.LandingPageURL = model.AdModelProp.LandingUrl.Trim();
                promo.DisplayURL = model.AdModelProp.DisplayUrl.Trim();
                dbcontext.SaveChanges();
                _savedCampaign = true;

                if (promo.IsLaunched)
                {
                    var sw = new ServiceClientWrapper();
                    var adEngines = new List<string>();
                    adEngines.AddRange(
                            promo.PromotionAdEngineSelecteds.Select(
                                pades => pades.AdvertisingEngine.AdvertisingEngine1));
                    if (shouldscheduleAds)
                    {
                        if (addAds.Any())
                        {
                            var addAdsIds =
                                addAds.Select(
                                    promoAd =>
                                    dbcontext.PromotionAds.Single(
                                        row =>
                                        row.AdTextLine1 == promoAd.AdTextLine1 && row.AdTextLine2 == promoAd.AdTextLine2 &&
                                        row.AdTitle == promoAd.AdTitle && row.PromotionFK == promo.PromotionPK).
                                        PromotionAdsPK).ToList();
                            sw.scheduleAds(promo.PromotionPK, addAdsIds, adEngines,
                                           SEMplestConstants.PromotionAdAction.Add);
                        }
                        if (updateAds.Any())
                            sw.scheduleAds(promo.PromotionPK, updateAds, adEngines,
                                           SEMplestConstants.PromotionAdAction.Update);
                        if (deleteAds.Any())
                            sw.scheduleAds(promo.PromotionPK, deleteAds, adEngines,
                                           SEMplestConstants.PromotionAdAction.Delete);
                    }
                    if (shouldUpdateGeoTargeting)
                        sw.scheduleUpdateGeoTargeting(promo.PromotionPK, adEngines);
                }
            }
        }
        public string SaveGeoTargetingAds(int customerFK, CampaignSetupModel model, CampaignSetupModel oldModel)
        {
            var rString = new System.Text.StringBuilder();
            using (var dbcontext = new SemplestModel.Semplest())
            {
                var queryProd = (from c in dbcontext.ProductGroups
                                 where
                                     c.CustomerFK == customerFK &&
                                     c.ProductGroupName == model.ProductGroup.ProductGroupName
                                 select c).Single();
                var promo = GetPromotionFromProductGroup(queryProd, model.ProductGroup.ProductPromotionName);

                List<PromotionAd> addAds;
                List<int> updateAds;
                List<int> deleteAds;
                GoogleViolation[] gv;
                PromoAdTableType at;
                var shouldscheduleAds = AddPromotionAdsToPromotion(promo, model, customerFK, oldModel,
                                                   out addAds, out updateAds, out deleteAds, out at);
                if (shouldscheduleAds)
                {
                    List<GoogleAddAdRequest> verifyAds =
                      model.AdModelProp.Ads.Where(t => !t.Delete).Select(pad => new GoogleAddAdRequest
                      {
                          promotionAdID = promo.PromotionPK,
                          headline = pad.AdTitle,
                          description1 =
                              pad.AdTextLine1,
                          description2 =
                              pad.AdTextLine2
                      }).ToList();
                    gv = ValidateAds(model.AdModelProp.LandingUrl,
                                                                           model.AdModelProp.DisplayUrl, verifyAds);
                    if (gv.Length > 0)
                        throw new Exception(gv.First().shortFieldPath + ": " + gv.First().errorMessage);
                }
                GeoTargetTableType gt;
                var shouldUpdateGeoTargeting = AddGeoTargetingToPromotion(promo, model, customerFK, oldModel, out gt);
                if (shouldUpdateGeoTargeting)
                {
                    var gtos = SerializeToGeoTargetObjectArray(model);
                    if (gtos.Any())
                    {
                        gv = ValidateGeotargeting(gtos);
                        if (gv.Length > 0)
                            throw new Exception(gv.First().shortFieldPath + ": " + gv.First().errorMessage);
                        var op = new System.Data.Objects.ObjectParameter("totalSize", typeof(int));
                        const string valueDelimiter = ",";
                        const string listDelimiter = ";";
                        dbcontext.GetMSNGeoLocation(null, SerializeToCommaDlimitedString(model.AdModelProp.Addresses, valueDelimiter, listDelimiter), valueDelimiter, listDelimiter, op);
                        if ((int)op.Value > 250)
                            throw new Exception("geotarget limit");
                    }
                }

                var parameter = new SqlParameter("PromotionPK", promo.PromotionPK) { SqlDbType = SqlDbType.Int };
                var parameter2 = new SqlParameter("LandingUrl", model.AdModelProp.LandingUrl.Trim()) { SqlDbType = SqlDbType.NVarChar };
                var parameter3 = new SqlParameter("DisplayUrl", model.AdModelProp.DisplayUrl.Trim()) { SqlDbType = SqlDbType.NVarChar };
                var parameter4 = new SqlParameter("GeoTVP", gt) { SqlDbType = SqlDbType.Structured, TypeName = "GeoTargetTableType" };
                var parameter5 = new SqlParameter("AdTVP", at) { SqlDbType = SqlDbType.Structured, TypeName = "PromoAdTableType" };
                var parameters = new object[] {parameter, parameter2, parameter3, parameter4, parameter5};
                var results = ((IObjectContextAdapter)dbcontext).ObjectContext.ExecuteStoreQuery<RVal>("exec UpdateGeoTargetingPromoAds @PromotionPK, @LandingUrl, @DisplayUrl, @GeoTVP, @AdTVP", parameters);
                _savedCampaign = true;
                foreach (var r in results)
                {
                    rString.Append(r.UID);
                    rString.Append("=");
                    rString.Append(r.PKEY);
                    rString.Append(",");
                }
                    
                if (promo.IsLaunched)
                {
                    var sw = new ServiceClientWrapper();
                    var adEngines = new List<string>();
                    adEngines.AddRange(
                            promo.PromotionAdEngineSelecteds.Select(
                                pades => pades.AdvertisingEngine.AdvertisingEngine1));
                    if (shouldscheduleAds)
                    {
                        if (addAds.Any())
                        {
                            var addAdsIds =
                                addAds.Select(
                                    promoAd =>
                                    dbcontext.PromotionAds.Single(
                                        row =>
                                        row.AdTextLine1 == promoAd.AdTextLine1 && row.AdTextLine2 == promoAd.AdTextLine2 &&
                                        row.AdTitle == promoAd.AdTitle && row.PromotionFK == promo.PromotionPK).
                                        PromotionAdsPK).ToList();
                            sw.scheduleAds(promo.PromotionPK, addAdsIds, adEngines,
                                           SEMplestConstants.PromotionAdAction.Add);
                        }
                        if (updateAds.Any())
                            sw.scheduleAds(promo.PromotionPK, updateAds, adEngines,
                                           SEMplestConstants.PromotionAdAction.Update);
                        if (deleteAds.Any())
                            sw.scheduleAds(promo.PromotionPK, deleteAds, adEngines,
                                           SEMplestConstants.PromotionAdAction.Delete);
                    }
                    if (shouldUpdateGeoTargeting)
                        sw.scheduleUpdateGeoTargeting(promo.PromotionPK, adEngines);
                }
            }
            return string.IsNullOrEmpty(rString.ToString()) ? String.Empty : rString.ToString().Substring(0, rString.ToString().Length - 1);
        }