示例#1
0
 /// <summary>
 /// Add a validation error if the point is not valid.
 /// </summary>
 /// <param name="point">The point to validate.</param>
 private void IsPointValid(Point point)
 {
     if (point == null || !point.IsPointValid())
     {
         FFErrors.Add(ValidationErrorCode.PropertyIsInvalid(nameof(point)));
     }
 }
示例#2
0
        /// <summary>
        /// Creates a dashboard.
        /// </summary>
        /// <param name="dto">Data Transfer Object (DTO) used to create an entity.</param>
        /// <returns>
        /// An asynchronous task result containing information needed to create an API response message.
        /// If successful, the task result contains the DTO associated with the entity created.
        /// </returns>
        public override async Task <CommandResult <DashboardQueryDto, Guid> > Create(DashboardBaseDto dto)
        {
            var userId = Thread.CurrentPrincipal == null ? null : Thread.CurrentPrincipal.GetUserIdFromPrincipal();

            if (userId == null)
            {
                return(Command.Error <DashboardQueryDto>(GeneralErrorCodes.TokenInvalid("UserId")));
            }

            var userIdGuid = Guid.Parse(userId);

            var validationResponse = ValidatorCreate.Validate(dto);

            if (dto == null)
            {
                return(Command.Error <DashboardQueryDto>(validationResponse));
            }

            if (dto.Id != Guid.Empty)
            {
                validationResponse.FFErrors.Add(ValidationErrorCode.PropertyIsInvalid("Id"));
            }

            var userTenants = _context.GetTenantsForUser(userIdGuid);

            if (dto.TenantId != Guid.Empty && !userTenants.Any(x => x.Id == dto.TenantId))
            {
                validationResponse.FFErrors.Add(ValidationErrorCode.ForeignKeyValueDoesNotExist("TenantId"));
            }

            if (_context.Dashboards.Any(x => x.OwnerUserId == userIdGuid && x.Name == dto.Name))
            {
                validationResponse.FFErrors.Add(EntityErrorCode.EntityAlreadyExists);
            }

            var userDashboardOptions = _context.GetDashboardOptionsForUser(userIdGuid);

            if (dto.DashboardOptionId != Guid.Empty && !userDashboardOptions.Any(x => x.Id == dto.DashboardOptionId))
            {
                validationResponse.FFErrors.Add(ValidationErrorCode.ForeignKeyValueDoesNotExist("DashboardOptionId"));
            }

            if (validationResponse.IsInvalid)
            {
                return(Command.Error <DashboardQueryDto>(validationResponse));
            }

            var newEntity = new Dashboard();

            _mapper.Map(dto, newEntity);

            newEntity.Id = Guid.NewGuid();
            newEntity.SetAuditFieldsOnCreate(userId);
            newEntity.OwnerUserId = userIdGuid;

            _context.Dashboards.Add(newEntity);
            await _context.SaveChangesAsync().ConfigureAwait(false);

            return(Command.Created(_mapper.Map(newEntity, new DashboardQueryDto()), newEntity.Id));
        }
示例#3
0
        /// <summary>
        /// Creates a Location Log Entry.
        /// </summary>
        /// <param name="dto">Data Transfer Object (DTO) used to create a Location Log Entry.</param>
        /// <returns>
        /// An asynchronous task result containing information needed to create an API response message.
        /// If successful, the task result contains the DTO associated with the Location Log Entry.
        /// </returns>
        public override async Task <CommandResult <LocationLogEntryQueryDto, Guid> > Create(LocationLogEntryBaseDto dto)
        {
            // User ID should always be available, but if not ...
            var userId = GetCurrentUser();

            if (!userId.HasValue)
            {
                return(Command.Error <LocationLogEntryQueryDto>(GeneralErrorCodes.TokenInvalid("UserId")));
            }

            var validationResponse = ValidatorCreate.Validate(dto);

            if (dto == null)
            {
                return(Command.Error <LocationLogEntryQueryDto>(validationResponse));
            }

            if (dto.Id != Guid.Empty)
            {
                validationResponse.FFErrors.Add(ValidationErrorCode.PropertyIsInvalid(nameof(LocationLogEntry.Id)));
            }

            var locationExists = await DoesLocationExist(dto.LocationId);

            if (!locationExists)
            {
                validationResponse.FFErrors.Add(ValidationErrorCode.ForeignKeyValueDoesNotExist(nameof(LocationLogEntry.LocationId)));
            }

            if (validationResponse.IsInvalid)
            {
                return(Command.Error <LocationLogEntryQueryDto>(validationResponse));
            }

            var locationLogEntry = new LocationLogEntry
            {
                Id = Guid.NewGuid()
            };

            _mapper.Map(dto, locationLogEntry);

            locationLogEntry.SetAuditFieldsOnCreate(userId.Value);

            _context.LocationLogEntries.Add(locationLogEntry);
            await _context.SaveChangesAsync().ConfigureAwait(false);

            return(Command.Created(_mapper.Map(locationLogEntry, new LocationLogEntryQueryDto()), locationLogEntry.Id));
        }
示例#4
0
        /// <summary>
        /// Creates a limit type.
        /// </summary>
        /// <param name="dto">Data Transfer Object (DTO) used to create an entity.</param>
        /// <returns>
        /// An asynchronous task result containing information needed to create an API response message.
        /// If successful, the task result contains the DTO associated with the entity created.
        /// </returns>
        public override async Task <CommandResult <LimitTypeQueryDto, Guid> > Create(LimitTypeBaseDto dto)
        {
            var userId = Thread.CurrentPrincipal == null ? null : Thread.CurrentPrincipal.GetUserIdFromPrincipal();

            if (userId == null)
            {
                return(Command.Error <LimitTypeQueryDto>(GeneralErrorCodes.TokenInvalid("UserId")));
            }

            var validationResponse = ValidatorCreate.Validate(dto);

            if (dto == null)
            {
                return(Command.Error <LimitTypeQueryDto>(validationResponse));
            }

            if (dto.Id != Guid.Empty)
            {
                validationResponse.FFErrors.Add(ValidationErrorCode.PropertyIsInvalid("Id"));
            }

            if (_context.LimitTypes.Any(x => x.I18NKeyName == dto.I18NKeyName))
            {
                validationResponse.FFErrors.Add(EntityErrorCode.EntityAlreadyExists);
            }

            if (validationResponse.IsInvalid)
            {
                return(Command.Error <LimitTypeQueryDto>(validationResponse));
            }

            var newEntity = new LimitType();

            _mapper.Map(dto, newEntity);

            newEntity.Id = Guid.NewGuid();
            newEntity.SetAuditFieldsOnCreate(userId);

            _context.LimitTypes.Add(newEntity);
            await _context.SaveChangesAsync().ConfigureAwait(false);

            return(Command.Created(_mapper.Map(newEntity, new LimitTypeQueryDto()), newEntity.Id));
        }
示例#5
0
        /// <summary>
        /// Creates a location.
        /// </summary>
        /// <param name="dto">Data Transfer Object (DTO) used to create a location.</param>
        /// <returns>
        /// An asynchronous task result containing information needed to create an API response message.
        /// If successful, the task result contains the DTO associated with the location.
        /// </returns>
        /// <remarks>
        /// Note that there is no checking for a circular reference for creating a location. This is
        /// because the created item does not have children. So, there cannot be a circular reference.
        /// </remarks>
        public override async Task <CommandResult <LocationQueryDto, Guid> > Create(LocationBaseDto dto)
        {
            // Thread.CurrentPrincipal is not available in the constructor.  Do not try to move this.
            var uid = GetCurrentUser();

            // User ID should always be available, but if not ...
            if (!uid.HasValue)
            {
                return(Command.Error <LocationQueryDto>(GeneralErrorCodes.TokenInvalid("UserId")));
            }

            var user = await _context.Users
                       .Include(x => x.Tenants.Select(y => y.ProductOfferings))
                       .FirstOrDefaultAsync(u => u.Id == uid.Value);

            if (user == null)
            {
                return(Command.Error <LocationQueryDto>(GeneralErrorCodes.TokenInvalid("UserId")));
            }

            var validationResponse = ValidatorCreate.Validate(dto);

            if (dto == null)
            {
                return(Command.Error <LocationQueryDto>(validationResponse));
            }

            if (dto.Id != Guid.Empty)
            {
                validationResponse.FFErrors.Add(ValidationErrorCode.PropertyIsInvalid(nameof(Location.Id)));
            }

            var existing = await _context.Locations.AnyAsync(l => l.Name == dto.Name).ConfigureAwait(false);

            if (existing)
            {
                validationResponse.FFErrors.Add(EntityErrorCode.EntityAlreadyExists);
            }

            if (dto.ParentId.HasValue)
            {
                existing = await _context.Locations.AnyAsync(l => l.Id == dto.ParentId.Value).ConfigureAwait(false);

                if (!existing)
                {
                    validationResponse.FFErrors.Add(ValidationErrorCode.ForeignKeyValueDoesNotExist(nameof(Location.ParentId)));
                }
            }

            if (dto.LocationTypeId != Guid.Empty && !_context.LocationTypes.Any(lt => lt.Id == dto.LocationTypeId))
            {
                validationResponse.FFErrors.Add(ValidationErrorCode.ForeignKeyValueDoesNotExist(nameof(Location.LocationTypeId)));
            }

            if (validationResponse.IsInvalid)
            {
                return(Command.Error <LocationQueryDto>(validationResponse));
            }

            var location = new Location
            {
                Id = Guid.NewGuid()
            };

            _mapper.Map(dto, location);

            location.CreatedById = uid.Value;
            location.CreatedOn   = DateTime.UtcNow;
            location.SetAuditFieldsOnUpdate(uid.Value);

            _context.Locations.Add(location);

            // Add the Location to the Product Offering / Tenant / Location List
            if (user.Tenants.Count > 0)
            {
                // Only care about the first tenant in the list. In the future, the list of tenants
                // will contain only one element and may be replaced by a scalar.
                var tenant = user.Tenants.ElementAt(0);

                // Add a Product Offering / Tenant / Location for the Collect PO
                // TODO: This is going to break if we change the name of the productOffering
                var productOffering = tenant.ProductOfferings.FirstOrDefault(x => x.Name == "Collect");

                if (productOffering == null)
                {
                    return(Command.Error <LocationQueryDto>(EntityErrorCode.ReferencedEntityNotFound));
                }

                var productOfferingTenantLocation = new ProductOfferingTenantLocation
                {
                    ProductOfferingId = productOffering.Id,
                    TenantId          = tenant.Id,
                    LocationId        = location.Id
                };

                _context.ProductOfferingTenantLocations.Add(productOfferingTenantLocation);
            }

            await _context.SaveChangesAsync().ConfigureAwait(false);

            return(Command.Created(_mapper.Map(location, new LocationQueryDto()), location.Id));
        }
示例#6
0
        /// <summary>
        /// Retrieves the indicated file.
        /// </summary>
        /// <param name="id">
        /// ID that uniquely identifies the file to be retrieved. The ID is is the key of the
        /// metadata stored in DocumentDb.
        /// </param>
        /// <returns>The file indicated by the specified ID.</returns>
        public async Task <HttpResponseMessage> Get(Guid?id)
        {
            // Check that token contains a user ID
            var userId = Thread.CurrentPrincipal == null ? null : Thread.CurrentPrincipal.GetUserIdFromPrincipal();

            if (userId == null)
            {
                return(HandleErrors(GeneralErrorCodes.TokenInvalid("UserId"), HttpStatusCode.Unauthorized));
            }

            // Make sure user ID is active
            var userIdGuid = new Guid(userId);
            var user       = await _context.Users.FirstOrDefaultAsync(u => u.Id == userIdGuid);

            if (user == null || !user.IsActive)
            {
                return(HandleErrors(GeneralErrorCodes.TokenInvalid("UserId"), HttpStatusCode.Unauthorized));
            }

            // Make sure there's a tenant associated with the user
            if (user.Tenants.Count < 1)
            {
                return(HandleErrors(GeneralErrorCodes.TokenInvalid("UserId"), HttpStatusCode.Unauthorized));
            }

            // Validate the argument (invalid Guid's are received as nulls)
            if (id == null)
            {
                return(HandleErrors(ValidationErrorCode.PropertyIsInvalid(nameof(id)), HttpStatusCode.BadRequest));
            }

            // Retrieve the metadata associated with the specified ID
            var metadata = await _documentDb.GetItemAsync(id.ToString());

            if (metadata == null || string.IsNullOrWhiteSpace(metadata.BlobStorageContainerName) ||
                string.IsNullOrWhiteSpace(metadata.BlobStorageBlobName))
            {
                return(HandleErrors(EntityErrorCode.EntityNotFound, HttpStatusCode.NotFound));
            }

            // Make sure the user is authorized (intentionally returns Not Found even though it's an authorization problem)
            if (metadata.TenantIds.Count < 1 ||
                !metadata.TenantIds.Intersect(user.Tenants.Select(u => u.Id)).Any())
            {
                return(HandleErrors(EntityErrorCode.EntityNotFound, HttpStatusCode.NotFound));
            }

            // Retrieve the blob
            var stream = new MemoryStream();
            BlobDownloadResult result;

            try
            {
                result = await _blobManager.DownloadBlobAsync(stream, _blobStorageConnectionString,
                                                              metadata.BlobStorageContainerName, metadata.BlobStorageBlobName);
            }
            catch (Exception ex)
            {
                FFLogManager.LogException(ex);
                return(HandleErrors(EntityErrorCode.EntityNotFound, HttpStatusCode.NotFound));
            }

            if (stream.Length == 0)
            {
                return(HandleErrors(EntityErrorCode.EntityNotFound, HttpStatusCode.NotFound));
            }

            // Create the response
            stream.Position = 0;
            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StreamContent(stream)
            };

            // Determine file name
            string filename = result.BlobName;

            if (!string.IsNullOrWhiteSpace(metadata.OriginalFileName))
            {
                var fileInfo = new FileInfo(metadata.OriginalFileName);
                if (!string.IsNullOrWhiteSpace(fileInfo.Name))
                {
                    filename = fileInfo.Name;
                }
            }

            // Set response content headers
            response.Content.Headers.ContentLength      = stream.Length;
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = filename,
                Size     = stream.Length
            };

            return(response);
        }