Розробка порталу для логістичної компанії

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Розробка порталу для логістичної компанії
Середня
~1-2 тижні
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Розробка портала для логістичної компанії

Логістичний портал — це не просто веб-сайт-візитка з формою заявки. Це робочий інструмент, через який менеджери клієнтів відстежують вантажі, диспетчери призначають машини, водії отримують маршрути, а бухгалтерія вивантажує накладні. Кожна з цих ролей працює зі своїми даними, своїми сценаріями, своїм рівнем доступу.

Функціональні блоки портала

Типовий портал для транспортно-логістичної компанії складається з кількох незалежних модулів, з'єднаних через спільну базу даних і API.

Особистий кабінет клієнта — реєстрація, історія замовлень, поточний статус доставки, документи (CMR, TTH, рахунки), запит на нову перевезення. Клієнт бачить тільки свої дані без чужих вантажів.

Панель диспетчера — вхідні заявки, призначення водіїв і транспортних засобів, відстеження позицій на карті в реальному часі, зміна статусів, чат з водієм.

Мобільний додаток водія (або PWA) — поточне замовлення, маршрут, зміна статусів (забрав/у дорозі/доставив), фотофіксація при видачі, підпис отримувача на екрані.

Адміністративна панель — управління довідниками (міста, тарифи, типи транспорту), звіти, управління користувачами.

Відстеження вантажів: технічний стек

Реальне положення транспортних засобів — один з ключових елементів. Є кілька підходів:

GPS-трекери з власним сервером. Пристрої типу Teltonika FMB920 відправляють координати за протоколом MQTT або через власний TCP-сервер. Дані приходять кожні 30–60 секунд:

# Приклад обробки вхідних даних з GPS-трекера через MQTT
import paho.mqtt.client as mqtt
import json
from datetime import datetime

def on_message(client, userdata, message):
    data = json.loads(message.payload.decode())
    vehicle_id = data['device_id']
    lat = data['lat']
    lng = data['lng']
    speed = data['speed']
    ts = datetime.fromtimestamp(data['timestamp'])

    # Зберігаємо у TimescaleDB (PostgreSQL з розширенням для часових рядів)
    db.execute("""
        INSERT INTO vehicle_positions (vehicle_id, lat, lng, speed, recorded_at)
        VALUES (%s, %s, %s, %s, %s)
    """, (vehicle_id, lat, lng, speed, ts))

    # Публікуємо в Redis для оновлення карти в реальному часі
    redis.publish(f'vehicle:{vehicle_id}', json.dumps({
        'lat': lat, 'lng': lng, 'speed': speed
    }))

Мобільний додаток з геолокацією. Водій включає відстеження через браузер або додаток. Дешевше в інфраструктурі, але залежить від заряду телефону та наявності Інтернету.

Інтеграція зі зовнішніми системами. Yandex.Transport, Wialon, Omnicomm — готові платформи моніторингу з API. Підключення до їх API дозволяє отримувати дані про позицію без власного сервера телеметрії.

Карта в реальному часі

Для відображення позицій використовується WebSocket — сервер штовхає оновлення клієнту без опитування:

// Фронтенд: підключення до WebSocket і оновлення маркерів на карті
const socket = new WebSocket('wss://api.example.com/ws/dispatch');

socket.addEventListener('message', (event) => {
  const { vehicleId, lat, lng, speed, status } = JSON.parse(event.data);

  if (markers[vehicleId]) {
    markers[vehicleId].setLatLng([lat, lng]);
    markers[vehicleId].setPopupContent(
      `<b>${vehicleId}</b><br>Швидкість: ${speed} км/ч<br>Статус: ${status}`
    );
  } else {
    markers[vehicleId] = L.marker([lat, lng])
      .addTo(map)
      .bindPopup(`<b>${vehicleId}</b>`);
  }
});

Для карти — Leaflet з плитками від OpenStreetMap (безкоштовно) або Yandex.Maps / Google Maps (платно, але краще геокодування для СНГ).

Розрахунок вартості перевезення

Тарифікація у логістичних компаній складна: залежить від ваги, обсягу, відстані, типу вантажу, терміновості, страховки. Рекомендується вивести логіку в окремий сервіс:

class FreightCalculator
{
    public function calculate(FreightRequest $request): FreightQuote
    {
        $distance = $this->distanceMatrix->calculate(
            $request->originCity,
            $request->destinationCity
        );

        $baseRate = $this->rateRepository->findRate(
            $request->cargoType,
            $request->vehicleType,
            $distance->zone
        );

        $weightCharge  = max($request->weight, $request->volumetricWeight()) * $baseRate->perKg;
        $distanceCharge = $distance->km * $baseRate->perKm;
        $insurance      = $request->declaredValue * 0.002; // 0.2%

        $total = ($weightCharge + $distanceCharge + $insurance)
            * $request->urgencyMultiplier()
            * $this->seasonalCoefficient();

        return new FreightQuote(
            base: $weightCharge + $distanceCharge,
            insurance: $insurance,
            total: round($total, 2),
            currency: 'RUB',
            validUntil: now()->addHours(24),
        );
    }
}

Документообіг

Транспортна накладна, CMR, експедиторська розписка — все це повинно генеруватися автоматично з даних замовлення. Використовуються бібліотеки типу TCPDF або Snappy (wkhtmltopdf) для PHP, або Puppeteer для Node.js.

Підпис отримувача збирається через Canvas API в браузері і зберігається як зображення, прикріплене до накладної:

const canvas = document.getElementById('signature-pad');
const signaturePad = new SignaturePad(canvas, {
  backgroundColor: 'rgb(255, 255, 255)',
  penColor: 'rgb(0, 0, 0)',
});

document.getElementById('save-signature').addEventListener('click', () => {
  if (!signaturePad.isEmpty()) {
    const dataUrl = signaturePad.toDataURL('image/png');
    // Відправляємо на сервер разом з підтвердженням доставки
    fetch('/api/deliveries/' + deliveryId + '/confirm', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ signature: dataUrl, confirmed_at: new Date().toISOString() }),
    });
  }
});

Інтеграції зі зовнішніми системами

Логістичний портал рідко живе ізольовано. Типові інтеграції:

  • — вивантаження накладних, синхронізація контрагентів, завантаження платежів
  • Diadoc / SBIS — електронний документообіг, підписання документів ЕЦП
  • Транспортні біржі (ATI.SU, Deliver) — автоматична публікація заявок на перевезення
  • Страхові компанії — оформлення страхування вантажу через API

Продуктивність у масштабі

Коли в системі тисячі активних перевезень, наївні запити до БД починають гальмувати. Кілька конкретних рішень:

Геопросторові індекси в PostgreSQL з розширенням PostGIS:

CREATE INDEX idx_vehicle_positions_location
ON vehicle_positions USING GIST (ST_SetSRID(ST_MakePoint(lng, lat), 4326));

-- Вибір усіх машин у радіусі 50 км від точки
SELECT vehicle_id, lat, lng
FROM vehicle_positions vp
JOIN (
    SELECT vehicle_id, MAX(recorded_at) as last_seen
    FROM vehicle_positions GROUP BY vehicle_id
) latest ON vp.vehicle_id = latest.vehicle_id AND vp.recorded_at = latest.last_seen
WHERE ST_DWithin(
    ST_SetSRID(ST_MakePoint(lng, lat), 4326)::geography,
    ST_SetSRID(ST_MakePoint(37.6173, 55.7558), 4326)::geography,
    50000
);

Розділення таблиці позицій за датою — через місяць дані архівуються і не заважають основним запитам.

Терміни розробки

Мінімально життєздатний портал (особистий кабінет клієнта + статуси + документи) — 6–8 тижнів. Повна система з диспетчерською картою, мобільним додатком водія, розрахунком тарифів і інтеграціями — 4–6 місяців. Це реальні цифри для команди з трьох розробників.