Cargando...
Regresar
@if(session('ok'))
{{ session('ok') }}
@endif @if($errors->any())
@endif
@php $issueRoute = request()->routeIs('accountant.*') ? route('accountant.incomes.generate_invoice.issue', ['generatedInvoice' => $generatedInvoice->id]) : route('admin.incomes.generate_invoice.issue', ['generatedInvoice' => $generatedInvoice->id]); $paymentComplementRoute = request()->routeIs('accountant.*') ? route('accountant.incomes.generate_invoice.payment_complement', ['generatedInvoice' => $generatedInvoice->id]) : route('admin.incomes.generate_invoice.payment_complement', ['generatedInvoice' => $generatedInvoice->id]); $invoiceRequests = ($hasGroupingPivot ?? false) ? ($generatedInvoice->pipefyRequests ?? collect()) : collect(); if ($invoiceRequests->isEmpty() && $generatedInvoice->pipefyRequest) { $invoiceRequests = collect([$generatedInvoice->pipefyRequest]); } $showItemRcColumn = (bool) ($generatedInvoice->client?->validation_rc ?? false) || $generatedInvoice->items->contains(function ($item) { return trim((string) ($item->item_rc ?? '')) !== ''; }); $showSatColumn = $generatedInvoice->items->contains(function ($item) { return trim((string) ($item->sat_code ?? '')) !== '' || trim((string) ($item->sat_item_label ?? '')) !== '' || !empty($item->sat_catalog_item_id); }); @endphp

Vista Previa

Documento preliminar para revisión interna, como referencia previa al timbrado.

Folio: {{ $generatedInvoice->folio }}
Fecha emisión: {{ optional($generatedInvoice->issue_date)->format('Y-m-d') ?: '-' }}
Solicitudes: {{ $invoiceRequests->count() }}
Facturama: {{ $generatedInvoice->facturama_cfdi_id ? 'Factura creada' : 'Pendiente' }}
Complemento: {{ $generatedInvoice->facturama_payment_complement_cfdi_id ? 'Creado' : 'Pendiente' }}
Cliente {{ $generatedInvoice->client?->name ?: '-' }}
RFC cliente {{ $generatedInvoice->client?->rfc ?: '-' }}
Oficina {{ $generatedInvoice->office ? (($generatedInvoice->office->office_code ?: 'SIN-COD').' | '.$generatedInvoice->office->name) : '-' }}
Agrupación @if($invoiceRequests->count() > 1) Vista previa agrupada @else Solicitud individual @endif

Solicitudes incluidas

@forelse($invoiceRequests as $invoiceRequest) @empty @endforelse
ID PROJECT NAME JN RC
#{{ $invoiceRequest->id }} {{ $invoiceRequest->project_name ?: '-' }} {{ $invoiceRequest->title ?: '-' }} {{ $invoiceRequest->rc_list ?: '-' }}
No hay solicitudes asociadas a esta vista previa.

Artículos

@if($showItemRcColumn) @endif @if($showSatColumn) @endif @forelse($generatedInvoice->items as $idx => $item) @php $sourceRequest = $item->pipefyRequestItem?->request; $inboundEmail = $item->inboundEmail; $displayDescription = (string) ($item->description ?: '-'); $ocLabel = trim((string) ($inboundEmail?->purchase_order_number ?? '')); $rcLabel = trim((string) ($inboundEmail?->purchase_receipt_number ?? '')); $deliveryLabel = trim((string) ($inboundEmail?->delivery_address ?? '')); if ($ocLabel !== '' && !\Illuminate\Support\Str::contains($displayDescription, 'OC '.$ocLabel)) { $displayDescription .= '; OC '.$ocLabel; } if ($rcLabel !== '' && !\Illuminate\Support\Str::contains($displayDescription, 'RC '.$rcLabel)) { $displayDescription .= '; RC '.$rcLabel; } if ($deliveryLabel !== '' && !\Illuminate\Support\Str::contains($displayDescription, $deliveryLabel)) { $displayDescription .= '; '.$deliveryLabel; } @endphp @if($showItemRcColumn) @endif @if($showSatColumn) @endif @empty @endforelse
# Solicitud Descripción CantidadRCClave SATPrecio unit. Importe
{{ $idx + 1 }} @if($sourceRequest) #{{ $sourceRequest->id }}
{{ $sourceRequest->title ?: '-' }}
RC: {{ $sourceRequest->rc_list ?: '-' }} @else - @endif
{{ $displayDescription }} @if($inboundEmail)
Inbound: OC {{ $inboundEmail->purchase_order_number ?: '-' }} ; RC {{ $inboundEmail->purchase_receipt_number ?: '-' }} ; {{ $inboundEmail->delivery_address ?: '-' }} @endif
{{ number_format((float) $item->quantity, 2) }}{{ $item->item_rc ?: '-' }} {{ $item->sat_item_label ?: ($item->satCatalogItem?->name ?: '-') }}
{{ $item->sat_code ?: ($item->satCatalogItem?->sat_code ?: '-') }}
{{ $item->sat_unit_code ?: ($item->satCatalogItem?->unit_code ?: '-') }} | {{ $item->sat_unit_name ?: ($item->satCatalogItem?->unit_name ?: '-') }}
${{ number_format((float) $item->unit_price, 2) }} ${{ number_format((float) $item->line_total, 2) }}
No hay artículos en esta vista previa.
Subtotal ${{ number_format((float) $generatedInvoice->subtotal, 2) }}
IVA ${{ number_format((float) $generatedInvoice->tax, 2) }}
Total ${{ number_format((float) $generatedInvoice->total, 2) }}
Paso 5. Crear factura
@if(!($hasFacturamaColumns ?? false))

Faltan las migraciones de Facturama en esta base. Primero agrega configuración y columnas de tracking para habilitar el paso 5.

@elseif($generatedInvoice->facturama_cfdi_id)
CFDI creado en Facturama {{ $generatedInvoice->facturama_folio ?: $generatedInvoice->facturama_cfdi_id }}
@if($generatedInvoice->facturama_pdf_path) Abrir PDF Facturama @endif @if($generatedInvoice->facturama_xml_path) Abrir XML Facturama @endif
@if($generatedInvoice->facturama_error_message)

{{ $generatedInvoice->facturama_error_message }}

@endif @else

Cuando esta vista previa ya esté correcta, desde aquí se crea la factura real en Facturama con los conceptos y datos fiscales capturados.

@csrf
@if($generatedInvoice->facturama_error_message)

Último error: {{ $generatedInvoice->facturama_error_message }}

@endif @endif
@php $paymentRecords = collect($paymentComplementState['records'] ?? []); $remainingBalance = (float) ($paymentComplementState['remaining_balance'] ?? 0); $defaultPreviousBalance = (float) ($paymentComplementState['previous_balance_amount'] ?? 0); $defaultAmount = (float) ($paymentComplementState['default_amount'] ?? 0); $oldAmount = (float) old('amount', number_format($defaultAmount, 2, '.', '')); $defaultInsoluto = max($defaultPreviousBalance - $oldAmount, 0); @endphp
Paso 6. Crear complemento de pago
@if(!($hasFacturamaPaymentComplementColumns ?? false) || !($hasGeneratedInvoicePaymentComplementsTable ?? false))

Faltan la tabla o las columnas del complemento de pago. Corre ambas migraciones nuevas para habilitar este paso.

@elseif(!$generatedInvoice->facturama_cfdi_id)

Primero crea la factura en Facturama. En cuanto exista el CFDI, aquí se habilita el registro del pago y la emisión del complemento.

@else
Pagado en complementos: ${{ number_format((float) ($paymentComplementState['issued_amount'] ?? 0), 2) }} Saldo remanente: ${{ number_format($remainingBalance, 2) }} Siguiente parcialidad: {{ (int) ($paymentComplementState['next_partiality_number'] ?? 1) }}
@if($paymentRecords->isNotEmpty())
@foreach($paymentRecords as $record) @php $status = strtolower((string) ($record->facturama_status ?? 'pending')); @endphp @endforeach
Parcialidad Fecha pago Monto Saldo insoluto Estatus Archivos
#{{ $record->partiality_number }} {{ optional($record->payment_date)->format('Y-m-d H:i') ?: '-' }} ${{ number_format((float) $record->amount, 2) }} {{ $record->currency ?: 'MXN' }} ${{ number_format((float) $record->insoluto_amount, 2) }} @if($status === 'issued') Emitido @elseif($status === 'failed') Error @if($record->facturama_error_message)
{{ $record->facturama_error_message }}
@endif @else Pendiente @endif
@if($record->facturama_pdf_path) PDF @endif @if($record->facturama_xml_path) XML @endif
@endif @if($remainingBalance <= \App\Support\ProviderPartialBilling::QUANTITY_TOLERANCE)
Saldo cubierto Ya no hay remanente para nuevos complementos.
@else

Captura el pago real. Esta pantalla ya soporta parcialidades, deja historial y emite el complemento contra el UUID de la factura original.

@csrf
@foreach(($paymentFormOptions ?? []) as $code => $label) {{ $label }} @endforeach
@foreach(array_unique([old('currency', $paymentComplementState['default_currency'] ?? 'MXN'), 'MXN', 'USD', 'EUR']) as $currencyCode) {{ $currencyCode }} @endforeach
Solo llena este campo si la moneda del pago no es MXN.
@endif @if($generatedInvoice->facturama_payment_complement_error_message)

Último error general: {{ $generatedInvoice->facturama_payment_complement_error_message }}

@endif @endif
@if($generatedInvoice->notes)
Notas: {{ $generatedInvoice->notes }}
@endif