Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
DiscountRateDto
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
3 / 3
10
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 fromArray
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
5
 toArray
100.00% covered (success)
100.00%
9 / 9
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\Discount\Application\DTO;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use InvalidArgumentException;
12
13/**
14 * Data Transfer Object for creating or updating a DiscountRate.
15 */
16final readonly class DiscountRateDto
17{
18    /**
19     * DiscountRateDto constructor.
20     */
21    public function __construct(
22        public ?int $id,
23        public string $discountCode,
24        public string $discountName,
25        public string $discountType = 'percent',
26        public float $discountValue = 0.0,
27        public bool $isDefault = false,
28        public bool $isActive = true,
29    ) {
30        if ($this->discountCode === '') {
31            throw new InvalidArgumentException('Discount code cannot be empty.');
32        }
33        if ($this->discountName === '') {
34            throw new InvalidArgumentException('Discount name cannot be empty.');
35        }
36        if ($this->discountValue < 0.0) {
37            throw new InvalidArgumentException('Discount value cannot be negative.');
38        }
39    }
40
41    /**
42     * Create DTO from raw array (e.g. from JSON body or POST form data).
43     *
44     * @param array<string, mixed> $data
45     */
46    public static function fromArray(array $data, ?int $id = null): self
47    {
48        $code = trim((string) ($data['discount_code'] ?? ''));
49        $name = trim((string) ($data['discount_name'] ?? ''));
50        $type = (string) ($data['discount_type'] ?? 'percent');
51        $val = (float) ($data['discount_value'] ?? 0.0);
52        $resolvedId = $id ?? (isset($data['id']) && $data['id'] !== '' ? (int) $data['id'] : null);
53
54        return new self(
55            id: $resolvedId,
56            discountCode: $code,
57            discountName: $name,
58            discountType: in_array($type, ['percent', 'amount'], true) ? $type : 'percent',
59            discountValue: $val,
60            isDefault: !empty($data['is_default']),
61            isActive: isset($data['is_active']) ? (bool) $data['is_active'] : true,
62        );
63    }
64
65    /**
66     * Convert DTO to array.
67     *
68     * @return array<string, mixed>
69     */
70    public function toArray(): array
71    {
72        return [
73            'id' => $this->id,
74            'discount_code' => $this->discountCode,
75            'discount_name' => $this->discountName,
76            'discount_type' => $this->discountType,
77            'discount_value' => $this->discountValue,
78            'is_default' => $this->isDefault,
79            'is_active' => $this->isActive,
80        ];
81    }
82}