Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Invoices Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require elegantly/laravel-invoices
    php artisan vendor:publish --tag="invoices-migrations"
    php artisan migrate
    php artisan vendor:publish --tag="invoices-config"
    
  2. First Use Case: Generate a simple PDF invoice in a controller:

    use Elegantly\Invoices\Pdf\PdfInvoice;
    use Elegantly\Invoices\Support\{Seller, Buyer, Address};
    
    public function generateInvoice()
    {
        $invoice = new PdfInvoice(
            name: "Invoice #1",
            serial_number: "INV-001",
            seller: new Seller(
                company: "Your Company",
                address: new Address(city: "New York")
            ),
            buyer: new Buyer(name: "John Doe"),
            items: [/* ... */]
        );
    
        return $invoice->stream();
    }
    

Where to Look First

  • Configuration: config/invoices.php for customizing serial numbers, PDF settings, and defaults.
  • Eloquent Model: app/Models/Invoice.php (auto-published) for database storage.
  • PDF Class: PdfInvoice for standalone PDF generation without database storage.
  • Demo: Interactive Demo for visual reference.

Implementation Patterns

Core Workflows

  1. Database-Driven Invoices:

    • Use the Invoice Eloquent model for CRUD operations.
    • Example:
      $invoice = Invoice::create([
          'serial_number' => 'INV-001',
          'type' => \Elegantly\Invoices\Enums\InvoiceType::Invoice,
          'state' => \Elegantly\Invoices\Enums\InvoiceState::Draft,
      ]);
      
  2. Standalone PDF Generation:

    • Use PdfInvoice for one-off or non-persisted invoices.
    • Example:
      $pdf = (new PdfInvoice(...))->stream();
      
  3. PDF Customization:

    • Override the default template (resources/views/vendor/invoices/default.layout).
    • Pass custom data via templateData:
      $pdfInvoice->templateData(['color' => '#FF0000']);
      
  4. Integration with Mailables/Notifications:

    • Attach PDF invoices to emails:
      $invoice->attachPdf($mailable);
      
    • Send via Notifications:
      InvoiceNotification::to($user)->send();
      
  5. Serial Number Management:

    • Auto-generate or manually set serial numbers.
    • Customize format in config/invoices.php:
      'format' => 'PPSSSS-YYCCCC', // e.g., "INV0001-230123"
      

Common Patterns

  • Taxes/Discounts:

    $invoice->addTax(Money::of(10, 'USD'), 'VAT');
    $invoice->addDiscount(InvoiceDiscount::percentOff(10));
    
  • QR Codes:

    $paymentInstruction = new PaymentInstruction(
        qrcode: 'base64_encoded_qr_data'
    );
    
  • Dynamic Logos:

    $invoice->logo = Storage::url('logos/' . $company->logo);
    
  • Livewire Integration:

    public function downloadPdf()
    {
        $pdf = (new PdfInvoice(...))->stream();
        return response()->streamDownload($pdf, 'invoice.pdf');
    }
    

Gotchas and Tips

Pitfalls

  1. PDF Rendering Issues:

    • Symptom: Blank PDFs or missing assets.
    • Fix: Ensure isRemoteEnabled: true in dompdf config and verify paths to logos/fonts.
    • Debug: Check storage_path('app/dompdf') for cached fonts.
  2. Serial Number Conflicts:

    • Symptom: Duplicate serial numbers when auto_generate: true.
    • Fix: Override the generateSerialNumber method in a custom Invoice model or adjust the format to include unique fields (e.g., YYYYMMDDHHMMSS).
  3. Money Calculation Errors:

    • Symptom: Incorrect totals due to rounding.
    • Fix: Configure rounding_mode in config/invoices.php (e.g., RoundingMode::HalfUp).
  4. Template Overrides:

    • Symptom: Custom templates not loading.
    • Fix: Place templates in resources/views/vendor/invoices/ and ensure the template config key matches the filename (without .blade.php).
  5. Cascade Deletion:

    • Symptom: Invoice items not deleted when invoice is deleted.
    • Fix: Set 'cascade_invoice_delete_to_invoice_items': true in config or manually handle soft deletes.

Debugging Tips

  • Log PDF Output:
    file_put_contents(storage_path('app/invoice_debug.pdf'), $pdfInvoice->getPdfOutput());
    
  • Validate Serial Numbers:
    $invoice->serial_number = Invoice::generateSerialNumber();
    
  • Check Dompdf Errors: Enable debug mode in dompdf config:
    'options' => [
        'debugPdf' => true,
    ]
    

Extension Points

  1. Custom Invoice Model:

    class CustomInvoice extends Invoice
    {
        protected $casts = [
            'state' => InvoiceState::class,
            'type' => InvoiceType::class,
        ];
    
        public function generateSerialNumber(): string
        {
            return 'CUSTOM-' . str_pad($this->incrementingId(), 6, '0', STR_PAD_LEFT);
        }
    }
    

    Update config/invoices.php:

    'model_invoice' => App\Models\CustomInvoice::class,
    
  2. Custom PdfInvoice Class: Extend PdfInvoice to add domain-specific logic:

    class CustomPdfInvoice extends PdfInvoice
    {
        public function __construct(array $options = [])
        {
            $options['templateData']['custom_field'] = 'value';
            parent::__construct($options);
        }
    }
    
  3. Event Listeners: Listen for invoice events (e.g., InvoiceCreated):

    Invoice::created(function ($invoice) {
        // Send Slack notification, log to database, etc.
    });
    
  4. Testing: Use the PdfInvoice class directly in tests to avoid database dependencies:

    public function testPdfGeneration()
    {
        $pdf = new PdfInvoice(...);
        $this->assertStringContainsString('Invoice', $pdf->getPdfOutput());
    }
    

Configuration Quirks

  • Google Fonts: Add URLs to template_data.fonts and ensure fontDir is writable.
  • Logo Paths: Use absolute paths (e.g., storage_path('app/logo.png')) or base64 strings for dynamic logos.
  • Currency: Ensure default_currency matches your laravel-money setup (e.g., USD).

Performance Tips

  • Batch Processing: Use chunk() for large invoice exports:
    Invoice::chunk(100, function ($invoices) {
        foreach ($invoices as $invoice) {
            $invoice->generatePdf();
        }
    });
    
  • Queue PDF Generation:
    InvoiceGenerated::dispatch($invoice)->delay(now()->addMinutes(5));
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky