Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
TaxDeterminationMatrix
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
1 / 1
 determine
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Modules\Tax\Domain\Service;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Modules\Tax\Domain\Model\TaxRate;
12use App\Modules\Tax\Domain\Model\TaxRule;
13
14/**
15 * Domain Service for evaluating tax determination rules and resolving target tax rates.
16 */
17final class TaxDeterminationMatrix
18{
19    /**
20     * Resolve the appropriate TaxRate based on transaction context.
21     *
22     * @param TaxRule[] $rules Active determination rules
23     * @param string $customerType 'all', 'b2b', 'b2c'
24     * @param string $geoZone 'domestic', 'eu_vat', 'eu_consumer', 'export_world'
25     * @param string $itemType 'all', 'product', 'service', 'margin_goods'
26     * @param TaxRate|null $fallbackRate Fallback tax rate if no rule matches
27     * @return TaxRate|null
28     */
29    public function determine(
30        array $rules,
31        string $customerType,
32        string $geoZone,
33        string $itemType,
34        ?TaxRate $fallbackRate = null,
35    ): ?TaxRate {
36        usort($rules, static fn(TaxRule $a, TaxRule $b): int => $a->priority <=> $b->priority);
37
38        foreach ($rules as $rule) {
39            if ($rule->matches($customerType, $geoZone, $itemType) && $rule->targetTaxRate !== null) {
40                return $rule->targetTaxRate;
41            }
42        }
43
44        return $fallbackRate;
45    }
46}