The View Pool page provides detailed information about the specific investment pools available to the Investment Team. It displays a summary of the pool, including the total amount invested, AUM (Assets Under Management), Cumulative Interest, % Cumulative Interest per Annum, Current Unit Price, and the Total Deposits. The page also allows the Investment Team to view the pool transactions, which include Asset, Asset Transfers, and User Withdrawals. The Investment Team can manage the pool transactions effectively using the provided functionalities which include:
On page load, /api:BVaDN9hl/asset_management/pool?pool_id=1 is hit to retrieve the data. It runs App\Http\Controllers\Admin\AssetManagementController@pool.
public function pool(Request $request)
{
$validator = Validator::make($request->all(), [
'filter' => 'nullable|string',
'date' => 'nullable|string',
'per_page' => 'nullable|integer',
'page' => 'nullable|integer',
'pool_id' => ['required', 'exists:investment_pools,id'],
]);
if ($validator->fails()) {
return response()->json(['errors' => $validator->errors()], 422);
}
$filter = $request->filter;
$date = $request->date;
$per_page = $request->per_page;
$page = $request->page;
$start_date = null;
$end_date = null;
if (!empty($date)) {
$date = explode('-', trim($date));
$start_date = Carbon::createFromDate(trim($date[0]));
$end_date = Carbon::createFromDate(trim($date[1]));
}
$investment_pool_id = $request->pool_id;
$investment_pool = InvestmentPool::findOrFail($investment_pool_id);
$investments_breakdown = GetInvestableFundsSummary::run(
$investment_pool_id,
start_date: $start_date,
end_date: $end_date
);
$deposits_total = GetInvestmentPoolTotalDepositAction::run(
$investment_pool_id,
start_date: $start_date,
end_date: $end_date
);
// $investments_total = GetInvestmentPoolTotalInvestmentAction::run($investment_pool_id);
// $unallocated_amount = number_format($deposits_total - $investments_total, 2);
$interest = GetInvestmentPoolInterestAction::run(
$investment_pool_id,
start_date: $start_date,
end_date: $end_date
);
$overall_return = GetInvestmentPoolInterestRateAction::run(investment_pool_id: $investment_pool_id);
$overall_return = number_format($overall_return, 2).'%';
$assets = GetInvestmentPoolAssetsAction::run(
$investment_pool_id,
filter: $filter,
start_date: $start_date,
end_date: $end_date
);
$buses = GetInvestmentPoolAssetBusesAction::run(
$investment_pool_id,
filter: $filter,
start_date: $start_date,
end_date: $end_date
);
$withdrawals = GetPoolWithdrawalsAction::run(
$investment_pool_id,
filter: $filter,
start_date: $start_date,
end_date: $end_date
);
$units_data = GetInvestmentPoolUnitisationHistory::run($investment_pool_id);
$current_unit_price = GetClosestUnitPrice::make()->handle($investment_pool_id, now(), UnitPriceScopeEnum::RETURNS);
return RespondWithSuccess::run(...[
'body' => [
'name' => $investment_pool->name,
'interest' => number_format($interest, 2),
'total_deposits' => number_format($deposits_total, 2),
'investable_funds' => number_format($investments_breakdown['investable'], 2),
'withdrawals' => $withdrawals,
'aum' => number_format(($deposits_total + $interest), 2),
'unit_price' => $current_unit_price,
'units_data' => $units_data,
'assets' => $assets,
'buses' => $buses,
'overall_return' => $overall_return,
// 'unallocated_amount' => $unallocated_amount,
'pool_details' => InvestmentPool::find($investment_pool_id)->only(['name', 'id']),
'assets_return_summary' => GetPoolViewAssetUnitPriceSummary::make()->handle($investment_pool_id)
]
]);
}
The API endpoint accepts the pool_id parameter to retrieve the specific pool data. It fetches the pool details, including the total deposits, investable funds, interest, AUM, and the current unit price. The endpoint also retrieves the pool transactions, such as assets, asset transfers, and user withdrawals, to display on the page. Various Action classes are used to fetch the data from the database and format it for display.
{
"name": "Short Term Pool",
"interest": "4,057,285.40",
"total_deposits": "11,593,371.27",
"investable_funds": "0.00",
"withdrawals": [
{
"username": "Maureen Mbaka",
"withdrawal_date": "09/03/2025",
"withdrawal_time": "16:03:48",
"amount": "8,000.00",
"member_no": "1001185",
"transaction_id": 6445
}
],
"aum": "15,650,656.67",
"unit_price": 1.236,
"units_data": [
{
"id": 844,
"name": "Current Unit Price",
"unit_price": "1.24",
"last_update": "2025-03-15 09:33:37"
},
{
"id": 846,
"name": "Incoming Unit Price",
"unit_price": "1.33",
"last_update": "2025-03-16 09:40:51"
}
],
"assets": [
{
"name": "Sanlam MMF",
"id": 3,
"maturity_date": "31/12/2023",
"maturity_time": "00:12:00",
"type": "MMF",
"amount": "11,002,004.00",
"created_date": "24/02/2023",
"created_time": "08:02:58"
}
],
"buses": [
{
"id": 77,
"asset_to": "Sanlam MMF",
"asset_from": "Bank",
"amount": "371,625.00",
"type": "DEPOSIT",
"status": "VERIFIED",
"investment_date": "30/05/2024",
"investment_time": "00:05:00",
"maturity_date": "30/05/2024",
"maturity_time": "00:05:00"
},
{
"id": 76,
"asset_to": "Sanlam MMF",
"asset_from": "Bank",
"amount": "644,150.00",
"type": "DEPOSIT",
"status": "VERIFIED",
"investment_date": "27/05/2024",
"investment_time": "00:05:00",
"maturity_date": "27/05/2024",
"maturity_time": "00:05:00"
},
{
"id": 75,
"asset_to": "Sanlam MMF",
"asset_from": "Bank",
"amount": "104,055.00",
"type": "DEPOSIT",
"status": "VERIFIED",
"investment_date": "17/05/2024",
"investment_time": "00:05:00",
"maturity_date": "17/05/2024",
"maturity_time": "00:05:00"
},
{
"id": 74,
"asset_to": "Sanlam MMF",
"asset_from": "Bank",
"amount": "153,110.00",
"type": "DEPOSIT",
"status": "VERIFIED",
"investment_date": "15/05/2024",
"investment_time": "00:05:00",
"maturity_date": "15/05/2024",
"maturity_time": "00:05:00"
},
{
"id": 73,
"asset_to": "Sanlam MMF",
"asset_from": "Bank",
"amount": "148,650.00",
"type": "DEPOSIT",
"status": "VERIFIED",
"investment_date": "08/05/2024",
"investment_time": "00:05:00",
"maturity_date": "08/05/2024",
"maturity_time": "00:05:00"
}
],
"overall_return": "9.01%",
"pool_details": {
"name": "Short Term Pool",
"id": 1
},
"assets_return_summary": [
{
"id": 3,
"name": "Sanlam MMF",
"unit_price": "1.0478",
"unit_cost": "3,143.36",
"last_updated_at": "2025-03-17 09:40:51"
}
]
}
The dashboard includes the following sections:
The Update Unit Price functionality allows the Investment Team to update the current unit price of the pool. This feature is useful for adjusting the unit price based on market conditions or other factors that may affect the pool's value. Steps to update the unit price:
The steps above will update the unit price of the pool and reflect the changes in the system by hitting the /api:BVaDN9hl/asset_management/pool/unitisation endpoint, which runs the App\Http\Controllers\Admin\AssetManagementController@addPoolUnit method.
public function addPoolUnit(Request $request)
{
$validator = Validator::make($request->all(), [
'pool_id' => 'required|exists:investment_pools,id',
'unit_price' => 'required|numeric',
'date' => 'required|date_format:d/m/Y|before_or_equal:today',
'link' => 'required',
]);
if ($validator->fails()) {
return RespondWithError::make()->handle(
code: RespondWithError::$ERROR_CODE_VALIDATION,
message: $validator->errors()->first(),
payload: $validator->errors()->toArray()
);
}
$data = $validator->validated();
$data['approved_by'] = Auth::id();
$func_2 = AddInvestmentPoolReturnAction::make()->handle(...$data);
return RespondWithSuccess::run(...[
'body' => [
'response' => $func_2,
]
]);
}
The code snippet above validates the pool ID, unit price, date, and link fields. It then adds the new unit price to the pool using the AddInvestmentPoolReturnAction class, which extends the AddInvestmentPoolReturn class and updates the pool's unit price in the database.
The Update Returns functionality enables the Investment Team to update the users dashboards. THis feature now makes it possible for the users to see the returns on their investments. Steps to update the returns:
The steps above hit /api:BVaDN9hl/asset_management/investment-pool-units/update-pool-returns endpoint, which runs the App\Http\Controllers\Admin\AssetManagementController@updateInvestmentPoolReturnUnitPrice method.
public function updateInvestmentPoolReturnUnitPrice(Request $request)
{
$validator = Validator::make($request->all(), [
'investment_pool_id' => ['required', 'exists:investment_pools,id'],
]);
if ($validator->fails()) {
return RespondWithError::make()->handle(
message: $validator->errors()->first(),
payload: $validator->errors()->toArray(),
status: 422
);
}
UpdateInvestmentPoolInterestUnitPrice::make()->handle($request->integer('investment_pool_id'));
// notify the users only once
$cacheKey = 'monthly_dashboard_interest_updated_notification_'.date('Y_m_d');
if (Cache::add($cacheKey, true, now()->endOfDay())) {
SendDashboardInterestUpdatedNotificationJob::dispatch();
}
return RespondWithSuccess::make()->handle();
}
The code snippet above validates the investment pool ID and updates the returns for the pool using the UpdateInvestmentPoolInterestUnitPrice action class, whci updates the scope of the investment pool unit prices in the database.
It also sends a notification to the users to inform them of the updated returns on their investments. The notification is sent only once per day to avoid spamming the users with multiple notifications.
The Assets View section allows the Investment Team to manage the assets in the pool effectively. The functionalities available in this section include: