elegantly/laravel-invoices
Manage invoices in Laravel with database storage, serial numbering, and PDF generation. Create, render, store, and download invoices as PDFs or views, add taxes/discounts and payment instructions (QR codes), and customize templates.
Installation:
composer require elegantly/laravel-invoices
php artisan vendor:publish --tag="invoices-migrations"
php artisan migrate
For config publishing (optional but recommended):
php artisan vendor:publish --tag="invoices-config"
First Use Case: Generate a simple PDF invoice without database storage:
use Elegantly\Invoices\Pdf\PdfInvoice;
use Elegantly\Invoices\Support\{Seller, Buyer, Address};
$pdf = new PdfInvoice(
name: "Test Invoice",
serial_number: "INV-001",
seller: new Seller(
company: "Your Company",
address: new Address(city: "New York")
),
buyer: new Buyer(name: "John Doe"),
items: [/* items array */]
);
return $pdf->stream();
PdfInvoice class in Pdf/ namespaceInvoice Eloquent model in Models/ namespaceconfig/invoices.php)resources/views/vendor/invoices/// Create invoice via model
$invoice = Invoice::create([
'serial_number' => 'INV-001',
'seller_id' => auth()->id(),
'buyer_name' => 'Client Co.',
// ...
]);
// Generate PDF from model
return $invoice->pdf()->download();
// For non-database invoices (e.g., admin previews)
$pdf = new PdfInvoice(/* params */);
return $pdf->stream();
// In Livewire component
public function downloadPdf()
{
$pdf = new PdfInvoice(/* params */);
return $pdf->download();
}
// In Mailable
public function build()
{
$invoice = Invoice::find(1);
return $this->attachData(
$invoice->pdf()->getPdfOutput(),
$invoice->getFilename()
);
}
With Livewire:
// Livewire component
public function render()
{
$pdf = new PdfInvoice(/* params */);
return view('livewire.invoice-view', [
'pdfPreview' => $pdf->getHtml()
]);
}
With Queues:
// Dispatch PDF generation job
GenerateInvoicePdf::dispatch($invoiceId);
// Job class
public function handle()
{
$invoice = Invoice::find($this->invoiceId);
Storage::put(
"invoices/{$invoice->getFilename()}",
$invoice->pdf()->getPdfOutput()
);
}
Custom Templates:
php artisan vendor:publish --tag="invoices-views"
default.layout in resources/views/vendor/invoices/PDF Generation Failures:
isRemoteEnabled: true in config and verify:
'options' => [
'isRemoteEnabled' => true,
'fontDir' => storage_path('app/dompdf'),
'fontCache' => storage_path('app/dompdf'),
]
Serial Number Conflicts:
auto_generate: true'serial_number' => [
'format' => 'PPSSSS-YYCCCC',
'prefix' => [
InvoiceType::Invoice->value => 'INV',
InvoiceType::Quote->value => 'QOT',
],
]
Money Calculation Errors:
'rounding_mode' => RoundingMode::HalfUp,
Template Issues:
Use dd($pdf->getHtml()) to inspect raw HTML before PDF conversion.
Storage Paths:
Verify storage_path() permissions and Dompdf cache paths.
Enum Casting:
Ensure state and type are properly cast in your Invoice model:
protected $casts = [
'state' => InvoiceState::class,
'type' => InvoiceType::class,
];
Custom PDF Classes:
Extend PdfInvoice for reusable configurations:
class CustomPdfInvoice extends PdfInvoice
{
public function __construct()
{
parent::__construct(/* default params */);
$this->templateData['color'] = '#2c3e50';
}
}
Dynamic Logo Handling:
Override logo logic in Invoice model:
public function getLogoAttribute()
{
return $this->seller->company === 'Premium'
? 'premium-logo.png'
: 'default-logo.png';
}
Event Listeners:
Hook into invoice events (e.g., InvoiceCreated):
Invoice::created(function ($invoice) {
// Send notification or log
});
Google Fonts:
Add URLs to template_data.fonts and ensure fontDir is writable:
'fonts' => [
'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400&display=swap',
],
Multi-Currency:
Use elegantly/laravel-money for dynamic currency handling:
use Brick\Money\Money;
$item->unit_price = Money::of(99.99, $invoice->currency);
Localization: Override Blade templates for language-specific content:
// In your template
@php echo __('invoices.payment_due', ['date' => $invoice->due_at]); @endphp
How can I help you explore Laravel packages today?