elegantly / laravel-invoices
Store invoices safely in your Laravel application
Installs: 839
Dependents: 0
Suggesters: 0
Security: 0
Stars: 170
Watchers: 3
Forks: 15
Open Issues: 1
Requires
- php: ^8.1
- dompdf/dompdf: ^3.1
- elegantly/laravel-money: ^2.1.0
- illuminate/contracts: ^11.0||^12.0
- spatie/laravel-package-tools: ^1.14
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1
- orchestra/testbench: ^9.0.0||^10.0.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/extension-installer: ^1.3||^2.0
- phpstan/phpstan-deprecation-rules: ^1.1||^2.0
- phpstan/phpstan-phpunit: ^1.3||^2.0
- dev-main
- v4.3.1
- v4.3.0
- v4.2.2
- v4.2.1
- v4.2.0
- v4.1.3
- v4.1.2
- v4.1.1
- v4.1.0
- v4.0.3
- v4.0.2
- v4.0.1
- v4.0.0
- v3.5.5
- v3.5.4
- v3.5.3
- v3.5.2
- v3.5.1
- v3.5.0
- v3.4.1
- v3.4.0
- v3.3.6
- v3.3.5
- v3.3.4
- v3.3.3
- v3.3.2
- v3.3.1
- v3.3.0
- v3.2.1
- v3.2.0
- v3.1.2
- v3.1.1
- v3.1.0
- v3.0.0
- v2.3.7
- v2.3.6
- v2.3.5
- v2.3.4
- v2.3.3
- v2.3.2
- v2.3.1
- v2.3.0
- v2.2.4
- v2.2.3
- v2.2.2
- v2.2.1
- v2.2
- v2.1.7
- v2.1.6
- v2.1.5
- v2.1.4
- v2.1.3
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.3
- v2.0.2
- v2.0.1
- v2.0.0
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v0.1.x-dev
- v0.1.1
- v0.1.0
- dev-dev
This package is auto-updated.
Last update: 2025-05-26 09:37:49 UTC
README
This package provides a robust, easy-to-use system for managing invoices within a Laravel application, with options for database storage, serial numbering, and PDF generation.
Interactive Demo
Try out the interactive demo to explore package capabilities.
Table of Contents
- Requirements
- Installation
- The
PdfInvoice
Class - The
Invoice
Eloquent Model- Complete Example
- Generating Unique Serial Numbers
- Using Multiple Prefixes and Series for Serial Numbers
- Customizing the Serial Number Format
- Converting an
Invoice
Model to aPdfInvoice
- Display, Download, and Store Invoices
- Attaching Invoices to Mailables
- Attaching Invoices to Notifications
- Customizing PDF Output from the Model
- Casting
state
andtype
to Enums - Using a Dynamic Logo
- Testing
- Changelog
- Contributing
- Security Vulnerabilities
- Credits
- License
Requirements
- PHP 8.1+
- Laravel 11.0+
dompdf/dompdf
for PDF renderingelegantly/laravel-money
for money computation which usebrick\money
under the hood
Installation
You can install the package via composer:
composer require elegantly/laravel-invoices
If you intent to store your invoices using the Eloquent Model, you must publish and run the migrations with:
php artisan vendor:publish --tag="invoices-migrations"
php artisan migrate
You can publish the config file with:
php artisan vendor:publish --tag="invoices-config"
This is the contents of the published config file:
use Elegantly\Invoices\Models\Invoice; use Elegantly\Invoices\InvoiceDiscount; use Elegantly\Invoices\Models\InvoiceItem; use Elegantly\Invoices\Enums\InvoiceType; return [ 'model_invoice' => Invoice::class, 'model_invoice_item' => InvoiceItem::class, 'discount_class' => InvoiceDiscount::class, 'cascade_invoice_delete_to_invoice_items' => true, 'serial_number' => [ /** * If true, will generate a serial number on creation * If false, you will have to set the serial_number yourself */ 'auto_generate' => true, /** * Define the serial number format used for each invoice type * * P: Prefix * S: Serie * M: Month * Y: Year * C: Count * Example: IN0012-220234 * Repeat letter to set the length of each information * Examples of formats: * - PPYYCCCC : IN220123 (default) * - PPPYYCCCC : INV220123 * - PPSSSS-YYCCCC : INV0001-220123 * - SSSS-CCCC: 0001-0123 * - YYCCCC: 220123 */ 'format' => 'PPYYCCCC', /** * Define the default prefix used for each invoice type */ 'prefix' => [ InvoiceType::Invoice->value => 'IN', InvoiceType::Quote->value => 'QO', InvoiceType::Credit->value => 'CR', InvoiceType::Proforma->value => 'PF', ], ], 'date_format' => 'Y-m-d', 'default_seller' => [ 'name' => null, 'address' => [ 'street' => null, 'city' => null, 'postal_code' => null, 'state' => null, 'country' => null, ], 'email' => null, 'phone' => null, 'tax_number' => null, 'company_number' => null, ], /** * ISO 4217 currency code */ 'default_currency' => 'USD', 'pdf' => [ 'paper' => [ 'size' => 'a4', 'orientation' => 'portrait', ], /** * Default DOM PDF options * * @see Available options https://github.com/barryvdh/laravel-dompdf#configuration */ 'options' => [ 'isRemoteEnabled' => true, 'isPhpEnabled' => false, 'fontHeightRatio' => 1, /** * Supported values are: 'DejaVu Sans', 'Helvetica', 'Courier', 'Times', 'Symbol', 'ZapfDingbats' */ 'defaultFont' => 'Helvetica', 'fontDir' => storage_path('fonts'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782) 'fontCache' => storage_path('fonts'), 'tempDir' => sys_get_temp_dir(), 'chroot' => realpath(base_path()), ], /** * The logo displayed in the PDF */ 'logo' => null, /** * The template used to render the PDF */ 'template' => 'default.layout', 'template_data' => [ /** * The color displayed at the top of the PDF */ 'color' => '#050038', ], ], ];
The PdfInvoice
Class
This package provides a powerful, standalone PdfInvoice
class. Its main functionalities include the ability to:
- Display your invoice as a PDF document.
- Render your invoice within a Blade view.
The PdfInvoice
class is also integrated with the Invoice
Eloquent Model, allowing you to easily convert an Invoice
model instance into its PDF representation.
You can even use this package exclusively for the PdfInvoice
class if you don't require database storage for your invoices.
Full Example
use \Elegantly\Invoices\Pdf\PdfInvoice; use \Elegantly\Invoices\Pdf\PdfInvoiceItem; use \Elegantly\Invoices\Support\Seller; use \Elegantly\Invoices\Support\Buyer; use \Elegantly\Invoices\Support\Address; use \Elegantly\Invoices\Support\PaymentInstruction; use \Elegantly\Invoices\InvoiceDiscount; use Brick\Money\Money; $pdfInvoice = new PdfInvoice( name: "Invoice", state: "paid", serial_number: "INV-241200001", seller: new Seller( company: 'elegantly', name: 'Quentin Gabriele', // (optional) address: new Address( street: "Place de l'Opéra", city: 'Paris', postal_code: '75009', country: 'France', ), email: 'john.doe@example.com', tax_number: 'FR123456789', fields: [ // Custom fields to display with the seller "foo" => "bar" ] ), buyer: new Buyer( company: "Doe Corporation" // (optional) name: 'John Doe', // (optional) address: new Address( street: '8405 Old James St.Rochester', city: 'New York', postal_code: '14609', state: 'NY', country: 'United States', ), shipping_address: new Address( // (optional) street: [ // multiple lines street '8405 Old James St.Rochester' 'Apartment 1', ], city: 'New York', postal_code: '14609', state: 'NY', country: 'United States', ), email: 'john.doe@example.com', fields: [ // Custom fields to display with the buyer "foo" => "bar" ] ), description: "An invoice description", created_at: now(), due_at: now(), paid_at: now(), tax_label: "VAT France (20%)", fields: [ // custom fields to display at the top 'Order' => "PO0234" ], items: [ new PdfInvoiceItem( label: "Laratranslate Unlimitted" , unit_price: Money::of(99.0, 'USD'), tax_percentage: 20.0, quantity: 1, description: "Elegant All-in-One Translations Manager for Laravel", ), ], discounts: [ new InvoiceDiscount( name: "Summer offer", code: "SUMMER", percent_off: 50, ) ], paymentInstructions: [ new PaymentInstruction( name: 'Bank Transfer', description: 'Make a direct bank transfer using the details below.', qrcode: 'data:image/png;base64,' . base64_encode( file_get_contents(__DIR__.'/../resources/images/qrcode.png') ), fields: [ 'Bank Name' => 'Acme Bank', 'Account Number' => '12345678', 'IBAN' => 'GB12ACME12345678123456', 'SWIFT/BIC' => 'ACMEGB2L', 'Reference' => 'INV-0032/001', '<a href="#">Pay online</a>', ], ), ], logo: public_path('/images/logo.png'), // local path or base64 string template: "default.layout", // use the default template or use your own templateData: [ // custom date to pass to the template 'color' => '#050038' ], );
Rendering the Invoice as a PDF
namespace App\Http\Controllers; use Elegantly\Invoices\Pdf\PdfInvoice; class InvoiceController extends Controller { public function showAsPdf() { $pdfInvoice = new PdfInvoice( // ... ); return $pdfInvoice->stream(); } }
Storing the PDF in a file
namespace App\Http\Controllers; use Elegantly\Invoices\Pdf\PdfInvoice; use Illuminate\Support\Facades\Storage; class InvoiceController extends Controller { public function store() { $pdfInvoice = new PdfInvoice( // ... ); Storage::put( "path/to/{$pdfInvoice->getFilename()}", $pdfInvoice->getPdfOutput() ); // ... } }
Downloading the Invoice as a PDF
From a controller
To download the PDF, simply return the download
method.
namespace App\Http\Controllers; use Elegantly\Invoices\Pdf\PdfInvoice; class InvoiceController extends Controller { public function download() { $pdfInvoice = new PdfInvoice( // ... ); return $pdfInvoice->download( /** * (optional) * The default filename is the serial_number */ filename: 'invoice.pdf' ); } }
From a Livewire component
To download the PDF from a Livewire component, use the streamDownload
method as shown below:
namespace App\Http\Controllers; use Elegantly\Invoices\Pdf\PdfInvoice; class Invoice extends Component { public function download() { $pdfInvoice = new PdfInvoice( // ... ); return response()->streamDownload(function () use ($pdfInvoice) { echo $pdf->getPdfOutput(); }, $pdf->getFilename()); // The default filename is the serial number } }
Rendering the Invoice as a view
namespace App\Http\Controllers; use Elegantly\Invoices\Pdf\PdfInvoice; class InvoiceController extends Controller { public function showAsView() { $pdfInvoice = new PdfInvoice( // ... ); return $pdfInvoice->view(); } }
Rendering the Invoice within a View
You can embed the invoice within a larger Blade view to create interfaces like an "invoice builder," similar to the interactive demo.
To do this, include the main invoice partial in your view as shown below:
<div class="aspect-[210/297] bg-white shadow-md"> @include('invoices::default.invoice', ['invoice' => $invoice]) </div>
This approach allows for seamless integration of the invoice into a dynamic and customizable user interface.
Note
The default template uses Tailwind CSS for styling. This ensures seamless integration with websites already using Tailwind. If your project doesn't use Tailwind, the invoice styling may not appear as intended.
Adding Taxes
Taxes are applied to individual PdfInvoiceItem
item. You can define them either as a percentage or a fixed amount.
Tax by Percentage
To add a tax as a percentage, set the tax_percentage
property on the PdfInvoiceItem
. This value should be a float between 0 and 100.
use \Elegantly\Invoices\Pdf\PdfInvoiceItem; new PdfInvoiceItem( label: "Laratranslate Unlimitted" , unit_price: Money::of(99.0, 'USD'), tax_percentage: 20.0, // a float between 0.0 and 100.0 ),
Tax as a Fixed Amount
To apply a tax as a specific monetary amount, set the unit_tax
property on the PdfInvoiceItem
.
use \Elegantly\Invoices\Pdf\PdfInvoiceItem; new PdfInvoiceItem( label: "Laratranslate Unlimitted" , unit_price: Money::of(99.0, 'USD'), unit_tax: Money::of(19.8, 'USD'), ),
Adding Discounts
Discounts are represented by the InvoiceDiscount
class and are applied to the entire PdfInvoice
. They cannot be attached to individual PdfInvoiceItem
s at this time.
- You can add multiple discounts to a single invoice.
- Discounts can be specified as a fixed amount (
amount_off
) or a percentage (percent_off
). If both are provided for the same discount, theamount_off
value takes precedence.
Discount by Percentage
To apply a discount as a percentage, set the percent_off
property.
use \Elegantly\Invoices\Pdf\PdfInvoice; use \Elegantly\Invoices\InvoiceDiscount; use Brick\Money\Money; $pdfInvoice = new PdfInvoice( // ... discounts: [ new InvoiceDiscount( name: "Summer offer", code: "SUMMER", percent_off: 20.0, ) ], );
Discount as a Fixed Amount
To apply a discount as a fixed amount, set the amount_off
property.
use \Elegantly\Invoices\Pdf\PdfInvoice; use \Elegantly\Invoices\InvoiceDiscount; use Brick\Money\Money; $pdfInvoice = new PdfInvoice( // ... discounts: [ new InvoiceDiscount( name: "Summer offer", code: "SUMMER", amount_off: Money::of(20.0, 'USD'), ) ], );
Adding Payment Instructions
You can include detailed payment instructions directly within the generated PDF invoice. This can be helpful for providing bank transfer details, QR codes for quick payments, and custom payment links.
Here’s an example of how to add a payment instruction:
use \Elegantly\Invoices\Pdf\PdfInvoice; use \Elegantly\Invoices\Support\PaymentInstruction; $pdfInvoice = new PdfInvoice( // ... paymentInstructions: [ new PaymentInstruction( name: 'Bank Transfer', description: 'Make a direct bank transfer using the details below.', qrcode: 'data:image/png;base64,' . base64_encode( file_get_contents(__DIR__.'/../resources/images/qrcode.png') ), fields: [ 'Bank Name' => 'Acme Bank', 'Account Number' => '12345678', 'IBAN' => 'GB12ACME12345678123456', 'SWIFT/BIC' => 'ACMEGB2L', 'Reference' => 'INV-0032/001', '<a href="#">Pay online</a>', ], ), ] );
Note: You can include HTML tags (e.g., links) within the
fields
array for interactive content.
QR Code Generation
To dynamically generate QR codes, I recommend using the chillerlan/php-qrcode
package. It provides a simple and flexible API for generating QR codes in various formats.
Customization
Customizing Fonts
See the Dompdf font guide.
Customizing the Invoice Template
To customize the invoice template, first publish the package's views:
php artisan vendor:publish --tag="invoices-views"
After publishing, you can modify the Blade files in resources/views/vendor/invoices/
to suit your needs.
Note
If you introduce new CSS classes in your custom template, ensure you define their styles in the style.blade.php file.
Alternatively, to use a completely different custom template, you can specify its path in the configuration file:
Warning
Your custom template file must be in resources/views/vendor/invoices
return [ // ... 'pdf' => [ /** * The template used to render the PDF */ 'template' => 'my-custom.layout', 'template_data' => [ /** * The color displayed at the top of the PDF */ 'color' => '#050038', ], ], ];
Ensure that your custom template follows the same structure and conventions as the default one to maintain compatibility with various use cases.
The Invoice
Eloquent Model
The design of the Invoice
Eloquent Model closely mirrors that of the PdfInvoice
class.
This model provides powerful features for:
- Generating unique and complex serial numbers.
- Attaching your invoice to any other Eloquent model.
- Easily including your invoice as an attachment in emails.
Note
Remember to publish and run the database migrations
Complete Example
The following example demonstrates how to create and store an invoice.
For this illustration, let's assume the following application structure:
Team
models haveUser
models.Team
models can have multipleInvoice
models.Invoice
models can be attached toOffer
models.
use App\Models\Team; use App\Models\Order; use Brick\Money\Money; use Elegantly\Invoices\Models\Invoice; use Elegantly\Invoices\Enums\InvoiceState; use Elegantly\Invoices\Enums\InvoiceType; $customer = Team::find(1); $order = Order::find(2); $invoice = new Invoice( 'type'=> "invoice", 'state'=> "paid", 'seller_information'=> config('invoices.default_seller'), 'buyer_information'=>[ 'company'=> "Doe Corporation" // (optional) 'name'=> 'John Doe', // (optional) 'address'=> [ 'street'=> '8405 Old James St.Rochester', 'city'=> 'New York', 'postal_code'=> '14609', 'state'=> 'NY', 'country'=> 'United States', ], 'shipping_address'=> [ // (optional) 'street'=> [ // multiple lines street '8405 Old James St.Rochester', 'Apartment 1', ], 'city'=> 'New York', 'postal_code'=> '14609', 'state'=> 'NY', 'country'=> 'United States', ] 'email'=> 'john.doe@example.com', 'fields'=> [ // Custom fields to display with the buyer "foo" => "bar" ] ], 'description'=> "An invoice description", 'due_at'=> now(), 'paid_at'=> now(), 'tax_type'=> "eu_VAT_FR", 'tax_exempt'=> null, ); // Learn more about the serial number in the next section $invoice->configureSerialNumber( prefix: "ORD", serie: $customer->id, year: now()->format('Y'), month: now()->format('m') ) $invoice->buyer()->associate($customer); // optionnally associate the invoice to any model $invoice->invoiceable()->associate($order); // optionnally associate the invoice to any model $invoice->save(); $invoice->items()->saveMany([ new InvoiceItem([ 'label' => "Laratranslate Unlimitted", 'description' => "Elegant All-in-One Translations Manager for Laravel", 'unit_price' => Money::of(99.0, 'USD'), 'tax_percentage' => 20.0, 'quantity' => 1, ]), ]);
Generating Unique Serial Numbers
This package provides a simple and reliable way to generate serial numbers automatically, such as "INV240001".
You can configure the format of your serial numbers in the configuration file. The default format is PPYYCCCC
, where each letter has a specific meaning (see the config file for details).
When invoices.serial_number.auto_generate
is set to true
, a unique serial number is assigned to each new invoice automatically.
Serial numbers are generated sequentially, with each new serial number based on the latest available one. To define what qualifies as the previous
serial number, you can extend the Elegantly\Invoices\Models\Invoice
class and override the getPreviousInvoice
method.
By default, the previous invoice is determined based on criteria such as prefix, series, year, and month for accurate, scoped numbering.
Using Multiple Prefixes and Series for Serial Numbers
In more complex applications, you may need to use different prefixes and/or series for your invoices.
For instance, you might want to define a unique series for each user, creating serial numbers that look like: INV0001-2400X
, where 0001
represents the user’s ID, 24
the year and X
the index of the invoice.
Note
When using IDs for series, it's recommended to plan for future growth to avoid overflow. Even if you have a limited number of users now, ensure that the ID can accommodate the maximum number of digits allowed by the serial number format.
When creating an invoice, you can dynamically specify the prefix and series with configureSerialNumber
method:
use Elegantly\Invoices\Models\Invoice; $invoice = new Invoice(); $invoice->configureSerialNumber( prefix: "ORG", serie: $buyer_id, );
Customizing the Serial Number Format
In most cases, the format of your serial numbers should remain consistent, so it's recommended to set it in the configuration file.
The format you choose will determine the types of information you need to provide to configureSerialNumber
.
Below is an example of the most complex serial number format you can create with this package:
$invoice = new Invoice(); $invoice->configureSerialNumber( format: "PP-SSSSSS-YYMMCCCC", prefix: "IN", serie: 100, year: now()->format('Y'), month: now()->format('m') ); $invoice->save(); $invoice->serial_number; // IN-000100-24010001
Converting an Invoice
Model to a PdfInvoice
You can obtained a PdfInvoice
class from your Invoice
model by calling the toPdfInvoice
method:
$invoice = Invoice::first(); $pdfInvoice = $invoice->toPdfInvoice();
Display, Download, and Store Invoices
You can then stream the PdfInvoice
instance directly or initiate a download:
namespace App\Http\Controllers; use App\Models\Invoice; use Illuminate\Http\Request; class InvoiceController extends Controller { public function show(Request $request, string $serial) { /** @var Invoice $invoice */ $invoice = Invoice::where('serial_number', $serial)->firstOrFail(); $this->authorize('view', $invoice); return $invoice->toPdfInvoice()->stream(); } public function download(Request $request, string $serial) { /** @var Invoice $invoice */ $invoice = Invoice::where('serial_number', $serial)->firstOrFail(); $this->authorize('view', $invoice); return $invoice->toPdfInvoice()->download(); } public function store(Request $request, string $serial) { /** @var Invoice $invoice */ $invoice = Invoice::where('serial_number', $serial)->firstOrFail(); Storage::put( "path/to/invoice.pdf", $invoice->toPdfInvoice()->getPdfOutput() ); // ... } }
Attaching Invoices to Mailables
You can easily attach an invoice to your Mailable
as follows:
namespace App\Mail; use App\Models\Invoice; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; class PaymentInvoice extends Mailable { use Queueable, SerializesModels; /** * Create a new message instance. */ public function __construct( protected Invoice $invoice, ) {} public function attachments(): array { return [ $this->invoice->toMailAttachment() ]; } }
Attaching Invoices to Notifications
You can easily attach an invoice to your Notification
as follows:
namespace App\Mail; use App\Models\Invoice; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; use Illuminate\Notifications\Messages\MailMessage; class PaymentInvoice extends Notification implements ShouldQueue { use Queueable; /** * Create a new message instance. */ public function __construct( protected Invoice $invoice, ) {} public function toMail($notifiable) { return (new MailMessage) ->attach($this->invoice->toMailAttachment()); } }
Customizing PDF Output from the Model
To customize how your Invoice
model is converted into a PdfInvoice
object, follow these steps:
- Create a Custom Invoice Model:
Define your own App\Models\Invoice
class and ensure it extends the base Elegantly\Invoices\Models\Invoice
.
namespace App\Models; class Invoice extends \Elegantly\Invoices\Models\Invoice { // ... }
- Override the
toPdfInvoice
Method:
In your custom Invoice
model, override the toPdfInvoice
method. This is where you'll implement your specific logic to construct and return the PdfInvoice
object with your desired customizations.
namespace App\Models; use Elegantly\Invoices\Pdf\PdfInvoice; class Invoice extends \Elegantly\Invoices\Models\Invoice { function toPdfInvoice(): PdfInvoice { return new PdfInvoice( // ... your custom PdfInvoice properties and configuration ); } }
- Update the Package Configuration:
First, if you haven't already, publish the package's configuration file:
php artisan vendor:publish --tag="invoices-config"
Then, modify the config/invoices.php
file to tell the package to use your custom model by updating the model_invoice
key:
return [ // ... 'model_invoice' => \App\Models\Invoice::class, // ... ];
Using a Custom PdfInvoice Class
You can extend the default PdfInvoice class provided by the package to customize its behavior, such as changing the generated filename or adding additional logic.
- Create Your Custom PdfInvoice Class
class PdfInvoice extends \Elegantly\Invoices\Pdf\PdfInvoice { public function __construct( // your custom constructor ){ // ... } public function getFilename(): string { return str($this->serial_number) ->replace(['/', '\\'], '_') ->append('.pdf') ->value(); } }
In this example, we're overriding the getFilename
method.
- Return Your Custom
PdfInvoice
from the Invoice Model
Update your Invoice
model to return an instance of your custom PdfInvoice
class.
namespace App\Models; use App\ValueObjects\PdfInvoice; class Invoice extends \Elegantly\Invoices\Models\Invoice { function toPdfInvoice(): PdfInvoice { return new PdfInvoice( // Pass any required data to your custom PdfInvoice constructor ); } }
By overriding the toPdfInvoice
method, you can inject your custom logic while preserving compatibility with the rest of the package.
Casting state
and type
to Enums
By default, the type
and state
properties on the Invoice
model are stored as strings. This approach offers flexibility, as it doesn't restrict you to predefined values and they are not automatically cast to Enum objects.
However, you might prefer to cast these properties to Enum objects for better type safety and code clarity. You can use your own custom Enums or the ones provided by this package (e.g., Elegantly\Invoices\Enums\InvoiceState
, Elegantly\Invoices\Enums\InvoiceType
).
To enable Enum casting for these properties, follow these steps:
- Create a Custom
Invoice
Model:
Define your own App\Models\Invoice
class that extends \Elegantly\Invoices\Models\Invoice
.
In this custom model, override the casts()
method to specify the Enum classes for the type
and state
attributes.
namespace App\Models; use Elegantly\Invoices\Enums\InvoiceState; use Elegantly\Invoices\Enums\InvoiceType; class Invoice extends \Elegantly\Invoices\Models\Invoice { protected function casts(): array { return [ ...parent::casts(), // Merge with parent casts for other potential attributes 'type' => InvoiceType::class, 'state' => InvoiceState::class, ]; } }
- Publish Package Configuration:
If you haven't already, publish the package's configuration file:
php artisan vendor:publish --tag="invoices-config"
- Update Configuration to Use Your Custom Model:
Modify the config/invoices.php
file and update the model_invoice
key to point to your newly created custom Invoice
model:
return [ // ... 'model_invoice' => \App\Models\Invoice::class, // ... ];
Using a Dynamic Logo
In scenarios where the invoice logo needs to be set dynamically (for instance, allowing users to upload their own company logo), you can achieve this by overriding the getLogo
method in your Invoice
model.
Follow these steps:
- Create a Custom
Invoice
Model:
Define your own App\Models\Invoice
that extends \Elegantly\Invoices\Models\Invoice
class.
Inside this custom model, implement the getLogo
method to return the path or data for your dynamic logo.
Note
The getLogo
method must return either a base64-encoded data URL (e.g., data:image/png;base64,...
) or a local filesystem path to the logo image.
Here's an example of how you might implement this:
namespace App\Models; . use Illuminate\Http\File; class Invoice extends \Elegantly\Invoices\Models\Invoice { public function getLogo(): ?string { $logoPath = public_path('logo.png'); // Replace with your dynamic logic if (!file_exists($logoPath)) { return null; // Or a default logo } $file = new File($logoPath); $mime = $file->getMimeType(); $logoData = "data:{$mime};base64," . base64_encode(file_get_contents($logoPath)); // Use file_get_contents for raw data return $logoData; } }
- Publish Package Configuration:
If you haven't done so already, publish the package's configuration file:
php artisan vendor:publish --tag="invoices-config"
- Update Configuration to Use Your Custom Model:
Modify the config/invoices.php
file and update the model_invoice
key to point to your custom Invoice
model:
return [ // ... 'model_invoice' => \App\Models\Invoice::class, // ... ];
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.