Passed
Push — master ( 1e7639...3fc4e5 )
by Tonina
51s queued 10s
created

AddressChange::markAsModified()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\AddressChange\Domain\Model;
6
7
use LogicException;
8
use Ramsey\Uuid\Uuid;
9
10
class AddressChange {
11
12
	public const ADDRESS_TYPE_PERSON = 'person';
13
	public const ADDRESS_TYPE_COMPANY = 'company';
14
15
	private $id;
0 ignored issues
show
introduced by
The private property $id is not used, and could be removed.
Loading history...
16
17
	private $identifier;
18
19
	private $previousIdentifier;
20
21
	private $address;
22
23
	private $addressType;
24
25
	private $donationReceipt;
26
27
	private $exportDate;
28
29
	private $createdAt;
30
31
	private $modifiedAt;
32
33
	private function __construct( string $addressType, ?string $identifier = null, ?Address $address = null, ?\DateTime $createdAt = null ) {
34
		$this->addressType = $addressType;
35
		$this->identifier = $identifier;
36
		$this->address = $address;
37
		if ( $identifier === null ) {
38
			$this->generateUuid();
39
		} elseif ( !Uuid::isValid( $identifier ) ) {
40
			throw new \InvalidArgumentException( 'Identifier must be a valid UUID' );
41
		}
42
		$this->createdAt = $createdAt ?? new \DateTime();
43
		$this->modifiedAt = clone( $this->createdAt );
44
		$this->donationReceipt = true;
45
	}
46
47
	public static function createNewPersonAddressChange( ?string $identifier = null, ?Address $address = null, ?\DateTime $createdAt = null ): self {
48
		return new AddressChange( self::ADDRESS_TYPE_PERSON, $identifier, $address, $createdAt );
49
	}
50
51
	public static function createNewCompanyAddressChange( ?string $identifier = null, ?Address $address = null, ?\DateTime $createdAt = null ): self {
52
		return new AddressChange( self::ADDRESS_TYPE_COMPANY, $identifier, $address, $createdAt );
53
	}
54
55
	private function generateUuid(): void {
56
		$this->identifier = Uuid::uuid4()->toString();
57
	}
58
59
	public function performAddressChange( Address $address ): void {
60
		if ( $this->address !== null ) {
61
			throw new LogicException( 'Cannot perform address change for instances that already have an address.' );
62
		}
63
		$this->address = $address;
64
		$this->markAsModified();
65
	}
66
67
	public function optOutOfDonationReceipt(): void {
68
		$this->donationReceipt = false;
69
		$this->markAsModified();
70
	}
71
72
	public function getCurrentIdentifier(): string {
73
		if ( $this->identifier === null ) {
74
			$this->generateUuid();
75
		}
76
		return $this->identifier;
77
	}
78
79
	public function getPreviousIdentifier(): ?string {
80
		return $this->previousIdentifier;
81
	}
82
83
	public function getAddress(): ?Address {
84
		return $this->address;
85
	}
86
87
	public function isPersonalAddress(): bool {
88
		return $this->addressType === self::ADDRESS_TYPE_PERSON;
89
	}
90
91
	public function isCompanyAddress(): bool {
92
		return $this->addressType === self::ADDRESS_TYPE_COMPANY;
93
	}
94
95
	public function isOptedIntoDonationReceipt(): bool {
96
		return $this->donationReceipt;
97
	}
98
99
	public function markAsExported(): void {
100
		if ( $this->isExported() ) {
101
			throw new LogicException( 'Address changes can only be exported once.' );
102
		}
103
		$this->exportDate = new \DateTime();
104
	}
105
106
	private function resetExportState(): void {
107
		$this->exportDate = null;
108
	}
109
110
	public function isExported(): bool {
111
		return $this->exportDate !== null;
112
	}
113
114
	public function isModified(): bool {
115
		return $this->createdAt < $this->modifiedAt;
116
	}
117
118
	private function markAsModified() {
119
		if ( !$this->isModified() ) {
120
			$this->previousIdentifier = $this->getCurrentIdentifier();
121
			$this->generateUuid();
122
		}
123
		$this->modifiedAt = new \DateTime();
124
		$this->resetExportState();
125
	}
126
}
127