Completed
Push — master ( 919a96...568a86 )
by wiese
73:55 queued 09:12
created

AddDonationUseCase::newTrackingInfoFromRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 10
nc 1
nop 1
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\Model\SofortPayment;
24
use WMDE\Fundraising\Frontend\PaymentContext\Domain\TransferCodeGenerator;
25
26
/**
27
 * @license GNU GPL v2+
28
 * @author Kai Nissen < [email protected] >
29
 * @author Jeroen De Dauw < [email protected] >
30
 */
31
class AddDonationUseCase {
32
33
	private $donationRepository;
34
	private $donationValidator;
35
	private $policyValidator;
36
	private $referrerGeneralizer;
37
	private $mailer;
38
	private $transferCodeGenerator;
39
	private $tokenFetcher;
40
41
	public function __construct( DonationRepository $donationRepository, AddDonationValidator $donationValidator,
42
								 AddDonationPolicyValidator $policyValidator, ReferrerGeneralizer $referrerGeneralizer,
43
								 DonationConfirmationMailer $mailer, TransferCodeGenerator $transferCodeGenerator,
44
								 DonationTokenFetcher $tokenFetcher ) {
45
		$this->donationRepository = $donationRepository;
46
		$this->donationValidator = $donationValidator;
47
		$this->policyValidator = $policyValidator;
48
		$this->referrerGeneralizer = $referrerGeneralizer;
49
		$this->mailer = $mailer;
50
		$this->transferCodeGenerator = $transferCodeGenerator;
51
52
		$this->tokenFetcher = $tokenFetcher;
53
	}
54
55
	public function addDonation( AddDonationRequest $donationRequest ): AddDonationResponse {
56
		$validationResult = $this->donationValidator->validate( $donationRequest );
57
58
		if ( $validationResult->hasViolations() ) {
59
			return AddDonationResponse::newFailureResponse( $validationResult->getViolations() );
60
		}
61
62
		$donation = $this->newDonationFromRequest( $donationRequest );
63
64
		if ( $this->policyValidator->needsModeration( $donationRequest ) ) {
65
			$donation->notifyOfPolicyValidationFailure();
66
		}
67
68
		if ( $this->policyValidator->isAutoDeleted( $donationRequest ) ) {
69
			$donation->markAsDeleted();
70
		}
71
72
		// TODO: handle exceptions
73
		$this->donationRepository->storeDonation( $donation );
74
75
		// TODO: handle exceptions
76
		$tokens = $this->tokenFetcher->getTokens( $donation->getId() );
77
78
		// TODO: handle exceptions
79
		$this->sendDonationConfirmationEmail( $donation );
80
81
		return AddDonationResponse::newSuccessResponse(
82
			$donation,
83
			$tokens->getUpdateToken(),
84
			$tokens->getAccessToken()
85
		);
86
	}
87
88
	private function newDonationFromRequest( AddDonationRequest $donationRequest ): Donation {
89
		return new Donation(
90
			null,
91
			$this->getInitialDonationStatus( $donationRequest->getPaymentType() ),
92
			$this->getPersonalInfoFromRequest( $donationRequest ),
93
			$this->getPaymentFromRequest( $donationRequest ),
94
			$donationRequest->getOptIn() === '1',
95
			$this->newTrackingInfoFromRequest( $donationRequest )
96
		);
97
	}
98
99
	private function getPersonalInfoFromRequest( AddDonationRequest $request ) {
100
		if ( $request->donorIsAnonymous() ) {
101
			return null;
102
		}
103
		return new Donor(
104
			$this->getNameFromRequest( $request ),
105
			$this->getPhysicalAddressFromRequest( $request ),
106
			$request->getDonorEmailAddress()
107
		);
108
	}
109
110
	private function getPhysicalAddressFromRequest( AddDonationRequest $request ): DonorAddress {
111
		$address = new DonorAddress();
112
113
		$address->setStreetAddress( $request->getDonorStreetAddress() );
114
		$address->setPostalCode( $request->getDonorPostalCode() );
115
		$address->setCity( $request->getDonorCity() );
116
		$address->setCountryCode( $request->getDonorCountryCode() );
117
118
		return $address->freeze()->assertNoNullFields();
119
	}
120
121
	private function getNameFromRequest( AddDonationRequest $request ): DonorName {
122
		$name = $request->donorIsCompany() ? DonorName::newCompanyName() : DonorName::newPrivatePersonName();
123
124
		$name->setSalutation( $request->getDonorSalutation() );
125
		$name->setTitle( $request->getDonorTitle() );
126
		$name->setCompanyName( $request->getDonorCompany() );
127
		$name->setFirstName( $request->getDonorFirstName() );
128
		$name->setLastName( $request->getDonorLastName() );
129
130
		return $name->freeze()->assertNoNullFields();
131
	}
132
133
	private function getInitialDonationStatus( string $paymentType ): string {
134
		if ( $paymentType === PaymentType::DIRECT_DEBIT ) {
135
			return Donation::STATUS_NEW;
136
		}
137
138
		if ( $paymentType === PaymentType::BANK_TRANSFER ) {
139
			return Donation::STATUS_PROMISE;
140
		}
141
142
		return Donation::STATUS_EXTERNAL_INCOMPLETE;
143
	}
144
145
	private function getPaymentFromRequest( AddDonationRequest $donationRequest ): DonationPayment {
146
		return new DonationPayment(
147
			$donationRequest->getAmount(),
148
			$donationRequest->getInterval(),
149
			$this->getPaymentMethodFromRequest( $donationRequest )
150
		);
151
	}
152
153
	private function getPaymentMethodFromRequest( AddDonationRequest $donationRequest ): PaymentMethod {
154
		$paymentType = $donationRequest->getPaymentType();
155
156
		switch ( $paymentType ) {
157
			case PaymentType::BANK_TRANSFER:
158
				return new BankTransferPayment( $this->transferCodeGenerator->generateTransferCode() );
159
			case PaymentType::DIRECT_DEBIT:
160
				return new DirectDebitPayment( $donationRequest->getBankData() );
161
			case PaymentType::PAYPAL:
162
				return new PayPalPayment( new PayPalData() );
163
			case PaymentType::SOFORT:
164
				return new SofortPayment( $this->transferCodeGenerator->generateTransferCode() );
165
			default:
166
				return new PaymentWithoutAssociatedData( $paymentType );
167
		}
168
	}
169
170
	private function newTrackingInfoFromRequest( AddDonationRequest $request ): DonationTrackingInfo {
171
		$trackingInfo = new DonationTrackingInfo();
172
173
		$trackingInfo->setTracking( $request->getTracking() );
174
		$trackingInfo->setSource( $this->referrerGeneralizer->generalize( $request->getSource() ) );
175
		$trackingInfo->setTotalImpressionCount( $request->getTotalImpressionCount() );
176
		$trackingInfo->setSingleBannerImpressionCount( $request->getSingleBannerImpressionCount() );
177
		$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...
178
		$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...
179
		$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...
180
181
		return $trackingInfo->freeze()->assertNoNullFields();
182
	}
183
184
	/**
185
	 * @param Donation $donation
186
	 *
187
	 * @throws \RuntimeException
188
	 */
189
	private function sendDonationConfirmationEmail( Donation $donation ) {
190
		if ( $donation->getDonor() !== null && !$donation->hasExternalPayment() ) {
191
			$this->mailer->sendConfirmationMailFor( $donation );
192
		}
193
	}
194
195
}