Passed
Pull Request — master (#31)
by
unknown
64:24
created

AddressChange::getExportState()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 3
nop 0
dl 0
loc 10
ccs 0
cts 0
cp 0
crap 12
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
17
	public const ADDRESS_TYPE_PERSON = 'person';
18
	public const ADDRESS_TYPE_COMPANY = 'company';
19
20
	public const EXTERNAL_ID_TYPE_DONATION = 'donation';
21
	public const EXTERNAL_ID_TYPE_MEMBERSHIP = 'membership';
22
23
	public const EXPORT_STATE_UNUSED = 'UNUSED';
24
	public const EXPORT_STATE_USED_NOT_EXPORTED = 'USED_NOT_EXPORTED';
25
	public const EXPORT_STATE_USED_EXPORTED = 'USED_EXPORTED';
26
27
	private ?int $id;
28
29
	private AddressChangeId $identifier;
30
31
	private AddressChangeId $previousIdentifier;
32
33
	private ?Address $address;
34
35
	private string $addressType;
36
37
	private bool $donationReceipt;
38
39
	private int $externalId;
40
41
	private string $externalIdType;
42
43
	private ?\DateTimeInterface $exportDate;
44
45 11
	private \DateTimeInterface $createdAt;
46
47 11
	private \DateTimeInterface $modifiedAt;
48 11
49 11
	public function __construct( string $addressType, string $externalIdType, int $externalId, AddressChangeId $identifier,
50 11
			?Address $address = null, ?\DateTime $createdAt = null ) {
51 11
		$this->addressType = $addressType;
52 1
		$this->identifier = $identifier;
53
		$this->previousIdentifier = $identifier;
54 10
		$this->address = $address;
55 1
		if ( $addressType !== self::ADDRESS_TYPE_PERSON && $addressType !== self::ADDRESS_TYPE_COMPANY ) {
56
			throw new \InvalidArgumentException( 'Invalid address type' );
57 9
		}
58 9
		if ( $externalIdType !== self::EXTERNAL_ID_TYPE_DONATION && $externalIdType !== self::EXTERNAL_ID_TYPE_MEMBERSHIP ) {
59 9
			throw new \InvalidArgumentException( 'Invalid external reference type' );
60 9
		}
61 9
		$this->exportDate = null;
62 9
		$this->createdAt = $createdAt ?? new \DateTime();
63 9
		$this->modifiedAt = clone $this->createdAt;
64
		$this->donationReceipt = true;
65 3
		$this->externalId = $externalId;
66 3
		$this->externalIdType = $externalIdType;
67
	}
68
69 3
	public function performAddressChange( Address $address, AddressChangeId $newIdentifier ): void {
70 3
		if ( $this->address !== null ) {
71 3
			throw new LogicException( 'Cannot perform address change for instances that already have an address.' );
72
		}
73 1
		$this->address = $address;
74 1
		$this->markAsModified( $newIdentifier );
75 1
	}
76 1
77
	public function optOutOfDonationReceipt( AddressChangeId $newIdentifier ): void {
78 4
		$this->donationReceipt = false;
79 4
		$this->markAsModified( $newIdentifier );
80
	}
81
82 2
	public function getCurrentIdentifier(): AddressChangeId {
83 2
		return $this->identifier;
84
	}
85
86 1
	public function getPreviousIdentifier(): ?AddressChangeId {
87 1
		return $this->previousIdentifier;
88
	}
89
90
	public function getAddress(): ?Address {
91
		return $this->address;
92
	}
93
94
	public function isPersonalAddress(): bool {
95
		return $this->addressType === self::ADDRESS_TYPE_PERSON;
96
	}
97
98
	public function isCompanyAddress(): bool {
99
		return $this->addressType === self::ADDRESS_TYPE_COMPANY;
100
	}
101
102 4
	public function isOptedIntoDonationReceipt(): bool {
103 4
		return $this->donationReceipt;
104 1
	}
105
106 4
	public function markAsExported(): void {
107 4
		if ( $this->isExported() ) {
108
			throw new LogicException( 'Address changes can only be exported once.' );
109 4
		}
110 4
		$this->exportDate = new \DateTime();
111 4
	}
112
113 5
	private function resetExportState(): void {
114 5
		$this->exportDate = null;
115
	}
116
117 4
	public function isExported(): bool {
118 4
		return $this->exportDate !== null;
119
	}
120
121 4
	public function isModified(): bool {
122 4
		return $this->createdAt < $this->modifiedAt;
123 4
	}
124
125 4
	private function markAsModified( AddressChangeId $newIdentifier ): void {
126 4
		$this->previousIdentifier = $this->getCurrentIdentifier();
127 4
		$this->identifier = $newIdentifier;
128
129
		$this->modifiedAt = new \DateTime();
130
		$this->resetExportState();
131
	}
132
133
	public function getId(): ?int {
134
		return $this->id;
135
	}
136
137
	public function getExternalId(): int {
138
		return $this->externalId;
139
	}
140
141
	public function getExternalIdType(): string {
142
		return $this->externalIdType;
143
	}
144
145
	public function getExportState(): string {
146
		if ( !$this->address ) {
147
			return self::EXPORT_STATE_UNUSED;
148
		}
149
150
		if ( $this->exportDate ) {
151
			return self::EXPORT_STATE_USED_EXPORTED;
152
		}
153
154
		return self::EXPORT_STATE_USED_NOT_EXPORTED;
155
	}
156
}
157