# Client SDK DPD
Client SDK - SDK для быстрой разработки клиентских решений для сервиса доставки DPD.

### Требования

* PHP 5.4.* или выше
* SOAP
* PDO
* PDO-SQLite

### Установка
Для установки скачайте [tar.gz](https://github.com) или [zip](https://github.com/), распакуйте его и подключите файл `autoload.php` в Вашем проекте. 

```php

require_once 'path/to/database-master/src/autoload.php';

```

После этого необходимо произвести импорт начальных данных. Примеры загрузчиков находятся в папке `examples/` внутри архива.

### Настройки
Следующие параметры используются в модуле

* ```UPLOAD_DIR``` - задается путь к директории для хранения запрошенных файлов
* ```DB``` - параметры подключения к БД. Модуль использует БД для хранения списка городов обслуживания и списка ПВЗ. По умолчанию модуль использует SQLite БД.
* ```DB.DSN``` - dsn строка подключения к БД
* ```DB.USERNAME``` - имя пользователя для подключения к БД
* ```DB.PASSWORD``` - пароль пользователя для подключения к БД
* ```DB.DRIVER``` - используемый драйвер при подключении к БД. По умолчанию будет вычеслен автоматически из строки DSN
* ```DB.PDO``` - вместо всех параметров, можно сразу передать готово подключение в виде объекта \PDO
* ```KLIENT_NUMBER``` - клиентский номер в системе DPD
* ```KLIENT_KEY``` - секретный ключ для авторизации в системе DPD
* ```KLIENT_CURRENCY``` - валюта аккаунта
* ```KLIENT_NUMBER_KZ```,```KLIENT_KEY_KZ```,```KLIENT_CURRENCY_KZ``` - параметры для подключения казахского аккаунта
* ```KLIENT_NUMBER_BY```,```KLIENT_KEY_BY```,```KLIENT_CURRENCY_BY``` - параметры для подключения белорусского аккаунта
* ```API_DEF_COUNTRY``` - возможные значения RU,KZ,BY. Код аккаунта по умолчанию
* ```IS_TEST``` - вкл./выкл. тестовый режим
* ```WEIGHT``` - вес товара по умолчанию
* ```LENGTH``` - длина товара по умолчанию
* ```WIDTH```  - ширина товара по умолчанию
* ```HEIGHT``` - высота товара по умолчанию
* ```TARIFF_OFF``` - список тарифов которые НЕ будут использованы в расчетах. возможные значения PCL,CSM,ECN,ECU
* ```DEFAULT_TARIFF_CODE``` - тариф по умолчанию, данный тариф будет выбран если стоимость доставки меньше чем указанов `DEFAULT_TARIFF_THRESHOLD`.
* ```DEFAULT_TARIFF_THRESHOLD``` - макс сумма доставки при которой будет использован тариф по умолчанию
* ```DECLARED_VALUE``` - Включать страховку в стоимость доставки
* ```COMMISSION_NPP_CHECK``` - Включать комиссию за инкассацию наложенным платежом в стоимость доставки, массив вида ```[PERSONE_TYPE_ID => bool, ...]```
* ```COMMISSION_NPP_PERCENT``` - Комиссия от стоимости товаров в заказе (в процентах), %. массив вида ```[PERSONE_TYPE_ID => double, ...]```
* ```COMMISSION_NPP_MINSUM``` - Минимальная сумма комиссии, руб. массив вида ```[PERSONE_TYPE_ID => double, ...]```
* ```COMMISSION_NPP_PAYMENT``` - ID платежных системы, которые означают что оплата будет происходить наложенным платежом . массив вида ```[PERSONE_TYPE_ID => [PAYMENT_SYSTEM_ID, ...], ...]```
* ```COMMISSION_NPP_DEFAULT``` - Если платежную систему определить не удалось, считать ли что оплата будет происходить наложенным платежом по умолчанию?. массив вида ```[PERSONE_TYPE_ID => bool, ...]```

Для хранения настроек в модуле реализован класс `\Ipol\DPD\Config\Config`, в конструктор класса можно передать массив 
опций, тем самым переопределив значения по умолчанию. Так же может быть реализован свой класс для хранения настроек, в этом случае он 
должен реализовывать интерфейс `Ipol\DPD\Config\ConfigInterface`.

### Расчет стоимости доставки
Для расчета стоимости доставки вначале необходимо создать объект описывающий отправку.
Для этого в модуле используется класс `Ipol\DPD\Shipment`

```php
$config = new \Ipol\DPD\Config\Config([
    // ... параметры авторизации
]);

$shipment = new \Ipol\DPD\Shipment($config);

// Указываем города отправления и назначения
$shipment->setSender('Россия', 'Москва', 'г. Москва');
$shipment->setReceiver('Россия', 'Тульская область', 'г. Тула');

// указываем отправку терминал - дверь
$shipment->setSelfPickup(true);
$shipment->setSelfDelivery(false);

// список товаров входящих в отправку
$goods = [
    1 => [
        'NAME'     => 'Название товара',
        'QUANTITY' => 1, // кол-во
        'PRICE'    => 1000, // стоимость за еденицу
        'VAT_RATE' => 18, // ставка налога, процент или строка Без НДС
        'WEIGHT'   => 1000, // вес, граммы,
        'DIMENSIONS' => [
            'LENGTH' => 100, // длина, мм,
            'WIDTH'  => 200, // ширина, мм,
            'HEIGHT' => 200, // высота, мм,
        ]
    ],
    
    // ...
];

// объявленная ценность
$goodsPrice = 1000;

// устанавливаем товары входящие в отправку
$shipment->setItems($goods, $goodsPrice);

// так же можно указать тип покупателя и платежную систему
// в зависимости от указанных параметров можно реализовать наценку на доставку при использовании наложенного платежа
$personeTypeId = 1; // значения переменный должны быть использованы в настроках секция COMMISSION_NPP_*
$paySystemId   = 1;
$shipment->setPaymentMethod($personeTypeId, $paySystemId);
```

За сам расчет стоимости доставки в модуле отвечает класс ```\Ipol\DPD\Calculator``` на вход он получает отправку для
которой необходимо произвести расчет стоимости. 

```php
// так можно получить калькулятор
$calc = $shipment->calculator();

// вернет информацию об актуальном тарифе для отправки
$tariff = $calc->calculate();

// а так можно расчитать стоимость доставки конкретного тарифа
$tariff = $calc->calculateWithTariff('PCL');
```

В методах ```calculate``` и ```calculateWithTariff``` калькулятора есть необязательный параметр ```$currency```, 
в котором можно передать код валюты, в этом случае стоимость достаки будет сконвертирована в указанную валюту.
Для поддержки конвертации Вам необходимо создать класс конвертер реализующий интерфейс ```\Ipol\DPD\Currency\ConverterInterface```,
а экземпляр этого класса необходимо передать калькулятору

```php
class Converter implements \Ipol\DPD\Currency\ConverterInterface
{
    // реализация
}

$converter = new Converter();
$tariff = $calc
            ->setCurrencyConverter($converter)
            ->calculate('USD');
```

### Отправка заказа
Для создания заказа в системе DPD сначала необходимо создать объект хранящий информацию об этом заказе.
В модуле за это отвечает класс ```\Ipol\DPD\DB\Order\Model```, данный заказ будет сохранен в БД.

```php
$config = new \Ipol\DPD\Config\COnfig([
    // ...
]);

$shipment = new Shipment($config);
// указываем параметры отправления

$order = \Ipol\DPD\DB\Connection::getInstance($config)->getTable('order')->makeModel();
$order->orderId = 'Внешний код заказа';

// данная модель может заполнить часть параметров из переданной отправки
// в противном случае можно все эти параметры заполнить вручную указав значения соответствующих полей
$order->setShipment($order);

// указываем тариф отправки
$order->serviceCode = 'PCL';
// если не использовать объект отправки, так же необходимо указать вариант доставки
// в нашем случае это терминал - дверь
// $order->serviceVariant = [SELF_PICKUP => true, SELF_DELIVERY => false]

// Дата и время забора
$order->pickupDate = '2017-11-29';
$order->pickupTimePeriod = '9-18';

// данные отправителя
$order->senderName = 'Наименование отправителя';
$order->senderFio = 'ФИО отправителя';
$order->senderPhone = 'Телефон отправителя';
$order->senderTerminalCode = 'Код терминала отправления';

// данные получателя
$order->receiverName = 'Наименование получателя';
$order->receiverFio = 'ФИО получателя';
$order->receiverPhone = 'Телефон получателя';
$order->receiverStreet = 'Улица';
$order->receiverStreetabbr = 'ул.';
$order->receiverHouse = 'дом';
$order->receiverComment = 'инструкция для курьера';
```

После того как все параметры заказа заполнены, нужно вызвать метод `dpd`.
Данные метод возвращает объект класса `Ipol\DPD\Order` позволяющий производить операции с заказом на стороне dpd,
в частности создание, отмену, запрос файла наклеек или накладной, проверка статуса и др.

```php
// создаем заказ в системе dpd
$result = $order->dpd()->create();

// $order->dpd()->cancel(); // отменяем
// $order->dpd()->checkStatus(); // проверка статуса заказа
// $order->dpd()->getLabelFile(); // получить файл с наклейкой
// $order->dpd()->getInvoiceFile(); // получить файл с накладной

// получить созданный ранее заказ и отменить его
$orderId = 1; // внешний ID заказа
$order = \Ipol\DPD\DB\Connection::getInstance($config)->getTable('order')->getByOrderId($orderId);
$order->dpd()->cancel();

### Работа с местоположениями и терминалами
При установке модуля и загрзуки первоначальных данных список городов и терминалов сохраняются во внутреннюю БД.
В дальнейшем возможно использовать эти данные в своих целях. Для этого в модуле реализован простейший DataMapper к бд.

Получить доступ к таблице можно следующим образом

```php

$locations = \Ipol\DB\Connection::getInstance($config)->getTable('location');
$terminals = \Ipol\DB\Connection::getInstance($config)->getTable('terminal');
$order     = \Ipol\DB\Connection::getInstance($config)->getTable('order');

```

Во всех случаях будет возвращен объект класс которого реализует интерфейс `\Ipol\DPD\DB\TableInterface` помимо этого,
в классе могут быть реализованы свои вспомогательные методы. Например у класса местоположений есть 
метод `getByAddress($country, $region, $city, $select = '*')` который ищет местоположение в БД по текстовому 
представлению.

### Примеры
В каталоге `examples/` приведены примеры использования модуля

### Заключение
Исходные коды модуля содержат развернутые комментарии описывающие работу методов, их параметров и возвращаемого результата.
