Leasing

Studi Kasus Leasing dan Buku Resep SQL

Perusahaan leasing (terutama bank dan penyedia leasing armada) mempertahankan kepemilikan kendaraan atau peralatan sementara klien hanya menyewa penggunaannya, sehingga mereka menanggung risiko terkait aset sepanjang durasi kontrak. 

Untuk melindungi nilai residu, menegakkan batasan kontraktual (jarak tempuh, wilayah, pemeliharaan), dan menyederhanakan kewajiban layanan penuh, mereka mengandalkan Navixy. Data GPS real-time, diagnostik berbasis sensor, dan analitik perilaku memungkinkan mereka memverifikasi kondisi penggunaan, mengotomatiskan penjadwalan layanan, mendeteksi masalah mekanis lebih awal, menghitung denda atau biaya kilometer berlebih, dan, bila perlu, menonaktifkan atau memulihkan aset—semua ini mengamankan investasi mereka, mengurangi biaya operasional, dan meningkatkan transparansi kepada pelanggan sepanjang siklus hidup sewa.

Navixy DataHub akan membantu mengatur segala jenis analitik pada setiap tahap kontrak leasing. Kontrak leasing melewati beberapa fase yang dapat diprediksi: Onboarding & Asset Setup → Operational Phase → Risk & Compliance Oversight

Resep SQL berikut dalam buku Anda secara kolektif memantau setiap tonggak kritis di seluruh siklus hidup tersebut:

Fase Siklus Hidup
Tujuan & Tonggak
Kasus Penggunaan / Resep yang Dicakup

Onboarding & Pengaturan Aset

• Daftarkan kendaraan, aktifkan asuransi dan kredensial pengemudi. • Impor aset ke portal klien dengan visibilitas yang benar.

Peringatan Kedaluwarsa Registrasi/Asuransi – tanggal dasar tercatat. Kedaluwarsa SIM Pengemudi – memvalidasi pengemudi sebelum pelepasan.

Perencanaan Pemeliharaan Preventif

• Tetapkan jadwal layanan berulang berbasis jarak tempuh dan waktu. • Jamin penggantian ban musiman.

Inspeksi Rutin berdasarkan Interval – tugas berbasis kalender. Layanan berdasarkan Ambang Kilometer – aturan servis kecil/besar berbasis km. Pemantauan Jam Mesin – servis berbasis jam untuk mesin.

Batasan Penggunaan Terikat Kontrak

• Tegakkan alokasi jarak tempuh dan batas finansial. • Deteksi penggunaan berlebih lebih awal untuk menghindari kejutan di akhir masa kontrak.

Batas Kilometer & Penalti – pengawasan kilometre tahunan / total kontrak.

Perilaku Pengemudi & Aset Real‑time

• Lindungi nilai aset; pembinaan pengemudi. • Deteksi penyalahgunaan yang membatalkan cakupan “layanan penuh”.

Pengereman Keras. Akselerasi Keras. Tikungan/Belokan Mendadak.

Pengawasan Risiko & Kepatuhan

• Jaga aset tetap di dalam batas geografis dan kontraktual. • Pertahankan hak untuk menonaktifkan atau memulihkan.

Keluar Geofence (Perbatasan Negara) – peringatan instan saat pelanggaran wilayah. Deteksi Pengapian & Idle – pelacakan pemborosan bahan bakar / penyalahgunaan.

Peringatan Kedaluwarsa Registrasi / Asuransi

Bank harus melacak kedaluwarsa registrasi dan asuransi yang akan datang karena mereka bertanggung jawab atas inspeksi teknis, registrasi, dan asuransi. Peringatan tepat waktu mencegah denda dan waktu henti kendaraan.

SELECT v.vehicle_id,       v.vehicle_label,       v.registration_number,       v.free_insurance_valid_till_date,       v.liability_insurance_valid_tillFROM raw_business_data.vehicles vWHERE v.free_insurance_valid_till_date BETWEEN CURRENT_DATE AND CURRENT_DATE + (30 * INTERVAL '1 day')   OR v.liability_insurance_valid_till   BETWEEN CURRENT_DATE1 AND CURRENT_DATE + (30 * INTERVAL '1 day');

Kedaluwarsa Surat Izin Mengemudi

Meskipun tidak selalu wajib, menawarkan peringatan kedaluwarsa SIM proaktif adalah layanan nilai tambah. Peringatan dini memungkinkan klien memperbarui SIM sebelum kedaluwarsa. Harap dicatat Anda

SELECT e.employee_id,
       e.first_name || ' ' || e.last_name AS driver_name,
       e.driver_license_number,
       e.driver_license_valid_till
FROM raw_business_data.employees e
WHERE e.driver_license_valid_till BETWEEN CURRENT_DATE AND CURRENT_DATE + (30 * INTERVAL '1 day');

Keluar Geofence (Perbatasan Negara)

Kontrak mungkin membatasi pergerakan kendaraan ke wilayah tertentu (mis. Serbia). Keluar dari zona itu harus segera memberi peringatan kepada bank sehingga dapat bertindak (mis. menghubungi klien, mengamankan aset).

Query SQL ini dirancang untuk memantau dan mengidentifikasi ketika perangkat keluar dari zona geografis yang telah ditentukan berlabel "Tallaght Depot Geofences." Proses dimulai dengan mengumpulkan dan mengurutkan titik geografis yang mendefinisikan batas zona. Untuk memastikan batas membentuk poligon yang valid, titik pertama ditambahkan ke akhir daftar, secara efektif menutup bentuk. Set titik tertutup ini kemudian digunakan untuk membuat poligon yang mewakili zona geografis, yang dikonversi menjadi objek geography untuk analisis spasial.

Query kemudian mengambil data pelacakan perangkat dalam rentang waktu tertentu, mengonversi nilai lintang dan bujur mentah menjadi titik geografis. Query menghitung apakah setiap titik perangkat berada di dalam atau di luar zona yang telah ditentukan menggunakan fungsi ST_Contains, yang memeriksa keterkaitan spasial. Parameter yang dihitung pos menunjukkan 'inside' jika titik berada di dalam zona dan 'outside' jika tidak. Akhirnya, query memfilter hasil ini untuk mendeteksi transisi di mana perangkat bergerak dari dalam zona ke luar, menggunakan fungsi jendela untuk membandingkan posisi saat ini dengan posisi sebelumnya. Logika ini membantu memantau pergerakan perangkat dan mendeteksi kejadian keluar dari area geografis tertentu. Pastikan Anda menambahkan nilai yang benar untuk parameter: z.zone_label = 'your_zone_label'.

WITH zone AS (
  SELECT z.zone_id,
         ST_MakePolygon(ST_MakeLine(ARRAY_AGG(ST_MakePoint(g.longitude, g.latitude) ORDER BY g.number)))::geography AS geog
  FROM raw_business_data.zones z
  JOIN raw_business_data.geofence_points g ON g.zone_id = z.zone_id
  WHERE z.zone_label = 'your_zone_label'
  GROUP BY z.zone_id
),
pts AS (
  SELECT device_id,
         device_time,
         ST_SetSRID(ST_MakePoint(longitude/1e7::numeric, latitude/1e7::numeric), 4326)::geography AS geog
  FROM raw_telematics_data.tracking_data_core
  WHERE device_time BETWEEN '2025-07-27 00:00:00' AND '2025-07-28 23:59:59'
),
states AS (
  SELECT p.*,
         CASE WHEN ST_Contains(z.geog::geometry, p.geog::geometry) THEN 'inside' ELSE 'outside' END AS pos
  FROM pts p CROSS JOIN zone z
),
filtered_states AS (
  SELECT
    device_id,
    device_time,
    pos,
    LAG(pos) OVER (PARTITION BY device_id ORDER BY device_time) AS prev_pos
  FROM states
)
SELECT device_id, device_time, pos
FROM filtered_states
WHERE prev_pos = 'inside' AND pos = 'outside';

Inspeksi Rutin berdasarkan Interval Waktu

Beberapa tugas pemeliharaan berulang pada jadwal waktu tetap. Sistem harus memberi tanda pada kendaraan yang pemeriksaan/cek berikutnya jatuh tempo dalam interval yang ditentukan.

SELECT vehicle_id,       description,       start_date,       date_repeat_interval,       start_date + date_repeat_interval * floor(EXTRACT(EPOCH FROM (CURRENT_DATE - start_date)) /                                                 EXTRACT(EPOCH FROM date_repeat_interval)) AS last_due,       start_date + date_repeat_interval * (floor(EXTRACT(EPOCH FROM (CURRENT_DATE - start_date)) /                                                  EXTRACT(EPOCH FROM date_repeat_interval)) + 1) AS next_dueFROM raw_business_data.vehicle_service_tasksWHERE date_repeat_interval IS NOT NULL  AND start_date + date_repeat_interval * (floor(EXTRACT(EPOCH FROM (CURRENT_DATE - start_date)) /                                                 EXTRACT(EPOCH FROM date_repeat_interval)) + 1)      BETWEEN CURRENT_DATE AND CURRENT_DATE + (30 * INTERVAL '1 day');

Layanan berdasarkan Ambang Kilometer (Minor/Major)

Servis kecil dan besar dipicu oleh jarak tempuh sejak kejadian servis terakhir. Ketika akumulasi kilometer melebihi ambang, servis yang sesuai harus dijadwalkan.

Harap perhatikan field vst.description harus memiliki komentar / deskripsi relevan untuk menggunakannya sebagai filter dalam kode SQL di bawah.

SELECT
  v.vehicle_id,
  v.vehicle_label,
  km.km_since_service,
  vst.mileage_limit
DARI
  raw_business_data.vehicles v
  JOIN LATERAL (
    SELECT MAX(vst.completion_date) AS last_service_date
    FROM raw_business_data.vehicle_service_tasks vst
    WHERE vst.vehicle_id = v.vehicle_id
      AND (vst.description ILIKE '%minor%' OR vst.description ILIKE '%major%')
      AND vst.completion_date IS NOT NULL
  ) ls ON TRUE
  JOIN raw_business_data.objects o ON o.object_id = v.vehicle_id
  JOIN LATERAL (
    SELECT SUM(t.track_distance_meters) / 1000.0 AS km_since_service
    FROM business_data.tracks t
    WHERE t.device_id = o.device_id
      AND t.track_start_time > ls.last_service_date
  ) km ON TRUE
  JOIN raw_business_data.vehicle_service_tasks vst
    ON vst.vehicle_id = v.vehicle_id
    AND vst.completion_date = ls.last_service_date
    AND (vst.description ILIKE '%minor%' OR vst.description ILIKE '%major%')

Batas Kilometer & Penalti

Kontrak leasing sering membatasi jarak tempuh (mis. 25.000 km/tahun). Jika batas dilampaui, klausul penalti berlaku. Sistem harus membandingkan jarak tempuh aktual selama periode kontrak dengan batas yang disepakati dan menghitung biaya.

WITH driven AS (
  SELECT
    o.object_id,
    DATE_TRUNC('year', t.track_start_time) AS year,
    SUM(t.track_distance_meters) / 1000.0 AS km_year
  DARI
    business_data.tracks t
    JOIN raw_business_data.objects o ON o.device_id = t.device_id
  WHERE
    t.track_start_time >= '2023-01-01'::date
    AND t.track_start_time < '2024-01-01'::date
  GROUP BY
    o.object_id, DATE_TRUNC('year', t.track_start_time)
),
limits AS (
  SELECT
    object_id,
    10000 AS km_limit,
    0.5 AS penalty_rate
  DARI
    raw_business_data.objects
)
SELECT
  d.object_id,
  d.year,
  d.km_year,
  l.km_limit,
  GREATEST(d.km_year - l.km_limit, 0) AS km_over,
  GREATEST(d.km_year - l.km_limit, 0) * l.penalty_rate AS penalty_amount
DARI
  driven d
  JOIN limits l ON d.object_id = l.object_id;

Pemantauan Jam Mesin

Untuk mesin dan peralatan pertanian, jam operasi—bukan jarak tempuh—menggerakkan pemeliharaan dan penagihan. Data jam mesin (mis. dari CAN‑Bus) harus dipantau dan diringkas.

WITH last_service AS (
  SELECT
    vst.vehicle_id,
    MAX(vst.completion_date) AS last_service_date,
    MAX(vst.completion_engine_hours) AS last_service_engine_hours
  DARI
    raw_business_data.vehicle_service_tasks vst
  GROUP BY
    vst.vehicle_id
),
engine_hours_since_service AS (
  SELECT
    v.vehicle_id,
    SUM(t.track_duration_seconds) / 3600.0 AS engine_hours_since_service
  DARI
    raw_business_data.vehicles v
    JOIN raw_business_data.objects o ON o.object_id = v.object_id
    JOIN business_data.tracks t ON t.device_id = o.device_id
    JOIN last_service ls ON ls.vehicle_id = v.vehicle_id
  WHERE
    t.track_start_time > ls.last_service_date
  GROUP BY
    v.vehicle_id
)
SELECT
  v.vehicle_id,
  v.vehicle_label,
  ls.last_service_engine_hours,
  ehs.engine_hours_since_service,
  (COALESCE(ehs.engine_hours_since_service,0) + COALESCE(ls.last_service_engine_hours,0)) AS current_engine_hours,
  vst.engine_hours_limit
DARI
  raw_business_data.vehicles v
  JOIN last_service ls ON ls.vehicle_id = v.vehicle_id
  LEFT JOIN engine_hours_since_service ehs ON ehs.vehicle_id = v.vehicle_id
  JOIN raw_business_data.vehicle_service_tasks vst
    ON vst.vehicle_id = v.vehicle_id
    AND vst.completion_date = ls.last_service_date

Kejadian Pengereman Keras

Perilaku mengemudi memengaruhi keausan dan kepatuhan kontrak. Mendeteksi pengereman keras membantu bank mengatribusikan keausan rem/ban prematur ke penyalahgunaan pengemudi dan, jika diperlukan, memindahkan biaya.

Query SQL di bawah ini pertama-tama menghitung kecepatan dalam kilometer per jam dan selisih waktu antara titik data berurutan untuk setiap perangkat. Dengan informasi ini, query kemudian menghitung laju perlambatan dalam kilometer per jam per detik. Akhirnya, query memfilter dan mengembalikan rekaman di mana laju perlambatan adalah 20 km/h per detik atau lebih tinggi, yang menunjukkan kejadian perlambatan signifikan.

WITH spd AS (
  SELECT
    device_id,
    device_time,
    speed/100.0 AS kmh,
    LAG(speed/100.0) OVER (PARTITION BY device_id ORDER BY device_time) AS prev_kmh,
    EXTRACT(EPOCH FROM (device_time - LAG(device_time) OVER (PARTITION BY device_id ORDER BY device_time))) AS dt_sec
  DARI
    raw_telematics_data.tracking_data_core
  WHERE
    device_time BETWEEN '2025-07-24 00:00:00' AND '2025-07-24 23:59:59'
),
decels AS (
  SELECT
    device_id,
    device_time,
    (prev_kmh - kmh) / NULLIF(dt_sec, 0) AS decel_kmh_per_sec
  DARI
    spd
  WHERE
    prev_kmh IS NOT NULL
)
SELECT *
FROM decels
WHERE decel_kmh_per_sec >= 20;

Kejadian Akselerasi Keras

Akselerasi agresif meningkatkan keausan pada ban, transmisi, drivetrain, dan dudukan mesin. Mengidentifikasi kejadian ini mendukung pembinaan dan potensi pemulihan biaya.

Query SQL di bawah ini dirancang untuk mengidentifikasi kejadian akselerasi signifikan dari dataset data pelacakan. Pertama menghitung kecepatan dalam kilometer per jam dan selisih waktu antara titik data berurutan untuk setiap perangkat. Menggunakan informasi ini, query kemudian menghitung laju akselerasi dalam kilometer per jam per detik. Akhirnya, query memfilter dan mengembalikan rekaman di mana laju akselerasi memenuhi atau melebihi ambang yang ditentukan, menunjukkan kejadian akselerasi yang signifikan.

WITH spd AS (
  SELECT
    device_id,
    device_time,
    speed/100.0 AS kmh,
    LAG(speed/100.0) OVER (PARTITION BY device_id ORDER BY device_time) AS prev_kmh,
    EXTRACT(EPOCH FROM (device_time - LAG(device_time) OVER (PARTITION BY device_id ORDER BY device_time))) AS dt_sec
  DARI
    raw_telematics_data.tracking_data_core
  WHERE
    device_time BETWEEN '2025-07-28 00:00:00' AND '2025-07-28 23:59:59'
)
SELECT
  device_id,
  device_time,
  (kmh - prev_kmh) / NULLIF(dt_sec, 0) AS accel_kmh_per_sec
DARI
  spd
WHERE
  prev_kmh IS NOT NULL
  AND (kmh - prev_kmh) / NULLIF(dt_sec, 0) >= 20;

Tikungan / Belokan Mendadak

Tikungan tajam yang dikombinasikan dengan perubahan kecepatan mendadak menunjukkan mengemudi berisiko. Melacak perilaku semacam itu membantu mendeteksi penggunaan kendaraan yang tidak semestinya.

Query SQL ini dirancang untuk mengidentifikasi perubahan signifikan arah dan kecepatan dari data pelacakan selama periode waktu tertentu. Pertama, query mengonversi nilai lintang dan bujur mentah menjadi derajat desimal dan menghitung kecepatan dalam kilometer per jam. Menggunakan fungsi LAG, query mengambil data lokasi dan kecepatan sebelumnya untuk setiap perangkat, memungkinkan perhitungan perubahan dari waktu ke waktu. Query kemudian menghitung perubahan heading dalam derajat menggunakan fungsi trigonometri untuk menentukan bearing antara titik berurutan. Ia juga menghitung perubahan kecepatan antara titik-titik tersebut. Akhirnya, query memfilter hasil untuk hanya memasukkan rekaman di mana perubahan heading absolut adalah 10 derajat atau lebih dan perubahan kecepatan absolut adalah 5 km/h atau lebih, mengidentifikasi manuver atau kejadian signifikan dalam data pelacakan.

WITH pts AS (
  SELECT
    device_id,
    device_time,
    latitude/1e7::numeric AS lat,
    longitude/1e7::numeric AS lon,
    LAG(latitude/1e7::numeric) OVER (PARTITION BY device_id ORDER BY device_time) AS prev_lat,
    LAG(longitude/1e7::numeric) OVER (PARTITION BY device_id ORDER BY device_time) AS prev_lon,
    speed/100.0 AS kmh,
    LAG(speed/100.0) OVER (PARTITION BY device_id ORDER BY device_time) AS prev_kmh
  DARI
    raw_telematics_data.tracking_data_core
  WHERE
    device_time BETWEEN '2025-07-28 00:00:00' AND '2025-07-28 23:59:59'
),
bearing AS (
  SELECT *,
         atan2(
           sin(radians(lon-prev_lon))*cos(radians(lat)),
           cos(radians(prev_lat))*sin(radians(lat)) -
           sin(radians(prev_lat))*cos(radians(lat))*cos(radians(lon-prev_lon))
         ) * 180/pi() AS heading_change,
         (kmh - prev_kmh) AS delta_speed
  FROM pts
)
SELECT *
FROM bearing
WHERE abs(heading_change) >= 10
  AND abs(delta_speed) >= 5;

Deteksi Pengapian & Idle

Mengukur waktu idle (pengapian menyala, kecepatan rendah/tidak ada) membantu mengurangi pemborosan bahan bakar dan mengidentifikasi penyalahgunaan. Periode idling yang panjang harus dilaporkan dan dikelola.

WITH ign AS (  SELECT device_id,         device_time,         value::int AS ign_on  FROM raw_telematics_data.states  WHERE state_name = 'ignition'    AND device_time BETWEEN :from_ts AND :to_ts),spd AS (  SELECT device_id, device_time, speed/100.0 AS kmh  FROM raw_telematics_data.tracking_data_core  WHERE device_time BETWEEN :from_ts AND :to_ts),merged AS (  SELECT i.device_id,         i.device_time,         i.ign_on,         s.kmh,         LEAD(i.device_time) OVER (PARTITION BY i.device_id ORDER BY i.device_time) AS next_time  FROM ign i  LEFT JOIN spd s USING (device_id, device_time))SELECT device_id,       device_time AS idle_start,       next_time   AS idle_end,       EXTRACT(EPOCH FROM (next_time - device_time))/60 AS idle_minutesFROM mergedWHERE ign_on = 1 AND kmh < :idle_speed AND next_time - device_time >= INTERVAL ':idle_min minutes';

Last updated

Was this helpful?