maguto/dilovod-sdk

PHP SDK for Dilovod API — Ukrainian online accounting and reporting service

Maintainers

Package info

github.com/magutodev/dilovod-php-sdk

pkg:composer/maguto/dilovod-sdk

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

2.0.0 2026-04-03 13:28 UTC

This package is auto-updated.

Last update: 2026-04-03 13:34:07 UTC


README

CI Latest Stable Version PHP Version License

PHP SDK для роботи з Dilovod API — українським онлайн-сервісом бухгалтерського, управлінського обліку та звітності.

Версія 2.x — потребує PHP 8.2+. Для PHP 7.4+ дивіться гілку 1.x.

Встановлення

composer require maguto/dilovod-sdk

SDK потребує реалізації PSR-18 (HTTP client) та PSR-17 (HTTP factories). Рекомендовані пакети:

# Guzzle (найпопулярніший)
composer require guzzlehttp/guzzle nyholm/psr7

# або тільки Nyholm + Symfony HTTP Client
composer require nyholm/psr7 symfony/http-client

Швидкий старт

use Maguto\Dilovod\Config;
use Maguto\Dilovod\DilovodClient;
use Maguto\Dilovod\Enum\Operator;
use Maguto\Dilovod\Transport\PsrTransport;
use GuzzleHttp\Client as GuzzleClient;
use Nyholm\Psr7\Factory\Psr17Factory;

// Конфігурація
$config = new Config(
    apiKey: 'ваш_api_ключ',
    // apiUrl: 'https://vps.example.com',  // для VPS-серверів
    // clientId: 'my-app',                 // для партнерської статистики
);

// Ініціалізація
$psr17 = new Psr17Factory();
$transport = new PsrTransport(
    config: $config,
    httpClient: new GuzzleClient(['timeout' => 30]),
    requestFactory: $psr17,
    streamFactory: $psr17,
    // logger: $psrLogger,  // опціонально, PSR-3
);

$client = new DilovodClient($config, $transport);

Основні методи

Отримання об'єкта за ID

$product = $client->getObject('1100300000022632');

$header = $product->get('header');
echo $header['name']['uk'];

Збереження об'єкта

// Створення
$id = $client->saveObject(
    header: [
        'id' => 'catalogs.goods',
        'name' => ['uk' => 'Новий товар', 'ru' => 'Новый товар'],
    ],
);

// Оновлення
$client->saveObject(
    header: ['id' => $id, 'name' => ['uk' => 'Оновлена назва']],
);

// Створення та проведення документа
use Maguto\Dilovod\Enum\SaveType;

$client->saveObject(
    header: [
        'id' => 'documents.saleOrder',
        'firm' => '1100400000001001',
        'person' => '1100100000001001',
        'currency' => '1101200000001001',
        'date' => '2026-04-03 14:00:00',
    ],
    saveType: SaveType::Register,
);

Позначка на видалення

$client->setDelMark('1100300000022632');

Query Builder

Fluent API для вибірки даних. Підтримує 5 типів запитів.

Важливо: alias, що використовується у where(), повинен бути оголошений у fields().

Прямий запит до довідника

$products = $client->query('catalogs.goods')
    ->fields(['id' => 'good', 'code' => 'code', 'name' => 'name', 'parent.code' => 'parentCode'])
    ->where('parentCode', Operator::Equal, 101010)
    ->limit(50)
    ->get();

foreach ($products as $product) {
    echo $product['name'] . PHP_EOL;
}

// Отримати перший запис
$first = $client->query('catalogs.firms')
    ->fields(['id' => 'id', 'name' => 'name'])
    ->first();

// Отримати значення одного поля з усіх записів
$codes = $client->query('catalogs.goods')
    ->fields(['id' => 'id', 'code' => 'code'])
    ->withoutLinks()
    ->get()
    ->pluck('code');

Товарні залишки на дату

$stock = $client->query()
    ->balance('goods', '2025-01-01 00:00:00', ['good', 'storage'])
    ->fields([
        'good' => 'good',
        'good.code' => 'code',
        'storage' => 'storage',
        'qty' => 'qty',
    ])
    ->where('good', Operator::Equal, '1100300000022619')
    ->get();

Обороти за період

$sales = $client->query()
    ->turnover('saleIncomes', '2025-01-01', '2025-06-30', ['good', 'firm'])
    ->fields([
        'good' => 'good',
        'good.code' => 'code',
        'amountReciept' => 'income',
    ])
    ->get();

Залишки + обороти

$report = $client->query()
    ->balanceAndTurnover('goods', '2025-01-01', '2025-06-30')
    ->fields([
        'good' => 'good',
        'qtyStart' => 'start',
        'qtyReceipt' => 'receipt',
        'qtyExpense' => 'expense',
        'qtyFinal' => 'final',
    ])
    ->get();

Зріз актуальних значень (ціни)

$prices = $client->query()
    ->sliceLast('goodsPrices', new \DateTimeImmutable())
    ->fields([
        'good' => 'good',
        'priceType' => 'priceType',
        'price' => 'price',
        'currency' => 'currency',
    ])
    ->where('priceType', Operator::Equal, '1101300000001002')
    ->get();

Мультимовні поля

При multilang() API змінює формат імен полів: namename__uk, name__ru.

$result = $client->query('catalogs.firms')
    ->fields(['id' => 'id', 'name' => 'name'])
    ->multilang()
    ->get();

// $result->first() = ['id' => '...', 'name__uk' => '...', 'name__ru' => '...']

Швидкий режим (без збірки посилань)

$result = $client->query('catalogs.goods')
    ->fields(['id' => 'id', 'code' => 'code', 'name' => 'name'])
    ->withoutLinks()
    ->get();

// ResultSet містить columns
$result->getColumns(); // ['id', 'code', 'name']

Створення замовлення покупця

$orderId = $client->createOrder()
    ->firm('1100400000001001')
    ->person('1100100000001001')
    ->remarkFromPerson('Зателефонуйте, будь ласка')
    ->addProduct('1100300000022632', qty: 1)
    ->addProduct('1100300000022876', qty: 2, price: 150.00)
    ->addProductByArticle('ART-001', qty: 3)
    ->withAutoPlacement()
    ->send();

Довільні спецметоди (call)

$response = $client->call('saleOrderCreate', [
    'header' => ['firm' => '1100400000001001', 'person' => '1100100000001001'],
    'goods' => [['good' => '1100300000022632', 'qty' => 1]],
]);

Метадані

// Список усіх об'єктів системи
$objects = $client->listMetadata('uk');

// Опис реквізитів об'єкта
$meta = $client->getMetadata(objectName: 'catalogs.goods');
// або за ID
$meta = $client->getMetadata(objectId: '1000000000001258');

Партнерська статистика

Увага: метод getStatistic реалізовано за документацією, але не верифіковано реальним API (потребує налаштованої партнерської інтеграції).

$stats = $client->getStatistic(
    partnerApiKey: 'ваш_партнерський_ключ',
    dateFrom: new \DateTimeImmutable('2025-01-01'),
    dateTo: new \DateTimeImmutable('2025-12-31'),
);

Webhook

use Maguto\Dilovod\Webhook\WebhookParser;

// У вашому контролері
$packetJson = $_GET['packet'] ?? '';

if (!WebhookParser::isValidSource($_SERVER['REMOTE_ADDR'])) {
    http_response_code(403);
    exit;
}

$event = WebhookParser::parse($packetJson);

echo $event->action;     // 'objectChanged'
echo $event->objectName; // 'documents.saleOrder'
echo $event->id;         // '1109100000001038'

Value Objects

use Maguto\Dilovod\ValueObject\ObjectId;
use Maguto\Dilovod\ValueObject\MultiLangString;

// ObjectId — 16-значний ID з типом та номером
$id = new ObjectId('1100300000022632');
$id->getPrefix(); // '11003' (тип — товари)
$id->getNumber(); // '00000022632'
$id->isSameType(new ObjectId('1100300000022876')); // true

// MultiLangString — мультимовний рядок
$name = MultiLangString::fromArray(['uk' => 'Товар', 'ru' => 'Товар']);
echo $name->get('uk');   // 'Товар'
echo $name;              // 'Товар' (uk за замовчуванням)

Обробка помилок

use Maguto\Dilovod\Exception\ApiException;
use Maguto\Dilovod\Exception\TransportException;
use Maguto\Dilovod\Exception\DilovodException;

try {
    $client->getObject('0000000000000000');
} catch (ApiException $e) {
    // Помилка від Dilovod API
    echo $e->getMessage();        // 'object with id ... not found'
    $e->getRawResponse();         // повний масив відповіді
} catch (TransportException $e) {
    // Мережева помилка або HTTP 5xx
    echo $e->getHttpStatusCode(); // 502, null для мережевих
} catch (DilovodException $e) {
    // Будь-яка помилка SDK
}

Розробка

# Встановити залежності
composer install

# Запустити всі перевірки (стиль + аналіз + тести)
composer check

# Unit-тести
composer test:unit

# Інтеграційні тести (потребують API-ключ)
cp .env.example .env    # вкажіть DILOVOD_API_KEY
composer test:integration

# Виправити стиль коду
composer cs:fix

# Статичний аналіз (PHPStan level max)
composer analyse

Вимоги

  • PHP 8.2+
  • Будь-яка реалізація PSR-18 HTTP client
  • Будь-яка реалізація PSR-17 HTTP factories

Посилання

Ліцензія

MIT — дивіться LICENSE.