User Transactions


Contents

Overview

The User Transactions section allows financial admins to view all user transactions. Additionally, admins can access detailed information about a specific user's transaction history. The page gets data from the endpoint /api:BVaDN9hl/transactions/list?filter%5Bsearch%5D=&filter%5Bpayment_method%5D=&page=1&per_page=15, which runs App\Http\Controllers\Admin\UserTransactionsController@transactions.

API Response

{
    "data": [
        {
            "name": "Sam Uzima",
            "email": "u******il.com",
            "phone_number": "+2547*****66",
            "type": "WITHDRAWAL",
            "date": "Mar 08, 2025",
            "time": "09:00PM",
            "amount": "-5,000.00",
            "tid": 1234,
            "users_id": 5678,
            "payment_method": "manual",
            "fulfillment": true,
            "bg_color": "/docs/1.0/financial-admin/user-transactions#7BBF7433",
            "color": "/docs/1.0/financial-admin/user-transactions#7bbf74"
        },
        {
            ---
        },
        {
            ---
        }
    ],
    "links": {
        "first": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/list?page=1",
        "last": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/list?page=114",
        "prev": null,
        "next": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/list?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 114,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/list?page=1",
                "label": "1",
                "active": true
            },
            {
                "url": null,
                "label": "...",
                "active": false
            },
            {
                "url": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/list?page=113",
                "label": "113",
                "active": false
            },
            {
                "url": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/list?page=114",
                "label": "114",
                "active": false
            },
            {
                "url": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/list?page=2",
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/list",
        "per_page": 15,
        "to": 15,
        "total": 1705
    }
}

User Transactions

The User Transactions section displays a list of all user transactions. The table includes the following columns:

  • Name: The user's name, email, and phone number.
  • Transaction Type: The transaction type (withdrawal).
  • Date/Time: The date of the transaction, and the time.
  • Amount: The transaction amount.
  • Payment Status: The payment method used.
  • Details: View more details about all the user's transactions.
 public function transactions(Request $request)
{
    $validator = Validator::make($request->all(), [
        'page' => 'required|numeric',
        'per_page' => 'required|numeric',
        'filter[search]' => 'nullable|string',
        'filter[type]' => 'nullable|string',
        'filter[payment_method]' => 'nullable|string',
    ]);
    if ($validator->fails()) {
        return response()->json(['errors' => $validator->errors()], 422);
    }
    $data = $validator->validated();
    $per_page = $data['per_page'];
    $filter = QueryBuilder::for(UserTransaction::query())
        ->allowedFilters([
            AllowedFilter::custom('search', new SearchFilter),
            AllowedFilter::exact('payment_method', 'is_fulfilled'),
            AllowedFilter::exact('type'),
        ])
        ->nonReceiptTransactions()
        ->whereNotIn('users_id', User::query()->adminAccounts()->pluck('id'));
    $userTransaction = GetTransactionsAction::run($per_page, $filter);
    return TransactionsResource::collection($userTransaction);
}

Looking at the code snippet above, the transactions method in the UserTransactionsController class is responsible for fetching user transactions. The method validates the request parameters and filters the transactions based on the search query, transaction type, and payment method. The GetTransactionsAction class is used to retrieve the transactions from the database, and the TransactionsResource class is used to format the response data.

Search User Transactions

The User Transactions page allows financial admins to search for specific user transactions using the search bar. Admins can enter the user's name, email, or phone number to filter the transactions. The search functionality hits /api:BVaDN9hl/transactions/list?filter%5Bsearch%5D=gesire&filter%5Bpayment_method%5D=&page=1&per_page=15, which runs App\Http\Controllers\Admin\UserTransactionsController@transactions, and returns the filtered transactions.

View User Transaction Details

Admins can view detailed information about a specific user's transaction by clicking on the "View All" button in the User Transactions table. The details page displays the following information:

  • User Profile: The user's profile information, including name, and contact details, the goals they have set categorized by the pool type, the total amount invested, amount in the long-term pool, amount in the short-term pool, and the total amount withdrawn.
  • Interest Details: The interest earned by the user, for each goal they have.
  • Transaction History: A list of all the user's transactions, including the transaction type, date, amount, allocation, and status.

The page gets data from the endpoints /api:BVaDN9hl/transactions/history/transactions?filter%5Bemail%5D=&page=1&per_page=3&search=&status=&type=&uid=1185 and /api:BVaDN9hl/transactions/history/stats?uid=1185, which runs App\Http\Controllers\Admin\UserTransactionsController@user_transactions and App\Http\Controllers\Admin\UserTransactionsController@stats respectively.

public function user_transactions(Request $request)
{
    $validator = Validator::make($request->all(), [
        'uid' => 'required|numeric',
        'search' => 'nullable|string',
        'page' => 'required|numeric',
        'per_page' => 'required|numeric',
        'status' => 'nullable|string',
    ]);
    if ($validator->fails()) {
        return response()->json(['errors' => $validator->errors()], 422);
    }
    $data = $validator->validated();
    $users_id = $data['uid'];
    $per_page = $data['per_page'];
    $search = $data['search'] ?? null;
    $user = User::find($users_id);
    if (!$user) {
        return RespondWithError::make()->handle(
            code: RespondWithError::$ERROR_CODE_NOT_FOUND,
            message: "user not found"
        );
    }
    $results = GetUserTransactionHistoryAction::run($users_id, $per_page, $search);
    return TransactionHistoryResource::collection($results);
}

API Response

{
    "data": [
        {
            "date": "Mar 08, 2025",
            "time": "09:00PM",
            "amount": "-8,000.00",
            "tid": 6791,
            "payment_method": "Manual",
            "status": "Successful",
            "bg_color": "/docs/1.0/financial-admin/user-transactions#7BBF7433",
            "color": "/docs/1.0/financial-admin/user-transactions#7bbf74",
            "allocations": [
                {
                    "id": 12347,
                    "name": "Emergency Fund",
                    "amount": "-4,000.00",
                    "percentage": "66.67%"
                }
            ]
        },
        {
            "date": "Mar 08, 2025",
            "time": "09:00PM",
            "amount": "-5,000.00",
            "tid": 6790,
            "payment_method": "Manual",
            "status": "Successful",
            "bg_color": "/docs/1.0/financial-admin/user-transactions#7BBF7433",
            "color": "/docs/1.0/financial-admin/user-transactions#7bbf74",
            "allocations": [
                {
                    "id": 12346,
                    "name": "Emergency Fund",
                    "amount": "-1,000.00",
                    "percentage": "33.33%"
                }
            ]
        },
        {
            "date": "Mar 08, 2025",
            "time": "09:00PM",
            "amount": "-10,000.00",
            "tid": 6789,
            "payment_method": "Manual",
            "status": "Successful",
            "bg_color": "/docs/1.0/financial-admin/user-transactions#7BBF7433",
            "color": "/docs/1.0/financial-admin/user-transactions#7bbf74",
            "allocations": [
                {
                    "id": 12345,
                    "name": "Emergency Fund",
                    "amount": "-6,000.00",
                    "percentage": "75.00%"
                }
            ]
        }
    ],
    "links": {
        "first": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/history/transactions?page=1",
        "last": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/history/transactions?page=12",
        "prev": null,
        "next": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/history/transactions?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 12,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "active": false
            },
            {
                "url": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/history/transactions?page=1",
                "label": "1",
                "active": true
            },
            ---
            {
                "url": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/history/transactions?page=12",
                "label": "12",
                "active": false
            },
            {
                "url": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/history/transactions?page=2",
                "label": "Next »",
                "active": false
            }
        ],
        "path": "http://127.0.0.1:8080/api:BVaDN9hl/transactions/history/transactions",
        "per_page": 3,
        "to": 3,
        "total": 36
    }
}

The user_transactions method in the UserTransactionsController class is responsible for fetching a specific user's transaction history. The method validates the request parameters and retrieves the user's transaction history using the GetUserTransactionHistoryAction class. The response data is formatted using the TransactionHistoryResource class.

public function stats(Request $request)
{
    $validator = Validator::make($request->all(), [
        'uid' => 'required|numeric',
    ]);
    if ($validator->fails()) {
        return response()->json(['errors' => $validator->errors()], 422);
    }
    $data = $validator->validated();
    $users_id = $data['uid'];
    $user = User::find($users_id);
    if (!$user) {
        return RespondWithError::make()->handle(
            code: RespondWithError::$ERROR_CODE_NOT_FOUND,
            message: "user not found"
        );
    }
    $user_goals = GetUserGoals::make()->handle($users_id)->pluck('id');
    UpdateUserInvestments::make()->handle($users_id);

    $long_term_goals = DB::table('goals as g')
        ->whereIn('g.id', $user_goals)
        ->where('g.investment_pool_id', '=', InvestmentPool::$LONG_TERM_POOL)
        ->leftJoin('investment_pools as pool', 'pool.id', '=', 'g.investment_pool_id')
        ->select(
            'g.title',
            'pool.name',
            'g.id',
            'g.principle',
            'g.value',
        )
        ->get();
    $long_amount = 0;
    $long_goals = [];
    foreach ( $long_term_goals as $goal) {
        $long_amount += $goal->principle;
        $long_goals[] = $goal->title;
    }
    $long_term = [
        'goals' => $long_goals,
        'amount' => number_format($long_amount, 2),
    ];
    $short_term_goals = DB::table('goals as g')
        ->whereIn('g.id', $user_goals)
        ->where('g.investment_pool_id', '=', InvestmentPool::$SHORT_TERM_POOL)
        ->leftJoin('investment_pools as pool', 'pool.id', '=', 'g.investment_pool_id')
        ->select(
            'g.title',
            'pool.name',
            'g.id',
            'g.principle',
            'g.value',
        )
        ->get();
    $short_amount = 0;
    $short_goals = [];
    foreach ($short_term_goals as $goal) {
        $short_amount += $goal->principle;
        $short_goals[] = $goal->title;
    }
    $short_term = [
        'goals' => $short_goals,
        'amount' => number_format($short_amount, 2),
    ];
    $completed_goals = DB::table('goals as g')
        ->whereIn('g.id', $user_goals)
        ->where('g.value', '>', DB::raw('g.target'))
        ->select(
            'g.title',
            'g.id',
            'g.principle',
            'g.value',
            'g.target'
        )
        ->get();
    $invested_amount = GoalTransaction::query()
        ->where('users_id', $users_id)
        ->where('status','=', TransactionStatusEnum::VERIFIED)
        ->where('action', '=', TransactionActionEnum::DEPOSIT)
        ->sum('amount');
    $invested_amount = number_format($invested_amount, 2);
    $withdrawn_amount = GoalTransaction::query()
        ->where('users_id', $users_id)
        ->where('status','=', TransactionStatusEnum::VERIFIED)
        ->where('action', '=', TransactionActionEnum::WITHDRAWAL)
        ->sum('amount');
    $withdrawn_amount = number_format($withdrawn_amount, 2);
    $interest_details = [];
    $goals_details = DB::table('goals as g')
        ->whereIn('g.id', $user_goals)
        ->where('g.principle', '>', 0)
        ->select(
            'g.title',
            'g.id',
            'g.principle',
            'g.value',
            'g.target'
        )
        ->get();
    foreach ($goals_details as $goal) {
        if ($goal->principle === floatval(0)){
            $principle_ff = 1;
        }else {
            $principle_ff = $goal->principle;
        }
        $interest = number_format((($goal->value - $goal->principle) / $principle_ff) * 100, 2);
        $interest_details[] = [
            'id' => $goal->id,
            'name' => $goal->title,
            'amount' => number_format($goal->value, 2),
            'interest' => $interest,
        ];
    }
    return response()->json([
        'user_info' => [
            'fullname' => $user->firstname . ' ' . $user->lastname,
            'email' => $user->email,
            'profile' => "",
        ],
        'long_term' => $long_term,
        'short_term' => $short_term,
        'completed' => $completed_goals,
        'amounts' => [
            'invested' => $invested_amount,
            'withdrawn' => $withdrawn_amount,
        ],
        'interest' => $interest_details,
    ]);
}

The stats method in the UserTransactionsController class is responsible for fetching detailed information about a specific user's transaction history. The method retrieves the user's profile information, long-term and short-term goals, completed goals, total amount invested, total amount withdrawn, and interest details. The response data is formatted and returned to the client.

API Response

{
    "user_info": {
        "fullname": "Sam Uzima",
        "email": "u******il.com",
        "profile": ""
    },
    "long_term": {
        "goals": [
            "Financial Freedom",
            "Real estate"
        ],
        "amount": "1,027,742.00"
    },
    "short_term": {
        "goals": [
            "Emergency Fund"
        ],
        "amount": "431,587.00"
    },
    "completed": [],
    "amounts": {
        "invested": "1,479,329.00",
        "withdrawn": "-20,000.00"
    },
    "interest": [
        {
            "id": 1236,
            "name": "Financial Freedom",
            "amount": "854,639.59",
            "interest": "19.69"
        },
        {
            "id": 1235,
            "name": "Emergency Fund",
            "amount": "493,131.52",
            "interest": "14.26"
        },
        {
            "id": 1234,
            "name": "Real estate",
            "amount": "385,009.54",
            "interest": "22.73"
        }
    ]
}