Completed
Push — master ( 16a7fa...6dd648 )
by Jeroen De
109:37 queued 44:36
created

AddDonationUseCase::donationNeedsModeration()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 2
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\DonationContext\UseCases\AddDonation;
6
7
use WMDE\Fundraising\Frontend\DonationContext\Authorization\DonationTokenFetcher;
8
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\Donation;
9
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonationPayment;
10
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonationTrackingInfo;
11
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\Donor;
12
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonorAddress;
13
use WMDE\Fundraising\Frontend\DonationContext\Domain\Model\DonorName;
14
use WMDE\Fundraising\Frontend\DonationContext\Domain\Repositories\DonationRepository;
15
use WMDE\Fundraising\Frontend\DonationContext\Infrastructure\DonationConfirmationMailer;
16
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\BankTransferPayment;
17
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\DirectDebitPayment;
18
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentMethod;
19
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentType;
20
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentWithoutAssociatedData;
21
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalData;
22
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PayPalPayment;
23
use WMDE\Fundraising\Frontend\PaymentContext\Domain\TransferCodeGenerator;
24
25
/**
26
 * @license GNU GPL v2+
27
 * @author Kai Nissen < [email protected] >
28
 * @author Jeroen De Dauw < [email protected] >
29
 */
30
class AddDonationUseCase {
31
32
	private $donationRepository;
33
	private $donationValidator;
34
	private $policyValidator;
35
	private $referrerGeneralizer;
36
	private $mailer;
37
	private $transferCodeGenerator;
38
	private $tokenFetcher;
39
40
	public function __construct( DonationRepository $donationRepository, AddDonationValidator $donationValidator,
41
								 AddDonationPolicyValidator $policyValidator, ReferrerGeneralizer $referrerGeneralizer,
42
								 DonationConfirmationMailer $mailer, TransferCodeGenerator $transferCodeGenerator,
43
								 DonationTokenFetcher $tokenFetcher ) {
44
		$this->donationRepository = $donationRepository;
45
		$this->donationValidator = $donationValidator;
46
		$this->policyValidator = $policyValidator;
47
		$this->referrerGeneralizer = $referrerGeneralizer;
48
		$this->mailer = $mailer;
49
		$this->transferCodeGenerator = $transferCodeGenerator;
50
51
		$this->tokenFetcher = $tokenFetcher;
52
	}
53
54
	public function addDonation( AddDonationRequest $donationRequest ): AddDonationResponse {
55
		$validationResult = $this->donationValidator->validate( $donationRequest );
56
57
		if ( $validationResult->hasViolations() ) {
58
			return AddDonationResponse::newFailureResponse( $validationResult->getViolations() );
59
		}
60
61
		$donation = $this->newDonationFromRequest( $donationRequest );
62
63
		if ( $this->donationNeedsModeration( $donationRequest, $donation ) ) {
64
			$donation->markForModeration();
65
		}
66
67
		// TODO: handle exceptions
68
		$this->donationRepository->storeDonation( $donation );
69
70
		// TODO: handle exceptions
71
		$tokens = $this->tokenFetcher->getTokens( $donation->getId() );
72
73
		// TODO: handle exceptions
74
		$this->sendDonationConfirmationEmail( $donation );
75
76
		return AddDonationResponse::newSuccessResponse(
77
			$donation,
78
			$tokens->getUpdateToken(),
79
			$tokens->getAccessToken()
80
		);
81
	}
82
83
	private function newDonationFromRequest( AddDonationRequest $donationRequest ): Donation {
84
		return new Donation(
85
			null,
86
			$this->getInitialDonationStatus( $donationRequest->getPaymentType() ),
87
			$this->getPersonalInfoFromRequest( $donationRequest ),
88
			$this->getPaymentFromRequest( $donationRequest ),
89
			$donationRequest->getOptIn() === '1',
90
			$this->newTrackingInfoFromRequest( $donationRequest )
91
		);
92
	}
93
94
	private function getPersonalInfoFromRequest( AddDonationRequest $request ) {
95
		if ( $request->donorIsAnonymous() ) {
96
			return null;
97
		}
98
		return new Donor(
99
			$this->getNameFromRequest( $request ),
100
			$this->getPhysicalAddressFromRequest( $request ),
101
			$request->getDonorEmailAddress()
102
		);
103
	}
104
105
	private function getPhysicalAddressFromRequest( AddDonationRequest $request ): DonorAddress {
106
		$address = new DonorAddress();
107
108
		$address->setStreetAddress( $request->getDonorStreetAddress() );
109
		$address->setPostalCode( $request->getDonorPostalCode() );
110
		$address->setCity( $request->getDonorCity() );
111
		$address->setCountryCode( $request->getDonorCountryCode() );
112
113
		return $address->freeze()->assertNoNullFields();
114
	}
115
116
	private function getNameFromRequest( AddDonationRequest $request ): DonorName {
117
		$name = $request->donorIsCompany() ? DonorName::newCompanyName() : DonorName::newPrivatePersonName();
118
119
		$name->setSalutation( $request->getDonorSalutation() );
120
		$name->setTitle( $request->getDonorTitle() );
121
		$name->setCompanyName( $request->getDonorCompany() );
122
		$name->setFirstName( $request->getDonorFirstName() );
123
		$name->setLastName( $request->getDonorLastName() );
124
125
		return $name->freeze()->assertNoNullFields();
126
	}
127
128
	private function getInitialDonationStatus( string $paymentType ): string {
129
		if ( $paymentType === PaymentType::DIRECT_DEBIT ) {
130
			return Donation::STATUS_NEW;
131
		}
132
133
		if ( $paymentType === PaymentType::BANK_TRANSFER ) {
134
			return Donation::STATUS_PROMISE;
135
		}
136
137
		return Donation::STATUS_EXTERNAL_INCOMPLETE;
138
	}
139
140
	private function getPaymentFromRequest( AddDonationRequest $donationRequest ): DonationPayment {
141
		return new DonationPayment(
142
			$donationRequest->getAmount(),
143
			$donationRequest->getInterval(),
144
			$this->getPaymentMethodFromRequest( $donationRequest )
145
		);
146
	}
147
148
	private function getPaymentMethodFromRequest( AddDonationRequest $donationRequest ): PaymentMethod {
149
		if ( $donationRequest->getPaymentType() === PaymentType::BANK_TRANSFER ) {
150
			return new BankTransferPayment( $this->transferCodeGenerator->generateTransferCode() );
151
		}
152
153
		if ( $donationRequest->getPaymentType() === PaymentType::DIRECT_DEBIT ) {
154
			return new DirectDebitPayment( $donationRequest->getBankData() );
155
		}
156
157
		if ( $donationRequest->getPaymentType() === PaymentType::PAYPAL ) {
158
			return new PayPalPayment( new PayPalData() );
159
		}
160
161
		return new PaymentWithoutAssociatedData( $donationRequest->getPaymentType() );
162
	}
163
164
	private function newTrackingInfoFromRequest( AddDonationRequest $request ): DonationTrackingInfo {
165
		$trackingInfo = new DonationTrackingInfo();
166
167
		$trackingInfo->setTracking( $request->getTracking() );
168
		$trackingInfo->setSource( $this->referrerGeneralizer->generalize( $request->getSource() ) );
169
		$trackingInfo->setTotalImpressionCount( $request->getTotalImpressionCount() );
170
		$trackingInfo->setSingleBannerImpressionCount( $request->getSingleBannerImpressionCount() );
171
		$trackingInfo->setColor( $request->getColor() );
0 ignored issues
show
Deprecated Code introduced by
The method WMDE\Fundraising\Fronten...tionRequest::getColor() has been deprecated.

This method has been deprecated.

Loading history...
172
		$trackingInfo->setSkin( $request->getSkin() );
0 ignored issues
show
Deprecated Code introduced by
The method WMDE\Fundraising\Fronten...ationRequest::getSkin() has been deprecated.

This method has been deprecated.

Loading history...
173
		$trackingInfo->setLayout( $request->getLayout() );
0 ignored issues
show
Deprecated Code introduced by
The method WMDE\Fundraising\Fronten...ionRequest::getLayout() has been deprecated.

This method has been deprecated.

Loading history...
174
175
		return $trackingInfo->freeze()->assertNoNullFields();
176
	}
177
178
	/**
179
	 * @param Donation $donation
180
	 *
181
	 * @throws \RuntimeException
182
	 */
183
	private function sendDonationConfirmationEmail( Donation $donation ) {
184
		if ( $donation->getDonor() !== null && !$donation->hasExternalPayment() ) {
185
			$this->mailer->sendConfirmationMailFor( $donation );
186
		}
187
	}
188
189
	private function donationNeedsModeration( AddDonationRequest $donationRequest, Donation $donation ): bool {
190
		return !$donation->hasExternalPayment() && $this->policyValidator->needsModeration( $donationRequest );
191
	}
192
193
}