schenke-io/laravel-invoice

A robust and flexible PHP package for Laravel that simplifies invoice management, currency handling, and complex VAT calculations.

Installs: 71

Dependents: 1

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/schenke-io/laravel-invoice

v0.3.5 2026-02-05 17:38 UTC

README

Coverage PHPStan Version Downloads Tests License PHP

Laravel Invoice

A robust and flexible PHP package for Laravel that simplifies invoice management, currency handling, and complex VAT calculations.

cover

Key Benefits

  • Precise Financial Calculations: Uses cent-based integer arithmetic via the Currency value object, eliminating common floating-point precision errors in financial data.
  • Automated VAT Logic: Built-in support for VAT rules across multiple countries (including DE, AT, FR, CH, and more) with a hierarchical system of InvoiceLineType, VatCategory, and VatRate.
  • Flexible Rendering: Generate clean HTML invoice tables out of the box, with full support for custom Blade templates when you need a personalized look.
  • SEPA Integration: Easily generate SEPA-compliant QR codes (BezahlCode) to facilitate faster and more accurate payments.
  • Developer Friendly: 100% test coverage, strict typing, and comprehensive documentation ensure a reliable and maintainable integration into your Laravel projects.
  • Eloquent Integration: Custom casts for Currency make it easy to work with monetary values directly in your models.

Core Components

Currency Value Object

The Currency class (src/Money/Currency.php) is the heart of all monetary operations. It stores values as integers (cents) and provides a rich set of methods for:

  • Parsing: Use Currency::fromAny($value) to handle strings, floats, integers, and even other Currency instances. It automatically detects EU/US decimal formats.
  • VAT Conversions:
    • vatFromGross(Vat $vat): Extract VAT amount from a gross total.
    • vatFromNet(Vat $vat): Calculate VAT amount from a net total.
    • fromGrossToNet(Vat $vat): Calculate net price from gross.
    • fromNetToGross(Vat $vat): Calculate gross price from net.
  • Arithmetic: Precise plus(), minus(), and times() operations that maintain integer integrity.

Example:

$price = Currency::fromAny("1.234,56 €"); // EU format detected
$vat = new Vat(0.19);
$net = $price->fromGrossToNet($vat);

InvoiceNumeric

InvoiceNumeric (src/Invoicing/InvoiceNumeric.php) orchestrates the creation of an invoice. Its main responsibilities include:

  • Managing invoice metadata (ID, Date, Customer).
  • Collecting invoice lines (addLine()).
  • Tracking total weights (addWeight()).
  • Generating structured view data for rendering via invoiceTableView().
  • Providing a default rendering of the invoice header, body, and footer with automated VAT summaries.

Usage Examples

Here are some examples of how to use the laravel-invoice package, ranging from basic currency operations to complex multi-tax invoices.

1. Basic Currency Operations

The Currency class ensures precision by using cents internally.

use SchenkeIo\Invoice\Money\Currency;

// Create from various formats
$price = Currency::fromFloat(19.99);
$price2 = Currency::fromAny('12,50 €'); // EU format
$price3 = Currency::fromAny('1,234.56'); // US format
$negative = Currency::fromAny('-10,00'); // Negative value

// Arithmetic
$total = $price->plus($price2); // 32.49 €
$discounted = $total->times(0.9); // 10% discount

echo $discounted->str(); // "29,24 €"

2. Simple Invoice Generation

Creating a basic invoice with a single tax rate.

use SchenkeIo\Invoice\Invoicing\InvoiceNumeric;
use SchenkeIo\Invoice\Invoicing\Customer;
use SchenkeIo\Invoice\Invoicing\LineData;
use SchenkeIo\Invoice\Enum\InvoiceLineType;
use Carbon\Carbon;

$customer = new Customer('Jane Doe', 'Main Street 1', '12345', 'Berlin', 'DE');
$invoice = new InvoiceNumeric('INV-2023-001', Carbon::now(), $customer);

// Add items (Gross price automatically calculates Net based on type)
$invoice->addLine(LineData::fromTotalGrossPrice(
    'Web Design Service', 
    119.00, 
    InvoiceLineType::SalesDE
));

// Get HTML table for the invoice
$view = $invoice->invoiceTableView(isGrossInvoice: true);

// Access header/body/footer specifically if needed
$header = $view->header;
$body = $view->body;
$footer = $view->footer;

echo $view->html();

3. Complex Multi-Tax Invoice

Invoices can contain items with different tax categories. The package automatically groups them in the summary.

use SchenkeIo\Invoice\Invoicing\InvoiceNumeric;
use SchenkeIo\Invoice\Invoicing\LineData;
use SchenkeIo\Invoice\Enum\InvoiceLineType;

$invoice = new InvoiceNumeric('INV-002', Carbon::now(), $customer);

// Standard VAT (19% for DE)
$invoice->addLine(LineData::fromTotalNetPrice('Laptop', 1000.00, InvoiceLineType::SalesDE));

// Reduced VAT (7% for DE)
$invoice->addLine(LineData::fromTotalGrossPrice('Technical Book', 10.70, InvoiceLineType::SaleBooksDE));

// Non-taxable deposit
$invoice->addLine(LineData::fromTotalGrossPrice('Security Deposit', 500.00, InvoiceLineType::Deposit));

// The generated HTML will include a detailed tax breakdown section
echo $invoice->invoiceTableView(false)->html();

4. Multi-Country Support

The package supports VAT rates for various countries. You can specify the country code when adding lines.

use SchenkeIo\Invoice\Invoicing\LineData;
use SchenkeIo\Invoice\Enum\InvoiceLineType;

// Austrian Invoice (20% Standard VAT)
$lineAT = LineData::fromTotalNetPrice(
    'Consulting', 
    100.00, 
    InvoiceLineType::SalesDE,  // Base type
    'AT'                       // Country code
);

// French Invoice (20% Standard VAT)
$lineFR = LineData::fromTotalNetPrice(
    'Service', 
    100.00, 
    InvoiceLineType::SalesDE, 
    'FR'
);

5. SEPA QR Code Integration

Generate a SEPA-compliant QR code for easy payments.

use SchenkeIo\Invoice\Banking\SepaCode;

$sepa = SepaCode::fromInvoice(
    $invoice,
    'Schenke Io',
    'DE12345678901234567890',
    'Invoice',
    'ABCDEFGH' // optional BIC
);

// Get a Data URI for an <img> tag
echo '<img src="' . $sepa->dataUri() . '" />';

Currency

Value object representing a monetary currency.

Public methods of Currency

method summary
fromAny static constructor from any value
fromFloat static constructor from a float value
fromCents static constructor from cents
vatFromGross VAT amount from the gross price, given a VAT rate.
vatFromNet Calculate the VAT amount from the net price, given a VAT rate.
fromGrossToNet convert a gross value to a net value using VAT
fromNetToGross Convert a net value to a gross value using VAT
toFloat exports to float
str exports to formatted currency string
plus adds two objects
minus subtracts two objects
times multiplies the object by a factor
toLivewire exports to Livewire format (numeric scalar)
fromLivewire static constructor from Livewire format (numeric scalar)
isEmpty Check if the object is empty (zero)

Vat

Represents a Value Added Tax (VAT) rate and provides factory methods for countries.

Public methods of Vat

method summary
country Get a country instance by its ISO code.
fromId Create a VAT instance from a numeric ID (e.g. '190' for 19.0%).
fromRate Create a VAT instance from a float rate (e.g. 0.19 for 19%).

VatCategory

Defines the high-level tax categories based on the analysis from

Public methods of VatCategory

method summary
description German description of the category.
vatRate -
hasVat Checks if this transaction case involves VAT.
isReverseCharge Checks if this transaction case is a reverse charge case.
cases -
from -
tryFrom -

InvoiceNumeric

Main class for managing invoice data and calculations.

Public methods of InvoiceNumeric

method summary
getTotalGrossPrice Get the total gross price of the invoice.
getTotalNetPrice Get the total net price of the invoice.
addWeight take the weight in grams and add it to the total weight
addLine add the lines with automatic positions
payMe show pay me information
isEmpty the total is zero
invoiceTableView Prepare data for a Blade template or raw HTML rendering.

Customer

Data transfer object for customer information.

LineData

Representation of a single line item on an invoice.

Public methods of LineData

method summary
fromTotalGrossPrice Create a line item from its total gross price.
fromTotalNetPrice Create a line item from its total net price.

InvoiceLineType

Enum defining the various types of line items that can appear on an invoice.

Public methods of InvoiceLineType

method summary
vatCategory Returns the tax category.
vatRate Returns the applicable VAT rate type.
cases -
from -
tryFrom -

InvoiceTableView

Data transfer object for the complete invoice table view.

LineViewBase

Base class for rendering invoice lines as HTML.

Public methods of LineViewBase

method summary
html Generate the HTML for a single invoice line row.

SepaCode

Generator for SEPA QR codes (BezahlCode).

Public methods of SepaCode

method summary
fromInvoice Create a SEPA code instance directly from an invoice.
dataUri Generate the QR code as a PNG data URI.

Custom invoice

To build a custom invoice you first generate a class which extends LineViewBase and implements LineViewInterface.

This class should define the column-alignment in the columns() method.

Then you start a new instance of InvoiceTableView and fill its public data. The columns() method must return keys that correspond to the public properties of your custom line view class.

CSS Styling

The rendering engine uses a configuration-based approach for CSS classes. You can customize the look of your tables by providing a config array to the html() method or by using the default configuration in TableView.

Row Classes

The following keys in the configuration control row-level styling:

  • invoice-row-thead: Classes for the <thead> row.
  • invoice-row-tbody: Classes for rows within <tbody>.
  • invoice-row-tfoot: Classes for rows within <tfoot>.
  • invoice-row-empty: Classes for empty/spacer rows.
  • invoice-row-{LineType}: Classes specifically for rows of a certain InvoiceLineType (e.g., invoice-row-SalesDE).

Cell Classes

The following keys control cell-level alignment and emphasis:

  • invoice-cell-left: Classes for left-aligned cells (default: cell-left).
  • invoice-cell-right: Classes for right-aligned cells (default: cell-right).
  • invoice-cell-bold: Classes for cells that should be bold (default: cell-bold).

Markdown file generated by schenke-io/packaging-tools