public async Task <IHttpActionResult> GetProductFileFeedbackImage(long productFileFeedbackId)
        {
            ProductFileFeedback productFileFeedback = db.Feedback.Where(_productFileFeedback => _productFileFeedback.ID == productFileFeedbackId).SingleOrDefault();

            if (productFileFeedback == null)
            {
                return(NotFound());
            }

            byte[] imageBytes;
            string mediaTypeHeader;

            if (productFileFeedback.Image != null)
            {
                imageBytes      = productFileFeedback.Image;
                mediaTypeHeader = "image/png";
            }
            else
            {
                string filePath = System.Web.Hosting.HostingEnvironment.MapPath("/img/user_image.svg");

                imageBytes      = File.ReadAllBytes(filePath);
                mediaTypeHeader = "image/svg+xml";
            }

            MemoryStream        memoryStream    = new MemoryStream(imageBytes);
            HttpResponseMessage responseMessage = new HttpResponseMessage(HttpStatusCode.OK);

            responseMessage.Content = new StreamContent(memoryStream);
            responseMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(mediaTypeHeader);

            return(ResponseMessage(responseMessage));
        }
        public IEnumerable <FeedbackDTO> GetProductFileFeedbackReplies(long productFileFeedbackId)
        {
            string userName = User.Identity.Name;
            User   user     = db.Users.Where(_user => _user.UserName == userName).AsNoTracking().SingleOrDefault();

            if (user == null)
            {
                throw new HttpResponseException(HttpStatusCode.Unauthorized);
            }

            ProductFileFeedback productFileFeedback = db.Feedback.Where(_productFileFeedback => _productFileFeedback.ID == productFileFeedbackId)
                                                      .Include(_productFileFeedback => _productFileFeedback.ProductFile.GroupsVisibleTo)
                                                      .Include(_productFileFeedback => _productFileFeedback.ProductFile.Product.GroupsVisibleTo)
                                                      .Include(_productFileFeedback => _productFileFeedback.Replies)
                                                      .SingleOrDefault();

            if (productFileFeedback == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            if ((productFileFeedback.ProductFile.Product.Privacy == ProductPrivacy.Private) ||
                (productFileFeedback.ProductFile.Product.Privacy == ProductPrivacy.VisibleToSelectedGroups &&
                 productFileFeedback.ProductFile.Product.GroupsVisibleTo.Any(followerGroup => followerGroup.Followers.Any(follower => follower.UserID == user.Id)) == false) ||
                (productFileFeedback.ProductFile.Privacy == ProductFilePrivacy.Private) ||
                (productFileFeedback.ProductFile.Privacy == ProductFilePrivacy.VisibleToSelectedGroups &&
                 productFileFeedback.ProductFile.GroupsVisibleTo.Any(followerGroup => followerGroup.Followers.Any(follower => follower.UserID == user.Id)) == false))
            {
                throw new HttpResponseException(HttpStatusCode.Unauthorized);
            }

            /*
             * IEnumerable<ProductFile> productFiles = product.ProductFiles.Where(productFile => productFile.Privacy == ProductFilePrivacy.Public || productFile.Viewers.Any(viewer => viewer.UserID == user.Id))
             *                                                                                                                  .OrderBy(productFile => productFile.Category)
             *                                                                                                                  .ThenByDescending(productFile => productFile.UploadedAt);
             */
            return(Mapper.Map <IEnumerable <FeedbackDTO> >(productFileFeedback.Replies.OrderByDescending(reply => reply.PostedAt)));
        }
        public async Task <IHttpActionResult> NewProductFileFeedback(NewFeedbackDTO newFeedbackDTO)
        {
            string userName = User.Identity.Name;
            User   user     = db.Users.Where(_user => _user.UserName == userName).SingleOrDefault();

            if (user == null)
            {
                throw new HttpResponseException(HttpStatusCode.Unauthorized);
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            ProductFile productFile = db.ProductFiles.Where(_productFile => _productFile.ID == newFeedbackDTO.ProductFileID)
                                      .Include(_productFile => _productFile.GroupsVisibleTo)
                                      .Include(_productFile => _productFile.Product.GroupsVisibleTo)
                                      .Include(_productFile => _productFile.Product.TeamMembers
                                               .Select(_teamMember => _teamMember.User))
                                      .Include(_productFile => _productFile.Product.Company)
                                      .Include(_productFile => _productFile.Product.Company.Owner)
                                      .SingleOrDefault();

            if (productFile == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            if ((productFile.Product.CompanyID != user.Company.ID) &&
                (productFile.Product.TeamMembers.Any(teamMember => teamMember.UserID == user.Id && teamMember.CanEditTheProduct == true)) &&
                ((productFile.Product.Privacy == ProductPrivacy.Private) ||
                 (productFile.Product.Privacy == ProductPrivacy.VisibleToSelectedGroups &&
                  productFile.Product.GroupsVisibleTo.Any(followerGroup => followerGroup.Followers.Any(follower => follower.UserID == user.Id)) == false)) &&
                ((productFile.Privacy == ProductFilePrivacy.Private) ||
                 (productFile.Privacy == ProductFilePrivacy.VisibleToSelectedGroups &&
                  productFile.GroupsVisibleTo.Any(followerGroup => followerGroup.Followers.Any(follower => follower.UserID == user.Id)) == false)))
            {
                throw new HttpResponseException(HttpStatusCode.Unauthorized);
            }

            ProductFileFeedback replyTo = null;

            if (newFeedbackDTO.ReplyToID != null)
            {
                replyTo = db.Feedback.Where(_feedback => _feedback.ID == newFeedbackDTO.ReplyToID).SingleOrDefault();

                if (replyTo == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
            }

            ProductFileFeedback feedback = Mapper.Map <NewFeedbackDTO, ProductFileFeedback>(newFeedbackDTO);

            if (replyTo != null)
            {
                feedback.ReplyToID      = replyTo.ID;
                feedback.ReplyTo        = replyTo;
                replyTo.UpdatedAt       = DateTime.Now;
                db.Entry(replyTo).State = EntityState.Modified;
            }

            feedback.UserID        = user.Id;
            feedback.User          = user;
            feedback.ProductFileID = productFile.ID;
            feedback.ProductFile   = productFile;
            feedback.PostedAt      = DateTime.Now;
            feedback.UpdatedAt     = DateTime.Now;
            feedback = db.Feedback.Add(feedback);
            await db.SaveChangesAsync();

            string feedbackAuthorUserName = user.UserName;

            if (user.FirstName != null || user.LastName != null)
            {
                feedbackAuthorUserName = (user.FirstName == null ? "" : user.FirstName) + " " + (user.LastName == null ? "" : user.LastName);
            }

            string          feedbackAuthorCompanyName = user.Company == null ? "" : user.Company.DisplayName;
            string          apiKey         = SENDGRID_API_KEY;
            SendGridClient  sendGridClient = new SendGridClient(apiKey, "https://api.sendgrid.com");
            EmailAddress    emailSender    = new EmailAddress("*****@*****.**", "Cervitt");
            String          subject        = "Feedback notification";
            EmailAddress    emailRecipient = new EmailAddress(productFile.Product.Company.Owner.Email);
            Content         content        = new Content("text/html", "Hello world!");
            SendGridMessage mail           = MailHelper.CreateSingleEmail(emailSender, emailRecipient, subject, "", "");

            mail.TemplateId = "976c0e75-4105-4f08-b924-aefb27bf44e8";
            mail.AddSubstitution("<%companyName%>", productFile.Product.Company.DisplayName);
            mail.AddSubstitution("<%productName%>", productFile.Product.Name);
            mail.AddSubstitution("<%feedbackAuthorUserId%>", user.Id.ToString());
            mail.AddSubstitution("<%feedbackAuthorUserName%>", feedbackAuthorUserName);
            mail.AddSubstitution("<%feedbackAuthorUserTitle%>", user.JobTitle);
            mail.AddSubstitution("<%feedbackAuthorCompanyName%>", feedbackAuthorCompanyName);
            mail.AddSubstitution("<%feedbackTitle%>", feedback.Title);
            mail.AddSubstitution("<%feedbackBody%>", feedback.Body);

            dynamic response = sendGridClient.SendEmailAsync(mail);

            return(Ok(Mapper.Map <ProductFileFeedback, FeedbackDTO>(feedback)));
        }