Tul xxx Tul
User / IP
:
216.73.216.191
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
gimnasiofitnes
/
app
/
Views
/
admin
/
memberships
/
Viewing: new.php
<?= $this->extend('layout/app'); ?> <?php $this->section('title'); ?> Nueva Membresía <?php $this->endSection(); ?> <?php $this->section('content'); ?> <style> .membership-client-picker .form-label { letter-spacing: 0.02em; } /* El desplegable va FUERA del input-group: nunca poner overflow:hidden en el contenedor del dropdown */ .membership-search-anchor { position: relative; z-index: 1; overflow: visible; } .modal-open .membership-client-picker { z-index: 0 !important; } .modal-open .membership-client-picker .membership-search-input-bar { visibility: hidden; } .membership-client-picker .membership-search-input-bar { border-radius: 12px; overflow: hidden; border: 1px solid #e5e7eb; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.04); transition: box-shadow .2s, border-color .2s; } .membership-client-picker .membership-search-input-bar:focus-within { border-color: #0a0a0a; box-shadow: 0 0 0 3px rgba(10,10,10,.08); } .membership-client-picker .input-group-text { border: 0; background: #f9fafb; color: #374151; padding-left: 1rem; } .membership-client-picker #client_search { border: 0; padding-left: 0.25rem; font-size: 0.95rem; } .membership-client-picker #client_search:focus { box-shadow: none; } .membership-client-picker .btn-client-action { border: 0; border-left: 1px solid #e5e7eb !important; padding: 0 1rem; display: inline-flex; align-items: center; justify-content: center; min-width: 3rem; transition: background .15s, color .15s; } .membership-client-picker .btn-client-search { background: #f9fafb; color: #111827; } .membership-client-picker .btn-client-search:hover { background: #e5e7eb; color: #000; } .membership-client-picker #client_search.is-loading { background-image: linear-gradient(90deg, #f3f4f6 25%, #e5e7eb 50%, #f3f4f6 75%); background-size: 200% 100%; animation: membershipSearchShimmer 1s ease-in-out infinite; } @keyframes membershipSearchShimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } } .membership-search-dropdown { border-radius: 12px; border: 1px solid #e5e7eb; box-shadow: 0 10px 40px -10px rgba(0,0,0,.12), 0 4px 12px rgba(0,0,0,.06); overflow: hidden; background: #fff; } .membership-search-dropdown .membership-search-meta { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: #6b7280; padding: 0.5rem 0.75rem; background: #f9fafb; border-bottom: 1px solid #e5e7eb; } .membership-search-dropdown .list-group-item { border: 0; border-bottom: 1px solid #f3f4f6; padding: 0.65rem 0.85rem; transition: background .12s ease; } .membership-search-dropdown .list-group-item:last-child { border-bottom: 0; } .membership-search-dropdown .list-group-item-action:hover, .membership-search-dropdown .list-group-item-action:focus { background: #f9fafb; } .membership-search-dropdown .list-group-item.is-active { background: #111827; color: #fff; } .membership-search-dropdown .list-group-item.is-active .text-dark, .membership-search-dropdown .list-group-item.is-active .text-muted, .membership-search-dropdown .list-group-item.is-active .text-secondary { color: #fff !important; opacity: 0.92; } .membership-search-dropdown .list-group-item.is-active .bg-light { background: rgba(255,255,255,.14) !important; } .membership-search-dropdown .list-group-item.is-active mark { background: #fde68a; color: #111827; } .membership-search-dropdown mark { background: #fef08a; color: inherit; padding: 0 0.1em; border-radius: 2px; } .membership-search-no-match { padding: 1.25rem 1rem; text-align: center; background: linear-gradient(160deg, #fafafa 0%, #fff 55%, #f9fafb 100%); } .membership-search-dropdown .list-group-item[disabled] { cursor: not-allowed; background: #fafafa; opacity: 0.65; } .membership-search-no-match .query-chip { display: inline-block; margin-top: 0.35rem; padding: 0.25rem 0.65rem; border-radius: 999px; background: #f3f4f6; border: 1px dashed #d1d5db; font-weight: 600; color: #111827; max-width: 100%; word-break: break-word; } .modal-search-client .modal-header { border: 0; padding-bottom: 0; background: linear-gradient(135deg, #0a0a0a 0%, #1f2937 100%); color: #fff; border-radius: 0.5rem 0.5rem 0 0; } .modal-search-client .modal-content { border: none; border-radius: 0.75rem; overflow: hidden; box-shadow: 0 25px 50px -12px rgba(0,0,0,.25); } .modal-search-client .empty-clients-card { border-radius: 16px; border: 1px dashed #e5e7eb; background: linear-gradient(180deg, #fafafa 0%, #fff 100%); padding: 2.5rem 1.5rem; text-align: center; } .modal-search-client .empty-clients-card .empty-icon { width: 72px; height: 72px; margin: 0 auto 1rem; border-radius: 50%; background: linear-gradient(135deg, #ecfdf5, #d1fae5); display: flex; align-items: center; justify-content: center; font-size: 2rem; color: #059669; } #search_results { position: absolute !important; top: calc(100% + 8px) !important; left: 0 !important; right: auto !important; width: 100% !important; z-index: 1055 !important; max-height: 320px; overflow-y: auto; overflow-x: hidden; } </style> <div class="app-title"> <div> <h1><i class="bi bi-credit-card"></i> Membresia</h1> <p>Nueva Membresia</p> </div> <ul class="app-breadcrumb breadcrumb"> <li class="breadcrumb-item"><i class="bi bi-house-door fs-6"></i></li> <li class="breadcrumb-item"><a href="<?= base_url('admin'); ?>">Admin</a></li> <li class="breadcrumb-item"><a href="#">Membresia</a></li> </ul> </div> <div class="card overflow-visible"> <div class="card-body overflow-visible"> <h6 class="card-title">Nueva Membresía</h6> <hr> <?php if (session()->get('errors')) : ?> <div class="alert alert-danger"> <ul> <?php foreach (session()->get('errors') as $error) : ?> <li><?= esc($error) ?></li> <?php endforeach ?> </ul> </div> <?php endif; ?> <form action="<?= base_url('admin/memberships'); ?>" method="post"> <?= csrf_field() ?> <div class="row"> <div class="mb-3 col-md-6 membership-client-picker" style="overflow: visible;"> <label for="client_search" class="form-label">Cliente</label> <div class="membership-search-anchor"> <div class="input-group membership-search-input-bar"> <span class="input-group-text"><i class="bi bi-person"></i></span> <input type="text" class="form-control" id="client_search" placeholder="Nombre, apellido, DNI o teléfono…" autocomplete="off" aria-describedby="client_search_help" aria-autocomplete="list" aria-controls="search_results"> <input type="hidden" id="user_id" name="user_id" value="<?= old('user_id') ?>"> <button class="btn btn-client-action btn-client-search" type="button" id="btnSearchLupa" title="Ver todos en tabla"> <i class="bi bi-search"></i> </button> </div> <div id="search_results" role="listbox" style="display:none; min-width:280px;"></div> </div> </div> <div class="mb-3 col-md-6"> <label for="membership_type_id" class="form-label">Tipo de Membresía</label> <select class="form-select" id="membership_type_id" name="membership_type_id"> <option value="">Seleccione un tipo de membresía</option> <?php foreach ($membership_types as $type) : ?> <option value="<?= $type['id'] ?>" <?= old('membership_type_id') == $type['id'] ? 'selected' : '' ?>> <?= esc($type['name'] . ' - ' . $type['duration']) ?> </option> <?php endforeach; ?> </select> </div> <div class="mb-3 col-md-3"> <label for="amount" class="form-label">Monto</label> <input type="text" class="form-control" id="amount" name="amount" value="<?= old('amount') ?>" placeholder="0.00" readonly> </div> <div class="mb-3 col-md-3"> <label for="discount_type" class="form-label">Tipo Descuento</label> <input type="text" class="form-control" id="discount_type" name="discount_type" value="<?= old('discount_type') ?>" placeholder="Tipo" readonly> </div> <div class="mb-3 col-md-3"> <label for="discount_value" class="form-label">Descuento</label> <input type="text" class="form-control" id="discount_value" name="discount_value" value="<?= old('discount_value') ?>" placeholder="0.00" readonly> </div> <div class="mb-3 col-md-3"> <label for="amount_pait" class="form-label">Monto Final</label> <input type="text" class="form-control" id="amount_pait" name="amount_pait" value="<?= old('amount_pait') ?>" placeholder="Monto Final" readonly> </div> <div class="mb-3 col-md-4"> <label for="box_id" class="form-label">Caja *</label> <select class="form-select" id="box_id" name="box_id"> <option value="">Seleccionar</option> <?php foreach ($boxes as $box) { ?> <option value="<?= $box['id']; ?>"><?= $box['name'] . ' - ' . $box['opening_date']; ?></option> <?php } ?> </select> </div> <div class="mb-3 col-md-4"> <label for="payment_method_id" class="form-label">Método de Pago</label> <select class="form-select" id="payment_method_id" name="payment_method_id"> <option value="">Seleccione un método de pago</option> <?php foreach ($payment_methods as $method) : ?> <option value="<?= $method['id'] ?>" <?= old('payment_method_id') == $method['id'] ? 'selected' : '' ?>> <?= esc($method['name']) ?> </option> <?php endforeach; ?> </select> </div> <div class="mb-3 col-md-4"> <label for="payment_type" class="form-label">Tipo de Venta <span class="text-danger">*</span></label> <select class="form-select" id="payment_type" name="payment_type" required> <option value="contado" <?= old('payment_type') == 'contado' ? 'selected' : '' ?>>Contado</option> <option value="credito" <?= old('payment_type') == 'credito' ? 'selected' : '' ?>>Crédito</option> </select> </div> <div class="mb-3 col-md-4" id="div_initial_payment" style="display: none;"> <label for="initial_payment" class="form-label">Abono Inicial</label> <div class="input-group"> <span class="input-group-text"><?= get_currency() ?></span> <input type="number" step="0.01" class="form-control" id="initial_payment" name="initial_payment" value="<?= old('initial_payment', 0) ?>" placeholder="0.00"> </div> </div> <div class="mb-3 col-md-4"> <label for="start_date" class="form-label">Fecha de Inicio</label> <input type="date" class="form-control" id="start_date" name="start_date" value="<?= old('start_date') ?>"> </div> <div class="mb-3 col-md-4"> <label for="end_date" class="form-label">Fecha de Fin</label> <input type="date" class="form-control" id="end_date" name="end_date" value="<?= old('end_date') ?>"> </div> <div class="mb-3 col-md-4"> <label for="status" class="form-label">Estado</label> <select class="form-select" id="status" name="status"> <option value="">Seleccione un estado</option> <option value="active" <?= old('status') == 'active' ? 'selected' : '' ?>>Activo</option> <option value="inactive" <?= old('status') == 'inactive' ? 'selected' : '' ?>>Inactivo</option> </select> </div> </div> <div class="row mt-4"> <div class="col-md-12"> <div class="card border-primary mb-3"> <div class="card-header bg-primary text-white"> <h5 class="card-title mb-0"><i class="bi bi-info-circle"></i> Resumen de la Operación</h5> </div> <div class="card-body"> <div class="row text-center"> <div class="col-md-3"> <h6>Total a Pagar</h6> <h4 id="summary_total"><?= get_currency() ?> 0.00</h4> </div> <div class="col-md-3"> <h6>Tipo de Venta</h6> <h4 id="summary_type">Contado</h4> </div> <div class="col-md-3"> <h6>Monto Recibido</h6> <h4 id="summary_paid"><?= get_currency() ?> 0.00</h4> </div> <div class="col-md-3"> <h6>Saldo Pendiente</h6> <h4 id="summary_balance" class="text-danger"><?= get_currency() ?> 0.00</h4> </div> </div> </div> </div> </div> </div> <div class="text-end"> <a href="<?= base_url('admin/memberships'); ?>" class="btn btn-danger">Cancelar</a> <button type="submit" class="btn btn-primary">Crear Membresía</button> </div> </form> </div> </div> <!-- Modal: elegir cliente --> <div class="modal fade modal-search-client" id="modalSearchCliente" tabindex="-1" aria-labelledby="modalSearchClienteLabel" aria-hidden="true"> <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable"> <div class="modal-content"> <div class="modal-header"> <div> <h5 class="modal-title" id="modalSearchClienteLabel"><i class="bi bi-people me-2"></i>Elegir cliente</h5> <p class="mb-0 small opacity-75">Busca en la tabla o selecciona una fila para continuar.</p> </div> <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Cerrar"></button> </div> <div class="modal-body pt-3"> <div id="wrapTableSearchClients" class="table-responsive-wrap"> <div class="table-responsive"> <table class="table table-hover align-middle w-100" id="tblSearchClients" style="width:100%"> <thead class="table-light"> <tr> <th>DNI</th> <th>Nombre completo</th> <th>Teléfono</th> <th width="120"></th> </tr> </thead> <tbody></tbody> </table> </div> </div> <div id="modalSearchEmptyWrap" class="d-none"> <div class="empty-clients-card"> <div class="empty-icon"><i class="bi bi-inbox"></i></div> <h5 class="fw-semibold mb-2">No hay clientes disponibles</h5> <p class="text-muted mb-4 small">Registra clientes desde el menú <strong>Clientes</strong> y vuelve aquí para asignar la membresía.</p> <a href="<?= base_url('admin/clients/new') ?>" class="btn btn-dark rounded-pill px-4"> <i class="bi bi-person-plus me-1"></i> Ir a nuevo cliente </a> </div> </div> </div> </div> </div> </div> <?php $this->endSection(); ?> <?php $this->section('js'); ?> <script> const eligibleClientsUrl = '<?= base_url('admin/memberships/eligible-clients') ?>'; const client_search = document.querySelector('#client_search'); const user_id = document.querySelector('#user_id'); const search_results = document.querySelector('#search_results'); const membership_type_id = document.querySelector('#membership_type_id'); const start_date = document.querySelector('#start_date'); const end_date = document.querySelector('#end_date'); const payment_type = document.querySelector('#payment_type'); const div_initial_payment = document.querySelector('#div_initial_payment'); const initial_payment = document.querySelector('#initial_payment'); const amount = document.querySelector('#amount'); const discount_type = document.querySelector('#discount_type'); const discount_value = document.querySelector('#discount_value'); const amount_pait = document.querySelector('#amount_pait'); const summary_total = document.querySelector('#summary_total'); const summary_type = document.querySelector('#summary_type'); const summary_paid = document.querySelector('#summary_paid'); const summary_balance = document.querySelector('#summary_balance'); document.addEventListener('DOMContentLoaded', function() { const membershipSearchAnchor = document.querySelector('.membership-search-anchor'); const modalTableBody = document.querySelector('#tblSearchClients tbody'); const modalEmptyWrap = document.getElementById('modalSearchEmptyWrap'); const modalTableWrap = document.getElementById('wrapTableSearchClients'); const modalSearchClienteEl = document.getElementById('modalSearchCliente'); const modalSearchCliente = typeof bootstrap !== 'undefined' && modalSearchClienteEl ? new bootstrap.Modal(modalSearchClienteEl) : null; let activeDropdownIndex = -1; let searchDebounceTimer = null; let searchAbort = null; let searchClienteModalVisible = false; let emptyClientsSwalShown = false; function positionDropdown() { search_results.style.width = membershipSearchAnchor.offsetWidth + 'px'; } function escapeHtml(str) { const d = document.createElement('div'); d.textContent = str == null ? '' : String(str); return d.innerHTML; } function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } function highlightMatch(text, query) { const safe = escapeHtml(String(text == null ? '' : text)); const needle = (query || '').trim(); if (!needle) { return safe; } try { const re = new RegExp('(' + escapeRegExp(needle) + ')', 'gi'); return safe.replace(re, '<mark>$1</mark>'); } catch (e) { return safe; } } function getSelectableOptions() { return Array.from(search_results.querySelectorAll('[data-client-id]')); } function setActiveDropdownOption(index) { const options = getSelectableOptions(); activeDropdownIndex = -1; options.forEach(function(option, idx) { const isActive = idx === index; option.classList.toggle('is-active', isActive); option.setAttribute('aria-selected', isActive ? 'true' : 'false'); if (isActive) { activeDropdownIndex = idx; option.scrollIntoView({ block: 'nearest' }); } }); } function resetActiveDropdownOption() { setActiveDropdownOption(-1); } function hideClientSearchDropdown() { search_results.style.display = 'none'; search_results.innerHTML = ''; resetActiveDropdownOption(); } async function fetchEligibleClients(query) { if (searchAbort) { searchAbort.abort(); } searchAbort = new AbortController(); const url = query ? eligibleClientsUrl + '?q=' + encodeURIComponent(query) : eligibleClientsUrl; const res = await fetch(url, { credentials: 'same-origin', headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' }, signal: searchAbort.signal }); if (!res.ok) { throw new Error('HTTP ' + res.status); } const ct = res.headers.get('content-type') || ''; if (!ct.includes('application/json')) { throw new Error('Respuesta no JSON'); } return await res.json(); } function renderClientOption(client, query) { const nameLine = [client.name, client.lastname].filter(Boolean).join(' '); return '' + '<button type="button" class="list-group-item list-group-item-action text-start" role="option" data-client-id="' + escapeHtml(client.id) + '" data-client-label="' + escapeHtml((client.dni || '') + ' — ' + nameLine.trim()) + '">' + '<div class="d-flex align-items-start gap-2">' + '<span class="rounded-circle bg-light d-flex align-items-center justify-content-center flex-shrink-0" style="width:36px;height:36px;"><i class="bi bi-person text-secondary"></i></span>' + '<div class="flex-grow-1 min-w-0">' + '<div class="fw-semibold text-dark">' + highlightMatch(nameLine, query) + '</div>' + '<div class="small text-muted">' + '<span class="me-2"><i class="bi bi-credit-card-2-front"></i> ' + highlightMatch(client.dni || '—', query) + '</span>' + (client.phone ? '<span><i class="bi bi-telephone"></i> ' + highlightMatch(client.phone, query) + '</span>' : '') + '</div>' + '</div>' + '<i class="bi bi-chevron-right text-muted opacity-50 mt-1"></i>' + '</div>' + '</button>'; } function bindDropdownSelection() { search_results.querySelectorAll('[data-client-id]').forEach(function(item) { item.addEventListener('click', function() { selectClient(this.getAttribute('data-client-id'), this.getAttribute('data-client-label')); }); }); } async function runClientSearch(queryValue) { const query = (queryValue || '').trim(); if (!query) { hideClientSearchDropdown(); client_search.classList.remove('is-loading'); return; } client_search.classList.add('is-loading'); let rows = []; try { rows = await fetchEligibleClients(query); } catch (err) { if (err.name === 'AbortError') { return; } hideClientSearchDropdown(); return; } finally { client_search.classList.remove('is-loading'); } rows = Array.isArray(rows) ? rows : []; const wrap = document.createElement('div'); wrap.className = 'membership-search-dropdown'; const meta = document.createElement('div'); meta.className = 'membership-search-meta'; meta.textContent = rows.length + ' resultado' + (rows.length === 1 ? '' : 's'); wrap.appendChild(meta); if (!rows.length) { const empty = document.createElement('div'); empty.className = 'membership-search-no-match border-top'; empty.innerHTML = '<div class="fw-semibold text-dark mb-1">No encontramos coincidencias</div>' + '<p class="small text-muted mb-0">Sigue escribiendo o usa la lupa para ver todos los clientes disponibles.</p>'; wrap.appendChild(empty); } else { const list = document.createElement('div'); list.className = 'list-group list-group-flush'; rows.forEach(function(client) { list.insertAdjacentHTML('beforeend', renderClientOption(client, query)); }); wrap.appendChild(list); } search_results.innerHTML = ''; search_results.appendChild(wrap); bindDropdownSelection(); resetActiveDropdownOption(); positionDropdown(); search_results.style.display = 'block'; } function selectClient(id, text) { user_id.value = id; client_search.value = text; hideClientSearchDropdown(); client_search.classList.add('is-valid'); setTimeout(function() { client_search.classList.remove('is-valid'); }, 1500); } function renderModalClients(rows) { const clients = Array.isArray(rows) ? rows : []; modalTableBody.innerHTML = ''; if (!clients.length) { modalEmptyWrap.classList.remove('d-none'); modalTableWrap.classList.add('d-none'); if (!emptyClientsSwalShown && searchClienteModalVisible && typeof Swal !== 'undefined') { emptyClientsSwalShown = true; Swal.fire({ title: 'No hay clientes disponibles', html: '<div class="text-start small text-muted">Aún no hay clientes sin membresía para asignar en este momento.</div>', icon: 'info', iconColor: '#059669', confirmButtonText: 'Entendido', confirmButtonColor: '#0a0a0a' }); } return; } modalEmptyWrap.classList.add('d-none'); modalTableWrap.classList.remove('d-none'); clients.forEach(function(row) { const tr = document.createElement('tr'); const label = ((row.dni || '') + ' — ' + (row.name || '') + ' ' + (row.lastname || '')).trim(); tr.innerHTML = '' + '<td>' + escapeHtml(row.dni || '—') + '</td>' + '<td>' + escapeHtml(((row.lastname || '') + ' ' + (row.name || '')).trim() || '—') + '</td>' + '<td>' + escapeHtml(row.phone || '—') + '</td>' + '<td class="text-end"><button type="button" class="btn btn-dark btn-sm rounded-pill px-3 btn-select-client-modal">Elegir</button></td>'; tr.addEventListener('dblclick', function() { selectClient(row.id, label); if (modalSearchCliente) { modalSearchCliente.hide(); } }); tr.querySelector('.btn-select-client-modal').addEventListener('click', function() { selectClient(row.id, label); if (modalSearchCliente) { modalSearchCliente.hide(); } }); modalTableBody.appendChild(tr); }); } async function loadModalClients() { try { const rows = await fetchEligibleClients(''); renderModalClients(rows); } catch (err) { modalTableBody.innerHTML = ''; modalEmptyWrap.classList.remove('d-none'); modalTableWrap.classList.add('d-none'); } } window.addEventListener('resize', function() { if (search_results.style.display !== 'none') { positionDropdown(); } }); window.addEventListener('scroll', function() { if (search_results.style.display !== 'none') { positionDropdown(); } }, true); if (modalSearchClienteEl) { modalSearchClienteEl.addEventListener('shown.bs.modal', function() { hideClientSearchDropdown(); searchClienteModalVisible = true; loadModalClients(); }); modalSearchClienteEl.addEventListener('hidden.bs.modal', function() { searchClienteModalVisible = false; }); } document.getElementById('btnSearchLupa').addEventListener('click', function() { hideClientSearchDropdown(); if (modalSearchCliente) { modalSearchCliente.show(); } }); client_search.addEventListener('input', function() { const raw = this.value; user_id.value = ''; clearTimeout(searchDebounceTimer); searchDebounceTimer = setTimeout(function() { runClientSearch(raw); }, 180); }); client_search.addEventListener('keydown', function(e) { const options = getSelectableOptions(); if (e.key === 'ArrowDown') { if (search_results.style.display === 'none') { if (!this.value.trim()) { return; } runClientSearch(this.value); return; } if (!options.length) { return; } e.preventDefault(); const nextIndex = activeDropdownIndex < options.length - 1 ? activeDropdownIndex + 1 : 0; setActiveDropdownOption(nextIndex); return; } if (e.key === 'ArrowUp') { if (!options.length) { return; } e.preventDefault(); const prevIndex = activeDropdownIndex > 0 ? activeDropdownIndex - 1 : options.length - 1; setActiveDropdownOption(prevIndex); return; } if (e.key === 'Enter') { if (search_results.style.display !== 'none' && activeDropdownIndex >= 0 && options[activeDropdownIndex]) { e.preventDefault(); options[activeDropdownIndex].click(); } return; } if (e.key === 'Escape') { hideClientSearchDropdown(); } }); document.addEventListener('click', function(e) { if (membershipSearchAnchor && !membershipSearchAnchor.contains(e.target) && !search_results.contains(e.target)) { hideClientSearchDropdown(); } }); payment_type.addEventListener('change', function() { if (this.value === 'credito') { div_initial_payment.style.display = 'block'; initial_payment.setAttribute('required', 'required'); initial_payment.value = '0.00'; } else { div_initial_payment.style.display = 'none'; initial_payment.removeAttribute('required'); initial_payment.value = '0.00'; } updateSummary(); }); initial_payment.addEventListener('input', updateSummary); membership_type_id.addEventListener('change', function() { const fecha = start_date.value || new Date().toISOString().split('T')[0]; durationMembership(this.value, fecha); }); start_date.addEventListener('change', function(e) { if (membership_type_id.value != '') { durationMembership(membership_type_id.value, e.target.value); } else { alertaPesonalizada('warning', 'SELECCIONA TIPO DE MEMBRESIA'); e.target.value = ''; } }); }); function durationMembership(membership_type, fecha) { if (membership_type != '') { const http = new XMLHttpRequest(); http.open("GET", base_url + 'admin/durationMembership/' + membership_type + '/' + fecha, true); http.send(); http.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { const res = JSON.parse(this.responseText); let monto = parseFloat(res.amount) || 0; let descuento = parseFloat(res.discount_value) || 0; let tipoDescuento = res.discount_type ? res.discount_type.toLowerCase() : ''; amount.value = monto.toFixed(2); // Formatear el tipo de descuento para que se vea profesional let displayTipo = ''; if (tipoDescuento === 'percent') { displayTipo = 'Porcentaje (%)'; } else if (tipoDescuento === 'fixed') { displayTipo = 'Monto Fijo'; } else { displayTipo = res.discount_type || 'Ninguno'; } discount_type.value = displayTipo; discount_value.value = descuento.toFixed(2); start_date.value = res.fecha_inicio; end_date.value = res.fecha_fin; // Calculamos monto final let montoFinal = monto; if (tipoDescuento === 'percent') { montoFinal = monto - (monto * (descuento / 100)); } else if (tipoDescuento === 'fixed') { montoFinal = monto - descuento; } amount_pait.value = montoFinal.toFixed(2); updateSummary(); } }; } } function updateSummary() { const amount_pait = document.querySelector('#amount_pait'); const payment_type = document.querySelector('#payment_type'); const initial_payment = document.querySelector('#initial_payment'); const summary_total = document.querySelector('#summary_total'); const summary_type = document.querySelector('#summary_type'); const summary_paid = document.querySelector('#summary_paid'); const summary_balance = document.querySelector('#summary_balance'); const total = parseFloat(amount_pait.value) || 0; const type = payment_type.value; const paid = type === 'contado' ? total : (parseFloat(initial_payment.value) || 0); const balance = total - paid; summary_total.textContent = '$ ' + total.toFixed(2); summary_type.textContent = type.charAt(0).toUpperCase() + type.slice(1); summary_paid.textContent = '$ ' + paid.toFixed(2); summary_balance.textContent = '$ ' + balance.toFixed(2); } </script> <?php $this->endSection(); ?>
Coded With 💗 by
0x6ick