{% extends 'wfbo/_layout.html.twig' %} {% block title %}{{ subject.firstName }} {{ subject.lastName }} — Transactions{% endblock %} {% block wfbo_title %}User Transactions{% endblock %} {% block wfbo_content %} {% for flash in app.flashes('success') %} {% endfor %} {% for flash in app.flashes('error') %} {% endfor %} {# ── User header ── #}
← Back to Users
{{ subject.firstName|first|upper }}{{ subject.lastName|first|upper }}

{{ subject.firstName }} {{ subject.lastName }}

{{ subject.userIdentifier }}

{# Wallet balance badge #}

Wallet Balance

₱{{ subject.walletBalance|number_format(2) }}

{# Actions dropdown #} {% if is_granted('ROLE_ADMIN') or is_granted('ROLE_SUPER_ADMIN') %} {% set isPlainUser = 'ROLE_MASTER_AGENT' not in subject.roles and 'ROLE_AGENT' not in subject.roles and 'ROLE_ADMIN' not in subject.roles and 'ROLE_SUPER_ADMIN' not in subject.roles and 'ROLE_FINANCE' not in subject.roles and 'ROLE_OPERATIONS' not in subject.roles %} {# Hidden forms — triggered by dropdown items #} {% if 'ROLE_ADMIN' not in subject.roles and 'ROLE_SUPER_ADMIN' not in subject.roles %} {% else %} {% endif %} {% if 'ROLE_FINANCE' not in subject.roles %} {% else %} {% endif %} {% if 'ROLE_OPERATIONS' not in subject.roles %} {% else %} {% endif %} {% if is_granted('ROLE_SUPER_ADMIN') %} {% endif %} {# Dropdown trigger #} {% endif %}
{# ── Upline family tree ── #} {% if treeUplineChain|length > 0 or isAgent %}

Agents

{% for uplineUser in treeUplineChain %} {% set uIsMaster = 'ROLE_MASTER_AGENT' in uplineUser.roles %} {% set uIsAgent = 'ROLE_AGENT' in uplineUser.roles %}
{% if uIsMaster %} Master Agent {% elseif uIsAgent %} Agent {% endif %} {{ uplineUser.firstName }} {{ uplineUser.lastName }}
{% endfor %} {% set subjectIsMaster = 'ROLE_MASTER_AGENT' in subject.roles %} {% set subjectIsAgent = 'ROLE_AGENT' in subject.roles %}
{% if subjectIsMaster %} Master Agent {% elseif subjectIsAgent %} Agent {% else %} Player {% endif %} {{ subject.firstName }} {{ subject.lastName }} viewing
{% endif %} {# ── Adjust Wallet form (ROLE_FINANCE only) ── #} {% if is_granted('ROLE_FINANCE') %}

Adjust Wallet

{% endif %} {# ── Period filter (scopes the stat cards below only, not the tables) ── #} {% set periodPresets = [ {key: 'today', label: 'Today'}, {key: 'yesterday', label: 'Yesterday'}, {key: 'this_month', label: 'This Month'}, {key: 'last_month', label: 'Last Month'}, {key: 'this_year', label: 'This Year'}, {key: 'last_year', label: 'Last Year'}, ] %}
{% for p in periodPresets %} {{ p.label }} {% endfor %} ↻ Refresh
{# ── Stats row ── #} {% set colClass = 'col-12 col-sm-4' %}

Total Deposited

₱{{ totalDeposited|number_format(2) }}

Total Bet Amount

₱{{ totalBetAmount|number_format(2) }}

Total Win Amount

₱{{ totalWinAmount|number_format(2) }}

{% if isAgent %}

Total Commission

₱{{ totalCommissionAmount|number_format(2) }}

Direct Referrals

{{ directReferralCount }}

{% if 'ROLE_MASTER_AGENT' in subject.roles %}

Referrals from Agents

{{ subAgentReferralCount }}

{% endif %}

Total Player Bet Amount

₱{{ totalPlayerBetAmount|number_format(2) }}

Total Player Win Amount

₱{{ totalPlayerWinAmount|number_format(2) }}

Total Win Rate

{{ totalPlayerWinRate|number_format(2) }}%

Total Revenue Collected

₱{{ totalPlayerRevenue|number_format(2) }}

{% endif %}
{# ── Type tabs ── #}
Deposits ({{ depositCount }}) Withdrawals ({{ withdrawalCount }}) Bets ({{ betCount }}) Adjustments ({{ adjustmentCount }}) Activity ({{ activityCount }}) {% if isAgent %} Commissions ({{ commissionCount }}) Players ({{ playerCount }}) Agents ({{ agentCount }}) {% endif %}
{# ── Unified transactions table (deposits/withdrawals/adjustments) ── #} {% if currentType in ['deposits', 'withdrawals', 'adjustments'] %}
{% for tx in transactions %} {% else %} {% endfor %}
Date Type Description Amount Balance

{{ tx.createdAt|date('M d, Y') }}

{{ tx.createdAt|date('h:i A') }}

{% if tx.type == 'deposit' %} Deposit {% elseif tx.type == 'withdrawal' %} Withdrawal {% elseif tx.type == 'bet' %} Bet {% elseif tx.type == 'win' %} Win {% elseif tx.type == 'adjustment' %} Adjustment {% elseif tx.type == 'refund' %} Refund {% elseif tx.type == 'commission' %} Commission {% else %} {{ tx.type|capitalize }} {% endif %} {{ tx.description ?? '—' }} {% set absAmount = tx.absoluteAmount %} {% if tx.amount > 0 %}

+₱{{ absAmount|number_format(2) }}

{% else %}

-₱{{ absAmount|number_format(2) }}

{% endif %}
₱{{ tx.balanceAfter|number_format(2) }}
No {{ currentType }} found for this user.
{% endif %} {# ── Bets table (real per-game bet entities via WfboController::betUnion) ── #} {% if currentType == 'bets' %}
{% if currentSearch %} Clear {{ total }} match{{ total != 1 ? 'es' : '' }} for "{{ currentSearch }}" {% endif %}
{% for bet in bets %} {% else %} {% endfor %}
Date Game Ref # Detail Bet Payout Outcome

{{ bet.created_at|date('M d, Y') }}

{{ bet.created_at|date('h:i A') }}

{% if bet.game == 'vk' %} Video Karera {% elseif bet.game == 'high-low' %} Pataasan {% elseif bet.game == 'mines' %} Mines {% elseif bet.game == 'fk' %} Fruit King {% elseif bet.game == 'ezdos' %} EZDOS {% elseif bet.game == 'pk' %} Pachinko {% elseif bet.game == 'h2h' %} Head2Head {% elseif bet.game == 'lr' %} Live Racing {% elseif bet.game == 'cg' %} Color Game {% else %} {% endif %} #{{ bet.ref_id }} {% if bet.game == 'high-low' %} {% if bet.round_cards is defined and bet.round_cards is not null %} {% set cards = bet.round_cards|split('|') %} {% set winnerCard = bet.round_result in ['card1', 'card2'] ? attribute({card1: cards[0], card2: cards[1]}, bet.round_result) : null %}
Bet: Card {{ bet.description|slice(4) }} {% if bet.round_result is defined and bet.round_result is not null %} Result: Card {{ bet.round_result|slice(4) }} ↑ {% if winnerCard %} {% endif %} {% endif %}
{% else %}
Bet: Card {{ bet.description|slice(4) }}
{% endif %} {% elseif bet.game == 'cg' %} {% set dice = bet.round_result ? bet.round_result|split(',') : [] %} {% set cgDiceBg = {'yellow':'#F4B942','white':'#F5F5F5','pink':'#FF3E9A','blue':'#3D87E8','red':'#E63946','green':'#3FB65D'} %} {% set cgDiceFg = {'yellow':'#3a2606','white':'#1a1330','pink':'#ffffff','blue':'#ffffff','red':'#ffffff','green':'#ffffff'} %}
{{ bet.description }} {% if dice|length == 3 %}
{% for d in dice %} {{ d|slice(0, 1) }} {% endfor %}
{% endif %}
{% elseif bet.game == 'mines' %} {{ bet.description|replace({'_': ' '})|capitalize }} — {{ bet.round_result }} tile{{ bet.round_result == '1' ? '' : 's' }} revealed {% elseif bet.game == 'fk' %} Bet: {{ bet.description|capitalize }}{% if bet.round_result %} — Landed: {{ bet.round_result|capitalize }}{% endif %} {% elseif bet.game == 'pk' %} {{ bet.description }} {% elseif bet.game == 'h2h' %} {{ bet.description }} {% elseif bet.game == 'lr' and bet.round_cards %} {% set comboStrings = bet.round_cards|split('|||') %} {% set allSegments = [] %} {% for cs in comboStrings %} {% set selections = cs|json_decode %} {% if selections|length == 1 and selections|first.horses is defined and selections|first.horses|length > 1 %} {% set segments = [] %} {% for h in selections|first.horses %} {% set segments = segments|merge([{'eventRaceId': selections|first.eventRaceId, 'value': h.horseNumber}]) %} {% endfor %} {% else %} {% set segments = [] %} {% for entry in selections %} {% if entry.selection is defined %} {% set segments = segments|merge([{'eventRaceId': entry.eventRaceId, 'value': entry.selection|capitalize}]) %} {% elseif entry.horses is defined and entry.horses|length > 0 %} {% set segments = segments|merge([{'eventRaceId': entry.eventRaceId, 'value': entry.horses|first.horseNumber}]) %} {% endif %} {% endfor %} {% endif %} {% set allSegments = allSegments|merge([segments]) %} {% endfor %} {% set parts = [] %} {% set lastRaceNumber = null %} {% if allSegments|length > 0 and allSegments|first|length > 0 %} {% set slotCount = allSegments|first|length %} {% set firstCombo = allSegments|first %} {% for i in 0..slotCount-1 %} {% set candidates = [] %} {% for segments in allSegments %} {% if segments[i] is defined and segments[i].value is not empty and segments[i].value not in candidates %} {% set candidates = candidates|merge([segments[i].value]) %} {% endif %} {% endfor %} {% set text = candidates|join(',') %} {% set raceNumber = (firstCombo[i] is defined and firstCombo[i].eventRaceId is defined) ? (lrRaceNumbers[firstCombo[i].eventRaceId] ?? null) : null %} {% if raceNumber is not null and raceNumber != lastRaceNumber %} {% set text = 'R' ~ raceNumber ~ ': ' ~ text %} {% set lastRaceNumber = raceNumber %} {% endif %} {% set parts = parts|merge([text]) %} {% endfor %} {% endif %} {{ bet.description|title }} — {{ parts|join('/ ') }}{% if bet.combo_count is defined and bet.combo_count > 1 %} (×{{ bet.combo_count }}){% endif %} {% else %} {{ bet.description }} {% endif %}

₱{{ bet.amount|number_format(2) }}

{% if (bet.status == 'won' or bet.status == 'mixed') and bet.payout and bet.payout > 0 %}

₱{{ bet.payout|number_format(2) }}

{% else %}

—

{% endif %}
{% if bet.status == 'won' %} Won {% elseif bet.status == 'lost' %} Lost {% elseif bet.status == 'void' %} Void {% elseif bet.status == 'mixed' %} {% set counts = bet.status_counts is not null ? bet.status_counts|json_decode : null %} {% set mixedParts = [] %} {% if counts %} {% if counts.pending > 0 %}{% set mixedParts = mixedParts|merge([counts.pending ~ ' pending']) %}{% endif %} {% if counts.won > 0 %}{% set mixedParts = mixedParts|merge([counts.won ~ ' won']) %}{% endif %} {% if counts.lost > 0 %}{% set mixedParts = mixedParts|merge([counts.lost ~ ' lost']) %}{% endif %} {% if counts.void > 0 %}{% set mixedParts = mixedParts|merge([counts.void ~ ' void']) %}{% endif %} {% endif %} {{ mixedParts|length > 0 ? mixedParts|join(', ') : 'Mixed' }} {% else %} Pending {% endif %}
No bets found for this user.
{% endif %} {# ── Activity log table ── #} {% if currentType == 'activity' %}
{% for log in auditLogs %} {% else %} {% endfor %}
Date Action Performed By

{{ log.createdAt|date('M d, Y') }}

{{ log.createdAt|date('h:i A') }}

{{ log.action }} {% if log.actor %} {{ log.actor.firstName }} {{ log.actor.lastName }} {% else %} — {% endif %}
No activity recorded for this user.
{% endif %} {# ── Pagination ── #} {% if totalPages > 1 %}

Page {{ currentPage }} of {{ totalPages }}  ·  {{ total }} total

{% set pageParams = currentSearch ? {id: subject.id, type: currentType, search: currentSearch} : {id: subject.id, type: currentType} %} {% if currentPage > 1 %} ← Previous {% endif %} {% if currentPage < totalPages %} Next → {% endif %}
{% endif %} {% endblock %} {% block javascripts %} {{ parent() }} {% if is_granted('ROLE_ADMIN') %} {# ── Change Agent Modal ── #} {# ── House Win Rate Modal ── #} {% endif %} {# ── Reset Password Result Modal ── #} {% set resetPwd = _flashes['reset_password_value'] ?? [] %} {% set resetName = _flashes['reset_password_name'] ?? [] %} {% if resetPwd %} {% endif %} {# ── Generic Confirmation Modal ── #} {% if is_granted('ROLE_ADMIN') %} {% endif %} {% endblock %}