Passed
Push — main ( c73e00...0a00da )
by
unknown
15:13 queued 14s
created

AddressChange::getExternalId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 2
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\AddressChangeContext\Domain\Model;
6
7
use LogicException;
8
9
/**
10
 * An Address change record with a UUID identifier for accessing it, an optional address (if the user preformed an
11
 * address change) and a reference to the originating record (donation or membership).
12
 *
13
 * The recommended way to construct this class is through the AddressChangeBuilder
14
 */
15
class AddressChange {
16
	public const EXTERNAL_ID_TYPE_DONATION = 'donation';
17
	public const EXTERNAL_ID_TYPE_MEMBERSHIP = 'membership';
18
19
	public const EXPORT_STATE_NO_DATA = 'NO_DATA';
20
	public const EXPORT_STATE_USED_NOT_EXPORTED = 'USED_NOT_EXPORTED';
21
	public const EXPORT_STATE_USED_EXPORTED = 'USED_EXPORTED';
22
23
	/**
24
	 * @var int|null
25
	 * @phpstan-ignore-next-line
26
	 */
27
	private ?int $id;
28
29
	private AddressChangeId $previousIdentifier;
30
31
	private bool $donationReceipt;
32
33
	private ?\DateTimeInterface $exportDate;
34
35
	private \DateTimeInterface $createdAt;
36
37
	private \DateTimeInterface $modifiedAt;
38
39 13
	public function __construct(
40
		private readonly AddressType $addressType,
41
		private readonly string $externalIdType,
42
		private readonly int $externalId,
43
		private AddressChangeId $identifier,
44
		private ?Address $address = null,
45
		?\DateTime $createdAt = null
46
	) {
47 13
		$this->previousIdentifier = $identifier;
48 13
		if ( $externalIdType !== self::EXTERNAL_ID_TYPE_DONATION && $externalIdType !== self::EXTERNAL_ID_TYPE_MEMBERSHIP ) {
49 1
			throw new \InvalidArgumentException( 'Invalid external reference type' );
50
		}
51 12
		$this->exportDate = null;
52 12
		$this->createdAt = $createdAt ?? new \DateTime();
53 12
		$this->modifiedAt = clone $this->createdAt;
54 12
		$this->donationReceipt = true;
55
	}
56
57 5
	public function performAddressChange( Address $address, AddressChangeId $newIdentifier ): void {
58 5
		if ( $this->address !== null ) {
59
			throw new LogicException( 'Cannot perform address change for instances that already have an address.' );
60
		}
61 5
		$this->address = $address;
62 5
		$this->markAsModified( $newIdentifier );
63
	}
64
65 1
	public function optOutOfDonationReceipt( AddressChangeId $newIdentifier ): void {
66 1
		$this->donationReceipt = false;
67 1
		$this->markAsModified( $newIdentifier );
68
	}
69
70 6
	public function getCurrentIdentifier(): AddressChangeId {
71 6
		return $this->identifier;
72
	}
73
74 2
	public function getPreviousIdentifier(): ?AddressChangeId {
75 2
		return $this->previousIdentifier;
76
	}
77
78 1
	public function getAddress(): ?Address {
79 1
		return $this->address;
80
	}
81
82
	public function isPersonalAddress(): bool {
83
		return $this->addressType === AddressType::Person;
84
	}
85
86
	public function isCompanyAddress(): bool {
87
		return $this->addressType === AddressType::Company;
88
	}
89
90
	public function isOptedIntoDonationReceipt(): bool {
91
		return $this->donationReceipt;
92
	}
93
94 5
	public function markAsExported(): void {
95 5
		if ( $this->isExported() ) {
96 1
			throw new LogicException( 'Address changes can only be exported once.' );
97
		}
98 5
		$this->exportDate = new \DateTime();
99
	}
100
101 6
	private function resetExportState(): void {
102 6
		$this->exportDate = null;
103
	}
104
105 6
	public function isExported(): bool {
106 6
		return $this->exportDate !== null;
107
	}
108
109 4
	public function isModified(): bool {
110 4
		return $this->createdAt < $this->modifiedAt;
111
	}
112
113 6
	private function markAsModified( AddressChangeId $newIdentifier ): void {
114 6
		$this->previousIdentifier = $this->getCurrentIdentifier();
115 6
		$this->identifier = $newIdentifier;
116
117 6
		$this->modifiedAt = new \DateTime();
118 6
		$this->resetExportState();
119
	}
120
121
	public function getId(): ?int {
122
		return $this->id;
123
	}
124
125
	public function getExternalId(): int {
126
		return $this->externalId;
127
	}
128
129
	public function getExternalIdType(): string {
130
		return $this->externalIdType;
131
	}
132
133 3
	public function getExportState(): string {
134 3
		if ( !$this->address ) {
135 1
			return self::EXPORT_STATE_NO_DATA;
136
		}
137
138 2
		if ( $this->exportDate ) {
139 1
			return self::EXPORT_STATE_USED_EXPORTED;
140
		}
141
142 1
		return self::EXPORT_STATE_USED_NOT_EXPORTED;
143
	}
144
}
145