feat(transmittal): replace PDF export with Excel export and add logo
- Remove PDF export functionality from TransmittalResource and CreateTransmittal page - Add new TransmittalExcelExport class for formatted Excel exports with company logo - Update export jobs to generate unique filenames per user and refresh user data - Replace PDF export action with Excel export in table actions - Comment out logo in PDF view template as it's no longer used - Fix import alias for Excel export action in GeneralLedger
This commit is contained in:
142
app/Filament/Exports/TransmittalExcelExport.php
Normal file
142
app/Filament/Exports/TransmittalExcelExport.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Exports;
|
||||
|
||||
use App\Models\Transmittal;
|
||||
use pxlrbt\FilamentExcel\Columns\Column;
|
||||
use pxlrbt\FilamentExcel\Exports\ExcelExport;
|
||||
use Maatwebsite\Excel\Events\AfterSheet;
|
||||
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
||||
use PhpOffice\PhpSpreadsheet\Style\Border;
|
||||
|
||||
class TransmittalExcelExport extends ExcelExport
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->fromTable()
|
||||
->withFilename('transmittals-' . now()->format('Y-m-d'))
|
||||
->modifyQueryUsing(
|
||||
fn ($query) => $query->with([
|
||||
'client',
|
||||
'branch',
|
||||
'files.notes',
|
||||
'files.remarks',
|
||||
])
|
||||
)
|
||||
->withColumns([
|
||||
Column::make('series')
|
||||
->heading('series'),
|
||||
Column::make('client')
|
||||
->heading('Client')
|
||||
->formatStateUsing(fn (Transmittal $record) => $record->client?->company),
|
||||
Column::make('branch')
|
||||
->heading('Branch')
|
||||
->formatStateUsing(fn (Transmittal $record) => $record->branch?->code),
|
||||
Column::make('files')
|
||||
->heading('files')
|
||||
->formatStateUsing(
|
||||
fn (Transmittal $record) => $record->files
|
||||
->pluck('description')
|
||||
->filter()
|
||||
->join(PHP_EOL)
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
public function registerEvents(): array
|
||||
{
|
||||
$recordIds = $this->getRecordIds();
|
||||
|
||||
return [
|
||||
AfterSheet::class => function (AfterSheet $event) use ($recordIds) {
|
||||
$sheet = $event->sheet->getDelegate();
|
||||
|
||||
$sheet->insertNewRowBefore(1, 2);
|
||||
$sheet->mergeCells('A1:F1');
|
||||
$sheet->getRowDimension(1)->setRowHeight(90);
|
||||
$sheet->getStyle('A1:F1')
|
||||
->getAlignment()
|
||||
->setHorizontal(Alignment::HORIZONTAL_CENTER);
|
||||
|
||||
|
||||
$logo = new Drawing();
|
||||
$logo->setName('MKM Logo');
|
||||
$logo->setDescription('MKM Tax & Accounting Services');
|
||||
$logo->setPath(public_path('images/logo-light.png'));
|
||||
$logo->setHeight(100);
|
||||
$logo->setOffsetX(120);
|
||||
$logo->setOffsetY(10);
|
||||
|
||||
$logo->setCoordinates('A1');
|
||||
$logo->setWorksheet($sheet);
|
||||
|
||||
$transmittal = Transmittal::with(['client', 'branch', 'files.notes', 'files.remarks'])->find($recordIds[0] ?? null);
|
||||
|
||||
if ($transmittal) {
|
||||
$sheet->mergeCells('A2:F2');
|
||||
$sheet->setCellValue('A2', $transmittal->client?->company);
|
||||
|
||||
$sheet->getStyle('A2')->getFont()->setBold(true);
|
||||
$sheet->getStyle('A2')->getAlignment()->setHorizontal('center');
|
||||
}
|
||||
|
||||
// Headings row
|
||||
$sheet->setCellValue('A3', 'series');
|
||||
$sheet->setCellValue('B3', 'Client');
|
||||
$sheet->setCellValue('C3', 'Branch');
|
||||
$sheet->setCellValue('D3', 'files');
|
||||
$sheet->setCellValue('E3', 'notes');
|
||||
$sheet->setCellValue('F3', 'remarks');
|
||||
|
||||
$sheet->getStyle('A3:F3')->getFont()->setBold(true);
|
||||
$sheet->getStyle('A3:F3')->getAlignment()->setHorizontal('center');
|
||||
|
||||
$rows = [];
|
||||
$firstRow = true;
|
||||
|
||||
if ($transmittal) {
|
||||
foreach ($transmittal->files as $file) {
|
||||
$fileNotes = $file->notes->pluck('comment')->values();
|
||||
$fileRemarks = $file->remarks->pluck('remark')->values();
|
||||
|
||||
$maxLines = max(1, $fileNotes->count(), $fileRemarks->count());
|
||||
|
||||
for ($i = 0; $i < $maxLines; $i++) {
|
||||
$rows[] = [
|
||||
'series' => $firstRow ? $transmittal->series : '',
|
||||
'client' => $firstRow ? $transmittal->client?->company : '',
|
||||
'branch' => $firstRow ? $transmittal->branch?->code : '',
|
||||
'file' => $i === 0 ? $file->description : '',
|
||||
'note' => $fileNotes[$i] ?? '',
|
||||
'remark' => $fileRemarks[$i] ?? '',
|
||||
];
|
||||
|
||||
$firstRow = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$currentRow = 4;
|
||||
|
||||
foreach ($rows as $dataRow) {
|
||||
$sheet->setCellValue("A{$currentRow}", $dataRow['series']);
|
||||
$sheet->setCellValue("B{$currentRow}", $dataRow['client']);
|
||||
$sheet->setCellValue("C{$currentRow}", $dataRow['branch']);
|
||||
$sheet->setCellValue("D{$currentRow}", $dataRow['file']);
|
||||
$sheet->setCellValue("E{$currentRow}", $dataRow['note']);
|
||||
$sheet->setCellValue("F{$currentRow}", $dataRow['remark']);
|
||||
|
||||
$currentRow++;
|
||||
}
|
||||
|
||||
$lastRow = max($currentRow - 1, 3);
|
||||
|
||||
$sheet->getStyle("A3:F{$lastRow}")
|
||||
->getBorders()
|
||||
->getAllBorders()
|
||||
->setBorderStyle(Border::BORDER_THIN);
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ use Filament\Tables\Filters\Filter;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Filament\Resources\Pages\Concerns\InteractsWithRecord;
|
||||
use pxlrbt\FilamentExcel\Actions\Tables\ExportAction;
|
||||
use pxlrbt\FilamentExcel\Actions\ExportAction as ExcelExportAction;
|
||||
use pxlrbt\FilamentExcel\Exports\ExcelExport;
|
||||
use pxlrbt\FilamentExcel\Columns\Column;
|
||||
|
||||
@@ -108,7 +108,7 @@ class GeneralLedger extends Page implements HasTable
|
||||
'account.account',
|
||||
])
|
||||
->headerActions([
|
||||
ExportAction::make()
|
||||
ExcelExportAction::make()
|
||||
->label('Export General Ledger')
|
||||
->exports([
|
||||
ExcelExport::make()
|
||||
|
||||
@@ -3,51 +3,12 @@
|
||||
namespace App\Filament\Resources\Transmittals\Pages;
|
||||
|
||||
use App\Filament\Resources\Transmittals\TransmittalResource;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Throwable;
|
||||
|
||||
class CreateTransmittal extends CreateRecord
|
||||
{
|
||||
protected static string $resource = TransmittalResource::class;
|
||||
|
||||
public bool $willExport = false;
|
||||
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function createAndExport(): void
|
||||
{
|
||||
$this->willExport = true;
|
||||
$this->create();
|
||||
}
|
||||
|
||||
public function afterCreate()
|
||||
{
|
||||
if ($this->willExport) {
|
||||
TransmittalResource::exportTransmittal([$this->record->id]);
|
||||
}
|
||||
}
|
||||
|
||||
public function getCreatedNotificationMessage(): ?string
|
||||
{
|
||||
if ($this->willExport) {
|
||||
return 'Transmittal Was Created Successfully!, Check your notification for file download link';
|
||||
}
|
||||
|
||||
return 'Transmittal Was Created Successfully!';
|
||||
}
|
||||
|
||||
protected function getFormActions(): array
|
||||
{
|
||||
return [
|
||||
$this->getCreateFormAction(),
|
||||
$this->getCreateAnotherFormAction(),
|
||||
Action::make('Create and Export')->action('createAndExport')->color('success'),
|
||||
$this->getCancelFormAction(),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getRedirectUrl(): string
|
||||
{
|
||||
return $this->previousUrl ?? $this->getResource()::getUrl('index');
|
||||
|
||||
@@ -8,7 +8,6 @@ use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Columns\Layout\View;
|
||||
use Filament\Actions\BulkActionGroup;
|
||||
use Filament\Actions\DeleteBulkAction;
|
||||
use Filament\Actions\BulkAction;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Actions\EditAction;
|
||||
@@ -21,8 +20,7 @@ use App\Filament\Resources\Transmittals\Pages\EditTransmittal;
|
||||
use App\Commands\Transmittal\GenerateTransmittalSeries;
|
||||
use App\Commands\Transmittal\StoreTransmittalCommand;
|
||||
use App\Filament\Resources\TransmittalResource\Pages;
|
||||
use App\Jobs\ExportCompleteJob;
|
||||
use App\Jobs\TransmittalPDFExportJob;
|
||||
use App\Filament\Exports\TransmittalExcelExport;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Client;
|
||||
use App\Models\Transmittal;
|
||||
@@ -33,14 +31,12 @@ use Filament\Forms\Components\Repeater;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Malzariey\FilamentDaterangepickerFilter\Filters\DateRangeFilter;
|
||||
|
||||
@@ -117,10 +113,6 @@ class TransmittalResource extends Resource
|
||||
->toolbarActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
BulkAction::make('Bulk Export')->action(function ($records) {
|
||||
|
||||
static::exportTransmittal(Arr::flatten($records->pluck('id')));
|
||||
}),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
@@ -128,7 +120,18 @@ class TransmittalResource extends Resource
|
||||
public static function getTableActions(): array
|
||||
{
|
||||
return [
|
||||
Action::make('Export')->label('Export as PDF')->action(fn ($record) => static::exportTransmittal([$record->id])),
|
||||
Action::make('Export')
|
||||
->label('Export as Excel')
|
||||
->icon('heroicon-o-arrow-down-tray')
|
||||
->action(function (Transmittal $record, $livewire) {
|
||||
$export = TransmittalExcelExport::make('transmittal');
|
||||
|
||||
return app()->call([$export, 'hydrate'], [
|
||||
'livewire' => $livewire,
|
||||
'records' => collect([$record]),
|
||||
'formData' => null,
|
||||
])->export();
|
||||
}),
|
||||
ViewAction::make(),
|
||||
Action::make('Update Status')
|
||||
->fillForm(function ($record) {
|
||||
@@ -161,24 +164,6 @@ class TransmittalResource extends Resource
|
||||
];
|
||||
}
|
||||
|
||||
public static function exportTransmittal(array $id): void
|
||||
{
|
||||
$recipient = Auth::user();
|
||||
|
||||
static::generateExportNotification();
|
||||
|
||||
dispatch(new TransmittalPDFExportJob($recipient, $id));
|
||||
}
|
||||
|
||||
public static function generateExportNotification(): Notification
|
||||
{
|
||||
|
||||
return Notification::make()
|
||||
->title('Your export will be ready. check your notification for file download link.')
|
||||
->success()
|
||||
->send();
|
||||
}
|
||||
|
||||
public static function form(Schema $schema): Schema
|
||||
{
|
||||
return $schema
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Jobs;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use App\Models\Transmittal;
|
||||
use App\Models\User;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@@ -20,12 +21,14 @@ class ExportCompleteJob implements ShouldQueue
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
public function __construct(private $user, private array $ids)
|
||||
public function __construct(private User $user, private array $ids)
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
$this->user->refresh();
|
||||
|
||||
$transmittals = Transmittal::query()
|
||||
->with(['client', 'branch', 'files.notes', 'files.remarks'])
|
||||
->whereIn('id', $this->ids)
|
||||
@@ -35,15 +38,17 @@ class ExportCompleteJob implements ShouldQueue
|
||||
'transmittals' => $transmittals,
|
||||
]);
|
||||
|
||||
Storage::disk('public')->put('transmittal-export.pdf', $pdf->output());
|
||||
$filename = 'transmittal-export-'.$this->user->id.'-'.now()->format('YmdHis').'.pdf';
|
||||
|
||||
Storage::disk('public')->put($filename, $pdf->output());
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Export Completed')
|
||||
->actions([
|
||||
Action::make('download_transmittal-export.pdf')
|
||||
Action::make('download_transmittal_export')
|
||||
->label('Download PDF File')
|
||||
->url(Storage::url('transmittal-export.pdf'), true)
|
||||
->url(Storage::url($filename), true)
|
||||
->markAsRead(),
|
||||
])
|
||||
->sendToDatabase($this->user);
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Jobs;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use App\Models\Transmittal;
|
||||
use App\Models\User;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Filament\Notifications\Notification;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
@@ -20,7 +21,7 @@ class TransmittalPDFExportJob implements ShouldQueue
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*/
|
||||
public function __construct(private $user, private array $ids)
|
||||
public function __construct(private User $user, private array $ids)
|
||||
{}
|
||||
|
||||
/**
|
||||
@@ -28,6 +29,8 @@ class TransmittalPDFExportJob implements ShouldQueue
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$this->user->refresh();
|
||||
|
||||
$transmittals = Transmittal::query()
|
||||
->with(['client', 'branch', 'files.notes', 'files.remarks'])
|
||||
->whereIn('id', $this->ids)
|
||||
@@ -37,15 +40,17 @@ class TransmittalPDFExportJob implements ShouldQueue
|
||||
'transmittals' => $transmittals,
|
||||
]);
|
||||
|
||||
Storage::disk('public')->put('transmittal-export.pdf', $pdf->output());
|
||||
$filename = 'transmittal-export-'.$this->user->id.'-'.now()->format('YmdHis').'.pdf';
|
||||
|
||||
Storage::disk('public')->put($filename, $pdf->output());
|
||||
|
||||
Notification::make()
|
||||
->success()
|
||||
->title('Export Completed')
|
||||
->actions([
|
||||
Action::make('download_transmittal-export.pdf')
|
||||
Action::make('download_transmittal_export')
|
||||
->label('Download PDF File')
|
||||
->url(Storage::url('transmittal-export.pdf'), true)
|
||||
->url(Storage::url($filename), true)
|
||||
->markAsRead(),
|
||||
])
|
||||
->sendToDatabase($this->user);
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<img src="{{ public_path('images/logo.png') }}" alt="Logo" class="header-logo">
|
||||
{{-- <img src="{{ asset('images/logo-dark.png') }}" alt="Logo" class="header-logo"> --}}
|
||||
<div class="header-title">Transmittal Report</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user