コード例 #1
0
        /// <summary>
        /// Get an array of parcels within the specified filter.
        /// Will not return sensitive parcels unless the user has the `sensitive-view` claim and belongs to the owning agency.
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public Paged <Parcel> Get(ParcelFilter filter)
        {
            filter.ThrowIfNull(nameof(filter));
            this.User.ThrowIfNotAuthorized(Permissions.SystemAdmin, Permissions.AgencyAdmin);

            if (filter.Page < 1)
            {
                throw new ArgumentException("Argument must be greater than or equal to 1.", nameof(filter.Page));
            }
            if (filter.Quantity < 1)
            {
                throw new ArgumentException("Argument must be greater than or equal to 1.", nameof(filter.Quantity));
            }

            // Check if user has the ability to view sensitive properties.
            var userAgencies  = this.User.GetAgenciesAsNullable();
            var viewSensitive = this.User.HasPermission(Security.Permissions.SensitiveView);

            // Users may only view sensitive properties if they have the `sensitive-view` claim and belong to the owning agency.
            var query = this.Context.Parcels.AsNoTracking();

            if (filter.NELatitude.HasValue && filter.NELongitude.HasValue && filter.SWLatitude.HasValue && filter.SWLongitude.HasValue)
            {
                query = query.Where(p =>
                                    p.Latitude != 0 &&
                                    p.Longitude != 0 &&
                                    p.Latitude <= filter.NELatitude &&
                                    p.Latitude >= filter.SWLatitude &&
                                    p.Longitude <= filter.NELongitude &&
                                    p.Longitude >= filter.SWLongitude);
            }

            if (filter.Agencies?.Any() == true)
            {
                var filterAgencies = filter.Agencies.Select(a => (int?)a);
                query = query.Where(p => filterAgencies.Contains(p.AgencyId));
            }
            if (filter.ClassificationId.HasValue)
            {
                query = query.Where(p => p.ClassificationId == filter.ClassificationId);
            }
            if (!String.IsNullOrWhiteSpace(filter.ProjectNumber))
            {
                query = query.Where(p => EF.Functions.Like(p.ProjectNumber, $"{filter.ProjectNumber}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Description))
            {
                query = query.Where(p => EF.Functions.Like(p.Description, $"%{filter.Description}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Municipality))
            {
                query = query.Where(p => EF.Functions.Like(p.Municipality, $"%{filter.Municipality}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Zoning))
            {
                query = query.Where(p => EF.Functions.Like(p.Zoning, $"%{filter.Zoning}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.ZoningPotential))
            {
                query = query.Where(p => EF.Functions.Like(p.ZoningPotential, $"%{filter.ZoningPotential}%"));
            }

            // TODO: Parse the address information by City, Postal, etc.
            if (!String.IsNullOrWhiteSpace(filter.Address))
            {
                query = query.Where(p => EF.Functions.Like(p.Address.Address1, $"%{filter.Address}%") || EF.Functions.Like(p.Address.City.Name, $"%{filter.Address}%"));
            }

            if (filter.MinLandArea.HasValue)
            {
                query = query.Where(p => p.LandArea >= filter.MinLandArea);
            }
            if (filter.MaxLandArea.HasValue)
            {
                query = query.Where(p => p.LandArea <= filter.MaxLandArea);
            }

            // TODO: Review performance of the evaluation query component.
            if (filter.MinEstimatedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MinEstimatedValue <= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == this.Context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == FiscalKeys.Estimated)
                                                    .Max(pe => pe.FiscalYear))
                                    .Value);
            }
            if (filter.MaxEstimatedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MaxEstimatedValue >= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == this.Context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == FiscalKeys.Estimated)
                                                    .Max(pe => pe.FiscalYear))
                                    .Value);
            }

            // TODO: Review performance of the evaluation query component.
            if (filter.MinAssessedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MinAssessedValue <= p.Evaluations
                                    .FirstOrDefault(e => e.Date == this.Context.ParcelEvaluations
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == EvaluationKeys.Assessed)
                                                    .Max(pe => pe.Date))
                                    .Value);
            }
            if (filter.MaxAssessedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MaxAssessedValue >= p.Evaluations
                                    .FirstOrDefault(e => e.Date == this.Context.ParcelEvaluations
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == EvaluationKeys.Assessed)
                                                    .Max(pe => pe.Date))
                                    .Value);
            }

            if (filter.Sort?.Any() == true)
            {
                query = query.OrderByProperty(filter.Sort);
            }

            var pagedEntities = query.Skip((filter.Page - 1) * filter.Quantity).Take(filter.Quantity);

            return(new Paged <Parcel>(pagedEntities, filter.Page, filter.Quantity, query.Count()));
        }