Order::reverse()   A
last analyzed

Complexity

Conditions 2
Paths 4

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 9.504
c 0
b 0
f 0
cc 2
nc 4
nop 2
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_INTERNAL_ERROR = 500;
23
    const ERROR_MSG_PRECONDITION_FAILED = 'precondition_failed';
24
25
    /**
26
     * @param Model\InStore\Order $order
27
     * @param HandlerStack|null   $stack
28
     *
29
     * @return array|\JMS\Serializer\scalar|object
30
     */
31
    public function create(Model\InStore\Order $order, HandlerStack $stack = null)
32
    {
33
        try {
34
            $params = $this->generateParams($order, $stack);
35
36
            $result = $this->getClient()->post('orders', $params);
37
38
            return $this->getSerializer()->deserialize(
39
                (string) $result->getBody(),
40
                Model\InStore\Order::class,
41
                'json'
42
            );
43
        } catch (BadResponseException $e) {
44
            throw new ApiException(
45
                $this->getSerializer()->deserialize(
46
                    (string) $e->getResponse()->getBody(),
47
                    Model\ErrorResponse::class,
48
                    'json'
49
                ),
50
                $e
51
            );
52
        }
53
    }
54
55
    /**
56
     * @param Model\InStore\Reversal $orderReversal
57
     * @param HandlerStack|null      $stack
58
     * @throws ApiException
59
     *
60
     * @return Model\InStore\Reversal
61
     */
62
    public function reverse(Model\InStore\Reversal $orderReversal, HandlerStack $stack = null)
63
    {
64
        try {
65
            $params = $this->generateParams($orderReversal, $stack);
66
67
            $result = $this->getClient()->post('orders/reverse', $params);
68
69
            /** @var Model\InStore\Reversal $reversal */
70
            $reversal = $this->getSerializer()->deserialize(
71
                (string) $result->getBody(),
72
                Model\InStore\Reversal::class,
73
                'json'
74
            );
75
76
            return $reversal;
77
        } catch (BadResponseException $e) {
78
            throw new ApiException(
79
                $this->getSerializer()->deserialize(
80
                    (string) $e->getResponse()->getBody(),
81
                    Model\ErrorResponse::class,
82
                    'json'
83
                ),
84
                $e
85
            );
86
        }
87
    }
88
89
    /**
90
     * Helper method to automatically attempt to reverse an order if an error occurs.
91
     *
92
     * Order reversal model does not have to be passed in and will be automatically generated if not.
93
     *
94
     * @param Model\InStore\Order         $order
95
     * @param Model\InStore\Reversal|null $orderReversal
96
     * @param HandlerStack|null           $stack
97
     *
98
     * @return Model\InStore\Order|Model\InStore\Reversal|array|\JMS\Serializer\scalar|object
99
     */
100
    public function createOrReverse(
101
        Model\InStore\Order $order,
102
        Model\InStore\Reversal $orderReversal = null,
103
        HandlerStack $stack = null
104
    ) {
105
        try {
106
            return $this->create($order, $stack);
107
        } catch (ApiException $orderException) {
108
            // http://docs.afterpay.com.au/instore-api-v1.html#create-order
109
            // Should a success or error response (with exception to 409 conflict) not be received,
110
            // the POS should queue the request ID for reversal
111
            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...
112
                throw $orderException;
113
            }
114
            $errorResponse = $orderException->getErrorResponse();
115
        } catch (RequestException $orderException) {
116
            // a timeout or other exception has occurred. attempt a reversal
117
            $errorResponse = new Model\ErrorResponse();
118
119
            $errorResponse->setHttpStatusCode(
120
                $orderException->getResponse() ? $orderException->getResponse()->getStatusCode() : self::ERROR_INTERNAL_ERROR
121
            );
122
123
            $errorResponse->setMessage($orderException->getMessage());
124
        }
125
126
        if ($orderReversal === null) {
127
            $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...
128
            $orderReversal->setReversingRequestId($order->getRequestId());
129
            $orderReversal->setRequestedAt(new DateTime());
130
        }
131
132
        try {
133
            $reversal = $this->reverse($orderReversal, $stack);
134
            $reversal->setErrorReason($errorResponse);
135
136
            return $reversal;
137
        } catch (ApiException $reversalException) {
138
            $reversalErrorResponse = $reversalException->getErrorResponse();
139
            if ($reversalErrorResponse->getErrorCode() === self::ERROR_MSG_PRECONDITION_FAILED) {
140
                // there was trouble reversing probably because the order failed
141
                throw $orderException;
142
            }
143
144
            throw $reversalException;
145
        }
146
    }
147
}
148