Files
pos_heidiver/app/Filament/Resources/CompraResource/Pages/CreateCompra.php
T
2026-01-06 15:35:59 -05:00

153 lines
6.6 KiB
PHP

<?php
namespace App\Filament\Resources\CompraResource\Pages;
use App\Filament\Resources\CompraResource;
use Filament\Actions;
use Filament\Resources\Pages\CreateRecord;
use App\Models\Producto;
use App\Models\ProductVariant;
use App\Imports\CompraDetallesImport;
use App\Exports\PlantillaCompraExport;
use Maatwebsite\Excel\Facades\Excel;
use Filament\Forms\Components\FileUpload;
use Filament\Notifications\Notification;
use Illuminate\Support\Facades\Storage;
class CreateCompra extends CreateRecord
{
protected static string $resource = CompraResource::class;
protected function getHeaderActions(): array
{
return [
Actions\Action::make('descargar_plantilla')
->label('Descargar Plantilla Excel')
->icon('heroicon-o-document-arrow-down')
->color('info')
->action(function () {
return Excel::download(
new PlantillaCompraExport(),
'plantilla_compras.xlsx'
);
}),
Actions\Action::make('importar_excel')
->label('Importar desde Excel')
->icon('heroicon-o-arrow-down-tray')
->color('success')
->form([
FileUpload::make('archivo')
->label('Archivo Excel')
->acceptedFileTypes([
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'text/csv',
])
->required()
->helperText('Formato: Código de Barras, Producto, Cantidad, Precio Unitario, Bodega (opcional), Observaciones (opcional)')
->disk('local')
->directory('temp-imports'),
])
->action(function (array $data) {
try {
$filePath = Storage::disk('local')->path($data['archivo']);
$import = new CompraDetallesImport();
Excel::import($import, $filePath);
$previewData = $import->getPreviewData();
$stats = $import->getStats();
// Mostrar vista preliminar en notificación
$message = "Total de filas: {$stats['total']}\n";
$message .= "Válidas: {$stats['valid']}\n";
$message .= "Con errores: {$stats['invalid']}\n";
if ($stats['productos_creados'] > 0) {
$message .= "✨ Productos nuevos creados: {$stats['productos_creados']}\n";
}
$message .= "Total estimado: $" . number_format($stats['total_amount'], 2);
// Si hay errores, mostrarlos
if ($stats['invalid'] > 0) {
$errorMessages = collect($previewData)
->filter(fn($item) => !$item['valid'])
->map(fn($item) => "Fila {$item['row_number']}: " . implode(', ', $item['errors']))
->take(5)
->implode("\n");
Notification::make()
->warning()
->title("Vista preliminar: {$stats['invalid']} filas con errores")
->body($errorMessages . "\n\n" . $message)
->persistent()
->send();
} else {
Notification::make()
->success()
->title('Vista preliminar de importación')
->body($message)
->persistent()
->send();
}
// Cargar los datos directamente en el formulario
$detallesParaFormulario = $import->getDetallesForSave();
// Actualizar el formulario con los datos importados
$currentData = $this->data;
$currentData['detalles'] = array_merge(
$currentData['detalles'] ?? [],
$detallesParaFormulario
);
// Calcular el total
$currentData['total'] = collect($currentData['detalles'])->sum('subtotal');
$this->form->fill($currentData);
// Limpiar archivo temporal
Storage::disk('local')->delete($data['archivo']);
} catch (\Exception $e) {
Notification::make()
->danger()
->title('Error en la importación')
->body($e->getMessage())
->send();
}
}),
];
}
protected function mutateFormDataBeforeCreate(array $data): array
{
// Calcular el total basado en los detalles
if (isset($data['detalles']) && is_array($data['detalles'])) {
$total = collect($data['detalles'])->sum('subtotal');
$data['total'] = $total;
// Agregar snapshots para cada detalle
foreach ($data['detalles'] as &$detalle) {
if (isset($detalle['producto_id'])) {
$producto = Producto::find($detalle['producto_id']);
$detalle['producto_nombre_snapshot'] = $producto?->nombre;
}
if (isset($detalle['variante_id'])) {
$variante = ProductVariant::find($detalle['variante_id']);
if ($variante) {
$colorName = $variante->color?->name ?? 'Sin color';
$sizeName = $variante->size?->name ?? 'Sin talla';
$detalle['variante_info_snapshot'] = "$colorName / $sizeName";
}
}
}
} else {
$data['total'] = 0;
}
return $data;
}
}