Investment Team | View Pool


Contents

Overview

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:

  • Update Unit Price: Allows the team to update the current unit price of the pool.
  • Update Returns: Enables the team to update the returns for the pool so that the system can calculate the cumulative interest accurately.
  • Add Asset: Allows the team to add assets to the pool.
  • Add Asset Transfer Bus: Enables the team to create an investment bus for asset transfers.
  • Process Withdrawal: Allows the team to process user withdrawals from the pool.

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"
        }
    ]
}

Dashboard

The dashboard includes the following sections:

  • Total Investable Amount: Displays the total amount available for investment.
  • Non-Investable Amount: Shows the amount that is not available for investment.
  • AP Repo: Provides an overview of the AP Repo amounts AP Repo.
  • Pools: Displays information about different investment pools, including:
    • AUM (Assets Under Management): Total value of assets managed.
    • Short Term Pool: Details of the short-term investment pool.
    • Long Term Pool: Details of the long-term investment pool.

Update Unit Price

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:

  1. Click on the Update Unit Price button.
  2. Enter the new unit price, date, and upload proof of the unit price update.
  3. Click on the Next button to confirm the update.
  4. Click on the Next button to save the changes.

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.

Update Returns

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:

  1. Click on the Update Returns button.
  2. Confirm the update by clicking on the Update button.

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.

Assets View

The Assets View section allows the Investment Team to manage the assets in the pool effectively. The functionalities available in this section include:

  • Add Asset: Enables the team to add assets to the pool.
  • View Asset: Allows the team to view detailed information about specific assets in the pool.