NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Shops for Laravel

Daňové sadzby

Každý obchod vlastní ľubovoľný počet riadkov TaxRate. Sadzba má daňovú triedu, voliteľnú krajinu ISO 3166-1 alpha-2 a hodnotu v celých bázických bodoch (1 bp = 0,01 %, takže 1900 = 19,00 % a 850 = 8,5 %):

use RoundlyConsulting\Shops\Contracts\TaxResolver;

$shop->taxRates()->createMany([
    ['name' => 'VAT',        'tax_class' => 'standard', 'rate' => 2000, 'is_default' => true], // 20.00 %
    ['name' => 'DE VAT',     'tax_class' => 'standard', 'rate' => 1900, 'country' => 'DE'],   // 19.00 %
    ['name' => 'LU reduced', 'tax_class' => 'reduced',  'rate' => 850,  'country' => 'LU'],   //  8.50 %
]);

$value = app(TaxResolver::class)->rateFor($shop, 'reduced', 'LU');
$value->basisPoints;             // 850
$value->percentage()->value();   // "8.5" — money's Percentage
$value->toTaxRate();             // money's TaxRate, which does the exact tax math
$value->isZero();                // false

app(TaxResolver::class)->rateFor($shop, 'standard', 'DE');   // 1900 — exact country match
app(TaxResolver::class)->rateFor($shop, 'standard', 'de');   // 1900 — countries match case-insensitively
app(TaxResolver::class)->rateFor($shop, 'standard');         // 2000 — the class default
app(TaxResolver::class)->rateFor(null, 'standard');          // 2000 — the config floor (20 %)

Poradie hľadania

Predvolený DatabaseTaxResolver načíta sadzby obchodu pre danú triedu (podľa priority zostupne, potom podľa id) a vyberie:

  • 1. prvú sadzbu, ktorej krajina sa zhoduje s požadovanou;
  • 2. inak predvolenú sadzbu triedy — sadzbu označenú is_default, najprv tú bez krajiny, inak tú s krajinou, napríklad vašej domovskej;
  • 3. inak sadzbu triedy s najvyššou prioritou bez ohľadu na krajinu;
  • 4. inak záložnú sadzbu z konfigurácie tax_classes — neznáma trieda použije standard a táto záloha sadzbu standard má vždy (dodaných 20 %, ak nie je nastavená).

Kroky 1–3 platia len pre inštancie Shop (alebo podtriedy); obchod null ide rovno na konfiguráciu. Krajiny sa porovnávajú bez ohľadu na veľkosť písmen (de = DE) a krajina sadzby sa ukladá veľkými písmenami. Ceny košíka krajinu neposielajú, takže presná zhoda krajiny (krok 1) nastane len pri objednávkach s doručovacou adresou.

TaxRateValue

use RoundlyConsulting\Money\Money;
use RoundlyConsulting\Shops\Support\Tax\TaxRateValue;

$rate = new TaxRateValue(1900, taxClass: 'standard', country: 'DE', label: 'DE VAT');
TaxRateValue::zero('zero');                                    // a 0 bp rate

$rate->percentage()->value();                                  // "19"
$rate->toTaxRate()->taxInGross(Money::ofMinor(1190, 'EUR'));   // 1.90 EUR

$taxRate->toValue();   // a TaxRate model as a TaxRateValue (label = its name)

Priradenie daňových tried

// What you sell carries a tax class — snapshotted onto cart and order lines:
$variant->update(['tax_class' => 'reduced']);

// What a class costs on a given order right now (its shop, its shipping country):
$order->taxRateFor('reduced');   // TaxRateValue

Riadok objednávky si pri pridaní zafixuje sadzbu, na ktorú sa jeho trieda vyhodnotila (order_items.tax_rate v bázických bodoch a tax_label), takže úprava sadzby ovplyvní len košíky a objednávky vytvorené neskôr.

Dane len z konfigurácie a vlastné resolvery

ConfigTaxResolver berie sadzby výhradne zo shops.tax_classes a ignoruje obchod aj krajinu. Každá nakonfigurovaná sadzba musí byť celé číslo od 0 do 100 (alebo reťazec s ním) — twenty či 19.5 vyhodí InvalidConfigurationException s kľúčom shops.tax_classes.<trieda> namiesto sadzby 0 %:

// config/shops.php — config-only tax, ignoring shop and country
'tax' => [
    'resolver' => \RoundlyConsulting\Shops\Support\Tax\ConfigTaxResolver::class,
],

Pre vlastnú daňovú logiku implementujte TaxResolver — musí vždy vrátiť TaxRateValue, nikdy null:

use RoundlyConsulting\Shops\Contracts\TaxResolver;
use RoundlyConsulting\Shops\Shops\Shop;
use RoundlyConsulting\Shops\Support\Tax\DatabaseTaxResolver;
use RoundlyConsulting\Shops\Support\Tax\TaxRateValue;

final class ExportAwareTaxResolver implements TaxResolver
{
    public function rateFor(?Shop $shop, string $taxClass = 'standard', ?string $country = null): TaxRateValue
    {
        if ($country !== null && ! in_array($country, ['DE', 'AT', 'SK'], true)) {
            return TaxRateValue::zero($taxClass);   // your own jurisdiction rule
        }

        return (new DatabaseTaxResolver)->rateFor($shop, $taxClass, $country);
    }
}

// config/shops.php → 'tax' => ['resolver' => ExportAwareTaxResolver::class]

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.