Passed
Push — master ( c0e452...1f19b9 )
by Jared
55s
created

Order::createOrReverse()   C

Complexity

Conditions 7
Paths 22

Size

Total Lines 43
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 43
rs 6.7272
cc 7
eloc 27
nc 22
nop 3
1
<?php
2
namespace CultureKings\Afterpay\Service\InStore;
3
4
use CultureKings\Afterpay\Exception\ApiException;
5
use CultureKings\Afterpay\Model;
6
use DateTime;
7
use GuzzleHttp\Exception\BadResponseException;
8
use GuzzleHttp\Exception\RequestException;
9
use GuzzleHttp\HandlerStack;
10
11
/**
12
 * Class Order
13
 * @package CultureKings\Afterpay\Service\InStore
14
 */
15
class Order extends AbstractService
16
{
17
    const ERROR_DECLINED = 402;
18
    const ERROR_MINIMUM_NOT_MET = 402;
19
    const ERROR_EXCEED_PREAPPROVAL = 402;
20
    const ERROR_CONFLICT = 409;
21
    const ERROR_INVALID_CODE = 412;
22
    const ERROR_MSG_PRECONDITION_FAILED = 'precondition_failed';
23
24
    /**
25
     * @param Model\InStore\Order $order
26
     * @param HandlerStack|null   $stack
27
     *
28
     * @return array|\JMS\Serializer\scalar|object
29
     */
30
    public function create(Model\InStore\Order $order, HandlerStack $stack = null)
31
    {
32
        try {
33
            $params = $this->generateParams($order, $stack);
34
35
            $result = $this->getClient()->post('orders', $params);
36
37
            return $this->getSerializer()->deserialize(
38
                (string) $result->getBody(),
39
                Model\InStore\Order::class,
40
                'json'
41
            );
42
        } catch (BadResponseException $e) {
43
            throw new ApiException(
44
                $this->getSerializer()->deserialize(
45
                    (string) $e->getResponse()->getBody(),
46
                    Model\ErrorResponse::class,
47
                    'json'
48
                ),
49
                $e
50
            );
51
        }
52
    }
53
54
    /**
55
     * @param Model\InStore\Reversal $orderReversal
56
     * @param HandlerStack|null      $stack
57
     * @throws ApiException
58
     *
59
     * @return Model\InStore\Reversal
60
     */
61
    public function reverse(Model\InStore\Reversal $orderReversal, HandlerStack $stack = null)
62
    {
63
        try {
64
            $params = $this->generateParams($orderReversal, $stack);
65
66
            $result = $this->getClient()->post('orders/reverse', $params);
67
68
            /** @var Model\InStore\Reversal $reversal */
69
            $reversal = $this->getSerializer()->deserialize(
70
                (string) $result->getBody(),
71
                Model\InStore\Reversal::class,
72
                'json'
73
            );
74
75
            return $reversal;
76
        } catch (BadResponseException $e) {
77
            throw new ApiException(
78
                $this->getSerializer()->deserialize(
79
                    (string) $e->getResponse()->getBody(),
80
                    Model\ErrorResponse::class,
81
                    'json'
82
                ),
83
                $e
84
            );
85
        }
86
    }
87
88
    /**
89
     * Helper method to automatically attempt to reverse an order if an error occurs.
90
     *
91
     * Order reversal model does not have to be passed in and will be automatically generated if not.
92
     *
93
     * @param Model\InStore\Order         $order
94
     * @param Model\InStore\Reversal|null $orderReversal
95
     * @param HandlerStack|null           $stack
96
     *
97
     * @return Model\InStore\Order|Model\InStore\Reversal|array|\JMS\Serializer\scalar|object
98
     */
99
    public function createOrReverse(
100
        Model\InStore\Order $order,
101
        Model\InStore\Reversal $orderReversal = null,
102
        HandlerStack $stack = null
103
    ) {
104
        try {
105
            return $this->create($order, $stack);
106
        } catch (ApiException $orderException) {
107
            // http://docs.afterpay.com.au/instore-api-v1.html#create-order
108
            // Should a success or error response (with exception to 409 conflict) not be received,
109
            // the POS should queue the request ID for reversal
110
            if ($orderException->getErrorResponse()->getErrorCode() === self::ERROR_CONFLICT) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $orderException->getErro...ponse()->getErrorCode() (string) and self::ERROR_CONFLICT (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
111
                throw $orderException;
112
            }
113
            $errorResponse = $orderException->getErrorResponse();
114
        } catch (RequestException $orderException) {
115
            // a timeout or other exception has occurred. attempt a reversal
116
            $errorResponse = new Model\ErrorResponse();
117
            $errorResponse->setHttpStatusCode($orderException->getResponse()->getStatusCode());
118
            $errorResponse->setMessage($orderException->getMessage());
119
        }
120
121
        if ($orderReversal === null) {
122
            $orderReversal = new Model\InStore\Reversal();
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $orderReversal. This often makes code more readable.
Loading history...
123
            $orderReversal->setReversingRequestId($order->getRequestId());
124
            $orderReversal->setRequestedAt(new DateTime());
125
        }
126
127
        try {
128
            $reversal = $this->reverse($orderReversal, $stack);
129
            $reversal->setErrorReason($errorResponse);
130
131
            return $reversal;
132
        } catch (ApiException $reversalException) {
133
            $reversalErrorResponse = $reversalException->getErrorResponse();
134
            if ($reversalErrorResponse->getErrorCode() === self::ERROR_MSG_PRECONDITION_FAILED) {
135
                // there was trouble reversing probably because the order failed
136
                throw $orderException;
137
            }
138
139
            throw $reversalException;
140
        }
141
    }
142
}
143