212 lines
7.3 KiB
PHP
212 lines
7.3 KiB
PHP
<?php
|
|
|
|
namespace App\Domains\Sale\Services;
|
|
|
|
use App\Domains\Logging\Models\ValueChange;
|
|
use App\Domains\Purchase\Models\Purchase;
|
|
use App\Domains\Tenant\Models\Tenant;
|
|
use Illuminate\Support\Collection;
|
|
use PhpOffice\PhpSpreadsheet\Cell\DataType;
|
|
use PhpOffice\PhpSpreadsheet\Shared\Date;
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
|
use PhpOffice\PhpSpreadsheet\Style\Fill;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
class AdminAppSaleExcelService
|
|
{
|
|
/** @param Collection<int, Purchase> $sales */
|
|
public function downloadSales(Tenant $tenant, Collection $sales, string $timeZone): StreamedResponse
|
|
{
|
|
$generatedAt = now();
|
|
$spreadsheet = $this->spreadsheet($tenant, 'Historial de ventas');
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
$sheet->setTitle('Ventas');
|
|
$sheet->fromArray([
|
|
'ID',
|
|
'Fecha',
|
|
'Cliente',
|
|
'Cantidad',
|
|
'Estado',
|
|
'Importe',
|
|
'Tickets',
|
|
], null, 'A1');
|
|
|
|
foreach ($sales->values() as $index => $sale) {
|
|
$row = $index + 2;
|
|
$sheet->setCellValueExplicit("A{$row}", '#'.$sale->id, DataType::TYPE_STRING);
|
|
if ($sale->created_at) {
|
|
$sheet->setCellValue(
|
|
"B{$row}",
|
|
Date::dateTimeToExcel($sale->created_at->copy()->timezone($timeZone)),
|
|
);
|
|
}
|
|
$sheet->setCellValueExplicit(
|
|
"C{$row}",
|
|
$sale->nombre_apellido ?: 'Sin nombre',
|
|
DataType::TYPE_STRING,
|
|
);
|
|
$sheet->setCellValue("D{$row}", (int) ($sale->quantity ?? 0));
|
|
$sheet->setCellValue("E{$row}", $this->saleStatus($sale->status));
|
|
$sheet->setCellValue("F{$row}", (float) $sale->total);
|
|
$sheet->setCellValue("G{$row}", (int) ($sale->tickets_count ?? 0));
|
|
}
|
|
|
|
$lastRow = max(2, $sales->count() + 1);
|
|
$sheet->getStyle("B2:B{$lastRow}")->getNumberFormat()->setFormatCode('dd/mm/yyyy hh:mm');
|
|
$sheet->getStyle("F2:F{$lastRow}")->getNumberFormat()->setFormatCode('$ #,##0.00');
|
|
$this->formatSheet($spreadsheet, 'A1:G1', "A1:G{$lastRow}", [
|
|
'A' => 13,
|
|
'B' => 20,
|
|
'C' => 32,
|
|
'D' => 12,
|
|
'E' => 22,
|
|
'F' => 16,
|
|
'G' => 12,
|
|
]);
|
|
|
|
return $this->download(
|
|
$spreadsheet,
|
|
'ventas_'.$tenant->codigo.'_'
|
|
.$generatedAt->copy()->timezone($timeZone)->format('Ymd_His').'.xlsx',
|
|
);
|
|
}
|
|
|
|
/** @param Collection<int, ValueChange> $modifications */
|
|
public function downloadModifications(
|
|
Tenant $tenant,
|
|
Collection $modifications,
|
|
string $timeZone,
|
|
): StreamedResponse {
|
|
$generatedAt = now();
|
|
$spreadsheet = $this->spreadsheet($tenant, 'Historial de modificaciones de ventas');
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
$sheet->setTitle('Modificaciones');
|
|
$sheet->fromArray([
|
|
'Fecha',
|
|
'Hora',
|
|
'Venta',
|
|
'Cliente',
|
|
'Campo',
|
|
'Valor anterior',
|
|
'Valor nuevo',
|
|
'Modificado por',
|
|
], null, 'A1');
|
|
|
|
foreach ($modifications->values() as $index => $modification) {
|
|
$row = $index + 2;
|
|
$changedAt = $modification->changed_at->copy()->timezone($timeZone);
|
|
$sale = $modification->trackable;
|
|
$sheet->setCellValue("A{$row}", Date::dateTimeToExcel($changedAt));
|
|
$sheet->setCellValue("B{$row}", Date::dateTimeToExcel($changedAt));
|
|
$sheet->setCellValueExplicit(
|
|
"C{$row}",
|
|
'#'.$modification->trackable_id,
|
|
DataType::TYPE_STRING,
|
|
);
|
|
$sheet->setCellValueExplicit(
|
|
"D{$row}",
|
|
$sale?->nombre_apellido ?: 'Sin nombre',
|
|
DataType::TYPE_STRING,
|
|
);
|
|
$sheet->setCellValueExplicit(
|
|
"E{$row}",
|
|
$modification->attribute,
|
|
DataType::TYPE_STRING,
|
|
);
|
|
$sheet->setCellValueExplicit(
|
|
"F{$row}",
|
|
$modification->old_value ?? '-',
|
|
DataType::TYPE_STRING,
|
|
);
|
|
$sheet->setCellValueExplicit(
|
|
"G{$row}",
|
|
$modification->new_value ?? '-',
|
|
DataType::TYPE_STRING,
|
|
);
|
|
$sheet->setCellValueExplicit(
|
|
"H{$row}",
|
|
$modification->user?->nombre_apellido ?? 'Sistema',
|
|
DataType::TYPE_STRING,
|
|
);
|
|
}
|
|
|
|
$lastRow = max(2, $modifications->count() + 1);
|
|
$sheet->getStyle("A2:A{$lastRow}")->getNumberFormat()->setFormatCode('dd/mm/yyyy');
|
|
$sheet->getStyle("B2:B{$lastRow}")->getNumberFormat()->setFormatCode('hh:mm:ss');
|
|
$this->formatSheet($spreadsheet, 'A1:H1', "A1:H{$lastRow}", [
|
|
'A' => 14,
|
|
'B' => 12,
|
|
'C' => 13,
|
|
'D' => 32,
|
|
'E' => 20,
|
|
'F' => 24,
|
|
'G' => 24,
|
|
'H' => 28,
|
|
]);
|
|
|
|
return $this->download(
|
|
$spreadsheet,
|
|
'historial_modificaciones_'.$tenant->codigo.'_'
|
|
.$generatedAt->copy()->timezone($timeZone)->format('Ymd_His').'.xlsx',
|
|
);
|
|
}
|
|
|
|
private function spreadsheet(Tenant $tenant, string $title): Spreadsheet
|
|
{
|
|
$spreadsheet = new Spreadsheet;
|
|
$spreadsheet->getProperties()
|
|
->setCreator('Shopit')
|
|
->setTitle($title)
|
|
->setSubject($tenant->nombre);
|
|
|
|
return $spreadsheet;
|
|
}
|
|
|
|
/** @param array<string, int> $widths */
|
|
private function formatSheet(
|
|
Spreadsheet $spreadsheet,
|
|
string $headerRange,
|
|
string $filterRange,
|
|
array $widths,
|
|
): void {
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
$sheet->getStyle($headerRange)->applyFromArray([
|
|
'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
|
|
'fill' => [
|
|
'fillType' => Fill::FILL_SOLID,
|
|
'startColor' => ['rgb' => '26382E'],
|
|
],
|
|
'alignment' => ['vertical' => Alignment::VERTICAL_CENTER],
|
|
]);
|
|
$sheet->getRowDimension(1)->setRowHeight(24);
|
|
$sheet->freezePane('A2');
|
|
$sheet->setAutoFilter($filterRange);
|
|
|
|
foreach ($widths as $column => $width) {
|
|
$sheet->getColumnDimension($column)->setWidth($width);
|
|
}
|
|
}
|
|
|
|
private function download(Spreadsheet $spreadsheet, string $filename): StreamedResponse
|
|
{
|
|
return response()->streamDownload(function () use ($spreadsheet): void {
|
|
(new Xlsx($spreadsheet))->save('php://output');
|
|
$spreadsheet->disconnectWorksheets();
|
|
}, $filename, [
|
|
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
]);
|
|
}
|
|
|
|
private function saleStatus(string $status): string
|
|
{
|
|
return match ($status) {
|
|
Purchase::STATUS_PAID => 'Confirmado',
|
|
Purchase::STATUS_CREATED => 'Por completar datos',
|
|
Purchase::STATUS_PENDING_PAYMENT, Purchase::STATUS_IN_REVIEW => 'Esperando pago',
|
|
default => 'Anulado',
|
|
};
|
|
}
|
|
}
|