mirror of
https://github.com/rjNemo/ticket_manager
synced 2026-06-12 11:46:40 +00:00
ticket model & endpoints done
This commit is contained in:
parent
734d8e931b
commit
b4b8b6f254
12 changed files with 102 additions and 59 deletions
|
|
@ -10,7 +10,7 @@ using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.Controllers
|
namespace TicketManager.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class UsersController : ControllerBase
|
public class UsersController : ControllerBase
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.Controllers
|
namespace TicketManager.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class FilesController : ControllerBase
|
public class FilesController : ControllerBase
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.Controllers
|
namespace TicketManager.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class HistoriesController : ControllerBase
|
public class HistoriesController : ControllerBase
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.Controllers
|
namespace TicketManager.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class NotesController : ControllerBase
|
public class NotesController : ControllerBase
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using TicketManager.Models;
|
||||||
namespace TicketManager.Controllers
|
namespace TicketManager.Controllers
|
||||||
{
|
{
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
[Route("api/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class ProjectsController : ControllerBase
|
public class ProjectsController : ControllerBase
|
||||||
{
|
{
|
||||||
|
|
@ -152,7 +152,7 @@ namespace TicketManager.Controllers
|
||||||
return project.GetMembers();
|
return project.GetMembers();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut("{id}/setMembers")]
|
[HttpPut("{id}/members")]
|
||||||
public async Task<ActionResult<Project>> SetProjectMembers(int id, List<AppUser> projectMembers)
|
public async Task<ActionResult<Project>> SetProjectMembers(int id, List<AppUser> projectMembers)
|
||||||
{
|
{
|
||||||
Project project = await GetProjectByIdAsync(id);
|
Project project = await GetProjectByIdAsync(id);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using TicketManager.Models;
|
||||||
|
|
||||||
namespace TicketManager.Controllers
|
namespace TicketManager.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/[controller]")]
|
[Route("api/v1/[controller]")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class TicketsController : ControllerBase
|
public class TicketsController : ControllerBase
|
||||||
{
|
{
|
||||||
|
|
@ -25,25 +25,14 @@ namespace TicketManager.Controllers
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<ActionResult<IEnumerable<Ticket>>> GetTickets()
|
public async Task<ActionResult<IEnumerable<Ticket>>> GetTickets()
|
||||||
{
|
{
|
||||||
return await _context.Tickets
|
return await getAllTicketsAsync();
|
||||||
.Include(t => t.Creator)
|
|
||||||
.Include(p => p.Notes)
|
|
||||||
.Include(p => p.Edits)
|
|
||||||
.Include(p => p.Files)
|
|
||||||
.AsNoTracking()
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET: api/Tickets/5
|
// GET: api/Tickets/5
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public async Task<ActionResult<Ticket>> GetTicket(int id)
|
public async Task<ActionResult<Ticket>> GetTicket(int id)
|
||||||
{
|
{
|
||||||
var ticket = await _context.Tickets
|
var ticket = await getTicketByIdAsync(id);
|
||||||
.Include(t => t.Creator)
|
|
||||||
.Include(p => p.Notes)
|
|
||||||
.Include(p => p.Edits)
|
|
||||||
.Include(p => p.Files)
|
|
||||||
.FirstOrDefaultAsync(t => t.Id == id);
|
|
||||||
|
|
||||||
if (ticket == null)
|
if (ticket == null)
|
||||||
{
|
{
|
||||||
|
|
@ -113,9 +102,47 @@ namespace TicketManager.Controllers
|
||||||
return ticket;
|
return ticket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}/assignees")]
|
||||||
|
public async Task<ActionResult<List<AppUser>>> GetTicketAssignees(int id)
|
||||||
|
{
|
||||||
|
Ticket ticket = await getTicketByIdAsync(id);
|
||||||
|
return ticket.GetAssignees();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{id}/closed")]
|
||||||
|
public async Task<ActionResult> CloseTicket(int id)
|
||||||
|
{
|
||||||
|
Ticket ticket = await getTicketByIdAsync(id);
|
||||||
|
ticket.Close();
|
||||||
|
return NoContent();
|
||||||
|
}
|
||||||
|
|
||||||
private bool TicketExists(int id)
|
private bool TicketExists(int id)
|
||||||
{
|
{
|
||||||
return _context.Tickets.Any(e => e.Id == id);
|
return _context.Tickets.Any(e => e.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IQueryable<Ticket> ticketQuery() // problem with link
|
||||||
|
{
|
||||||
|
return _context.Tickets
|
||||||
|
.Include(p => p.Project)
|
||||||
|
.ThenInclude(a => a.Assignments)
|
||||||
|
.ThenInclude(p => p.User)
|
||||||
|
// .Include(p => p.Edits)
|
||||||
|
// .Include(p => p.Notes)
|
||||||
|
// .Include(p => p.Files)
|
||||||
|
.Include(p => p.Creator)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<ActionResult<IEnumerable<Ticket>>> getAllTicketsAsync()
|
||||||
|
{
|
||||||
|
return await ticketQuery().ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Ticket> getTicketByIdAsync(int id)
|
||||||
|
{
|
||||||
|
return await ticketQuery().FirstOrDefaultAsync(a => a.Id == id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ namespace TicketManager.Models
|
||||||
|
|
||||||
[DataType(DataType.Date)]
|
[DataType(DataType.Date)]
|
||||||
[Display(Name = "Member since"), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
|
[Display(Name = "Member since"), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
|
||||||
public DateTime Created_at { get; set; } = DateTime.Now;
|
public DateTime Created_at { get; private set; } = DateTime.Now;
|
||||||
|
|
||||||
// [Display(Name = "Avatar")]
|
// [Display(Name = "Avatar")]
|
||||||
// public byte[] Picture { get; set; }
|
// public byte[] Picture { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,25 @@ namespace TicketManager.Models
|
||||||
{
|
{
|
||||||
public class File
|
public class File
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public string Location { get; set; }
|
|
||||||
|
public string FileName { get; set; }
|
||||||
|
|
||||||
|
private string _location;
|
||||||
|
public string Location
|
||||||
|
{
|
||||||
|
get { return _location; }
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
string filesUrl = "";
|
||||||
|
_location = $"{filesUrl}/{FileName}";
|
||||||
|
}
|
||||||
|
}
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public int Size { get; set; }
|
public int Size { get; set; } // deduce auto from FileName
|
||||||
public string Format { get; set; }
|
public string Format { get; set; } // deduce auto from FileName
|
||||||
|
|
||||||
public AppUser AddedBy { get; set; }
|
public AppUser AddedBy { get; set; }
|
||||||
public int UserId { get; set; }
|
public int UserId { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ namespace TicketManager.Models
|
||||||
{
|
{
|
||||||
return _progression;
|
return _progression;
|
||||||
}
|
}
|
||||||
set
|
private set
|
||||||
{
|
{
|
||||||
_progression = Tickets.Count() == 0 ? 0 :
|
_progression = Tickets.Count() == 0 ? 0 :
|
||||||
(decimal)this.Tickets.
|
(decimal)this.Tickets.
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,27 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace TicketManager.Models
|
namespace TicketManager.Models
|
||||||
{
|
{
|
||||||
public class Ticket : ITask
|
public class Ticket : ITask
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[StringLength(100)]
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
[StringLength(100)]
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public DateTime CreatedAt { get; set; } = DateTime.Now;
|
|
||||||
|
[DataType(DataType.Date)]
|
||||||
|
[Display(Name = "Creation Date"), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
|
||||||
|
public DateTime CreatedAt { get; private set; } = DateTime.Now;
|
||||||
|
|
||||||
|
[DataType(DataType.Date)]
|
||||||
|
[Display(Name = "Estimated Ending Date"), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
|
||||||
public DateTime PlannedEnding { get; set; }
|
public DateTime PlannedEnding { get; set; }
|
||||||
|
|
||||||
public Status Status { get; set; } = Status.ToDo;
|
public Status Status { get; set; } = Status.ToDo;
|
||||||
|
|
@ -16,42 +29,28 @@ namespace TicketManager.Models
|
||||||
public Difficulty Difficulty { get; set; } = Difficulty.Undefined;
|
public Difficulty Difficulty { get; set; } = Difficulty.Undefined;
|
||||||
public Category Category { get; set; } = Category.Undefined;
|
public Category Category { get; set; } = Category.Undefined;
|
||||||
|
|
||||||
|
[Display(Name = "Created By")]
|
||||||
public AppUser Creator { get; set; }
|
public AppUser Creator { get; set; }
|
||||||
public Guid CreatorId { get; set; }
|
public Guid CreatorId { get; set; }
|
||||||
|
|
||||||
|
[Display(Name = "Project")]
|
||||||
public Project Project { get; set; }
|
public Project Project { get; set; }
|
||||||
public int ProjectId { get; set; }
|
public int ProjectId { get; set; }
|
||||||
private List<Note> _notes;
|
public List<Note> Notes = new List<Note>();
|
||||||
public List<Note> Notes
|
|
||||||
{
|
public List<History> Edits = new List<History>();
|
||||||
get
|
|
||||||
{
|
public List<File> Files = new List<File>();
|
||||||
return _notes ?? new List<Note>();
|
|
||||||
}
|
|
||||||
set { _notes = value; }
|
|
||||||
}
|
|
||||||
private List<History> _edits;
|
|
||||||
public List<History> Edits
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _edits ?? new List<History>();
|
|
||||||
}
|
|
||||||
set { _edits = value; }
|
|
||||||
}
|
|
||||||
private List<File> _files;
|
|
||||||
public List<File> Files
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _files ?? new List<File>();
|
|
||||||
}
|
|
||||||
set { _files = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
public void GetAssignees() { throw new NotImplementedException("Not Implemented"); }
|
public List<AppUser> GetAssignees()
|
||||||
|
{
|
||||||
|
return Project.Assignments.Select(a => a.User).ToList();
|
||||||
|
}
|
||||||
public void GetLastUpdateTime() { throw new NotImplementedException("Not Implemented"); }
|
public void GetLastUpdateTime() { throw new NotImplementedException("Not Implemented"); }
|
||||||
public void Close() { throw new NotImplementedException("Not Implemented"); }
|
public void Close()
|
||||||
public void AddFile() { throw new NotImplementedException("Not Implemented"); }
|
{
|
||||||
|
Status = Status.Done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
|
|
||||||
## API Documentation
|
## API Documentation
|
||||||
|
|
||||||
- [Internal Link. Don't forget to update](https://localhost:5001/swagger/index.html)
|
### v1
|
||||||
|
|
||||||
|
- [Internal Link. Don't forget to update](https://localhost:5001/swagger)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
|
@ -39,3 +41,4 @@
|
||||||
- Ensure Tickets Files belong to Project Files
|
- Ensure Tickets Files belong to Project Files
|
||||||
- Write a query class to refactor code and optimize perf on get queries (AsNoTracking)
|
- Write a query class to refactor code and optimize perf on get queries (AsNoTracking)
|
||||||
- Async model methods ?
|
- Async model methods ?
|
||||||
|
- setMembers & removeMembers from project api not working
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ namespace TicketManager
|
||||||
{
|
{
|
||||||
Version = "v1",
|
Version = "v1",
|
||||||
Title = "Ticket Manager API",
|
Title = "Ticket Manager API",
|
||||||
Description = "A simple example ASP.NET Core Web API",
|
Description = "Ticket Manger API for Teams",
|
||||||
Contact = new OpenApiContact
|
Contact = new OpenApiContact
|
||||||
{
|
{
|
||||||
Name = "Ruidy Nemausat",
|
Name = "Ruidy Nemausat",
|
||||||
|
|
@ -91,7 +91,7 @@ namespace TicketManager
|
||||||
|
|
||||||
app.UseSwaggerUI(c =>
|
app.UseSwaggerUI(c =>
|
||||||
{
|
{
|
||||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Ticket Manager API V1");
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Ticket Manager API v1");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue