public ActionResult Newsletter(CommunicationsContext context) { var member = _membersQuery.GetMember(context.UserId); if (member == null || !member.IsEnabled || !member.IsActivated) { return(HttpNotFound()); } var candidate = _candidatesQuery.GetCandidate(context.UserId); var resume = candidate.ResumeId == null ? null : _resumesQuery.GetResume(candidate.ResumeId.Value); var model = CreateModel <NewsletterModel>(context); model.Member = member; model.Candidate = candidate; model.Resume = resume; var lastMonth = new DateTimeRange(DateTime.Today.AddMonths(-1), DateTime.Today); model.TotalJobAds = _jobAdReportsQuery.GetCreatedJobAds(lastMonth); model.TotalViewed = _employerMemberAccessReportsQuery.GetMemberViewings(context.UserId, lastMonth); model.ProfilePercentComplete = _memberStatusQuery.GetPercentComplete(member, candidate, resume); var execution = _executeJobAdSearchCommand.SearchSuggested(member, null, new Range(0, MaxSuggestedJobCount)); var jobAds = _jobAdsQuery.GetJobAds <JobAd>(execution.Results.JobAdIds).ToDictionary(j => j.Id, j => j); model.SuggestedJobs = (from i in execution.Results.JobAdIds where jobAds.ContainsKey(i) select jobAds[i]).ToList(); return(View(model)); }
CloseReport IJobAdPostsManager.CloseJobAds(Guid integratorUserId, IEmployer jobPoster, IEnumerable <string> externalReferenceIds) { var report = new CloseReport(); // Read the existing job ads for this integrator/job poster combination. var existingJobAdIds = GetExistingJobAdIds(integratorUserId, jobPoster.Id); // Find which of the specified job ad external IDs exist and close those. var externalReferenceIdList = externalReferenceIds.ToList(); var jobAdIds = FilterJobAdIds(externalReferenceIdList, existingJobAdIds, report); if (jobAdIds.Count > 0) { var jobAds = _jobAdsQuery.GetJobAds <JobAd>(jobAdIds); foreach (var jobAd in jobAds) { if (_jobAdsCommand.CanBeClosed(jobAd)) { _jobAdsCommand.CloseJobAd(jobAd); } } } // Fill in the report. report.Closed = jobAdIds.Count; report.Failed = externalReferenceIdList.Count - jobAdIds.Count; return(report); }
IList <JobAdView> IMemberJobAdViewsQuery.GetJobAdViews(IEnumerable <Guid> jobAdIds) { var jobAds = _jobAdsQuery.GetJobAds <JobAd>(jobAdIds); return((from j in jobAds select new JobAdView(j, _jobAdProcessingQuery.GetJobAdProcessing(j))).ToList()); }
public void TestJob() { var employer = CreateEmployer(); ExecuteTask(false, "SampleJob.xml"); var jobAds = _jobAdsQuery.GetJobAds <JobAd>(_jobAdsQuery.GetOpenJobAdIds(employer.Id)); Assert.AreEqual(1, jobAds.Count); Assert.AreEqual("118204981", jobAds[0].Integration.IntegratorReferenceId); Assert.AreEqual("200116851", jobAds[0].Integration.ExternalReferenceId); Assert.AreEqual("Change Analyst / Process Analyst", jobAds[0].Title); }
protected JobAd AssertJobAd(IntegratorUser integratorUser, Guid employerId, string externalReferenceId, JobAdStatus expectedStatus) { var jobAds = _jobAdsQuery.GetJobAds <JobAd>(_jobAdIntegrationQuery.GetJobAdIds(integratorUser.Id, employerId, externalReferenceId)); Assert.AreEqual(1, jobAds.Count); return(AssertJobAd(jobAds[0], integratorUser, externalReferenceId, expectedStatus)); }
public ActionResult Download(JobAdMimeType?mimeType, Guid[] jobAdIds) { try { if (jobAdIds.IsNullOrEmpty()) { throw new NotFoundException("job ad"); } mimeType = GetMimeType(mimeType, jobAdIds); var jobAds = _jobAdsQuery.GetJobAds <JobAd>(jobAdIds).ToArray(); switch (mimeType.Value) { case JobAdMimeType.Doc: return(DocFile(_memberJobAdFilesQuery.GetJobAdFile(jobAds[0]))); default: return(ZipFile(_memberJobAdFilesQuery.GetJobAdFile(jobAds))); } } catch (UserException ex) { ModelState.AddModelError(ex, new StandardErrorHandler()); } return(View("Error")); }
public void TestSalaryUpTo() { var employer = CreateEmployer(); CreateJobAd(employer, "Fantastic opportunity up to $90k", null, null); _jobAdSalariesParserCommand.ParseJobAdSalaries(true); var ads = _jobAdsQuery.GetJobAds <JobAd>(_jobAdsQuery.GetOpenJobAdIds()); Assert.AreEqual(1, ads.Count); Assert.AreEqual(90000M * SalaryConversionMaxToMin, ads[0].Description.ParsedSalary.LowerBound); Assert.AreEqual(90000M, ads[0].Description.ParsedSalary.UpperBound); }
protected JobAd AssertJobAd(Guid jobPosterId) { var jobAds = _jobAdsQuery.GetJobAds <JobAd>(_jobAdsQuery.GetJobAdIds(jobPosterId, JobAdStatus.Open)); Assert.AreEqual(1, jobAds.Count); Assert.AreEqual(jobAds[0].Integration.IntegratorReferenceId, "RefABCD/1235"); Assert.AreEqual(jobAds[0].Integration.ExternalReferenceId, "RefABCD"); return(jobAds[0]); }
public void Run(Guid userId, DateTime lastRunTime) { const string method = "Run"; // The user has to be active to receive this email. if (!_userAccountsQuery.IsActive(userId)) { #region Log Logger.Raise(Event.Trace, method, "The user is not active and therefore won't get any suggested jobs.", Event.Arg("userId", userId)); #endregion return; } var member = _membersQuery.GetMember(userId); var execution = _jobAdSearchCommand.SearchSuggested(member, DateTime.Now - lastRunTime, new Range(0, MaxResults)); if (execution.Results.JobAdIds.Count == 0) { #region Log Logger.Raise(Event.Trace, method, "No new suggested jobs were found.", Event.Arg("userId", userId)); #endregion return; } var jobAdIds = execution.Results.JobAdIds.Take(MaxResults).ToList(); var jobAds = _jobAdsQuery.GetJobAds <JobAd>(jobAdIds).ToDictionary(j => j.Id, j => j); var emailJobAds = from i in jobAdIds where jobAds.ContainsKey(i) select jobAds[i]; var to = _membersQuery.GetMember(userId); var email = SuggestedJobsEmail.Create(to, emailJobAds, execution.Results.JobAdIds.Count); var ok = _emailsCommand.TrySend(email); #region Log if (ok) { Logger.Raise(Event.Trace, method, "SuggestedJobsEmail sent.", Event.Arg("userId", userId)); } else { Logger.Raise(Event.Warning, method, "Unable to send SuggestedJobsEmail.", Event.Arg("userId", userId)); } #endregion }
public ActionResult Usage(Guid id, [Bind(Include = "StartDate")] DateTime?startDate, [Bind(Include = "EndDate")] DateTime?endDate) { var employer = _employersQuery.GetEmployer(id); if (employer == null) { return(NotFound("employer", "id", id)); } if (startDate == null) { startDate = DateTime.Now.Date.AddDays(-1 * DefaultUsageDays); } if (endDate == null) { endDate = DateTime.Now.Date.AddDays(1); } // Get credits exercised by this employer. var exercisedCredits = _exercisedCreditsQuery.GetExercisedCreditsByExerciserId(id, new DateTimeRange(startDate.Value, endDate.Value)); // Get all associated data. var allocations = _allocationsQuery.GetAllocations(exercisedCredits); var organisations = _organisationsQuery.GetOrganisations((from a in allocations select a.OwnerId).Distinct()); return(View(new EmployerExercisedCreditsModel { Employer = employer, StartDate = startDate.Value, EndDate = endDate.Value, ExercisedCredits = exercisedCredits, Credits = _creditsQuery.GetCredits().ToDictionary(c => c.Id, c => c), Allocations = allocations.ToDictionary(a => a.Id, a => a), JobAds = _jobAdsQuery.GetJobAds(exercisedCredits), Members = _membersQuery.GetMembers(exercisedCredits), Organisations = organisations.ToDictionary(o => o.Id, o => o), })); }
public ActionResult Usage(Guid id, [Bind(Include = "StartDate")] DateTime?startDate, [Bind(Include = "EndDate")] DateTime?endDate) { var organisation = _organisationsQuery.GetOrganisation(id); if (organisation == null) { return(NotFound("organisation", "id", id)); } if (startDate == null) { startDate = DateTime.Now.Date.AddDays(-1 * DefaultUsageDays); } if (endDate == null) { endDate = DateTime.Now.Date.AddDays(1); } // Get credits exercised by this employer. var exercisedCredits = _exercisedCreditsQuery.GetExercisedCreditsByOwnerId(id, new DateTimeRange(startDate.Value, endDate.Value)); // Get all associated data. return(View(new OrganisationExercisedCreditsModel { Organisation = organisation, StartDate = startDate.Value, EndDate = endDate.Value, ExercisedCredits = exercisedCredits, Credits = _creditsQuery.GetCredits().ToDictionary(c => c.Id, c => c), Allocations = _allocationsQuery.GetAllocations(exercisedCredits).ToDictionary(a => a.Id, a => a), JobAds = _jobAdsQuery.GetJobAds(exercisedCredits), Members = _membersQuery.GetMembers(exercisedCredits), Employers = _employersQuery.GetEmployers(exercisedCredits), })); }
private JobAdEntry Post(IEmployer employer) { // Apply for the job. LogIn(employer); Get(_newJobAdUrl); CreateJobAd(employer.EmailAddress.Address); _previewButton.Click(); _publishButton.Click(); var jobAd = _jobAdsQuery.GetJobAds <JobAdEntry>(_jobAdsQuery.GetJobAdIds(employer.Id, JobAdStatus.Open))[0]; LogOut(); return(jobAd); }
private LuceneQuery GetApplicationsMltQuery(MoreLikeThis mlt, IEnumerable <Guid> jobAdIds) { var jobAds = _jobAdsQuery.GetJobAds <JobAd>(jobAdIds); var applicationsString = new StringBuilder(); foreach (var jobAd in jobAds) { applicationsString.AppendLine(jobAd.Title) .AppendLine(jobAd.Description.BulletPoints == null ? string.Empty : jobAd.Description.BulletPoints.ToString()) .AppendLine(jobAd.Description.Content); } return(mlt.like(new StringReader(applicationsString.ToString()))); }
private void UpdateFeaturedJobAds(int jobAdCount) { var jobAds = _jobAdsQuery.GetJobAds <JobAd>(_jobAdsQuery.GetRecentOpenJobAdIds(new Range(0, jobAdCount))); var featuredJobAds = from j in jobAds where !string.IsNullOrEmpty(j.Title) select new FeaturedItem { Id = j.Id, Url = GetJobUrl(j), Title = GetTitle(j), }; _featuredCommand.UpdateFeaturedJobAds(featuredJobAds); }
private void CloseJobAds(Guid posterId, IDictionary <Guid, bool> hasCredits) { if (HasApplicantCredits(posterId, hasCredits)) { return; } // No active allocations so close all their job ads. var jobAdIds = _jobAdsQuery.GetOpenJobAdIds(posterId); var jobAds = _jobAdsQuery.GetJobAds <JobAd>(jobAdIds); foreach (var jobAd in jobAds) { _jobAdsCommand.CloseJobAd(jobAd); } }
public ActionResult JobAds() { var employer = CurrentEmployer; if (employer == null) { return(Json(new JsonJobAdsModel { JobAds = new List <JobAdApplicantsModel>() })); } // Get the open and closed job ads. var jobAdIds = _jobAdsQuery.GetJobAdIds(employer.Id, JobAdStatus.Open).Concat(_jobAdsQuery.GetJobAdIds(employer.Id, JobAdStatus.Closed)); var jobAds = _jobAdsQuery.GetJobAds <JobAdEntry>(jobAdIds); // Get the counts for each job ad through each applicant list. var applicantLists = (from j in jobAds select _jobAdApplicantsQuery.GetApplicantList(employer, j)).ToList(); var counts = _jobAdApplicantsQuery.GetApplicantCounts(employer, from a in applicantLists where a != null select a); return(Json(new JsonJobAdsModel { JobAds = (from m in (from j in jobAds orderby j.Status, j.CreatedTime descending select new JobAdApplicantsModel { Id = j.Id, Title = string.IsNullOrEmpty(j.Integration.ExternalReferenceId) ? j.Title : j.Integration.ExternalReferenceId + ": " + j.Title, Status = j.Status.ToString(), ApplicantCounts = new ApplicantCountsModel { ShortListed = j.GetShortlistedCount(applicantLists, counts), New = j.GetNewCount(applicantLists, counts), Rejected = j.GetRejectedCount(applicantLists, counts) } }) select m).ToList(), })); }
protected IList <TJobAd> GetOrderedJobAds <TJobAd>(ICollection <Guid> jobAdIds) where TJobAd : JobAdEntry { if (jobAdIds.Count == 0) { return(new List <TJobAd>()); } // Look for job ads that are not deleted. var jobAds = _jobAdsQuery.GetJobAds <TJobAd>(jobAdIds); if (jobAds.Count == 0) { return(new List <TJobAd>()); } return((from j in jobAds where j.Status != JobAdStatus.Deleted orderby j.CreatedTime descending select j).ToList()); }
private IDictionary <string, IList <JobAd> > GetJobsAds() { // Get all open job ads that were created yesterday. var jobAdIds = _jobAdsQuery.GetOpenJobAdIds(new DateTimeRange(DateTime.Today.AddDays(-1), DateTime.Today)); // Group the job ads by contact email address. var jobAdsByEmailAddress = new Dictionary <string, IList <JobAd> >(StringComparer.CurrentCultureIgnoreCase); var jobAds = _jobAdsQuery.GetJobAds <JobAd>(jobAdIds); foreach (var jobAd in jobAds) { // Use the contact details email address. if (jobAd.ContactDetails == null) { continue; } var emailAddress = jobAd.ContactDetails.EmailAddress; if (string.IsNullOrEmpty(emailAddress)) { continue; } IList <JobAd> list; if (!jobAdsByEmailAddress.TryGetValue(emailAddress, out list)) { list = new List <JobAd>(); jobAdsByEmailAddress.Add(emailAddress, list); } list.Add(jobAd); } return(jobAdsByEmailAddress); }
private void InitJobAdsRepeater(IEmployer employer) { if (_currentJobAdsIds.IsNullOrEmpty()) { phNoJobAds.Visible = true; phJobAds.Visible = false; return; } var currentPageIds = ucPagingBar.GetResultSubset(_currentJobAdsIds); var jobAds = _jobAdsQuery.GetJobAds <JobAd>(currentPageIds); // Get the counts for each job ad through each applicant list. var applicantLists = (from a in jobAds select _jobAdApplicantsQuery.GetApplicantList(employer, a)).ToArray(); _counts = _jobAdApplicantsQuery.GetApplicantCounts(employer, from a in applicantLists where a != null select a); AdsRepeater.DataSource = jobAds; AdsRepeater.DataBind(); phJobAds.Visible = true; }
public ActionResult JobAds() { var employer = CurrentEmployer; if (employer == null) { return(View()); } // Get the jobAds and their counts. var jobAdIds = _jobAdsQuery.GetJobAdIds(employer.Id, JobAdStatus.Open).Concat(_jobAdsQuery.GetJobAdIds(employer.Id, JobAdStatus.Closed)); var jobAds = _jobAdsQuery.GetJobAds <JobAd>(jobAdIds); // Get the counts for each job ad through each applicant list. var applicantLists = (from a in jobAds select _jobAdApplicantsQuery.GetApplicantList(employer, a)).ToList(); var counts = _jobAdApplicantsQuery.GetApplicantCounts(employer, from a in applicantLists where a != null select a); var applicantCounts = jobAds.ToDictionary( jobAd => jobAd.Id, jobAd => new ApplicantCountsModel { New = jobAd.GetNewCount(applicantLists, counts), Rejected = jobAd.GetRejectedCount(applicantLists, counts), ShortListed = jobAd.GetShortlistedCount(applicantLists, counts) }); // Convert counts to jobAdData. return(View(new JobAdsModel { OpenJobAds = (from j in jobAds where j.Status == JobAdStatus.Open select j).ToList(), ClosedJobAds = (from j in jobAds where j.Status == JobAdStatus.Closed select j).ToList(), ApplicantCounts = applicantCounts })); }
public void TestNewJobAd() { var member = CreateMember(); var folder = _jobAdFoldersQuery.GetFolders(member)[0]; var searchQuery = new JobAdSearchQuery { AdTitle = Expression.Parse(Title) }; var sortQuery = new JobAdSortQuery(); // Do some searches. var results = _searchService1.Search(null, searchQuery); Assert.AreEqual(0, results.JobAdIds.Count); results = _searchService2.Search(null, searchQuery); Assert.AreEqual(0, results.JobAdIds.Count); results = _sortService1.SortFolder(member.Id, folder.Id, sortQuery); Assert.AreEqual(0, results.JobAdIds.Count); results = _sortService2.SortFolder(member.Id, folder.Id, sortQuery); Assert.AreEqual(0, results.JobAdIds.Count); // Add a job ad. var employer = CreateEmployer(); LogIn(employer); Get(_newJobAdUrl); CreateJobAd(employer.EmailAddress.Address); _previewButton.Click(); _publishButton.Click(); LogOut(); // Add it to the folder. var jobAd = _jobAdsQuery.GetJobAds <JobAdEntry>(_jobAdsQuery.GetJobAdIds(employer.Id, JobAdStatus.Open))[0]; _memberJobAdListsCommand.AddJobAdToFolder(member, folder, jobAd.Id); // Do some searches again. results = _searchService1.Search(null, searchQuery); Assert.AreEqual(1, results.JobAdIds.Count); Assert.AreEqual(jobAd.Id, results.JobAdIds[0]); results = _sortService1.SortFolder(member.Id, folder.Id, sortQuery); Assert.AreEqual(1, results.JobAdIds.Count); Assert.AreEqual(jobAd.Id, results.JobAdIds[0]); // Wait for the polling to kick in. Thread.Sleep(3 * MonitorInterval * 1000); results = _searchService2.Search(null, searchQuery); Assert.AreEqual(1, results.JobAdIds.Count); Assert.AreEqual(jobAd.Id, results.JobAdIds[0]); results = _sortService2.SortFolder(member.Id, folder.Id, sortQuery); Assert.AreEqual(1, results.JobAdIds.Count); Assert.AreEqual(jobAd.Id, results.JobAdIds[0]); }
public DeleteAdvertResponseMessage DeleteAdvert(DeleteAdvertRequestMessage request) { const string method = "DeleteAdvert"; EventSource.Raise(Event.Information, method, Event.Arg("request", request)); IntegratorUser integratorUser; IEmployer jobPoster; CheckUser(request.UserCredentials, out integratorUser, out jobPoster); var errors = new List <string>(); var report = new DeleteAdvertReport(); foreach (var deleteAd in request.DeleteAdvert.Adverts.DeleteAdvert) { report.JobAds++; try { var ids = _jobAdIntegrationQuery.GetJobAdIds(integratorUser.Id, deleteAd.JobReference); var jobAds = _jobAdsQuery.GetJobAds <JobAd>(ids); foreach (var jobAd in jobAds) { _jobAdsCommand.CloseJobAd(jobAd); } var closed = ids.Count; if (closed > 0) { report.Closed += closed; } else { var message = string.Format("Job ad to be deleted, '{0}', was not found.", deleteAd.JobReference); EventSource.Raise(Event.Error, method, message, Event.Arg("deleteAd", deleteAd)); errors.Add(message); report.NotFound++; } } catch (ServiceEndUserException e) { EventSource.Raise(Event.Error, method, e, null, Event.Arg("postAd", deleteAd)); errors.Add(string.Format("JobReference='{0}': {1}", deleteAd.JobReference, e.Message)); report.Failed++; } catch (Exception e) { EventSource.Raise(Event.Error, method, e, null, Event.Arg("postAd", deleteAd)); errors.Add(string.Format("JobReference='{0}': Unexpected error.", deleteAd.JobReference)); report.Failed++; } } // Record it. _jobAdIntegrationReportsCommand.CreateJobAdIntegrationEvent(new JobAdImportCloseEvent { IntegratorUserId = integratorUser.Id, Success = true, JobAds = report.JobAds, Closed = report.Closed, Failed = report.Failed, NotFound = report.NotFound }); var response = new DeleteAdvertResponseMessage { DeleteAdvertResponse = new Response { Success = string.Join("\r\n", errors.ToArray()) } }; EventSource.Raise(Event.Information, method, string.Format("{0} ads processed; {1} ads deleted, {2} ads not found, {3} errors.", report.JobAds, report.Closed, report.NotFound, report.Failed), Event.Arg("response", response)); return(response); }
// The logic here gets somewhat complex: // If no employer is logged in show a placeholder item that takes them to LoginRequired.aspx // If an employer is logged in and they have job ads show them (of course) // If they have no job ads and no job ad credit show a placeholder that takes them to the "pricing" page // If they have no job ads, but have job ad credits just don't show anything (return null) public static ListItem[] GetJobAdItems(Employer employer, Guid?excludeJobAdId, string headingText) { // Add the header item headingText = headingText ?? "Add to jobs"; var addToItems = new List <ListItem> { new ListItem(headingText, BlankItemValue + " - add") }; if (employer == null) { AddJobAdItemsForNoJobAds(addToItems, false); return(addToItems.ToArray()); } // For job ads the ListItem value is the job ad ID, since there may not be a candidate list yet - it's created // when the first candidate is added. var jobAdIds = (_jobAdsQuery.GetJobAdIds(employer.Id, JobAdStatus.Open).Concat(_jobAdsQuery.GetJobAdIds(employer.Id, JobAdStatus.Closed))).ToList(); if (jobAdIds.Count == 0 || (excludeJobAdId.HasValue && jobAdIds.Count == 1 && jobAdIds[0] == excludeJobAdId)) { var quantity = _employerCreditsQuery.GetEffectiveActiveAllocation <JobAdCredit>(employer).RemainingQuantity; if (quantity == null || quantity > 0) { return(null); } AddJobAdItemsForNoJobAds(addToItems, true); return(addToItems.ToArray()); } bool closedHeadingAdded = false; if (jobAdIds.Count != 0) { var jobAds = _jobAdsQuery.GetJobAds <JobAdEntry>(jobAdIds); if (jobAds[0].Status == JobAdStatus.Open) { addToItems.Add(new ListItem("----- Active jobs -----", BlankItemValue + " - active")); } foreach (var jobAd in jobAds) { if (!excludeJobAdId.HasValue || jobAd.Id != excludeJobAdId.Value) { if (!closedHeadingAdded && jobAd.Status == JobAdStatus.Closed) { // End of Active job ads, all following ads are Closed. addToItems.Add(new ListItem("----- Closed jobs -----", BlankItemValue + " - closed")); closedHeadingAdded = true; } addToItems.Add(new ListItem(" " + jobAd.Integration.ExternalReferenceId + " - " + jobAd.Title, jobAd.Id.ToString("n"))); } } } return(addToItems.ToArray()); }
private void ExecuteTaskCore(int?maxPostCount) { const string method = "ExecuteTask"; // Check properties. if (string.IsNullOrEmpty(RemoteUsername)) { throw new ArgumentException("RemoteUsername property must be specified."); } if (string.IsNullOrEmpty(RemotePassword)) { throw new ArgumentException("RemotePassword property must be specified."); } if (RemoteCompanyId == 0) { throw new ArgumentException("RemoteCompanyId property must be specified."); } _mapper.VerticalId = VerticalId; // Extract and map jobs to post. #region Log Logger.Raise(Event.Information, method, "Searching for HR related job ad..."); #endregion var searchResults = _searcher.Search(); // map: jobAdId -> categoryId[] var jobAds = _jobAdsQuery.GetJobAds <JobAd>(searchResults.Select(r => r.Key)).Where(jobAd => !IsExcluded(jobAd)); var posts = new List <Job>(); var i = 0; foreach (var jobAd in jobAds) { i++; try { var post = _mapper.Map(jobAd, searchResults[jobAd.Id]); if (post.description.Length < MaxDescriptionLength) { posts.Add(post); } } catch (Exception e) { #region Log Logger.Raise(Event.NonCriticalError, method, "Unable to map job ad.", e, null, Event.Arg("JobAdId", jobAd.Id)); #endregion } if (maxPostCount.HasValue && i >= maxPostCount) { // Prepare request. PostJobs(method, posts); i = 0; posts = new List <Job>(); } } if (posts.Count > 0) { // Prepare request. PostJobs(method, posts); } }
public static IDictionary <Guid, JobAd> GetJobAds(this IJobAdsQuery jobAdsQuery, IEnumerable <ExercisedCredit> exercisedCredits) { // Assumption: the job ads come from those credits where no-one has been exercised on. return(jobAdsQuery.GetJobAds <JobAd>((from c in exercisedCredits where c.ExercisedOnId == null && c.ReferenceId != null select c.ReferenceId.Value).Distinct()).ToDictionary(j => j.Id, j => j)); }