HEX
Server: LiteSpeed
System: Linux s3.sitechai.com 4.18.0-553.51.1.lve.1.el8.x86_64 #1 SMP Wed May 14 14:34:57 UTC 2025 x86_64
User: workzeni (2217)
PHP: 8.1.32
Disabled: mail, show_source, system, shell_exec, passthru, exec, eval, shell
Upload Files
File: /home/workzeni/agency-erp-05.workzenix.com/resources/views/admin/hotel/create.blade.php
@extends('layouts.master')
@section('title', 'Hotel Booking')
@section('content')
    <div class="card">
        <div class="card-header d-flex justify-content-between align-items-center">
            <h5 class="mb-0">Create Hotel Booking</h5>
            <a href="{{ route('hotel.list') }}" class="btn btn-danger btn-sm">Manage Bookings</a>
        </div>

        <div class="card-body">
            <form action="{{ route('hotel.store') }}" method="POST" class="form">
                @csrf

                {{-- ========== Agency / User Selection ========== --}}
                @if (in_array(auth()->user()->role, [1, 2, 3]))
                    <div class="row row-cols-md-2 mt-3">
                        <div class="form-group">
                            <label for="agency_id">Select Agency <span class="text-danger">*</span></label>
                            <select name="agency_id" id="agency_id" class="form-control" required>
                                <option value="" disabled selected>Select Agency</option>
                                @foreach ($agencies as $agency)
                                    <option value="{{ $agency->id }}">{{ $agency->name }}</option>
                                @endforeach
                            </select>
                        </div>

                        <div class="form-group">
                            <label for="user_id">Select User <span class="text-danger">*</span></label>
                            <select name="user_id" id="user_id" class="form-control" required>
                                <option value="" disabled selected>Select User</option>
                            </select>
                        </div>
                    </div>
                @else
                    <input type="hidden" name="agency_id" id="agency_id" value="{{ auth()->user()->company_id }}">
                @endif

                {{-- ========== City Selection ========== --}}
                <div class="d-flex gap-3 align-items-center mt-3">
                    <div class="form-check">
                        <input class="form-check-input" type="radio" name="city" id="cityMakkah" value="makkah">
                        <label class="form-check-label" for="cityMakkah">🕋 Makkah</label>
                    </div>
                    <div class="form-check">
                        <input class="form-check-input" type="radio" name="city" id="cityMadinah" value="madinah">
                        <label class="form-check-label" for="cityMadinah">🕌 Madinah</label>
                    </div>
                </div>

                {{-- ========== Season Selection ========== --}}
                <div class="form-group mt-4">
                    <label for="season_id">Select Season <span class="text-danger">*</span></label>
                    @if ($activeSeasons->count() > 1)
                        <select name="season_id" id="season_id" class="form-control" required>
                            <option value="" disabled selected>Select Season</option>
                            @foreach ($activeSeasons as $season)
                                <option value="{{ $season->id }}">{{ $season->name }}</option>
                            @endforeach
                        </select>
                    @elseif($activeSeasons->count() === 1)
                        @php $season = $activeSeasons->first(); @endphp
                        <input type="hidden" name="season_id" id="season_id" value="{{ $season->id }}">
                        <input type="text" class="form-control" value="{{ $season->name }}" readonly>
                    @else
                        <input type="text" class="form-control" value="No active season" readonly>
                    @endif
                </div>

                {{-- ========== Hotel Details ========== --}}
                <div class="row row-cols-md-2 mt-3">
                    <div class="form-group">
                        <label for="hotel_name">Hotel Name <span class="text-danger">*</span></label>
                        <input type="text" name="hotel_name" id="hotel_name" class="form-control" required>
                    </div>
                    <div class="form-group">
                        <label for="owner_name">Owner Name <span class="text-danger">*</span></label>
                        <input type="text" name="owner_name" id="owner_name" class="form-control" required>
                    </div>
                    <div class="form-group">
                        <label for="representative_name">Representative Name</label>
                        <input type="text" name="representative_name" id="representative_name" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="phone_number">Phone Number</label>
                        <input type="text" name="phone_number" id="phone_number" class="form-control">
                    </div>

                    <div class="form-group">
                        <label for="tasria_owner">Tasria Name</label>
                        <input type="text" name="tasria_owner" id="tasria_owner" class="form-control">
                    </div>

                    <div class="form-group">
                        <label for="tasria_number">Tasria Number</label>
                        <input type="text" name="tasria_number" id="tasria_number" class="form-control">
                    </div>
                </div>

                {{-- ========== Quota Info ========== --}}
                <div class="row row-cols-md-3 mt-3">
                    <div class="form-group">
                        <label for="total_seat">Total Seat <span class="text-danger">*</span></label>
                        <input type="number" name="total_seat" id="total_seat" class="form-control" required
                            min="0">
                    </div>
                    <div class="form-group">
                        <label for="city_quota">Quota Balance (<strong class="city_label">--</strong>)</label>
                        <input type="number" id="city_quota" class="form-control" readonly>
                    </div>
                    <div class="form-group">
                        <label for="used_city_quota">Used Quota (<strong class="city_label">--</strong>)</label>
                        <input type="number" id="used_city_quota" class="form-control" readonly>
                    </div>
                </div>

                {{-- ========== Room Allotment ========== --}}
                <h5 class="mt-4">Room Allotment</h5>
                <div class="row row-cols-md-4 mt-2">
                    @php $roomTypes = ['double'=>2, 'triple'=>3, 'quad'=>4, 'quintuple'=>5]; @endphp
                    @foreach ($roomTypes as $type => $multiplier)
                        <div class="form-group">
                            <label for="{{ $type }}_qty">{{ ucfirst($type) }} Rooms</label>
                            <input type="number" min="0" name="{{ $type }}_qty"
                                id="{{ $type }}_qty" class="form-control room-input"
                                data-multiplier="{{ $multiplier }}">
                            <small>Total: <span id="{{ $type }}_total">0</span> seats</small>
                        </div>
                    @endforeach
                </div>

                {{-- Allocated Seats and Quota Validation --}}
                <div class="row row-cols-md-2 mt-3">
                    <div class="form-group mt-3">
                        <label>Total Allocated Seats</label>
                        <input type="number" class="form-control" id="allocated_seats" name="allocated_seats" readonly>
                        <div class="alert alert-warning d-none mt-2" id="seat_alert">
                            ⚠️ Total allocated seats exceed Total Seat!
                        </div>
                    </div>

                    <div class="form-group mt-3">
                        <label>Overall Quota Check</label>
                        <input type="number" class="form-control" id="quota_check" readonly>
                        <div class="alert alert-warning d-none mt-2" id="quota_alert">
                            ⚠️ <span id="city_name_alert"></span>
                        </div>
                    </div>
                </div>

                <hr>
                {{-- ========== Payable Information ========== --}}
                <h5 class="mt-4">Payable Information</h5>
                <div class="row row-cols-md-2">
                    {{-- <div class="form-group">
                        <label for="subtotal_amount">Total Amount (without tax & VAT) <span class="text-danger">*</span>
                            <span class="sar_balance_display text-muted">(Balance: -- SAR)</span></label>
                        <input type="number" name="subtotal" id="subtotal_amount" class="form-control" step="0.01">
                    </div>
                    <div class="form-group">
                        <label for="total_amount">
                            Total Amount (with tax & VAT) <span class="text-danger">*</span>
                            <span class="sar_balance_display text-muted">(Balance: -- SAR)</span>
                        </label>
                        <input type="number" name="total_amount" id="total_amount" class="form-control" step="0.01">
                        <div id="sar_error" class="invalid-feedback d-none"></div>
                    </div> --}}
                    <div class="form-group">
                        <label for="subtotal_amount">Total Amount (without tax & VAT) <span class="text-danger">*</span>
                            <span class="sar_balance_display text-muted">(Balance: -- SAR)</span></label>
                        <input type="number" name="subtotal" id="subtotal_amount" class="form-control" step="0.01">
                    </div>
                    <div class="form-group">
                        <label for="total_amount">
                            Total Amount (with tax & VAT) <span class="text-danger">*</span>
                            <span class="sar_balance_display text-muted">(Balance: -- SAR)</span>
                        </label>
                        <input type="number" name="total_amount" id="total_amount" class="form-control"
                            step="0.01">
                        <div id="sar_error" class="invalid-feedback d-none"></div>
                    </div>
                </div>

                <button type="submit" class="btn btn-primary mt-4">Submit Booking</button>
            </form>
        </div>
    </div>

    <!-- Preview Modal -->
    <!-- Hotel Booking – Preview Modal -->
    <div class="modal fade" id="bookingPreviewModal" tabindex="-1" aria-hidden="true">
        <div class="modal-dialog modal-xl modal-dialog-centered">
            <div class="modal-content border-0 shadow-lg rounded-3">

                <div class="modal-header bg-primary text-white rounded-top-3">
                    <h5 class="modal-title fw-semibold">
                        <i class="bi bi-building-check me-2"></i>Booking Summary
                    </h5>
                    <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"
                        aria-label="Close"></button>
                </div>

                <div class="modal-body bg-light">
                    <p class="text-muted mb-4">
                        Please review the details below before submitting your booking.
                    </p>

                    <!-- dynamic preview table -->
                    <div id="bookingPreviewContent" class="table-responsive">
                        <!-- Filled by JavaScript -->
                    </div>
                </div>

                <div class="modal-footer bg-light rounded-bottom-4">
                    <button type="button" class="btn btn-outline-secondary px-4" data-bs-dismiss="modal">
                        <i class="bi bi-pencil-square me-1"></i> Edit
                    </button>
                    <button type="button" class="btn btn-primary px-4" id="confirmSubmit">
                        <i class="bi bi-check-circle me-1"></i> Confirm & Submit
                    </button>
                </div>

            </div>
        </div>
    </div>

    {{-- <script>
        document.addEventListener('DOMContentLoaded', function() {
            const form = document.querySelector('form.form');
            const previewContent = document.getElementById('bookingPreviewContent');
            const confirmBtn = document.getElementById('confirmSubmit');

            form.addEventListener('submit', function(e) {
                e.preventDefault(); // stop normal submission

                const fd = new FormData(form);
                let html = `
          <table class="table table-striped table-hover align-middle bg-white rounded">
            <tbody>
        `;

                fd.forEach((value, key) => {
                    const label = key.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
                    html += `
              <tr>
                <th class="w-25 text-primary fw-semibold">${label}</th>
                <td class="text-dark">${value || '<span class="text-muted">—</span>'}</td>
              </tr>
            `;
                });

                html += '</tbody></table>';
                previewContent.innerHTML = html;

                const modal = new bootstrap.Modal(document.getElementById('bookingPreviewModal'));
                modal.show();

                confirmBtn.onclick = () => {
                    modal.hide();
                    form.submit();
                };
            });
        });
    </script> --}}

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const form = document.querySelector('form.form');
            const previewContent = document.getElementById('bookingPreviewContent');
            const confirmBtn = document.getElementById('confirmSubmit');
            const bookingModalEl = document.getElementById('bookingPreviewModal');
            const bookingModal = new bootstrap.Modal(bookingModalEl);

            form.addEventListener('submit', function(e) {
                e.preventDefault(); // stop normal submit for preview

                const fd = new FormData(form);
                let html =
                    `<table class="table table-striped table-hover align-middle bg-white rounded"><tbody>`;

                fd.forEach((value, key) => {
                    // Skip fields we never want to preview
                    if (['_token', 'user_id'].includes(key)) return;

                    let label = '';
                    let displayValue = value || '<span class="text-muted">—</span>';

                    // Custom labels / lookups
                    switch (key) {
                        case 'agency_id':
                            label = 'Agency';
                            const agencySelect = document.getElementById('agency_id');
                            if (agencySelect) {
                                // works for both select or hidden input
                                if (agencySelect.tagName === 'SELECT') {
                                    const opt = agencySelect.querySelector(
                                        `option[value="${value}"]`);
                                    if (opt) displayValue = opt.textContent.trim();
                                } else {
                                    // hidden input – get agency name from the single option text if present
                                    const singleOpt = document.querySelector(
                                        '#agency_id option[value="' + value + '"]');
                                    if (singleOpt) displayValue = singleOpt.textContent.trim();
                                }
                            }
                            break;

                        case 'season_id':
                            label = 'Season';
                            const seasonEl = document.getElementById('season_id');
                            if (seasonEl) {
                                if (seasonEl.tagName === 'SELECT') {
                                    // multi-season: take selected option text
                                    const opt = seasonEl.querySelector(`option[value="${value}"]`);
                                    if (opt) displayValue = opt.textContent.trim();
                                } else {
                                    // single-season: look for the readonly text input that shows name
                                    const readOnlyText = seasonEl
                                        .closest('.form-group')
                                        ?.querySelector('input[readonly]');
                                    if (readOnlyText) displayValue = readOnlyText.value.trim();
                                }
                            }
                            break;

                        default:
                            label = key.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
                    }


                    html += `
                <tr>
                    <th class="w-25 text-primary fw-semibold">${label}</th>
                    <td class="text-dark">${displayValue}</td>
                </tr>
            `;
                });

                html += '</tbody></table>';
                previewContent.innerHTML = html;

                bookingModal.show();
            });

            confirmBtn.addEventListener('click', function() {
                bookingModal.hide();
                // small delay to let modal close animation finish
                setTimeout(() => form.submit(), 200);
            });
        });
    </script>





    {{-- ========== JavaScript ========== --}}
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            /* ---------- Seat calculation ---------- */
            const roomInputs = document.querySelectorAll('.room-input');
            const allocated = document.getElementById('allocated_seats');
            const totalSeat = document.getElementById('total_seat');
            const seatAlert = document.getElementById('seat_alert');

            function calcSeats() {
                let total = 0;
                roomInputs.forEach(i => {
                    const qty = parseInt(i.value) || 0;
                    const mult = parseInt(i.dataset.multiplier);
                    const subtotal = qty * mult;
                    document.getElementById(i.id.replace('_qty', '') + '_total').textContent = subtotal;
                    total += subtotal;
                });
                allocated.value = total;
                seatAlert.classList.toggle('d-none', total <= (parseInt(totalSeat.value) || 0));
                calcQuota();
            }
            roomInputs.forEach(i => i.addEventListener('input', calcSeats));
            totalSeat.addEventListener('input', calcSeats);

            /* ---------- Agency / User fetch ---------- */
            const agencySelect = document.getElementById('agency_id');
            const userSelect = document.getElementById('user_id');
            agencySelect?.addEventListener('change', () => {
                if (!userSelect) return;
                userSelect.innerHTML = '<option>Loading...</option>';
                fetch(`/admin/payment/get-users/${agencySelect.value}`)
                    .then(r => r.json())
                    .then(d => {
                        userSelect.innerHTML = d.length ?
                            '<option value="">Select User</option>' :
                            '<option>No users found</option>';
                        d.forEach(u =>
                            userSelect.innerHTML +=
                            `<option value="${u.id}">${u.name} (${u.phone ?? ''})</option>`
                        );
                        loadCityQuota();
                    })
                    .catch(() => userSelect.innerHTML = '<option>Error loading users</option>');
            });

            /* ---------- Quota info ---------- */
            const seasonSelect = document.getElementById('season_id');
            const cityRadios = document.querySelectorAll('input[name="city"]');
            const quotaInput = document.getElementById('city_quota');
            const usedQuotaInput = document.getElementById('used_city_quota');
            const cityLabels = document.querySelectorAll('.city_label');

            let extraQuota = 0;

            function selectedCity() {
                const checked = document.querySelector('input[name="city"]:checked');
                return checked ? checked.value : null;
            }

            function setCityLabel(label) {
                cityLabels.forEach(l => l.textContent = label || '--');
            }

            function loadCityQuota() {
                const agencyId = agencySelect?.value;
                const seasonId = seasonSelect?.value;
                const city = selectedCity();
                if (!agencyId || !seasonId || !city) {
                    setCityLabel('--');
                    quotaInput.value = usedQuotaInput.value = '';
                    return;
                }
                fetch(`/get-quota-by-agency?agency_id=${agencyId}&season_id=${seasonId}`)
                    .then(r => r.json())
                    .then(d => {
                        let quota = 0,
                            used = 0,
                            label = '';
                        if (city === 'makkah') {
                            quota = d.makka_qouta ?? 0;
                            used = d.makka_used_qouta ?? 0;
                            label = 'Makkah';
                            extraQuota = d.makka_extra_qouta ?? 0;
                        } else {
                            quota = d.modina_qouta ?? 0;
                            used = d.modina_used_qouta ?? 0;
                            label = 'Madinah';
                            extraQuota = d.modina_extra_qouta ?? 0;
                        }
                        setCityLabel(label);
                        quotaInput.value = quota;
                        usedQuotaInput.value = used;
                        calcQuota();
                    });
            }
            agencySelect?.addEventListener('change', loadCityQuota);
            seasonSelect?.addEventListener('change', loadCityQuota);
            cityRadios.forEach(r => r.addEventListener('change', loadCityQuota));

            /* ---------- Quota check with detailed alert ---------- */
            const quotaCheck = document.getElementById('quota_check');
            const quotaAlert = document.getElementById('quota_alert');
            const cityNameAlert = document.getElementById('city_name_alert');

            function calcQuota() {
                const allocatedSeats = parseInt(allocated.value) || 0;
                const used = parseInt(usedQuotaInput.value) || 0;
                const quota = parseInt(quotaInput.value) || 0;
                const totalAllowed = quota + (parseInt(extraQuota) || 0);
                const cityName = selectedCity() === 'madinah' ? 'Madinah' :
                    selectedCity() === 'makkah' ? 'Makkah' : '';
                quotaCheck.value = allocatedSeats + used;

                if ((allocatedSeats + used) > totalAllowed) {
                    const diff = (allocatedSeats + used - quota) + (parseInt(extraQuota) || 0);
                    cityNameAlert.textContent =
                        `${cityName}: Over Extra Quota  ${diff}`;
                    quotaAlert.classList.remove('d-none');
                } else {
                    quotaAlert.classList.add('d-none');
                }
            }
            calcSeats();
            validatePayable();
        });
    </script>

    {{-- <script>
        document.addEventListener('DOMContentLoaded', function() {

            /* ---------- existing variables ---------- */
            const subtotalInput = document.getElementById('subtotal_amount');
            const totalInput = document.getElementById('total_amount');
            const sarDisplay = document.getElementByClass('sar_balance_display');
            const sarError = document.getElementById('sar_error');
            const agencySelect = document.getElementById('agency_id');

            let agencySarBalance = 0; // 💡 will be filled from server

            /* ---------- fetch SAR balance when agency changes ---------- */
            function loadAgencySarBalance() {
                const agencyId = agencySelect?.value;
                if (!agencyId) return;

                fetch(`/get-agency-sar-balance/${agencyId}`)
                    .then(r => r.json())
                    .then(d => {
                        agencySarBalance = parseFloat(d.sar_balance ?? 0);
                        sarDisplay.textContent = `(Balance: ${agencySarBalance.toFixed(2)} SAR)`;
                        validatePayable(); // re-check current input
                    })
                    .catch(() => {
                        agencySarBalance = 0;
                        sarDisplay.textContent = '(Balance: -- SAR)';
                    });
            }

            agencySelect?.addEventListener('change', loadAgencySarBalance);

            subtotalInput.addEventListener('input', validatePayable);
            totalInput.addEventListener('input', validatePayable);

            // Initial call (if agency already pre-selected)
            loadAgencySarBalance();
            // validatePayable();
        });
    </script>

    <script>
        let sarBalance = 0;

        function fetchAgencyBalance(agencyId) {
            if (!agencyId) return;

            fetch(`/get-agency-balance/${agencyId}`)
                .then(response => response.json())
                .then(data => {
                    sarBalance = parseFloat(data.sar_acct || 0);
                    document.getElementByClass('sar_balance_display').textContent =
                        `(Balance: ${sarBalance.toFixed(2)} SAR)`;

                    const totalAmountInput = document.getElementById('total_amount');
                    const currentSAR = parseFloat(totalAmountInput.value) || 0;

                    if (currentSAR > sarBalance) {
                        showSarError(`SAR amount cannot exceed ${sarBalance}`);
                        disableSubmit();
                    } else {
                        hideSarError();
                        enableSubmit();
                    }
                })
                .catch(() => {
                    sarBalance = 0;
                    document.getElementByClass('sar_balance_display').textContent = `(Balance: --.-- SAR)`;
                    showSarError('Could not load SAR balance.');
                    disableSubmit();
                });
        }

        function showSarError(message) {
            const errorDiv = document.getElementById('sar_error');
            errorDiv.textContent = message;
            errorDiv.classList.remove('d-none');
            document.getElementById('total_amount').classList.add('is-invalid');
        }

        function hideSarError() {
            const errorDiv = document.getElementById('sar_error');
            errorDiv.classList.add('d-none');
            errorDiv.textContent = '';
            document.getElementById('total_amount').classList.remove('is-invalid');
        }

        function disableSubmit() {
            document.querySelector('button[type="submit"]').disabled = true;
        }

        function enableSubmit() {
            document.querySelector('button[type="submit"]').disabled = false;
        }

        document.addEventListener('DOMContentLoaded', function() {
            const agencyInput = document.getElementById('agency_id');

            if (agencyInput && agencyInput.value) {
                fetchAgencyBalance(agencyInput.value);
            }

            agencyInput?.addEventListener('change', function() {
                fetchAgencyBalance(this.value);
            });

            document.getElementById('total_amount').addEventListener('input', function() {
                const entered = parseFloat(this.value) || 0;
                if (entered > sarBalance) {
                    showSarError(`SAR amount cannot exceed ${sarBalance}`);
                    disableSubmit();
                } else {
                    hideSarError();
                    enableSubmit();
                }



            });
        });
    </script> --}}

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const subtotalInput = document.getElementById('subtotal_amount');
            const totalInput = document.getElementById('total_amount');
            const sarDisplays = document.querySelectorAll('.sar_balance_display'); // multiple elements
            const sarError = document.getElementById('sar_error');
            const agencySelect = document.getElementById('agency_id');
            let sarBalance = 0;

            // Update all balance display spans
            function updateSarDisplay(balance) {
                sarDisplays.forEach(el => {
                    el.textContent = `(Balance: ${balance ? balance.toFixed(2) : '--'} SAR)`;
                });
            }

            function showSarError(message) {
                sarError.textContent = message;
                sarError.classList.remove('d-none');
                totalInput.classList.add('is-invalid');
                disableSubmit();
            }

            function hideSarError() {
                sarError.textContent = '';
                sarError.classList.add('d-none');
                totalInput.classList.remove('is-invalid');
                enableSubmit();
            }

            function disableSubmit() {
                const btn = document.querySelector('button[type="submit"]');
                if (btn) btn.disabled = true;
            }

            function enableSubmit() {
                const btn = document.querySelector('button[type="submit"]');
                if (btn) btn.disabled = false;
            }

            function validatePayable() {
                const entered = parseFloat(totalInput.value) || 0;
                if (entered > sarBalance) {
                    showSarError(`SAR amount cannot exceed ${sarBalance.toFixed(2)}`);
                } else {
                    hideSarError();
                }
            }

            function fetchAgencyBalance(agencyId) {
                if (!agencyId) return;

                fetch(`/get-agency-balance/${agencyId}`)
                    .then(res => res.json())
                    .then(data => {
                        sarBalance = parseFloat(data.sar_acct ?? 0);
                        updateSarDisplay(sarBalance);
                        validatePayable();
                    })
                    .catch(() => {
                        sarBalance = 0;
                        updateSarDisplay(null);
                        showSarError('Could not load SAR balance.');
                    });
            }

            // Events
            agencySelect?.addEventListener('change', () => fetchAgencyBalance(agencySelect.value));
            totalInput.addEventListener('input', validatePayable);
            subtotalInput.addEventListener('input', validatePayable);

            // Initial load
            if (agencySelect && agencySelect.value) {
                fetchAgencyBalance(agencySelect.value);
            }
        });
    </script>




@endsection