Skip to content

Commit

Permalink
Merge pull request #7 from lucasdaquina/feat/create-new-medication
Browse files Browse the repository at this point in the history
Feat/create new medication
  • Loading branch information
lucasdaquina authored Jul 26, 2024
2 parents add4a5c + 6850814 commit 1ad01de
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 9 deletions.
45 changes: 40 additions & 5 deletions src/SM.Medication.Api/EndPoints/MedicationEndPoints.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
using System.Runtime.Versioning;
using SM.Medication.Api.Extensions;
using SM.Medication.Application.Commands;

namespace SM.Medication.Api.EndPoints;

public static class MedicationEndPoints
Expand All @@ -9,12 +13,43 @@ public static void MapMedicationEndPoints(this WebApplication app)
async (IMedicationHandler handler) =>
{
return await handler.Handle();
})
.WithTags(MEDICATION_TAG)
.WithMetadata(new SwaggerOperationAttribute(MEDICATION_TAG, "Get List of Medications"))
.WithMetadata(new SwaggerResponseAttribute(StatusCodes.Status200OK, "Success!"))
}).AddMetadata("Get List of Medications");


app.MapPost("/medications",
async (IMedicationHandler handler, CreateMedicationCommand request) =>
{
try
{
request.Name.GuardString(nameof(request.Name));

var result = await handler.Handle(request);
if (!result)
return Results.Problem(
"Failed to create Medication",
statusCode: StatusCodes.Status500InternalServerError);

return Results.Created();
}
catch (Exception e)
{
//Log specific exception
return Results.Problem(
e.Message,
statusCode: StatusCodes.Status500InternalServerError);
}
}).AddMetadata("Create Medication");

}

public static RouteHandlerBuilder AddMetadata(this RouteHandlerBuilder builder, string description)
{
return builder.WithTags(MEDICATION_TAG)
.WithMetadata(new SwaggerOperationAttribute(MEDICATION_TAG, description))
.WithMetadata(new SwaggerResponseAttribute(StatusCodes.Status201Created, "Created!"))
.WithMetadata(new SwaggerResponseAttribute(StatusCodes.Status400BadRequest, "Bad Request!"))
.WithMetadata(new SwaggerResponseAttribute(StatusCodes.Status401Unauthorized, "You're not Authorized!"))
.WithMetadata(new SwaggerResponseAttribute(StatusCodes.Status500InternalServerError, "Failed!"))
.RequireAuthorization(); ;
.RequireAuthorization();
}
}
17 changes: 17 additions & 0 deletions src/SM.Medication.Api/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Azure.Core;

namespace SM.Medication.Api.Extensions;

public static class StringExtensions
{
public static void GuardString(this string? value, string nameOf)
{
ArgumentNullException.ThrowIfNull(value, nameOf);

if(string.IsNullOrEmpty(value))
throw new Exception($"{nameOf} cannot be null or empty");

if(string.IsNullOrWhiteSpace(value))
throw new Exception($"{nameOf} cannot be empty or whitespace");
}
}
14 changes: 14 additions & 0 deletions src/SM.Medication.Application/Commands/CreateMedicationCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace SM.Medication.Application.Commands;

public class CreateMedicationCommand
{
[Required]
public string? Name { get; set; }
[Required]
[DefaultValue(1)]
[Range(1, int.MaxValue)]
public int Quantity { get; set; }
}
22 changes: 22 additions & 0 deletions src/SM.Medication.Application/Handlers/MedicationHandler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Mapster;
using MapsterMapper;
using SM.Medication.Application.Commands;
using SM.Medication.Application.Interfaces;
using SM.Medication.Domain.Interfaces;

Expand All @@ -13,4 +15,24 @@ public async Task<List<MedicationDTO>> Handle()
var medications = await medicationRepository.GetAll();
return mapper.Map<List<MedicationDTO>>(medications);
}

public async Task<bool> Handle(CreateMedicationCommand command)
{
TypeAdapterConfig<CreateMedicationCommand, Domain.Entities.Medication>
.NewConfig()
.Map(dest => dest.CreatedBy, src => Environment.UserName)
.Map(dest => dest.CreatedAt, src => DateTime.UtcNow)
.Map(dest => dest.ModifiedBy, src => Environment.UserName)
.Map(dest => dest.ModifiedAt, src => DateTime.UtcNow);

//var entity = new Domain.Entities.Medication();
var entity = mapper.Map<Domain.Entities.Medication>(command);

var isMedicationExist = (await medicationRepository.GetByName(entity.Name!)) is null;

if (!isMedicationExist)
throw new Exception("Medication already exist.");

return await medicationRepository.Add(entity);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using SM.Medication.Application.Commands;

namespace SM.Medication.Application.Interfaces;
public interface IMedicationHandler
{
Task<List<MedicationDTO>> Handle();
Task<bool> Handle(CreateMedicationCommand command);
}
45 changes: 41 additions & 4 deletions src/SM.Medication.Domain/Common/AuditableEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,45 @@ namespace SM.Medication.Domain.Common;

public class AuditableEntity
{
public string? CreatedBy { get; set; }
public string? ModifiedBy { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime ModifiedAt { get; set; }
private string? _createdBy;
private string? _modifiedBy;
private DateTime _createdAt;
private DateTime _modifiedAt;

public string? CreatedBy
{
get { return _createdBy; }
set
{
if (string.IsNullOrEmpty(_createdBy))
_createdBy = Environment.UserName;
}
}
public string? ModifiedBy
{
get { return _modifiedBy; }
set
{
_modifiedBy = Environment.UserName;
}
}
public DateTime CreatedAt
{
get { return _createdAt; }
set
{
if (_createdAt == DateTime.MinValue)
_createdAt = DateTime.UtcNow;
}
}

public DateTime ModifiedAt
{
get { return _modifiedAt; }
set
{
if (_modifiedAt == DateTime.MinValue)
_modifiedAt = DateTime.UtcNow;
}
}
}
3 changes: 3 additions & 0 deletions src/SM.Medication.Domain/Interfaces/IMedicationRepository.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@

namespace SM.Medication.Domain.Interfaces;

public interface IMedicationRepository
{
Task<bool> Add(Entities.Medication entity);
Task<List<Domain.Entities.Medication>> GetAll();
Task<Domain.Entities.Medication?> GetByName(string name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,26 @@ namespace SM.Medication.Infrastructure.Services.Repositories;

public class MedicationRepository(SmartMedMedicationDbContext context) : IMedicationRepository
{
public async Task<bool> Add(Domain.Entities.Medication entity)
{
context.Medications.Add(entity);

var result = await context.SaveChangesAsync();

return result > 0;
}

public async Task<List<Domain.Entities.Medication>> GetAll()
{
return await context
.Medications
.ToListAsync();
}

public async Task<Domain.Entities.Medication?> GetByName(string name)
{
return await context
.Medications
.FirstOrDefaultAsync(med => string.Equals(med.Name!.ToUpper(), name.ToUpper()));
}
}

0 comments on commit 1ad01de

Please sign in to comment.