Skip to content
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

Psp 8368 variable payments, gst fixes, unit tests. #4166

Merged
merged 14 commits into from
Jul 9, 2024
Merged
2 changes: 2 additions & 0 deletions source/backend/api/Controllers/LookupController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ public IActionResult GetAll()
var dispositionChecklistSectionTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllDispositionChecklistSectionTypes());
var historicalNumberTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllHistoricalNumberTypes());
var leaseChecklistSectionTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllLeaseChecklistSectionTypes());
var leasePaymentCategoryTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllLeasePaymentCategoryTypes());

var codes = new List<object>();
codes.AddRange(areaUnitTypes);
Expand Down Expand Up @@ -222,6 +223,7 @@ public IActionResult GetAll()
codes.AddRange(dispositionChecklistSectionTypes);
codes.AddRange(historicalNumberTypes);
codes.AddRange(leaseChecklistSectionTypes);
codes.AddRange(leasePaymentCategoryTypes);

var response = new JsonResult(codes);

Expand Down
32 changes: 26 additions & 6 deletions source/backend/api/Services/LeasePaymentService.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Pims.Api.Models.CodeTypes;
using Pims.Dal.Entities;
using Pims.Dal.Repositories;
using static Pims.Dal.Entities.PimsLeasePaymentStatusType;
Expand Down Expand Up @@ -52,22 +54,40 @@ public PimsLeasePayment AddPayment(long leaseId, PimsLeasePayment payment)
return updatedPayment;
}

private static string GetPaymentStatus(PimsLeasePayment payment, PimsLeasePeriod parent)
public static string GetPaymentStatus(PimsLeasePayment payment, PimsLeasePeriod parent)
{
decimal? expectedTotal = (parent.PaymentAmount ?? 0) + (parent.GstAmount ?? 0);
if (payment.PaymentAmountTotal == 0)
if (!Enum.TryParse(payment.LeasePaymentCategoryTypeCode, out LeasePaymentCategoryTypes leasePaymentCategoryType))
{
throw new InvalidOperationException();
}
decimal? expectedTotal;
switch (leasePaymentCategoryType)
{
case LeasePaymentCategoryTypes.VBL:
expectedTotal = (parent?.VblRentAgreedPmt ?? 0) + (parent?.VblRentGstAmount ?? 0);
break;
case LeasePaymentCategoryTypes.ADDL:
expectedTotal = (parent?.AddlRentAgreedPmt ?? 0) + (parent?.AddlRentGstAmount ?? 0);
break;
case LeasePaymentCategoryTypes.BASE:
expectedTotal = (parent?.PaymentAmount ?? 0) + (parent?.GstAmount ?? 0);
break;
default:
throw new InvalidOperationException();
}
if (payment?.PaymentAmountTotal == 0)
{
return PimsLeasePaymentStatusTypes.UNPAID;
}
else if (payment.PaymentAmountTotal < expectedTotal)
else if (payment?.PaymentAmountTotal < expectedTotal)
{
return PimsLeasePaymentStatusTypes.PARTIAL;
}
else if (payment.PaymentAmountTotal == expectedTotal)
else if (payment?.PaymentAmountTotal == expectedTotal)
{
return PimsLeasePaymentStatusTypes.PAID;
}
else if (payment.PaymentAmountTotal > expectedTotal)
else if (payment?.PaymentAmountTotal > expectedTotal)
{
return PimsLeasePaymentStatusTypes.OVERPAID;
}
Expand Down
4 changes: 4 additions & 0 deletions source/backend/api/Services/LeasePeriodService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ private void ValidateUpdateRules(PimsLeasePeriod period, long periodId)
{
throw new InvalidOperationException("Period must be 'exercised' if payments have been made.");
}
if(leasePeriodToUpdate.IsVariablePayment != period.IsVariablePayment)
{
throw new InvalidOperationException("Period payment variability may not be changed after period creation.");
}
}

/// <summary>
Expand Down
16 changes: 16 additions & 0 deletions source/backend/apimodels/CodeTypes/LeasePaymentCategoryTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Runtime.Serialization;
using System.Text.Json.Serialization;

namespace Pims.Api.Models.CodeTypes
{
[JsonConverter(typeof(JsonStringEnumMemberConverter))]
public enum LeasePaymentCategoryTypes
{
[EnumMember(Value = "ADDL")]
ADDL,
[EnumMember(Value = "BASE")]
BASE,
[EnumMember(Value = "VBL")]
VBL,
}
}
16 changes: 16 additions & 0 deletions source/backend/apimodels/Models/Concepts/Lease/LeasePeriodMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,20 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.IsGstEligible, src => src.IsGstEligible)
.Map(dest => dest.IsTermExercised, src => src.LeasePeriodStatusTypeCode == LeasePeriodStatusTypes.EXER)
.Map(dest => dest.GstAmount, src => src.IsGstEligible.HasValue && src.IsGstEligible.Value ? src.GstAmount : null)
.Map(dest => dest.AdditionalRentGstAmount, src => src.IsAddlRentSubjectToGst.HasValue && src.IsAddlRentSubjectToGst.Value ? src.AddlRentGstAmount : null)
.Map(dest => dest.VariableRentGstAmount, src => src.IsVblRentSubjectToGst.HasValue && src.IsVblRentSubjectToGst.Value ? src.VblRentGstAmount : null)
.Map(dest => dest.PaymentAmount, src => src.PaymentAmount)
.Map(dest => dest.PaymentNote, src => src.PaymentNote)
.Map(dest => dest.PaymentDueDateStr, src => src.PaymentDueDate)
.Map(dest => dest.Payments, src => src.PimsLeasePayments)
.Map(dest => dest.IsFlexible, src => src.IsFlexibleDuration)
.Map(dest => dest.IsVariable, src => src.IsVariablePayment)
.Map(dest => dest.AdditionalRentPaymentAmount, src => src.AddlRentAgreedPmt)
.Map(dest => dest.AdditionalRentFreqTypeCode, src => src.AddlRentFreqNavigation)
.Map(dest => dest.IsAdditionalRentGstEligible, src => src.IsAddlRentSubjectToGst)
.Map(dest => dest.VariableRentPaymentAmount, src => src.VblRentAgreedPmt)
.Map(dest => dest.VariableRentFreqTypeCode, src => src.VblRentFreqNavigation)
.Map(dest => dest.IsVariableRentGstEligible, src => src.IsVblRentSubjectToGst)
.Inherits<Entity.IBaseAppEntity, BaseAuditModel>();

config.NewConfig<LeasePeriodModel, Entity.PimsLeasePeriod>()
Expand All @@ -41,12 +49,20 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.IsGstEligible, src => src.IsGstEligible)
.Map(dest => dest.IsPeriodExercised, src => src.LeasePmtFreqTypeCode != null && src.StatusTypeCode.Id == LeasePeriodStatusTypes.EXER)
.Map(dest => dest.GstAmount, src => src.IsGstEligible ? src.GstAmount : null)
.Map(dest => dest.AddlRentGstAmount, src => src.IsAdditionalRentGstEligible == true ? src.AdditionalRentGstAmount : null)
.Map(dest => dest.VblRentGstAmount, src => src.IsVariableRentGstEligible == true ? src.VariableRentGstAmount : null)
.Map(dest => dest.PaymentAmount, src => src.PaymentAmount)
.Map(dest => dest.PaymentNote, src => src.PaymentNote)
.Map(dest => dest.PaymentDueDate, src => src.PaymentDueDateStr)
.Map(dest => dest.PimsLeasePayments, src => src.Payments)
.Map(dest => dest.IsFlexibleDuration, src => src.IsFlexible)
.Map(dest => dest.IsVariablePayment, src => src.IsVariable)
.Map(dest => dest.AddlRentAgreedPmt, src => src.AdditionalRentPaymentAmount)
.Map(dest => dest.AddlRentFreq, src => src.AdditionalRentFreqTypeCode != null ? src.AdditionalRentFreqTypeCode.Id : null)
.Map(dest => dest.IsAddlRentSubjectToGst, src => src.IsAdditionalRentGstEligible)
.Map(dest => dest.VblRentAgreedPmt, src => src.VariableRentPaymentAmount)
.Map(dest => dest.VblRentFreq, src => src.VariableRentFreqTypeCode != null ? src.VariableRentFreqTypeCode.Id : null)
.Map(dest => dest.IsVblRentSubjectToGst, src => src.IsVariableRentGstEligible)
.Inherits<BaseAuditModel, Entity.IBaseAppEntity>();
}
}
Expand Down
40 changes: 40 additions & 0 deletions source/backend/apimodels/Models/Concepts/Lease/LeasePeriodModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ public class LeasePeriodModel : BaseAuditModel
/// </summary>
public decimal? GstAmount { get; set; }

/// <summary>
/// get/set - The stored calculated additional gst amount based on the total payment and the system gst constant.
/// </summary>
public decimal? AdditionalRentGstAmount { get; set; }

/// <summary>
/// get/set - The stored calculated variable gst amount based on the total payment and the system gst constant.
/// </summary>
public decimal? VariableRentGstAmount { get; set; }

/// <summary>
/// get/set - The expected payment amount of the period, less GST.
/// </summary>
Expand Down Expand Up @@ -86,6 +96,36 @@ public class LeasePeriodModel : BaseAuditModel
/// </summary>
public bool IsVariable { get; set; }

/// <summary>
/// get/set - Additional rent payment amount
/// </summary>
public decimal? AdditionalRentPaymentAmount { get; set; }

/// <summary>
/// get/set - Is the additional rent subject to GST.
/// </summary>
public bool? IsAdditionalRentGstEligible { get; set; }

/// <summary>
/// get/set - Frequency type code for additional rent.
/// </summary>
public CodeTypeModel<string> AdditionalRentFreqTypeCode { get; set; }

/// <summary>
/// get/set - Variable rent payment amount
/// </summary>
public decimal? VariableRentPaymentAmount { get; set; }

/// <summary>
/// get/set - Is the variable rent subject to GST.
/// </summary>
public bool? IsVariableRentGstEligible { get; set; }

/// <summary>
/// get/set - Frequency type code for variable rent.
/// </summary>
public CodeTypeModel<string> VariableRentFreqTypeCode { get; set; }

/// <summary>
/// get/set - An (optional) list of payments associated to this period. Should only be set if the period is excercised.
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions source/backend/apimodels/Models/Concepts/Lease/PaymentMap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.LeasePeriodId, src => src.LeasePeriodId)
.Map(dest => dest.LeasePaymentMethodType, src => src.LeasePaymentMethodTypeCodeNavigation)
.Map(dest => dest.LeasePaymentStatusTypeCode, src => src.LeasePaymentStatusTypeCodeNavigation)
.Map(dest => dest.LeasePaymentCategoryTypeCode, src => src.LeasePaymentCategoryTypeCodeNavigation)
.Map(dest => dest.AmountGst, src => src.PaymentAmountGst)
.Map(dest => dest.AmountPreTax, src => src.PaymentAmountPreTax)
.Map(dest => dest.AmountPst, src => src.PaymentAmountPst)
Expand All @@ -27,6 +28,7 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.LeasePeriodId, src => src.LeasePeriodId)
.Map(dest => dest.LeasePaymentMethodTypeCode, src => src.LeasePaymentMethodType.Id)
.Map(dest => dest.LeasePaymentStatusTypeCode, src => src.LeasePaymentStatusTypeCode.Id)
.Map(dest => dest.LeasePaymentCategoryTypeCode, src => src.LeasePaymentCategoryTypeCode.Id)
.Map(dest => dest.PaymentAmountGst, src => src.AmountGst)
.Map(dest => dest.PaymentAmountPreTax, src => src.AmountPreTax)
.Map(dest => dest.PaymentAmountPst, src => src.AmountPst)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public class PaymentModel : BaseAuditModel
/// </summary>
public CodeTypeModel<string> LeasePaymentStatusTypeCode { get; set; }

/// <summary>
/// get/set - The category of the payment: base, variable or additional.
/// </summary>
public CodeTypeModel<string> LeasePaymentCategoryTypeCode { get; set; }

/// <summary>
/// get/set - The date the payment was or will be received.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,5 +157,7 @@ public interface ILookupRepository : IRepository
IEnumerable<PimsHistoricalFileNumberType> GetAllHistoricalNumberTypes();

IEnumerable<PimsLeaseChklstSectionType> GetAllLeaseChecklistSectionTypes();

IEnumerable<PimsLeasePaymentCategoryType> GetAllLeasePaymentCategoryTypes();
}
}
1 change: 1 addition & 0 deletions source/backend/dal/Repositories/LeasePaymentRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public PimsLeasePayment Add(PimsLeasePayment pimsLeasePayment)
public IEnumerable<PimsLeasePayment> GetAll(DateTime startDate, DateTime endDate)
{
return this.Context.PimsLeasePayments
.Include(p => p.LeasePaymentCategoryTypeCodeNavigation)
.Include(p => p.LeasePeriod)
.ThenInclude(t => t.Lease)
.ThenInclude(p => p.PimsPropertyLeases)
Expand Down
4 changes: 4 additions & 0 deletions source/backend/dal/Repositories/LeasePeriodRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,15 @@ public IEnumerable<PimsLeasePeriod> GetAllByLeaseId(long leaseId)
{
var periods = this.Context.PimsLeasePeriods.AsNoTracking()
.Include(t => t.LeasePmtFreqTypeCodeNavigation)
.Include(t => t.VblRentFreqNavigation)
.Include(t => t.AddlRentFreqNavigation)
.Include(t => t.LeasePeriodStatusTypeCodeNavigation)
.Include(t => t.PimsLeasePayments)
.ThenInclude(p => p.LeasePaymentMethodTypeCodeNavigation)
.Include(t => t.PimsLeasePayments)
.ThenInclude(p => p.LeasePaymentStatusTypeCodeNavigation)
.Include(t => t.PimsLeasePayments)
.ThenInclude(p => p.LeasePaymentCategoryTypeCodeNavigation)
.Where(t => t.LeaseId == leaseId).ToArray();

periods = periods.OrderBy(t => t.PeriodStartDate).ThenBy(t => t.LeasePeriodId).Select(t =>
Expand Down
5 changes: 5 additions & 0 deletions source/backend/dal/Repositories/LookupRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,11 @@ public IEnumerable<PimsLeaseChklstSectionType> GetAllLeaseChecklistSectionTypes(
return Context.PimsLeaseChklstSectionTypes.AsNoTracking().OrderBy(a => a.DisplayOrder).ToArray();
}

public IEnumerable<PimsLeasePaymentCategoryType> GetAllLeasePaymentCategoryTypes()
{
return Context.PimsLeasePaymentCategoryTypes.AsNoTracking().OrderBy(a => a.DisplayOrder).ToArray();
}

#endregion
}
}
36 changes: 36 additions & 0 deletions source/backend/entities/Partials/LeasePaymentCategoryType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.ComponentModel.DataAnnotations.Schema;

namespace Pims.Dal.Entities
{
/// <summary>
/// PimsLeasePaymentCategoryType class, provides an entity for the datamodel to manage a list of lease payment category types.
/// </summary>
public partial class PimsLeasePaymentCategoryType : ITypeEntity<string>
{
#region Properties

/// <summary>
/// get/set - Primary key to identify lease payment frequency type.
/// </summary>
[NotMapped]
public string Id { get => LeasePaymentCategoryTypeCode; set => LeasePaymentCategoryTypeCode = value; }
#endregion

#region Constructors

/// <summary>
/// Create a new instance of a LeasePaymentFrequencyType class.
/// </summary>
/// <param name="id"></param>
public PimsLeasePaymentCategoryType(string id)
: this()
{
Id = id;
}

public PimsLeasePaymentCategoryType()
{
}
#endregion
}
}
Loading
Loading