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 Invoicable Laravel Package

sander-van-hooft/laravel-invoicable

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require sander-van-hooft/laravel-invoicable
    php artisan vendor:publish --provider="SanderVanHooft\Invoicable\InvoicableServiceProvider" --tag="migrations"
    php artisan migrate
    

    Publish config (optional):

    php artisan vendor:publish --provider="SanderVanHooft\Invoicable\InvoicableServiceProvider" --tag="config"
    
  2. First Use Case: Create an Invoicable Model Extend your Eloquent model with SanderVanHooft\Invoicable\Traits\Invoicable and define invoiceable relationships:

    use SanderVanHooft\Invoicable\Traits\Invoicable;
    
    class Order extends Model
    {
        use Invoicable;
    
        public function invoice()
        {
            return $this->hasOne(Invoice::class);
        }
    }
    
  3. Generate an Invoice

    $order = Order::find(1);
    $invoice = $order->createInvoice(); // Creates a concept invoice
    
  4. Add Invoice Lines

    $invoice->lines()->create([
        'description' => 'Product 1',
        'quantity' => 2,
        'unit_price' => 10.00,
    ]);
    
  5. Send Invoice via Email

    $invoice->send(); // Uses default email template
    

Implementation Patterns

Core Workflows

1. Invoice Lifecycle Management

  • Concept → Draft → Sent → Paid → Cancelled
    $invoice = Invoice::find(1);
    $invoice->markAsDraft(); // Transition status
    $invoice->markAsSent();
    

2. Dynamic Line Items

Use createLine() or addLine() for dynamic invoicing:

$invoice->addLine([
    'description' => 'Service Fee',
    'quantity' => 1,
    'unit_price' => $serviceFee,
    'tax_rate' => 21, // Optional tax rate
]);

3. Recurring Invoices

Schedule recurring invoices via events or queues:

$invoice = $subscription->createInvoice();
$invoice->setRecurring(true)
        ->setRecurrence('monthly')
        ->setNextDueDate(now()->addMonth());

4. Custom Templates

Publish and override Blade templates:

php artisan vendor:publish --provider="SanderVanHooft\Invoicable\InvoicableServiceProvider" --tag="views"

Modify resources/views/vendor/invoicable/invoice.blade.php.

5. PDF Generation

Generate PDFs on-demand:

$pdf = $invoice->download(); // Returns a PDF response
// OR save to storage:
$invoice->saveAsPdf('path/to/invoice.pdf');

Integration Tips

1. Sync with Payments

Use events to sync invoices with payment gateways:

Invoice::created(function (Invoice $invoice) {
    if ($invoice->isPaid()) {
        event(new InvoicePaid($invoice));
    }
});

2. API Endpoints

Create API routes for invoice management:

Route::get('/invoices/{invoice}', [InvoiceController::class, 'show']);
Route::post('/invoices/{invoice}/send', [InvoiceController::class, 'send']);

3. Notifications

Extend notifications for custom logic:

use SanderVanHooft\Invoicable\Notifications\InvoiceSent;

InvoiceSent::toMailUsing(function ($notifiable, $notification) {
    return (new MailMessage)
        ->subject('Custom Subject')
        ->line('Custom content');
});

4. Localization

Override locale in config or dynamically:

$invoice->setLocale('en_US'); // Per-invoice override

5. Testing

Use factories and assertions:

$invoice = Invoice::factory()->create();
$invoice->assertStatus('concept');
$invoice->assertLinesCount(1);

Gotchas and Tips

Pitfalls

1. Migration Conflicts

  • Issue: Running migrations after modifying invoice_lines table schema.
  • Fix: Reset migrations or use --force:
    php artisan migrate:fresh --force
    

2. Tax Calculation Quirks

  • Issue: Tax rates not applying as expected.
  • Fix: Ensure tax_rate is set on lines or use setTaxRate() on the invoice:
    $invoice->setTaxRate(21); // Applies to all lines
    

3. PDF Generation Failures

  • Issue: Blank PDFs or styling issues.
  • Fix: Verify:
    • DomPDF is installed (composer require barryvdh/laravel-dompdf).
    • Blade templates are correctly published.
    • No syntax errors in custom templates.

4. Status Transitions

  • Issue: Invalid status transitions (e.g., conceptpaid).
  • Fix: Use provided methods:
    $invoice->markAsDraft(); // Valid: concept → draft
    $invoice->markAsSent();  // Valid: draft → sent
    

5. Locale Mismatches

  • Issue: Currency/formatting issues in non-default locales.
  • Fix: Set locale per invoice or globally in config:
    config(['invoicable.locale' => 'en_US']);
    

Debugging Tips

1. Log Invoice Data

Dump invoice data for debugging:

\Log::info('Invoice data:', $invoice->toArray());

2. Check Events

Listen for invoice events to debug lifecycle:

Invoice::created(fn ($invoice) => \Log::debug('Invoice created:', $invoice->id));

3. Validate Line Items

Ensure line items meet requirements:

$line = $invoice->lines()->create([...]);
$line->validate(); // Throws exception if invalid

4. Test PDF Locally

Generate PDFs locally before deployment:

$pdf = $invoice->download();
Storage::disk('local')->put('test.pdf', $pdf->output());

Extension Points

1. Custom Invoice Models

Extend the Invoice model:

class CustomInvoice extends \SanderVanHooft\Invoicable\Models\Invoice
{
    protected $casts = [
        'custom_field' => 'boolean',
    ];
}

2. Line Item Extensions

Add custom fields to invoice_lines:

$invoice->lines()->create([
    'description' => 'Custom Line',
    'custom_data' => json_encode(['key' => 'value']),
]);

3. Hooks for Business Logic

Use model events:

Invoice::created(function (Invoice $invoice) {
    // Add custom logic (e.g., update order status)
});

4. Override PDF Generation

Replace the PDF driver:

$invoice->setPdfDriver('snappy'); // Requires `barryvdh/laravel-snappy`

5. Custom Validation

Extend line item validation:

use SanderVanHooft\Invoicable\Rules\InvoiceLine;

$validator = Validator::make($data, [
    'unit_price' => ['required', new InvoiceLine],
]);
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope