Перейти до змісту

Система розрахунку витрати пального - Звiт про реалiзацiю

Дата: 2026-03-06 Модуль: Fleet (Транспорт) Функцiонал: Кнопка "Розрахувати" у подорожньому листi - розрахунок витрати пального за нормою


Короткий опис

Реалiзовано повну систему розрахунку витрати пального для подорожнього листа (Waybill). Кнопка "Розрахувати" на формi подорожнього листа викликає бекенд-розрахунок, який застосовує формулу нормативної витрати пального до кожного рядка табличної частини "Витрата пального". Пiдтримуються декiлька споживачiв пального на одному ТЗ (основний двигун, компресор, автономний опалювач тощо).


Формула

Qh = 0.01 * (Hs + Hg * (Gnp + Ggr)) * S * (1 + 0.01 * Ksum) + 0.01 * W * Hw

Де: | Символ | Опис | Джерело | |--------|------|---------| | 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

Основний двигун розрахунку. Алгоритм:

  1. Отримати пробiг S (з одометра або work_results)
  2. Отримати транспортну роботу W, Ggr, Sgr (iз завдань)
  3. Отримати масу причепа Gnp (з trailer.curb_weight)
  4. Визначити дiючий сезон (через SeasonOrder або waybill.season)
  5. Зiбрати застосовнi записи FuelModifier, обчислити Ksum
  6. Для кожного рядка 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нт розрахунку

POST /api/v1/fleet/waybills/{id}/calculate/
Виконує розрахунок витрати пального. Повертає оновлений подорожній лист з перерахованими 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я

fleet/migrations/0020_fuel_calculation_system.py

Застосована усп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'

Порядок використання

  1. Налаштування (одноразово):
  2. Створити записи FuelConsumptionNorm для кожного ТЗ + тип пального (+ обладнання за потреби)
  3. Створити записи шкал FuelModifier (температурнi, вiковi, умови роботи тощо)
  4. Створити записи SeasonOrder з дiапазонами дат
  5. Налаштувати FleetModuleSettings.temperature_calc_method

  6. По кожному подорожньому листу:

  7. Заповнити шапку (ТЗ, причiп, водiй, одометр, дати)
  8. Заповнити завдання (маса вантажу, планова вiдстань)
  9. Заповнити витрату пального (тип пального, обладнання, залишки початок/видано/кiнець)
  10. Натиснути кнопку "Розрахувати"
  11. Система заповнює quantity_by_norm (За нормою) для кожного рядка
  12. Переглянути результати, провести документ

  13. Аудит:

  14. Кожний рядок витрати пального зберiгає повну деталiзацiю розрахунку в calc_details (JSON)
  15. Включає рядок формули, вс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в + postingConfig
  • vehicleRefuelings (Заправка ТЗ) — з postingConfig
  • fuelDrains (Злив ГСМ) — з 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, зменшення балансу)