Загрузка данных


using System;
using System.Linq;
using System.Net;
using System.Web.Http;
using TaskTracker.Models;

namespace TaskTracker.Controllers
{
    public class TasksController : ApiController
    {
        [HttpGet]
        public IHttpActionResult GetTasks(
            string status = null,
            int? priority = null,
            int? projectId = null,
            string search = null)
        {
            var tasks = AppData.Tasks.AsEnumerable();

            if (!string.IsNullOrEmpty(status))
            {
                string[] statuses =
                {
                    "New",
                    "InProgress",
                    "Done",
                    "Cancelled"
                };

                if (!statuses.Contains(status))
                    return BadRequest("Неизвестный статус");

                tasks = tasks.Where(t => t.Status == status);
            }

            if (priority.HasValue)
            {
                if (priority.Value < 1 || priority.Value > 4)
                    return BadRequest("Приоритет должен быть от 1 до 4");

                tasks = tasks.Where(t => t.Priority == priority.Value);
            }

            if (projectId.HasValue)
            {
                tasks = tasks.Where(t => t.ProjectId == projectId.Value);
            }

            if (!string.IsNullOrEmpty(search))
            {
                tasks = tasks.Where(t =>
                    t.Title.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0 ||
                    t.Description.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0);
            }

            return Ok(tasks.ToList());
        }

        [HttpGet]
        public IHttpActionResult GetTask(int id)
        {
            var task = AppData.Tasks.FirstOrDefault(t => t.Id == id);

            if (task == null)
                return NotFound();

            return Ok(task);
        }

        [HttpGet]
        [Route("api/projects/{projectId}/tasks")]
        public IHttpActionResult GetProjectTasks(int projectId)
        {
            var project = AppData.Projects.FirstOrDefault(p => p.Id == projectId);

            if (project == null)
                return NotFound();

            var tasks = AppData.Tasks
                .Where(t => t.ProjectId == projectId)
                .ToList();

            return Ok(tasks);
        }

        [HttpPost]
        public IHttpActionResult CreateTask(TaskItem task)
        {
            if (task == null)
                return BadRequest("Данные задачи не переданы");

            var project = AppData.Projects
                .FirstOrDefault(p => p.Id == task.ProjectId);

            if (project == null)
                return NotFound();

            if (project.IsArchived)
            {
                return Content(
                    HttpStatusCode.Conflict,
                    "Нельзя добавить задачу в архивированный проект");
            }

            if (string.IsNullOrWhiteSpace(task.Title))
                return BadRequest("Название задачи не может быть пустым");

            if (string.IsNullOrWhiteSpace(task.Description) ||
                task.Description.Length < 10)
                return BadRequest(
                    "Описание должно содержать минимум 10 символов");

            if (task.Priority < 1 || task.Priority > 4)
                return BadRequest("Приоритет должен быть от 1 до 4");

            if (task.DueDate.HasValue &&
                task.DueDate.Value.Date < DateTime.Today)
                return BadRequest(
                    "Срок выполнения не может быть раньше текущей даты");

            int newId = AppData.Tasks.Count == 0
                ? 1
                : AppData.Tasks.Max(t => t.Id) + 1;

            task.Id = newId;
            task.Status = "New";
            task.CreatedAt = DateTime.Now;

            AppData.Tasks.Add(task);

            return Content(HttpStatusCode.Created, task);
        }

        [HttpPut]
        public IHttpActionResult UpdateTask(int id, TaskItem newTask)
        {
            var task = AppData.Tasks.FirstOrDefault(t => t.Id == id);

            if (task == null)
                return NotFound();

            if (newTask == null)
                return BadRequest("Данные задачи не переданы");

            if (string.IsNullOrWhiteSpace(newTask.Title))
                return BadRequest("Название задачи не может быть пустым");

            if (string.IsNullOrWhiteSpace(newTask.Description) ||
                newTask.Description.Length < 10)
                return BadRequest(
                    "Описание должно содержать минимум 10 символов");

            if (newTask.Priority < 1 || newTask.Priority > 4)
                return BadRequest("Приоритет должен быть от 1 до 4");

            if (newTask.DueDate.HasValue &&
                newTask.DueDate.Value.Date < DateTime.Today)
                return BadRequest(
                    "Срок выполнения не может быть раньше текущей даты");

            task.Title = newTask.Title;
            task.Description = newTask.Description;
            task.Priority = newTask.Priority;
            task.DueDate = newTask.DueDate;

            return Ok(task);
        }

        [HttpPut]
        [Route("api/tasks/{id}/status")]
        public IHttpActionResult ChangeStatus(int id, StatusModel model)
        {
            var task = AppData.Tasks.FirstOrDefault(t => t.Id == id);

            if (task == null)
                return NotFound();

            string[] statuses =
            {
                "New",
                "InProgress",
                "Done",
                "Cancelled"
            };

            if (model == null || !statuses.Contains(model.Status))
                return BadRequest("Неизвестный статус");

            bool allowed = false;

            if (task.Status == "New" &&
                (model.Status == "InProgress" ||
                 model.Status == "Cancelled"))
            {
                allowed = true;
            }

            if (task.Status == "InProgress" &&
                (model.Status == "Done" ||
                 model.Status == "Cancelled"))
            {
                allowed = true;
            }

            if (!allowed)
            {
                return Content(
                    HttpStatusCode.Conflict,
                    "Такой переход статуса запрещен");
            }

            task.Status = model.Status;

            return Ok(task);
        }

        [HttpDelete]
        public IHttpActionResult DeleteTask(int id)
        {
            var task = AppData.Tasks.FirstOrDefault(t => t.Id == id);

            if (task == null)
                return NotFound();

            if (task.Status == "InProgress")
            {
                return Content(
                    HttpStatusCode.Conflict,
                    "Нельзя удалить задачу, которая находится в работе");
            }

            AppData.Tasks.Remove(task);

            return StatusCode(HttpStatusCode.NoContent);
        }

        [HttpGet]
        [Route("api/tasks/overdue")]
        public IHttpActionResult GetOverdueTasks()
        {
            var tasks = AppData.Tasks
                .Where(t =>
                    t.DueDate.HasValue &&
                    t.DueDate.Value.Date < DateTime.Today &&
                    t.Status != "Done" &&
                    t.Status != "Cancelled")
                .ToList();

            return Ok(tasks);
        }
    }

    public class StatusModel
    {
        public string Status { get; set; }
    }
}