Passed
Pull Request — master (#3)
by Tonina
64:57
created

AddressChange::optOutOfDonationReceipt()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 5
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, bool $donationReceipt = false,
34
								  ?\DateTime $createdAt = null ) {
35
		$this->addressType = $addressType;
36
		$this->donationReceipt = $donationReceipt;
37
		$this->identifier = $identifier;
38
		$this->address = $address;
39
		if ( $identifier === null ) {
40
			$this->generateUuid();
41
		} elseif ( !Uuid::isValid( $identifier ) ) {
42
			throw new \InvalidArgumentException( 'Identifier must be a valid UUID' );
43
		}
44
		$this->createdAt = $createdAt ?? new \DateTime();
45
		$this->modifiedAt = clone( $this->createdAt );
46
	}
47
48
	public static function createNewPersonAddressChange( ?string $identifier = null, ?Address $address = null, bool $donationReceipt = false,
49
														 ?\DateTime $createdAt = null ): self {
50
		return new AddressChange( self::ADDRESS_TYPE_PERSON, $identifier, $address, $donationReceipt, $createdAt );
51
	}
52
53
	public static function createNewCompanyAddressChange( ?string $identifier = null, ?Address $address = null, bool $donationReceipt = false,
54
														  ?\DateTime $createdAt = null ): self {
55
		return new AddressChange( self::ADDRESS_TYPE_COMPANY, $identifier, $address, $donationReceipt, $createdAt );
56
	}
57
58
	private function generateUuid(): void {
59
		$this->identifier = Uuid::uuid4()->toString();
60
	}
61
62
	public function performAddressChange( Address $address ): void {
63
		if ( $this->address !== null ) {
64
			throw new LogicException( 'Cannot perform address change for instances that already have an address.' );
65
		}
66
		$this->address = $address;
67
		$this->previousIdentifier = $this->getCurrentIdentifier();
68
		$this->modifiedAt = new \DateTime();
69
		$this->generateUuid();
70
		$this->resetExportState();
71
	}
72
73
	public function optOutOfDonationReceipt( bool $donationReceipt ): void {
74
		$this->donationReceipt = $donationReceipt;
75
		$this->previousIdentifier = $this->getCurrentIdentifier();
76
		$this->modifiedAt = new \DateTime();
77
		$this->resetExportState();
78
	}
79
80
	public function getCurrentIdentifier(): string {
81
		if ( $this->identifier === null ) {
82
			$this->generateUuid();
83
		}
84
		return $this->identifier;
85
	}
86
87
	public function getPreviousIdentifier(): ?string {
88
		return $this->previousIdentifier;
89
	}
90
91
	public function getAddress(): ?Address {
92
		return $this->address;
93
	}
94
95
	public function isPersonalAddress(): bool {
96
		return $this->addressType === self::ADDRESS_TYPE_PERSON;
97
	}
98
99
	public function isCompanyAddress(): bool {
100
		return $this->addressType === self::ADDRESS_TYPE_COMPANY;
101
	}
102
103
	public function isOptedIntoDonationReceipt(): bool {
104
		return $this->donationReceipt;
105
	}
106
107
	public function markAsExported(): void {
108
		if ( $this->isExported() ) {
109
			throw new LogicException( 'Address changes can only be exported once.' );
110
		}
111
		$this->exportDate = new \DateTime();
112
	}
113
114
	private function resetExportState(): void {
115
		$this->exportDate = null;
116
	}
117
118
	public function isExported(): bool {
119
		return $this->exportDate !== null;
120
	}
121
122
	public function isModified(): bool {
123
		return $this->createdAt < $this->modifiedAt;
124
	}
125
}
126