403Webshell
Server IP : 72.60.21.38  /  Your IP : 216.73.217.154
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/ajax_get_allocation_details.php
<?php
session_start();
require_once 'includes/db.php';
require_once 'includes/functions.php';
require_once 'includes/installments.php';

header('Content-Type: application/json');

if (!isset($_GET['id'])) {
    echo json_encode(['error' => 'No ID provided']);
    exit;
}

$alloc_id = $_GET['id'];

try {
    // 1. Fetch Allocation Details
    $hasProps = false;
    $hasDeals = false;
    try { $hasProps = $pdo->query("SHOW TABLES LIKE 'properties'")->rowCount() > 0; } catch (Throwable $e) { $hasProps = false; }
    try { $hasDeals = $pdo->query("SHOW TABLES LIKE 'deals_submit'")->rowCount() > 0; } catch (Throwable $e) { $hasDeals = false; }

    $areaCol = ($hasProps && tableHasColumn('properties', 'area_sqm')) ? "p.area_sqm" : "NULL";
    $phoneCol = tableHasColumn('users', 'phone') ? "c.phone" : (tableHasColumn('users', 'mobile') ? "c.mobile" : (tableHasColumn('users', 'phone_number') ? "c.phone_number" : "NULL"));
    $unitCol = ($hasProps && tableHasColumn('properties', 'unit_number')) ? "p.unit_number" : "NULL";
    $plotCol = ($hasProps && tableHasColumn('properties', 'plot_number')) ? "p.plot_number" : "NULL";
    $allocHouseTypeCol = tableHasColumn('allocations', 'house_type') ? "a.house_type" : "NULL";
    $allocBuildingUseCol = tableHasColumn('allocations', 'building_use') ? "a.building_use" : "NULL";
    $allocBuildingNumberCol = tableHasColumn('allocations', 'building_number') ? "a.building_number" : "NULL";

    $pTitleCol = ($hasProps && tableHasColumn('properties', 'title')) ? "p.title" : "NULL";
    $pAddrCol = "NULL";
    if ($hasProps) {
        if (tableHasColumn('properties', 'location')) { $pAddrCol = "p.location"; }
        elseif (tableHasColumn('properties', 'address')) { $pAddrCol = "p.address"; }
        elseif (tableHasColumn('properties', 'property_address')) { $pAddrCol = "p.property_address"; }
    }
    $pPriceCol = "0";
    if ($hasProps) {
        if (tableHasColumn('properties', 'price')) { $pPriceCol = "p.price"; }
        elseif (tableHasColumn('properties', 'amount')) { $pPriceCol = "p.amount"; }
        elseif (tableHasColumn('properties', 'total_price')) { $pPriceCol = "p.total_price"; }
    }
    $aPriceCol = "0";
    if (tableHasColumn('allocations', 'total_price')) { $aPriceCol = "a.total_price"; }
    elseif (tableHasColumn('allocations', 'price')) { $aPriceCol = "a.price"; }
    elseif (tableHasColumn('allocations', 'amount')) { $aPriceCol = "a.amount"; }
    elseif (tableHasColumn('allocations', 'amount_offered')) { $aPriceCol = "a.amount_offered"; }
    elseif (tableHasColumn('allocations', 'offer_amount')) { $aPriceCol = "a.offer_amount"; }
    $dTitleCol = $hasDeals && tableHasColumn('deals_submit', 'project_desc') ? "d.project_desc" : "NULL";
    $dNameCol  = $hasDeals && tableHasColumn('deals_submit', 'project_name') ? "d.project_name" : "NULL";
    $dAmountCol = "0";
    if ($hasDeals) {
        if (tableHasColumn('deals_submit', 'amount_offered')) { $dAmountCol = "d.amount_offered"; }
        elseif (tableHasColumn('deals_submit', 'offer_amount')) { $dAmountCol = "d.offer_amount"; }
        elseif (tableHasColumn('deals_submit', 'price')) { $dAmountCol = "d.price"; }
        elseif (tableHasColumn('deals_submit', 'amount')) { $dAmountCol = "d.amount"; }
    }
    $propJoin = $hasProps ? "LEFT JOIN properties p ON a.property_id = p.id" : "LEFT JOIN (SELECT NULL AS id) p ON 1=0";
    $dealJoin = $hasDeals ? "LEFT JOIN deals_submit d ON a.deal_id = d.id" : "LEFT JOIN (SELECT NULL AS id) d ON 1=0";
    $titleExpr = "COALESCE(NULLIF({$pTitleCol},''), NULLIF({$dTitleCol},''), NULLIF({$dNameCol},''), CONCAT('Allocation #', a.id))";
    $addrExpr = "COALESCE(NULLIF({$pAddrCol},''), NULLIF({$dNameCol},''), NULLIF({$dTitleCol},''), '')";
    $priceExpr = "COALESCE(NULLIF({$aPriceCol},0), NULLIF({$pPriceCol},0), NULLIF({$dAmountCol},0), 0)";
    $sql = "
        SELECT a.*, 
               {$titleExpr} as property_title,
               {$addrExpr} as property_address,
               {$priceExpr} as property_price,
               " . (($hasProps && tableHasColumn('properties','type')) ? "p.type" : "NULL") . " as property_type,
               $areaCol as area_sqm,
               $unitCol as unit_number, $plotCol as plot_number,
               $allocHouseTypeCol as alloc_house_type, $allocBuildingUseCol as alloc_building_use, $allocBuildingNumberCol as alloc_building_number,
               c.name as client_name, c.email as client_email, $phoneCol as client_phone,
               ag.name as agent_name
        FROM allocations a
        {$propJoin}
        {$dealJoin}
        LEFT JOIN users c ON a.user_id = c.id
        LEFT JOIN users ag ON a.agent_id = ag.id
        WHERE a.id = ?
    ";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$alloc_id]);
    $allocation = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$allocation) {
        echo json_encode(['error' => 'Allocation not found']);
        exit;
    }
    $approvedAt = $allocation['approved_at'] ?? null;
    $updatedAt = $allocation['updated_at'] ?? null;
    if (!empty($approvedAt) && !empty($updatedAt)) {
        $wasApproved = strtolower((string)($allocation['status'] ?? '')) === 'approved';
        if ($wasApproved && strtotime($updatedAt) > strtotime($approvedAt)) {
            try {
                $st = $pdo->prepare("UPDATE allocations SET status = 'pending', signed = 0 WHERE id = ?");
                $st->execute([$alloc_id]);
                $allocation['status'] = 'pending';
                $allocation['signed'] = 0;
                try {
                    $pdo->query("DESCRIBE audit_logs");
                    $ins = $pdo->prepare("INSERT INTO audit_logs (action, details, ip_address, user_id, created_at) VALUES (?, ?, ?, ?, NOW())");
                    $ins->execute([
                        'allocation_reset_pending',
                        'Allocation edited after approval; reset to Pending. Allocation #'.$alloc_id,
                        $_SERVER['REMOTE_ADDR'] ?? '',
                        $_SESSION['user_id'] ?? null
                    ]);
                } catch (\Throwable $e) {}
            } catch (\Throwable $e) {}
        }
    }

    // Try to attach client photo from documents (passport/profile)
    try {
        $photoStmt = $pdo->prepare("SELECT file_path FROM documents WHERE user_id = ? AND type IN ('passport','photo','profile','profile_photo','id_photo') ORDER BY created_at DESC LIMIT 1");
        $photoStmt->execute([$allocation['user_id']]);
        $allocation['client_photo'] = $photoStmt->fetchColumn() ?: null;
        $allocation['client_photo_b64'] = null;
        if (!$allocation['client_photo']) {
            $alt = getClientAvatarUrl($pdo, (int)$allocation['user_id']);
            if ($alt) { $allocation['client_photo'] = $alt; }
        }
        if ($allocation['client_photo']) {
            $p = $allocation['client_photo'];
            if (!preg_match('#^https?://#i', $p)) {
                $abs = __DIR__ . '/' . ltrim($p, '/');
                if (is_file($abs) && filesize($abs) <= 5*1024*1024) {
                    $mime = 'image/jpeg';
                    if (function_exists('finfo_open')) {
                        $f = finfo_open(FILEINFO_MIME_TYPE);
                        $m = finfo_file($f, $abs);
                        finfo_close($f);
                        if ($m) $mime = $m;
                    }
                    $allocation['client_photo_b64'] = 'data:' . $mime . ';base64,' . base64_encode(file_get_contents($abs));
                }
            }
        }
    } catch (Exception $e) {
        $allocation['client_photo'] = null;
        $allocation['client_photo_b64'] = null;
    }

    // 2. Fetch Payments
    $payOrder = "id DESC";
    if (tableHasColumn('payments','date')) { $payOrder = "date DESC"; }
    elseif (tableHasColumn('payments','created_at')) { $payOrder = "created_at DESC"; }
    $stmt = $pdo->prepare("SELECT * FROM payments WHERE allocation_id = ? ORDER BY {$payOrder}");
    $stmt->execute([$alloc_id]);
    $payments = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $total_paid = 0;
    foreach ($payments as $pay) {
        $st = strtolower(trim((string)($pay['status'] ?? '')));
        if (in_array($st, ['verified','approved','paid','completed','success'], true)) {
            $amtRaw = $pay['amount'] ?? 0;
            $amtStr = is_string($amtRaw) ? $amtRaw : (string)$amtRaw;
            $amtStr = preg_replace('/[^\d.\-]/', '', $amtStr);
            $total_paid += (float)($amtStr !== '' ? $amtStr : 0);
        }
    }
    
    $allocationPriceRaw = $allocation['property_price'] ?? 0;
    $allocationPriceStr = is_string($allocationPriceRaw) ? $allocationPriceRaw : (string)$allocationPriceRaw;
    $allocationPriceStr = preg_replace('/[^\d.\-]/', '', $allocationPriceStr);
    $allocationPrice = (float)($allocationPriceStr !== '' ? $allocationPriceStr : 0);
    $allocation['property_price'] = $allocationPrice;
    $outstanding = $allocationPrice - $total_paid;
    $payment_status = ($outstanding <= 0) ? 'Paid' : (($total_paid > 0) ? 'Partially Paid' : 'Unpaid');

    // Derived fields
    $allocation['building_number'] = $allocation['alloc_building_number'] ?? $allocation['plot_number'] ?? $allocation['unit_number'] ?? null;
    $allocation['house_type'] = $allocation['alloc_house_type'] ?? $allocation['property_type'] ?? null;
    $allocation['space_size'] = $allocation['area_sqm'] ?? null;
    $allocation['building_use'] = $allocation['alloc_building_use'] ?? null;
    $allocation['location'] = $allocation['property_address'] ?? null;
    $companyId = function_exists('getCurrentCompanyId') ? getCurrentCompanyId() : ($_SESSION['company_id'] ?? null);
    if (function_exists('ensureAllocationBillingTable')) { ensureAllocationBillingTable($pdo); }
    $defaultInfraPercent = (float)parseMoneyValue(getSetting('infra_lease_percent', '20'));
    $defaultVatPercent = (float)parseMoneyValue(getSetting('vat_percent', '7.5'));
    $defaultApplicationFee = (float)parseMoneyValue(getSetting('application_fee', '0'));
    $billingRow = null;
    try {
        $stB = $pdo->prepare("SELECT * FROM allocation_billing WHERE allocation_id = ? LIMIT 1");
        $stB->execute([(int)$alloc_id]);
        $billingRow = $stB->fetch(PDO::FETCH_ASSOC) ?: null;
    } catch (Throwable $e) { $billingRow = null; }
    $billingSettings = [
        'allocation_id' => (int)$alloc_id,
        'land_cost' => $allocationPrice,
        'infra_mode' => 'percent',
        'infra_percent' => $defaultInfraPercent,
        'infra_amount' => 0,
        'excavation_fee' => 0,
        'construction_supervision' => 0,
        'approval_fee' => 0,
        'application_form_fee' => $defaultApplicationFee,
        'fence_gate_cost' => 0,
        'carcass_cost' => 0,
        'exterior_finishing_cost' => 0,
        'dpc_cost' => 0,
        'include_fence' => 0,
        'include_carcass' => 0,
        'include_exterior_finishing' => 0,
        'include_dpc' => 0,
        'vat_percent' => $defaultVatPercent,
        'payment_plan_months' => 3,
    ];
    if (is_array($billingRow)) {
        foreach ($billingSettings as $k => $v) {
            if (array_key_exists($k, $billingRow)) { $billingSettings[$k] = $billingRow[$k]; }
        }
        if (array_key_exists('infra_mode', $billingRow)) { $billingSettings['infra_mode'] = $billingRow['infra_mode']; }
        if (array_key_exists('include_exterior_finishing', $billingRow)) { $billingSettings['include_exterior_finishing'] = $billingRow['include_exterior_finishing']; }
    }
    $computedBilling = function_exists('computeAllocationBilling') ? computeAllocationBilling($billingSettings) : [];
    $grandTotal = (float)($computedBilling['grand_total'] ?? $allocationPrice);
    $outstanding = $grandTotal - $total_paid;
    $payment_status = ($outstanding <= 0) ? 'Paid' : (($total_paid > 0) ? 'Partially Paid' : 'Unpaid');

    // 3. Fetch Documents (if any linked to user/property)
    // Assuming simple fetch for now based on property or user context
    $stmt = $pdo->prepare("SELECT * FROM documents WHERE property_id = ? OR (user_id = ? AND type = 'allocation_letter') ORDER BY created_at DESC");
    $stmt->execute([$allocation['property_id'], $allocation['user_id']]);
    $documents = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // 3b. Fetch Edit History from audit logs
    $edit_history = [];
    try {
        $qh = $pdo->prepare("
            SELECT a.entity_id, a.changed_by, a.created_at, a.reason, a.old_value, a.new_value, u.name AS editor_name
            FROM audit_logs a
            LEFT JOIN users u ON a.changed_by = u.id
            WHERE a.entity_type = 'allocation_edit' AND a.entity_id = ?
            ORDER BY a.created_at DESC
        ");
        $qh->execute([$alloc_id]);
        $rowsH = $qh->fetchAll(PDO::FETCH_ASSOC);
        foreach ($rowsH as $h) {
            $note = isset($h['reason']) ? (string)$h['reason'] : '';
            $parsed = null;
            if ($note !== '') {
                try { $tmp = json_decode($note, true); if (is_array($tmp)) $parsed = $tmp; } catch (\Throwable $e) {}
            }
            $summary = $note;
            $oldV = null; $newV = null;
            if (!empty($h['old_value'])) { try { $oldV = json_decode($h['old_value'], true); } catch (\Throwable $e) {} }
            if (!empty($h['new_value'])) { try { $newV = json_decode($h['new_value'], true); } catch (\Throwable $e) {} }
            if (is_array($oldV) && is_array($newV)) {
                $parts = [];
                foreach (['plot_size','plot_number'] as $k) {
                    if (array_key_exists($k, $oldV) || array_key_exists($k, $newV)) {
                        $parts[] = $k . ': ' . (isset($oldV[$k]) && $oldV[$k] !== null && $oldV[$k] !== '' ? $oldV[$k] : '—') . ' → ' . (isset($newV[$k]) && $newV[$k] !== null && $newV[$k] !== '' ? $newV[$k] : '—');
                    }
                }
                if (count($parts) > 0) {
                    $summary = implode('; ', $parts);
                    if (is_array($parsed) && isset($parsed['note']) && $parsed['note'] !== '') { $summary .= ' — ' . $parsed['note']; }
                }
            } elseif (is_array($parsed)) {
                $parts = [];
                if (!empty($parsed['plot_size'])) $parts[] = 'plot_size: ' . $parsed['plot_size'];
                if (!empty($parsed['plot_number'])) $parts[] = 'plot_number: ' . $parsed['plot_number'];
                if (!empty($parsed['note'])) $parts[] = $parsed['note'];
                if (count($parts) > 0) $summary = implode('; ', $parts);
            }
            $edit_history[] = [
                'allocation_id' => (int)$h['entity_id'],
                'edited_by' => (int)($h['changed_by'] ?? 0),
                'edited_by_name' => $h['editor_name'] ?? null,
                'edited_at' => $h['created_at'] ?? null,
                'edit_note' => (is_array($parsed) && isset($parsed['note'])) ? $parsed['note'] : ($note !== '' ? $note : null),
                'summary' => $summary
            ];
        }
    } catch (Exception $e) {
        $edit_history = [];
    }

    $letterData = [];
    try {
        if (function_exists('ensureAllocationLetterDataTable')) { ensureAllocationLetterDataTable($pdo); }
        if (function_exists('allocationLetterDataGet')) {
            $letterData = allocationLetterDataGet($pdo, (int)$alloc_id);
        }
    } catch (Throwable $e) { $letterData = []; }

    // 4. Construct Timeline (Allocation + Letter workflow)
    $timeline = [];
    $timeline[] = [
        'step' => 'Reservation Created',
        'date' => $allocation['created_at'],
        'status' => 'done',
        'role' => 'System'
    ];
    
    if ($total_paid > 0) {
        $timeline[] = [
            'step' => 'Initial Payment Received',
            'date' => $payments[count($payments)-1]['date'] ?? $allocation['created_at'], // First payment date
            'status' => 'done',
            'role' => 'Finance'
        ];
    } else {
        $timeline[] = [
            'step' => 'Initial Payment',
            'date' => null,
            'status' => 'pending',
            'role' => 'Client'
        ];
    }

    if ($allocation['status'] === 'approved' || $allocation['status'] === 'completed') {
        $timeline[] = [
            'step' => 'Manager Approval',
            'date' => $allocation['updated_at'], // Approximation
            'status' => 'done',
            'role' => 'Manager'
        ];
    } else {
        $timeline[] = [
            'step' => 'Manager Approval',
            'date' => null,
            'status' => ($allocation['status'] == 'rejected') ? 'rejected' : 'pending',
            'role' => 'Manager'
        ];
    }

    if ($allocation['status'] === 'completed') {
        $timeline[] = [
            'step' => 'Allocation Finalized',
            'date' => $allocation['allocated_at'] ?? $allocation['updated_at'],
            'status' => 'done',
            'role' => 'Admin'
        ];
    }

    if (!empty($letterData)) {
        $letterStatus = strtolower((string)($letterData['status'] ?? ''));
        $ldUpdated = (string)($letterData['updated_at'] ?? '');
        if ($ldUpdated !== '') {
            $timeline[] = [
                'step' => 'Letter Draft Saved',
                'date' => $ldUpdated,
                'status' => in_array($letterStatus, ['draft','rejected','changes_requested','pending_chairman_approval','chairman_approved','sent_to_client','accepted_by_client'], true) ? 'done' : 'pending',
                'role' => 'Admin'
            ];
        }
        if (!empty($letterData['sent_to_chairman_at'])) {
            $timeline[] = [
                'step' => 'Sent to Chairman Approval',
                'date' => $letterData['sent_to_chairman_at'],
                'status' => 'done',
                'role' => 'Admin'
            ];
        } elseif (in_array($letterStatus, ['pending_chairman_approval'], true)) {
            $timeline[] = [
                'step' => 'Sent to Chairman Approval',
                'date' => null,
                'status' => 'pending',
                'role' => 'Admin'
            ];
        }
        if (!empty($letterData['chairman_decided_at'])) {
            $decision = strtolower((string)($letterData['chairman_decision'] ?? ''));
            $label = $decision === 'approve' ? 'Chairman Approved' : ($decision === 'request_changes' ? 'Chairman Requested Changes' : 'Chairman Rejected');
            $tone = $decision === 'approve' ? 'done' : ($decision === 'request_changes' ? 'pending' : 'rejected');
            $timeline[] = [
                'step' => $label,
                'date' => $letterData['chairman_decided_at'],
                'status' => $tone,
                'role' => 'Chairman'
            ];
        }
        if (!empty($letterData['sent_to_client_at'])) {
            $timeline[] = [
                'step' => 'Sent to Client Dashboard',
                'date' => $letterData['sent_to_client_at'],
                'status' => 'done',
                'role' => 'Admin'
            ];
        } elseif (in_array($letterStatus, ['sent_to_client'], true)) {
            $timeline[] = [
                'step' => 'Sent to Client Dashboard',
                'date' => null,
                'status' => 'pending',
                'role' => 'Admin'
            ];
        }
        if (!empty($letterData['client_viewed_at'])) {
            $timeline[] = [
                'step' => 'Viewed by Client',
                'date' => $letterData['client_viewed_at'],
                'status' => 'done',
                'role' => 'Client'
            ];
        }
        if (!empty($letterData['client_accepted_at']) || (int)($letterData['client_accepted'] ?? 0) === 1) {
            $timeline[] = [
                'step' => 'Accepted by Client',
                'date' => $letterData['client_accepted_at'] ?? null,
                'status' => 'done',
                'role' => 'Client'
            ];
        } else {
            $timeline[] = [
                'step' => 'Accepted by Client',
                'date' => null,
                'status' => 'pending',
                'role' => 'Client'
            ];
        }
    }

    $instSummary = getInstallmentStatusSummary($pdo, (int)$alloc_id);
    if ($outstanding <= 0.00001 && $total_paid > 0) {
        $instSummary = ['label' => 'Paid', 'class' => 'badge bg-success'];
    }
    echo json_encode([
        'success' => true,
        'allocation' => $allocation,
        'payments' => $payments,
        'installment_summary' => $instSummary,
        'payment_summary' => [
            'total_price' => (float)$grandTotal,
            'total_paid' => (float)$total_paid,
            'outstanding' => (float)$outstanding,
            'status' => $payment_status
        ],
        'billing_settings' => $billingSettings,
        'cost_breakdown' => $computedBilling,
        'letter_data' => $letterData,
        'documents' => $documents,
        'timeline' => $timeline,
        'edit_history' => $edit_history
    ]);

} catch (Exception $e) {
    echo json_encode(['error' => $e->getMessage()]);
}

Youez - 2016 - github.com/yon3zu
LinuXploit