Changes between Version 6 and Version 7 of AdvancedReports


Ignore:
Timestamp:
08/15/25 23:10:44 (2 months ago)
Author:
221071
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AdvancedReports

    v6 v7  
    44
    55
    6 === 1. Извештај за вкупни приходи на изнајмувачите на недвижности за нивните изнајмени единици како и просечен приход остварен по изнајмена единица во тековната година.
    7 {{{
    8 SELECT
    9     u.first_name,
    10     u.last_name,
    11     u.email,
    12     u.rating,
    13     lp.is_agent,
    14     COUNT(DISTINCT l.id) AS lease_count,
    15     COUNT(DISTINCT l.tenant_id) AS tenant_count,
    16     COALESCE(SUM(p.amount), 0) AS total_revenue,
    17     ROUND(
    18         CASE WHEN COUNT(DISTINCT l.id) > 0
    19              THEN COALESCE(SUM(p.amount), 0) / COUNT(DISTINCT l.id)
    20              ELSE 0
    21         END, 2
    22     ) AS avg_revenue_per_lease
    23 FROM LandlordProfile lp
    24 JOIN UserD u ON u.id = lp.id
    25 JOIN Lease l ON lp.id = l.landlord_id
    26 LEFT JOIN Payment p
    27     ON p.lease_id = l.id
    28     AND p.payment_date >= date_trunc('year', CURRENT_DATE)
    29 GROUP BY u.id, u.first_name, u.last_name, u.email, u.rating, lp.is_agent
    30 ORDER BY total_revenue DESC;
    31 }}}
    32 
    33 
    34 === 2. Извештај за перформансите на недвижностите по градови: број на имоти, број на издавачки единици, активни единици, остварени приходи за тековната година по град како и просечна кирија по изнајмувачка единица како и остварен приход по објект.
    35 
    36 {{{
    37 SELECT
    38     a.city,
    39     COUNT(DISTINCT p.id) as total_properties,
    40     COUNT(DISTINCT u.id) as total_units,
    41     COUNT(DISTINCT l.id) as active_leases,
    42     SUM(pay.amount) as total_revenue,
    43     ROUND(AVG(l.rent_amount),2) as avg_rent_per_lease,
    44     ROUND (SUM(pay.amount) / COUNT(DISTINCT p.id),2) as revenue_per_property
    45 FROM Address a
    46 JOIN Property p ON a.id = p.address_id
    47 JOIN Unit u ON p.id = u.property_id
    48 JOIN Listing lst ON u.id = lst.unit_id
    49 JOIN Lease l ON lst.id = l.listing_id
    50 JOIN Payment pay ON l.id = pay.lease_id
    51 WHERE EXTRACT(YEAR FROM pay.payment_date) = EXTRACT(YEAR FROM CURRENT_DATE)
    52     AND pay.status = 'завршено'
    53 GROUP BY a.city
    54 ORDER BY total_revenue DESC;
    55 }}}
    56 
    57 === 3. Извештај за процент на изнајмени недвижности во однос на објавени огласи за секоја година.
     6=== 1. Извештај за процент на изнајмени недвижности во однос на објавени огласи за секоја година.
    587{{{
    598WITH total_listings AS (
     
    8332
    8433
    85 === 4. Извештај за раст на приходи (извршени успешни плаќања за изнајмувања) за претходна и тековна година  за секој град изразена во проценти.
     34=== 2. Извештај за раст на приходи (извршени успешни плаќања за изнајмувања) за претходна и тековна година  за секој град изразена во проценти.
    8635{{{
    8736
     
    11665}}}
    11766
    118 === 5. Извештај за цени за изнајмување на недвижности (просечна, минимална, максимална и цена по метар квадратен) согласно категорија на објект, град, број на соби, големина на објект.
    119 {{{
    120 
    121 SELECT
    122     pt.name AS property_type,
    123     a.city,
    124     u.bedrooms,
     67=== 3. Детален месечен извештај за приходите, наплатата, останатиот долг, ненаплатените и активните изнајмувања и нерешените сервисни барања на изнајмувачите
     68
     69
     70{{{
     71WITH month_period AS (
     72    SELECT
     73        DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 month' AS month_start,
     74        (DATE_TRUNC('month', CURRENT_DATE) - INTERVAL '1 month') + INTERVAL '1 month - 1 day' AS month_end
     75),
     76landlords AS (
     77    SELECT lp.id AS landlord_id, u.first_name || ' ' || u.last_name AS landlord_name
     78    FROM domify.LandlordProfile lp
     79    JOIN domify.UserD u ON lp.id = u.id
     80),
     81total_due_cte AS (
     82    SELECT
     83        l.landlord_id,
     84        COALESCE(SUM(l.rent_amount), 0) AS total_due
     85    FROM domify.Lease l
     86    CROSS JOIN month_period mp
     87    WHERE l.start_date <= mp.month_end
     88      AND l.end_date >= mp.month_start
     89    GROUP BY l.landlord_id
     90),
     91total_paid_cte AS (
     92    SELECT
     93        l.landlord_id,
     94        COALESCE(SUM(p.amount), 0) AS total_paid
     95    FROM domify.Payment p
     96    JOIN domify.Lease l ON p.lease_id = l.id
     97    CROSS JOIN month_period mp
     98    WHERE p.payment_date BETWEEN mp.month_start AND mp.month_end
     99      AND p.status IN ('completed','paid')
     100    GROUP BY l.landlord_id
     101),
     102late_count_cte AS (
     103    SELECT
     104        l.landlord_id,
     105        COUNT(*) AS late_count
     106    FROM domify.Lease l
     107    CROSS JOIN month_period mp
     108    WHERE l.start_date <= mp.month_end
     109      AND l.end_date >= mp.month_start
     110      AND NOT EXISTS (
     111          SELECT 1
     112          FROM domify.Payment p
     113          WHERE p.lease_id = l.id
     114            AND p.payment_date BETWEEN mp.month_start AND mp.month_end
     115            AND p.status IN ('completed','paid')
     116      )
     117    GROUP BY l.landlord_id
     118),
     119active_leases_cte AS (
     120    SELECT
     121        l.landlord_id,
     122        COUNT(*) AS active_leases
     123    FROM domify.Lease l
     124    WHERE l.start_date <= CURRENT_DATE
     125      AND l.end_date >= CURRENT_DATE
     126    GROUP BY l.landlord_id
     127),
     128pending_services_cte AS (
     129    SELECT
     130        l.landlord_id,
     131        COUNT(*) AS pending_services
     132    FROM domify.ServiceRequest sr
     133    JOIN domify.Lease l ON sr.lease_id = l.id
     134    WHERE sr.status IN ('pending','in_progress')
     135    GROUP BY l.landlord_id
     136)
     137SELECT
     138    ld.landlord_id,
     139    ld.landlord_name,
     140    td.total_due,
     141    tp.total_paid,
     142    (td.total_due - tp.total_paid) AS remaining_debt,
     143    lc.late_count,
     144    al.active_leases,
     145    ps.pending_services
     146FROM landlords ld
     147CROSS JOIN month_period mp
     148LEFT JOIN total_due_cte td ON ld.landlord_id = td.landlord_id
     149LEFT JOIN total_paid_cte tp ON ld.landlord_id = tp.landlord_id
     150LEFT JOIN late_count_cte lc ON ld.landlord_id = lc.landlord_id
     151LEFT JOIN active_leases_cte al ON ld.landlord_id = al.landlord_id
     152LEFT JOIN pending_services_cte ps ON ld.landlord_id = ps.landlord_id
     153ORDER BY ld.landlord_name;
     154
     155}}}
     156=== 4. Детален извештај за историјата на плаќања, задоцнети и тековни обврски, просечна кирија и оценка на платежната дисциплина на изнајмувачите
     157{{{
     158WITH TenantPaymentStats AS (
     159    SELECT
     160        t.id as tenant_id,
     161        CONCAT(u.first_name, ' ', u.last_name) as tenant_name,
     162        u.rating as tenant_rating,
     163        COUNT(DISTINCT le.id) as total_leases,
     164        COUNT(DISTINCT pay.id) as total_payments,
     165        SUM(CASE WHEN pay.status = 'завршено' THEN pay.amount ELSE 0 END) as total_paid,
     166        SUM(CASE WHEN pay.status = 'доцнење' THEN pay.amount ELSE 0 END) as late_payments_amount,
     167        COUNT(CASE WHEN pay.status = 'доцнење' THEN 1 END) as late_payment_count,
     168        COUNT(CASE WHEN pay.status = 'во тек' THEN 1 END) as pending_payment_count,
     169        AVG(le.rent_amount) as avg_rent_amount,
     170        MIN(le.start_date) as first_lease_date,
     171        MAX(le.end_date) as latest_lease_end
     172    FROM TenantProfile t
     173    JOIN UserD u ON t.id = u.id
     174    LEFT JOIN Lease le ON t.id = le.tenant_id
     175    LEFT JOIN Payment pay ON le.id = pay.lease_id
     176    GROUP BY t.id, u.first_name, u.last_name, u.rating
     177)
     178SELECT
     179    tenant_id,
     180    tenant_name,
     181    tenant_rating,
     182    total_leases,
     183    total_payments,
     184    total_paid,
     185    late_payments_amount,
     186    late_payment_count,
     187    pending_payment_count,
     188    ROUND((late_payment_count * 100.0 / NULLIF(total_payments, 0)), 2) as late_payment_percentage,
     189    avg_rent_amount,
     190    first_lease_date,
     191    latest_lease_end,
    125192    CASE
    126         WHEN u.area_sq_m < 50 THEN 'Мала (<50м²)'
    127         WHEN u.area_sq_m < 80 THEN 'Средна (50-80м²)'
    128         ELSE 'Голема (>80м²)'
    129     END AS size_category,
    130     COUNT(l.id) AS lease_count,
    131     ROUND(AVG(l.rent_amount), 2) AS avg_rent,
    132     ROUND(MIN(l.rent_amount), 2) AS min_rent,
    133     ROUND(MAX(l.rent_amount), 2) AS max_rent,
    134     ROUND(AVG(l.rent_amount / u.area_sq_m), 2) AS price_per_sqm
    135 FROM Lease l
    136 JOIN Listing li ON l.listing_id = li.id
    137 JOIN Unit u ON li.unit_id = u.id
    138 JOIN Property p ON u.property_id = p.id
    139 JOIN PropertyType pt ON p.property_type_id = pt.id
    140 JOIN Address a ON p.address_id = a.id
    141 WHERE l.start_date >= CURRENT_DATE - INTERVAL '12 months'
    142 GROUP BY pt.name, a.city, u.bedrooms, size_category
    143 HAVING COUNT(l.id) >= 1
    144 ORDER BY a.city, pt.name, u.bedrooms;
    145 }}}
    146 
    147 === 6. Извештај за последната година за тоа колку просечно денови во секој месец огласите биле изложени пред да биде склучен договор за нив.
    148 {{{
    149 SELECT
    150     EXTRACT(YEAR FROM li.available_from) AS year,
    151     EXTRACT(MONTH FROM li.available_from) AS month,
    152     COUNT(*) AS total_listings,
    153     AVG(l.start_date - li.available_from) AS avg_days_on_market
    154 FROM Listing li
    155 JOIN Lease l ON li.id = l.listing_id
    156 WHERE li.available_from >= CURRENT_DATE - INTERVAL '365 days' AND l.start_date BETWEEN li.available_from AND li.available_to
    157 GROUP BY year, month
    158 ORDER BY year, month;
    159 }}}
    160 
    161 === 7. Извештај за број на барања за поправка/сервисирање на недвижност по град
    162 {{{
    163 SELECT
    164   a.city,
    165   COUNT(sr.id) AS request_count
    166 FROM ServiceRequest sr
    167 JOIN Lease l ON sr.lease_id = l.id
    168 JOIN Listing li ON l.listing_id = li.id
    169 JOIN Unit u ON li.unit_id = u.id
    170 JOIN Property p ON u.property_id = p.id
    171 JOIN Address a ON p.address_id = a.id
    172 WHERE EXTRACT(YEAR FROM sr.request_date) = EXTRACT(YEAR FROM CURRENT_DATE)
    173 GROUP BY a.city
    174 ORDER BY request_count DESC
    175 }}}
    176 
    177 === 8. Извештај за заинтересираност на изнајмувачи, издавачи со најмногу заинтересирани огласи сортирани по популарност
    178 
    179 {{{
    180 SELECT
    181     u.first_name,
    182     u.last_name,
    183     u.email,
    184     a.city,
    185     COUNT(DISTINCT li.id) AS total_listings,
    186     COUNT(i.tenant_profile_id) AS total_interested_tenants,
    187         ROUND(COUNT(i.tenant_profile_id) / COUNT(DISTINCT li.id), 2) AS avg_interest_per_listing
    188 FROM LandlordProfile lp
    189 JOIN UserD u ON lp.id = u.id
    190 JOIN Property p ON p.owner_id = u.id
    191 JOIN Unit un ON un.property_id = p.id
    192 JOIN Listing li ON li.unit_id = un.id
    193 JOIN Address a ON p.address_id = a.id
    194 LEFT JOIN Interested i ON li.id = i.listing_id
    195 WHERE li.available_from >= CURRENT_DATE - INTERVAL '12 months'
    196 GROUP BY u.id, u.first_name, u.last_name, u.email, a.city
    197 HAVING COUNT(i.tenant_profile_id) > 0
    198 ORDER BY total_interested_tenants DESC;
    199 }}}
     193        WHEN late_payment_count = 0 THEN 'Одличен'
     194        WHEN late_payment_count <= 2 THEN 'Добар'
     195        WHEN late_payment_count <= 5 THEN 'Среден'
     196        ELSE 'Ризичен'
     197    END as payment_reliability_score
     198FROM TenantPaymentStats
     199WHERE total_leases > 0
     200ORDER BY late_payment_percentage ASC, total_paid DESC;
     201
     202}}}
     203=== 5. Детален извештај за сервисни барања, стапка на завршување и просечно време на решавање по општина и град
     204{{{
     205WITH MaintenanceAnalysis AS (
     206    SELECT
     207        a.municipality,
     208        a.city,
     209        sc.name as service_category,
     210        COUNT(sr.id) as total_requests,
     211        COUNT(CASE WHEN sr.status = 'завршено' THEN 1 END) as completed_requests,
     212        COUNT(CASE WHEN sr.status = 'во тек' THEN 1 END) as in_progress_requests,
     213        COUNT(CASE WHEN sr.status = 'во очекување' THEN 1 END) as pending_requests,
     214        AVG(CASE
     215            WHEN sr.status = 'завршено' AND ml.maintenance_date IS NOT NULL
     216            THEN DATEDIFF(ml.maintenance_date, sr.request_date)
     217        END) as avg_resolution_days
     218    FROM ServiceRequest sr
     219    JOIN ServiceCategory sc ON sr.service_category_id = sc.id
     220    JOIN Lease le ON sr.lease_id = le.id
     221    JOIN Listing l ON le.listing_id = l.id
     222    JOIN Unit u ON l.unit_id = u.id
     223    JOIN Property p ON u.property_id = p.id
     224    JOIN Address a ON p.address_id = a.id
     225    LEFT JOIN MaintenanceLog ml ON sr.id = ml.service_request_id
     226    GROUP BY a.municipality, a.city, sc.name
     227)
     228SELECT
     229    municipality,
     230    city,
     231    service_category,
     232    total_requests,
     233    completed_requests,
     234    in_progress_requests,
     235    pending_requests,
     236    ROUND((completed_requests * 100.0 / NULLIF(total_requests, 0)), 2) as completion_rate_percent,
     237    ROUND(avg_resolution_days, 1) as avg_resolution_days,
     238    CASE
     239        WHEN avg_resolution_days <= 2 THEN 'Брзо'
     240        WHEN avg_resolution_days <= 5 THEN 'Средно'
     241        WHEN avg_resolution_days <= 10 THEN 'Бавно'
     242        ELSE 'Многу бавно'
     243    END as response_time_rating
     244FROM MaintenanceAnalysis
     245ORDER BY municipality, total_requests DESC;
     246
     247}}}
     248=== 6.Анализа на пазарни трендови и изнајмувачка понуда по општина, град и тип на недвижност
     249{{{
     250WITH MarketTrends AS (
     251    SELECT
     252        a.municipality,
     253        a.city,
     254        pt.name as property_type,
     255        COUNT(DISTINCT l.id) as total_listings,
     256        COUNT(DISTINCT CASE WHEN l.status = 'available' THEN l.id END) as available_listings,
     257        AVG(u.rent_amount) as avg_rent_asking,
     258        AVG(le.rent_amount) as avg_rent_actual,
     259        AVG(u.area_sq_m) as avg_unit_size,
     260        AVG(u.rent_amount / u.area_sq_m) as avg_rent_per_sq_m,
     261        MIN(u.rent_amount) as min_rent,
     262        MAX(u.rent_amount) as max_rent,
     263        COUNT(DISTINCT in_list.tenant_profile_id) as total_interested_tenants
     264    FROM Address a
     265    JOIN Property p ON a.id = p.address_id
     266    JOIN PropertyType pt ON p.property_type_id = pt.id
     267    JOIN Unit u ON p.id = u.property_id
     268    JOIN Listing l ON u.id = l.unit_id
     269    LEFT JOIN Lease le ON l.id = le.listing_id
     270    LEFT JOIN Interested in_list ON l.id = in_list.listing_id
     271    GROUP BY a.municipality, a.city, pt.name
     272)
     273SELECT
     274    municipality,
     275    city,
     276    property_type,
     277    total_listings,
     278    available_listings,
     279    ROUND((available_listings * 100.0 / NULLIF(total_listings, 0)), 2) as availability_rate,
     280    ROUND(avg_rent_asking, 2) as avg_rent_asking,
     281    ROUND(avg_rent_actual, 2) as avg_rent_actual,
     282    ROUND((avg_rent_actual - avg_rent_asking), 2) as rent_variance,
     283    ROUND(avg_unit_size, 1) as avg_unit_size_sq_m,
     284    ROUND(avg_rent_per_sq_m, 2) as avg_rent_per_sq_m,
     285    min_rent,
     286    max_rent,
     287    total_interested_tenants,
     288    ROUND(total_interested_tenants / NULLIF(available_listings, 0), 2) as interest_ratio,
     289    CASE
     290        WHEN availability_rate > 75 THEN 'Висока понуда'
     291        WHEN availability_rate > 50 THEN 'Умерена понуда'
     292        WHEN availability_rate > 25 THEN 'Ограничена понуда'
     293        ELSE 'Ниска Понуда'
     294    END as market_availability_status
     295FROM MarketTrends
     296WHERE total_listings > 0
     297ORDER BY municipality, avg_rent_per_sq_m DESC;
     298
     299}}}
     300
    200301== Историја
    201302* [[html(<a href="https://develop.finki.ukim.mk/projects/domify/wiki/ProcedureV1" style="color: red;">Верзија1</a>)]]