Completed
Pull Request — master (#594)
by Jeroen De
12:09
created

handleNotification()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.439
c 0
b 0
f 0
cc 6
eloc 14
nc 6
nop 1
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\DonatingContext\UseCases\CreditCardPaymentNotification;
6
7
use Psr\Log\LoggerInterface;
8
use WMDE\Fundraising\Frontend\DonatingContext\Authorization\DonationAuthorizer;
9
use WMDE\Fundraising\Frontend\DonatingContext\Domain\Model\Donation;
10
use WMDE\Fundraising\Frontend\DonatingContext\Domain\Repositories\DonationRepository;
11
use WMDE\Fundraising\Frontend\DonatingContext\Domain\Repositories\GetDonationException;
12
use WMDE\Fundraising\Frontend\DonatingContext\Domain\Repositories\StoreDonationException;
13
use WMDE\Fundraising\Frontend\DonatingContext\Infrastructure\DonationConfirmationMailer;
14
use WMDE\Fundraising\Frontend\DonatingContext\Infrastructure\DonationEventLogger;
15
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\CreditCardTransactionData;
16
use WMDE\Fundraising\Frontend\PaymentContext\Domain\Model\PaymentType;
17
use WMDE\Fundraising\Frontend\PaymentContext\Infrastructure\CreditCardService;
18
19
/**
20
 * @license GNU GPL v2+
21
 * @author Kai Nissen < [email protected] >
22
 */
23
class CreditCardNotificationUseCase {
24
25
	private $repository;
26
	private $authorizationService;
27
	private $mailer;
28
	private $logger;
29
	private $donationEventLogger;
30
31
	public function __construct( DonationRepository $repository, DonationAuthorizer $authorizationService,
32
								 CreditCardService $creditCardService, DonationConfirmationMailer $mailer,
33
								 LoggerInterface $logger, DonationEventLogger $donationEventLogger ) {
34
		$this->repository = $repository;
35
		$this->authorizationService = $authorizationService;
36
		$this->creditCardService = $creditCardService;
0 ignored issues
show
Bug introduced by
The property creditCardService does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
37
		$this->mailer = $mailer;
38
		$this->logger = $logger;
39
		$this->donationEventLogger = $donationEventLogger;
40
	}
41
42
	/**
43
	 * @param CreditCardPaymentNotificationRequest $request
44
	 * @throws CreditCardPaymentHandlerException
45
	 */
46
	public function handleNotification( CreditCardPaymentNotificationRequest $request ) {
47
		try {
48
			$donation = $this->repository->getDonationById( $request->getDonationId() );
49
		} catch ( GetDonationException $ex ) {
50
			throw new CreditCardPaymentHandlerException( 'data set could not be retrieved from database', $ex );
51
		}
52
53
		if ( $donation === null ) {
54
			throw new CreditCardPaymentHandlerException( 'donation not found' );
55
		}
56
57
		if ( $donation->getPaymentType() !== PaymentType::CREDIT_CARD ) {
58
			throw new CreditCardPaymentHandlerException( 'payment type mismatch' );
59
		}
60
61
		if ( !$donation->getAmount()->equals( $request->getAmount() ) ) {
62
			throw new CreditCardPaymentHandlerException( 'amount mismatch' );
63
		}
64
65
		if ( !$this->authorizationService->systemCanModifyDonation( $request->getDonationId() ) ) {
66
			throw new CreditCardPaymentHandlerException( 'invalid or expired token' );
67
		}
68
69
		$this->handleRequest( $request, $donation );
70
	}
71
72
	/**
73
	 * @param CreditCardPaymentNotificationRequest $request
74
	 * @param \WMDE\Fundraising\Frontend\DonatingContext\Domain\Model\Donation $donation
75
	 */
76
	private function handleRequest( CreditCardPaymentNotificationRequest $request, Donation $donation ) {
77
		try {
78
			$donation->addCreditCardData( $this->newCreditCardDataFromRequest( $request ) );
79
			$donation->confirmBooked();
80
		} catch ( \RuntimeException $e ) {
81
			throw new CreditCardPaymentHandlerException( 'data set could not be updated', $e );
82
		}
83
84
		try {
85
			$this->repository->storeDonation( $donation );
86
		}
87
		catch ( StoreDonationException $ex ) {
88
			throw new CreditCardPaymentHandlerException( 'updated data set could not be stored', $ex );
89
		}
90
91
		$this->sendConfirmationEmail( $donation );
92
		$this->donationEventLogger->log( $donation->getId(), 'mcp_handler: booked' );
93
	}
94
95
	private function sendConfirmationEmail( Donation $donation ) {
96
		if ( $donation->getDonor() !== null ) {
97
			try {
98
				$this->mailer->sendConfirmationMailFor( $donation );
99
			} catch ( \RuntimeException $ex ) {
100
				// no need to re-throw or return false, this is not a fatal error, only a minor inconvenience
101
			}
102
		}
103
	}
104
105
	private function newCreditCardDataFromRequest( CreditCardPaymentNotificationRequest $request ): CreditCardTransactionData {
106
		return ( new CreditCardTransactionData() )
107
			->setTransactionId( $request->getTransactionId() )
108
			->setTransactionStatus( 'processed' )
109
			->setTransactionTimestamp( new \DateTime() )
110
			->setCardExpiry( $this->creditCardService->getExpirationDate( $request->getCustomerId() ) )
111
			->setAmount( $request->getAmount() )
112
			->setCustomerId( $request->getCustomerId() )
113
			->setSessionId( $request->getSessionId() )
114
			->setAuthId( $request->getAuthId() )
115
			->setTitle( $request->getTitle() )
116
			->setCountryCode( $request->getCountry() )
117
			->setCurrencyCode( $request->getCurrency() );
118
	}
119
120
}
121