summaryrefslogtreecommitdiff
path: root/src/FundLab.Api/App.fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/FundLab.Api/App.fs')
-rw-r--r--src/FundLab.Api/App.fs77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/FundLab.Api/App.fs b/src/FundLab.Api/App.fs
index d5c3a50..3d89dae 100644
--- a/src/FundLab.Api/App.fs
+++ b/src/FundLab.Api/App.fs
@@ -487,6 +487,35 @@ type CapitalDepositResponse =
createdAt: string
}
+type CashLedgerEventResponse =
+ {
+ source: string
+ eventDate: string
+ amount: string
+ referenceType: string
+ referenceId: string
+ note: string option
+ }
+
+type CashLedgerSourceResponse =
+ {
+ source: string
+ netAmount: string
+ eventCount: int
+ }
+
+type CashReconciliationResponse =
+ {
+ fundId: Guid
+ openingCash: string
+ netInflow: string
+ closingCash: string
+ ledgerBalance: string
+ difference: string
+ sources: CashLedgerSourceResponse list
+ events: CashLedgerEventResponse list
+ }
+
type FundReturnsPointResponse =
{
date: string
@@ -846,6 +875,39 @@ module App =
createdAt = timestampText deposit.CreatedAt
}
+ let private cashLedgerEventResponse (event: CashLedger.CashLedgerEvent) : CashLedgerEventResponse =
+ {
+ source = CashLedger.sourceText event.Source
+ eventDate = dateText event.EventDate
+ amount = cashText event.Amount
+ referenceType = event.ReferenceType
+ referenceId = event.ReferenceId
+ note = event.Note
+ }
+
+ let private cashReconciliationResponse
+ (fundId: Guid)
+ (reconciliation: CashLedger.CashReconciliation)
+ (events: CashLedger.CashLedgerEvent list)
+ : CashReconciliationResponse =
+ {
+ fundId = fundId
+ openingCash = cashText reconciliation.OpeningCash
+ netInflow = cashText reconciliation.NetInflow
+ closingCash = cashText reconciliation.ClosingCash
+ ledgerBalance = cashText reconciliation.LedgerBalance
+ difference = cashText reconciliation.Difference
+ sources =
+ reconciliation.Sources
+ |> List.map (fun total ->
+ {
+ source = CashLedger.sourceText total.Source
+ netAmount = cashText total.NetAmount
+ eventCount = total.EventCount
+ })
+ events = events |> List.map cashLedgerEventResponse
+ }
+
let private sipPlanResponse (plan: SipPlanRecord) : SipPlanResponse =
{
id = plan.Id
@@ -1763,6 +1825,20 @@ module App =
with _ ->
errorResponse 500 "PERSISTENCE_ERROR" "capital deposit persistence failed" next ctx
+ let private getCashReconciliation (repository: FundRepository) (fundIdText: string) : HttpHandler =
+ fun next ctx ->
+ match Guid.TryParse fundIdText with
+ | false, _ -> errorResponse 400 "INVALID_FUND_ID" "fund id must be a UUID" next ctx
+ | true, fundId ->
+ try
+ match repository.GetCashReconciliation fundId with
+ | Error _ -> errorResponse 404 "FUND_NOT_FOUND" "fund was not found" next ctx
+ | Ok reconciliation ->
+ let events = repository.GetCashLedger fundId
+ json (cashReconciliationResponse fundId reconciliation events) next ctx
+ with _ ->
+ errorResponse 500 "PERSISTENCE_ERROR" "cash reconciliation failed" next ctx
+
let private createSipPlan (repository: FundRepository) (fundIdText: string) : HttpHandler =
fun next ctx ->
task {
@@ -3555,6 +3631,7 @@ module App =
GET >=> routef "/funds/%s/positions" (getPositions repository)
POST >=> routef "/funds/%s/capital/deposit" (createCapitalDeposit repository)
GET >=> routef "/funds/%s/capital/deposits" (getCapitalDeposits repository)
+ GET >=> routef "/funds/%s/cash-reconciliation" (getCashReconciliation repository)
POST >=> routef "/funds/%s/sip/plans" (createSipPlan repository)
GET >=> routef "/funds/%s/sip/plans" (getSipPlans repository)
POST >=> routef "/funds/%s/sip/advance" (advanceSipPlans repository probes)