poniedziałek, 11 maja 2015

Własny opis przesyłki – czyli jak dodać na etykiecie numer zamówienia


Przedstawię pokrótce sposób dodawania do nalepek adresowych własnego opisu, którym może być numer zamówienia lub każda inna dodatkowa informacja, niezbędna w procesie sprzedaży produktów.



Własny opis, który drukowany jest na etykietach dodaje się do pola „opis” klasy przesylkaType, która jest dziedziczona przez wszystkie przesyłki.



Poniżej przedstawiam przykładowy kod dla kilku wybranych typów przesyłek oraz wygenerowana na ich podstawie nalepka adresowa.

class client
{
 // -------------------------------------------------------------------------
 public function testPrzesylkaBiznesowaType()
 {
  $P = new przesylkaBiznesowaType();

  $this->setAddress($P);

  $P->iloscPotwierdzenOdbioru = 0;
  $P->masa = 1500;
  $P->opis = "My own description.";
  $P->kategoria = kategoriaType::EKONOMICZNA;
  $P->gabaryt = gabarytBiznesowaType::S;
  $P->wartosc = 1000;
  $P->ostroznie = true;

  $P->guid = getGuid();
  $this->przesylki[] = $P;
 }
 // -------------------------------------------------------------------------
 public function testPrzesylkaFirmowaPoleconaType()
 {
  $P = new przesylkaFirmowaPoleconaType();

  $this->setAddress($P);

  $P->kategoria = kategoriaType::EKONOMICZNA;
  $P->opis = "My own description.";
  $P->masa = "1203";
  $P->gabaryt = gabarytType::GABARYT_A;
  $P->miejscowa = false; // ustawiamy tylko jeśli podpisana umowa / set if you have additional agreement
  $P->obszarMiasto = false; // ustawiamy tylko jeśli podpisana umowa / set if you have additional agreement

  $P->guid = getGuid();
  $this->przesylki[] = $P;
 }
 protected $przesylki;
 // -----------------------------------------------------------------------------
 public function testPrzesylkaPoleconaKrajowaType()
 {
  $P = new przesylkaPoleconaKrajowaType();

  $this->setAddress($P);

  $P->kategoria = kategoriaType::EKONOMICZNA;
  $P->opis = "My own description.";
  $P->masa = "1203";
  $P->gabaryt = gabarytType::GABARYT_A;
  $P->miejscowa = false; // ustawiamy tylko jeśli podpisana umowa / set if you have additional agreement
  $P->obszarMiasto = false; // ustawiamy tylko jeśli podpisana umowa / set if you have additional agreement

  $P->guid = getGuid();
  $this->przesylki[] = $P;
 }
 // -----------------------------------------------------------------------------
 public function testUslugaKurierskaType()
 {
  $P = new uslugaKurierskaType();

  $this->setAddress($P);

  $P->termin = terminKurierskaType::EKSPRES24;
  $P->opis = "My own description.";
  $P->guid = getGuid();
  $this->przesylki[] = $P;
 }
 // -----------------------------------------------------------------------------
 public function testUslugaPaczkowaType()
 {
  $P = new uslugaPaczkowaType();

  $this->setAddress($P);

  $P->guid = getGuid();
  $this->przesylki[] = $P;
 }
 // -----------------------------------------------------------------------------
 public function setAddress($P)
 {
  $adres = new adresType();
  $adres->miejscowosc = "Szczecin";
  $adres->kodPocztowy = "55-555";
  $adres->kraj = "Polska";
  $adres->nazwa = "Jan Kowalski";
  $adres->ulica = "Szczecińska";
  $adres->numerDomu = "10";
  $adres->email = "jan.kowalski@mailowo.pl";
  $adres->mobile = "510000000";
  $P->adres = $adres;
 }
}


Przykładowa Nalepka Adresowa

wtorek, 11 listopada 2014

Bufory użytkownika

Dziś odniosę się do drugiej strategii, a mianowicie do używania buforów tworzonych przez użytkownika.

Jest bardziej optymalna, daje możliwość bezkonfiliktowego użytkowania jednocześnie kilku niezależnych buforów i powinna być stosowana jako jedyna sensowna, a jej stosowanie nie uniemożliwi nam w przyszłości rozbudwania funkcjonalności apolikacji.

Całą procedurę wysyłania przesyłek opisać można w 7 krokach.

1. ustalenie dostępnych numerów kart (getKarty)

2. ustawienie bieżącej karty (setAktywnaKarta)

3. utworzenie nowego bufora (createEnvelopeBufor)

4. utworzenie przesyłki

5. wysłanie przesyłki do elektronicznego nadawcy do zdefiniowanego bufora (addShipmnet)

6. pobranie dostępnych urzędów nadania dla bieżącej karty (getUrzedyNadania)

7. wysłanie informacji o utworzonych przesyłkach w wybranym buforze na określony urząd nadania (sendEnvelope)

W wywołaniu createEnvelopeBufor nie trzeba podawać urzędu nadania, tylko datę nadania i najlepiej opis, aby móc łatwo zidentyfikować zbiór na stronie Elektronicznego Nadawcy, w folderze Przygotowanych. Urząd nadania jest wymagany zawsze w metodzie sendEnvelope.
Metoda createEnvelopeBufor, jeśli nie zwróci nam błędów, wówczas zwróci nam pole bufor, którego pole idBufor będzie nam potrzebny do identyfikacji bufora, przy dodawaniu przesyłek oraz przy wysyłaniu przesyłek na urząd.


Plik do pobrania

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<?php
include "ElektronicznyNadawca.php";

class client
{
 protected $guid = null;
 public $urzedyNadania = null;
 protected $karty = null;
 protected $przesylki = array();
 protected $przesylkiDodane = array();
 protected $login = 'użytkownik w systemie Elektroniczny Nadawca';
 protected $location = 'https://en-testwebapi.poczta-polska.pl/websrv/labs.php';
 protected $password = 'hasło';
 protected $en = null;
 // -------------------------------------------------------------------------
 public function __construct()
 {
  $this->en = new ElektronicznyNadawca("labs.wsdl", array(
                'login' => $this->login,
                'password' => $this->password,
                'location' => $this->location ));
 }
 // -------------------------------------------------------------------------
 public function testGetKarty()
 {
  echo "========testGetKarty====================
";
  $parameters = new getKarty();
  $response = $this->en->getKarty($parameters);
  var_dump($response);
  $response->karta = $this->convertToArray($response->karta);
  $this->karty = $response->karta;
 }
 // -------------------------------------------------------------------------
 public function testSetAktywnaKarta()
 {
  echo "========setAktywnaKarta====================
";
  $parameters = new setAktywnaKarta();
  $parameters->idKarta = reset($this->karty)->idKarta;
  $response = $this->en->setAktywnaKarta($parameters);
  var_dump($parameters);
  $response = new setAktywnaKartaResponse();
  if(!is_null($response->error))
  {
   $this->printErrors($response->error);
   throw new Exception("Błąd ustawiania karty.");
  }
 }
 // -------------------------------------------------------------------------
 public function testCreateEnvelopeBufor()
 {
  echo "========testCreateEnvelopeBufor====================
";
  $parameters = new createEnvelopeBufor();
  $parameters->bufor = new buforType();
  $date = new DateTime(Date("Y-m-d"));
  $date->add(new DateInterval('P3D'));
  $parameters->bufor->dataNadania = $date->format('Y-m-d');
  $parameters->bufor->opis = "Moj nowy bufor z datą " . $parameters->bufor->dataNadania;
  $response = $this->en->createEnvelopeBufor($parameters);
  var_dump($response);
  $response = new createEnvelopeBuforResponse();
  $response->createdBufor = new buforType();
  if(!is_null($response->error))
  {
   $this->printErrors($response->error);
   throw new Exception("Błąd towrzenia bufora.");
  }
  return $response->createdBufor;
 }
 // -------------------------------------------------------------------------
 public function testPaczkaPocztowaType()
 {
  echo "========testPaczkaPocztowaType====================
";
  $paczka = new paczkaPocztowaType();
  $paczka->adres = new adresType();
  $paczka->adres->nazwa = "Jan Kowalski";
  $paczka->adres->ulica = "Kowalska";
  $paczka->adres->numerDomu = "666";
  $paczka->adres->numerLokalu = "666";
  $paczka->adres->kodPocztowy = "66-666";
  $paczka->adres->miejscowosc = "Warszawa";
  $paczka->kategoria = kategoriaType::PRIORYTETOWA;
  $paczka->gabaryt = gabarytType::GABARYT_B;
  $paczka->wartosc = 20000;
  
  $paczka->guid = $this->getGuid();
  var_dump($paczka);
  $this->przesylki[] = $paczka;
 }
 // -------------------------------------------------------------------------
 public function testAddShipment(buforType $bufor)
 {
  echo "========testAddShipment====================
";
  $parameters = new addShipment();
  $parameters->idBufor = $bufor->idBufor;
  $parameters->przesylki = $this->przesylki;
  $response = $this->en->addShipment($parameters);
  var_dump($response);
  $response->retval = $this->convertToArray($response->retval);
  foreach($response->retval as $przesylka)
  {
   if(is_null($przesylka->error))
    $this->przesylkiDodane[] = $przesylka;
   else
   {
    echo "Nie udało się dodać przesyłki " . $przesylka->guid . " z powodu błędów.
";
    $this->printErrors($przesylka->error);
   }
  }
 }
 // -------------------------------------------------------------------------
 public function testSendEnvelope(buforType $bufor)
 {
  echo "========testSendEnvelope====================
";
  $parameters = new sendEnvelope();
  $parameters->urzadNadania = reset($this->urzedyNadania)->urzadNadania;
  $parameters->idBufor = $bufor->idBufor;
  $response = $this->en->sendEnvelope($parameters);
  var_dump($response);
  if(!is_null($response->error))
  {
   $this->printErrors($response->error);
   throw new Exception("Błąd wysyłania zbioru");
  }
  else
  {
   echo "Status wysłanego kontenera przesyłek: " . $response->envelopeStatus . "
";
   echo "Identyfikator kontenera przesyłek: " . $response->idEnvelope . "
";
   return $response->idEnvelope;
  }
 }
 // -------------------------------------------------------------------------
 public function testGetUrzadNadania()
 {
  echo "========testGetUrzadNadania====================
";
  $response = $this->en->getUrzedyNadania(new getUrzedyNadania());
  var_dump($response->urzedyNadania);
  $response->urzedyNadania = $this->convertToArray($response->urzedyNadania);
  if(count($response->urzedyNadania) == 0)
   throw new Exception("Brak urzędów nadania.");
  $this->urzedyNadania = $response->urzedyNadania;
 }
 // -------------------------------------------------------------------------
 function getGuid()
 {
  mt_srand((double)microtime() * 10000);
  $charid = strtoupper(md5(uniqid(rand(), true)));
  $retval = substr($charid, 0, 32);
  return $retval;
 }
 // -------------------------------------------------------------------------
 function convertToArray($data)
 {
  if(!is_array($data))
   $data = array(
      $data );
  return $data;
 }
 // -------------------------------------------------------------------------
 function printErrors($errors)
 {
  $errors = $this->convertToArray($errors);
  foreach($errors as $error)
  {
   echo "[" . $error->errorNumber . "] " . $error->errorDesc . " " . $error->guid . "
";
  }
 }
}
$c = new client();
$c->testGetKarty();
$c->testSetAktywnaKarta();
$bufor = $c->testCreateEnvelopeBufor();
$c->testPaczkaPocztowaType();
$c->testAddShipment($bufor);
$c->testGetUrzadNadania();
$c->testSendEnvelope($bufor);

?>
 </body>
</html>

niedziela, 9 listopada 2014

Wysyłanie przesyłek do domyślnego bufora

Gdy mamy już gotowego prostego klienta, czas wrzucić jakąś przesyłkę.


Ale na początek może wytłumaczę czym jest karta, którą definiuje się jako dodatnią liczbę całkowitą. Najprościej wyobrazić sobie ją jako kontener, który umożliwia wkładanie do niego tylko przesyłek, które są do niego przypisane. Tak więc jeśli mamy umowę z Pocztą i dostajemy od nich jakieś numery kart, to każda z tych kart definiuje co w jej ramach można wysyłać.



Przed wysłaniem przesyłki potrzebny jest nam bufor, do którego będziemy mogli ją wrzucić. Oczywiście system pozwala nam się czymś takim nie przejmować, będziemy wówczas musieli korzystać z bufora domyślnego, dlatego przedstawię tu dwie strategie:

1. korzystanie z bufora domyślnego

2. korzystanie, z świadomie tworzonych przez użytkownika buforów



Dziś zajmę się punktem pierwszym: korzystanie z bufora domyślnego



Użytkowanie bufora domyślnego ma swoje ograniczenie, dzień w którym coś do niego wrzucamy musi być dniem jego wysłania a jednocześnie jest dniem nadania. Dodatkowo, najbezpieczniej przed wrzuceniem do niego nowych przesyłek wyczyścić go całkowicie (metoda clearEnvelope) tak aby mieć pewność, że nie ma tam przesyłek, których zapomnieliśmy wysłać dzień wcześniej.



Całą procedurę wysyłania przesyłek opisać można w 7 krokach.

1. ustalenie dostępnych numerów kart (getKarty)

2. ustawienie bieżącej karty (setAktywnaKarta)

3. wyczyszczenie istniejącego bufora (clearEnvelope)

4. utworzenie przesyłki

5. wysłanie przesyłki do elektronicznego nadawcy (addShipmnet)

6. pobranie dostępnych urzędów nadania dla bieżącej karty (getUrzedyNadania)

7. wysłanie informacji o utworzonych przesyłkach na wybrany urząd nadania (sendEnvelope)



Pominąłem na tą chwilę pobieranie nalepek adresowych aby nie zaciemniać kodu, nalepki adresowe można pobrać po utworzeniu przesyłek jaki i po ich wysłaniu na wybrany urząd nadania. Dodatkowo uprościłem sprawę wybierania karty oraz urzędu nadania, po przez użycie zawsze pierwszej z dostępnych.



Poniżej wrzucam, mam nadzieję czytelny kod, który wykona wszystkie czynności od 1 do 7. Najlepiej go odpalić i sprawdzić jak działa, oraz dla pewności co pozostaje po jego wykonaniu w folderze "Wysłane" na stronie Testowej Elektronicznego Nadawcy.


Plik do pobrania
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<?php
include "ElektronicznyNadawca.php";
class client
{
 protected $guid = null;
 public $urzedyNadania = null;
 protected $karty = null;
 protected $przesylki = array();
 protected $przesylkiDodane = array();
 protected $login = 'nazwa użytkownika w systemie elektroniczny nadawca';
 protected $location = 'https://en-testwebapi.poczta-polska.pl/websrv/labs.php';
 protected $password = 'hasło';
 protected $en = null;
 // -------------------------------------------------------------------------
 public function __construct()
 {
  $this->en = new ElektronicznyNadawca("labs.wsdl", array('login' => $this->login, 'password' => $this->password, 'location' => $this->location ));
 }
 // -------------------------------------------------------------------------
 public function testGetKarty()
 {
  echo "========<b>testGetKarty</b>====================<BR>";
  $parameters = new getKarty();
  $response = $this->en->getKarty($parameters);
  var_dump($response);
  $response->karta = $this->convertToArray($response->karta);
  $this->karty = $response->karta;
 }
// -------------------------------------------------------------------------
public function testSetAktywnaKarta()
{
 echo "========<b>setAktywnaKarta</b>====================<BR>";
 $parameters = new setAktywnaKarta();
 $parameters->idKarta = reset($this->karty)->idKarta;
 $response = $this->en->setAktywnaKarta($parameters);
 var_dump($parameters);
 $response = new setAktywnaKartaResponse();
 if(!is_null($response->error))
 {
  $this->printErrors($response->error);
  throw new Exception("Błąd ustawiania karty.");
 }
}
 // -------------------------------------------------------------------------
 public function testClearEnvelope()
 {
  echo "========<b>testClearEnvelope</b>====================<BR>";
  $response = $this->en->clearEnvelope(new clearEnvelope());
  var_dump($response);
 }
 // -------------------------------------------------------------------------
 public function testPaczkaPocztowaType()
 {
  echo "========<b>testPaczkaPocztowaType</b>====================<BR>";
  $paczka = new paczkaPocztowaType();
  $paczka->adres = new adresType();
  $paczka->adres->nazwa = "Jan Kowalski";
  $paczka->adres->ulica = "Kowalska";
  $paczka->adres->numerDomu = "666";
  $paczka->adres->numerLokalu = "666";
  $paczka->adres->kodPocztowy = "66-666";
  $paczka->adres->miejscowosc = "Warszawa";
  $paczka->kategoria = kategoriaType::PRIORYTETOWA;
  $paczka->gabaryt = gabarytType::GABARYT_B;
  $paczka->wartosc = 20000;
  
  $paczka->guid = $this->getGuid();
  var_dump($paczka);
  $this->przesylki[] = $paczka;
 }
 // -------------------------------------------------------------------------
 public function testAddShipment()
 {
  echo "========<b>testAddShipment</b>====================<BR>";
  $parameters = new addShipment();
  $parameters->przesylki = $this->przesylki;
  $response = $this->en->addShipment($parameters);
  var_dump($response);
  $response->retval = $this->convertToArray($response->retval);
  foreach($response->retval as $przesylka)
  {
   if(is_null($przesylka->error))
    $this->przesylkiDodane[] = $przesylka;
   else
   {
    echo "<B>Nie udało się dodać przesyłki </B>" . $przesylka->guid . " z powodu błędów.<BR>";
    $this->printErrors($przsylka->error);
   }
  }
 }
 // -------------------------------------------------------------------------
 public function testSendEnvelope()
 {
  echo "========<b>testSendEnvelope</b>====================<BR>";
  $parameters = new sendEnvelope();
  $parameters->urzadNadania = $this->urzedyNadania[0]->urzadNadania;
  $response = $this->en->sendEnvelope($parameters);
  var_dump($response);
  
  if(!is_null($response->error))
  {
   $this->printErrors($response->error);
  }
  echo "<B>Status wysłanego kontenera przesyłek: </B>" . $response->envelopeStatus . "<BR>";
  echo "<B>Identyfikator kontenera przesyłek: </B>" . $response->idEnvelope . "<BR>";
  return $response->idEnvelope;
 }
 // -------------------------------------------------------------------------
 public function testGetUrzadNadania()
 {
  echo "========<b>testGetUrzadNadania</b>====================<BR>";
  $response = $this->en->getUrzedyNadania(new getUrzedyNadania());
  var_dump($response->urzedyNadania);
  $response->urzedyNadania = $this->convertToArray($response->urzedyNadania);
  if(count($response->urzedyNadania) == 0)
   throw new Exception("Brak urzędów nadania.");
  $this->urzedyNadania = $response->urzedyNadania;
 }
 // -------------------------------------------------------------------------
 function getGuid()
 {
  mt_srand((double)microtime() * 10000);
  $charid = strtoupper(md5(uniqid(rand(), true)));
  $retval = substr($charid, 0, 32);
  return $retval;
 }
 // -------------------------------------------------------------------------
 function convertToArray($data)
 {
  if(!is_array($data))
   $data = array( $data );
  return $data;
 }
 // -------------------------------------------------------------------------
 function printErrors($errors)
 {
  $errors = $this->convertToArray($errors);
  foreach($errors as $error)
  {
   echo "[" . $error->errorNumber . "] " . $error->errorDesc . " " . $error->guid . "<BR>";
  }
 }
}
$c = new client();
$c->testGetKarty();
$c->testSetAktywnaKarta();
$c->testClearEnvelope();
$c->testPaczkaPocztowaType();
$c->testAddShipment();
$c->testGetUrzadNadania();
$c->testSendEnvelope();
?>
 </body>
</html>

piątek, 7 listopada 2014

Podstawy towrzenia klienta

Witam
Ostatnimi czasy zmuszony zostałem do integracji systemu z Elektronicznym Nadawcą. Podczas tej integracji pojawiało się bardzo dużo pytań, które do dziś się powtarzają, od współpracowników i osób zainteresowanych taką integracją. Bloga stworzyłem aby ułatwić sobie życie i nie musieć odpowiadać na te same pytania a jednocześnie będzie to miejsce dokumentujące funkcjonalność
tego systemu.


Pierwszego posta chciałbym poświęcić najbardziej podstawowej kwestii, jak stworzyć klienta w PHP, który byłby w stanie łączyć się z webserwisem Elektronicznego Nadawcy.

Najłatwiej będzie to opisać w kilku krokach:

1. Ściągamy konwerter WSDL2PHP ze strony
Po rozpakowaniu w katalogu bin widzimy plik wsdl2php.php to on nas najbardziej interesuje.

2. Ze strony Elektronicznego Nadawcy ściągamy plik WSDL, w zależności od potrzeb możemy ściągnąć go z jednego z poniższych adresów
lub
Na stronie en-testwebapi znaleźć można funkcjonalność, która w najbliższej przyszłości będzie dostępna na wersji produkcyjnej e-nadawca.poczta-polska.pl.
Zaś lasb.wsdl różni się od en.wsdl rozszeżonymi funkcjonalnościami.
Ściągnięty plik zapisujemy do katalogu, w którym znajduje się plik wsdl2php.php

3. Odpalamy z linii komend
php.exe wsdl2php.php labs.wsdl

4. W wyniku tej operacji otrzymamy ładną bibliotekę (ElektronicznyNadawca.php), którą nasz przyszły klient będzie mógł wykorzystać do komunikacji.

Niestety, aby życie nie było za proste, najpierw trzeba dokonać małej poprawki w nowo utworzonej bibliotece. A mianowicie, w dwóch klasach
oczekiwanaGodzinaDoreczeniaType
oraz
oczekiwanaGodzinaDoreczeniaUslugiType
musimy poprawić nazwy stałych, które są źle generowane przez użyty konwerter. To jedyny z dwóch zauważonych problemów z tym konwerterem, który całkiem dobrze się spisuje.
Zmieniamy wszystkie nazwy stałych postaci 

const DO_08:00
na
const DO_08_00.

Dla wytrwałych!
Drugi problem z konwerterem, który nie uniemożliwia z nim pracy ale czyni ją niezbyt wygodną przy developerce jest brak dziedziczenia. W klasach utworzonych w pliku ElektronicznyNadawca.php można ustawić takie dziedziczenie opierając się na pliku WSDL.


 
include "ElektronicznyNadawca.php";

class client
{
 protected $guid = null;
  protected $login = "login";
  protected $location = "https://en-testwebapi.poczta-polska.pl/websrv/labs.php";
  protected $password = "hasło";
 // -------------------------------------------------------------------------
 public function testGetKarty()
 {
  echo "========testGetKarty====================";
  $E = new ElektronicznyNadawca("labs.wsdl", array("login" => $this->login, "password" => $this->password, "location" => $this->location ));
  
  $tmp = new getKarty();
  
  $response = $E->getKarty($tmp);
  
  var_dump($response);
  if(!is_array($response->karta))
   $response->karta = array(
    $response->karta );
  return $response->karta;
 }
}
$c = new client();
$c->testGetKarty();