• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PiteurStudio / CourierDZ / 13101535973

02 Feb 2025 06:48PM UTC coverage: 26.042%. First build
13101535973

Pull #9

github

web-flow
Merge a8aadf6dd into 4fe37b9d1
Pull Request #9: improve composer test scripts

1 of 23 new or added lines in 5 files covered. (4.35%)

100 of 384 relevant lines covered (26.04%)

3.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

5.21
/src/ProviderIntegrations/ProcolisProviderIntegration.php
1
<?php
2

3
namespace CourierDZ\ProviderIntegrations;
4

5
use CourierDZ\Contracts\ShippingProviderContract;
6
use CourierDZ\Exceptions\CreateOrderException;
7
use CourierDZ\Exceptions\CredentialsException;
8
use CourierDZ\Exceptions\FunctionNotSupportedException;
9
use CourierDZ\Exceptions\HttpException;
10
use CourierDZ\Exceptions\TrackingIdNotFoundException;
11
use CourierDZ\Support\ShippingProviderValidation;
12
use GuzzleHttp\Client;
13
use GuzzleHttp\Exception\GuzzleException;
14
use GuzzleHttp\Psr7\Request;
15
use http\Exception\InvalidArgumentException;
16

17
abstract class ProcolisProviderIntegration implements ShippingProviderContract
18
{
19
    use ShippingProviderValidation;
20

21
    /**
22
     * Provider credentials
23
     *
24
     * @var array<non-empty-string, non-empty-string>
25
     */
26
    private array $credentials;
27

28
    /**
29
     * Validation rules for creating an order
30
     *
31
     * @var array<non-empty-string, non-empty-string>
32
     */
33
    public array $getCreateOrderValidationRules = [
34
        'Tracking' => 'nullable|string',
35
        'TypeLivraison' => 'in:0,1', // Domicile : 0 & Stopdesk : 1
36
        'TypeColis' => 'in:0,1', // Echange : 1
37
        'Confrimee' => 'required|in:0,1', // 1 pour les colis Confirmer directement en pret a expedier ( note : if empty zr will set it to 1 because if that field is required )
38
        'Client' => 'required|string',
39
        'MobileA' => 'required|string',
40
        'MobileB' => 'nullable|string',
41
        'Adresse' => 'required|string',
42
        'IDWilaya' => 'required|numeric',
43
        'Commune' => 'required|string',
44
        'Total' => 'required|numeric',
45
        'Note' => 'nullable|string',
46
        'TProduit' => 'required|string',
47
        'id_Externe' => 'nullable|string', // Votre ID ou Tracking
48
        'Source' => 'nullable|string',
49
    ];
50

51
    /**
52
     * Create a new instance of the Procolis provider integration.
53
     *
54
     * @param  array<non-empty-string, non-empty-string>  $credentials  An array of credentials for the provider, containing the 'token' and 'key' keys
55
     *
56
     * @throws CredentialsException If the credentials do not contain the 'token' and 'key' keys
57
     */
58
    public function __construct(array $credentials)
59
    {
60
        // Check if the credentials contain the 'token' and 'key' keys
61
        if (! isset($credentials['token']) || ! isset($credentials['key'])) {
36✔
62
            throw new CredentialsException('Procolis credentials must include "token" and "key".');
12✔
63
        }
64

65
        // Store the credentials
66
        $this->credentials = $credentials;
24✔
67
    }
68

69
    // test credentials method
70

71
    /**
72
     * Tests the credentials by making a GET request to the Procolis API to retrieve
73
     * the token status. If the request is successful, the method returns true. If
74
     * the request returns a 401 status code, the method returns false. If the
75
     * request returns any other status code, the method throws an HttpException.
76
     *
77
     * @throws HttpException If the request fails
78
     */
79
    public function testCredentials(): bool
80
    {
81
        try {
82
            // Initialize Guzzle client
83
            $client = new Client;
×
84

85
            // Define the headers
86
            $headers = [
×
87
                'token' => $this->credentials['token'],
×
88
                'key' => $this->credentials['key'],
×
89
            ];
×
90

91
            // Make the GET request
92
            $response = $client->request('GET', 'https://procolis.com/api_v1/token', [
×
93
                'headers' => $headers,
×
94
            ]);
×
95

96
            // Get the response body
97
            $body = $response->getBody()->getContents();
×
98

99
            // Decode JSON response
100
            $data = json_decode($body, true);
×
101

102
            // Check the status code
NEW
103
            return match ($response->getStatusCode()) {
×
104
                // If the request is successful, return true
NEW
105
                200 => $data['Statut'] === 'Accès activé',
×
106
                // If the request returns a 401 status code, return false
NEW
107
                401 => false,
×
108
                // If the request returns any other status code, throw an HttpException
NEW
109
                default => throw new HttpException('Procolis, Unexpected error occurred.'),
×
NEW
110
            };
×
111
        } catch (GuzzleException $e) {
×
112
            // Handle exceptions
113
            throw new HttpException($e->getMessage());
×
114
        }
115

116
    }
117

118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function getRates(?int $from_wilaya_id, ?int $to_wilaya_id): array
122
    {
123
        try {
124
            // Initialize Guzzle client
125
            $client = new Client;
×
126

127
            // Define the headers
128
            $headers = [
×
129
                'token' => $this->credentials['token'],
×
130
                'key' => $this->credentials['key'],
×
131
                'Content-Type' => 'application/json',
×
132
            ];
×
133

134
            // Make the GET request
135
            $response = $client->request('POST', 'https://procolis.com/api_v1/tarification', [
×
136
                'headers' => $headers,
×
137
            ]);
×
138

139
            // Get the response body
140
            $body = $response->getBody()->getContents();
×
141

142
            $result = json_decode($body, true);
×
143

144
            // If the to_wilaya_id is specified, filter the result to only include the specified wilaya
145
            if ($to_wilaya_id) {
×
146
                $filteredResult = [];
×
147
                foreach ($result as $wilaya) {
×
148
                    if ($wilaya['IDWilaya'] == $to_wilaya_id) {
×
149
                        $filteredResult = $wilaya;
×
150
                        break;
×
151
                    }
152
                }
153

154
                // If no matching wilaya is found, return an empty array
155
                if (empty($filteredResult)) {
×
156
                    return [];
×
157
                }
158

159
                // Return the first matching wilaya
160
                return $filteredResult;
×
161
            }
162

163
            // Decode JSON response
164
            return $result;
×
165

166
        } catch (GuzzleException $e) {
×
167
            // Handle exceptions
168
            throw new HttpException($e->getMessage());
×
169
        }
170
    }
171

172
    public function getCreateOrderValidationRules(): array
173
    {
174
        return $this->getCreateOrderValidationRules;
6✔
175
    }
176

177
    /**
178
     * {@inheritdoc}
179
     */
180
    public function createOrder(array $orderData): array
181
    {
182
        // Validate the order data
183
        $this->validateCreate($orderData);
6✔
184

185
        // Prepare the request body
186
        $data = [
×
187
            'Colis' => [
×
188
                $orderData,
×
189
            ],
×
190
        ];
×
191

192
        $requestBody = json_encode($data, JSON_UNESCAPED_UNICODE);
×
193

194
        if ($requestBody === false) {
×
195
            throw new CreateOrderException('Create Order failed ( JSON Encoding Error ) : '.json_last_error_msg());
×
196
        }
197

198
        try {
199
            // Initialize Guzzle client
200
            $client = new Client;
×
201

202
            // Define the headers
203
            $headers = [
×
204
                'token' => $this->credentials['token'],
×
205
                'key' => $this->credentials['key'],
×
206
                'Content-Type' => 'application/json',
×
207
            ];
×
208

209
            $request = new Request('POST', 'https://procolis.com/api_v1/add_colis', $headers, $requestBody);
×
210

211
            $response = $client->send($request);
×
212

213
            // Get the response body
214
            $body = $response->getBody()->getContents();
×
215

216
            $arrayResponse = json_decode($body, true);
×
217

218
            $message = $arrayResponse['Colis'][0]['MessageRetour'];
×
219

220
            // Check if the order creation was successful
221
            if ($message === 'Double Tracking') {
×
222
                throw new CreateOrderException('Create Order failed ( Duplicate `Tracking` ) : '.implode(' ', $arrayResponse['Colis'][0]));
×
223
            }
224

225
            if ($message !== 'Good') {
×
226

227
                throw new CreateOrderException('Create Order failed ( `'.$message.'` ) : '.implode(' ', $arrayResponse['Colis'][0]));
×
228
            }
229

230
            // Return the created order
231
            return $arrayResponse['Colis'][0];
×
232

233
        } catch (GuzzleException $e) {
×
234
            // Handle exceptions
235
            throw new HttpException($e->getMessage());
×
236
        }
237
    }
238

239
    /**
240
     * {@inheritdoc}
241
     */
242
    public function getOrder(string $trackingId): array
243
    {
244
        $data = [
×
245
            'Colis' => [
×
246
                ['Tracking' => $trackingId],
×
247
            ],
×
248
        ];
×
249

250
        $requestBody = json_encode($data, JSON_UNESCAPED_UNICODE);
×
251

252
        if ($requestBody === false) {
×
253
            throw new InvalidArgumentException('$trackingId must be a non-empty string');
×
254
        }
255

256
        try {
257
            // Initialize Guzzle client
258
            $client = new Client;
×
259

260
            // Define the headers
261
            $headers = [
×
262
                'token' => $this->credentials['token'],
×
263
                'key' => $this->credentials['key'],
×
264
                'Content-Type' => 'application/json',
×
265
            ];
×
266

267
            $request = new Request('POST', 'https://procolis.com/api_v1/lire', $headers, $requestBody);
×
268

269
            $response = $client->send($request);
×
270

271
            // Get the response body
272
            $body = $response->getBody()->getContents();
×
273

274
            if ($body === 'null') {
×
275
                throw new TrackingIdNotFoundException('Tracking ID not found : '.$trackingId.' , Provider : Procolis');
×
276
            }
277

278
            $arrayResponse = json_decode($body, true);
×
279

280
            // Decode JSON response
281
            return $arrayResponse['Colis'][0];
×
282

283
        } catch (GuzzleException $e) {
×
284
            // Handle exceptions
285
            throw new HttpException($e->getMessage());
×
286
        }
287
    }
288

289
    /**
290
     * @throws FunctionNotSupportedException
291
     */
292
    public function cancelOrder(string $orderId): bool
293
    {
294
        throw new FunctionNotSupportedException('Cancel order is not supported by Procolis.');
×
295
    }
296

297
    /**
298
     * @throws FunctionNotSupportedException
299
     */
300
    public function orderLabel(string $orderId): array
301
    {
302
        throw new FunctionNotSupportedException('orderLabel is not supported by Procolis.');
×
303
    }
304

305
    /**
306
     * {@inheritdoc}
307
     */
308
    abstract public static function metadata(): array;
309
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc