Completed
Pull Request — master (#5)
by Gabriel
100:15 queued 35:12
created

AddressChange   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 51
dl 0
loc 131
rs 10
c 0
b 0
f 0
wmc 24

18 Methods

Rating   Name   Duplication   Size   Complexity  
A isPersonalAddress() 0 2 1
A getPreviousIdentifier() 0 2 1
A isOptedIntoDonationReceipt() 0 2 1
A createNewPersonAddressChange() 0 2 1
A createNewCompanyAddressChange() 0 2 1
A isModified() 0 2 1
A markAsExported() 0 5 2
A optOutOfDonationReceipt() 0 3 1
A markAsModified() 0 7 2
A isExported() 0 2 1
A generateUuid() 0 2 1
A getAddress() 0 2 1
A getCurrentIdentifier() 0 5 2
A resetExportState() 0 2 1
A isCompanyAddress() 0 2 1
A getId() 0 2 1
A performAddressChange() 0 6 2
A __construct() 0 12 3
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
	/**
16
	 * @var int|null
17
	 */
18
	private $id;
19
20
	private $identifier;
21
22
	/**
23
	 * @var string|null
24
	 */
25
	private $previousIdentifier;
26
27
	private $address;
28
29
	private $addressType;
30
31
	private $donationReceipt;
32
33
	/**
34
	 * @var \DateTimeInterface|null
35
	 */
36
	private $exportDate;
37
38
	/**
39
	 * @var \DateTimeInterface|null
40
	 */
41
	private $createdAt;
42
43
	private $modifiedAt;
44
45
	private function __construct( string $addressType, ?string $identifier = null, ?Address $address = null, ?\DateTime $createdAt = null ) {
46
		$this->addressType = $addressType;
47
		$this->identifier = $identifier;
48
		$this->address = $address;
49
		if ( $identifier === null ) {
50
			$this->generateUuid();
51
		} elseif ( !Uuid::isValid( $identifier ) ) {
52
			throw new \InvalidArgumentException( 'Identifier must be a valid UUID' );
53
		}
54
		$this->createdAt = $createdAt ?? new \DateTime();
55
		$this->modifiedAt = clone( $this->createdAt );
56
		$this->donationReceipt = true;
57
	}
58
59
	public static function createNewPersonAddressChange( ?string $identifier = null, ?Address $address = null, ?\DateTime $createdAt = null ): self {
60
		return new AddressChange( self::ADDRESS_TYPE_PERSON, $identifier, $address, $createdAt );
61
	}
62
63
	public static function createNewCompanyAddressChange( ?string $identifier = null, ?Address $address = null, ?\DateTime $createdAt = null ): self {
64
		return new AddressChange( self::ADDRESS_TYPE_COMPANY, $identifier, $address, $createdAt );
65
	}
66
67
	private function generateUuid(): void {
68
		$this->identifier = Uuid::uuid4()->toString();
69
	}
70
71
	public function performAddressChange( Address $address ): void {
72
		if ( $this->address !== null ) {
73
			throw new LogicException( 'Cannot perform address change for instances that already have an address.' );
74
		}
75
		$this->address = $address;
76
		$this->markAsModified();
77
	}
78
79
	public function optOutOfDonationReceipt(): void {
80
		$this->donationReceipt = false;
81
		$this->markAsModified();
82
	}
83
84
	public function getCurrentIdentifier(): string {
85
		if ( $this->identifier === null ) {
86
			$this->generateUuid();
87
		}
88
		return $this->identifier;
89
	}
90
91
	public function getPreviousIdentifier(): ?string {
92
		return $this->previousIdentifier;
93
	}
94
95
	public function getAddress(): ?Address {
96
		return $this->address;
97
	}
98
99
	public function isPersonalAddress(): bool {
100
		return $this->addressType === self::ADDRESS_TYPE_PERSON;
101
	}
102
103
	public function isCompanyAddress(): bool {
104
		return $this->addressType === self::ADDRESS_TYPE_COMPANY;
105
	}
106
107
	public function isOptedIntoDonationReceipt(): bool {
108
		return $this->donationReceipt;
109
	}
110
111
	public function markAsExported(): void {
112
		if ( $this->isExported() ) {
113
			throw new LogicException( 'Address changes can only be exported once.' );
114
		}
115
		$this->exportDate = new \DateTime();
116
	}
117
118
	private function resetExportState(): void {
119
		$this->exportDate = null;
120
	}
121
122
	public function isExported(): bool {
123
		return $this->exportDate !== null;
124
	}
125
126
	public function isModified(): bool {
127
		return $this->createdAt < $this->modifiedAt;
128
	}
129
130
	private function markAsModified(): void {
131
		if ( !$this->isModified() ) {
132
			$this->previousIdentifier = $this->getCurrentIdentifier();
133
			$this->generateUuid();
134
		}
135
		$this->modifiedAt = new \DateTime();
136
		$this->resetExportState();
137
	}
138
139
	public function getId(): ?int {
140
		return $this->id;
141
	}
142
}
143