fuel-db: customer on every row, place and holder for site, licence tables
Draft migrations rewritten in place (PD-16, PD-18), with 0004 for the licence tables (PD-20) and rule tests in fuel-db/tests. Dashboards' column list regenerated; coverage_detail selects operator_uid. Checks: tests/run.sh 106 of 106; 18 views, 686 rows, 0 differences against a reference from the same corpus. Codex's fixes to its inspection are not re-inspected. Bands: persistence, Superset. Rules: 6, 8. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e4806f5799
commit
ab553526f6
11 files changed
+1197
-398
No files matched your search
@@ -18,16 +18,16 @@ SET LOCAL search_path = fm, pg_catalog, public;
|
||||
-- insufficient_evidence: none of the above (today: every site, since there is no runtime).
|
||||
CREATE VIEW fm.v_site_baseline_status AS
|
||||
WITH cur AS (
|
||||
SELECT DISTINCT ON (b.site_uid) b.*
|
||||
SELECT DISTINCT ON (b.holder_uid) b.*
|
||||
FROM fm.baseline_version b
|
||||
WHERE b.status IN ('approved','proposed')
|
||||
AND b.metric IN ('measured_generator_l_per_h','apparent_l_per_generator_h',
|
||||
'apparent_l_per_set_h','apparent_l_per_site_dg_h') -- never modelled, never per-day
|
||||
ORDER BY b.site_uid, (b.status = 'approved') DESC, b.approved_on DESC NULLS LAST, b.computed_at DESC),
|
||||
ORDER BY b.holder_uid, (b.status = 'approved') DESC, b.approved_on DESC NULLS LAST, b.computed_at DESC),
|
||||
ev AS (
|
||||
SELECT site_uid, count(*) FILTER (WHERE eligibility <> 'excluded') AS n_usable
|
||||
FROM fm.v_lph_interval GROUP BY site_uid)
|
||||
SELECT s.site_uid,
|
||||
SELECT holder_uid, count(*) FILTER (WHERE eligibility <> 'excluded') AS n_usable
|
||||
FROM fm.v_lph_interval GROUP BY holder_uid)
|
||||
SELECT s.holder_uid,
|
||||
CASE WHEN cur.status = 'approved' THEN 'approved'
|
||||
WHEN cur.status = 'proposed' AND cur.meets_policy AND val.inputs_unchanged THEN 'eligible'
|
||||
WHEN cur.status = 'proposed' OR coalesce(ev.n_usable, 0) > 0 THEN 'provisional'
|
||||
@@ -42,37 +42,45 @@ SELECT s.site_uid,
|
||||
cur.metric AS lph_metric, cur.population, cur.window_start AS lph_window_start,
|
||||
cur.window_end AS lph_window_end, cur.conditions, cur.decision_ref,
|
||||
coalesce(ev.n_usable, 0) AS n_usable_intervals
|
||||
FROM fm.site s LEFT JOIN cur USING (site_uid) LEFT JOIN ev USING (site_uid)
|
||||
FROM fm.holder s LEFT JOIN cur USING (holder_uid) LEFT JOIN ev USING (holder_uid)
|
||||
LEFT JOIN fm.v_baseline_validity val ON val.baseline_id = cur.baseline_id;
|
||||
|
||||
-- One row per site, every status: the map dataset and the single source of site-level fields.
|
||||
-- "Current" means the period that contains today's date in Kabul, not "no end date".
|
||||
-- One row per holder, every status: the map dataset and the single source of site-level fields.
|
||||
-- Public column names stay site_* (a telecom site is a place with one fixed holder); internal fm uses
|
||||
-- holder and place. "Current" means the period that contains today in the holder's local time.
|
||||
CREATE VIEW public.v_site AS
|
||||
WITH today AS (SELECT (now() AT TIME ZONE 'Asia/Kabul')::date AS d),
|
||||
alias AS ( -- v1: the operator is ATOMA; later: the site's current operator
|
||||
SELECT a.site_uid, a.label FROM fm.site_alias a, today
|
||||
WHERE a.issuer = 'ATOMA' AND a.is_primary
|
||||
AND daterange(coalesce(a.valid_from, '-infinity'::date), a.valid_to, '[)') @> today.d),
|
||||
pp AS ( -- one programme, chosen explicitly
|
||||
SELECT p.site_uid, p.status FROM fm.pilot_participation p, today
|
||||
WHERE p.programme = 'ATOMA OFMS pilot' AND daterange(p.valid_from, p.valid_to, '[)') @> today.d),
|
||||
-- alias and pp are at most one row per site: the exclusion constraints forbid overlapping primary
|
||||
-- labels per (site, issuer) and overlapping periods per (site, programme).
|
||||
loc AS (SELECT site_uid, latitude, longitude, basis, precision_m FROM fm.site_location WHERE acceptance = 'accepted'),
|
||||
loc_any AS (SELECT site_uid, bool_or(acceptance = 'pending') AS has_pending FROM fm.site_location GROUP BY site_uid),
|
||||
cal AS (SELECT site_uid, sum(consumed_l) AS fuel_l, sum(days) AS days
|
||||
FROM fm.v_stock_interval WHERE stock_status = 'ok' GROUP BY site_uid),
|
||||
latest AS (SELECT site_uid, max(visit_on) AS latest_record_on -- live records only: a fully
|
||||
FROM fm.v_visit_live GROUP BY site_uid) -- retracted visit does not count
|
||||
SELECT s.site_uid::varchar(12) AS site_uid,
|
||||
coalesce(alias.label, s.site_uid)::varchar(20) AS site_code,
|
||||
WITH alias AS ( -- the label the customer's people use
|
||||
SELECT a.holder_uid, a.label FROM fm.holder_alias a
|
||||
JOIN fm.v_holder_current z ON z.holder_uid = a.holder_uid
|
||||
JOIN fm.operator o ON o.operator_uid = z.operator_uid
|
||||
WHERE a.issuer = o.label_issuer AND a.is_primary
|
||||
AND daterange(coalesce(a.valid_from, '-infinity'::date), a.valid_to, '[)') @> z.today),
|
||||
pp AS ( -- the customer's one programme
|
||||
SELECT p.holder_uid, p.status FROM fm.participation p
|
||||
JOIN fm.v_holder_current z ON z.holder_uid = p.holder_uid
|
||||
JOIN fm.operator o ON o.operator_uid = z.operator_uid
|
||||
WHERE p.programme = o.programme AND daterange(p.valid_from, p.valid_to, '[)') @> z.today),
|
||||
-- alias and pp are at most one row per holder: the exclusion constraints forbid overlapping primary
|
||||
-- labels per (holder, issuer) and overlapping periods per (holder, programme).
|
||||
loc AS (SELECT z.holder_uid, l.latitude, l.longitude, l.basis, l.precision_m
|
||||
FROM fm.place_location l JOIN fm.v_holder_current z ON z.place_uid = l.place_uid
|
||||
WHERE l.acceptance = 'accepted'),
|
||||
loc_any AS (SELECT z.holder_uid, bool_or(l.acceptance = 'pending') AS has_pending
|
||||
FROM fm.place_location l JOIN fm.v_holder_current z ON z.place_uid = l.place_uid GROUP BY z.holder_uid),
|
||||
cal AS (SELECT holder_uid, sum(consumed_l) AS fuel_l, sum(days) AS days
|
||||
FROM fm.v_stock_interval WHERE stock_status = 'ok' GROUP BY holder_uid),
|
||||
latest AS (SELECT holder_uid, max(visit_on) AS latest_record_on -- live records only: a fully
|
||||
FROM fm.v_visit_live GROUP BY holder_uid) -- retracted visit does not count
|
||||
SELECT s.holder_uid::varchar(12) AS site_uid,
|
||||
coalesce(alias.label, s.holder_uid)::varchar(20) AS site_code,
|
||||
coalesce(s.name, 'name not recorded')::varchar(120) AS site_name,
|
||||
(coalesce(alias.label, s.site_uid) || ' - ' || coalesce(s.name, 'name not recorded')
|
||||
|| ' - ' || s.site_uid)::varchar(170) AS site_label, -- the one filter value
|
||||
s.zone::varchar(40) AS zone, s.province::varchar(40) AS province, s.district::varchar(60) AS district,
|
||||
(coalesce(alias.label, s.holder_uid) || ' - ' || coalesce(s.name, 'name not recorded')
|
||||
|| ' - ' || s.holder_uid)::varchar(170) AS site_label, -- the one filter value
|
||||
s.operator_uid::varchar(12) AS operator_uid,
|
||||
pl.zone::varchar(40) AS zone, pl.province::varchar(40) AS province, pl.district::varchar(60) AS district,
|
||||
coalesce(pp.status, 'none')::varchar(12) AS pilot_status,
|
||||
loc.latitude::numeric(9,6) AS latitude, loc.longitude::numeric(9,6) AS longitude, -- NULL unless accepted
|
||||
(CASE WHEN loc.site_uid IS NOT NULL THEN 'accepted'
|
||||
(CASE WHEN loc.holder_uid IS NOT NULL THEN 'accepted'
|
||||
WHEN loc_any.has_pending THEN 'awaiting acceptance' ELSE 'missing' END)::varchar(20) AS location_status,
|
||||
loc.basis::varchar(20) AS location_basis, loc.precision_m::integer AS location_precision_m,
|
||||
bs.baseline_status::varchar(24) AS baseline_status,
|
||||
@@ -91,19 +99,22 @@ SELECT s.site_uid::varchar(12) AS site_ui
|
||||
bs.decision_ref::varchar(12) AS baseline_decision_ref,
|
||||
round(cal.fuel_l / NULLIF(cal.days, 0), 1)::numeric(7,1) AS fuel_l_per_calendar_day,
|
||||
latest.latest_record_on
|
||||
FROM fm.site s
|
||||
LEFT JOIN alias USING (site_uid) LEFT JOIN loc USING (site_uid) LEFT JOIN loc_any USING (site_uid)
|
||||
LEFT JOIN pp USING (site_uid) LEFT JOIN fm.v_site_baseline_status bs USING (site_uid)
|
||||
LEFT JOIN cal USING (site_uid) LEFT JOIN latest USING (site_uid);
|
||||
FROM fm.holder s
|
||||
JOIN fm.v_holder_current z ON z.holder_uid = s.holder_uid
|
||||
LEFT JOIN fm.place pl ON pl.place_uid = z.place_uid
|
||||
LEFT JOIN alias ON alias.holder_uid = s.holder_uid LEFT JOIN loc ON loc.holder_uid = s.holder_uid
|
||||
LEFT JOIN loc_any ON loc_any.holder_uid = s.holder_uid LEFT JOIN pp ON pp.holder_uid = s.holder_uid
|
||||
LEFT JOIN fm.v_site_baseline_status bs ON bs.holder_uid = s.holder_uid
|
||||
LEFT JOIN cal ON cal.holder_uid = s.holder_uid LEFT JOIN latest ON latest.holder_uid = s.holder_uid;
|
||||
|
||||
-- Every view below joins public.v_site for site_uid, site_code, site_name and site_label, so one
|
||||
-- Every view below joins public.v_site for site_uid, site_code, site_name, site_label and operator_uid, so one
|
||||
-- Site filter drives every dataset, and casts to plain types (varchar(n), integer,
|
||||
-- numeric(p,s), date, timestamp(0), boolean). Live = asserted, reviewed or disputed.
|
||||
|
||||
-- S2, R3: one row per site and measure; the rows stay when a value is not established.
|
||||
CREATE VIEW public.v_kpi_measures AS
|
||||
WITH cur AS ( -- the site's L/h version; its snapshot only while approved or its inputs unchanged
|
||||
SELECT bs.site_uid, b.baseline_id, b.code, b.fuel_l, b.runtime_h, b.matched_days, b.window_start, b.window_end,
|
||||
SELECT bs.holder_uid, b.baseline_id, b.code, b.fuel_l, b.runtime_h, b.matched_days, b.window_start, b.window_end,
|
||||
(b.status = 'approved' OR coalesce(val.inputs_unchanged, false)) AS shown,
|
||||
' (' || b.status || ')'
|
||||
|| CASE WHEN coalesce(val.inputs_unchanged, false) THEN ''
|
||||
@@ -112,35 +123,35 @@ WITH cur AS ( -- the site's L/h version; its snapshot only while
|
||||
FROM fm.v_site_baseline_status bs JOIN fm.baseline_version b ON b.code = bs.baseline_code
|
||||
LEFT JOIN fm.v_baseline_validity val ON val.baseline_id = b.baseline_id),
|
||||
ninp AS (SELECT baseline_id, count(*) FILTER (WHERE included) AS n FROM fm.baseline_input GROUP BY baseline_id),
|
||||
m4 AS (SELECT site_uid, sum(consumed_l) AS fuel_l, sum(days) AS days, min(start_on) AS first_on, max(end_on) AS last_on
|
||||
FROM fm.v_m4_interval WHERE eligibility = 'eligible' GROUP BY site_uid),
|
||||
span AS (SELECT site_uid, min(visit_on) AS first_on, max(visit_on) AS last_on FROM fm.v_visit_live GROUP BY site_uid),
|
||||
del AS (SELECT v.site_uid, count(*) AS n FROM fm.v_movement_event e JOIN fm.v_visit_live v ON v.visit_id = e.visit_id
|
||||
WHERE e.kind = 'delivery' GROUP BY v.site_uid),
|
||||
rdg AS (SELECT m.site_uid, count(*) AS n FROM fm.hour_meter_reading h JOIN fm.runtime_meter m ON m.meter_id = h.meter_id
|
||||
WHERE h.claim_status IN ('asserted','reviewed','disputed') GROUP BY m.site_uid),
|
||||
kwh AS (SELECT site_uid, sum(kwh) AS kwh, count(kwh) AS n_kwh, min(bill_month) AS first_m, max(bill_month) AS last_m
|
||||
FROM fm.electricity_bill WHERE claim_status IN ('asserted','reviewed') GROUP BY site_uid), -- values never from disputed
|
||||
m4 AS (SELECT holder_uid, sum(consumed_l) AS fuel_l, sum(days) AS days, min(start_on) AS first_on, max(end_on) AS last_on
|
||||
FROM fm.v_m4_interval WHERE eligibility = 'eligible' GROUP BY holder_uid),
|
||||
span AS (SELECT holder_uid, min(visit_on) AS first_on, max(visit_on) AS last_on FROM fm.v_visit_live GROUP BY holder_uid),
|
||||
del AS (SELECT v.holder_uid, count(*) AS n FROM fm.v_movement_event e JOIN fm.v_visit_live v ON v.visit_id = e.visit_id
|
||||
WHERE e.kind = 'delivery' GROUP BY v.holder_uid),
|
||||
rdg AS (SELECT m.holder_uid, count(*) AS n FROM fm.hour_meter_reading h JOIN fm.runtime_meter m ON m.meter_id = h.meter_id
|
||||
WHERE h.claim_status IN ('asserted','reviewed','disputed') GROUP BY m.holder_uid),
|
||||
kwh AS (SELECT holder_uid, sum(kwh) AS kwh, count(kwh) AS n_kwh, min(bill_month) AS first_m, max(bill_month) AS last_m
|
||||
FROM fm.electricity_bill WHERE claim_status IN ('asserted','reviewed') GROUP BY holder_uid), -- values never from disputed
|
||||
lday AS ( -- the L/day reference: the latest approved, else proposed, L/day version
|
||||
SELECT DISTINCT ON (b.site_uid) b.site_uid, b.code, b.status, b.value, b.window_start, b.window_end,
|
||||
SELECT DISTINCT ON (b.holder_uid) b.holder_uid, b.code, b.status, b.value, b.window_start, b.window_end,
|
||||
coalesce(val.inputs_unchanged, false) AS inputs_unchanged
|
||||
FROM fm.baseline_version b LEFT JOIN fm.v_baseline_validity val ON val.baseline_id = b.baseline_id
|
||||
WHERE b.metric = 'fuel_l_per_calendar_day' AND b.status IN ('approved','proposed')
|
||||
ORDER BY b.site_uid, (b.status = 'approved') DESC, b.approved_on DESC NULLS LAST, b.computed_at DESC)
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
ORDER BY b.holder_uid, (b.status = 'approved') DESC, b.approved_on DESC NULLS LAST, b.computed_at DESC)
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
x.ord::integer AS measure_order, x.measure::varchar(60) AS measure,
|
||||
round(x.value, 2)::numeric(12,2) AS value, x.unit::varchar(12) AS unit,
|
||||
(CASE WHEN x.value IS NULL THEN 'not established' ELSE x.kind END)::varchar(16) AS value_kind,
|
||||
x.window_start, x.window_end, x.note::varchar(200) AS note
|
||||
FROM public.v_site s
|
||||
LEFT JOIN cur ON cur.site_uid = s.site_uid
|
||||
LEFT JOIN cur ON cur.holder_uid = s.site_uid
|
||||
LEFT JOIN ninp ON ninp.baseline_id = cur.baseline_id
|
||||
LEFT JOIN m4 ON m4.site_uid = s.site_uid
|
||||
LEFT JOIN span ON span.site_uid = s.site_uid
|
||||
LEFT JOIN del ON del.site_uid = s.site_uid
|
||||
LEFT JOIN rdg ON rdg.site_uid = s.site_uid
|
||||
LEFT JOIN kwh ON kwh.site_uid = s.site_uid
|
||||
LEFT JOIN lday ON lday.site_uid = s.site_uid
|
||||
LEFT JOIN m4 ON m4.holder_uid = s.site_uid
|
||||
LEFT JOIN span ON span.holder_uid = s.site_uid
|
||||
LEFT JOIN del ON del.holder_uid = s.site_uid
|
||||
LEFT JOIN rdg ON rdg.holder_uid = s.site_uid
|
||||
LEFT JOIN kwh ON kwh.holder_uid = s.site_uid
|
||||
LEFT JOIN lday ON lday.holder_uid = s.site_uid
|
||||
CROSS JOIN LATERAL (VALUES
|
||||
(1, 'Matched fuel', CASE WHEN cur.shown THEN cur.fuel_l END, 'L', 'calculated', cur.window_start, cur.window_end,
|
||||
'fuel used in the intervals of L/h baseline version ' || cur.code || cur.state),
|
||||
@@ -175,7 +186,7 @@ CROSS JOIN LATERAL (VALUES
|
||||
|
||||
-- R2: timer readings as recorded (no rows in v1).
|
||||
CREATE VIEW public.v_hour_meter_evidence AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
m.source_label::varchar(40) AS meter_label,
|
||||
(CASE WHEN m.asset_uid IS NULL THEN 'unmapped'
|
||||
ELSE m.asset_uid || ' (' || m.mapping_status || ')' END)::varchar(60) AS mapped_set,
|
||||
@@ -186,13 +197,13 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
FROM fm.hour_meter_reading h
|
||||
JOIN fm.runtime_meter m ON m.meter_id = h.meter_id
|
||||
JOIN fm.visit v ON v.visit_id = h.visit_id
|
||||
JOIN public.v_site s ON s.site_uid = m.site_uid
|
||||
JOIN public.v_site s ON s.site_uid = m.holder_uid
|
||||
LEFT JOIN fm.meter_epoch e ON e.epoch_id = h.epoch_id
|
||||
WHERE h.claim_status IN ('asserted','reviewed','disputed');
|
||||
|
||||
-- B5: assumption versions in force or proposed; a coverage assumption lists its members.
|
||||
CREATE VIEW public.v_assumption AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
x.code::varchar(60) AS code, x.topic::varchar(30) AS topic, x.asset_uid::varchar(40) AS asset_uid,
|
||||
x.value_num::numeric(10,3) AS value, x.low_num::numeric(10,3) AS value_low,
|
||||
x.high_num::numeric(10,3) AS value_high, x.unit::varchar(20) AS unit,
|
||||
@@ -201,7 +212,7 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
x.rationale::varchar(400) AS rationale, x.contradicted_by::varchar(200) AS contradicted_by,
|
||||
mem.members::varchar(400) AS members
|
||||
FROM fm.assumption x
|
||||
JOIN public.v_site s ON s.site_uid = x.site_uid
|
||||
JOIN public.v_site s ON s.site_uid = x.holder_uid
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT string_agg(m.member_role || ': ' || coalesce(m.meter_id, m.asset_uid), '; '
|
||||
ORDER BY m.member_role, coalesce(m.meter_id, m.asset_uid)) AS members
|
||||
@@ -210,7 +221,7 @@ WHERE x.status <> 'superseded';
|
||||
|
||||
-- B1: baseline versions, with whether their inputs are unchanged today.
|
||||
CREATE VIEW public.v_baseline_version AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
b.code::varchar(60) AS code, b.metric::varchar(40) AS metric, b.status::varchar(12) AS status,
|
||||
b.population::varchar(200) AS population,
|
||||
round(b.value, 3)::numeric(8,3) AS value, round(b.range_low, 3)::numeric(8,3) AS range_low,
|
||||
@@ -222,14 +233,15 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
b.evidence_grade::varchar(2) AS evidence_grade, b.conditions::varchar(200) AS conditions,
|
||||
b.season_note::varchar(200) AS season_note, b.approved_on, b.approved_by_role::varchar(40) AS approved_by_role,
|
||||
b.decision_ref::varchar(12) AS decision_ref, coalesce(val.inputs_unchanged, false) AS inputs_unchanged,
|
||||
(b.computed_at AT TIME ZONE 'Asia/Kabul')::timestamp(0) AS computed_at
|
||||
(b.computed_at AT TIME ZONE z.timezone)::timestamp(0) AS computed_at
|
||||
FROM fm.baseline_version b
|
||||
JOIN public.v_site s ON s.site_uid = b.site_uid
|
||||
JOIN public.v_site s ON s.site_uid = b.holder_uid
|
||||
JOIN fm.v_holder_current z ON z.holder_uid = b.holder_uid
|
||||
LEFT JOIN fm.v_baseline_validity val ON val.baseline_id = b.baseline_id;
|
||||
|
||||
-- B2: the inputs of each version, with dependency drift since computation.
|
||||
CREATE VIEW public.v_baseline_input AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
b.code::varchar(60) AS baseline_code, b.status::varchar(12) AS baseline_status,
|
||||
(to_char(bi.start_on, 'YYYY-MM-DD') || ' to ' || to_char(bi.end_on, 'YYYY-MM-DD'))::varchar(30) AS interval_label,
|
||||
bi.start_on, bi.end_on, bi.included, bi.exclusion_reason::varchar(300) AS exclusion_reason,
|
||||
@@ -241,42 +253,42 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
AND d.runtime_dep_sha256 IS DISTINCT FROM bi.runtime_dep_sha256)) AS dependencies_changed
|
||||
FROM fm.baseline_input bi
|
||||
JOIN fm.baseline_version b ON b.baseline_id = bi.baseline_id
|
||||
JOIN public.v_site s ON s.site_uid = bi.site_uid
|
||||
JOIN public.v_site s ON s.site_uid = bi.holder_uid
|
||||
LEFT JOIN fm.v_interval_dependency d ON d.open_visit_id = bi.open_visit_id AND d.close_visit_id = bi.close_visit_id;
|
||||
|
||||
-- B7: documents the site's figures rest on (the document itself is never served).
|
||||
CREATE VIEW public.v_evidence AS
|
||||
WITH cites AS (
|
||||
SELECT site_uid, source_sha256, 'fuel movement' AS record_type
|
||||
SELECT holder_uid, source_sha256, 'fuel movement' AS record_type
|
||||
FROM fm.fuel_movement WHERE claim_status IN ('asserted','reviewed','disputed')
|
||||
UNION SELECT site_uid, source_sha256, 'stock reading'
|
||||
UNION SELECT holder_uid, source_sha256, 'stock reading'
|
||||
FROM fm.stock_observation WHERE claim_status IN ('asserted','reviewed','disputed')
|
||||
UNION SELECT m.site_uid, h.source_sha256, 'timer reading'
|
||||
UNION SELECT m.holder_uid, h.source_sha256, 'timer reading'
|
||||
FROM fm.hour_meter_reading h JOIN fm.runtime_meter m ON m.meter_id = h.meter_id
|
||||
WHERE h.claim_status IN ('asserted','reviewed','disputed')
|
||||
UNION SELECT site_uid, source_sha256, 'electricity bill'
|
||||
UNION SELECT holder_uid, source_sha256, 'electricity bill'
|
||||
FROM fm.electricity_bill WHERE claim_status IN ('asserted','reviewed','disputed')
|
||||
UNION SELECT site_uid, source_sha256, 'imported calculation'
|
||||
FROM fm.imported_calculation WHERE site_uid IS NOT NULL AND claim_status IN ('asserted','reviewed','disputed')
|
||||
UNION SELECT p.site_uid, e.source_sha256, 'equipment specification'
|
||||
UNION SELECT holder_uid, source_sha256, 'imported calculation'
|
||||
FROM fm.imported_calculation WHERE holder_uid IS NOT NULL AND claim_status IN ('asserted','reviewed','disputed')
|
||||
UNION SELECT p.holder_uid, e.source_sha256, 'equipment specification'
|
||||
FROM fm.equipment_spec e JOIN fm.asset_placement p ON p.asset_uid = e.asset_uid
|
||||
WHERE e.source_sha256 IS NOT NULL AND e.claim_status IN ('asserted','reviewed','disputed')
|
||||
UNION SELECT site_uid, source_sha256, 'assumption'
|
||||
UNION SELECT holder_uid, source_sha256, 'assumption'
|
||||
FROM fm.assumption WHERE source_sha256 IS NOT NULL AND status <> 'superseded')
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
left(d.sha256, 16)::varchar(16) AS document_key, d.title::varchar(200) AS title,
|
||||
d.kind::varchar(20) AS kind, d.issuer::varchar(80) AS issuer, d.document_date,
|
||||
string_agg(c.record_type, ', ' ORDER BY c.record_type)::varchar(200) AS used_for,
|
||||
d.contains_personal_data
|
||||
FROM cites c
|
||||
JOIN fm.source_document d ON d.sha256 = c.source_sha256
|
||||
JOIN public.v_site s ON s.site_uid = c.site_uid
|
||||
GROUP BY s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
JOIN public.v_site s ON s.site_uid = c.holder_uid
|
||||
GROUP BY s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
d.sha256, d.title, d.kind, d.issuer, d.document_date, d.contains_personal_data;
|
||||
|
||||
-- F1, F4: one row per delivery event; quantity NULL = not recorded. No monthly sums.
|
||||
CREATE VIEW public.v_delivery AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
e.event_key::varchar(80) AS event_key, v.visit_on AS delivery_date, v.seq_in_day::integer AS seq_in_day,
|
||||
round(e.litres, 1)::numeric(8,1) AS delivered_l,
|
||||
b.unit_price::numeric(8,2) AS unit_price, b.price_currency::varchar(8) AS currency,
|
||||
@@ -284,19 +296,19 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
e.n_claims::integer AS n_sources, (e.spread_l > 0) AS sources_disagree, e.all_reviewed AS reviewed
|
||||
FROM fm.v_movement_event e
|
||||
JOIN fm.v_visit_live v ON v.visit_id = e.visit_id
|
||||
JOIN public.v_site s ON s.site_uid = v.site_uid
|
||||
JOIN public.v_site s ON s.site_uid = v.holder_uid
|
||||
CROSS JOIN LATERAL ( -- price and reference of the best-ranked claim;
|
||||
-- a disputed claim gives the reference only, never a price
|
||||
SELECT CASE WHEN m.claim_status <> 'disputed' THEN m.unit_price END AS unit_price,
|
||||
CASE WHEN m.claim_status <> 'disputed' THEN m.price_currency END AS price_currency, m.record_ref
|
||||
FROM fm.fuel_movement m JOIN fm.v_source_rank r ON r.sha256 = m.source_sha256
|
||||
WHERE m.event_key = e.event_key AND m.claim_status IN ('asserted','reviewed','disputed')
|
||||
WHERE m.visit_id = e.visit_id AND m.event_key = e.event_key AND m.claim_status IN ('asserted','reviewed','disputed')
|
||||
ORDER BY (m.claim_status = 'disputed'), r.rank, m.movement_id LIMIT 1) b
|
||||
WHERE e.kind = 'delivery';
|
||||
|
||||
-- F2: stock readings as recorded, plus after-delivery points derived as before + delivered.
|
||||
CREATE VIEW public.v_stock_reading AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
v.visit_on AS observed_on, v.seq_in_day::integer AS seq_in_day,
|
||||
(CASE st.phase WHEN 'before_delivery' THEN 'before delivery' WHEN 'after_delivery' THEN 'after delivery'
|
||||
ELSE 'stock check' END)::varchar(20) AS reading_type,
|
||||
@@ -304,20 +316,20 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
round(st.spread_l, 1)::numeric(8,1) AS spread_l, st.all_reviewed AS reviewed
|
||||
FROM fm.v_visit_stock st
|
||||
JOIN fm.v_visit_live v ON v.visit_id = st.visit_id
|
||||
JOIN public.v_site s ON s.site_uid = v.site_uid
|
||||
JOIN public.v_site s ON s.site_uid = v.holder_uid
|
||||
UNION ALL
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
p.visit_on, p.seq_in_day::integer, 'after delivery'::varchar(20),
|
||||
round(p.depart_l, 1)::numeric(8,1), 'calculated'::varchar(12),
|
||||
round(p.depart_spread_l, 1)::numeric(8,1), p.depart_reviewed
|
||||
FROM fm.v_stock_point p
|
||||
JOIN public.v_site s ON s.site_uid = p.site_uid
|
||||
JOIN public.v_site s ON s.site_uid = p.holder_uid
|
||||
WHERE p.depart_basis = 'derived';
|
||||
|
||||
-- F3, F4, B3, B4: one row per stock interval, with its L/h evaluation. The approved baseline is set
|
||||
-- beside an interval only when both have the same metric and population (B4 compares like with like).
|
||||
CREATE VIEW public.v_interval AS
|
||||
WITH cur AS (SELECT bs.site_uid, bs.baseline_code, bs.baseline_status, bs.lph_estimate, b.metric, b.population_key
|
||||
WITH cur AS (SELECT bs.holder_uid, bs.baseline_code, bs.baseline_status, bs.lph_estimate, b.metric, b.population_key
|
||||
FROM fm.v_site_baseline_status bs LEFT JOIN fm.baseline_version b ON b.code = bs.baseline_code),
|
||||
inb AS ( -- the inputs of each site's KPI version
|
||||
SELECT bi.open_visit_id, bi.close_visit_id, bi.included
|
||||
@@ -327,12 +339,12 @@ inb AS ( -- the inputs of each site's KPI vers
|
||||
cond AS ( -- assumptions a valid interval depends on
|
||||
SELECT l.interval_key, string_agg(DISTINCT x.code, ', ') AS codes
|
||||
FROM fm.v_lph_interval l
|
||||
JOIN fm.assumption x ON x.site_uid = l.site_uid AND x.status IN ('proposed','accepted')
|
||||
JOIN fm.assumption x ON x.holder_uid = l.holder_uid AND x.status IN ('proposed','accepted')
|
||||
AND x.topic IN ('generator_idle','meter_coverage')
|
||||
AND daterange(x.applies_from, x.applies_to, '[]') @> daterange(l.start_on, l.end_on, '[]')
|
||||
WHERE l.population_valid
|
||||
GROUP BY l.interval_key)
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
(to_char(l.start_on, 'YYYY-MM-DD') || ' to ' || to_char(l.end_on, 'YYYY-MM-DD'))::varchar(30) AS interval_label,
|
||||
l.start_on, l.end_on, l.days::integer AS days,
|
||||
round(l.opening_l, 1)::numeric(9,1) AS opening_l, l.opening_basis::varchar(8) AS opening_basis,
|
||||
@@ -357,15 +369,15 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
AND l.population_key = cur.population_key
|
||||
THEN cur.lph_estimate END)::numeric(8,3) AS current_baseline_l_per_h
|
||||
FROM fm.v_lph_interval l
|
||||
JOIN public.v_site s ON s.site_uid = l.site_uid
|
||||
JOIN cur ON cur.site_uid = l.site_uid
|
||||
JOIN public.v_site s ON s.site_uid = l.holder_uid
|
||||
JOIN cur ON cur.holder_uid = l.holder_uid
|
||||
LEFT JOIN inb ON inb.open_visit_id = l.open_visit_id AND inb.close_visit_id = l.close_visit_id
|
||||
LEFT JOIN cond ON cond.interval_key = l.interval_key;
|
||||
|
||||
-- R1: hours per day by meter interval (no rows in v1). Every pair is listed with its flags; runtime
|
||||
-- and h/day only for a valid pair (one epoch, not decreasing, at most 24 h per day).
|
||||
CREATE VIEW public.v_runtime AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
m.source_label::varchar(40) AS meter_label,
|
||||
(CASE WHEN m.asset_uid IS NULL THEN 'unmapped'
|
||||
ELSE m.asset_uid || ' (' || m.mapping_status || ')' END)::varchar(60) AS mapped_set,
|
||||
@@ -378,55 +390,56 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
FROM fm.v_runtime_pair r
|
||||
CROSS JOIN LATERAL (SELECT coalesce(r.same_epoch AND r.monotonic AND NOT r.over_24h_per_day, false) AS pair_valid) v
|
||||
JOIN fm.runtime_meter m ON m.meter_id = r.meter_id
|
||||
JOIN public.v_site s ON s.site_uid = r.site_uid;
|
||||
JOIN public.v_site s ON s.site_uid = r.holder_uid;
|
||||
|
||||
-- S3 (Gantt): which periods each kind of evidence covers; Kabul midnight as timestamp(0).
|
||||
-- S3 (Gantt): which periods each kind of evidence covers; local midnight as timestamp(0).
|
||||
CREATE VIEW public.v_coverage AS
|
||||
WITH spans AS (
|
||||
SELECT site_uid, '1 Stock intervals' AS lane, stock_status AS status, start_on, end_on
|
||||
SELECT holder_uid, '1 Stock intervals' AS lane, stock_status AS status, start_on, end_on
|
||||
FROM fm.v_stock_interval
|
||||
UNION ALL
|
||||
SELECT r.site_uid, '2 Runtime: ' || m.source_label,
|
||||
SELECT r.holder_uid, '2 Runtime: ' || m.source_label,
|
||||
CASE WHEN r.same_epoch AND r.monotonic AND NOT r.over_24h_per_day THEN 'ok' ELSE 'flagged' END,
|
||||
r.start_on, r.end_on
|
||||
FROM fm.v_runtime_pair r JOIN fm.runtime_meter m ON m.meter_id = r.meter_id
|
||||
UNION ALL
|
||||
SELECT site_uid, '3 Baseline window', baseline_status, lph_window_start, lph_window_end
|
||||
SELECT holder_uid, '3 Baseline window', baseline_status, lph_window_start, lph_window_end
|
||||
FROM fm.v_site_baseline_status WHERE lph_window_start IS NOT NULL
|
||||
UNION ALL
|
||||
SELECT site_uid, '4 Electricity bills',
|
||||
SELECT holder_uid, '4 Electricity bills',
|
||||
CASE WHEN claim_status = 'disputed' THEN 'disputed' WHEN kwh IS NULL THEN 'cost only' ELSE 'kWh' END,
|
||||
coalesce(period_start, bill_month), coalesce(period_end, (bill_month + interval '1 month')::date)
|
||||
FROM fm.electricity_bill WHERE claim_status IN ('asserted','reviewed','disputed'))
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
x.lane::varchar(60) AS lane, x.status::varchar(40) AS status, x.start_on, x.end_on,
|
||||
x.start_on::timestamp(0) AS start_ts, x.end_on::timestamp(0) AS end_ts
|
||||
FROM spans x JOIN public.v_site s ON s.site_uid = x.site_uid;
|
||||
FROM spans x JOIN public.v_site s ON s.site_uid = x.holder_uid;
|
||||
|
||||
-- B9: stock-balance fuel against engine-measured fuel inside the interval. No rows until flow-meter
|
||||
-- data exist. The window runs from the opening visit's departure to the closing visit's arrival
|
||||
-- (Kabul time) when both times are recorded, else from midnight to midnight. covered_h = the hours
|
||||
-- (the holder's local time) when both times are recorded, else from midnight to midnight. covered_h = the hours
|
||||
-- of that window the generator's records cover (live records never overlap per asset). The
|
||||
-- difference is shown only for an `ok` stock interval with both times recorded, in which every
|
||||
-- generator is placed at the site throughout (one placement spans the interval, as in
|
||||
-- fm.v_lph_interval) and covered for the whole window.
|
||||
CREATE VIEW public.v_reconciliation AS
|
||||
WITH gen AS ( -- one row per interval and generator placed at the site at any time in it
|
||||
SELECT l.interval_key, l.site_uid, l.start_on, l.end_on, l.consumed_l, l.stock_status, p.asset_uid,
|
||||
SELECT l.interval_key, l.holder_uid, l.start_on, l.end_on, l.consumed_l, l.stock_status, p.asset_uid,
|
||||
bool_or(daterange(coalesce(p.occupied_from, '-infinity'::date), p.occupied_to, '[)')
|
||||
@> daterange(l.start_on, l.end_on, '[]')) AS placed_throughout,
|
||||
(o.time_out_local IS NOT NULL AND c.time_in_local IS NOT NULL) AS times_known,
|
||||
(l.start_on + coalesce(o.time_out_local, '00:00'::time)) AT TIME ZONE 'Asia/Kabul' AS t0,
|
||||
(l.end_on + coalesce(c.time_in_local, '00:00'::time)) AT TIME ZONE 'Asia/Kabul' AS t1
|
||||
(l.start_on + coalesce(o.time_out_local, '00:00'::time)) AT TIME ZONE z.timezone AS t0,
|
||||
(l.end_on + coalesce(c.time_in_local, '00:00'::time)) AT TIME ZONE z.timezone AS t1
|
||||
FROM fm.v_stock_interval l
|
||||
JOIN fm.visit o ON o.visit_id = l.open_visit_id
|
||||
JOIN fm.visit c ON c.visit_id = l.close_visit_id
|
||||
JOIN fm.asset_placement p ON p.site_uid = l.site_uid
|
||||
JOIN fm.v_holder_current z ON z.holder_uid = l.holder_uid
|
||||
JOIN fm.asset_placement p ON p.holder_uid = l.holder_uid
|
||||
JOIN fm.asset a ON a.asset_uid = p.asset_uid AND a.kind = 'generator'
|
||||
WHERE daterange(coalesce(p.occupied_from, '-infinity'::date), p.occupied_to, '[)')
|
||||
&& daterange(l.start_on, l.end_on, '[]')
|
||||
GROUP BY l.interval_key, l.site_uid, l.start_on, l.end_on, l.consumed_l, l.stock_status, p.asset_uid,
|
||||
o.time_out_local, c.time_in_local),
|
||||
GROUP BY l.interval_key, l.holder_uid, l.start_on, l.end_on, l.consumed_l, l.stock_status, p.asset_uid,
|
||||
o.time_out_local, c.time_in_local, z.timezone),
|
||||
eng AS (
|
||||
SELECT g.interval_key, g.asset_uid, sum(t.net_fuel_l) AS engine_l,
|
||||
sum(extract(epoch FROM t.ended_at - t.started_at)) / 3600 AS covered_h,
|
||||
@@ -440,7 +453,7 @@ tot AS (
|
||||
count(*) FILTER (WHERE g.placed_throughout AND e.full_cover) AS n_complete, sum(e.engine_l) AS engine_all_l
|
||||
FROM gen g LEFT JOIN eng e ON e.interval_key = g.interval_key AND e.asset_uid = g.asset_uid
|
||||
GROUP BY g.interval_key)
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
(to_char(g.start_on, 'YYYY-MM-DD') || ' to ' || to_char(g.end_on, 'YYYY-MM-DD'))::varchar(30) AS interval_label,
|
||||
g.start_on, g.end_on, g.stock_status::varchar(40) AS stock_status, g.times_known AS endpoint_times_known,
|
||||
g.asset_uid::varchar(40) AS asset_uid, g.placed_throughout,
|
||||
@@ -456,60 +469,60 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
FROM gen g
|
||||
JOIN eng e ON e.interval_key = g.interval_key AND e.asset_uid = g.asset_uid
|
||||
JOIN tot t ON t.interval_key = g.interval_key
|
||||
JOIN public.v_site s ON s.site_uid = g.site_uid;
|
||||
JOIN public.v_site s ON s.site_uid = g.holder_uid;
|
||||
|
||||
-- B6: one row per site and check; rows stay when ok.
|
||||
CREATE VIEW public.v_data_quality AS
|
||||
WITH c AS (
|
||||
SELECT s.site_uid,
|
||||
(SELECT count(*) FROM fm.stock_observation o WHERE o.site_uid = s.site_uid
|
||||
SELECT s.holder_uid,
|
||||
(SELECT count(*) FROM fm.stock_observation o WHERE o.holder_uid = s.holder_uid
|
||||
AND o.litres_basis = 'placeholder_zero' AND o.claim_status IN ('asserted','reviewed','disputed')) AS n_placeholder,
|
||||
(SELECT count(*) FROM fm.v_movement_event e JOIN fm.visit v ON v.visit_id = e.visit_id
|
||||
WHERE v.site_uid = s.site_uid AND e.spread_l > 0)
|
||||
WHERE v.holder_uid = s.holder_uid AND e.spread_l > 0)
|
||||
+ (SELECT count(*) FROM fm.v_visit_stock st JOIN fm.visit v ON v.visit_id = st.visit_id
|
||||
WHERE v.site_uid = s.site_uid AND st.spread_l > 0) AS n_conflicts,
|
||||
WHERE v.holder_uid = s.holder_uid AND st.spread_l > 0) AS n_conflicts,
|
||||
(SELECT count(*) FROM fm.hour_meter_reading h JOIN fm.runtime_meter m ON m.meter_id = h.meter_id
|
||||
WHERE m.site_uid = s.site_uid AND h.claim_status IN ('asserted','reviewed','disputed')) AS n_readings,
|
||||
(SELECT count(*) FROM fm.runtime_meter m WHERE m.site_uid = s.site_uid AND m.mapping_status <> 'confirmed') AS n_unmapped,
|
||||
WHERE m.holder_uid = s.holder_uid AND h.claim_status IN ('asserted','reviewed','disputed')) AS n_readings,
|
||||
(SELECT count(*) FROM fm.runtime_meter m WHERE m.holder_uid = s.holder_uid AND m.mapping_status <> 'confirmed') AS n_unmapped,
|
||||
(SELECT count(*) FROM fm.asset_placement p JOIN fm.asset a ON a.asset_uid = p.asset_uid
|
||||
WHERE p.site_uid = s.site_uid AND a.kind = 'generator'
|
||||
WHERE p.holder_uid = s.holder_uid AND a.kind = 'generator'
|
||||
AND daterange(coalesce(p.occupied_from, '-infinity'::date), p.occupied_to, '[)')
|
||||
@> (now() AT TIME ZONE 'Asia/Kabul')::date
|
||||
@> (SELECT z.today FROM fm.v_holder_current z WHERE z.holder_uid = s.holder_uid)
|
||||
AND NOT EXISTS (SELECT 1 FROM fm.runtime_meter m JOIN fm.hour_meter_reading h ON h.meter_id = m.meter_id
|
||||
WHERE m.asset_uid = p.asset_uid AND m.mapping_status = 'confirmed'
|
||||
AND h.claim_status IN ('asserted','reviewed'))) AS n_gen_no_readings,
|
||||
(SELECT count(*) FROM fm.fuel_movement x WHERE x.site_uid = s.site_uid AND x.claim_status = 'asserted')
|
||||
+ (SELECT count(*) FROM fm.stock_observation x WHERE x.site_uid = s.site_uid AND x.claim_status = 'asserted')
|
||||
(SELECT count(*) FROM fm.fuel_movement x WHERE x.holder_uid = s.holder_uid AND x.claim_status = 'asserted')
|
||||
+ (SELECT count(*) FROM fm.stock_observation x WHERE x.holder_uid = s.holder_uid AND x.claim_status = 'asserted')
|
||||
+ (SELECT count(*) FROM fm.hour_meter_reading x JOIN fm.runtime_meter m ON m.meter_id = x.meter_id
|
||||
WHERE m.site_uid = s.site_uid AND x.claim_status = 'asserted')
|
||||
+ (SELECT count(*) FROM fm.electricity_bill x WHERE x.site_uid = s.site_uid AND x.claim_status = 'asserted') AS n_unreviewed,
|
||||
(SELECT count(*) FROM fm.v_stock_point p WHERE p.site_uid = s.site_uid
|
||||
WHERE m.holder_uid = s.holder_uid AND x.claim_status = 'asserted')
|
||||
+ (SELECT count(*) FROM fm.electricity_bill x WHERE x.holder_uid = s.holder_uid AND x.claim_status = 'asserted') AS n_unreviewed,
|
||||
(SELECT count(*) FROM fm.v_stock_point p WHERE p.holder_uid = s.holder_uid
|
||||
AND abs(p.after_vs_before_plus_delivered_l) > 0.5) AS n_after_mismatch,
|
||||
(SELECT count(*) FROM fm.v_stock_interval i WHERE i.site_uid = s.site_uid
|
||||
(SELECT count(*) FROM fm.v_stock_interval i WHERE i.holder_uid = s.holder_uid
|
||||
AND i.stock_status IN ('negative','same_day')) AS n_neg_same_day,
|
||||
(SELECT count(*) FROM fm.v_stock_interval i WHERE i.site_uid = s.site_uid
|
||||
(SELECT count(*) FROM fm.v_stock_interval i WHERE i.holder_uid = s.holder_uid
|
||||
AND i.stock_status NOT IN ('ok','negative','same_day')) AS n_gaps,
|
||||
(SELECT count(*) FROM fm.electricity_bill b WHERE b.site_uid = s.site_uid
|
||||
(SELECT count(*) FROM fm.electricity_bill b WHERE b.holder_uid = s.holder_uid
|
||||
AND b.claim_status IN ('asserted','reviewed','disputed')) AS n_bills,
|
||||
(SELECT count(*) FROM fm.electricity_bill b WHERE b.site_uid = s.site_uid
|
||||
(SELECT count(*) FROM fm.electricity_bill b WHERE b.holder_uid = s.holder_uid
|
||||
AND (b.kwh IS NULL OR b.claim_status = 'disputed')
|
||||
AND b.claim_status IN ('asserted','reviewed','disputed')) AS n_bills_no_kwh, -- no usable kWh
|
||||
(SELECT count(*) FROM fm.fuel_movement m WHERE m.site_uid = s.site_uid
|
||||
(SELECT count(*) FROM fm.fuel_movement m WHERE m.holder_uid = s.holder_uid
|
||||
AND m.kind IN ('withdrawal','drain','spill','loss_reported','internal_transfer')
|
||||
AND m.claim_status IN ('asserted','reviewed','disputed')) AS n_transfer_records,
|
||||
(SELECT count(*) FROM fm.baseline_version b JOIN fm.v_baseline_validity v ON v.baseline_id = b.baseline_id
|
||||
WHERE b.site_uid = s.site_uid AND b.status IN ('proposed','approved') AND NOT v.inputs_unchanged) AS n_drift,
|
||||
(SELECT count(*) FROM fm.v_review_stale r WHERE r.site_uid = s.site_uid) AS n_stale,
|
||||
(SELECT count(*) FROM fm.v_visit_provenance_only v WHERE v.site_uid = s.site_uid) AS n_provenance_only,
|
||||
(SELECT count(*) FROM fm.v_lph_interval l WHERE l.site_uid = s.site_uid
|
||||
WHERE b.holder_uid = s.holder_uid AND b.status IN ('proposed','approved') AND NOT v.inputs_unchanged) AS n_drift,
|
||||
(SELECT count(*) FROM fm.v_review_stale r WHERE r.holder_uid = s.holder_uid) AS n_stale,
|
||||
(SELECT count(*) FROM fm.v_visit_provenance_only v WHERE v.holder_uid = s.holder_uid) AS n_provenance_only,
|
||||
(SELECT count(*) FROM fm.v_lph_interval l WHERE l.holder_uid = s.holder_uid
|
||||
AND l.exclusion_reasons LIKE '%confirmed for a generator not placed here%') AS n_unplaced_counter,
|
||||
(SELECT count(*) FROM fm.v_lph_interval l WHERE l.site_uid = s.site_uid
|
||||
(SELECT count(*) FROM fm.v_lph_interval l WHERE l.holder_uid = s.holder_uid
|
||||
AND l.exclusion_reasons LIKE '%meter-coverage assumption % does not name%') AS n_cov_mismatch
|
||||
FROM fm.site s)
|
||||
SELECT vs.site_uid, vs.site_code, vs.site_name, vs.site_label,
|
||||
FROM fm.holder s)
|
||||
SELECT vs.site_uid, vs.site_code, vs.site_name, vs.site_label, vs.operator_uid,
|
||||
x.ord::integer AS check_order, x.code::varchar(40) AS check_code, x.label::varchar(80) AS label,
|
||||
x.status::varchar(10) AS status, x.detail::varchar(300) AS detail
|
||||
FROM c JOIN public.v_site vs ON vs.site_uid = c.site_uid
|
||||
FROM c JOIN public.v_site vs ON vs.site_uid = c.holder_uid
|
||||
CROSS JOIN LATERAL (VALUES
|
||||
(1, 'placeholder_rows', 'Placeholder rows',
|
||||
CASE WHEN c.n_placeholder > 0 THEN 'warning' ELSE 'ok' END,
|
||||
@@ -564,8 +577,8 @@ CROSS JOIN LATERAL (VALUES
|
||||
-- B10: specifications, labelled as such; live rows only. A disputed specification is listed with its
|
||||
-- status and without its value.
|
||||
CREATE VIEW public.v_spec_reference AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
p.slot_label::varchar(20) AS slot, e.asset_uid::varchar(40) AS asset_uid, a.kind::varchar(10) AS asset_kind,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
p.slot_label::varchar(20) AS slot, e.asset_uid::varchar(40) AS asset_uid, a.kind::varchar(20) AS asset_kind,
|
||||
concat_ws(' ', a.make, a.model)::varchar(120) AS make_model,
|
||||
e.attribute::varchar(40) AS attribute, e.load_pct::numeric(5,1) AS load_pct,
|
||||
(CASE WHEN e.claim_status <> 'disputed' THEN e.value_num END)::numeric(12,3) AS value,
|
||||
@@ -575,14 +588,14 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
'specification, not measured'::varchar(30) AS value_kind, e.claim_status::varchar(12) AS claim_status
|
||||
FROM fm.equipment_spec e
|
||||
JOIN fm.asset a ON a.asset_uid = e.asset_uid
|
||||
JOIN (SELECT DISTINCT ON (asset_uid, site_uid) asset_uid, site_uid, slot_label
|
||||
FROM fm.asset_placement ORDER BY asset_uid, site_uid, occupied_from DESC NULLS LAST) p ON p.asset_uid = e.asset_uid
|
||||
JOIN public.v_site s ON s.site_uid = p.site_uid
|
||||
JOIN (SELECT DISTINCT ON (asset_uid, holder_uid) asset_uid, holder_uid, slot_label
|
||||
FROM fm.asset_placement ORDER BY asset_uid, holder_uid, occupied_from DESC NULLS LAST) p ON p.asset_uid = e.asset_uid
|
||||
JOIN public.v_site s ON s.site_uid = p.holder_uid
|
||||
WHERE e.claim_status IN ('asserted','reviewed','disputed');
|
||||
|
||||
-- M3 sensitivity table, reference tab only (shown only once Q9 approves a runtime assumption).
|
||||
CREATE VIEW public.v_modelled_lph AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
m.code::varchar(60) AS assumption_code, m.status::varchar(12) AS status, m.basis::varchar(20) AS basis,
|
||||
m.h_per_day::numeric(5,2) AS h_per_day, m.h_per_day_low::numeric(5,2) AS h_per_day_low,
|
||||
m.h_per_day_high::numeric(5,2) AS h_per_day_high, m.window_start, m.window_end,
|
||||
@@ -591,31 +604,31 @@ SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
round(m.modelled_l_per_h_low, 2)::numeric(6,2) AS modelled_l_per_h_low,
|
||||
round(m.modelled_l_per_h_high, 2)::numeric(6,2) AS modelled_l_per_h_high,
|
||||
'modelled: L per calendar day / assumed runtime; not measured'::varchar(70) AS value_kind
|
||||
FROM fm.v_modelled_lph m JOIN public.v_site s ON s.site_uid = m.site_uid;
|
||||
FROM fm.v_modelled_lph m JOIN public.v_site s ON s.site_uid = m.holder_uid;
|
||||
|
||||
-- R4: electricity cost per bill month; cost context only, never joined into fuel metrics. A
|
||||
-- disputed bill stays listed, without amount or kWh.
|
||||
CREATE VIEW public.v_electricity_cost AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
b.bill_month, b.period_start, b.period_end, (b.period_start IS NOT NULL) AS period_known,
|
||||
(CASE WHEN b.claim_status <> 'disputed' THEN b.amount END)::numeric(12,2) AS amount, b.currency::varchar(8) AS currency,
|
||||
b.currency_basis::varchar(10) AS currency_basis,
|
||||
(CASE WHEN b.claim_status <> 'disputed' THEN b.kwh END)::numeric(10,1) AS kwh,
|
||||
b.record_ref::varchar(60) AS source_ref, b.claim_status::varchar(12) AS claim_status
|
||||
FROM fm.electricity_bill b JOIN public.v_site s ON s.site_uid = b.site_uid
|
||||
FROM fm.electricity_bill b JOIN public.v_site s ON s.site_uid = b.holder_uid
|
||||
WHERE b.claim_status IN ('asserted','reviewed','disputed');
|
||||
|
||||
-- B8: operator workbook calculations and our assessment; live rows only. A disputed transcription is
|
||||
-- listed with its status and without its formula or value.
|
||||
CREATE VIEW public.v_imported_calculation AS
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label,
|
||||
SELECT s.site_uid, s.site_code, s.site_name, s.site_label, s.operator_uid,
|
||||
c.cell_ref::varchar(40) AS cell_ref, c.source_label::varchar(80) AS source_label,
|
||||
(CASE WHEN c.claim_status <> 'disputed' THEN c.formula END)::varchar(200) AS formula,
|
||||
(CASE WHEN c.claim_status <> 'disputed' THEN c.cached_value END)::numeric(14,6) AS cached_value,
|
||||
c.unit_as_labelled::varchar(30) AS unit_as_labelled, c.our_reading::varchar(300) AS our_reading,
|
||||
c.baseline_use::varchar(12) AS baseline_use, c.exclusion_reason::varchar(300) AS exclusion_reason,
|
||||
left(c.source_sha256, 16)::varchar(16) AS document_key, c.claim_status::varchar(12) AS claim_status
|
||||
FROM fm.imported_calculation c JOIN public.v_site s ON s.site_uid = c.site_uid
|
||||
FROM fm.imported_calculation c JOIN public.v_site s ON s.site_uid = c.holder_uid
|
||||
WHERE c.claim_status IN ('asserted','reviewed','disputed');
|
||||
|
||||
COMMIT;
|
||||
Reference in new issue
Block a user