Completed
Push — master ( 530061...ece7ee )
by Jeroen De
82:37 queued 40:45
created

ApplyForMembershipHandler   B

Complexity

Total Complexity 12

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 18

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 18
dl 0
loc 136
rs 7.3333
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A createMembershipRequest() 0 50 2
A isSubmissionAllowed() 0 14 3
A __construct() 0 4 1
B handle() 0 26 3
B newHttpResponse() 0 31 3
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\App\RouteHandlers;
6
7
use Silex\Application;
8
use Symfony\Component\HttpFoundation\Cookie;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
use WMDE\Fundraising\Frontend\Factories\FunFunFactory;
12
use WMDE\Fundraising\Frontend\MembershipContext\Tracking\MembershipApplicationTrackingInfo;
13
use WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\ApplyForMembershipRequest;
14
use WMDE\Fundraising\Frontend\MembershipContext\UseCases\ApplyForMembership\ApplyForMembershipResponse;
15
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\BankData;
16
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\Iban;
17
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentType;
18
19
/**
20
 * @license GNU GPL v2+
21
 * @author Kai Nissen < [email protected] >
22
 */
23
class ApplyForMembershipHandler {
24
25
	private $ffFactory;
26
	private $app;
27
28
	public function __construct( FunFunFactory $ffFactory, Application $app ) {
29
		$this->ffFactory = $ffFactory;
30
		$this->app = $app;
31
	}
32
33
	public function handle( Request $request ): Response {
34
		if ( !$this->isSubmissionAllowed( $request ) ) {
35
			return new Response( $this->ffFactory->newSystemMessageResponse( 'membership_application_rejected_limit' ) );
36
		}
37
38
		$applyForMembershipRequest = $this->createMembershipRequest( $request );
39
		$responseModel = $this->ffFactory->newApplyForMembershipUseCase()->applyForMembership( $applyForMembershipRequest );
40
41
		if ( $responseModel->isSuccessful() ) {
42
			$httpResponse = $this->newHttpResponse( $responseModel );
43
44
			$cookie = new Cookie(
45
				ShowMembershipConfirmationHandler::SUBMISSION_COOKIE_NAME,
46
				date( ShowMembershipConfirmationHandler::TIMESTAMP_FORMAT )
47
			);
48
			$httpResponse->headers->setCookie( $cookie );
49
			return $httpResponse;
50
		}
51
52
		return new Response(
53
			$this->ffFactory->newMembershipFormViolationPresenter()->present(
54
				$applyForMembershipRequest,
55
				$request->request->get( 'showMembershipTypeOption' ) === 'true'
56
			)
57
		);
58
	}
59
60
	private function createMembershipRequest( Request $httpRequest ): ApplyForMembershipRequest {
61
		$request = new ApplyForMembershipRequest();
62
63
		$request->setMembershipType( $httpRequest->request->get( 'membership_type', '' ) );
64
65
		if ( $httpRequest->request->get( 'adresstyp', '' )  === 'firma' ) {
66
			$request->markApplicantAsCompany();
67
		}
68
69
		$request->setApplicantSalutation( $httpRequest->request->get( 'anrede', '' ) );
70
		$request->setApplicantTitle( $httpRequest->request->get( 'titel', '' ) );
71
		$request->setApplicantFirstName( $httpRequest->request->get( 'vorname', '' ) );
72
		$request->setApplicantLastName( $httpRequest->request->get( 'nachname', '' ) );
73
		$request->setApplicantCompanyName( $httpRequest->request->get( 'firma', '' ) );
74
75
		$request->setApplicantStreetAddress( $httpRequest->request->get( 'strasse', '' ) );
76
		$request->setApplicantPostalCode( $httpRequest->request->get( 'postcode', '' ) );
77
		$request->setApplicantCity( $httpRequest->request->get( 'ort', '' ) );
78
		$request->setApplicantCountryCode( $httpRequest->request->get( 'country', '' ) );
79
80
		$request->setApplicantEmailAddress( $httpRequest->request->get( 'email', '' ) );
81
		$request->setApplicantPhoneNumber( $httpRequest->request->get( 'phone', '' ) );
82
		$request->setApplicantDateOfBirth( $httpRequest->request->get( 'dob', '' ) );
83
84
		$request->setPaymentType( $httpRequest->request->get( 'payment_type', '' ) );
85
		$request->setPaymentIntervalInMonths( (int)$httpRequest->request->get( 'membership_fee_interval', 0 ) );
86
		// TODO: German format expected here, amount should be converted based on user's locale
87
		$request->setPaymentAmountInEuros( str_replace( ',', '.', $httpRequest->request->get( 'membership_fee', '' ) ) );
88
89
		$request->setTrackingInfo( new MembershipApplicationTrackingInfo(
90
			$httpRequest->request->get( 'templateCampaign', '' ),
91
			$httpRequest->request->get( 'templateName', '' )
92
		) );
93
94
		$request->setPiwikTrackingString( $httpRequest->cookies->get( 'spenden_tracking', '' ) );
95
96
		$bankData = new BankData();
97
98
		$bankData->setBankName( $httpRequest->request->get( 'bank_name', '' ) );
99
		$bankData->setIban( new Iban( $httpRequest->request->get( 'iban', '' ) ) );
100
		$bankData->setBic( $httpRequest->request->get( 'bic', '' ) );
101
		$bankData->setAccount( $httpRequest->request->get( 'account_number', '' ) );
102
		$bankData->setBankCode( $httpRequest->request->get( 'bank_code', '' ) );
103
104
		$bankData->assertNoNullFields()->freeze();
105
		$request->setBankData( $bankData );
106
		$request->assertNoNullFields()->freeze();
107
108
		return $request;
109
	}
110
111
	private function isSubmissionAllowed( Request $request ) {
112
		$lastSubmission = $request->cookies->get( ShowMembershipConfirmationHandler::SUBMISSION_COOKIE_NAME, '' );
113
		if ( $lastSubmission === '' ) {
114
			return true;
115
		}
116
117
		$minNextTimestamp = \DateTime::createFromFormat( ShowMembershipConfirmationHandler::TIMESTAMP_FORMAT, $lastSubmission )
118
			->add( new \DateInterval( $this->ffFactory->getMembershipApplicationTimeframeLimit() ) );
119
		if ( $minNextTimestamp > new \DateTime() ) {
120
			return false;
121
		}
122
123
		return true;
124
	}
125
126
	private function newHttpResponse( ApplyForMembershipResponse $responseModel ): Response {
127
		switch( $responseModel->getMembershipApplication()->getPayment()->getPaymentMethod()->getType() ) {
128
			case PaymentType::DIRECT_DEBIT:
129
				$httpResponse = $this->app->redirect(
130
					$this->app['url_generator']->generate(
131
						'show-membership-confirmation',
132
						[
133
							'id' => $responseModel->getMembershipApplication()->getId(),
134
							'accessToken' => $responseModel->getAccessToken()
135
						]
136
					),
137
					Response::HTTP_SEE_OTHER
138
				);
139
140
				break;
141
			case PaymentType::PAYPAL:
142
				$httpResponse = $this->app->redirect(
143
					$this->ffFactory->newPayPalUrlGeneratorForMembershipApplications()->generateUrl(
144
						$responseModel->getMembershipApplication()->getId(),
145
						$responseModel->getMembershipApplication()->getPayment()->getAmount(),
146
						$responseModel->getMembershipApplication()->getPayment()->getIntervalInMonths(),
147
						$responseModel->getUpdateToken(),
148
						$responseModel->getAccessToken()
149
					)
150
				);
151
				break;
152
			default:
153
				throw new \LogicException( 'This code should not be reached' );
154
		}
155
		return $httpResponse;
156
	}
157
158
}