Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.45% covered (success)
95.45%
21 / 22
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
TaxRule
95.24% covered (success)
95.24%
20 / 21
66.67% covered (warning)
66.67%
2 / 3
9
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 matches
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
7.23
 toArray
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
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\Model;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11/**
12 * Domain model representing a conditional tax determination rule.
13 */
14final class TaxRule
15{
16    /**
17     * TaxRule constructor.
18     *
19     * @param int|null $id Database primary key ID
20     * @param string $ruleName Descriptive rule name
21     * @param int $priority Evaluation priority (lower = evaluated first)
22     * @param string $customerType Condition: 'all', 'b2b', 'b2c'
23     * @param string $geoZone Condition: 'domestic', 'eu_vat', 'eu_consumer', 'export_world'
24     * @param string $itemType Condition: 'all', 'product', 'service', 'margin_goods'
25     * @param int $targetTaxRateId Assigned tax rate ID when conditions match
26     * @param bool $isActive Rule active status
27     * @param TaxRate|null $targetTaxRate Optional resolved tax rate
28     * @param int $owner Owner user ID
29     * @param string|null $createdAt Creation timestamp
30     * @param string|null $updatedAt Last update timestamp
31     */
32    public function __construct(
33        public ?int $id,
34        public string $ruleName,
35        public int $priority = 10,
36        public string $customerType = 'all',
37        public string $geoZone = 'domestic',
38        public string $itemType = 'all',
39        public int $targetTaxRateId = 0,
40        public bool $isActive = true,
41        public ?TaxRate $targetTaxRate = null,
42        public int $owner = 1,
43        public ?string $createdAt = null,
44        public ?string $updatedAt = null,
45    ) {
46    }
47
48    /**
49     * Check whether this rule matches the provided context criteria.
50     */
51    public function matches(string $customerType, string $geoZone, string $itemType): bool
52    {
53        if (!$this->isActive) {
54            return false;
55        }
56
57        $matchCustomer = ($this->customerType === 'all' || $this->customerType === $customerType);
58        $matchGeo = ($this->geoZone === 'all' || $this->geoZone === $geoZone);
59        $matchItem = ($this->itemType === 'all' || $this->itemType === $itemType);
60
61        return $matchCustomer && $matchGeo && $matchItem;
62    }
63
64    /**
65     * Convert TaxRule to associative array.
66     *
67     * @return array<string, mixed>
68     */
69    public function toArray(): array
70    {
71        return [
72            'id' => $this->id,
73            'rule_name' => $this->ruleName,
74            'priority' => $this->priority,
75            'customer_type' => $this->customerType,
76            'geo_zone' => $this->geoZone,
77            'item_type' => $this->itemType,
78            'target_tax_rate_id' => $this->targetTaxRateId,
79            'target_tax_rate' => $this->targetTaxRate?->toArray(),
80            'is_active' => $this->isActive,
81            'owner' => $this->owner,
82            'created_at' => $this->createdAt,
83            'updated_at' => $this->updatedAt,
84        ];
85    }
86}