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

Taxation Laravel Package

sylius/taxation

Sylius Taxation Component provides core models and extensible tax calculators to handle taxes for different items, zones, and tax rates in PHP applications. Part of the Sylius eCommerce ecosystem, designed for easy integration and customization.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sylius/taxation
    

    Add the service provider to config/app.php:

    Sylius\Taxation\TaxationServiceProvider::class,
    
  2. First Use Case: Define a basic tax category and rate:

    use Sylius\Taxation\Model\TaxCategoryInterface;
    use Sylius\Taxation\Model\TaxRateInterface;
    
    // Create a tax category (e.g., "Standard")
    $taxCategory = new TaxCategory();
    $taxCategory->setName('Standard');
    
    // Create a tax rate (e.g., 20% VAT for a specific zone)
    $taxRate = new TaxRate();
    $taxRate->setName('VAT 20%');
    $taxRate->setRate(20.0); // 20%
    $taxRate->setCategory($taxCategory);
    $taxRate->setZone('EU'); // Define your zone logic (e.g., country code)
    
  3. Calculate Tax:

    use Sylius\Taxation\Calculator\TaxItemsCalculatorInterface;
    
    $calculator = app()->make(TaxItemsCalculatorInterface::class);
    $taxItems = $calculator->calculate($orderItems, $taxRate);
    
  4. Key Classes to Explore:

    • TaxCategory: Groups taxable items.
    • TaxRate: Defines the tax percentage and applicable zones.
    • TaxItem: Represents a taxable line item in an order.
    • TaxItemsCalculator: Core logic for tax calculation.

Implementation Patterns

Core Workflows

  1. Tax Category Assignment: Assign tax categories to products or product variants:

    $product->setTaxCategory($taxCategory);
    

    Useful for differentiating taxable items (e.g., digital vs. physical goods).

  2. Zone-Based Taxation: Implement zone logic (e.g., country/region) to apply rates dynamically:

    $taxRate->setZone('US-CA'); // State-level taxation
    

    Extend ZoneInterface or use existing implementations like CountryZone.

  3. Order-Level Calculation: Calculate taxes for an entire order:

    $orderTaxItems = $calculator->calculate($order->getItems(), $taxRates);
    $order->setTaxTotal($orderTaxItems->getTotal());
    
  4. Custom Calculators: Extend TaxItemsCalculator for business-specific rules (e.g., tiered pricing):

    class CustomTaxCalculator implements TaxItemsCalculatorInterface {
        public function calculate(array $items, TaxRateInterface $taxRate): TaxItemsCollectionInterface {
            // Custom logic here
        }
    }
    
  5. Integration with Sylius Ecosystem:

    • Use sylius/resource for admin CRUD of tax categories/rates.
    • Integrate with sylius/order to auto-calculate taxes during checkout.

Best Practices

  • Immutable Tax Rates: Treat tax rates as read-only after creation to avoid runtime changes.
  • Caching: Cache tax rate lookups for zones/categories if performance is critical.
  • Testing: Mock TaxItemsCalculator in unit tests to isolate tax logic.

Gotchas and Tips

Pitfalls

  1. Zone Logic:

    • Zones are not enforced by default; implement your own logic (e.g., CustomerZoneProvider).
    • Example pitfall: Assuming setZone() accepts ISO codes without validation.
  2. Tax Category Inheritance:

    • Tax categories are flat by default. Use a tree structure (e.g., NestedSet) if hierarchical rules are needed.
  3. Floating-Point Precision:

    • Tax calculations may suffer from floating-point errors. Use bcmath or round to 2 decimal places:
      $taxRate->setRate(round($rate, 2));
      
  4. Order Item Taxability:

    • Not all order items are taxable. Explicitly mark items as taxable:
      $orderItem->setTaxable(true);
      

Debugging Tips

  • Log Tax Calculations:

    $calculator->calculate($items, $taxRate, ['debug' => true]);
    

    (Extend TaxItemsCalculator to support debug mode.)

  • Validate Tax Rates: Ensure rates are positive and zones are non-empty:

    if ($taxRate->getRate() <= 0) {
        throw new \InvalidArgumentException('Tax rate must be positive.');
    }
    

Extension Points

  1. Custom Calculators: Override TaxItemsCalculator to support:

    • Compound taxes (e.g., state + federal).
    • Discounts on taxes.
  2. Tax Rate Providers: Implement TaxRateProviderInterface to fetch rates dynamically (e.g., from an API):

    class ApiTaxRateProvider implements TaxRateProviderInterface {
        public function getTaxRateForItem(TaxableInterface $item): ?TaxRateInterface {
            // Fetch from external API
        }
    }
    
  3. Event Listeners: Listen to sylius.taxation.calculate events to modify calculations:

    event(new TaxCalculationEvent($items, $taxRate, $taxItems));
    

Configuration Quirks

  • Default Tax Rate: The package doesn’t enforce a default rate. Define one in your config/packages/sylius_taxation.yaml:

    sylius_taxation:
        default_tax_rate: 'default_rate_id'
    
  • Database Schema: Ensure your tax_category and tax_rate tables include:

    • code (for unique identification).
    • created_at/updated_at (for auditing).
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
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
spatie/mailcoach-vapor