Skip to content

Commit

Permalink
(WIP): start of payment work
Browse files Browse the repository at this point in the history
  • Loading branch information
carlsixsmith-moj committed Jan 29, 2025
1 parent bbcfc20 commit 8c182c7
Show file tree
Hide file tree
Showing 18 changed files with 5,573 additions and 25 deletions.
2 changes: 2 additions & 0 deletions src/Application/Common/Interfaces/IApplicationDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,6 @@ public interface IApplicationDbContext
DbSet<DateDimension> DateDimensions { get; }

DbSet<PriCode> PriCodes { get; }

DbSet<SupportAndReferralPayment> SupportAndReferralPayments { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Cfo.Cats.Application.Features.PRIs.IntegrationEvents;
using MassTransit;

namespace Cfo.Cats.Application.Features.ManagementInformation.IntegrationEventHandlers;

public class RecordPreReleaseSupportPayment(IUnitOfWork unitOfWork) : IConsumer<PRIAssignedIntegrationEvent>
{
private static class IneligibilityReasons
{
public const string AlreadyPaid = "A wing induction has already been claimed under this contract";
public const string NotYetApproved = "The enrolment for this participant has not yet been approved";
public const string BeforeConsent = "This occurred before the consent date";
}

public async Task Consume(ConsumeContext<PRIAssignedIntegrationEvent> context)
{
var db = unitOfWork.DbContext;

var query = from pri in db.PRIs
join u in db.Users on pri.CreatedBy equals u.Id
where pri.Id == context.Message.PRIId
select new
{
pri.Id,
pri.ParticipantId
};

await Task.CompletedTask;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ namespace Cfo.Cats.Application.Features.ManagementInformation.IntegrationEventHa

public class RecordWingInductionPaymentConsumer(IUnitOfWork unitOfWork) : IConsumer<WingInductionCreatedIntegrationEvent>
{

private static class IneligibilityReasons
{
public const string AlreadyPaid = "A wing induction has already been claimed under this contract";
Expand Down
7 changes: 6 additions & 1 deletion src/Application/Features/PRIs/Commands/AddPRI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Handler(IUnitOfWork unitOfWork, ICurrentUserService currentUserService) :
public async Task<Result> Handle(Command request, CancellationToken cancellationToken)
{
var pri = PRI
.Create(request.ParticipantId, DateOnly.FromDateTime(request.Release.ExpectedOn!.Value), request.Release.ExpectedRegion!.Id)
.Create(request.ParticipantId, DateOnly.FromDateTime(request.Release.ExpectedOn!.Value), request.Release.ExpectedRegion!.Id, request.Release.CustodyLocation!.Id)
.WithMeeting(DateOnly.FromDateTime(request.Meeting.AttendedOn!.Value),
reasonCustodyDidNotAttendInPerson: request.Meeting.ReasonCustodyDidNotAttendInPerson,
reasonCommunityDidNotAttendInPerson: request.Meeting.ReasonCommunityDidNotAttendInPerson,
Expand Down Expand Up @@ -113,13 +113,18 @@ async Task<bool> BeValid(string participantId, int code, CancellationToken cance

public class PriReleaseDto
{
public LocationDto? CustodyLocation { get; set; }
public LocationDto? ExpectedRegion { get; set; }
public DateTime? ExpectedOn { get; set; }

public class Validator : AbstractValidator<PriReleaseDto>
{
public Validator()
{
RuleFor(c => c.CustodyLocation)
.NotNull()
.WithMessage("You must choose a discharge location");

RuleFor(c => c.ExpectedRegion)
.NotNull()
.WithMessage("You must choose an expected release region");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Cfo.Cats.Application.Features.PRIs.IntegrationEvents;
using Cfo.Cats.Application.Outbox;
using Cfo.Cats.Domain.Events;

namespace Cfo.Cats.Application.Features.PRIs.EventHandlers;

public class RaisePRIAssignedIntegrationEvent(IUnitOfWork unitOfWork) : INotificationHandler<PRIAssignedDomainEvent>
{
public async Task Handle(PRIAssignedDomainEvent notification, CancellationToken cancellationToken)
{
var @event = new PRIAssignedIntegrationEvent(notification.Item.Id, notification.DateOccurred.DateTime);
await unitOfWork.DbContext.InsertOutboxMessage(@event);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Cfo.Cats.Application.Features.PRIs.IntegrationEvents;

public record PRIAssignedIntegrationEvent(Guid PRIId, DateTime OccurredOn);
135 changes: 135 additions & 0 deletions src/Domain/Entities/ManagementInformation/SupportAndReferralPayment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using Cfo.Cats.Domain.Common.Enums;

namespace Cfo.Cats.Domain.Entities.ManagementInformation;

public class SupportAndReferralPayment
{
#pragma warning disable CS8618
internal SupportAndReferralPayment()
{
}

#pragma warning restore CS8618

public Guid Id { get; set; } = Guid.CreateVersion7();

public Guid PriId { get; set; }

public string SupportType { get; set; }

public DateTime CreatedOn { get; set; } = DateTime.UtcNow;

public DateTime Approved { get; set; }

public string ParticipantId { get; set; }

public string SupportWorker { get; set; }

public string ContractId { get; set; }

public int LocationId { get; set; }

public string LocationType { get; set; }

public string TenantId { get; set; }

public bool EligibleForPayment { get; set; }

public string? IneligibilityReason { get; set; }

}

public class SupportAndReferralBuilder
{
private Guid? _priId;
private string? _supportType;
private string? _participantId;
private string? _contractId;
private DateTime? _approved;
private int? _locationId;
private string? _locationType;
private string? _tenantId;
private bool? _eligibleForPayment;
private string? _ineligibilityReason;

public SupportAndReferralBuilder WithPri(Guid priId)
{
_priId = priId;
return this;
}

public SupportAndReferralBuilder WithSupportType(string supportType)
{
_supportType = supportType;
return this;
}

public SupportAndReferralBuilder WithParticipantId(string participantId)
{
_participantId = participantId;
return this;
}

public SupportAndReferralBuilder WithContractId(string contractId)
{
_contractId = contractId;
return this;
}

public SupportAndReferralBuilder WithApproved(DateTime approved)
{
_approved = approved;
return this;
}

public SupportAndReferralBuilder WithLocationId(int locationId)
{
_locationId = locationId;
return this;
}

public SupportAndReferralBuilder WithLocationType(string locationType)
{
_locationType = locationType;
return this;
}

public SupportAndReferralBuilder WithTenantId(string tenantId)
{
_tenantId = tenantId;
return this;
}

public SupportAndReferralBuilder WithEligibleForPayment(bool eligibleForPayment)
{
_eligibleForPayment = eligibleForPayment;
return this;
}

public SupportAndReferralBuilder WithIneligibilityReason(string? ineligibilityReason)
{
_ineligibilityReason = ineligibilityReason;
return this;
}

public SupportAndReferralPayment Build()
{
var payment = new SupportAndReferralPayment()
{
PriId = _priId ?? throw new ApplicationException("PriId must be set before calling build"),
Approved = _approved ?? throw new ApplicationException("Approved must be set before calling build"),
SupportType = _supportType ?? throw new ApplicationException("SupportType must be set before calling build"),
ContractId = _contractId ?? throw new ApplicationException("ContractId must be set before calling build"),
EligibleForPayment = _eligibleForPayment ?? throw new ApplicationException("EligibleForPayment must be set before calling build"),
IneligibilityReason = _eligibleForPayment == false && _ineligibilityReason == null
? throw new ApplicationException("IneligibilityReason must be set before calling build")
: _ineligibilityReason,
LocationId = _locationId ?? throw new ApplicationException("LocationId must be set before calling build"),
LocationType = _locationType ?? throw new ApplicationException("LocationType must be set before calling build"),
ParticipantId = _participantId ?? throw new ApplicationException("ParticipantId must be set before calling build"),
TenantId = _tenantId ?? throw new ApplicationException("TenantId must be set before calling build"),
};
return payment;
}

}
10 changes: 8 additions & 2 deletions src/Domain/Entities/PRIs/PRI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,18 @@ private PRI()
public string? ReasonParticipantDidNotAttendInPerson { get; private set; }
public virtual Participant? Participant { get; private set; }

public static PRI Create(string participantId, DateOnly expectedReleaseDate, int expectedReleaseRegionId)
public int CustodyLocationId { get; private set; }

public virtual Location CustodyLocation { get; private set; }

public static PRI Create(string participantId, DateOnly expectedReleaseDate, int expectedReleaseRegionId, int custodyLocationId)
{
var pri = new PRI()
{
ParticipantId = participantId,
ExpectedReleaseDate = expectedReleaseDate,
ExpectedReleaseRegionId = expectedReleaseRegionId
ExpectedReleaseRegionId = expectedReleaseRegionId,
CustodyLocationId = custodyLocationId
};

pri.AddDomainEvent(new PRICreatedDomainEvent(pri));
Expand All @@ -47,6 +52,7 @@ public static PRI Create(string participantId, DateOnly expectedReleaseDate, int
public PRI AssignTo(string? to)
{
AssignedTo = to;
AcceptedOn = DateTime.UtcNow;
AddDomainEvent(new PRIAssignedDomainEvent(this, to));
return this;
}
Expand Down
1 change: 1 addition & 0 deletions src/Domain/Events/PRIEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public sealed class PRIAssignedDomainEvent(PRI pri, string? to) : DomainEvent
{
public PRI Item { get; set; } = pri;
public string? To { get; set; } = to;

}
2 changes: 2 additions & 0 deletions src/Infrastructure/Persistence/ApplicationDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)

public DbSet<DateDimension> DateDimensions => Set<DateDimension>();

public DbSet<SupportAndReferralPayment> SupportAndReferralPayments => Set<SupportAndReferralPayment>();

protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Cfo.Cats.Domain.Entities.ManagementInformation;
using Cfo.Cats.Infrastructure.Constants.Database;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Cfo.Cats.Infrastructure.Persistence.Configurations.ManagementInformation;

public class SupportAndReferralPaymentEntityTypeConfiguration
: IEntityTypeConfiguration<SupportAndReferralPayment>
{
public void Configure(EntityTypeBuilder<SupportAndReferralPayment> builder)
{
builder.ToTable(nameof(SupportAndReferralPayment), DatabaseConstants.Schemas.Mi);

builder.HasKey(x => x.Id);

builder.Property(x => x.PriId)
.IsRequired();

builder.Property(x => x.SupportType)
.IsRequired()
.HasMaxLength(20);

builder.Property(x => x.CreatedOn)
.IsRequired();

builder.Property(x => x.Approved)
.IsRequired()
.HasColumnType("date");

builder.Property(x => x.ContractId)
.IsRequired()
.HasMaxLength(12);

builder.Property(x => x.LocationType)
.IsRequired()
.HasMaxLength(25);

builder.Property(x => x.TenantId)
.IsRequired()
.HasMaxLength(DatabaseConstants.FieldLengths.TenantId);

builder.Property(x => x.EligibleForPayment)
.IsRequired();

builder.Property(x => x.IneligibilityReason)
.HasMaxLength(250);

builder.Property(x => x.ParticipantId)
.IsRequired()
.HasMaxLength(DatabaseConstants.FieldLengths.ParticipantId);

builder.HasIndex(x => new {
x.ParticipantId,
x.ContractId,
x.SupportType,
x.Approved
})
.HasDatabaseName("ix_ActivityPayment_ParticipantId");

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,19 @@ public void Configure(EntityTypeBuilder<PRI> builder)
.HasForeignKey(p => p.ExpectedReleaseRegionId)
.OnDelete(DeleteBehavior.Restrict);

builder.HasOne(p => p.CustodyLocation)
.WithMany()
.HasForeignKey(p => p.CustodyLocationId)
.OnDelete(DeleteBehavior.Restrict);

builder.HasOne<ApplicationUser>()
.WithMany()
.HasForeignKey(p => p.AssignedTo)
.OnDelete(DeleteBehavior.Restrict);

builder.Property(x => x.AssignedTo)
.HasMaxLength(36);

builder.Property(x => x.ReasonCommunityDidNotAttendInPerson).HasMaxLength(ValidationConstants.NotesLength);
builder.Property(x => x.ReasonCustodyDidNotAttendInPerson).HasMaxLength(ValidationConstants.NotesLength);
builder.Property(x => x.ReasonParticipantDidNotAttendInPerson).HasMaxLength(ValidationConstants.NotesLength);
Expand Down
Loading

0 comments on commit 8c182c7

Please sign in to comment.