Exemplo n.º 1
0
        public ActionResult Credits()
        {
            var employerId = User.Id().Value;

            var credits = _creditsQuery.GetCredits();

            var hierarchy   = _recruitersQuery.GetOrganisationHierarchyPath(employerId);
            var allocations = _allocationsQuery.GetAllocationsByOwnerId(hierarchy);

            var orders = _ordersQuery.GetOrders(from a in allocations.SelectMany(b => b.Value) where a.ReferenceId != null select a.ReferenceId.Value);

            return(View(new EmployerCreditsModel
            {
                Employer = CurrentEmployer,
                OrganisationHierarchy = _organisationsQuery.GetOrganisations(hierarchy.Skip(1)),
                Credits = credits,
                Allocations = allocations.ToDictionary(a => a.Key, a => (IList <Allocation>)a.Value),
                Orders = orders
            }));
        }
Exemplo n.º 2
0
        private EffectiveRecipientSettings GetEffectiveEmployerSettings(Guid employerId, Category category)
        {
            var hierarchyPath = _recruitersQuery.GetOrganisationHierarchyPath(employerId);

            foreach (var organisationId in hierarchyPath.Skip(1))
            {
                var settings = _settingsQuery.GetSettings(organisationId);
                if (settings != null)
                {
                    var categorySettings = (from s in settings.CategorySettings where s.CategoryId == category.Id select s).SingleOrDefault();
                    if (categorySettings != null && categorySettings.Frequency == Frequency.Never)
                    {
                        return new EffectiveRecipientSettings {
                                   Timing = category.Timing, Frequency = Frequency.Never, LastSentTime = null
                        }
                    }
                    ;
                }
            }

            return(null);
        }
Exemplo n.º 3
0
        private bool Send(Guid employerId)
        {
            const string method = "Send";

            try
            {
                // Only send if there are allocations that expire in the future.

                var today       = DateTime.Today;
                var allocations = from x in _allocationsQuery.GetAllocationsByOwnerId(_recruitersQuery.GetOrganisationHierarchyPath(employerId))
                                  from a in x.Value
                                  where a.ExpiryDate == null || a.ExpiryDate >= today
                                  select a;

                if (allocations.Count() > 0)
                {
                    var employer = _employersQuery.GetEmployer(employerId);
                    return(_emailsCommand.TrySend(new EmployerNewsletterEmail(employer)));
                }

                return(false);
            }
            catch (Exception ex)
            {
                EventSource.Raise(Event.NonCriticalError, method, "Failed to send an employer newsletter to an member.", ex, new StandardErrorHandler(), Event.Arg("employerId", employerId));
                return(false);
            }
        }
Exemplo n.º 4
0
        Guid?IEmployerCreditsCommand.ExerciseContactCredit(IEmployer employer, ProfessionalView view)
        {
            // No employer automatically means not enough credits.

            if (employer == null)
            {
                throw new InsufficientCreditsException {
                          Available = 0, Required = 1
                }
            }
            ;

            return(ExerciseContactCredits(employer.Id, new[] { view }, view.ContactCredits)[view.Id]);
        }

        void IEmployerCreditsCommand.CheckCanExerciseContactCredit(IEmployer employer, ProfessionalView view)
        {
            // No employer automatically means not enough credits.

            if (employer == null)
            {
                throw new InsufficientCreditsException {
                          Available = 0, Required = 1
                }
            }
            ;

            CheckCanExerciseContactCredits(new[] { view }, view.ContactCredits);
        }

        IDictionary <Guid, Guid?> IEmployerCreditsCommand.ExerciseContactCredits(IEmployer employer, ProfessionalViews views)
        {
            // No employer automatically means not enough credits.

            if (employer == null)
            {
                throw new InsufficientCreditsException {
                          Available = 0, Required = views.Count()
                }
            }
            ;

            return(ExerciseContactCredits(employer.Id, views, views.ContactCredits));
        }

        void IEmployerCreditsCommand.CheckCanExerciseContactCredits(IEmployer employer, ProfessionalViews views)
        {
            // No employer automatically means not enough credits.

            if (employer == null)
            {
                throw new InsufficientCreditsException {
                          Available = 0, Required = views.Count()
                }
            }
            ;

            CheckCanExerciseContactCredits(views, views.ContactCredits);
        }

        Guid?IEmployerCreditsCommand.ExerciseApplicantCredit(InternalApplication application, IJobAd jobAd)
        {
            var hierarchyPath = _recruitersQuery.GetOrganisationHierarchyPath(jobAd.PosterId);

            // If the employer has already purchased this applicant or they have already applied then don't exercise a credit
            // because they already have access.

            if (_exercisedCreditsQuery.HasExercisedCredit <ContactCredit>(hierarchyPath, application.ApplicantId))
            {
                return(ExerciseCredit(hierarchyPath, false, application, jobAd));
            }

            // If the poster has unlimited credits or zero credits then nothing to do.

            var allocation = GetEffectiveActiveAllocation <ApplicantCredit>(hierarchyPath);

            if (allocation.RemainingQuantity == null || allocation.RemainingQuantity == 0)
            {
                return(ExerciseCredit(hierarchyPath, false, application, jobAd));
            }

            // If the applicant has applied for another job ad from this employer then don't exercise
            // - one credit used for each applicant for each poster.
            // The application that triggered this event will be returned so look for more than 1 applications.

            var employer = _employersQuery.GetEmployer(jobAd.PosterId);

            if (employer == null)
            {
                return(ExerciseCredit(hierarchyPath, false, application, jobAd));
            }

            if (_jobAdApplicantsQuery.GetApplications(employer, application.ApplicantId).Count > 1)
            {
                return(ExerciseCredit(hierarchyPath, false, application, jobAd));
            }

            // Check whether the job ad threshold has already been passed.

            var applicantList = _jobAdApplicantsQuery.GetApplicantList(employer, jobAd);

            if (applicantList == null)
            {
                return(ExerciseCredit(hierarchyPath, false, application, jobAd));
            }
            var applicants = _jobAdApplicantsQuery.GetApplicantCount(employer, applicantList);

            if (applicants > _maxCreditsPerJobAd)
            {
                return(ExerciseCredit(hierarchyPath, false, application, jobAd));
            }

            // Need to adjust an allocation.

            return(ExerciseCredit(hierarchyPath, true, application, jobAd));
        }

        Guid?IEmployerCreditsCommand.ExerciseJobAdCredit(JobAdEntry jobAd)
        {
            if (jobAd.Status != JobAdStatus.Draft)
            {
                return(null);
            }

            // Check has both job ad and applicant credits.

            var hierarchyPath = _recruitersQuery.GetOrganisationHierarchyPath(jobAd.PosterId);

            var jobAdCreditId     = _creditsQuery.GetCredit <JobAdCredit>().Id;
            var applicantCreditId = _creditsQuery.GetCredit <ApplicantCredit>().Id;
            var allocations       = GetEffectiveActiveAllocations(hierarchyPath, new[] { jobAdCreditId, applicantCreditId });

            if (allocations == null || allocations.Any(a => a.Value.RemainingQuantity == 0))
            {
                throw new InsufficientCreditsException {
                          Available = 0, Required = 1
                }
            }
            ;

            // Exercise.

            var credit = _creditsQuery.GetCredit <JobAdCredit>();

            return(_exercisedCreditsCommand.ExerciseCredit(credit.Id, hierarchyPath, true, jobAd.PosterId, null, jobAd.Id));
        }

        private IDictionary <Guid, Guid?> ExerciseContactCredits(Guid employerId, IEnumerable <ProfessionalView> views, int?contactCredits)
        {
            // Split by statuses.

            var statuses = GetStatuses(views);

            // If there are any that cannot contact at this stage then simply reject.  It is really up to the caller to ensure that this does not happen.

            if (statuses[CanContactStatus.No].Count > 0 || statuses[CanContactStatus.YesIfHadCredit].Count > 0)
            {
                throw new InsufficientCreditsException {
                          Available = contactCredits, Required = statuses[CanContactStatus.No].Count + statuses[CanContactStatus.YesWithCredit].Count + statuses[CanContactStatus.YesIfHadCredit].Count
                }
            }
            ;

            // Check the number of credits available.

            if (statuses[CanContactStatus.YesWithCredit].Count > 0)
            {
                // Really you can't get this combination but just throw just in case.

                if (contactCredits == null)
                {
                    throw new InsufficientCreditsException {
                              Available = contactCredits, Required = statuses[CanContactStatus.YesWithCredit].Count
                    }
                }
                ;

                // Check that there are enough.

                if (contactCredits.Value < statuses[CanContactStatus.YesWithCredit].Count)
                {
                    throw new InsufficientCreditsException {
                              Available = contactCredits, Required = statuses[CanContactStatus.YesWithCredit].Count
                    }
                }
                ;
            }

            // Exercise credits as necessary.

            var hierarchyPath = _recruitersQuery.GetOrganisationHierarchyPath(employerId);

            // For those who need a credit used adjust allocations.

            var yesWithCredits   = statuses[CanContactStatus.YesWithCredit];
            var exercisedCredits = yesWithCredits.Count > 0
                ? ExerciseCredits(hierarchyPath, true, employerId, from y in yesWithCredits select y.Id)
                : new Dictionary <Guid, Guid?>();

            var yesWithoutCredits = statuses[CanContactStatus.YesWithoutCredit];

            if (yesWithoutCredits.Count > 0)
            {
                // For those who don't need a credit used only exercise a credit for those who have not been contacted.

                var hasContacted = _exercisedCreditsQuery.HasExercisedCredits <ContactCredit>(hierarchyPath, from y in yesWithoutCredits select y.Id);
                foreach (var id in hasContacted)
                {
                    exercisedCredits[id] = null;
                }

                var hasNotContacted = (from y in yesWithoutCredits select y.Id).Except(hasContacted);
                if (hasNotContacted.Any())
                {
                    var hasNotContactedExercisedCreditIds = ExerciseCredits(hierarchyPath, false, employerId, hasNotContacted);
                    foreach (var id in hasNotContacted)
                    {
                        exercisedCredits[id] = hasNotContactedExercisedCreditIds[id];
                    }
                }
            }

            return(exercisedCredits);
        }

        private static void CheckCanExerciseContactCredits(IEnumerable <ProfessionalView> views, int?contactCredits)
        {
            // Split by statuses.

            var statuses = GetStatuses(views);

            // If there are any that cannot contact at this stage then simply reject.  It is really up to the caller to ensure that this does not happen.

            if (statuses[CanContactStatus.No].Count > 0 || statuses[CanContactStatus.YesIfHadCredit].Count > 0)
            {
                throw new InsufficientCreditsException {
                          Available = contactCredits, Required = statuses[CanContactStatus.No].Count + statuses[CanContactStatus.YesWithCredit].Count + statuses[CanContactStatus.YesIfHadCredit].Count
                }
            }
            ;

            // Check the number of credits available.

            if (statuses[CanContactStatus.YesWithCredit].Count > 0)
            {
                // Really you can't get this combination but just throw just in case.

                if (contactCredits == null)
                {
                    throw new InsufficientCreditsException {
                              Available = contactCredits, Required = statuses[CanContactStatus.YesWithCredit].Count
                    }
                }
                ;

                // Check that there are enough.

                if (contactCredits.Value < statuses[CanContactStatus.YesWithCredit].Count)
                {
                    throw new InsufficientCreditsException {
                              Available = contactCredits, Required = statuses[CanContactStatus.YesWithCredit].Count
                    }
                }
                ;
            }
        }
Exemplo n.º 5
0
 private IEnumerable <Guid> GetOrganisationHierarchyPath(IHasId <Guid> employer)
 {
     return(employer == null
         ? new OrganisationHierarchyPath()
         : _recruitersQuery.GetOrganisationHierarchyPath(employer.Id));
 }