public async Task <IActionResult> GetWorksByAuthor(int id)
        {
            Author existingAuthor = await _db.Authors
                                    .Where(a => a.AuthorId == id)
                                    .FirstOrDefaultAsync();

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

            try
            {
                return(Ok(await _db.Works
                          .Where(w => w.AuthorId == id)
                          .OrderBy(w => w.Title)
                          .Select(w => WorkGetDTO.FromModel(w))
                          .ToListAsync()));
            }
            catch (InvalidOperationException)
            {
                return(StatusCode(StatusCodes.Status500InternalServerError,
                                  _errorMessageFetchingData));
            }
        }
        public async Task <IActionResult> CreateWork(WorkPostDTO workToBeCreated)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            // Check if author exists.
            Author existingAuthor = await _db.Authors.FirstOrDefaultAsync(a => a.AuthorId == workToBeCreated.AuthorId);

            if (existingAuthor == null)
            {
                return(BadRequest(new { message = _errorMessageAuthorNotExists }));
            }

            // Check if work already exists.
            Work existingWork = await _db.Works
                                .FirstOrDefaultAsync(w => w.Title == workToBeCreated.Title);

            if (existingWork != null)
            {
                return(Conflict(new { message = _errorMessageWorkExists }));
            }

            try
            {
                int  userId  = (int)_userCtx.GetId();
                Work newWork = WorkPostDTO.ToModel(workToBeCreated, userId);

                await _db.Works.AddAsync(newWork);

                await _db.SaveChangesAsync();

                // Prepare response.
                WorkGetDTO newWorkResponse = WorkGetDTO.FromModel(newWork);

                // Trigger webhook for new work.
                TriggerWorkWebhook(Event.EditedWork, newWorkResponse, userId);

                string locationUri = $"{_baseUrl}/api/v1/works/{newWork.WorkId}";

                return(Created(locationUri, WorkGetDTO.FromModel(newWork)));
            }
            catch (DbUpdateException)
            {
                return(StatusCode(StatusCodes.Status500InternalServerError,
                                  _errorMessageSavingData));
            }
        }
 public async Task <IActionResult> GetWorksAddedByUser(int id)
 {
     try
     {
         return(Ok(await _db.Works
                   .Where(w => w.AddedBy == id)
                   .OrderBy(w => w.Title)
                   .Select(w => WorkGetDTO.FromModel(w))
                   .ToListAsync()));
     }
     catch (InvalidOperationException)
     {
         return(StatusCode(StatusCodes.Status500InternalServerError,
                           _errorMessageFetchingData));
     }
 }
        public async Task <IActionResult> GetWorks(string genre)
        {
            try
            {
                IEnumerable <WorkGetDTO> existingWorks = await _db.Works
                                                         .OrderBy(w => w.Title)
                                                         .Select(w => WorkGetDTO.FromModel(w))
                                                         .ToListAsync();

                if (!String.IsNullOrEmpty(genre))
                {
                    existingWorks = existingWorks.Where(w => w.Genre.ToLower() == genre.ToLower());
                }

                return(Ok(existingWorks));
            }
            catch (InvalidOperationException)
            {
                return(StatusCode(StatusCodes.Status500InternalServerError,
                                  _errorMessageFetchingData));
            }
        }
        public async Task <IActionResult> GetWork(int id)
        {
            Work existingWork = await _db.Works
                                .Where(w => w.WorkId == id)
                                .FirstOrDefaultAsync();

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

            try
            {
                WorkGetDTO workResponseDto = WorkGetDTO.FromModel(existingWork);

                return(Ok(workResponseDto));
            }
            catch (InvalidOperationException)
            {
                return(StatusCode(StatusCodes.Status500InternalServerError,
                                  _errorMessageFetchingData));
            }
        }
        public async Task <IActionResult> UpdateWork(int id, WorkPutDTO workToBeUpdated)
        {
            // Check that model is valid, and also that id in URI matches id in Body.
            if (!ModelState.IsValid ||
                id != workToBeUpdated.WorkId)
            {
                return(BadRequest(ModelState));
            }

            // Check that work by that ID exists.
            Work existingWork = await _db.Works
                                .Where(w => w.WorkId == id)
                                .FirstOrDefaultAsync();

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

            // Check if author exists.
            Author existingAuthor = await _db.Authors
                                    .FirstOrDefaultAsync(a => a.AuthorId == workToBeUpdated.AuthorId);

            if (existingAuthor == null)
            {
                return(BadRequest(new { message = _errorMessageAuthorNotExists }));
            }

            // Check if work with that title already exists.
            Work existingWorkWithTitle = await _db.Works
                                         .FirstOrDefaultAsync(w => w.Title == workToBeUpdated.Title);

            if (existingWorkWithTitle != null)
            {
                return(Conflict(new { message = _errorMessageWorkExists }));
            }

            try
            {
                int userId = (int)_userCtx.GetId();

                // First update work.
                _db.Entry(existingWork).CurrentValues.SetValues(workToBeUpdated);
                existingWork.LastEditedBy   = userId;
                existingWork.LastEditedDate = DateTime.Now;
                await _db.SaveChangesAsync();

                // Prepare response.
                WorkGetDTO editedWorkResponse = WorkGetDTO.FromModel(existingWork);

                // Trigger webhook for edited work.
                TriggerWorkWebhook(Event.EditedWork, editedWorkResponse, userId);

                return(Ok(editedWorkResponse));
            }
            catch (DbUpdateException)
            {
                return(StatusCode(StatusCodes.Status500InternalServerError,
                                  _errorMessageSavingData));
            }
        }