-
Notifications
You must be signed in to change notification settings - Fork 1
Purchase request resource files #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,3 +50,4 @@ Thumbs.db | |
| .idea/ | ||
| *.swp | ||
| *.swo | ||
| client_secret.json | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| using Microsoft.AspNetCore.Mvc; | ||
| using TRFSAE.MemberPortal.API.DTOs; | ||
| using TRFSAE.MemberPortal.API.Interfaces; | ||
| using Supabase; | ||
|
|
||
| namespace TRFSAE.MemberPortal.API.Controllers | ||
| { | ||
| [ApiController] | ||
| [Route("api/purchase-request")] | ||
| public class PurchaseRequestController : ControllerBase | ||
| { | ||
| private readonly IPurchaseRequestService _purchaseRequestService; | ||
|
|
||
| public PurchaseRequestController(IPurchaseRequestService purchaseRequestService) | ||
| { | ||
| _purchaseRequestService = purchaseRequestService; | ||
| } | ||
|
|
||
| [HttpGet] | ||
| public async Task<IActionResult> GetAllPurchaseAsync([FromQuery] PurchaseRequestSearchDto? dto) | ||
| { | ||
| var result = await _purchaseRequestService.GetAllPurchaseRequestsAsync(dto ?? new PurchaseRequestSearchDto()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we making a new DTO here? There should only exist 1 instance of a DTO as it's a singleton. |
||
| return Ok(result); | ||
| } | ||
|
|
||
| [HttpGet("{id:guid}", Name = "GetPurchaseRequestById")] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
| public async Task<IActionResult> GetPurchaseRequestByIDAsync(Guid id) | ||
| { | ||
| var item = await _purchaseRequestService.GetPurchaseRequestByIDAsync(id); | ||
| return item is null ? NotFound() : Ok(item); | ||
| } | ||
|
|
||
| [HttpPost] | ||
| public async Task<IActionResult> CreatePurchaseRequestAsync(PurchaseRequestCreateDto dto) | ||
| { | ||
| var created = await _purchaseRequestService.CreatePurchaseRequestAsync(dto); | ||
| return CreatedAtRoute("GetPurchaseRequestById", new { id = created.Id }, created); | ||
| } | ||
|
|
||
| [HttpPut("{id:guid}")] | ||
| public async Task<IActionResult> UpdatePurchaseRequestByIDAsync(Guid id, PurchaseRequestUpdateDto dto) | ||
| { | ||
| var updated = await _purchaseRequestService.UpdatePurchaseRequestByIDAsync(id, dto); | ||
| return updated is null ? NotFound() : Ok(updated); | ||
| } | ||
|
|
||
| [HttpDelete("{id:guid}")] | ||
| public async Task<IActionResult> DeletePurchaseRequestAsync(Guid id, string confirmationString) | ||
| { | ||
| var deleted = await _purchaseRequestService.DeletePurchaseRequestAsync(id, confirmationString); | ||
| return deleted ? NoContent() : NotFound(); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| namespace TRFSAE.MemberPortal.API.DTOs | ||
| { | ||
| public class PurchaseRequestCreateDto | ||
| { | ||
| public string Status { get; set; } = string.Empty; | ||
| public Guid Requester { get; set; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| using System.Text.Json.Serialization; | ||
|
|
||
| namespace TRFSAE.MemberPortal.API.DTOs | ||
| { | ||
| public class PurchaseRequestResponseDto | ||
| { | ||
| [JsonPropertyName("id")] | ||
| public Guid Id { get; set; } | ||
|
|
||
| [JsonPropertyName("status")] | ||
| public string Status { get; set; } = string.Empty; | ||
|
|
||
| [JsonPropertyName("requester")] | ||
| public Guid? Requester { get; set; } | ||
|
|
||
| [JsonPropertyName("created_at")] | ||
| public DateTimeOffset CreatedAt { get; set; } | ||
|
|
||
| [JsonPropertyName("updated_at")] | ||
| public DateTime UpdatedAt { get; set; } | ||
| } | ||
| } |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Need to be able to search by informal ID (i.e. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| namespace TRFSAE.MemberPortal.API.DTOs | ||
| { | ||
| public class PurchaseRequestSearchDto | ||
| { | ||
| public string Status { get; set; } = string.Empty; | ||
| public Guid? Requester { get; set; } | ||
| } | ||
| } |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is incomplete. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| namespace TRFSAE.MemberPortal.API.DTOs | ||
| { | ||
| public class PurchaseRequestUpdateDto | ||
| { | ||
| public string Status { get; set; } = string.Empty; | ||
| public Guid Requester { get; set; } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| using TRFSAE.MemberPortal.API.DTOs; | ||
|
|
||
| namespace TRFSAE.MemberPortal.API.Interfaces | ||
| { | ||
| public interface IPurchaseRequestService | ||
| { | ||
| Task<List<PurchaseRequestResponseDto>> GetAllPurchaseRequestsAsync(PurchaseRequestSearchDto dto); | ||
| Task<PurchaseRequestResponseDto> GetPurchaseRequestByIDAsync(Guid id); | ||
| Task<PurchaseRequestResponseDto> CreatePurchaseRequestAsync(PurchaseRequestCreateDto dto); | ||
| Task<PurchaseRequestResponseDto> UpdatePurchaseRequestByIDAsync(Guid id, PurchaseRequestUpdateDto dto); | ||
| Task<bool> DeletePurchaseRequestAsync(Guid id, string confirmationString); | ||
| } | ||
| } |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is incomplete. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| using Supabase.Postgrest.Attributes; | ||
| using Supabase.Postgrest.Models; | ||
|
|
||
| namespace TRFSAE.MemberPortal.API.Models | ||
| { | ||
| [Table("purchase_request")] | ||
| public class PurchaseRequestModel: BaseModel | ||
| { | ||
| [PrimaryKey("id", false)] | ||
| public Guid Id { get; set; } | ||
|
|
||
| [Column("status")] | ||
| public string Status { get; set; } = string.Empty; | ||
|
|
||
| [Column("requester")] | ||
| public Guid Requester { get; set; } | ||
|
|
||
| [Column("created_at")] | ||
| public DateTimeOffset CreatedAt { get; set; } | ||
|
|
||
| [Column("updated_at")] | ||
| public DateTime UpdatedAt { get; set; } | ||
| } | ||
| } |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs to handle upserts. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| using TRFSAE.MemberPortal.API.DTOs; | ||
| using TRFSAE.MemberPortal.API.Interfaces; | ||
| using TRFSAE.MemberPortal.API.Models; | ||
| using System.Text.Json; | ||
| using Supabase; | ||
|
|
||
| namespace TRFSAE.MemberPortal.API.Services | ||
| { | ||
| public class PurchaseRequestService : IPurchaseRequestService | ||
| { | ||
| private readonly Client _supabaseClient; | ||
|
|
||
| public PurchaseRequestService(Client supabaseClient) | ||
| { | ||
| _supabaseClient = supabaseClient; | ||
| } | ||
|
|
||
| private PurchaseRequestResponseDto MapToDto(PurchaseRequestModel model) | ||
| { | ||
| return new PurchaseRequestResponseDto | ||
| { | ||
| Id = model.Id, | ||
| Status = model.Status, | ||
| Requester = model.Requester, | ||
| CreatedAt = model.CreatedAt, | ||
| UpdatedAt = model.UpdatedAt | ||
| }; | ||
| } | ||
|
|
||
| private PurchaseRequestModel MapToModel(PurchaseRequestCreateDto dto) | ||
| { | ||
| return new PurchaseRequestModel | ||
| { | ||
| Status = dto.Status, | ||
| Requester = dto.Requester | ||
| }; | ||
| } | ||
|
|
||
| public async Task<List<PurchaseRequestResponseDto>> GetAllPurchaseRequestsAsync(PurchaseRequestSearchDto dto) | ||
| { | ||
| var response = await _supabaseClient | ||
| .From<PurchaseRequestModel>() | ||
| .Get(); | ||
|
|
||
| var results = response.Models.AsEnumerable(); | ||
|
|
||
| if (!string.IsNullOrWhiteSpace(dto.Status)) | ||
| { | ||
| results = results.Where(x => x.Status == dto.Status); | ||
| } | ||
|
|
||
| if (dto.Requester.HasValue && dto.Requester != Guid.Empty) | ||
| { | ||
| results = results.Where(x => x.Requester == dto.Requester); | ||
| } | ||
|
|
||
| return results.Select(MapToDto).ToList(); | ||
| } | ||
|
|
||
| public async Task<PurchaseRequestResponseDto> GetPurchaseRequestByIDAsync(Guid id) | ||
| { | ||
| var response = await _supabaseClient | ||
| .From<PurchaseRequestModel>() | ||
| .Where(x => x.Id == id) | ||
| .Single(); | ||
|
|
||
| if (response == null) | ||
| { | ||
| throw new Exception("Purchase request not found"); | ||
| } | ||
|
|
||
| return MapToDto(response); | ||
| } | ||
|
|
||
| public async Task<PurchaseRequestResponseDto> CreatePurchaseRequestAsync(PurchaseRequestCreateDto dto) | ||
| { | ||
| var newModel = MapToModel(dto); | ||
| if (newModel.Id == Guid.Empty) | ||
| newModel.Id = Guid.NewGuid(); | ||
| if (newModel.CreatedAt == default) | ||
| newModel.CreatedAt = DateTimeOffset.UtcNow; | ||
|
|
||
| var response = await _supabaseClient | ||
| .From<PurchaseRequestModel>() | ||
| .Insert(new List<PurchaseRequestModel> { newModel }); | ||
|
|
||
| if (response.Models is null || response.Models.Count == 0) | ||
| throw new Exception("Failed to create purchase request"); | ||
|
|
||
| return MapToDto(response.Models.First()); | ||
| } | ||
|
|
||
| public async Task<PurchaseRequestResponseDto> UpdatePurchaseRequestByIDAsync(Guid id, PurchaseRequestUpdateDto dto) | ||
| { | ||
| var currentRequest = await _supabaseClient | ||
| .From<PurchaseRequestModel>() | ||
| .Where(x => x.Id == id) | ||
| .Single(); | ||
|
|
||
| if (currentRequest == null) | ||
| throw new Exception("Purchase request not found"); | ||
|
|
||
| if (!string.IsNullOrWhiteSpace(dto.Status)) | ||
| currentRequest.Status = dto.Status; | ||
|
|
||
| if (dto.Requester != Guid.Empty) | ||
| currentRequest.Requester = dto.Requester; | ||
|
|
||
| currentRequest.UpdatedAt = DateTime.UtcNow; | ||
|
|
||
| var response = await _supabaseClient | ||
| .From<PurchaseRequestModel>() | ||
| .Update(currentRequest); | ||
|
|
||
| if (response.Models is null || response.Models.Count == 0) | ||
| throw new Exception("Failed to update purchase request"); | ||
|
|
||
| return MapToDto(response.Models.First()); | ||
| } | ||
|
|
||
| public async Task<bool> DeletePurchaseRequestAsync(Guid id, string confirmationString) | ||
| { | ||
| if (confirmationString != "confirm") | ||
| return false; | ||
|
|
||
| try | ||
| { | ||
| await _supabaseClient | ||
| .From<PurchaseRequestModel>() | ||
| .Where(x => x.Id == id) | ||
| .Delete(); | ||
| return true; | ||
| } | ||
| catch | ||
| { | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opt to use the
.envinstead.