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 Filament\Forms\Components\DatePicker;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Filament\Resources\Pages\Concerns\InteractsWithRecord;
|
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\Exports\ExcelExport;
|
||||||
use pxlrbt\FilamentExcel\Columns\Column;
|
use pxlrbt\FilamentExcel\Columns\Column;
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ class GeneralLedger extends Page implements HasTable
|
|||||||
'account.account',
|
'account.account',
|
||||||
])
|
])
|
||||||
->headerActions([
|
->headerActions([
|
||||||
ExportAction::make()
|
ExcelExportAction::make()
|
||||||
->label('Export General Ledger')
|
->label('Export General Ledger')
|
||||||
->exports([
|
->exports([
|
||||||
ExcelExport::make()
|
ExcelExport::make()
|
||||||
|
|||||||
@@ -3,51 +3,12 @@
|
|||||||
namespace App\Filament\Resources\Transmittals\Pages;
|
namespace App\Filament\Resources\Transmittals\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\Transmittals\TransmittalResource;
|
use App\Filament\Resources\Transmittals\TransmittalResource;
|
||||||
use Filament\Actions\Action;
|
|
||||||
use Filament\Resources\Pages\CreateRecord;
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
use Throwable;
|
|
||||||
|
|
||||||
class CreateTransmittal extends CreateRecord
|
class CreateTransmittal extends CreateRecord
|
||||||
{
|
{
|
||||||
protected static string $resource = TransmittalResource::class;
|
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
|
protected function getRedirectUrl(): string
|
||||||
{
|
{
|
||||||
return $this->previousUrl ?? $this->getResource()::getUrl('index');
|
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\Tables\Columns\Layout\View;
|
||||||
use Filament\Actions\BulkActionGroup;
|
use Filament\Actions\BulkActionGroup;
|
||||||
use Filament\Actions\DeleteBulkAction;
|
use Filament\Actions\DeleteBulkAction;
|
||||||
use Filament\Actions\BulkAction;
|
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Actions\ViewAction;
|
use Filament\Actions\ViewAction;
|
||||||
use Filament\Actions\EditAction;
|
use Filament\Actions\EditAction;
|
||||||
@@ -21,8 +20,7 @@ use App\Filament\Resources\Transmittals\Pages\EditTransmittal;
|
|||||||
use App\Commands\Transmittal\GenerateTransmittalSeries;
|
use App\Commands\Transmittal\GenerateTransmittalSeries;
|
||||||
use App\Commands\Transmittal\StoreTransmittalCommand;
|
use App\Commands\Transmittal\StoreTransmittalCommand;
|
||||||
use App\Filament\Resources\TransmittalResource\Pages;
|
use App\Filament\Resources\TransmittalResource\Pages;
|
||||||
use App\Jobs\ExportCompleteJob;
|
use App\Filament\Exports\TransmittalExcelExport;
|
||||||
use App\Jobs\TransmittalPDFExportJob;
|
|
||||||
use App\Models\Branch;
|
use App\Models\Branch;
|
||||||
use App\Models\Client;
|
use App\Models\Client;
|
||||||
use App\Models\Transmittal;
|
use App\Models\Transmittal;
|
||||||
@@ -33,14 +31,12 @@ use Filament\Forms\Components\Repeater;
|
|||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
use Filament\Notifications\Notification;
|
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Support\Enums\FontWeight;
|
use Filament\Support\Enums\FontWeight;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
use Filament\Tables\Filters\SelectFilter;
|
use Filament\Tables\Filters\SelectFilter;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Malzariey\FilamentDaterangepickerFilter\Filters\DateRangeFilter;
|
use Malzariey\FilamentDaterangepickerFilter\Filters\DateRangeFilter;
|
||||||
|
|
||||||
@@ -117,10 +113,6 @@ class TransmittalResource extends Resource
|
|||||||
->toolbarActions([
|
->toolbarActions([
|
||||||
BulkActionGroup::make([
|
BulkActionGroup::make([
|
||||||
DeleteBulkAction::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
|
public static function getTableActions(): array
|
||||||
{
|
{
|
||||||
return [
|
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(),
|
ViewAction::make(),
|
||||||
Action::make('Update Status')
|
Action::make('Update Status')
|
||||||
->fillForm(function ($record) {
|
->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
|
public static function form(Schema $schema): Schema
|
||||||
{
|
{
|
||||||
return $schema
|
return $schema
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Jobs;
|
|||||||
|
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use App\Models\Transmittal;
|
use App\Models\Transmittal;
|
||||||
|
use App\Models\User;
|
||||||
use Barryvdh\DomPDF\Facade\Pdf;
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
@@ -20,12 +21,14 @@ class ExportCompleteJob implements ShouldQueue
|
|||||||
use Queueable;
|
use Queueable;
|
||||||
use SerializesModels;
|
use SerializesModels;
|
||||||
|
|
||||||
public function __construct(private $user, private array $ids)
|
public function __construct(private User $user, private array $ids)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): void
|
public function handle(): void
|
||||||
{
|
{
|
||||||
|
$this->user->refresh();
|
||||||
|
|
||||||
$transmittals = Transmittal::query()
|
$transmittals = Transmittal::query()
|
||||||
->with(['client', 'branch', 'files.notes', 'files.remarks'])
|
->with(['client', 'branch', 'files.notes', 'files.remarks'])
|
||||||
->whereIn('id', $this->ids)
|
->whereIn('id', $this->ids)
|
||||||
@@ -35,15 +38,17 @@ class ExportCompleteJob implements ShouldQueue
|
|||||||
'transmittals' => $transmittals,
|
'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()
|
Notification::make()
|
||||||
->success()
|
->success()
|
||||||
->title('Export Completed')
|
->title('Export Completed')
|
||||||
->actions([
|
->actions([
|
||||||
Action::make('download_transmittal-export.pdf')
|
Action::make('download_transmittal_export')
|
||||||
->label('Download PDF File')
|
->label('Download PDF File')
|
||||||
->url(Storage::url('transmittal-export.pdf'), true)
|
->url(Storage::url($filename), true)
|
||||||
->markAsRead(),
|
->markAsRead(),
|
||||||
])
|
])
|
||||||
->sendToDatabase($this->user);
|
->sendToDatabase($this->user);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Jobs;
|
|||||||
|
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use App\Models\Transmittal;
|
use App\Models\Transmittal;
|
||||||
|
use App\Models\User;
|
||||||
use Barryvdh\DomPDF\Facade\Pdf;
|
use Barryvdh\DomPDF\Facade\Pdf;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
@@ -20,7 +21,7 @@ class TransmittalPDFExportJob implements ShouldQueue
|
|||||||
/**
|
/**
|
||||||
* Create a new job instance.
|
* 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
|
public function handle(): void
|
||||||
{
|
{
|
||||||
|
$this->user->refresh();
|
||||||
|
|
||||||
$transmittals = Transmittal::query()
|
$transmittals = Transmittal::query()
|
||||||
->with(['client', 'branch', 'files.notes', 'files.remarks'])
|
->with(['client', 'branch', 'files.notes', 'files.remarks'])
|
||||||
->whereIn('id', $this->ids)
|
->whereIn('id', $this->ids)
|
||||||
@@ -37,15 +40,17 @@ class TransmittalPDFExportJob implements ShouldQueue
|
|||||||
'transmittals' => $transmittals,
|
'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()
|
Notification::make()
|
||||||
->success()
|
->success()
|
||||||
->title('Export Completed')
|
->title('Export Completed')
|
||||||
->actions([
|
->actions([
|
||||||
Action::make('download_transmittal-export.pdf')
|
Action::make('download_transmittal_export')
|
||||||
->label('Download PDF File')
|
->label('Download PDF File')
|
||||||
->url(Storage::url('transmittal-export.pdf'), true)
|
->url(Storage::url($filename), true)
|
||||||
->markAsRead(),
|
->markAsRead(),
|
||||||
])
|
])
|
||||||
->sendToDatabase($this->user);
|
->sendToDatabase($this->user);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="header">
|
<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 class="header-title">Transmittal Report</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user