Skip to content

Commit

Permalink
Merge pull request #11 from n4ss1m/feature_maystro_delivery
Browse files Browse the repository at this point in the history
features: support more methods for Maystro Delivery
  • Loading branch information
n4ss1m authored Feb 4, 2025
2 parents f1521f2 + 7b83a36 commit b5476a7
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 33 deletions.
44 changes: 25 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
<img src="https://banners.beyondco.de/CourierDZ.png?theme=light&packageManager=composer+require&packageName=piteurstudio%2Fcourierdz&pattern=architect&style=style_1&description=Simplify+the+integration+of+Algerian+shipping+providers+into+your+applications&md=1&showWatermark=1&fontSize=100px&images=https%3A%2F%2Fwww.php.net%2Fimages%2Flogos%2Fnew-php-logo.svg&widths=300&heights=auto" alt="CourierDZ Banner" />

<p align="center">
<a href="https://php.net"><img src="https://img.shields.io/badge/PHP-8.2-777BB4?logo=php" alt="PHP 8.2"></a>
<a href="https://packagist.org/packages/piteurstudio/courierdz"><img src="https://img.shields.io/packagist/v/piteurstudio/courierdz.svg?style=flat-square" alt="Latest Version on Packagist"></a>
<a href="https://github.com/piteurstudio/courierdz/actions/workflows/run-tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/piteurstudio/courierdz/run-tests.yml?branch=main&amp;label=tests&amp;style=flat-square" alt="Tests"></a>
<a href="https://php.net"><img src="https://poser.pugx.org/piteurstudio/CourierDZ/require/php" alt="PHP 8.2"></a>
<a href="https://packagist.org/packages/piteurstudio/courierdz"><img src="https://img.shields.io/packagist/v/piteurstudio/courierdz.svg" alt="Latest Version on Packagist"></a>
<a href="https://github.com/piteurstudio/courierdz/actions/workflows/run-tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/piteurstudio/courierdz/run-tests.yml?branch=main&amp;label=tests" alt="Tests"></a>
<a href="https://coveralls.io/github/PiteurStudio/CourierDZ?branch=main"><img src="https://coveralls.io/repos/github/PiteurStudio/CourierDZ/badge.svg?branch=main" alt="Coverage Status"></a>
<a href="https://packagist.org/packages/piteurstudio/courierdz"><img src="https://img.shields.io/packagist/dt/piteurstudio/courierdz.svg?style=flat-square" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/piteurstudio/courierdz"><img src="https://img.shields.io/packagist/dt/piteurstudio/courierdz.svg" alt="Total Downloads"></a>
<a href="https://github.com/PiteurStudio/CourierDZ/tree/main/src/ShippingProviders"><img src="https://img.shields.io/badge/Supported_providers-6-blue" alt="Supported providers"></a>
</p>

# CourierDZ

CourierDZ is a PHP client designed to simplify the integration of Algerian shipping providers into your applications.
Whether you're working on an e-commerce platform or logistics solution, CourierDZ provides a unified and easy-to-use interface for managing orders, tracking shipments, and more.
Whether you're working on an e-commerce platform or logistics solution, and provides a unified and easy-to-use interface for managing orders, tracking shipments.

## Features

- **Multi-Provider Support**: Integrate with popular Algerian shipping services such as:
- Procolis ( Zr Express , <s>E-Com Delivery, Abex Express , Flash Delivery, E-Send , WIN DELIVERY , COLILOG EXPRESS, GODYMA EXPRESS , LETS GO DELIVERY, LEOPARD EXPRESS , MR LIVREUR, EL AMANA DELIVERY, ALLO LIVRAISON, COLIRELI</s> )
- Yalidine ( Yalitec <s>, [GuepEX](https://guepex.app/app/login.php) , [Zimou Express](https://zimou-express.app/app/login.php)</s> )
- Ecotrack ( DHD , Conexlog (UPS) )
- <s>Mayesto Delivery</s>
- <s>[Elogistia](https://documenter.getpostman.com/view/21600448/2s8YzP14j2) </s>
- And more to come!
- `Yalidine` , `Yalitec`
- `Mayesto Delivery`
- `Procolis` ( `Zr Express` )
- `Ecotrack` ( `DHD` , `Conexlog/UPS` )
- **Unified API**: A consistent interface to interact with all supported providers.
- <s>**Order Management**: Create, update, and cancel shipping orders effortlessly.</s>
- **Order Management**: Create, update, and cancel shipping orders effortlessly.
- **Extensible Design**: Easily add new providers or customize existing ones.


Expand All @@ -42,18 +41,19 @@ composer require piteurstudio/courierdz
```

### Current Supported Methods
| **Provider/Feature** | **Yalidine** | **Procolis** | **Ecotrack** | **Mayesto Delivery** |
| **Provider/Feature** | **Yalidine** | **Procolis** | **Ecotrack** | **Maystro Delivery** |
|---------------------------------------------|--------------|--------------|--------------|----------------------|
| testCredentials |||||
| getRates |||||
| getRates(null , \$to_wilaya_id) |||| |
| getRates(\$from_wilaya_id , \$to_wilaya_id) |||| |
| getCreateValidationRules |||| |
| createOrder |||| |
| getOrder |||| |
| getRates(null , \$to_wilaya_id) |||| |
| getRates(\$from_wilaya_id , \$to_wilaya_id) |||| |
| getCreateValidationRules |||| |
| createOrder |||| |
| getOrder |||| |
| updateOrder |||||
| cancelOrder |||||
| orderLabel |||||
| orderLabel |||||
| createProduct |||||

- ✅ Implemented
- ❌ Unsupported by the provider
Expand Down Expand Up @@ -246,6 +246,12 @@ We appreciate your feedback and contributions to help improve this package.
- API Documentation
- Any other relevant information

### Future Planned Features
- [ ] Add more providers ( eg : [Elogistia](https://documenter.getpostman.com/view/21600448/2s8YzP14j2), E-Com Delivery, Abex Express , Flash Delivery, E-Send , WIN DELIVERY , COLILOG EXPRESS, GODYMA EXPRESS , LETS GO DELIVERY, LEOPARD EXPRESS , MR LIVREUR, EL AMANA DELIVERY, ALLO LIVRAISON, COLIRELI , Yalitec , [GuepEX](https://guepex.app/app/login.php) , [Zimou Express](https://zimou-express.app/app/login.php))
- [ ] Add more methods
- [ ] Add more tests
- [ ] Add more examples
- [ ] Add more documentation

## Changelog

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"scripts": {
"lint": "pint",
"refactor": "rector",
"test:unit": "pest --coverage --min=25",
"test:unit": "pest --coverage --min=22",
"test:lint": "pint --test",
"test:refactor": "rector --dry-run",
"test:types": "phpstan",
Expand Down
180 changes: 167 additions & 13 deletions src/ShippingProviders/MaystroDeliveryProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,22 @@ class MaystroDeliveryProvider implements ShippingProviderContract

/**
* Validation rules for creating an order
*
* @var array<non-empty-string, non-empty-string>
*/
public array $getCreateOrderValidationRules = [

'wilaya' => 'required|integer|min:1|max:58',
'commune' => 'required|integer|min:1',
'destination_text' => 'nullable|string|max:255',
'customer_phone' => 'required|numeric|digits_between:9,10',
'customer_name' => 'required|string|max:255',
'product_price' => 'required|integer',
'delivery_type' => 'required|integer|in:0,1', // 0 = Livraison à domicile , 1 = Point de retrait
'express' => 'boolean',
'note_to_driver' => 'nullable|string|max:255',
'products' => 'required|array',
'source' => 'required|equals:4',
'external_order_id' => 'nullable|string|max:255',
];

/**
Expand Down Expand Up @@ -58,12 +71,17 @@ public static function metadata(): array
'logo' => 'https://maystro-delivery.com/img/Maystro-blue-extonly.svg',
'description' => 'Maystro Delivery société de livraison en Algérie offre un service de livraison rapide et sécurisé .',
'website' => 'https://maystro-delivery.com/',
'api_docs' => null,
'api_docs' => 'https://maystro.gitbook.io/maystro-delivery-documentation',
'support' => 'https://maystro-delivery.com/ContactUS.html',
'tracking_url' => 'https://maystro-delivery.com/trackingSD.html',
];
}

public static function apiDomain(): string
{
return 'https://backend.maystro-delivery.com/api/';
}

/**
* Test the credentials
*
Expand All @@ -88,17 +106,17 @@ public function testCredentials(): bool
];

// Make the GET request
$response = $client->request('GET', 'https://b.maystro-delivery.com/api/base/wilayas/?country=1', [
$response = $client->request('GET', static::apiDomain().'base/wilayas/?country=1', [
'headers' => $headers,
'Content-Type' => 'application/json',
]);

// Check the status code
return match ($response->getStatusCode()) {
// If the request is successful, return true
200 => true,
// If the request returns a 401 or 403 status code, return false
401, 403 => false,
200, 201 => true,
// If the request returns a 401 status code, return false
401 => false,
// If the request returns any other status code, throw an HttpException
default => throw new HttpException(static::metadata()['name'].', Unexpected error occurred.'),
};
Expand All @@ -108,6 +126,9 @@ public function testCredentials(): bool
}
}

/**
* {@inheritdoc}
*/
public function getRates(?int $from_wilaya_id, ?int $to_wilaya_id): array
{
throw new NotImplementedException('Not implemented');
Expand All @@ -118,23 +139,156 @@ public function getCreateOrderValidationRules(): array
return $this->getCreateOrderValidationRules;
}

public function createProduct(string $store_id, string $logistical_description, ?string $product_id): array
{
$productData = [
'store_id' => $store_id,
'logistical_description' => $logistical_description,
];

if ($product_id !== null && $product_id !== '' && $product_id !== '0') {
$productData['product_id'] = $product_id;
}

try {
// Initialize Guzzle client
$client = new Client(['http_errors' => false]);

// Define the headers
$headers = [
'Authorization' => 'Token '.$this->credentials['token'],
];

// Make the GET request
$response = $client->request('POST', static::apiDomain().'stores/product/', [
'headers' => $headers,
'body' => $productData,
]);

if ($response->getStatusCode() == 200) {
return json_decode($response->getBody()->getContents(), true);
}

throw new HttpException(static::metadata()['name'].', Unexpected error occurred.');
} catch (GuzzleException $guzzleException) {
// Handle exceptions
throw new HttpException($guzzleException->getMessage());
}
}

/**
* {@inheritdoc}
*/
public function createOrder(array $orderData): array
{
throw new NotImplementedException('Not implemented');
// Validate the order data
$this->validateCreate($orderData);

try {
// Initialize Guzzle client
$client = new Client(['http_errors' => false]);

// Define the headers
$headers = [
'Authorization' => 'Token '.$this->credentials['token'],
];

// Make the GET request
$response = $client->request('POST', static::apiDomain().'stores/orders/', [
'headers' => $headers,
'body' => $orderData,
]);

if (in_array($response->getStatusCode(), [200, 201])) {
return json_decode($response->getBody()->getContents(), true);
}

throw new HttpException(static::metadata()['name'].', Unexpected error occurred.');
} catch (GuzzleException $guzzleException) {
// Handle exceptions
throw new HttpException($guzzleException->getMessage());
}
}

/**
* {@inheritdoc}
*/
public function getOrder(string $trackingId): array
{
throw new NotImplementedException('Not implemented');
$orderId = $trackingId;

try {
// Initialize Guzzle client
$client = new Client(['http_errors' => false]);

// Define the headers
$headers = [
'Authorization' => 'Token '.$this->credentials['token'],
];

// Make the GET request
$response = $client->request('GET', static::apiDomain().'stores/orders/'.$orderId.'/', [
'headers' => $headers,
]);

if (in_array($response->getStatusCode(), [200, 201])) {
return json_decode($response->getBody()->getContents(), true);
}

throw new HttpException(static::metadata()['name'].', Unexpected error occurred.');
} catch (GuzzleException $guzzleException) {
// Handle exceptions
throw new HttpException($guzzleException->getMessage());
}
}

/**
* {@inheritdoc}
*/
public function orderLabel(string $orderId): array
{
throw new NotImplementedException('Not implemented');
}
try {
// Initialize Guzzle client
$client = new Client(['http_errors' => false]);

public function validateCreate(array $data): bool
{
throw new NotImplementedException('Not implemented');
// Define the headers
$headers = [
'Authorization' => 'Token '.$this->credentials['token'],
];

// Make the GET request
$response = $client->request('POST', static::apiDomain().'delivery/starter/starter_bordureau/', [
'headers' => $headers,
'body' => [
'all_created' => true,
'orders_ids' => [$orderId],
],
]);

if (in_array($response->getStatusCode(), [200, 201])) {

$label = $response->getBody()->getContents();

if ($label === '' || $label === '0') {
throw new HttpException('Failed to retrieve label for order with tracking ID '.$orderId.' - Empty response from Maystro Delivery API.');
}

$base64data = base64_encode($label);

if ($base64data === '') {
throw new \RuntimeException('Unexpected empty base64 string');
}

return [
'type' => 'pdf',
'data' => $base64data,
];
}

throw new HttpException(static::metadata()['name'].', Unexpected error occurred.');
} catch (GuzzleException $guzzleException) {
// Handle exceptions
throw new HttpException($guzzleException->getMessage());
}
}
}

0 comments on commit b5476a7

Please sign in to comment.