Skip to content

Commit

Permalink
Add Create Declaration API (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
Philippluca authored Nov 15, 2023
2 parents 590e756 + b3c0637 commit 0ee35b9
Show file tree
Hide file tree
Showing 9 changed files with 358 additions and 5 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Start db
run: docker-compose up -d db

- name: Setup dotnet
uses: actions/setup-dotnet@v3
with:
Expand Down
21 changes: 20 additions & 1 deletion src/GeoCop.Api/Context.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,40 @@ namespace GeoCop.Api
/// <summary>
/// Database context to manage the delivery database.
/// </summary>
internal class Context : DbContext
public class Context : DbContext
{
/// <summary>
/// Database context to manage the database.
/// </summary>
/// <param name="options"></param>
public Context(DbContextOptions<Context> options)
: base(options)
{
}

/// <summary>
/// Set of all <see cref="User"/>.
/// </summary>
public DbSet<User> Users { get; set; }

/// <summary>
/// Set of all <see cref="Organisation"/>.
/// </summary>
public DbSet<Organisation> Organisations { get; set; }

/// <summary>
/// Set of all <see cref="DeliveryMandate"/>.
/// </summary>
public DbSet<Delivery> Deliveries { get; set; }

/// <summary>
/// Set of all <see cref="DeliveryMandate"/>.
/// </summary>
public DbSet<DeliveryMandate> DeliveryMandates { get; set; }

/// <summary>
/// Set of all <see cref="Asset"/>.
/// </summary>
public DbSet<Asset> Assets { get; set; }
}
}
22 changes: 22 additions & 0 deletions src/GeoCop.Api/Contracts/DeliveryRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;

namespace GeoCop.Api.Contracts
{
/// <summary>
/// Request for transforming a validation to a delivery.
/// </summary>
public class DeliveryRequest
{
/// <summary>
/// The job identification provided by the validation endpoint.
/// </summary>
[Required]
public Guid JobId { get; set; }

/// <summary>
/// The id of a DeliveryMandate selected by the user to reference.
/// </summary>
[Required]
public int DeliveryMandateId { get; set; }
}
}
83 changes: 83 additions & 0 deletions src/GeoCop.Api/Controllers/DeliveryController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System.Globalization;
using GeoCop.Api.Contracts;
using GeoCop.Api.Models;
using GeoCop.Api.Validation;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace GeoCop.Api.Controllers
{
/// <summary>
/// Controller for declaring deliveries.
/// </summary>
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
public class DeliveryController : ControllerBase
{
private readonly ILogger<DeliveryController> logger;
private readonly Context context;
private readonly IValidationService validatorService;

/// <summary>
/// Initializes a new instance of the <see cref="DeliveryController"/> class.
/// </summary>
public DeliveryController(ILogger<DeliveryController> logger, Context context, IValidationService validatorService)
{
this.logger = logger;
this.context = context;
this.validatorService = validatorService;
}

/// <summary>
/// Create a delivery from a validation with the status <see cref="Status.Completed"/>.
/// </summary>
/// <param name="declaration"><see cref="DeliveryRequest"/> containing all information for the declaration process.</param>
/// <returns>Created <see cref="Delivery"/>.</returns>
[HttpPost]
public IActionResult Create(DeliveryRequest declaration)
{
logger.LogTrace("Declaration for job <{JobId}> requested.", declaration.JobId);

var job = validatorService.GetJobStatus(declaration.JobId);
if (job == default)
{
logger.LogTrace("No job information available for job id <{JobId}>.", declaration.JobId);
return Problem($"No job information available for job id <{declaration.JobId}>", statusCode: StatusCodes.Status404NotFound);
}
else if (job.Status != Status.Completed)
{
logger.LogTrace("Job <{JobId}> is not completed.", declaration.JobId);
return Problem($"Job <{declaration.JobId}> is not completed.", statusCode: StatusCodes.Status400BadRequest);
}

var mandate = context.DeliveryMandates
.Include(m => m.Organisations)
.ThenInclude(o => o.Users)
.FirstOrDefault(m => m.Id == declaration.DeliveryMandateId);

var dummyUser = mandate?.Organisations.SelectMany(u => u.Users).First() ?? new User();

if (mandate is null || !mandate.Organisations.SelectMany(u => u.Users).Any(u => u.AuthIdentifier.Equals(dummyUser.AuthIdentifier, StringComparison.OrdinalIgnoreCase)))
{
logger.LogTrace("User <{AuthIdentifier}> is not authorized to create a delivery for mandate <{MandateId}>.", dummyUser, declaration.DeliveryMandateId);
return Problem("Mandate with id <{declaration.DeliveryMandateId}> not found or user is not authorized.", statusCode: StatusCodes.Status404NotFound);
}

var delivery = new Delivery
{
DeliveryMandate = mandate,
DeclaringUser = dummyUser,
Assets = new List<Asset>(),
};

var entityEntry = context.Deliveries.Add(delivery);
context.SaveChanges();

var location = new Uri(
string.Format(CultureInfo.InvariantCulture, "/api/v1/delivery/{0}", entityEntry.Entity.Id),
UriKind.Relative);

return Created(location, entityEntry.Entity);
}
}
}
2 changes: 1 addition & 1 deletion src/GeoCop.Api/Models/Delivery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class Delivery
/// <summary>
/// The date the delivery was declared.
/// </summary>
public DateTime Date { get; set; } = DateTime.Now;
public DateTime Date { get; set; } = DateTime.UtcNow;

/// <summary>
/// The user that declared the delivery.
Expand Down
32 changes: 29 additions & 3 deletions src/GeoCop.Frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0ee35b9

Please sign in to comment.