Falta agrupar por personas encargadas de comunidad el corte

This commit is contained in:
DANYDHSV 2026-02-12 15:09:19 -06:00
parent 12bb5c04a4
commit c989d180fa
3 changed files with 1560 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -181,6 +181,25 @@ if (isset($_GET['action'])) {
exit; exit;
} }
if ($_GET['action'] === 'get_oxxo_history') {
if (ob_get_level()) ob_end_clean();
header('Content-Type: application/json');
$stripeCustomerId = $_GET['stripeCustomerId'] ?? '';
if (!$stripeCustomerId) {
echo json_encode(['error' => 'Missing stripeCustomerId']);
exit;
}
try {
$history = $stripeService->getLastOxxoPayments($stripeCustomerId);
echo json_encode(['history' => $history]);
} catch (Exception $e) {
echo json_encode(['error' => $e->getMessage()]);
}
exit;
}
if ($_GET['action'] === 'search_stripe') { if ($_GET['action'] === 'search_stripe') {
$q = $_GET['q'] ?? ''; $q = $_GET['q'] ?? '';
echo json_encode($stripeService->searchClients($q)); echo json_encode($stripeService->searchClients($q));
@ -1375,6 +1394,33 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
</div> </div>
</div> </div>
</div> </div>
<!-- OXXO HISTORY CONTAINER -->
<div id="oxxoHistoryContainer" style="display: none; margin-top: 2rem;">
<div class="card">
<h3 class="section-title" style="margin-bottom: 1rem;">Historial de Fichas OXXO (Últimas 5)</h3>
<div class="table-responsive">
<table class="table table-hover" id="oxxoHistoryTable">
<thead>
<tr>
<th>ID Pago</th>
<th>Fecha</th>
<th>Monto</th>
<th>Ref. OXXO</th>
<th>Estatus</th>
<th>Ficha</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="6" style="text-align:center">Seleccione un cliente...</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section> </section>
</div> </div>
</div> </div>
@ -1768,6 +1814,60 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
document.getElementById('stripeResultModal').style.display = 'flex'; document.getElementById('stripeResultModal').style.display = 'flex';
} }
async function loadOxxoHistory(stripeCustomerId) {
const tbody = document.querySelector('#oxxoHistoryTable tbody');
tbody.innerHTML = '<tr><td colspan="6" style="text-align:center">Cargando historial...</td></tr>';
try {
const res = await fetch(`?action=get_oxxo_history&stripeCustomerId=${stripeCustomerId}`);
const data = await res.json();
if (data.error) {
tbody.innerHTML = `<tr><td colspan="6" style="text-align:center;color:var(--danger)">Error: ${data.error}</td></tr>`;
return;
}
if (!data.history || data.history.length === 0) {
tbody.innerHTML = '<tr><td colspan="6" style="text-align:center">No hay fichas recientes</td></tr>';
return;
}
tbody.innerHTML = data.history.map(p => {
let statusBadge = '';
switch (p.status) {
case 'succeeded':
statusBadge = '<span class="badge badge-success">Pagado</span>';
break;
case 'requires_action':
statusBadge = '<span class="badge badge-warning">Pendiente</span>';
break;
case 'canceled':
statusBadge = '<span class="badge badge-danger">Cancelado</span>';
break;
default:
statusBadge = `<span class="badge badge-secondary">${p.status}</span>`;
}
const date = new Date(p.created * 1000).toLocaleString();
const voucherBtn = p.voucherUrl ?
`<a href="${p.voucherUrl}" target="_blank" class="btn btn-sm btn-outline-primary" style="padding: 2px 8px; font-size: 0.8rem;">Ver Ficha</a>` :
'-';
return `<tr>
<td><small style="font-family:monospace">${p.id.slice(-8)}</small></td>
<td>${date}</td>
<td>$${p.amount.toFixed(2)} ${p.currency}</td>
<td style="font-family:monospace">${p.oxxoNumber}</td>
<td>${statusBadge}</td>
<td>${voucherBtn}</td>
</tr>`;
}).join('');
} catch (e) {
console.error(e);
tbody.innerHTML = '<tr><td colspan="6" style="text-align:center;color:var(--danger)">Error de conexión</td></tr>';
}
}
// 3. OXXO SEARCH // 3. OXXO SEARCH
let selectedOxxoClient = null; let selectedOxxoClient = null;
setupSearch('oxxoSearch', 'oxxoResults', 'search_stripe', async (partialClient) => { setupSearch('oxxoSearch', 'oxxoResults', 'search_stripe', async (partialClient) => {
@ -1788,6 +1888,14 @@ $installersData = json_decode($config['installersDataWhatsApp'] ?? '{"instalador
document.getElementById('oxxoResult').innerHTML = ''; document.getElementById('oxxoResult').innerHTML = '';
document.getElementById('oxxoDetailContainer').style.display = 'block'; document.getElementById('oxxoDetailContainer').style.display = 'block';
// Load History
if (data.stripeCustomerId) {
document.getElementById('oxxoHistoryContainer').style.display = 'block';
loadOxxoHistory(data.stripeCustomerId);
} else {
document.getElementById('oxxoHistoryContainer').style.display = 'none';
}
}); });
document.getElementById('btnCreateOxxoIntent').onclick = async () => { document.getElementById('btnCreateOxxoIntent').onclick = async () => {

View File

@ -168,6 +168,55 @@ class PaymentIntentService
} }
} }
public function getLastOxxoPayments($stripeCustomerId, $limit = 5)
{
try {
// Fetch a bit more to allow for filtering
$collection = $this->stripeClient->paymentIntents->all([
'customer' => $stripeCustomerId,
'limit' => 20,
]);
$result = [];
foreach ($collection->data as $payment) {
// Check if it's an OXXO payment
$isOxxo = false;
if (isset($payment->payment_method_types) && in_array('oxxo', $payment->payment_method_types)) {
$isOxxo = true;
}
if ($isOxxo) {
$oxxoNumber = $payment->next_action->oxxo_display_details->number ?? '-';
$pdfUrl = $payment->next_action->oxxo_display_details->hosted_voucher_url ?? null;
// Fallback for Succeeded payments (where next_action might be null)
if ($oxxoNumber === '-' && !empty($payment->charges->data)) {
$charge = $payment->charges->data[0];
if (isset($charge->payment_method_details->oxxo->number)) {
$oxxoNumber = $charge->payment_method_details->oxxo->number;
}
}
$result[] = [
'id' => $payment->id,
'amount' => $payment->amount / 100,
'currency' => strtoupper($payment->currency),
'status' => $payment->status,
'created' => $payment->created,
'oxxoNumber' => $oxxoNumber, // Reference Number
'voucherUrl' => $pdfUrl
];
}
if (count($result) >= $limit) break;
}
return $result;
} catch (\Exception $e) {
$this->log("Error fetching OXXO payments: " . $e->getMessage());
return ['error' => $e->getMessage()];
}
}
public function getCustomerCashBalance($stripeCustomerId) public function getCustomerCashBalance($stripeCustomerId)
{ {
try { try {