commit21
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\SupplyRecord;
|
||||
use App\Models\User;
|
||||
use App\Services\SupplyCoordination;
|
||||
use App\Services\SupplyCoordinationRead;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class SupplyCoordinationReportController extends Controller
|
||||
{
|
||||
public function csv(Request $request, SupplyCoordinationRead $read): StreamedResponse
|
||||
{
|
||||
$actor = $request->user('web');
|
||||
abort_unless($actor instanceof User, 403);
|
||||
$view = $request->validate(['view' => 'required|in:reservations,deliveries,alternatives'])['view'];
|
||||
$kind = $read->kind($actor, $view);
|
||||
$filters = $read->filters($request, $kind);
|
||||
abort_unless(Schema::hasTable('supply_records'), 503, 'Instalação do fornecimento pendente.');
|
||||
// Validate the same focus as the page, without silently exporting other records.
|
||||
$focus = $request->validate(['record_id' => ['nullable', 'integer', 'min:1', Rule::exists('supply_records', 'id')->where('tenant_id', $actor->tenant_id)->where('kind', $kind)]]);
|
||||
|
||||
return response()->streamDownload(function () use ($read, $actor, $view, $kind, $filters, $focus) {
|
||||
DB::transaction(function () use ($read, $actor, $view, $kind, $filters, $focus) {
|
||||
if (DB::getDriverName() === 'pgsql' && DB::transactionLevel() === 1) {
|
||||
DB::statement('SET TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY');
|
||||
}
|
||||
// Recheck access when the response is consumed.
|
||||
$read->kind($actor, $view);
|
||||
$query = $read->query($kind, isset($focus['record_id']) ? ['record_search' => '', 'record_state' => ''] : $filters);
|
||||
if (isset($focus['record_id'])) {
|
||||
$key = SupplyRecord::query()->whereKey($focus['record_id'])->value('record_key');
|
||||
$query->where('record_key', $key);
|
||||
}
|
||||
$out = fopen('php://output', 'w');
|
||||
if ($out === false) {
|
||||
throw new \RuntimeException('Não foi possível preparar a exportação.');
|
||||
}
|
||||
$text = static function (mixed $value): string {
|
||||
$value = (string) ($value ?? '');
|
||||
|
||||
return preg_match('/^[\s\x00-\x1F]*[=+\-@]/u', $value) ? "'".$value : $value;
|
||||
};
|
||||
try {
|
||||
fwrite($out, "\xEF\xBB\xBF");
|
||||
fputcsv($out, ['Acompanhamento de fornecimentos', $view, 'Conferido em', now()->toIso8601String()], ';', '"', '');
|
||||
fputcsv($out, ['Filtros', $text(json_encode($filters, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)), 'Registo em foco', $focus['record_id'] ?? ''], ';', '"', '');
|
||||
fputcsv($out, ['Registo', 'Versão', 'Estado registado', 'Artigo', 'Designação preservada', 'Local preservado', 'Referência', 'Encomenda', 'Quantidade', 'Unidade', 'Data prevista/necessidade', 'Quantidade por satisfazer (ver estado)', 'Substituto', 'Aplicação', 'Validade', 'Processo'], ';', '"', '');
|
||||
foreach ($query->lazyById(100) as $record) {
|
||||
$pending = match ($kind) {
|
||||
'reservation' => app(SupplyCoordination::class)->remainingReservation($record),
|
||||
'delivery' => app(SupplyCoordination::class)->remainingDelivery($record),
|
||||
default => null,
|
||||
};
|
||||
fputcsv($out, array_map($text, [$record->record_key, $record->version, $record->state,
|
||||
$record->snapshot['item']['code'] ?? '', $record->snapshot['item']['name'] ?? '', $record->snapshot['warehouse']['name'] ?? '',
|
||||
$record->data['reference'] ?? '', $record->snapshot['order']['number'] ?? '',
|
||||
isset($record->data['quantity_milli']) ? $record->data['quantity_milli'] / 1000 : '', $record->snapshot['item']['unit'] ?? '',
|
||||
$record->data['needed_on'] ?? $record->data['expected_on'] ?? '', $pending === null ? '' : $pending / 1000,
|
||||
$record->snapshot['substitute']['code'] ?? '', $record->data['application'] ?? '', $record->data['valid_until'] ?? '',
|
||||
url('/compras/fornecimento?view='.$view.'&record_id='.$record->id).'#supply-record-'.$record->id]), ';', '"', '');
|
||||
}
|
||||
} finally {
|
||||
fclose($out);
|
||||
}
|
||||
});
|
||||
}, 'fornecimentos-'.$view.'-'.now()->format('Ymd-His').'.csv', ['Content-Type' => 'text/csv; charset=UTF-8', 'Cache-Control' => 'private, no-store, max-age=0']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user