GithubHelp home page GithubHelp logo

tax's Introduction

tax

Build Status

A PHP 5.4+ tax management library.

Features:

  • Smart data model designed for fluctuating tax rate amounts ("19% -> 21% on January 1st")
  • Predefined tax rates for EU countries and Switzerland. More to come.
  • Tax resolvers with logic for all major use cases.

Requires commerceguys/zone.

The backstory behind the library design can be found in this blog post.

Don't see your country's tax types and rates in the dataset? Send us a PR!

Data model

Zone 1-1 TaxType 1-n TaxRate 1-n TaxRateAmount

Each tax type has a zone and one or more tax rates. Each tax rate has one or more tax rate amounts.

Example:

  • Tax type: French VAT
  • Zone: "France (VAT)" (covers "France without Corsica" and "Monaco")
  • Tax rates: Standard, Intermediate, Reduced, Super Reduced
  • Tax rate amounts for Standard: 19.6% (until January 1st 2014), 20% (from January 1st 2014)

Tax resolvers

The process of finding the most suitable tax type/rate/amount for the given taxable object is called resolving. Along with the Taxable object, a Context object containing customer and store information is also passed to the system.

Tax is resolved in three steps:

  1. Resolve the tax types.
  2. Resolve the tax rate for each resolved tax type.
  3. Get the tax rate amount for each resolved tax rate (by calling $rate->getAmount($date)).

Tax types and tax rates are resolved by invoking registered resolvers (sorted by priority) until one of them returns a result.

Included tax type resolvers:

  • CanadaTaxTypeResolver (Canada specific logic)

    The store charges the tax defined by the customer’s home province/territory.

    If selling from a store in Quebec to a customer in Ontario, apply the Ontario HST.

  • EuTaxTypeResolver (EU specific logic)

    A French store selling physical products (e.g. t-shirts) will charge French VAT to EU customers.

    A French store selling digital products (e.g. ebooks) from Jan 1st 2015 will apply the EU customer's tax rates (German customer - German VAT, etc)

    A French store will charge the 0% Intra-Community rate if the EU customer has provided a VAT number.

  • DefaultTaxTypeResolver (logic valid for most countries)

    If both the customer and the store belong to the same zone, returns the matched tax type.

    The Serbian store is selling to a Serbian customer, use Serbian VAT.

Included tax rate resolvers:

Users would create a custom resolver for:

  • "No tax in New York for t-shirts under 200$"
  • "No tax for school supplies on september 1st (US tax holiday)"
  • "Reduced rate for ebooks in France and other countries".
  • "Return the tax type / rate referenced by the $taxable object" (explicit place of supply, e.g. "French company providing a training in Spain")

Usage example:

use CommerceGuys\Tax\Repository\TaxTypeRepository;
use CommerceGuys\Tax\Resolver\Engine\TaxTypeResolverEngine;
use CommerceGuys\Tax\Resolver\Engine\TaxRateResolverEngine;
use CommerceGuys\Tax\Resolver\TaxType\CanadaTaxTypeResolver;
use CommerceGuys\Tax\Resolver\TaxType\EuTaxTypeResolver;
use CommerceGuys\Tax\Resolver\TaxType\DefaultTaxTypeResolver;
use CommerceGuys\Tax\Resolver\TaxRate\DefaultTaxRateResolver;
use CommerceGuys\Tax\Resolver\TaxResolver;

// The repository, engine and individual resolvers are usualy initialized by the
// container, this is just a verbose example.
$taxTypeRepository = new TaxTypeRepository();
$taxTypeResolverEngine = new TaxTypeResolverEngine();
$taxTypeResolverEngine->add(new CanadaTaxTypeResolver($taxTypeRepository));
$taxTypeResolverEngine->add(new EuTaxTypeResolver($taxTypeRepository));
$taxTypeResolverEngine->add(new DefaultTaxTypeResolver($taxTypeRepository));
$taxRateResolverEngine = new TaxRateResolverEngine();
$taxRateResolverEngine->add(new DefaultTaxRateResolver());
$resolver = new TaxResolver($taxTypeResolverEngine, $taxRateResolverEngine);

// You can also provide the customer's tax number (e.g. VAT number needed
// to trigger Intra-Community supply rules in EU), list of additional countries
// where the store is registered to collect tax, a different calculation date.
$context = new Context($customerAddress, $storeAddress);

$amounts = $resolver->resolveAmounts($taxable, $context);
// More rarely, if only the types or rates are needed:
$rates = $resolver->resolveRates($taxable, $context);
$types = $resolver->resolveTypes($taxable, $context);

Credits

tax's People

Contributors

bojanz avatar dwkitchen avatar jnicola avatar juliend avatar

Watchers

 avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.