-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added agreeemnts for projects with file upload (#535)
Co-authored-by: md <[email protected]>
- Loading branch information
Showing
23 changed files
with
2,049 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
using Api.Common; | ||
using Api.StaffingController; | ||
using Core.Agreements; | ||
using Core.Consultants; | ||
using Core.DomainModels; | ||
using Core.Organizations; | ||
using Core.Staffings; | ||
using Infrastructure.DatabaseContext; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.EntityFrameworkCore; | ||
using Microsoft.Extensions.Caching.Memory; | ||
|
||
namespace Api.Projects; | ||
|
||
[Authorize] | ||
[Route("/v0/{orgUrlKey}/agreements")] | ||
[ApiController] | ||
public class AgreementController( | ||
ApplicationContext context, | ||
IMemoryCache cache, | ||
IOrganisationRepository organisationRepository, | ||
IAgreementsRepository agreementsRepository) : ControllerBase | ||
{ | ||
|
||
[HttpGet] | ||
[Route("get/{agreementId}")] | ||
public async Task<ActionResult<AgreementReadModel>> GetAgreement([FromRoute] string orgUrlKey, | ||
[FromRoute] int agreementId, CancellationToken ct) | ||
{ | ||
var selectedOrg = await organisationRepository.GetOrganizationByUrlKey(orgUrlKey, ct); | ||
if (selectedOrg is null) return BadRequest("Selected org not found"); | ||
|
||
var agreement = await agreementsRepository.GetAgreementById(agreementId, ct); | ||
|
||
if (agreement is null) return NotFound(); | ||
|
||
var responseModel = new AgreementReadModel( | ||
AgreementId: agreement.Id, | ||
EngagementId: agreement.EngagementId, | ||
StartDate: agreement.StartDate, | ||
EndDate: agreement.EndDate, | ||
NextPriceAdjustmentDate: agreement.NextPriceAdjustmentDate, | ||
PriceAdjustmentIndex: agreement.PriceAdjustmentIndex, | ||
Notes: agreement.Notes, | ||
Files: agreement.Files.Select(f => new FileReferenceReadModel( | ||
FileName: f.FileName, | ||
BlobName: f.BlobName, | ||
UploadedOn: f.UploadedOn | ||
)).ToList() | ||
); | ||
return Ok(responseModel); | ||
} | ||
|
||
[HttpGet] | ||
[Route("get/engagement/{engagementId}")] | ||
public async Task<ActionResult<AgreementReadModel>> GetAgreementByEngagement([FromRoute] string orgUrlKey, | ||
[FromRoute] int engagementId, CancellationToken ct) | ||
{ | ||
var selectedOrg = await organisationRepository.GetOrganizationByUrlKey(orgUrlKey, ct); | ||
if (selectedOrg is null) return BadRequest("Selected org not found"); | ||
|
||
var agreement = await agreementsRepository.GetAgreementByEngagementId(engagementId, ct); | ||
|
||
if (agreement is null) return NotFound(); | ||
|
||
var responseModel = new AgreementReadModel( | ||
AgreementId: agreement.Id, | ||
EngagementId: agreement.EngagementId, | ||
StartDate: agreement.StartDate, | ||
EndDate: agreement.EndDate, | ||
NextPriceAdjustmentDate: agreement.NextPriceAdjustmentDate, | ||
PriceAdjustmentIndex: agreement.PriceAdjustmentIndex, | ||
Notes: agreement.Notes, | ||
Files: agreement.Files.Select(f => new FileReferenceReadModel( | ||
FileName: f.FileName, | ||
BlobName: f.BlobName, | ||
UploadedOn: f.UploadedOn | ||
)).ToList() | ||
); | ||
return Ok(responseModel); | ||
} | ||
|
||
[HttpPost] | ||
[Route("create")] | ||
public async Task<ActionResult<AgreementWriteModel>> Post([FromRoute] string orgUrlKey, | ||
[FromBody] AgreementWriteModel body, CancellationToken ct) | ||
{ | ||
|
||
Console.WriteLine(body); | ||
|
||
var selectedOrg = await organisationRepository.GetOrganizationByUrlKey(orgUrlKey, ct); | ||
if (selectedOrg is null) return BadRequest("Selected org not found"); | ||
|
||
var engagement = await context.Project.FindAsync(body.EngagementId); | ||
if (engagement is null) return BadRequest("Engagement not found"); | ||
|
||
var agreement = new Agreement | ||
{ | ||
EngagementId = body.EngagementId, | ||
Engagement = engagement, | ||
StartDate = body.StartDate, | ||
EndDate = body.EndDate, | ||
NextPriceAdjustmentDate = body.NextPriceAdjustmentDate, | ||
PriceAdjustmentIndex = body.PriceAdjustmentIndex, | ||
Notes = body.Notes, | ||
Files = body.Files.Select(f => new FileReference | ||
{ | ||
FileName = f.FileName, | ||
BlobName = f.BlobName, | ||
UploadedOn = f.UploadedOn | ||
}).ToList() | ||
}; | ||
|
||
await agreementsRepository.AddAgreementAsync(agreement, ct); | ||
|
||
var responseModel = new AgreementReadModel( | ||
AgreementId: agreement.Id, | ||
EngagementId: agreement.EngagementId, | ||
StartDate: agreement.StartDate, | ||
EndDate: agreement.EndDate, | ||
NextPriceAdjustmentDate: agreement.NextPriceAdjustmentDate, | ||
PriceAdjustmentIndex: agreement.PriceAdjustmentIndex, | ||
Notes: agreement.Notes, | ||
Files: agreement.Files.Select(f => new FileReferenceReadModel( | ||
FileName: f.FileName, | ||
BlobName: f.BlobName, | ||
UploadedOn: f.UploadedOn | ||
)).ToList() | ||
); | ||
|
||
return Ok(responseModel); | ||
} | ||
|
||
[HttpPut] | ||
[Route("update/{agreementId}")] | ||
public async Task<ActionResult<AgreementReadModel>> Put([FromRoute] string orgUrlKey, | ||
[FromRoute] int agreementId, [FromBody] AgreementWriteModel body, CancellationToken ct) | ||
{ | ||
var selectedOrg = await organisationRepository.GetOrganizationByUrlKey(orgUrlKey, ct); | ||
if (selectedOrg is null) return BadRequest("Selected org not found"); | ||
|
||
var agreement = await agreementsRepository.GetAgreementById(agreementId, ct); | ||
if (agreement is null) return NotFound(); | ||
|
||
agreement.EngagementId = body.EngagementId; | ||
agreement.StartDate = body.StartDate; | ||
agreement.EndDate = body.EndDate; | ||
agreement.NextPriceAdjustmentDate = body.NextPriceAdjustmentDate; | ||
agreement.PriceAdjustmentIndex = body.PriceAdjustmentIndex; | ||
agreement.Notes = body.Notes; | ||
agreement.Files = body.Files.Select(f => new FileReference | ||
{ | ||
FileName = f.FileName, | ||
BlobName = f.BlobName, | ||
UploadedOn = f.UploadedOn | ||
}).ToList(); | ||
|
||
await agreementsRepository.UpdateAgreementAsync(agreement, ct); | ||
|
||
var responseModel = new AgreementReadModel( | ||
AgreementId: agreement.Id, | ||
EngagementId: agreement.EngagementId, | ||
StartDate: agreement.StartDate, | ||
EndDate: agreement.EndDate, | ||
NextPriceAdjustmentDate: agreement.NextPriceAdjustmentDate, | ||
PriceAdjustmentIndex: agreement.PriceAdjustmentIndex, | ||
Notes: agreement.Notes, | ||
Files: agreement.Files.Select(f => new FileReferenceReadModel( | ||
FileName: f.FileName, | ||
BlobName: f.BlobName, | ||
UploadedOn: f.UploadedOn | ||
)).ToList() | ||
); | ||
|
||
return Ok(responseModel); | ||
} | ||
|
||
[HttpDelete] | ||
[Route("delete/{agreementId}")] | ||
public async Task<ActionResult> Delete([FromRoute] string orgUrlKey, [FromRoute] int agreementId, CancellationToken ct) | ||
{ | ||
var selectedOrg = await organisationRepository.GetOrganizationByUrlKey(orgUrlKey, ct); | ||
if (selectedOrg is null) return BadRequest("Selected org not found"); | ||
|
||
var agreement = await agreementsRepository.GetAgreementById(agreementId, ct); | ||
if (agreement is null) return NotFound(); | ||
|
||
await agreementsRepository.DeleteAgreementAsync(agreementId, ct); | ||
|
||
return Ok(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.ComponentModel.DataAnnotations; | ||
|
||
public record AgreementReadModel( | ||
int AgreementId, | ||
int EngagementId, | ||
DateTime? StartDate, | ||
DateTime EndDate, | ||
DateTime? NextPriceAdjustmentDate, | ||
string? PriceAdjustmentIndex, | ||
string? Notes, | ||
List<FileReferenceReadModel> Files | ||
); | ||
|
||
public record FileReferenceReadModel( | ||
string FileName, | ||
string BlobName, | ||
DateTime UploadedOn | ||
); | ||
|
||
public record AgreementWriteModel( | ||
int EngagementId, | ||
DateTime? StartDate, | ||
DateTime EndDate, | ||
DateTime? NextPriceAdjustmentDate, | ||
string? PriceAdjustmentIndex, | ||
string? Notes, | ||
List<FileReferenceWriteModel> Files | ||
); | ||
|
||
public record FileReferenceWriteModel( | ||
string FileName, | ||
string BlobName, | ||
DateTime UploadedOn | ||
); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using System.ComponentModel.DataAnnotations.Schema; | ||
using Core.Engagements; | ||
|
||
namespace Core.Agreements | ||
{ | ||
public class Agreement | ||
{ | ||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] | ||
public int Id { get; set; } | ||
|
||
public int EngagementId { get; set; } | ||
|
||
public required Engagement Engagement { get; set; } | ||
|
||
public ICollection<FileReference> Files { get; set; } = new List<FileReference>(); | ||
|
||
public DateTime? StartDate { get; set; } | ||
|
||
public required DateTime EndDate { get; set; } | ||
|
||
public DateTime? NextPriceAdjustmentDate { get; set; } | ||
|
||
public string? PriceAdjustmentIndex { get; set; } | ||
|
||
public string? Notes { get; set; } = string.Empty; | ||
} | ||
|
||
public class FileReference | ||
{ | ||
public string FileName { get; set; } = string.Empty; | ||
public string BlobName { get; set; } = string.Empty; // URI to the blob storage | ||
public DateTime UploadedOn { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
namespace Core.Agreements; | ||
|
||
public interface IAgreementsRepository | ||
{ | ||
public Task<Agreement?> GetAgreementById(int id, CancellationToken cancellationToken); | ||
|
||
public Task<Agreement?> GetAgreementByEngagementId(int engagementId, CancellationToken cancellationToken); | ||
|
||
public Task AddAgreementAsync(Agreement agreement, CancellationToken cancellationToken); | ||
|
||
public Task UpdateAgreementAsync(Agreement agreement, CancellationToken cancellationToken); | ||
|
||
public Task DeleteAgreementAsync(int id, CancellationToken cancellationToken); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.