Completed
Push — master ( 25648a...558e7e )
by Jeroen De
14s
created

AddDonationUseCase::getPaymentFromRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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