private void fetch() { Response.Clear(); SpotInfo sinfo = new SpotInfo(); String key = Request["key"]; sinfo.Address = key; Geocoder geo = new Geocoder(); GeoResult result = geo.GetGeoResult(sinfo); JsonObject jobj = new JsonObject(); if (GeoResultStatus.OK.Equals(result.Status))//@since 0.1.1 { jobj.NameValuePair.Add(new JsonObject.nvpair() { Name = "lat", Value = result.Results[0].Geometry.Location.Lat }); jobj.NameValuePair.Add(new JsonObject.nvpair() { Name = "lng", Value = result.Results[0].Geometry.Location.Lng }); } AjaxResponse jresponse = new AjaxResponse(); jresponse.Status = "OK"; jresponse.RawData = jobj; jresponse.Msg = "lat, lng of " + key; Response.Write(jresponse.ToString()); Response.ContentType = "application/json"; }
public void TestTotalHouses() { // Исходнве данные string insolationFile = @"c:\work\test\АР\ЖУКИ\Задание по инсоляции ПИК1.xlsx"; List <HouseOptions> options = new List <HouseOptions>() { new HouseOptions("P1", 15, 25, new List <bool> { false, false, false, false, true }), new HouseOptions("P2", 15, 25, new List <bool> { false, false, false, false, true }) }; SpotInfo sp = GetSpotInformation(); // схема проекта ProjectScheme projectSpot = new ProjectScheme(options, sp); // Чтение файла схемы объекта projectSpot.ReadScheme(insolationFile); // Получение всех домов var totalHouses = projectSpot.GetTotalHouses(); foreach (var hs in totalHouses) { foreach (var house in hs) { CreateHouseImage.TestCreateImage(house); } } Assert.AreEqual(totalHouses.Count, 2); }
private static void CheckProductClashExposureCount( IReadOnlyDictionary <string, Clash> clashesByExternalRef, IClashExposureCountService clashExposureCountService, SmoothFailureMessagesForSpotsCollection result, IReadOnlyDictionary <string, int> spotChildClashCodeCount, Spot spot, SpotInfo spotInfo, IReadOnlyCollection <Spot> childProductClashSpots) { if (!clashesByExternalRef.TryGetValue(spotInfo.ProductClashCode, out Clash childClash)) { return; } int exposureCount = clashExposureCountService.Calculate( childClash.Differences, (childClash.DefaultPeakExposureCount, childClash.DefaultOffPeakExposureCount), (spot.StartDateTime, spot.SalesArea) ); if (exposureCount > 0 && childProductClashSpots.Count + spotChildClashCodeCount[spotInfo.ProductClashCode] > exposureCount) { result.Add(spot.Uid, SmoothFailureMessages.T1_ProductClash); } }
private void SetupTestData( out IReadOnlyCollection<Break> breaksBeingSmoothed, out SmoothBreak theSmoothBreak, out IReadOnlyCollection<Programme> scheduleProgrammes, out List<Spot> spotsForBreak, out SalesArea salesArea, out IReadOnlyDictionary<string, Clash> clashesByExternalRef, out IReadOnlyDictionary<Guid, SpotInfo> spotInfos, out ProductClashRules productClashRule, out SmoothResources smoothResources, out IClashExposureCountService clashExposureCountService, out SponsorshipRestrictionService sponsorshipRestrictionsService) { breaksBeingSmoothed = _repositoryWrapper.LoadAllTestBreaks().ToList(); theSmoothBreak = new SmoothBreak(breaksBeingSmoothed.First(), 1); scheduleProgrammes = _repositoryWrapper.LoadAllProgrammes().ToList(); spotsForBreak = new List<Spot>() { _spot }; salesArea = _repositoryWrapper.LoadAllSalesArea().First(); clashesByExternalRef = _repositoryWrapper.LoadAllClashes().ToDictionary(c => c.Externalref); spotInfos = SpotInfo.Factory( spotsForBreak, _repositoryWrapper.LoadAllProducts().ToDictionary(p => p.Externalidentifier), clashesByExternalRef ); productClashRule = ProductClashRules.LimitOnExposureCount; smoothResources = new SmoothResources(); clashExposureCountService = ClashExposureCountService.Create(); sponsorshipRestrictionsService = SponsorshipRestrictionService.Factory( spotInfos, new SponsorshipRestrictionFilterService(ImmutableList.Create<Sponsorship>()), new SmoothSponsorshipTimelineManager(new List<SmoothSponsorshipTimeline>()), scheduleProgrammes.First(), DebugLogger); }
/// <summary> /// 保存景点信息 /// add by fruitchan /// 2016-12-6 20:02:05 /// </summary> /// <param name="spotInfo">景点信息</param> /// <returns>保存结果</returns> public ActionResult SaveScenicSpot(SpotInfo spotInfo) { string status = "fail"; string msg = "保存失败!"; if (spotInfo != null) { #region 校验数据 msg = Validate.ValidateString(new CustomValidate() { FieldName = "景区名称", FieldValue = spotInfo.ScenicSpotName, IsRequired = true, MaxLength = 100 }, new CustomValidate() { FieldName = "景区图片", FieldValue = spotInfo.ScenicSpotImgs, IsRequired = true }); if (msg == null && (spotInfo.ProvinceId == null || spotInfo.ProvinceId <= 0)) { msg = "请选择省份!"; } if (msg == null && (spotInfo.CityId == null || spotInfo.CityId <= 0)) { msg = "请选择城市!"; } #endregion if (msg == null) { spotInfo.CreateTime = DateTime.Now; if (spotInfo.LinkSpotId.HasValue) { var linkSpot = OperateContext.Current.BLLSession.ISpotInfoBLL.GetListBy(h => h.ID == spotInfo.LinkSpotId).FirstOrDefault(); if (linkSpot != null) { spotInfo.LinkSpotId = linkSpot.ID; spotInfo.LinkSpotName = linkSpot.ScenicSpotName; } } int result = spotInfo.ID > 0 ? OperateContext.Current.BLLSession.ISpotInfoBLL.Modify(spotInfo) : OperateContext.Current.BLLSession.ISpotInfoBLL.Add(spotInfo); if (result == 1) { status = "ok"; msg = "保存成功!"; } } } return(OperateContext.Current.RedirectAjax(status, msg, null, null)); }
private MapSerializable GetInfo(string mapName) { List <SpotInfo> spotsInfo = mapsSpotsInfo[mapName]; SpotInfo root = mapsRoots[mapName]; int rootIndex = GetIndex(root, mapName); return(new MapSerializable(spotsInfo, rootIndex)); }
public void CopyDataFromMapsCacheToSceneSpots() { foreach (Spot root in finalSpotForEachMap) { string mapName = root.MapName; SpotInfo rootInfo = mapsCache.GetRootInfo(mapName); root.BuildFromInfo(rootInfo, mapsCache.GetSpotsInfoList(mapName)); } }
public static SpotInfo FromJson(string jsonStr) { JavaScriptSerializer jss = new JavaScriptSerializer(); jss.MaxJsonLength = 2097152; SpotInfo result = jss.Deserialize <SpotInfo>(jsonStr); return(result); }
public static string GetSpotIdOnline(string latY, string lngX) { string result = "{\"success\": "; LatLng baiduLoc = BdCoodOffsetProvider.getInstance().StandardMercator2BaiduMercator(new LatLng(double.Parse(latY), double.Parse(lngX))); string url = "http://pcsv0.map.bdimg.com/?qt=qsdata&x=" + baiduLoc.longitude + "&y=" + baiduLoc.latitude; string spotInfo = HttpGetText(url); if (spotInfo != null) { SpotInfo info = SpotInfo.FromJson(spotInfo); if (info != null) { result = result + "true,"; LatLng correctLoc = BdCoodOffsetProvider.getInstance().BaiduMercator2StandardMercator(new LatLng(((double)info.content.y) / 100.0, ((double)info.content.x) / 100.0)); result = result + "\"pid\": \"" + info.content.id + "\"," + "\"x\": " + correctLoc.longitude + ", \"y\": " + correctLoc.latitude + "}"; for (int z = 5; z > 2; z--) { if (!File.Exists("site/" + "Pics/" + BaiDuMapManager.inst.streetudt + "/" + info.content.id + "/" + z + ".jpeg")) { new Thread((level) => { int zoom = (int)level; MultiPicDownloadDispatcher <DownloadWorker> d3 = getAttendant(zoom); d3.setPicInfo(info.content.id, zoom - 1); d3.start(); Utility.LogSimple(LogLevel.Debug, "level " + level + " pano triggered!"); byte[] pic = d3.getResult(); Utility.LogSimple(LogLevel.Debug, "level " + level + " pano returned!"); if (pic != null && pic.Length > 0) { Utility.LogSimple(LogLevel.Debug, "level " + level + " pano start to write to file!"); string path = "site/" + "Pics/" + BaiDuMapManager.inst.streetudt + "/" + info.content.id; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } path = path + "/" + zoom + ".jpeg"; File.WriteAllBytes(path, pic); } }).Start(z); } } } else { result = result + "true,\"pid\": null, \"x\":0, \"y\":0}"; } } else { result = result + "false,\"pid\": null, \"x\":0, \"y\":0}"; } return(result); }
private void CopyMapDataToAttributes(string mapName, MapSerializable mapsData) { mapsSpotsInfo[mapName] = mapsData.Recover(out int rootIndex); // Get root List <SpotInfo> spotsInfo = mapsSpotsInfo[mapName]; SpotInfo rootInfo = spotsInfo[rootIndex]; mapsRoots[mapName] = rootInfo; }
public static SpotInfo GetSpotInformation() { SpotInfo spotInfo = new SpotInfo(); spotInfo.requirments.Add(new Requirment("Студия", 22, 23, 15, 15, 3, 0, 0, 1, "01")); spotInfo.requirments.Add(new Requirment("Студия", 33, 35, 8, 0, 8, 0, 0, 4, "01")); spotInfo.requirments.Add(new Requirment("Однокомн.", 33, 47, 17, 0, 4, 0, 0, 1, "1")); spotInfo.requirments.Add(new Requirment("Двухкомн.", 45, 47, 16, 0, 3, 0, 0, 4, "2")); spotInfo.requirments.Add(new Requirment("Двухкомн.", 57, 60, 11, 0, 3, 0, 0, 8, "2")); spotInfo.requirments.Add(new Requirment("Двухкомн.", 68, 71, 12, 0, 3, 0, 0, 1, "2")); spotInfo.requirments.Add(new Requirment("Трехкомн.", 85, 95, 21, 0, 2, 0, 0, 1, "3")); return(spotInfo); }
/// <summary> /// <para>Returns whether spots are for same sponsor.</para> /// </summary> public static bool IsSameSpotSponsor( Spot spot1, Spot spot2, IReadOnlyDictionary <Guid, SpotInfo> spotInfos) { SpotInfo spot1Info = spotInfos[spot1.Uid]; SpotInfo spot2Info = spotInfos[spot2.Uid]; return (HasAdvertiser(spot1Info) && HasAdvertiser(spot2Info) && AdvertisersAreTheSame(spot1Info, spot2Info)); }
public MapSerializable(List <SpotInfo> spotsInfo, int rootIndex) { this.rootIndex = rootIndex; for (int i = 0; i < spotsInfo.Count; i++) { SpotInfo spt = spotsInfo[i]; GONames.Add(spt.GOName); Cleareds.Add(spt.Cleared); Levels.Add(spt.Level); PlayLvlBtnIndexes.Add(spt.PlayLvlBtnIndex); AntecessorsIndexes.Add(spt.AntecessorsIndexes); } }
private int GetIndex(SpotInfo desiredInfo, string mapName) { List <SpotInfo> allSpotsInfo = mapsSpotsInfo[mapName]; for (int i = 0; i < allSpotsInfo.Count; i++) { if (desiredInfo == allSpotsInfo[i]) { return(i); } } return(NODE_NOT_FOUND); }
private static void CheckProductClashRulesWhenClashLimitsAreAllowed( IReadOnlyDictionary <Guid, SpotInfo> spotInfos, IReadOnlyDictionary <string, Clash> clashesByExternalRef, SmoothResources smoothResources, IClashExposureCountService clashExposureCountService, SmoothFailureMessagesForSpotsCollection result, IReadOnlyDictionary <string, int> spotChildClashCodeCount, IReadOnlyDictionary <string, int> spotParentClashCodeCount, IReadOnlyCollection <Spot> spotsAlreadyInTheBreak, Spot spot, SpotInfo spotInfo, IReadOnlyCollection <Spot> childProductClashSpots) { if (childProductClashSpots.Count > 0 && !String.IsNullOrEmpty(spotInfo.ProductClashCode)) { CheckProductClashExposureCount( clashesByExternalRef, clashExposureCountService, result, spotChildClashCodeCount, spot, spotInfo, childProductClashSpots); } // Check parent clashes var parentProductClashSpots = smoothResources.ProductClashChecker .GetProductClashesForSingleSpot( spot, spotsAlreadyInTheBreak, spotInfos, ClashCodeLevel.Parent) .ToList(); if (parentProductClashSpots.Count > 0 && !String.IsNullOrEmpty(spotInfo.ParentProductClashCode)) { CheckProductParentClashExposure( clashesByExternalRef, clashExposureCountService, result, spotParentClashCodeCount, spot, spotInfo, parentProductClashSpots); } }
public void TestRead() { string insolationFile = @"c:\work\test\АР\ЖУКИ\Задание по инсоляции ПИК1.xlsx"; List <HouseOptions> options = new List <HouseOptions>() { new HouseOptions("P1", 15, 25, new List <bool> { true, false, false, false, false }), new HouseOptions("P2", 15, 25, new List <bool> { true, false, false, false, false }) }; SpotInfo sp = TestProjectScheme.GetSpotInformation(); ProjectScheme projectSpot = new ProjectScheme(options, sp); // Чтение файла схемы объекта projectSpot.ReadScheme(insolationFile); // Получение домов (пятен) List <HouseSpot> houseSpots = projectSpot.HouseSpots; Assert.AreEqual(houseSpots.Count, 2); }
ClashCodesForSpotsCount( IReadOnlyCollection <Spot> spots, IReadOnlyDictionary <Guid, SpotInfo> spotInfos) { var countNewSpotsPerChildClashCode = new Dictionary <string, int>(); var countNewSpotsPerParentClashCode = new Dictionary <string, int>(); foreach (var spot in spots) { SpotInfo spotInfo = spotInfos[spot.Uid]; if (!String.IsNullOrEmpty(spotInfo.ProductClashCode)) { if (!countNewSpotsPerChildClashCode.ContainsKey(spotInfo.ProductClashCode)) { countNewSpotsPerChildClashCode.Add(spotInfo.ProductClashCode, 0); } countNewSpotsPerChildClashCode[spotInfo.ProductClashCode]++; } if (!String.IsNullOrEmpty(spotInfo.ParentProductClashCode)) { if (!countNewSpotsPerParentClashCode.ContainsKey(spotInfo.ParentProductClashCode)) { countNewSpotsPerParentClashCode.Add(spotInfo.ParentProductClashCode, 0); } countNewSpotsPerParentClashCode[spotInfo.ParentProductClashCode]++; } } return( countNewSpotsPerChildClashCode, countNewSpotsPerParentClashCode ); }
public void SaveSpotPlacements( DateTime processorDateTime, IReadOnlyCollection <Spot> spotsToSave, IReadOnlyDictionary <string, SpotPlacement> spotPlacementsByExternalRef, IReadOnlyDictionary <Guid, SpotInfo> spotInfos, string batchStartEndDateForLogging ) { if (spotsToSave is null || spotInfos is null) { return; } if (spotsToSave.Count == 0) { return; } RaiseInfo( "Starting to save SpotPlacements " + $"for {Log(spotsToSave.Count)} spots " + $"for {batchStartEndDateForLogging}"); int pageNumber = 0; int newCount = 0; int updatedCount = 0; var batch = spotsToSave.Take(DefaultBatchSize); using var scope = RepositoryFactory.BeginRepositoryScope(); do { var spotPlacementRepository = scope.CreateRepository <ISpotPlacementRepository>(); foreach (Spot spot in batch) { if (spotPlacementsByExternalRef.TryGetValue( spot.ExternalSpotRef, out SpotPlacement spotPlacement) ) { updatedCount++; // Before updating ExternalBreakRef record // previous value so we can reset schedule data spotPlacement.ResetExternalBreakRef = spotPlacement.ExternalBreakRef; spotPlacement.ModifiedTime = processorDateTime; spotPlacement.ExternalBreakRef = ExternalBreakNumberOrDefault(spot); spotPlacementRepository.Update(spotPlacement); } else { newCount++; SpotInfo spotInfo = spotInfos[spot.Uid]; // A subsequent schedule data reset needs to // reset SpotPlacement.ExternalBreakRef to the // break that the spot was in before this run started spotPlacement = new SpotPlacement() { ModifiedTime = processorDateTime, ExternalSpotRef = spot.ExternalSpotRef, ResetExternalBreakRef = spotInfo.ExternalBreakRefAtRunStart, ExternalBreakRef = ExternalBreakNumberOrDefault(spot), }; spotPlacementRepository.Add(spotPlacement); } try { spotPlacementRepository.SaveChanges(); } catch (Exception exception) { throw new Exception( "Error saving Smooth spot placements for " + $"spot {spotPlacement.ExternalSpotRef} for " + $"batch {batchStartEndDateForLogging}", exception ); } } batch = spotsToSave .Skip(DefaultBatchSize * ++pageNumber) .Take(DefaultBatchSize); } while (batch.Any()); RaiseInfo( $"Finished saving SpotPlacements for {Log(spotsToSave.Count)} spots " + $"(New={Log(newCount)}, Updated={Log(updatedCount)}) " + $"for {batchStartEndDateForLogging}" );
/// <summary> /// Gets spots matching filter criteria /// </summary> /// <param name="spotFilter"></param> /// <param name="spots"></param> /// <param name="spotInfos"></param> /// <returns></returns> protected IEnumerable <Spot> GetSpots( SpotFilter spotFilter, IReadOnlyCollection <Spot> spots, IReadOnlyDictionary <Guid, SpotInfo> spotInfos) { var spotsOutput = new List <Spot>(spots); // Remove specific spots to exclude _ = spotsOutput.RemoveAll(s => !s.ClientPicked); if (spotFilter.SpotIdsToExclude?.Count > 0) { _ = spotsOutput.RemoveAll(s => spotFilter.SpotIdsToExclude.Contains(s.Uid)); } // Remove spots that don't meet criteria if (spotFilter.MinPreemptLevel != null) { _ = spotsOutput.RemoveAll(s => s.Preemptlevel < spotFilter.MinPreemptLevel); } if (spotFilter.MaxPreemptLevel != null) { _ = spotsOutput.RemoveAll(s => s.Preemptlevel > spotFilter.MaxPreemptLevel); } if (spotFilter.Sponsored != null) { _ = spotsOutput.RemoveAll(s => s.Sponsored != spotFilter.Sponsored); } if (spotFilter.Preemptable != null) { _ = spotsOutput.RemoveAll(s => s.Preemptable != spotFilter.Preemptable); } if (spotFilter.HasBreakRequest != null) { _ = spotsOutput.RemoveAll(s => (spotFilter.HasBreakRequest == true && String.IsNullOrEmpty(s.BreakRequest)) || (spotFilter.HasBreakRequest == false && !String.IsNullOrEmpty(s.BreakRequest)) ); } if (spotFilter.BreakRequests?.Count > 0) { _ = spotsOutput.RemoveAll(s => (!String.IsNullOrEmpty(s.BreakRequest) && !spotFilter.BreakRequests.Contains(s.BreakRequest)) || (String.IsNullOrEmpty(s.BreakRequest) && !spotFilter.BreakRequests.Contains(null)) ); } if (spotFilter.HasPositionInBreakRequest != null) { _ = spotsOutput.RemoveAll(s => (spotFilter.HasPositionInBreakRequest == true && String.IsNullOrEmpty(s.RequestedPositioninBreak)) || (spotFilter.HasPositionInBreakRequest == false && !String.IsNullOrEmpty(s.RequestedPositioninBreak)) ); } if (spotFilter.PositionInBreakRequestsToExclude?.Any() == true) { _ = spotsOutput.RemoveAll(s => spotFilter.PositionInBreakRequestsToExclude.Contains(s.RequestedPositioninBreak)); } if (spotFilter.HasMultipartSpots != null) { _ = spotsOutput.RemoveAll(s => (spotFilter.HasMultipartSpots == true && !s.IsMultipartSpot) || (spotFilter.HasMultipartSpots == false && s.IsMultipartSpot) ); } if (spotFilter.MultipartSpots?.Count > 0) { _ = spotsOutput.RemoveAll(s => s.IsMultipartSpot && !spotFilter.MultipartSpots.Contains(s.MultipartSpot)); } if (spotFilter.ExternalCampaignRefsToExclude?.Count > 0) { _ = spotsOutput.RemoveAll(s => spotFilter.ExternalCampaignRefsToExclude.Contains(s.ExternalCampaignNumber)); } if (spotFilter.ProductClashCodesToExclude?.Count > 0) { _ = spotsOutput.RemoveAll(s => spotFilter.ProductClashCodesToExclude.Contains(spotInfos[s.Uid].ProductClashCode)); } if (spotFilter.HasProductClashCode != null) { var spotsToRemove = new List <Spot>(); foreach (var spot in spotsOutput) { SpotInfo spotInfo = spotInfos[spot.Uid]; if ((spotFilter.HasProductClashCode == true && String.IsNullOrEmpty(spotInfo.ProductClashCode)) || (spotFilter.HasProductClashCode == false && !String.IsNullOrEmpty(spotInfo.ProductClashCode)) ) { spotsToRemove.Add(spot); } } if (spotsToRemove.Count > 0) { _ = spotsOutput.RemoveAll(s => spotsToRemove.Contains(s)); } } if (spotFilter.MinSpotLength != null) { _ = spotsOutput.RemoveAll(s => s.SpotLength.ToTimeSpan() < spotFilter.MinSpotLength); } if (spotFilter.MaxSpotLength != null) { _ = spotsOutput.RemoveAll(s => s.SpotLength.ToTimeSpan() > spotFilter.MaxSpotLength); } if (spotFilter.ProductAdvertiserIdentifiersToExclude?.Count > 0) { _ = spotsOutput.RemoveAll(s => spotFilter.ProductAdvertiserIdentifiersToExclude.Contains(spotInfos[s.Uid].ProductAdvertiserIdentifier) ); } if (spotFilter.HasSpotEndTime != null) { if (spotFilter.HasSpotEndTime.Value) { _ = spotsOutput.RemoveAll(s => s.EndDateTime < s.StartDateTime); } else { _ = spotsOutput.RemoveAll(s => s.EndDateTime > s.StartDateTime); } } // Order will be set elsewhere return(spotsOutput); }
private static bool HasAdvertiser(SpotInfo spotInfo) => !String.IsNullOrEmpty(spotInfo.ProductAdvertiserIdentifier);
public void SetSpotInfoToClearIfPlayerSucceed(string spotInfoGOName, string mapName) { SpotInfo spt = GetInfoFromGraphOrGetNull(spotInfoGOName, mapName); SpotToClearAndLevelUpIfPlayerWins = spt; }
private static bool AdvertisersAreTheSame( SpotInfo spot1Info, SpotInfo spot2Info) => spot1Info.ProductAdvertiserIdentifier == spot2Info.ProductAdvertiserIdentifier;
Execute(DateTimeRange weekBeingSmoothed) { string salesAreaName = _salesArea.Name; string auditMessageForSalesAreaNameAndBatchStartEndDate = $"for sales area {salesAreaName} ({Log(weekBeingSmoothed)})"; RaiseInfoAndDebug($"Smoothing batch {auditMessageForSalesAreaNameAndBatchStartEndDate}"); var batchThreadOutput = new SmoothBatchOutput(); foreach (var item in PrepareSmoothFailureMessageCollection(_threadSafeCollections.SmoothFailureMessages)) { batchThreadOutput.SpotsByFailureMessage.Add(item); } foreach (var item in PrepareSmoothOutputWithSmoothPasses(_smoothPasses)) { batchThreadOutput.OutputByPass.Add(item); } int countBreaksWithPreviousSpots = 0; int countBreaksWithNoPreviousSpots = 0; var programmes = new List <Programme>(); var allSpots = new List <Spot>(); var spots = new List <Spot>(); IImmutableList <Break> breaksForTheWeekBeingSmoothed = ImmutableList <Break> .Empty; IImmutableList <RatingsPredictionSchedule> ratingsPredictionSchedules = ImmutableList <RatingsPredictionSchedule> .Empty; IReadOnlyDictionary <string, SpotPlacement> spotPlacementsByExternalRef; try { #pragma warning disable HAA0101 // Array allocation for params parameter Parallel.Invoke( () => programmes.AddRange(LoadProgrammesToSmooth(weekBeingSmoothed, salesAreaName)), () => { var results = LoadSpotsToSmooth(weekBeingSmoothed, salesAreaName); allSpots.AddRange(results.allSpots); spots.AddRange(results.unbookedSpots); }, () => ratingsPredictionSchedules = LoadRatingsPredictionSchedules(weekBeingSmoothed, salesAreaName), () => breaksForTheWeekBeingSmoothed = LoadBreaksToSmooth(weekBeingSmoothed, salesAreaName) ); #pragma warning restore HAA0101 // Array allocation for params parameter void RaiseInfoForCounts(string message) => RaiseInfo($"Read {message} {auditMessageForSalesAreaNameAndBatchStartEndDate}"); RaiseInfoForCounts($"{Log(programmes.Count)} programmes"); RaiseInfoForCounts($"{Log(allSpots.Count)} client picked spots"); RaiseInfoForCounts($"{Log(spots.Count)} unbooked spots"); RaiseInfoForCounts($"{Log(ratingsPredictionSchedules.Count)} ratings prediction schedules"); RaiseInfoForCounts($"{Log(breaksForTheWeekBeingSmoothed.Count)} breaks"); spotPlacementsByExternalRef = LoadSmoothPreviousSpotPlacements(allSpots); } catch (Exception exception) { throw new Exception( $"Error loading smooth data {auditMessageForSalesAreaNameAndBatchStartEndDate})", exception ); } VerifyModel.VerifySpotProductsReferences( salesAreaName, allSpots, _threadSafeCollections.ProductsByExternalRef, _threadSafeCollections.ClashesByExternalRef, RaiseWarning ); // Default all spots to no placement attempt, will reduce // the list as we attempt, generate Smooth failures at the // end for any where no attempt was made to place it (E.g. // no breaks or progs) IReadOnlyDictionary <Guid, SpotInfo> spotInfos = SpotInfo.Factory( allSpots, _threadSafeCollections.ProductsByExternalRef, _threadSafeCollections.ClashesByExternalRef ); IReadOnlyDictionary <string, Break> breaksByExternalRef = Break.IndexListByExternalId(breaksForTheWeekBeingSmoothed); var filterService = new SponsorshipRestrictionFilterService( _threadSafeCollections.SponsorshipRestrictions); IReadOnlyList <SmoothSponsorshipTimeline> timelines = filterService .GetSponsorshipRestrictionTimeline( weekBeingSmoothed, salesAreaName); ISmoothSponsorshipTimelineManager timelineManager = new SmoothSponsorshipTimelineManager(timelines); timelineManager.SetupTimelineRunningTotals(breaksForTheWeekBeingSmoothed); IReadOnlyCollection <Product> products = _threadSafeCollections .ProductsByExternalRef.Values.ToList(); IReadOnlyCollection <Clash> clashes = _threadSafeCollections .ClashesByExternalRef.Values.ToList(); var smoothFailures = new List <SmoothFailure>(); var recommendations = new List <Recommendation>(); var spotIdsUsedForBatch = new HashSet <Guid>(); foreach (Programme oneProgramme in programmes.OrderBy(p => p.StartDateTime)) { var(programmeBreaks, programmeSpots) = GetProgrammeBreaksAndSpots( oneProgramme, allSpots, breaksForTheWeekBeingSmoothed); // The running total and maximums allowed will add up // within the service as we can't access the variables // outside of the programme loop from inside the event // handlers (they're in a different scope). var sponsorshipRestrictionService = SponsorshipRestrictionService.Factory( spotInfos, filterService, timelineManager, oneProgramme, RaiseException); var smoothOneProgramme = new SmoothOneProgramme( oneProgramme, programmeBreaks, programmeSpots, spotInfos, _runId, _salesArea, _processorDateTime, _smoothDiagnostics, ratingsPredictionSchedules, _threadSafeCollections, _clashExposureCountService, sponsorshipRestrictionService, products, clashes, programmes, RaiseInfo, RaiseException); var smoothProgramme = smoothOneProgramme.Execute( batchThreadOutput, _smoothPasses, breaksByExternalRef, spotPlacementsByExternalRef, breaksForTheWeekBeingSmoothed, spotIdsUsedForBatch); countBreaksWithPreviousSpots += smoothProgramme.BreaksWithPreviousSpots; countBreaksWithNoPreviousSpots += smoothProgramme.BreaksWithoutPreviousSpots; _saveSmoothChanges.SaveSmoothedSpots(smoothProgramme.SpotsToBatchSave); smoothFailures.AddRange(smoothProgramme.SmoothFailures); recommendations.AddRange(smoothProgramme.Recommendations); bool SpotNotSetDueToExternalCampaignRef(Spot s) => _smoothConfiguration.ExternalCampaignRefsToExclude.Contains(s.ExternalCampaignNumber) && !s.IsBooked(); batchThreadOutput.SpotsNotSetDueToExternalCampaignRef += programmeSpots.Count(SpotNotSetDueToExternalCampaignRef); // Copy the final values of the sponsorship restriction // calculations and running totals into the outer // variables so the next iteration can use them. This // seems to be the only way to do this at the minute, // until I think of something else. timelineManager = sponsorshipRestrictionService.TimelineManager; } // End of foreach programme loop string batchStartEndDateForLogging = Log(weekBeingSmoothed); var recommendationsForUnplacedSpots = _smoothRecommendationsFactory .CreateRecommendationsForUnplacedSpots( allSpots, _salesArea, _processorDateTime ); RaiseInfo( $"Created {Log(recommendationsForUnplacedSpots.Count)} recommendations " + $"for unplaced spots {auditMessageForSalesAreaNameAndBatchStartEndDate}"); recommendations.AddRange(recommendationsForUnplacedSpots); batchThreadOutput.Recommendations += recommendations.Count; _saveSmoothChanges.SaveSpotPlacements( _processorDateTime, allSpots, spotPlacementsByExternalRef, spotInfos, batchStartEndDateForLogging ); _saveSmoothChanges.SaveSmoothFailures( _runId, salesAreaName, _smoothFailuresFactory, smoothFailures, spots, spotInfos, batchStartEndDateForLogging ); UpdateSmoothOutputForSpotsByFailureMessage( batchThreadOutput.SpotsByFailureMessage, smoothFailures, batchStartEndDateForLogging ); batchThreadOutput.Failures += smoothFailures.Count; var unusedSpotIdsForBatch = new HashSet <Guid>(); AddUnusedSpotsToUnusedSpotsCollection(spotIdsUsedForBatch, unusedSpotIdsForBatch, allSpots); spotIdsUsedForBatch.CopyDistinctTo(batchThreadOutput.UsedSpotIds); unusedSpotIdsForBatch.CopyDistinctTo(batchThreadOutput.UnusedSpotIds); _saveSmoothChanges.SaveSmoothRecommendations( _firstScenarioId, auditMessageForSalesAreaNameAndBatchStartEndDate, recommendations ); RaiseInfo( $"Smoothed batch {auditMessageForSalesAreaNameAndBatchStartEndDate}: " + $"Breaks with no prev spots={countBreaksWithNoPreviousSpots.ToString()}, " + $"Breaks with prev spots={countBreaksWithPreviousSpots.ToString()})" ); return(batchThreadOutput, recommendations, smoothFailures); }