229 lines
6.6 KiB
SQL
229 lines
6.6 KiB
SQL
DROP VIEW IF EXISTS mv_reports_ucepsa_demo.odoo_discrepancies_demo;
|
|
DROP VIEW IF EXISTS mv_reports_ucepsa_demo.odoo_vs_machine_demo;
|
|
DROP VIEW IF EXISTS mv_reports_ucepsa_demo.odoo_current_order_demo;
|
|
|
|
CREATE OR REPLACE VIEW mv_reports_ucepsa_demo.odoo_current_order_demo AS
|
|
SELECT
|
|
o.id,
|
|
o.tenant,
|
|
o.site,
|
|
o.odoo_instance,
|
|
o.odoo_workorder_id,
|
|
o.odoo_production_id,
|
|
o.odoo_order_ref,
|
|
o.odoo_state,
|
|
o.odoo_workcenter_code,
|
|
o.odoo_workcenter_name,
|
|
o.machine_id,
|
|
o.asset,
|
|
o.product,
|
|
o.qty_planned,
|
|
o.qty_done,
|
|
o.uom,
|
|
o.planned_cycles,
|
|
o.target_cycle_rate_ppm,
|
|
|
|
CASE
|
|
WHEN o.odoo_state IN ('progress', 'in_progress', 'started')
|
|
THEN o.odoo_start
|
|
ELSE NULL::timestamptz
|
|
END AS odoo_start,
|
|
|
|
o.odoo_start AS odoo_reference_start,
|
|
|
|
CASE
|
|
WHEN o.odoo_state IN ('progress', 'in_progress', 'started')
|
|
THEN true
|
|
ELSE false
|
|
END AS odoo_is_started,
|
|
|
|
o.odoo_end,
|
|
o.notes,
|
|
o.snapshot_at
|
|
FROM mv_edge_oee_ucepsa_demo.odoo_workorders_demo o
|
|
WHERE o.machine_id = 'CORT-01'
|
|
AND o.odoo_instance = 'odoo_demo'
|
|
AND o.odoo_workorder_id IS NOT NULL
|
|
AND o.odoo_state IN ('progress', 'in_progress', 'started', 'ready', 'waiting')
|
|
ORDER BY
|
|
CASE
|
|
WHEN o.odoo_state IN ('progress', 'in_progress', 'started') THEN 1
|
|
WHEN o.odoo_state = 'ready' THEN 2
|
|
WHEN o.odoo_state = 'waiting' THEN 3
|
|
ELSE 9
|
|
END,
|
|
o.odoo_workorder_id DESC NULLS LAST
|
|
LIMIT 1;
|
|
|
|
|
|
CREATE OR REPLACE VIEW mv_reports_ucepsa_demo.odoo_vs_machine_demo AS
|
|
WITH current_order AS (
|
|
SELECT *
|
|
FROM mv_reports_ucepsa_demo.odoo_current_order_demo
|
|
),
|
|
machine AS (
|
|
SELECT *
|
|
FROM mv_reports_ucepsa_demo.latest_machine_state_fast
|
|
),
|
|
first_real_activity AS (
|
|
SELECT
|
|
MIN(l.ingest_ts) AS first_machine_activity
|
|
FROM current_order o
|
|
LEFT JOIN mv_reports_ucepsa_demo.live_telemetry l
|
|
ON o.odoo_is_started = true
|
|
AND l.asset = o.asset
|
|
AND l.ingest_ts >= o.odoo_start
|
|
AND l.ingest_ts <= COALESCE(o.odoo_end, now())
|
|
AND (
|
|
l.machine_running = true
|
|
OR COALESCE(l.cycle_pulse_count, 0) > 0
|
|
)
|
|
),
|
|
stops_in_order AS (
|
|
SELECT
|
|
COUNT(s.id) AS stop_count,
|
|
ROUND(COALESCE(SUM(s.duration_min), 0)::numeric, 2) AS stop_min,
|
|
ROUND(COALESCE(SUM(s.cost_eur), 0)::numeric, 2) AS stop_cost_eur
|
|
FROM current_order o
|
|
LEFT JOIN mv_reports_ucepsa_demo.stops_recent s
|
|
ON o.odoo_is_started = true
|
|
AND s.machine_id = o.machine_id
|
|
AND s.started_at >= o.odoo_start
|
|
AND s.started_at <= COALESCE(o.odoo_end, now())
|
|
),
|
|
cycles_in_order AS (
|
|
SELECT
|
|
COALESCE(
|
|
GREATEST(MAX(l.cycle_pulse_count) - MIN(l.cycle_pulse_count), 0),
|
|
0
|
|
)::numeric AS real_cycles
|
|
FROM current_order o
|
|
LEFT JOIN mv_reports_ucepsa_demo.live_telemetry l
|
|
ON o.odoo_is_started = true
|
|
AND l.asset = o.asset
|
|
AND l.ingest_ts >= o.odoo_start
|
|
AND l.ingest_ts <= COALESCE(o.odoo_end, now())
|
|
AND l.cycle_pulse_count IS NOT NULL
|
|
)
|
|
SELECT
|
|
o.odoo_workorder_id,
|
|
o.odoo_production_id,
|
|
o.odoo_order_ref,
|
|
o.odoo_state,
|
|
o.odoo_is_started,
|
|
o.product,
|
|
o.machine_id,
|
|
o.asset,
|
|
o.odoo_start,
|
|
o.odoo_reference_start,
|
|
o.odoo_end,
|
|
|
|
m.machine_running,
|
|
m.age_s AS telemetry_age_s,
|
|
m.cycle_pulse_count,
|
|
m.cycle_rate_ppm,
|
|
|
|
f.first_machine_activity,
|
|
|
|
CASE
|
|
WHEN o.odoo_is_started = false THEN NULL::numeric
|
|
WHEN f.first_machine_activity IS NULL THEN NULL::numeric
|
|
ELSE ROUND((EXTRACT(EPOCH FROM (f.first_machine_activity - o.odoo_start)) / 60.0)::numeric, 2)
|
|
END AS start_delay_min,
|
|
|
|
s.stop_count,
|
|
s.stop_min,
|
|
s.stop_cost_eur,
|
|
|
|
CASE
|
|
WHEN o.odoo_is_started = true THEN c.real_cycles
|
|
ELSE 0::numeric
|
|
END AS real_cycles,
|
|
|
|
o.planned_cycles,
|
|
|
|
CASE
|
|
WHEN o.odoo_is_started = true
|
|
AND o.planned_cycles > 0
|
|
THEN ROUND(((c.real_cycles / o.planned_cycles) * 100)::numeric, 2)
|
|
WHEN o.odoo_is_started = false
|
|
THEN 0::numeric
|
|
ELSE NULL::numeric
|
|
END AS cycle_completion_pct,
|
|
|
|
CASE
|
|
WHEN m.age_s > 30 THEN 'SIN_TELEMETRIA'
|
|
|
|
WHEN o.odoo_is_started = false
|
|
AND m.machine_running = true
|
|
THEN 'MAQUINA_EN_MARCHA_SIN_ORDEN_INICIADA'
|
|
|
|
WHEN o.odoo_is_started = false
|
|
AND COALESCE(m.machine_running, false) = false
|
|
THEN 'ORDEN_PREPARADA_MAQUINA_PARADA'
|
|
|
|
WHEN o.odoo_is_started = true
|
|
AND f.first_machine_activity IS NULL
|
|
THEN 'ORDEN_ACTIVA_SIN_ACTIVIDAD_REAL'
|
|
|
|
WHEN o.odoo_is_started = true
|
|
AND m.machine_running = false
|
|
THEN 'ORDEN_ACTIVA_MAQUINA_PARADA'
|
|
|
|
WHEN o.odoo_is_started = true
|
|
AND f.first_machine_activity IS NOT NULL
|
|
AND EXTRACT(EPOCH FROM (f.first_machine_activity - o.odoo_start)) > 600
|
|
THEN 'ARRANQUE_REAL_TARDIO'
|
|
|
|
ELSE 'OK'
|
|
END AS status_check
|
|
FROM current_order o
|
|
LEFT JOIN machine m ON m.asset = o.asset
|
|
LEFT JOIN first_real_activity f ON true
|
|
LEFT JOIN stops_in_order s ON true
|
|
LEFT JOIN cycles_in_order c ON true;
|
|
|
|
|
|
CREATE OR REPLACE VIEW mv_reports_ucepsa_demo.odoo_discrepancies_demo AS
|
|
SELECT
|
|
now() AS checked_at,
|
|
odoo_order_ref,
|
|
product,
|
|
machine_id,
|
|
odoo_state,
|
|
odoo_is_started,
|
|
status_check,
|
|
CASE
|
|
WHEN status_check = 'SIN_TELEMETRIA'
|
|
THEN 'No hay telemetría reciente de la RevPi.'
|
|
|
|
WHEN status_check = 'MAQUINA_EN_MARCHA_SIN_ORDEN_INICIADA'
|
|
THEN 'La máquina está en marcha, pero la orden de Odoo está preparada o en espera, no iniciada.'
|
|
|
|
WHEN status_check = 'ORDEN_PREPARADA_MAQUINA_PARADA'
|
|
THEN 'La orden está preparada/en espera y la máquina está parada. No hay desviación productiva activa.'
|
|
|
|
WHEN status_check = 'ORDEN_ACTIVA_SIN_ACTIVIDAD_REAL'
|
|
THEN 'Odoo tiene una orden activa, pero no se detecta actividad real de máquina.'
|
|
|
|
WHEN status_check = 'ORDEN_ACTIVA_MAQUINA_PARADA'
|
|
THEN 'Odoo tiene una orden activa, pero la máquina aparece parada.'
|
|
|
|
WHEN status_check = 'ARRANQUE_REAL_TARDIO'
|
|
THEN 'La primera actividad real de máquina llega más de 10 minutos después del inicio Odoo.'
|
|
|
|
ELSE 'Sin discrepancia relevante.'
|
|
END AS descripcion,
|
|
start_delay_min,
|
|
stop_count,
|
|
stop_min,
|
|
stop_cost_eur,
|
|
cycle_completion_pct
|
|
FROM mv_reports_ucepsa_demo.odoo_vs_machine_demo;
|
|
|
|
GRANT SELECT ON
|
|
mv_reports_ucepsa_demo.odoo_current_order_demo,
|
|
mv_reports_ucepsa_demo.odoo_vs_machine_demo,
|
|
mv_reports_ucepsa_demo.odoo_discrepancies_demo
|
|
TO grafana_ucepsa_ro, edge_oee_odoo_sync_writer;
|