Skip to content

Commit

Permalink
Merge pull request #2 from answear/parcel-shop-list
Browse files Browse the repository at this point in the history
Get parcel shop list
  • Loading branch information
jrawska authored Jun 1, 2022
2 parents 670946e + e9ac7e6 commit 53ebd60
Show file tree
Hide file tree
Showing 30 changed files with 1,606 additions and 22 deletions.
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,52 @@
# ACS stations bundle

ACS pickup point integration for Symfony.

## Installation

* install with Composer

```
composer require [email protected]:answear/acs-bundle.git
```

`Answear\AcsBundle\AnswearAcsBundle::class => ['all' => true],`
should be added automatically to your `config/bundles.php` file by Symfony Flex.

## Setup

* provide required config data: `apiKey`, `companyId`, `companyId`, `userId`, `userPassword`

```yaml
# config/packages/answear_acs.yaml
answear_gls:
apiKey:
companyId:
companyPassword:
userId:
userPassword:
language: //default GR
```
## Usage
### Get ParcelShops
```php
/** @var \Answear\AcsBundle\Service\ParcelShopsService $parcelShopService **/
$parcelShopService->getList(CountryIdEnum $countryId, ?int $kind = null);
```

will return `\Answear\AcsBundle\Response\DTO\ParcelShop[]` array.

Where `countryId` is Greece or Cyprus, and `kind` is shop kind according to ACS documentation, `null` means all kinds

### Error handling

- `Answear\AcsBundle\Exception\ServiceUnavailable` for all `GuzzleException`
- `Answear\AcsBundle\Exception\MalformedResponse` for incorrect responses

Final notes
------------

Feel free to open pull requests with new features, improvements or bug fixes. The Answear team will be grateful for any comments.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"symfony/http-kernel": "^4.4|^5.1.5",
"symfony/property-info": "^4.4|^5.0",
"symfony/serializer": "^4.4|^5.0",
"webmozart/assert": "^1.3"
"webmozart/assert": "^1.10"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.4",
Expand All @@ -26,7 +26,7 @@
},
"autoload": {
"psr-4": {
"Answear\\AcsBundle\\\\": "src/"
"Answear\\AcsBundle\\": "src/"
}
},
"autoload-dev": {
Expand Down
48 changes: 47 additions & 1 deletion src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,55 @@

namespace Answear\AcsBundle;

use Answear\AcsBundle\Request\BaseInputParameters;

class ConfigProvider
{
public function __construct()
private const API_URL = 'https://webservices.acscourier.net/ACSRestServices/api/ACSAutoRest';

private string $apiKey;
private string $companyId;
private string $companyPassword;
private string $userId;
private string $userPassword;
private string $language;

public function __construct(
string $apiKey,
string $companyId,
string $companyPassword,
string $userId,
string $userPassword,
string $language
) {
$this->apiKey = $apiKey;
$this->companyId = $companyId;
$this->companyPassword = $companyPassword;
$this->userId = $userId;
$this->userPassword = $userPassword;
$this->language = $language;
}

public function getRequestHeaders(): array
{
return [
'AcsApiKey' => $this->getApiKey(),
'Content-Type' => 'application/json',
];
}

public function getBaseInputParameters(): BaseInputParameters
{
return new BaseInputParameters($this->companyId, $this->companyPassword, $this->userId, $this->userPassword, $this->language);
}

public function getUrl(): string
{
return self::API_URL;
}

private function getApiKey(): string
{
return $this->apiKey;
}
}
3 changes: 3 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

class Configuration implements ConfigurationInterface
{
private const DEFAULT_LANGUAGE = 'GR';

public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('answear_acs');
Expand All @@ -20,6 +22,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->scalarNode('companyPassword')->cannotBeEmpty()->end()
->scalarNode('userId')->cannotBeEmpty()->end()
->scalarNode('userPassword')->cannotBeEmpty()->end()
->scalarNode('language')->defaultValue(self::DEFAULT_LANGUAGE)->end()
->end();

return $treeBuilder;
Expand Down
23 changes: 23 additions & 0 deletions src/Enum/CountryIdEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Answear\AcsBundle\Enum;

use MabeEnum\Enum;

class CountryIdEnum extends Enum
{
public const GREECE = 'GR';
public const CYPRUS = 'CY';

public static function greece(): self
{
return static::get(static::GREECE);
}

public static function cyprus(): self
{
return static::get(static::CYPRUS);
}
}
25 changes: 25 additions & 0 deletions src/Exception/MalformedResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Answear\AcsBundle\Exception;

class MalformedResponse extends \RuntimeException
{
/**
* @var mixed
*/
private $response;

public function __construct($message, $response, ?\Throwable $previous = null)
{
parent::__construct($message, 0, $previous);

$this->response = $response;
}

public function getResponse()
{
return $this->response;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

namespace Answear\AcsBundle\Exception;

class ServiceUnavailableException extends \RuntimeException
class ServiceUnavailable extends \RuntimeException
{
}
34 changes: 34 additions & 0 deletions src/Request/BaseInputParameters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Answear\AcsBundle\Request;

class BaseInputParameters
{
protected string $companyId;
protected string $companyPassword;
protected string $userId;
protected string $userPassword;
protected string $language;

public function __construct(string $companyId, string $companyPassword, string $userId, string $userPassword, string $language)
{
$this->companyId = $companyId;
$this->companyPassword = $companyPassword;
$this->userId = $userId;
$this->userPassword = $userPassword;
$this->language = $language;
}

public function toArray(): array
{
return [
'Company_ID' => $this->companyId,
'Company_Password' => $this->companyPassword,
'User_ID' => $this->userId,
'User_Password' => $this->userPassword,
'language' => $this->language,
];
}
}
13 changes: 13 additions & 0 deletions src/Request/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Answear\AcsBundle\Request;

interface Request
{
/**
* Converts request object to json that will be sent via the API.
*/
public function toJson(): string;
}
39 changes: 39 additions & 0 deletions src/Request/StationsRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Answear\AcsBundle\Request;

use Answear\AcsBundle\Enum\CountryIdEnum;

class StationsRequest implements Request
{
private const ALIAS = 'ACS_Stations';

private BaseInputParameters $baseInputParameters;
private CountryIdEnum $countryId;
private ?int $kind;

public function __construct(BaseInputParameters $baseInputParameters, CountryIdEnum $countryId, ?int $kind = null)
{
$this->baseInputParameters = $baseInputParameters;
$this->countryId = $countryId;
$this->kind = $kind;
}

public function toJson(): string
{
$parameters = [
'ACS_SHOP_COUNTRY_ID' => $this->countryId->getValue(),
];

if (null !== $this->kind) {
$parameters['ACS_SHOP_KIND'] = $this->kind;
}

return json_encode([
'ACSAlias' => self::ALIAS,
'ACSInputParameters' => array_merge($parameters, $this->baseInputParameters->toArray()),
], JSON_THROW_ON_ERROR);
}
}
9 changes: 9 additions & 0 deletions src/Resources/config/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false

Answear\AcsBundle\ConfigProvider: ~
Answear\AcsBundle\Service\Client: ~
Answear\AcsBundle\Service\ParcelShopsService: ~
82 changes: 82 additions & 0 deletions src/Response/DTO/Address.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);

namespace Answear\AcsBundle\Response\DTO;

use Webmozart\Assert\Assert;

class Address
{
private string $street;
private string $zipCode;
private string $city;
private string $phones;
private string $email;
private string $fax;

public function __construct(
string $street,
string $zipCode,
string $city,
string $phones,
string $email,
string $fax
) {
$this->street = $street;
$this->zipCode = $zipCode;
$this->city = $city;
$this->phones = $phones;
$this->email = $email;
$this->fax = $fax;
}

public static function fromArray(array $parcelShopArray): self
{
Assert::keyExists($parcelShopArray, 'ACS_SHOP_ADDRESS');
Assert::keyExists($parcelShopArray, 'ACS_SHOP_ZIPCODE');
Assert::keyExists($parcelShopArray, 'ACS_SHOP_CITY');
Assert::keyExists($parcelShopArray, 'ACS_SHOP_PHONES');
Assert::keyExists($parcelShopArray, 'ACS_SHOP_EMAIL');
Assert::keyExists($parcelShopArray, 'ACS_SHOP_FAX');

return new self(
$parcelShopArray['ACS_SHOP_ADDRESS'],
$parcelShopArray['ACS_SHOP_ZIPCODE'],
$parcelShopArray['ACS_SHOP_CITY'],
$parcelShopArray['ACS_SHOP_PHONES'],
$parcelShopArray['ACS_SHOP_EMAIL'],
$parcelShopArray['ACS_SHOP_FAX']
);
}

public function getZipCode(): string
{
return $this->zipCode;
}

public function getCity(): string
{
return $this->city;
}

public function getStreet(): string
{
return $this->street;
}

public function getFax(): ?string
{
return $this->fax;
}

public function getPhones(): ?string
{
return $this->phones;
}

public function getEmail(): ?string
{
return $this->email;
}
}
Loading

0 comments on commit 53ebd60

Please sign in to comment.