Система розрахунку витрати пального - Звiт про реалiзацiю¶
Дата: 2026-03-06 Модуль: Fleet (Транспорт) Функцiонал: Кнопка "Розрахувати" у подорожньому листi - розрахунок витрати пального за нормою
Короткий опис¶
Реалiзовано повну систему розрахунку витрати пального для подорожнього листа (Waybill). Кнопка "Розрахувати" на формi подорожнього листа викликає бекенд-розрахунок, який застосовує формулу нормативної витрати пального до кожного рядка табличної частини "Витрата пального". Пiдтримуються декiлька споживачiв пального на одному ТЗ (основний двигун, компресор, автономний опалювач тощо).
Формула¶
Де: | Символ | Опис | Джерело | |--------|------|---------| | Hs | Базова лiнiйна норма (л/100км) | FuelConsumptionNorm.linear_norm | | Hg | Норма на змiну власної ваги (л/100ткм) | FuelConsumptionNorm.weight_norm | | Hw | Норма на транспортну роботу (л/100ткм) | FuelConsumptionNorm.transport_work_norm | | Hh | Норма на спецiальнi моточаси (л/год) | FuelConsumptionNorm.engine_hours_norm | | S | Пробiг (км) | odometer_end - odometer_start або sum(work_results.distance_actual) | | W | Транспортна робота (ткм) | sum(task.weight * task.distance_planned) | | Gnp | Маса причепа (т) | trailer.curb_weight | | Ggr | Маса вантажу (т) | sum(task.weight) | | Ksum | Сума всiх коефiцiєнтiв (%) | записи FuelModifier |
Для типу норми "моточаси": Qh = Hh * S (де S = моточаси).
Коефiцiєнти-модифiкатори (Ksum)¶
| Код | Тип | Умова застосування |
|---|---|---|
| Кт | Температурний | Спiвпадання сезону (зима/лiто); визначається за наказом на сезон або вручну |
| Кк | Кондицiонер | Тiльки влiтку |
| Као | Автономний опалювач | Тiльки взимку |
| Ку | Умови роботи | work_condition спiвпадає з waybill.work_condition |
| Кв | Вiковий | Вiк ТЗ потрапляє в дiапазон min_age..max_age. Скидається при капремонтi |
| Кп | Причiп | Тiльки при наявностi причепа у подорожньому листi |
Режими температурного коефiцiєнта¶
Два режими розрахунку (налаштовуються у FleetModuleSettings):
1. by_season_order (за замовчуванням) - Сезон визначається автоматично з довiдника SeasonOrder (накази з дiапазонами дат)
2. by_scale - Сезон береться з поля waybill.season (встановлюється користувачем вручну)
Вiковий коефiцiєнт та капiтальний ремонт¶
Якщо у ТЗ встановлено поле overhaul_date (дата капремонту), вiк ТЗ рахується вiд дати капремонту, а не вiд року випуску. Це скидає шкалу вiкових коефiцiєнтiв пiсля капiтального ремонту.
Новi моделi бекенду¶
1. FleetModuleSettings (Налаштування модуля Fleet)¶
Файл: backend/fleet/models/fleet_module_settings.py
Один запис на тенант. Зберiгає налаштування розрахунку на рiвнi модуля.
| Поле | Тип | Опис |
|---|---|---|
| temperature_calc_method | CharField | 'by_scale' або 'by_season_order' |
2. SeasonOrder (Наказ на встановлення сезону)¶
Файл: backend/fleet/models/season_order.py
Накази пiдприємства, що визначають сезоннi перiоди для розрахунку коефiцiєнтiв витрати пального.
| Поле | Тип | Опис |
|---|---|---|
| name | CharField | Назва наказу |
| date_from | DateField | Початок перiоду |
| date_to | DateField | Кiнець перiоду |
| season | CharField | winter/spring/summer/autumn |
| is_active | BooleanField | Активний |
Метод класу: SeasonOrder.get_season_for_date(tenant_id, date) - повертає сезон для заданої дати.
3. FuelModifier (Шкали коефiцiєнтiв витрати пального)¶
Файл: backend/fleet/models/fuel_modifier.py
Шкали коефiцiєнтiв витрати пального. Єдинi для всiх органiзацiй в межах тенанта.
| Поле | Тип | Опис |
|---|---|---|
| modifier_type | CharField | temperature/ac/heater/work_condition/age/trailer |
| name | CharField | Назва |
| value | DecimalField | Значення у вiдсотках (напр. 10 = +10%) |
| season | CharField | Сезон застосування (для temperature/ac/heater) |
| work_condition | FK(WorkCondition) | Для типу work_condition |
| min_age | PositiveIntegerField | Мiн. вiк ТЗ для типу age |
| max_age | PositiveIntegerField | Макс. вiк ТЗ для типу age |
| is_active | BooleanField | Активний |
Приклади записiв шкали:
| Тип | Назва | Значення | Сезон | min_age | max_age |
|---|---|---|---|---|---|
| temperature | Зима -5..-10 | 5% | winter | ||
| temperature | Зима -10..-20 | 10% | winter | ||
| temperature | Зима нижче -20 | 15% | winter | ||
| age | 5-8 рокiв | 5% | 5 | 8 | |
| age | понад 8 рокiв | 10% | 8 | 999 | |
| work_condition | Мiсто > 2.5М | 25% | |||
| ac | Кондицiонер | 7% | summer | ||
| heater | Автономний опалювач | 5% | winter | ||
| trailer | Причiп | 2% |
Розширенi моделi¶
Vehicle (2 новi поля)¶
Файл: backend/fleet/models/vehicle.py
| Поле | Тип | Опис |
|---|---|---|
| curb_weight | DecimalField(10,3) | Власна маса в тоннах (для Gnp) |
| overhaul_date | DateField(null) | Дата останнього капремонту (скидає вiковий коефiцiєнт) |
FuelConsumptionNorm (6 нових полiв)¶
Файл: backend/fleet/models/fuel_consumption_norm.py
| Поле | Тип | Опис |
|---|---|---|
| weight_norm | DecimalField(10,2) | Hg - норма на тонну змiни ваги |
| transport_work_norm | DecimalField(10,2) | Hw - норма на тонно-кiлометр |
| engine_hours_norm | DecimalField(10,2) | Hh - норма на моточасу |
| loaded_mileage_norm | DecimalField(10,2) | Hb - для бетоновозiв |
| equipment | FK(TransportComponent, null) | null = основний двигун, iнакше — конкретне обладнання |
| norm_type | CharField | 'mileage' (за пробiгом) або 'engine_hours' (за моточасами) |
WaybillFuelRecord (11 нових полiв)¶
Файл: backend/fleet/models/waybill_fuel_record.py
| Поле | Тип | Опис |
|---|---|---|
| equipment | FK(TransportComponent, null) | Споживач пального (null = основний двигун) |
| fuel_consumption_norm | FK(FuelConsumptionNorm, null) | Посилання на застосовану норму |
| quantity_by_norm | DecimalField(10,3) | Розрахована витрата за нормою (Qh) |
| calc_mileage | DecimalField(10,2) | S використаний у розрахунку |
| calc_cargo_weight | DecimalField(10,3) | Ggr використаний |
| calc_cargo_distance | DecimalField(10,2) | Sgr використаний |
| calc_transport_work | DecimalField(15,3) | W використаний |
| calc_trailer_weight | DecimalField(10,3) | Gnp використаний |
| calc_coefficient_sum | DecimalField(8,2) | Ksum використаний |
| calc_details | JSONField | Повна деталiзацiя розрахунку для аудиту |
Сервiс розрахунку¶
FuelCalculator¶
Файл: backend/fleet/services/fuel_calculator.py
Основний двигун розрахунку. Алгоритм:
- Отримати пробiг S (з одометра або work_results)
- Отримати транспортну роботу W, Ggr, Sgr (iз завдань)
- Отримати масу причепа Gnp (з trailer.curb_weight)
- Визначити дiючий сезон (через SeasonOrder або waybill.season)
- Зiбрати застосовнi записи FuelModifier, обчислити Ksum
- Для кожного рядка fuel_records: a. Знайти вiдповiдну FuelConsumptionNorm (за vehicle + fuel_type + equipment) b. Застосувати формулу c. Зберегти результат + данi аудиту в запис
Логiка сезонних коефiцiєнтiв¶
якщо settings.temperature_calc_method == 'by_season_order':
сезон = SeasonOrder.get_season_for_date(дата_подорожнього_листа)
iнакше: # by_scale
сезон = waybill.season (встановлений вручну)
якщо сезон == 'winter':
Као = FuelModifier(type='heater').value -> застосовується
Кк = 0 -> НЕ застосовується
якщо сезон == 'summer':
Кк = FuelModifier(type='ac').value -> застосовується
Као = 0 -> НЕ застосовується
Логiка вiкового коефiцiєнта¶
якщо vehicle.overhaul_date встановлено:
вiк = (дата_подорожнього_листа - vehicle.overhaul_date) в роках # вiд капремонту
iнакше:
вiк = рiк_подорожнього_листа - vehicle.year # вiд року випуску
Кв = FuelModifier(type='age', min_age <= вiк < max_age).value
API Ендпоiнти¶
Новий ендпоiнт розрахунку¶
Виконує розрахунок витрати пального. Повертає оновлений подорожній лист з перерахованими fuel_records. Не можна запустити для проведеного документа.Новi CRUD ендпоiнти¶
/api/v1/fleet/fuel-modifiers/ GET/POST
/api/v1/fleet/fuel-modifiers/{id}/ GET/PUT/PATCH/DELETE
/api/v1/fleet/season-orders/ GET/POST
/api/v1/fleet/season-orders/{id}/ GET/PUT/PATCH/DELETE
/api/v1/fleet/fleet-module-settings/ GET/POST
/api/v1/fleet/fleet-module-settings/{id}/ GET/PUT/PATCH/DELETE
Змiни фронтенду¶
fleet.ts (конфiгурацiя)¶
- Додано
fuelModifiers(Коефiцiєнти витрати пального) до пiдгрупи "Облiк ГСМ" - Додано
seasonOrders(Накази на встановлення сезону) до пiдгрупи "Облiк ГСМ" - Налаштування температурного коефiцiєнта перенесено на сторiнку "Налаштування" (Settings → Транспорт)
SettingsPage (Налаштування програми)¶
- Активовано вкладку "Транспорт" (ранiше була заглушкою)
- Створено компонент
FleetSettings.tsx— завантажує/зберiгаєtemperature_calc_methodчерез API/fleet/fleet-module-settings/ - Два режими: "За шкалою температур" або "За наказом на встановлення сезону"
WaybillForm.tsx¶
- Кнопка "Розрахувати" тепер викликає
POST /fleet/waybills/{id}/calculate/ - Показує повiдомлення про успiх/помилку
- Iнвалiдує кеш React Query для оновлення даних
- Додано завантаження довiдника
transportComponentsдля поля обладнання
WaybillSubtables.tsx¶
- Додано стовпець
Обладнання(Equipment) до таблицi витрати пального (редагується inline + модальне вiкно) - Додано стовпець
За нормою(By Norm) — тiльки для читання, показує результат розрахунку - Якщо обладнання не обрано — показується "Основний" (основний двигун)
- Модальне вiкно включає вибiр обладнання + поле "За нормою" (тiльки читання)
Мiграцiя¶
Застосована успiшно. Додає всi новi моделi та розширює iснуючi.
Змiненi файли¶
Новi файли¶
| Файл | Опис |
|---|---|
backend/fleet/models/fleet_module_settings.py |
Модель налаштувань модуля Fleet |
backend/fleet/models/season_order.py |
Модель наказу на встановлення сезону |
backend/fleet/models/fuel_modifier.py |
Модель шкал коефiцiєнтiв |
backend/fleet/services/fuel_calculator.py |
Сервiс розрахунку витрати пального |
backend/fleet/migrations/0020_fuel_calculation_system.py |
Мiграцiя БД |
Змiненi файли¶
| Файл | Змiни |
|---|---|
backend/fleet/models/fuel_consumption_norm.py |
+6 полiв норм (Hg, Hw, Hh, Hb, equipment, norm_type) |
backend/fleet/models/vehicle.py |
+curb_weight, +overhaul_date |
backend/fleet/models/waybill_fuel_record.py |
+11 полiв (обладнання, посилання на норму, результати розрахунку, аудит JSON) |
backend/fleet/models/__init__.py |
+3 iмпорти моделей |
backend/fleet/apps.py |
+3 реєстрацiї в EntityRegistry |
backend/fleet/serializers.py |
+4 серiалiзатори (FuelModifier, SeasonOrder, FleetModuleSettings, розширений FuelRecord) |
backend/fleet/views.py |
+дiя calculate, +3 ViewSet |
backend/fleet/urls.py |
+3 реєстрацiї маршрутiв |
frontend/erp/src/config/fleet.ts |
+3 елементи конфiгурацiї |
frontend/erp/src/components/Fleet/Waybill/WaybillForm.tsx |
Кнопка розрахунку пiдключена до API |
frontend/erp/src/components/Fleet/Waybill/WaybillSubtables.tsx |
+стовпцi equipment, quantity_by_norm |
Схема даних¶
Vehicle (iснуючий + curb_weight, overhaul_date)
|
+-- FuelConsumptionNorm (розширена: Hs, Hg, Hw, Hh, Hb + equipment)
| +-- рядок 1: основний двигун -- Hs=25, Hg=1.3, Hw=1.3
| +-- рядок 2: компресор -- Hs=5, Hh=2.0
|
+-- Waybill (подорожній лист)
+-- tasks[] -> weight, distance -> W (транспортна робота)
+-- work_results[] -> distance_actual -> S (пробiг)
+-- fuel_records[] (розширена)
+-- рядок 1: Дизель / основний двигун -> quantity_by_norm = 87.5 л
+-- рядок 2: Дизель / компресор -> quantity_by_norm = 12.3 л
FuelModifier (новий, єдиний для всiх органiзацiй тенанта)
+-- Кт: зима = +10%
+-- Кв: вiк > 8 рокiв = +5%
+-- Ку: мiсто = +25%
SeasonOrder (новий)
+-- з 10.10.2025 по 03.03.2026 = зима
+-- з 04.03.2026 по 30.05.2026 = весна
FleetModuleSettings (новий)
+-- temperature_calc_method = 'by_season_order'
Порядок використання¶
- Налаштування (одноразово):
- Створити записи
FuelConsumptionNormдля кожного ТЗ + тип пального (+ обладнання за потреби) - Створити записи шкал
FuelModifier(температурнi, вiковi, умови роботи тощо) - Створити записи
SeasonOrderз дiапазонами дат -
Налаштувати
FleetModuleSettings.temperature_calc_method -
По кожному подорожньому листу:
- Заповнити шапку (ТЗ, причiп, водiй, одометр, дати)
- Заповнити завдання (маса вантажу, планова вiдстань)
- Заповнити витрату пального (тип пального, обладнання, залишки початок/видано/кiнець)
- Натиснути кнопку "Розрахувати"
- Система заповнює
quantity_by_norm(За нормою) для кожного рядка -
Переглянути результати, провести документ
-
Аудит:
- Кожний рядок витрати пального зберiгає повну деталiзацiю розрахунку в
calc_details(JSON) - Включає рядок формули, всi параметри (Hs, Hg, Hw, S, W, Ksum), список застосованих модифiкаторiв
Агрегати, комплектацiя, документи палива — Звiт про реалiзацiю¶
Дата: 2026-03-06 Модуль: Fleet (Транспорт) Функцiонал: Перелiчення типу агрегата, довiдник агрегатiв ТЗ, комплектацiя ТЗ, документи: введення початкових залишкiв, заправка ТЗ, злив ГСМ, журнал амортизацiї агрегатiв
Перелiчення (Enums)¶
AggregateType¶
Тип агрегату транспортного засобу:
| Значення | Назва |
|----------|-------|
| accumulator | Акумулятор |
| tire | Шина |
ConfigurationStatus¶
Статус комплектацiї:
| Значення | Назва |
|----------|-------|
| installed | Встановлено |
| removed | Знято |
RefuelingType¶
Вид заправки:
| Значення | Назва |
|----------|-------|
| own_station | Власна АЗС |
| cash_on_road | Готiвка в дорозi |
Новi моделi бекенду¶
1. VehicleAggregate (Агрегати ТЗ)¶
Файл: backend/fleet/models/vehicle_aggregate.py
Базовий клас: MasterDataModel
| Поле | Тип | Опис |
|---|---|---|
| aggregate_type | CharField(choices=AggregateType) | Тип агрегату (акумулятор/шина) |
| item | FK(essentials.Item, null) | Номенклатура |
| serial_number | CharField(100) | Серiйний номер |
| mileage_norm | DecimalField(10,2) | Норма пробiгу (км) |
| work_time_norm | DecimalField(10,2) | Норма часу роботи (год) |
| + успадкованi вiд MasterDataModel: code, name, name_ua, is_active, description |
2. VehicleConfiguration (Комплектацiя ТЗ)¶
Файл: backend/fleet/models/vehicle_configuration.py
Базовий клас: TenantAwareModel
| Поле | Тип | Опис |
|---|---|---|
| vehicle | FK(Vehicle) | Транспортний засiб |
| aggregate | FK(VehicleAggregate) | Агрегат |
| status | CharField(choices=ConfigurationStatus) | Встановлено/Знято |
| date | DateField(null) | Дата встановлення/зняття |
| note | CharField(255) | Примiтка |
3. InitialBalances (Введення початкових залишкiв)¶
Файл: backend/fleet/models/initial_balances.py
Базовий клас: TransactionModel
| Поле | Тип | Опис |
|---|---|---|
| vehicle | FK(Vehicle) | Транспортний засiб |
| odometer_value | PositiveIntegerField | Показання спiдометра (км) |
| fuel_type | FK(FuelType, null) | Тип пального |
| fuel_balance | DecimalField(10,3) | Залишок пального в баку (л) |
| + табличну частину: aggregate_lines (InitialBalanceAggregateLine) |
При проведеннi: - Створює запис OdometerReading (показання одометра) - Створює запис FuelLedger (залишок пального) - Створює записи AggregateAmortizationJournal (знос агрегатiв)
InitialBalanceAggregateLine (Табличнa частинa)¶
| Поле | Тип | Опис |
|---|---|---|
| document | FK(InitialBalances) | Документ |
| aggregate | FK(VehicleAggregate) | Агрегат |
| current_mileage | DecimalField(10,2) | Поточний пробiг (км) |
| current_work_time | DecimalField(10,2) | Поточний час роботи (год) |
| note | CharField(255) | Примiтка |
4. VehicleRefueling (Заправка ТЗ)¶
Файл: backend/fleet/models/vehicle_refueling.py
Базовий клас: TransactionModel
| Поле | Тип | Опис |
|---|---|---|
| vehicle | FK(Vehicle) | Транспортний засiб |
| fuel_type | FK(FuelType) | Тип пального |
| refueling_type | CharField(choices=RefuelingType) | Вид заправки |
| quantity | DecimalField(10,3) | Кiлькiсть (л) |
| price | DecimalField(10,2) | Цiна за лiтр |
| amount | DecimalField(12,2) | Загальна сума |
| driver | FK(Driver, null) | Водiй |
При проведеннi: - Створює запис FuelJournal (операцiя issue) - Створює запис FuelLedger (збiльшення залишку)
5. FuelDrain (Злив ГСМ)¶
Файл: backend/fleet/models/fuel_drain.py
Базовий клас: TransactionModel
| Поле | Тип | Опис |
|---|---|---|
| vehicle | FK(Vehicle) | Транспортний засiб |
| fuel_type | FK(FuelType) | Тип пального |
| quantity | DecimalField(10,3) | Кiлькiсть (л) |
| reason | TextField | Причина зливу |
| driver | FK(Driver, null) | Водiй |
При проведеннi: - Створює запис FuelJournal (операцiя consumption) - Створює запис FuelLedger (зменшення залишку)
6. AggregateAmortizationJournal (Журнал амортизацiї агрегатiв)¶
Файл: backend/registers/models/aggregate_amortization_journal.py
Базовий клас: RegisterModel
| Поле | Тип | Опис |
|---|---|---|
| vehicle | FK(Vehicle) | Транспортний засiб |
| aggregate | FK(VehicleAggregate) | Агрегат |
| mileage | DecimalField(10,2) | Пробiг (км) |
| work_time | DecimalField(10,2) | Час роботи (год) |
| notes | TextField | Примiтки |
| + успадкованi вiд RegisterModel: date, document_type, document_id, manual_edit |
API Ендпоiнти¶
Новi CRUD ендпоiнти¶
/api/v1/fleet/vehicle-aggregates/ GET/POST
/api/v1/fleet/vehicle-aggregates/{id}/ GET/PUT/PATCH/DELETE
/api/v1/fleet/vehicle-configurations/ GET/POST
/api/v1/fleet/vehicle-configurations/{id}/ GET/PUT/PATCH/DELETE
/api/v1/fleet/initial-balances/ GET/POST
/api/v1/fleet/initial-balances/{id}/ GET/PUT/PATCH/DELETE
/api/v1/fleet/initial-balances/{id}/post_document/ POST (проведення)
/api/v1/fleet/initial-balances/{id}/unpost_document/ POST (скасування)
/api/v1/fleet/initial-balance-aggregate-lines/ GET/POST
/api/v1/fleet/initial-balance-aggregate-lines/{id}/ GET/PUT/PATCH/DELETE
/api/v1/fleet/vehicle-refuelings/ GET/POST
/api/v1/fleet/vehicle-refuelings/{id}/ GET/PUT/PATCH/DELETE
/api/v1/fleet/vehicle-refuelings/{id}/post_document/ POST (проведення)
/api/v1/fleet/vehicle-refuelings/{id}/unpost_document/ POST (скасування)
/api/v1/fleet/fuel-drains/ GET/POST
/api/v1/fleet/fuel-drains/{id}/ GET/PUT/PATCH/DELETE
/api/v1/fleet/fuel-drains/{id}/post_document/ POST (проведення)
/api/v1/fleet/fuel-drains/{id}/unpost_document/ POST (скасування)
Змiни фронтенду¶
fleet.ts (конфiгурацiя)¶
- Додано
vehicleAggregates(Агрегати ТЗ) до пiдгрупи "Ремонт та техобслуговування" - Додано
vehicleConfigurations(Комплектацiя ТЗ) до пiдгрупи "Ремонт та техобслуговування" - Додано нову пiдгрупу
fueloperations(Операцiї з ГСМ) до групи "Операцiї": initialBalances(Введення початкових залишкiв) — з subtable агрегатiв + postingConfigvehicleRefuelings(Заправка ТЗ) — з postingConfigfuelDrains(Злив ГСМ) — з postingConfig
Мiграцiї¶
fleet/migrations/0021_fueldrain_initialbalances_vehicleaggregate_and_more.py
registers/migrations/0007_aggregateamortizationjournal.py
Застосованi успiшно.
Змiненi/додано файли¶
Новi файли¶
| Файл | Опис |
|---|---|
backend/fleet/models/vehicle_aggregate.py |
Довiдник агрегатiв ТЗ + enum AggregateType |
backend/fleet/models/vehicle_configuration.py |
Комплектацiя ТЗ + enum ConfigurationStatus |
backend/fleet/models/initial_balances.py |
Документ введення початкових залишкiв + табличнa частинa |
backend/fleet/models/vehicle_refueling.py |
Документ заправки ТЗ + enum RefuelingType |
backend/fleet/models/fuel_drain.py |
Документ зливу ГСМ |
backend/registers/models/aggregate_amortization_journal.py |
Журнал амортизацiї агрегатiв |
backend/fleet/migrations/0021_... |
Мiграцiя Fleet |
backend/registers/migrations/0007_... |
Мiграцiя Registers |
Змiненi файли¶
| Файл | Змiни |
|---|---|
backend/fleet/models/__init__.py |
+6 iмпортiв моделей |
backend/registers/models/__init__.py |
+1 iмпорт AggregateAmortizationJournal |
backend/fleet/serializers.py |
+10 серiалiзаторiв |
backend/fleet/views.py |
+6 ViewSet + логiка проведення 3 документiв |
backend/fleet/urls.py |
+6 маршрутiв |
backend/fleet/apps.py |
+5 реєстрацiй в EntityRegistry |
frontend/erp/src/config/fleet.ts |
+2 довiдники + 3 документи + нова пiдгрупа |
Схема проведення документiв¶
InitialBalances (Введення початкових залишкiв)
|-- odometer_value -> OdometerReading
|-- fuel_balance -> FuelLedger (quantity_in)
|-- aggregate_lines[] -> AggregateAmortizationJournal (по кожному рядку)
VehicleRefueling (Заправка ТЗ)
|-- quantity -> FuelJournal (issue)
|-- quantity -> FuelLedger (quantity_in, збiльшення балансу)
FuelDrain (Злив ГСМ)
|-- quantity -> FuelJournal (consumption)
|-- quantity -> FuelLedger (quantity_out, зменшення балансу)