Skip to content

Commit

Permalink
Merge pull request #5 from t3ko/tracking-service
Browse files Browse the repository at this point in the history
Implement tracking service
  • Loading branch information
t3ko authored Sep 5, 2020
2 parents 1c6f7b6 + 345f28b commit b961f5c
Show file tree
Hide file tree
Showing 31 changed files with 1,913 additions and 6 deletions.
84 changes: 78 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
Klient API w języku PHP do komunikacji z następującymi web-serwisami firmy kurierskiej DPD:
- `PackageService` (rejestrowanie przesyłek, drukowanie etykiet i protokołów przekazania przesyłek kurierowi, zamawianie kuriera po odbiór przesyłki)
- `AppService` (obsługa zleceń odbioru przesyłek od osób trzecich)

TODO:
- `InfoService` (tracking przesyłek)

## Instalacja
Expand Down Expand Up @@ -69,7 +67,7 @@ Poza powyższymi podstawowymi metodami obsługi paczek, poniższa biblioteka umo

* Zlecanie odbioru od osoby trzeciej
* Pobieranie listy puntów doręczenia (TODO)
* Śledzenie przesyłek (TODO)
* Śledzenie przesyłek

### 0. Połączenie z API
Aby rozpocząć korzystanie z API wymagane są dane autentykacyjne składające się z trzech parametrów:
Expand Down Expand Up @@ -290,7 +288,7 @@ DOC TODO
### 5. Zamówienie kuriera po odbiór przesyłek
DOC TODO

### 6. Zlecanie odbioru od osoby trzeciej
### Zlecanie odbioru od osoby trzeciej
Korzystając z API `AppService` można wystawić żądanie odebrania przesyłki od osoby trzeciej.
W tym celu należy utworzyć obiekt (lub obiekty) typu `Package` opisujące konfigurację przesyłki jak przy zwykłym nadawaniu,
pamiętając, że w polu `$sender` powinny znajdować się dane podmiotu faktycznie wydającego paczkę kurierowi, a nie zlecającego odbiór!
Expand Down Expand Up @@ -352,8 +350,82 @@ $parcel->getParcelId(); //identyfikator paczki nadany przez DPD
$parcel->getWaybill(); //numer listu przewozowego dla tej paczki
```

Składanie zlecenia odbioru przesyłki od osoby trzeciej w tym miejscu się kończy. Nie ma potrzeby drukowania etykiet i przekazywania
ich nadającemu lub zamawiania kuriera - to zadzieje się automatycznie po stronie DPD.
Składanie zlecenia odbioru przesyłki od osoby trzeciej w tym miejscu się kończy. Nie ma potrzeby drukowania etykiet i przekazywania ich nadającemu lub zamawiania kuriera - to zadzieje się automatycznie po stronie DPD.

### Śledzenie przesyłek

Aby uzyskać informacje na temat konkretnej przesyłki możemy wykorzystać API `InfoService` poprzez metodę `getParcelTracking`:

```php
use \T3ko\Dpd\Request\GetParcelTrackingRequest;

/** @var GetParcelTrackingRequest $request */
$response = $api->getParcelTracking($request);
```

### GetParcelTrackingRequest
Obiekt żądania przekazywany do tej metody tworzymy przekazując numer listu przewozowego:
```php
use \T3ko\Dpd\Request\GetParcelTrackingRequest;

$request = GetParcelTrackingRequest::fromWaybill(...);
```
Opcjonalnie możemy wskazać czy chodzi nam o podgląd pełnej historii paczki czy tylko ostatnie zarejestrowane zdarzenie jej dotyczące:
```php
use \T3ko\Dpd\Request\GetParcelTrackingRequest;
use T3ko\Dpd\Objects\Enum\TrackingEventsCount;

$request = GetParcelTrackingRequest::fromWaybill('01234567890U', TrackingEventsCount::ALL());
$request = GetParcelTrackingRequest::fromWaybill('01234567890U', TrackingEventsCount::ONLY_LAST());
```
przy czym domyślną wartością jest `TrackingEventsCount::ALL()` czyli pobieranie wszystkich zdarzeń w historii paczki.

### GetParcelTrackingResponse
W odpowiedzi uzyskujemy obiekt typu `GetParcelTrackingResponse`
```php
use \T3ko\Dpd\Response\GetParcelTrackingResponse;

/** @var GetParcelTrackingResponse $response */
$response = $api->getParcelTracking($request);
```
dający poprzez metodę `getEvents()` do tablicy obiektów typu `ParcelEvent` wyrażających pojedyncze zdarzenie w historii przesyłki:
```php
/** @var GetParcelTrackingResponse $response */
$response = $api->getParcelTracking($request);
foreach ($response->getEvents() as $event) {
printf("%s - %s - %s - %s - %s (%s %s) (%s) %s",
$event->getEventTime()->format(DATE_ATOM), //data zdarzenia
$event->getWaybill(), //numer listu przewozowego
$event->getPackageReference(), //dowolne dane powiązane z przesyłką podane przez wysyłającego
$event->getParcelReference(), //j.w. związane z pojedynczą paczką
$event->getCountry(), //kod kraju operacji
$event->getDepot(), //numer oddziału DPD
$event->getDepotName(), //nazwa oddziału DPD
$event->getBusinessCode(), //kod zdarzenia
$event->getDescription() //opis słowny zdarzenia
);
$eventAdditionalData = [];
if (!empty($event->getAdditionalData())) { //dodatkowe dane zdarzenia
foreach ($event->getAdditionalData() as $additionalData) {
$eventAdditionalData[] = $additionalData->getValue();
}
}
if (!empty($eventAdditionalData)) {
printf(' [%s]', implode(', ', $eventAdditionalData));
}
echo "\n";
}
```
Przykładowy efekt powyższego wywołania możemy zobaczyć poniżej
```
2020-08-26T09:05:18+00:00 - 0123456789012A - - - PL (1349 Warszawa3) (190101) Przesyłka doręczona [Kowalski]
2020-08-26T07:02:15+00:00 - 0123456789012A - - - PL (1349 Warszawa3) (170304) Wysłano powiadomienie
2020-08-26T07:01:46+00:00 - 0123456789012A - - - PL (1305 Warszawa) (170309) Powiadomienie SMS [+48000000000, DELIVERED]
2020-08-26T06:38:21+00:00 - 0123456789012A - - - PL (1305 Warszawa) (170310) Powiadomienie mail [xxx@xxx.pl, SENT]
2020-08-26T06:19:49+00:00 - 0123456789012A - - - PL (1349 Warszawa3) (170102) Wydanie przesyłki do doręczenia [LOK9999WAC]
2020-08-26T00:44:23+00:00 - 0123456789012A - - - PL (1349 Warszawa3) (330137) Przyjęcie przesyłki w oddziale DPD [LOK0002WAC]
2020-08-25T16:16:14+00:00 - 0123456789012A - - - PL (1320 Piotrków Tryb.) (330135) Przyjęcie przesyłki w oddziale DPD [LOK0033PTR]
2020-08-25T14:46:29+00:00 - 0123456789012A - - - PL (1320 Piotrków Tryb.) (040101) Przesyłka odebrana przez Kuriera
2020-08-24T15:05:48+00:00 - 0123456789012A - - - ( ) (030103) Zarejestrowano dane przesyłki, przesyłka jeszcze nie nadana
```

60 changes: 60 additions & 0 deletions src/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
use T3ko\Dpd\Request\GeneratePackageNumbersRequest;
use T3ko\Dpd\Request\GenerateProtocolRequest;
use T3ko\Dpd\Request\GetCourierAvailabilityRequest;
use T3ko\Dpd\Request\GetParcelTrackingRequest;
use T3ko\Dpd\Response\CollectionOrderResponse;
use T3ko\Dpd\Response\FindPostalCodeResponse;
use T3ko\Dpd\Response\GenerateLabelsResponse;
use T3ko\Dpd\Response\GeneratePackageNumbersResponse;
use T3ko\Dpd\Response\GenerateProtocolResponse;
use T3ko\Dpd\Response\GetCourierAvailabilityResponse;
use T3ko\Dpd\Response\GetParcelTrackingResponse;
use T3ko\Dpd\Soap\Client\AppServicesClient;
use T3ko\Dpd\Soap\Client\InfoServicesClient;
use T3ko\Dpd\Soap\Client\PackageServicesClient;
use T3ko\Dpd\Soap\Types\AuthDataV1;

Expand All @@ -30,6 +33,8 @@ class Api
const PACKAGESERVICE_PRODUCTION_WSDL_URL = 'http://dpdservices.dpd.com.pl/DPDPackageObjServicesService/DPDPackageObjServices?wsdl';
const APPSERVICE_SANDBOX_WSDL_URL = 'http://dpdappservicesdemo.dpd.com.pl/DPDCRXmlServicesService/DPDCRXmlServices?wsdl';
const APPSERVICE_PRODUCTION_WSDL_URL = 'http://dpdappservices.dpd.com.pl/DPDCRXmlServicesService/DPDCRXmlServices?wsdl';
const INFOSERVICE_SANDBOX_WSDL_URL = null;
const INFOSERVICE_PRODUCTION_WSDL_URL = 'https://dpdinfoservices.dpd.com.pl/DPDInfoServicesObjEventsService/DPDInfoServicesObjEvents?wsdl';

/**
* @var string
Expand Down Expand Up @@ -61,6 +66,11 @@ class Api
*/
private $appServicesClient;

/**
* @var InfoServicesClient
*/
private $infoServicesClient;

/**
* @var LoggerInterface
*/
Expand Down Expand Up @@ -165,6 +175,9 @@ private function getWsdl($clientClass)
return self::PACKAGESERVICE_SANDBOX_WSDL_URL;
case AppServicesClient::class:
return self::APPSERVICE_SANDBOX_WSDL_URL;
case InfoServicesClient::class:
//InfoServices endpoint has no sandbox mode - using production instead
return self::INFOSERVICE_PRODUCTION_WSDL_URL;
}
}

Expand All @@ -173,6 +186,8 @@ private function getWsdl($clientClass)
return self::PACKAGESERVICE_PRODUCTION_WSDL_URL;
case AppServicesClient::class:
return self::APPSERVICE_PRODUCTION_WSDL_URL;
case InfoServicesClient::class:
return self::INFOSERVICE_PRODUCTION_WSDL_URL;
}
}

Expand Down Expand Up @@ -200,6 +215,18 @@ private function obtainAppServiceClient()
return $this->appServicesClient;
}

/**
* @return InfoServicesClient
*/
private function obtainInfoServiceClient()
{
if ($this->infoServicesClient === null) {
$this->infoServicesClient = $this->obtainClient(InfoServicesClient::class);
}

return $this->infoServicesClient;
}

/**
* @param $clientClass
*
Expand Down Expand Up @@ -371,6 +398,25 @@ private function getClassMaps()
new ClassMap('generateSpedLabelsV2Response', \T3ko\Dpd\Soap\Types\GenerateSpedLabelsV2Response::class),
new ClassMap('importPackagesXV1', \T3ko\Dpd\Soap\Types\ImportPackagesXV1Request::class),
new ClassMap('importPackagesXV1Response', \T3ko\Dpd\Soap\Types\ImportPackagesXV1Response::class),
new ClassMap('getEventsForCustomerV4', \T3ko\Dpd\Soap\Types\GetEventsForCustomerV4Request::class),
new ClassMap('getEventsForCustomerV4Response', \T3ko\Dpd\Soap\Types\GetEventsForCustomerV4Response::class),
new ClassMap('customerEventsResponseV2', \T3ko\Dpd\Soap\Types\CustomerEventsResponseV2::class),
new ClassMap('customerEventV2', \T3ko\Dpd\Soap\Types\CustomerEventV2::class),
new ClassMap('customerEventDataV2', \T3ko\Dpd\Soap\Types\CustomerEventDataV2::class),
new ClassMap('getEventsForCustomerV3', \T3ko\Dpd\Soap\Types\GetEventsForCustomerV3Request::class),
new ClassMap('getEventsForCustomerV3Response', \T3ko\Dpd\Soap\Types\GetEventsForCustomerV3Response::class),
new ClassMap('getEventsForCustomerV2', \T3ko\Dpd\Soap\Types\GetEventsForCustomerV2Request::class),
new ClassMap('getEventsForCustomerV2Response', \T3ko\Dpd\Soap\Types\GetEventsForCustomerV2Response::class),
new ClassMap('customerEventsResponseV1', \T3ko\Dpd\Soap\Types\CustomerEventsResponseV1::class),
new ClassMap('customerEventV1', \T3ko\Dpd\Soap\Types\CustomerEventV1::class),
new ClassMap('getEventsForCustomerV1', \T3ko\Dpd\Soap\Types\GetEventsForCustomerV1Request::class),
new ClassMap('getEventsForCustomerV1Response', \T3ko\Dpd\Soap\Types\GetEventsForCustomerV1Response::class),
new ClassMap('getEventsForWaybillV1', \T3ko\Dpd\Soap\Types\GetEventsForWaybillV1Request::class),
new ClassMap('getEventsForWaybillV1Response', \T3ko\Dpd\Soap\Types\GetEventsForWaybillV1Response::class),
new ClassMap('customerEventsResponseV3', \T3ko\Dpd\Soap\Types\CustomerEventsResponseV3::class),
new ClassMap('customerEventV3', \T3ko\Dpd\Soap\Types\CustomerEventV3::class),
new ClassMap('customerEventDataV3', \T3ko\Dpd\Soap\Types\CustomerEventDataV3::class),
new ClassMap('markEventsAsProcessedV1Response', \T3ko\Dpd\Soap\Types\MarkEventsAsProcessedV1Response::class),
]);
}

Expand Down Expand Up @@ -467,4 +513,18 @@ public function collectionOrder(CollectionOrderRequest $request): CollectionOrde

return CollectionOrderResponse::from($response);
}

/**
* @param GetParcelTrackingRequest $request
*
* @return GetParcelTrackingResponse
*/
public function getParcelTracking(GetParcelTrackingRequest $request): GetParcelTrackingResponse
{
$payload = $request->toPayload();
$payload->setAuthData($this->getAuthDataStruct());
$response = $this->obtainInfoServiceClient()->getEventsForWaybillV1($payload);

return GetParcelTrackingResponse::from($response);
}
}
42 changes: 42 additions & 0 deletions src/Objects/Enum/TrackingEventsCount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace T3ko\Dpd\Objects\Enum;

final class TrackingEventsCount
{
private static $all;
private static $onlyLast;

/**
* @var string
*/
private $value;

private function __construct($value)
{
$this->value = $value;
}

public static function ALL(): TrackingEventsCount
{
if (null === static::$all) {
static::$all = new static('ALL');
}

return static::$all;
}

public static function ONLY_LAST(): TrackingEventsCount
{
if (null === static::$onlyLast) {
static::$onlyLast = new static('ONLY_LAST');
}

return static::$onlyLast;
}

public function __toString()
{
return $this->value;
}
}
Loading

0 comments on commit b961f5c

Please sign in to comment.