-- -- PostgreSQL database dump -- \restrict 1wX0I2K6nLSszbhqDMaBaJRF13jG1hT3a3HKImFGiykK1wx4riB6Rf5OY4lcf06 -- Dumped from database version 16.14 -- Dumped by pg_dump version 16.14 SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off; -- -- Name: mv_edge_oee_ucepsa_demo; Type: SCHEMA; Schema: -; Owner: mesavault -- CREATE SCHEMA mv_edge_oee_ucepsa_demo; ALTER SCHEMA mv_edge_oee_ucepsa_demo OWNER TO mesavault; -- -- Name: SCHEMA mv_edge_oee_ucepsa_demo; Type: COMMENT; Schema: -; Owner: mesavault -- COMMENT ON SCHEMA mv_edge_oee_ucepsa_demo IS 'Capa normalizada de la demo Edge-OEE UCEPSA. Inicialmente contiene vistas puente hacia mv_hot.'; -- -- Name: mv_edge_oee_ucepsa_prod; Type: SCHEMA; Schema: -; Owner: mesavault -- CREATE SCHEMA mv_edge_oee_ucepsa_prod; ALTER SCHEMA mv_edge_oee_ucepsa_prod OWNER TO mesavault; -- -- Name: mv_hot; Type: SCHEMA; Schema: -; Owner: mesavault -- CREATE SCHEMA mv_hot; ALTER SCHEMA mv_hot OWNER TO mesavault; -- -- Name: mv_reports_ucepsa_demo; Type: SCHEMA; Schema: -; Owner: mesavault -- CREATE SCHEMA mv_reports_ucepsa_demo; ALTER SCHEMA mv_reports_ucepsa_demo OWNER TO mesavault; -- -- Name: SCHEMA mv_reports_ucepsa_demo; Type: COMMENT; Schema: -; Owner: mesavault -- COMMENT ON SCHEMA mv_reports_ucepsa_demo IS 'Capa de reporting para Grafana UCEPSA demo. Grafana debe consultar preferentemente este schema.'; -- -- Name: mv_reports_ucepsa_prod; Type: SCHEMA; Schema: -; Owner: mesavault -- CREATE SCHEMA mv_reports_ucepsa_prod; ALTER SCHEMA mv_reports_ucepsa_prod OWNER TO mesavault; -- -- Name: oee_kpis(timestamp with time zone, timestamp with time zone, text, text); Type: FUNCTION; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE FUNCTION mv_reports_ucepsa_demo.oee_kpis(p_from timestamp with time zone, p_to timestamp with time zone, p_machine_id text DEFAULT 'CORT-01'::text, p_asset text DEFAULT 'revpi_oee_node_01'::text) RETURNS TABLE(oee_pct numeric, availability_pct numeric, performance_pct numeric, quality_pct numeric) LANGUAGE sql STABLE AS $$ WITH dashboard_bounds AS ( SELECT p_from AS dashboard_from, LEAST(p_to, now()) AS dashboard_to ), telemetry_span AS ( SELECT MIN(ingest_ts) AS first_ts, MAX(ingest_ts) AS last_ts FROM mv_hot.edge_oee_live_telemetry WHERE asset = p_asset AND ingest_ts >= (SELECT dashboard_from FROM dashboard_bounds) AND ingest_ts <= (SELECT dashboard_to FROM dashboard_bounds) ), bounds AS ( SELECT CASE WHEN first_ts IS NULL THEN dashboard_from ELSE GREATEST(dashboard_from, first_ts) END AS t_from, CASE WHEN last_ts IS NULL THEN dashboard_to ELSE LEAST(dashboard_to, last_ts) END AS t_to FROM dashboard_bounds CROSS JOIN telemetry_span ), target AS ( SELECT COALESCE(( SELECT mt.target_cycle_rate_ppm FROM mv_hot.edge_oee_machine_targets mt WHERE mt.machine_id = p_machine_id LIMIT 1 ), 10.00)::numeric AS target_cycle_rate_ppm, COALESCE(( SELECT mt.quality_pct_default FROM mv_hot.edge_oee_machine_targets mt WHERE mt.machine_id = p_machine_id LIMIT 1 ), 100.00)::numeric AS quality_pct_default ), planned AS ( SELECT GREATEST(EXTRACT(EPOCH FROM (t_to - t_from))::numeric, 0) AS planned_s FROM bounds ), stops AS ( SELECT COALESCE( SUM( GREATEST( EXTRACT(EPOCH FROM ( LEAST(COALESCE(s.ended_at, b.t_to), b.t_to) - GREATEST( CASE WHEN s.started_at > s.created_at + interval '5 seconds' THEN s.created_at ELSE s.started_at END, b.t_from ) ))::numeric, 0 ) ) FILTER ( WHERE s.started_at < b.t_to AND COALESCE(s.ended_at, now()) > b.t_from ), 0 )::numeric AS stop_s FROM mv_hot.edge_oee_machine_stops s CROSS JOIN bounds b WHERE s.machine_id = p_machine_id ), cycles AS ( SELECT COALESCE( GREATEST( MAX(cycle_pulse_count) - MIN(cycle_pulse_count), 0 ), 0 )::numeric AS actual_cycles FROM mv_hot.edge_oee_live_telemetry l CROSS JOIN bounds b WHERE l.asset = p_asset AND l.ingest_ts >= b.t_from AND l.ingest_ts <= b.t_to AND l.cycle_pulse_count IS NOT NULL ), calc AS ( SELECT p.planned_s, st.stop_s, GREATEST(p.planned_s - st.stop_s, 0)::numeric AS running_s, c.actual_cycles, t.target_cycle_rate_ppm, t.quality_pct_default, CASE WHEN p.planned_s > 0 THEN ROUND(((GREATEST(p.planned_s - st.stop_s, 0) / p.planned_s) * 100)::numeric, 2) ELSE 0 END AS availability_pct, CASE WHEN GREATEST(p.planned_s - st.stop_s, 0) > 0 AND t.target_cycle_rate_ppm > 0 THEN ROUND( LEAST( 100::numeric, ( c.actual_cycles / NULLIF( t.target_cycle_rate_ppm * (GREATEST(p.planned_s - st.stop_s, 0) / 60.0), 0 ) ) * 100 )::numeric, 2 ) ELSE 0 END AS performance_pct, t.quality_pct_default AS quality_pct FROM planned p CROSS JOIN stops st CROSS JOIN cycles c CROSS JOIN target t ) SELECT ROUND(((calc.availability_pct * calc.performance_pct * calc.quality_pct) / 10000.0)::numeric, 2) AS oee_pct, calc.availability_pct, calc.performance_pct, calc.quality_pct FROM calc; $$; ALTER FUNCTION mv_reports_ucepsa_demo.oee_kpis(p_from timestamp with time zone, p_to timestamp with time zone, p_machine_id text, p_asset text) OWNER TO mesavault; -- -- Name: oee_operational_data(timestamp with time zone, timestamp with time zone, text, text); Type: FUNCTION; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE FUNCTION mv_reports_ucepsa_demo.oee_operational_data(p_from timestamp with time zone, p_to timestamp with time zone, p_machine_id text DEFAULT 'CORT-01'::text, p_asset text DEFAULT 'revpi_oee_node_01'::text) RETURNS TABLE(running_min numeric, stop_min numeric, actual_cycles numeric) LANGUAGE sql STABLE AS $$ WITH dashboard_bounds AS ( SELECT p_from AS dashboard_from, LEAST(p_to, now()) AS dashboard_to ), telemetry_span AS ( SELECT MIN(ingest_ts) AS first_ts, MAX(ingest_ts) AS last_ts FROM mv_hot.edge_oee_live_telemetry WHERE asset = p_asset AND ingest_ts >= (SELECT dashboard_from FROM dashboard_bounds) AND ingest_ts <= (SELECT dashboard_to FROM dashboard_bounds) ), bounds AS ( SELECT CASE WHEN first_ts IS NULL THEN dashboard_from ELSE GREATEST(dashboard_from, first_ts) END AS t_from, CASE WHEN last_ts IS NULL THEN dashboard_to ELSE LEAST(dashboard_to, last_ts) END AS t_to FROM dashboard_bounds CROSS JOIN telemetry_span ), planned AS ( SELECT GREATEST(EXTRACT(EPOCH FROM (t_to - t_from))::numeric, 0) AS planned_s FROM bounds ), stops AS ( SELECT COALESCE( SUM( GREATEST( EXTRACT(EPOCH FROM ( LEAST(COALESCE(s.ended_at, b.t_to), b.t_to) - GREATEST( CASE WHEN s.started_at > s.created_at + interval '5 seconds' THEN s.created_at ELSE s.started_at END, b.t_from ) ))::numeric, 0 ) ) FILTER ( WHERE s.started_at < b.t_to AND COALESCE(s.ended_at, now()) > b.t_from ), 0 )::numeric AS stop_s FROM mv_hot.edge_oee_machine_stops s CROSS JOIN bounds b WHERE s.machine_id = p_machine_id ), cycles AS ( SELECT COALESCE( GREATEST( MAX(cycle_pulse_count) - MIN(cycle_pulse_count), 0 ), 0 )::numeric AS actual_cycles FROM mv_hot.edge_oee_live_telemetry l CROSS JOIN bounds b WHERE l.asset = p_asset AND l.ingest_ts >= b.t_from AND l.ingest_ts <= b.t_to AND l.cycle_pulse_count IS NOT NULL ), calc AS ( SELECT p.planned_s, st.stop_s, GREATEST(p.planned_s - st.stop_s, 0)::numeric AS running_s, c.actual_cycles FROM planned p CROSS JOIN stops st CROSS JOIN cycles c ) SELECT ROUND((running_s / 60.0)::numeric, 2) AS running_min, ROUND((stop_s / 60.0)::numeric, 2) AS stop_min, actual_cycles FROM calc; $$; ALTER FUNCTION mv_reports_ucepsa_demo.oee_operational_data(p_from timestamp with time zone, p_to timestamp with time zone, p_machine_id text, p_asset text) OWNER TO mesavault; SET default_tablespace = ''; SET default_table_access_method = heap; -- -- Name: data_quality_contract_rules; Type: TABLE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_demo.data_quality_contract_rules ( id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'ucepsa_test'::text NOT NULL, rule_code text NOT NULL, rule_name text NOT NULL, domain text NOT NULL, dimension text NOT NULL, severity text NOT NULL, owner_area text NOT NULL, applies_to text NOT NULL, description text NOT NULL, expected_condition text NOT NULL, blocking_for text, is_active boolean DEFAULT true NOT NULL, created_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_edge_oee_ucepsa_demo.data_quality_contract_rules OWNER TO mesavault; -- -- Name: data_quality_contract_rules_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_demo.data_quality_contract_rules_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_demo.data_quality_contract_rules_id_seq OWNER TO mesavault; -- -- Name: data_quality_contract_rules_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_demo.data_quality_contract_rules_id_seq OWNED BY mv_edge_oee_ucepsa_demo.data_quality_contract_rules.id; -- -- Name: edge_oee_eastron_readings; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_eastron_readings ( id bigint NOT NULL, ts timestamp with time zone DEFAULT now() NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'demo_edge_oee'::text NOT NULL, asset text DEFAULT 'revpi_eastron_demo'::text NOT NULL, source text DEFAULT 'eastron_reader'::text NOT NULL, meter_model text, meter_id text, machine_id text, order_id text, voltage_l1_v numeric(10,3), voltage_l2_v numeric(10,3), voltage_l3_v numeric(10,3), current_l1_a numeric(10,3), current_l2_a numeric(10,3), current_l3_a numeric(10,3), power_l1_kw numeric(10,3), power_l2_kw numeric(10,3), power_l3_kw numeric(10,3), power_total_kw numeric(10,3), frequency_hz numeric(10,3), import_kwh numeric(14,3), export_kwh numeric(14,3), comm_ok boolean DEFAULT true NOT NULL, error_text text, payload_json jsonb DEFAULT '{}'::jsonb NOT NULL, ingest_ts timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_hot.edge_oee_eastron_readings OWNER TO mesavault; -- -- Name: edge_oee_eastron_latest; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_eastron_latest AS SELECT DISTINCT ON (asset) id, ts, tenant, site, asset, source, meter_model, meter_id, machine_id, order_id, voltage_l1_v, voltage_l2_v, voltage_l3_v, current_l1_a, current_l2_a, current_l3_a, power_l1_kw, power_l2_kw, power_l3_kw, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, payload_json, ingest_ts FROM mv_hot.edge_oee_eastron_readings ORDER BY asset, ingest_ts DESC; ALTER VIEW mv_hot.edge_oee_eastron_latest OWNER TO mesavault; -- -- Name: edge_oee_eastron_dashboard; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_eastron_dashboard AS SELECT ts, ingest_ts, GREATEST((EXTRACT(epoch FROM (now() - ingest_ts)))::integer, 0) AS age_s, tenant, site, asset, meter_model, meter_id, machine_id, voltage_l1_v, voltage_l2_v, voltage_l3_v, current_l1_a, current_l2_a, current_l3_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, CASE WHEN (comm_ok = false) THEN 2 WHEN (GREATEST((EXTRACT(epoch FROM (now() - ingest_ts)))::integer, 0) > 180) THEN 2 WHEN (GREATEST((EXTRACT(epoch FROM (now() - ingest_ts)))::integer, 0) > 60) THEN 1 ELSE 0 END AS comm_risk_level, CASE WHEN (comm_ok = false) THEN 'Sin comunicación Modbus'::text WHEN (GREATEST((EXTRACT(epoch FROM (now() - ingest_ts)))::integer, 0) > 180) THEN 'Lectura antigua'::text WHEN (GREATEST((EXTRACT(epoch FROM (now() - ingest_ts)))::integer, 0) > 60) THEN 'Lectura no reciente'::text ELSE 'Comunicación correcta'::text END AS comm_status FROM mv_hot.edge_oee_eastron_latest; ALTER VIEW mv_hot.edge_oee_eastron_dashboard OWNER TO mesavault; -- -- Name: eastron_dashboard; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.eastron_dashboard AS SELECT ts, ingest_ts, age_s, tenant, site, asset, meter_model, meter_id, machine_id, voltage_l1_v, voltage_l2_v, voltage_l3_v, current_l1_a, current_l2_a, current_l3_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, comm_risk_level, comm_status FROM mv_hot.edge_oee_eastron_dashboard; ALTER VIEW mv_edge_oee_ucepsa_demo.eastron_dashboard OWNER TO mesavault; -- -- Name: edge_oee_eastron_diagnosis_latest; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_eastron_diagnosis_latest AS SELECT 1 AS sort_order, 'Comunicación'::text AS group_name, 'Edad último dato'::text AS metric, (edge_oee_eastron_dashboard.age_s)::numeric AS value, 's'::text AS unit, CASE WHEN (edge_oee_eastron_dashboard.comm_risk_level = 0) THEN 'OK'::text WHEN (edge_oee_eastron_dashboard.comm_risk_level = 1) THEN 'Warning'::text ELSE 'Peligro'::text END AS status, CASE WHEN (edge_oee_eastron_dashboard.comm_risk_level = 0) THEN 'Lectura reciente recibida por PostgreSQL'::text ELSE 'La lectura no es reciente o hay fallo de comunicación'::text END AS problem, CASE WHEN (edge_oee_eastron_dashboard.comm_risk_level = 0) THEN 'La captura industrial está viva'::text ELSE 'El dashboard puede estar mostrando un valor antiguo'::text END AS likely_impact, CASE WHEN (edge_oee_eastron_dashboard.comm_risk_level = 0) THEN 'Sin acción'::text ELSE 'Revisar RevPi, MQTT, sink, RS-485, SDM120-M y logs'::text END AS recommended_action FROM mv_hot.edge_oee_eastron_dashboard UNION ALL SELECT 2 AS sort_order, 'Energía'::text AS group_name, 'Potencia total'::text AS metric, edge_oee_eastron_dashboard.power_total_kw AS value, 'kW'::text AS unit, CASE WHEN (edge_oee_eastron_dashboard.power_total_kw IS NULL) THEN 'Warning'::text ELSE 'OK'::text END AS status, CASE WHEN (edge_oee_eastron_dashboard.power_total_kw IS NULL) THEN 'No hay potencia total disponible'::text ELSE 'Potencia total leída correctamente'::text END AS problem, CASE WHEN (edge_oee_eastron_dashboard.power_total_kw IS NULL) THEN 'No se puede validar carga eléctrica'::text ELSE 'Permite demostrar captura energética industrial'::text END AS likely_impact, CASE WHEN (edge_oee_eastron_dashboard.power_total_kw IS NULL) THEN 'Revisar mapa de registros Modbus'::text ELSE 'Sin acción'::text END AS recommended_action FROM mv_hot.edge_oee_eastron_dashboard; ALTER VIEW mv_hot.edge_oee_eastron_diagnosis_latest OWNER TO mesavault; -- -- Name: eastron_diagnosis_latest; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.eastron_diagnosis_latest AS SELECT sort_order, group_name, metric, value, unit, status, problem, likely_impact, recommended_action FROM mv_hot.edge_oee_eastron_diagnosis_latest; ALTER VIEW mv_edge_oee_ucepsa_demo.eastron_diagnosis_latest OWNER TO mesavault; -- -- Name: eastron_latest; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.eastron_latest AS SELECT id, ts, tenant, site, asset, source, meter_model, meter_id, machine_id, order_id, voltage_l1_v, voltage_l2_v, voltage_l3_v, current_l1_a, current_l2_a, current_l3_a, power_l1_kw, power_l2_kw, power_l3_kw, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, payload_json, ingest_ts FROM mv_hot.edge_oee_eastron_latest; ALTER VIEW mv_edge_oee_ucepsa_demo.eastron_latest OWNER TO mesavault; -- -- Name: eastron_readings; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.eastron_readings AS SELECT id, ts, tenant, site, asset, source, meter_model, meter_id, machine_id, order_id, voltage_l1_v, voltage_l2_v, voltage_l3_v, current_l1_a, current_l2_a, current_l3_a, power_l1_kw, power_l2_kw, power_l3_kw, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, payload_json, ingest_ts FROM mv_hot.edge_oee_eastron_readings; ALTER VIEW mv_edge_oee_ucepsa_demo.eastron_readings OWNER TO mesavault; -- -- Name: edge_oee_live_telemetry; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_live_telemetry AS SELECT ts, ingest_ts, GREATEST((EXTRACT(epoch FROM (now() - ingest_ts)))::integer, 0) AS age_s, tenant, site, asset, COALESCE(machine_id, (payload_json ->> 'machine_id'::text)) AS machine_id, COALESCE(order_id, (payload_json ->> 'order_id'::text)) AS order_id, voltage_l1_v, current_l1_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, CASE WHEN (payload_json ? 'machine_auto_signal'::text) THEN ((payload_json ->> 'machine_auto_signal'::text))::boolean ELSE NULL::boolean END AS machine_auto_signal, CASE WHEN (payload_json ? 'machine_running'::text) THEN ((payload_json ->> 'machine_running'::text))::boolean ELSE NULL::boolean END AS machine_running, CASE WHEN (payload_json ? 'cycle_pulse_count'::text) THEN ((payload_json ->> 'cycle_pulse_count'::text))::bigint ELSE NULL::bigint END AS cycle_pulse_count, CASE WHEN (payload_json ? 'cycle_rate_ppm'::text) THEN ((payload_json ->> 'cycle_rate_ppm'::text))::numeric ELSE NULL::numeric END AS cycle_rate_ppm, CASE WHEN ((payload_json ? 'last_cycle_age_s'::text) AND ((payload_json ->> 'last_cycle_age_s'::text) IS NOT NULL) AND ((payload_json ->> 'last_cycle_age_s'::text) <> 'null'::text)) THEN ((payload_json ->> 'last_cycle_age_s'::text))::numeric ELSE NULL::numeric END AS last_cycle_age_s, (payload_json -> 'digital_inputs'::text) AS digital_inputs, payload_json FROM mv_hot.edge_oee_eastron_readings r WHERE (asset = 'revpi_oee_node_01'::text) ORDER BY ingest_ts DESC; ALTER VIEW mv_hot.edge_oee_live_telemetry OWNER TO mesavault; -- -- Name: edge_oee_latest_machine_snapshot; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_latest_machine_snapshot AS SELECT DISTINCT ON (asset) ts, ingest_ts, age_s, tenant, site, asset, machine_id, order_id, voltage_l1_v, current_l1_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, machine_auto_signal, machine_running, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, digital_inputs, payload_json FROM mv_hot.edge_oee_live_telemetry ORDER BY asset, ingest_ts DESC; ALTER VIEW mv_hot.edge_oee_latest_machine_snapshot OWNER TO mesavault; -- -- Name: latest_machine_snapshot; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.latest_machine_snapshot AS SELECT ts, ingest_ts, age_s, tenant, site, asset, machine_id, order_id, voltage_l1_v, current_l1_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, machine_auto_signal, machine_running, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, digital_inputs, payload_json FROM mv_hot.edge_oee_latest_machine_snapshot; ALTER VIEW mv_edge_oee_ucepsa_demo.latest_machine_snapshot OWNER TO mesavault; -- -- Name: live_telemetry; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.live_telemetry AS SELECT ts, ingest_ts, age_s, tenant, site, asset, machine_id, order_id, voltage_l1_v, current_l1_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, machine_auto_signal, machine_running, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, digital_inputs, payload_json FROM mv_hot.edge_oee_live_telemetry; ALTER VIEW mv_edge_oee_ucepsa_demo.live_telemetry OWNER TO mesavault; -- -- Name: edge_oee_node_events; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_node_events ( id bigint NOT NULL, received_at timestamp with time zone DEFAULT now() NOT NULL, event_ts timestamp with time zone NOT NULL, topic text NOT NULL, tenant text NOT NULL, site text NOT NULL, vertical text NOT NULL, asset text NOT NULL, machine_id text, order_id text, event_type text NOT NULL, event_name text NOT NULL, previous_auto_signal boolean, new_auto_signal boolean, machine_running boolean, reason_pending boolean, cycle_pulse_count bigint, cycle_rate_ppm numeric(10,2), last_cycle_age_s numeric(10,2), payload_json jsonb DEFAULT '{}'::jsonb NOT NULL ); ALTER TABLE mv_hot.edge_oee_node_events OWNER TO mesavault; -- -- Name: edge_oee_machine_state_latest; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_machine_state_latest AS SELECT DISTINCT ON (asset) received_at, (EXTRACT(epoch FROM (now() - received_at)))::integer AS age_s, event_ts, tenant, site, vertical, asset, machine_id, event_name, previous_auto_signal, new_auto_signal, machine_running, reason_pending, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s FROM mv_hot.edge_oee_node_events WHERE (event_type = 'machine_state_changed'::text) ORDER BY asset, event_ts DESC; ALTER VIEW mv_hot.edge_oee_machine_state_latest OWNER TO mesavault; -- -- Name: machine_state_latest; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.machine_state_latest AS SELECT received_at, age_s, event_ts, tenant, site, vertical, asset, machine_id, event_name, previous_auto_signal, new_auto_signal, machine_running, reason_pending, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s FROM mv_hot.edge_oee_machine_state_latest; ALTER VIEW mv_edge_oee_ucepsa_demo.machine_state_latest OWNER TO mesavault; -- -- Name: edge_oee_machine_stops; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_machine_stops ( id bigint NOT NULL, tenant text NOT NULL, site text NOT NULL, vertical text NOT NULL, asset text NOT NULL, machine_id text, order_id text, started_at timestamp with time zone NOT NULL, ended_at timestamp with time zone, status text DEFAULT 'OPEN'::text NOT NULL, classification_status text DEFAULT 'PENDING'::text NOT NULL, cause_code text, operator_note text, value_hour_eur numeric(10,2) DEFAULT 36.00 NOT NULL, duration_s numeric(14,2), cost_eur numeric(14,2), start_event_name text, end_event_name text, start_payload_json jsonb DEFAULT '{}'::jsonb NOT NULL, end_payload_json jsonb DEFAULT '{}'::jsonb NOT NULL, created_at timestamp with time zone DEFAULT now() NOT NULL, updated_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_hot.edge_oee_machine_stops OWNER TO mesavault; -- -- Name: machine_stops; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.machine_stops AS SELECT id, tenant, site, vertical, asset, machine_id, order_id, started_at, ended_at, status, classification_status, cause_code, operator_note, value_hour_eur, duration_s, cost_eur, start_event_name, end_event_name, start_payload_json, end_payload_json, created_at, updated_at FROM mv_hot.edge_oee_machine_stops; ALTER VIEW mv_edge_oee_ucepsa_demo.machine_stops OWNER TO mesavault; -- -- Name: edge_oee_machine_targets; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_machine_targets ( machine_id text NOT NULL, machine_name text NOT NULL, asset text NOT NULL, target_cycle_rate_ppm numeric(10,2) DEFAULT 10.00 NOT NULL, value_hour_eur numeric(10,2) DEFAULT 36.00 NOT NULL, quality_pct_default numeric(10,2) DEFAULT 100.00 NOT NULL, notes text ); ALTER TABLE mv_hot.edge_oee_machine_targets OWNER TO mesavault; -- -- Name: machine_targets; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.machine_targets AS SELECT machine_id, machine_name, asset, target_cycle_rate_ppm, value_hour_eur, quality_pct_default, notes FROM mv_hot.edge_oee_machine_targets; ALTER VIEW mv_edge_oee_ucepsa_demo.machine_targets OWNER TO mesavault; -- -- Name: margin_cost_parameters; Type: TABLE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_demo.margin_cost_parameters ( id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'ucepsa_test'::text NOT NULL, scope_level text DEFAULT 'GLOBAL'::text NOT NULL, machine_id text, product_default_code text, energy_cost_eur_per_kwh numeric(14,6), material_cost_eur_per_kg numeric(14,6), machine_run_cost_eur_per_h numeric(14,4), labor_cost_eur_per_h numeric(14,4), overhead_cost_eur_per_h numeric(14,4), valid_from timestamp with time zone DEFAULT now() NOT NULL, valid_to timestamp with time zone, is_active boolean DEFAULT true NOT NULL, notes text, created_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_edge_oee_ucepsa_demo.margin_cost_parameters OWNER TO mesavault; -- -- Name: margin_cost_parameters_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_demo.margin_cost_parameters_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_demo.margin_cost_parameters_id_seq OWNER TO mesavault; -- -- Name: margin_cost_parameters_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_demo.margin_cost_parameters_id_seq OWNED BY mv_edge_oee_ucepsa_demo.margin_cost_parameters.id; -- -- Name: node_events; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.node_events AS SELECT id, received_at, event_ts, topic, tenant, site, vertical, asset, machine_id, order_id, event_type, event_name, previous_auto_signal, new_auto_signal, machine_running, reason_pending, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, payload_json FROM mv_hot.edge_oee_node_events; ALTER VIEW mv_edge_oee_ucepsa_demo.node_events OWNER TO mesavault; -- -- Name: edge_oee_node_events_recent; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_node_events_recent AS SELECT received_at, (EXTRACT(epoch FROM (now() - received_at)))::integer AS age_s, event_ts, tenant, site, vertical, asset, machine_id, order_id, event_type, event_name, previous_auto_signal, new_auto_signal, machine_running, reason_pending, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, topic, payload_json FROM mv_hot.edge_oee_node_events ORDER BY event_ts DESC; ALTER VIEW mv_hot.edge_oee_node_events_recent OWNER TO mesavault; -- -- Name: node_events_recent; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.node_events_recent AS SELECT received_at, age_s, event_ts, tenant, site, vertical, asset, machine_id, order_id, event_type, event_name, previous_auto_signal, new_auto_signal, machine_running, reason_pending, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, topic, payload_json FROM mv_hot.edge_oee_node_events_recent; ALTER VIEW mv_edge_oee_ucepsa_demo.node_events_recent OWNER TO mesavault; -- -- Name: odoo_order_commercials; Type: TABLE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_demo.odoo_order_commercials ( id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'ucepsa_test'::text NOT NULL, odoo_instance text NOT NULL, odoo_production_id integer NOT NULL, odoo_order_ref text NOT NULL, odoo_origin text, odoo_state text, product_id integer, product_default_code text, product_name text, product_uom text, product_standard_price numeric(14,4), product_list_price numeric(14,4), production_qty numeric(14,3), qty_producing numeric(14,3), production_uom text, sale_line_id integer, sale_order_id integer, sale_order_ref text, customer_id integer, customer_name text, sale_state text, sale_date_order timestamp with time zone, currency text, sale_line_qty numeric(14,3), sale_line_qty_delivered numeric(14,3), sale_price_unit numeric(14,4), sale_discount_pct numeric(10,2), revenue_net_eur numeric(14,4), revenue_total_eur numeric(14,4), raw_material_value_eur numeric(14,4), finished_value_eur numeric(14,4), material_cost_status text DEFAULT 'UNAVAILABLE'::text NOT NULL, stock_raw_moves_json jsonb DEFAULT '[]'::jsonb NOT NULL, stock_finished_moves_json jsonb DEFAULT '[]'::jsonb NOT NULL, raw_json jsonb DEFAULT '{}'::jsonb NOT NULL, snapshot_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_edge_oee_ucepsa_demo.odoo_order_commercials OWNER TO mesavault; -- -- Name: odoo_order_commercials_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_demo.odoo_order_commercials_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_demo.odoo_order_commercials_id_seq OWNER TO mesavault; -- -- Name: odoo_order_commercials_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_demo.odoo_order_commercials_id_seq OWNED BY mv_edge_oee_ucepsa_demo.odoo_order_commercials.id; -- -- Name: odoo_workcenter_map; Type: TABLE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_demo.odoo_workcenter_map ( id bigint NOT NULL, tenant text NOT NULL, site text NOT NULL, odoo_instance text NOT NULL, odoo_workcenter_id integer, odoo_workcenter_code text NOT NULL, odoo_workcenter_name text NOT NULL, machine_id text NOT NULL, asset text NOT NULL, is_active boolean DEFAULT true NOT NULL, created_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_edge_oee_ucepsa_demo.odoo_workcenter_map OWNER TO mesavault; -- -- Name: odoo_workcenter_map_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_demo.odoo_workcenter_map_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_demo.odoo_workcenter_map_id_seq OWNER TO mesavault; -- -- Name: odoo_workcenter_map_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_demo.odoo_workcenter_map_id_seq OWNED BY mv_edge_oee_ucepsa_demo.odoo_workcenter_map.id; -- -- Name: odoo_workorders_demo; Type: TABLE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_demo.odoo_workorders_demo ( id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'demo_edge_oee'::text NOT NULL, odoo_instance text DEFAULT 'odoo_demo'::text NOT NULL, odoo_workorder_id integer, odoo_production_id integer, odoo_order_ref text NOT NULL, odoo_state text NOT NULL, odoo_workcenter_code text NOT NULL, odoo_workcenter_name text NOT NULL, machine_id text NOT NULL, asset text NOT NULL, product text NOT NULL, qty_planned numeric(14,2), qty_done numeric(14,2), uom text, planned_cycles numeric(14,2), target_cycle_rate_ppm numeric(10,2), odoo_start timestamp with time zone NOT NULL, odoo_end timestamp with time zone, notes text, snapshot_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_edge_oee_ucepsa_demo.odoo_workorders_demo OWNER TO mesavault; -- -- Name: odoo_workorders_demo_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_demo.odoo_workorders_demo_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_demo.odoo_workorders_demo_id_seq OWNER TO mesavault; -- -- Name: odoo_workorders_demo_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_demo.odoo_workorders_demo_id_seq OWNED BY mv_edge_oee_ucepsa_demo.odoo_workorders_demo.id; -- -- Name: edge_oee_stop_causes; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_stop_causes ( cause_code text NOT NULL, cause_name text NOT NULL, description text, is_planned boolean DEFAULT false NOT NULL, is_active boolean DEFAULT true NOT NULL, sort_order integer DEFAULT 100 NOT NULL ); ALTER TABLE mv_hot.edge_oee_stop_causes OWNER TO mesavault; -- -- Name: edge_oee_open_stops; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_open_stops AS WITH src AS ( SELECT s_1.id, s_1.tenant, s_1.site, s_1.vertical, s_1.asset, s_1.machine_id, s_1.order_id, s_1.started_at, s_1.ended_at, s_1.status, s_1.classification_status, s_1.cause_code, s_1.operator_note, s_1.value_hour_eur, s_1.duration_s, s_1.cost_eur, s_1.start_event_name, s_1.end_event_name, s_1.start_payload_json, s_1.end_payload_json, s_1.created_at, s_1.updated_at, CASE WHEN (s_1.started_at > (s_1.created_at + '00:00:05'::interval)) THEN s_1.created_at ELSE s_1.started_at END AS effective_started_at FROM mv_hot.edge_oee_machine_stops s_1 ) SELECT s.id, s.tenant, s.site, s.vertical, s.asset, s.machine_id, s.order_id, s.started_at, (GREATEST(EXTRACT(epoch FROM (now() - s.effective_started_at)), (0)::numeric))::numeric(14,2) AS current_duration_s, round((GREATEST(EXTRACT(epoch FROM (now() - s.effective_started_at)), (0)::numeric) / 60.0), 2) AS current_duration_min, round(((GREATEST(EXTRACT(epoch FROM (now() - s.effective_started_at)), (0)::numeric) / 3600.0) * s.value_hour_eur), 2) AS current_cost_eur, s.status, s.classification_status, s.cause_code, c.cause_name, s.operator_note, s.value_hour_eur FROM (src s LEFT JOIN mv_hot.edge_oee_stop_causes c ON ((c.cause_code = s.cause_code))) WHERE (s.status = 'OPEN'::text) ORDER BY s.started_at DESC; ALTER VIEW mv_hot.edge_oee_open_stops OWNER TO mesavault; -- -- Name: open_stops; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.open_stops AS SELECT id, tenant, site, vertical, asset, machine_id, order_id, started_at, current_duration_s, current_duration_min, current_cost_eur, status, classification_status, cause_code, cause_name, operator_note, value_hour_eur FROM mv_hot.edge_oee_open_stops; ALTER VIEW mv_edge_oee_ucepsa_demo.open_stops OWNER TO mesavault; -- -- Name: raw_material_cost_parameters; Type: TABLE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_demo.raw_material_cost_parameters ( id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'ucepsa_test'::text NOT NULL, raw_product_default_code text NOT NULL, raw_product_name text, material_cost_eur_per_kg numeric(14,6) NOT NULL, source text DEFAULT 'MANUAL'::text NOT NULL, valid_from timestamp with time zone DEFAULT now() NOT NULL, valid_to timestamp with time zone, is_active boolean DEFAULT true NOT NULL, notes text, created_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_edge_oee_ucepsa_demo.raw_material_cost_parameters OWNER TO mesavault; -- -- Name: raw_material_cost_parameters_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_demo.raw_material_cost_parameters_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_demo.raw_material_cost_parameters_id_seq OWNER TO mesavault; -- -- Name: raw_material_cost_parameters_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_demo.raw_material_cost_parameters_id_seq OWNED BY mv_edge_oee_ucepsa_demo.raw_material_cost_parameters.id; -- -- Name: edge_oee_stop_cause_options; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_stop_cause_options AS SELECT cause_code, cause_name, description, is_planned, sort_order FROM mv_hot.edge_oee_stop_causes WHERE (is_active = true) ORDER BY sort_order, cause_name; ALTER VIEW mv_hot.edge_oee_stop_cause_options OWNER TO mesavault; -- -- Name: stop_cause_options; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.stop_cause_options AS SELECT cause_code, cause_name, description, is_planned, sort_order FROM mv_hot.edge_oee_stop_cause_options; ALTER VIEW mv_edge_oee_ucepsa_demo.stop_cause_options OWNER TO mesavault; -- -- Name: stop_causes; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.stop_causes AS SELECT cause_code, cause_name, description, is_planned, is_active, sort_order FROM mv_hot.edge_oee_stop_causes; ALTER VIEW mv_edge_oee_ucepsa_demo.stop_causes OWNER TO mesavault; -- -- Name: edge_oee_stop_summary_demo; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_stop_summary_demo AS WITH src AS ( SELECT s.id, s.tenant, s.site, s.vertical, s.asset, s.machine_id, s.order_id, s.started_at, s.ended_at, s.status, s.classification_status, s.cause_code, s.operator_note, s.value_hour_eur, s.duration_s, s.cost_eur, s.start_event_name, s.end_event_name, s.start_payload_json, s.end_payload_json, s.created_at, s.updated_at, c.cause_name, CASE WHEN (s.started_at > (s.created_at + '00:00:05'::interval)) THEN s.created_at ELSE s.started_at END AS effective_started_at FROM (mv_hot.edge_oee_machine_stops s LEFT JOIN mv_hot.edge_oee_stop_causes c ON ((c.cause_code = s.cause_code))) ), base AS ( SELECT src.id, src.tenant, src.site, src.vertical, src.asset, src.machine_id, src.order_id, src.started_at, src.ended_at, src.status, src.classification_status, src.cause_code, src.operator_note, src.value_hour_eur, src.duration_s, src.cost_eur, src.start_event_name, src.end_event_name, src.start_payload_json, src.end_payload_json, src.created_at, src.updated_at, src.cause_name, src.effective_started_at, CASE WHEN (src.duration_s IS NOT NULL) THEN GREATEST(src.duration_s, (0)::numeric) WHEN (src.ended_at IS NOT NULL) THEN GREATEST(EXTRACT(epoch FROM (src.ended_at - src.effective_started_at)), (0)::numeric) ELSE GREATEST(EXTRACT(epoch FROM (now() - src.effective_started_at)), (0)::numeric) END AS safe_duration_s FROM src ) SELECT COALESCE(cause_name, 'Pendiente de clasificar'::text) AS cause_name, COALESCE(cause_code, 'pending'::text) AS cause_code, count(*) AS stop_count, round((sum(safe_duration_s) / 60.0), 2) AS total_min, round(sum(COALESCE(cost_eur, ((safe_duration_s / 3600.0) * value_hour_eur))), 2) AS total_cost_eur FROM base GROUP BY COALESCE(cause_name, 'Pendiente de clasificar'::text), COALESCE(cause_code, 'pending'::text) ORDER BY (round(sum(COALESCE(cost_eur, ((safe_duration_s / 3600.0) * value_hour_eur))), 2)) DESC; ALTER VIEW mv_hot.edge_oee_stop_summary_demo OWNER TO mesavault; -- -- Name: stop_summary; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.stop_summary AS SELECT cause_name, cause_code, stop_count, total_min, total_cost_eur FROM mv_hot.edge_oee_stop_summary_demo; ALTER VIEW mv_edge_oee_ucepsa_demo.stop_summary OWNER TO mesavault; -- -- Name: edge_oee_stops_recent; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_stops_recent AS WITH src AS ( SELECT s.id, s.tenant, s.site, s.vertical, s.asset, s.machine_id, s.order_id, s.started_at, s.ended_at, s.status, s.classification_status, s.cause_code, s.operator_note, s.value_hour_eur, s.duration_s, s.cost_eur, s.start_event_name, s.end_event_name, s.start_payload_json, s.end_payload_json, s.created_at, s.updated_at, c.cause_name, c.is_planned, CASE WHEN (s.started_at > (s.created_at + '00:00:05'::interval)) THEN s.created_at ELSE s.started_at END AS effective_started_at FROM (mv_hot.edge_oee_machine_stops s LEFT JOIN mv_hot.edge_oee_stop_causes c ON ((c.cause_code = s.cause_code))) ), base AS ( SELECT src.id, src.tenant, src.site, src.vertical, src.asset, src.machine_id, src.order_id, src.started_at, src.ended_at, src.status, src.classification_status, src.cause_code, src.operator_note, src.value_hour_eur, src.duration_s, src.cost_eur, src.start_event_name, src.end_event_name, src.start_payload_json, src.end_payload_json, src.created_at, src.updated_at, src.cause_name, src.is_planned, src.effective_started_at, CASE WHEN (src.duration_s IS NOT NULL) THEN GREATEST(src.duration_s, (0)::numeric) WHEN (src.ended_at IS NOT NULL) THEN GREATEST(EXTRACT(epoch FROM (src.ended_at - src.effective_started_at)), (0)::numeric) ELSE GREATEST(EXTRACT(epoch FROM (now() - src.effective_started_at)), (0)::numeric) END AS safe_duration_s FROM src ) SELECT id, tenant, site, vertical, asset, machine_id, order_id, started_at, ended_at, (safe_duration_s)::numeric(14,2) AS duration_s, round((safe_duration_s / 60.0), 2) AS duration_min, COALESCE(cost_eur, round(((safe_duration_s / 3600.0) * value_hour_eur), 2)) AS cost_eur, status, classification_status, cause_code, cause_name, is_planned, operator_note, value_hour_eur, start_event_name, end_event_name, created_at, updated_at FROM base ORDER BY started_at DESC; ALTER VIEW mv_hot.edge_oee_stops_recent OWNER TO mesavault; -- -- Name: stops_recent; Type: VIEW; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_edge_oee_ucepsa_demo.stops_recent AS SELECT id, tenant, site, vertical, asset, machine_id, order_id, started_at, ended_at, duration_s, duration_min, cost_eur, status, classification_status, cause_code, cause_name, is_planned, operator_note, value_hour_eur, start_event_name, end_event_name, created_at, updated_at FROM mv_hot.edge_oee_stops_recent; ALTER VIEW mv_edge_oee_ucepsa_demo.stops_recent OWNER TO mesavault; -- -- Name: data_quality_contract_rules; Type: TABLE; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_prod.data_quality_contract_rules ( id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'ucepsa_test'::text NOT NULL, rule_code text NOT NULL, rule_name text NOT NULL, domain text NOT NULL, dimension text NOT NULL, severity text NOT NULL, owner_area text NOT NULL, applies_to text NOT NULL, description text NOT NULL, expected_condition text NOT NULL, blocking_for text, is_active boolean DEFAULT true NOT NULL, created_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_edge_oee_ucepsa_prod.data_quality_contract_rules OWNER TO mesavault; -- -- Name: data_quality_contract_rules_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_prod.data_quality_contract_rules_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_prod.data_quality_contract_rules_id_seq OWNER TO mesavault; -- -- Name: data_quality_contract_rules_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_prod.data_quality_contract_rules_id_seq OWNED BY mv_edge_oee_ucepsa_prod.data_quality_contract_rules.id; -- -- Name: margin_cost_parameters; Type: TABLE; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_prod.margin_cost_parameters ( id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'ucepsa_test'::text NOT NULL, scope_level text DEFAULT 'GLOBAL'::text NOT NULL, machine_id text, product_default_code text, energy_cost_eur_per_kwh numeric(14,6), material_cost_eur_per_kg numeric(14,6), machine_run_cost_eur_per_h numeric(14,4), labor_cost_eur_per_h numeric(14,4), overhead_cost_eur_per_h numeric(14,4), valid_from timestamp with time zone DEFAULT now() NOT NULL, valid_to timestamp with time zone, is_active boolean DEFAULT true NOT NULL, notes text, created_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_edge_oee_ucepsa_prod.margin_cost_parameters OWNER TO mesavault; -- -- Name: margin_cost_parameters_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_prod.margin_cost_parameters_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_prod.margin_cost_parameters_id_seq OWNER TO mesavault; -- -- Name: margin_cost_parameters_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_prod.margin_cost_parameters_id_seq OWNED BY mv_edge_oee_ucepsa_prod.margin_cost_parameters.id; -- -- Name: odoo_order_commercials; Type: TABLE; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_prod.odoo_order_commercials ( id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'ucepsa_test'::text NOT NULL, odoo_instance text NOT NULL, odoo_production_id integer NOT NULL, odoo_order_ref text NOT NULL, odoo_origin text, odoo_state text, product_id integer, product_default_code text, product_name text, product_uom text, product_standard_price numeric(14,4), product_list_price numeric(14,4), production_qty numeric(14,3), qty_producing numeric(14,3), production_uom text, sale_line_id integer, sale_order_id integer, sale_order_ref text, customer_id integer, customer_name text, sale_state text, sale_date_order timestamp with time zone, currency text, sale_line_qty numeric(14,3), sale_line_qty_delivered numeric(14,3), sale_price_unit numeric(14,4), sale_discount_pct numeric(10,2), revenue_net_eur numeric(14,4), revenue_total_eur numeric(14,4), raw_material_value_eur numeric(14,4), finished_value_eur numeric(14,4), material_cost_status text DEFAULT 'UNAVAILABLE'::text NOT NULL, stock_raw_moves_json jsonb DEFAULT '[]'::jsonb NOT NULL, stock_finished_moves_json jsonb DEFAULT '[]'::jsonb NOT NULL, raw_json jsonb DEFAULT '{}'::jsonb NOT NULL, snapshot_at timestamp with time zone DEFAULT now() NOT NULL ); ALTER TABLE mv_edge_oee_ucepsa_prod.odoo_order_commercials OWNER TO mesavault; -- -- Name: odoo_order_commercials_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_prod.odoo_order_commercials_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_prod.odoo_order_commercials_id_seq OWNER TO mesavault; -- -- Name: odoo_order_commercials_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_prod.odoo_order_commercials_id_seq OWNED BY mv_edge_oee_ucepsa_prod.odoo_order_commercials.id; -- -- Name: raw_material_cost_parameters; Type: TABLE; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE TABLE mv_edge_oee_ucepsa_prod.raw_material_cost_parameters ( id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'ucepsa_test'::text NOT NULL, raw_product_default_code text NOT NULL, raw_product_name text, material_cost_eur_per_kg numeric(14,6) NOT NULL, source text DEFAULT 'MANUAL'::text NOT NULL, valid_from timestamp with time zone DEFAULT now() NOT NULL, valid_to timestamp with time zone, is_active boolean DEFAULT true NOT NULL, notes text, created_at timestamp with time zone DEFAULT now() NOT NULL, raw_product_id integer, raw_uom text ); ALTER TABLE mv_edge_oee_ucepsa_prod.raw_material_cost_parameters OWNER TO mesavault; -- -- Name: raw_material_cost_parameters_id_seq; Type: SEQUENCE; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE SEQUENCE mv_edge_oee_ucepsa_prod.raw_material_cost_parameters_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_edge_oee_ucepsa_prod.raw_material_cost_parameters_id_seq OWNER TO mesavault; -- -- Name: raw_material_cost_parameters_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER SEQUENCE mv_edge_oee_ucepsa_prod.raw_material_cost_parameters_id_seq OWNED BY mv_edge_oee_ucepsa_prod.raw_material_cost_parameters.id; -- -- Name: edge_oee_loss_summary_demo; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_loss_summary_demo ( cause text NOT NULL, hours_month numeric(10,2) NOT NULL, value_hour_eur numeric(10,2) NOT NULL, monthly_cost_eur numeric(10,2) NOT NULL, recommended_action text NOT NULL, effort text, priority text, machine_focus text ); ALTER TABLE mv_hot.edge_oee_loss_summary_demo OWNER TO mesavault; -- -- Name: edge_oee_actions_demo; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_actions_demo AS SELECT cause AS "Causa", monthly_cost_eur AS "Impacto estimado €/mes", effort AS "Esfuerzo", priority AS "Prioridad", recommended_action AS "Acción recomendada", CASE WHEN (cause = 'Ajuste de sellado'::text) THEN (4000)::numeric ELSE NULL::numeric END AS "Inversión ejemplo €", CASE WHEN (cause = 'Ajuste de sellado'::text) THEN round(((4000)::numeric / NULLIF(monthly_cost_eur, (0)::numeric)), 1) ELSE NULL::numeric END AS "Payback ejemplo meses" FROM mv_hot.edge_oee_loss_summary_demo ORDER BY monthly_cost_eur DESC; ALTER VIEW mv_hot.edge_oee_actions_demo OWNER TO mesavault; -- -- Name: edge_oee_data_quality_demo; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_data_quality_demo ( metric_id text NOT NULL, metric text NOT NULL, value_numeric numeric(10,2), value_text text, unit text, status text NOT NULL, problem text, likely_impact text, recommended_action text, sort_order integer NOT NULL ); ALTER TABLE mv_hot.edge_oee_data_quality_demo OWNER TO mesavault; -- -- Name: edge_oee_data_quality_dashboard_demo; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_data_quality_dashboard_demo AS SELECT sort_order, metric AS "Indicador", COALESCE((value_numeric)::text, value_text) AS "Valor", unit AS "Unidad", status AS "Estado", problem AS "Qué está mal", likely_impact AS "Impacto probable", recommended_action AS "Qué revisar / acción" FROM mv_hot.edge_oee_data_quality_demo ORDER BY sort_order; ALTER VIEW mv_hot.edge_oee_data_quality_dashboard_demo OWNER TO mesavault; -- -- Name: edge_oee_eastron_readings_id_seq; Type: SEQUENCE; Schema: mv_hot; Owner: mesavault -- CREATE SEQUENCE mv_hot.edge_oee_eastron_readings_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_hot.edge_oee_eastron_readings_id_seq OWNER TO mesavault; -- -- Name: edge_oee_eastron_readings_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_hot; Owner: mesavault -- ALTER SEQUENCE mv_hot.edge_oee_eastron_readings_id_seq OWNED BY mv_hot.edge_oee_eastron_readings.id; -- -- Name: edge_oee_energy_demo; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_energy_demo ( ts timestamp with time zone NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'demo_edge_oee'::text NOT NULL, machine_id text NOT NULL, order_id text, power_kw numeric(10,3), kwh_total numeric(14,3), source text DEFAULT 'demo'::text, payload_json jsonb DEFAULT '{}'::jsonb ); ALTER TABLE mv_hot.edge_oee_energy_demo OWNER TO mesavault; -- -- Name: edge_oee_events_demo; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_events_demo ( event_id bigint NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'demo_edge_oee'::text NOT NULL, machine_id text NOT NULL, order_id text, event_type text NOT NULL, cause text NOT NULL, start_time timestamp with time zone NOT NULL, end_time timestamp with time zone NOT NULL, duration_min numeric(10,2) NOT NULL, cost_eur numeric(10,2) DEFAULT 0 NOT NULL, source text DEFAULT 'mesavault_demo'::text NOT NULL, notes text ); ALTER TABLE mv_hot.edge_oee_events_demo OWNER TO mesavault; -- -- Name: edge_oee_events_demo_event_id_seq; Type: SEQUENCE; Schema: mv_hot; Owner: mesavault -- CREATE SEQUENCE mv_hot.edge_oee_events_demo_event_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_hot.edge_oee_events_demo_event_id_seq OWNER TO mesavault; -- -- Name: edge_oee_events_demo_event_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_hot; Owner: mesavault -- ALTER SEQUENCE mv_hot.edge_oee_events_demo_event_id_seq OWNED BY mv_hot.edge_oee_events_demo.event_id; -- -- Name: edge_oee_executive_summary_demo; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_executive_summary_demo AS WITH losses AS ( SELECT sum(edge_oee_loss_summary_demo.hours_month) AS classified_loss_hours, sum(edge_oee_loss_summary_demo.monthly_cost_eur) AS estimated_loss_cost_eur FROM mv_hot.edge_oee_loss_summary_demo ), principal AS ( SELECT edge_oee_loss_summary_demo.cause FROM mv_hot.edge_oee_loss_summary_demo ORDER BY edge_oee_loss_summary_demo.monthly_cost_eur DESC LIMIT 1 ) SELECT now() AS evaluated_at, 816.0::numeric(10,1) AS hours_analyzed, losses.classified_loss_hours, losses.estimated_loss_cost_eur, principal.cause AS main_loss_cause, 'Cortadora 2'::text AS machine_with_more_losses, 5.0::numeric(10,1) AS unclassified_stop_hours, 7 AS orders_with_odoo_machine_discrepancy FROM losses, principal; ALTER VIEW mv_hot.edge_oee_executive_summary_demo OWNER TO mesavault; -- -- Name: edge_oee_kpi_cards_demo; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_kpi_cards_demo AS SELECT 1 AS sort_order, 'Horas analizadas'::text AS kpi, edge_oee_executive_summary_demo.hours_analyzed AS value, 'h'::text AS unit, 'OK'::text AS status FROM mv_hot.edge_oee_executive_summary_demo UNION ALL SELECT 2 AS sort_order, 'Pérdidas clasificadas'::text AS kpi, edge_oee_executive_summary_demo.classified_loss_hours AS value, 'h/mes'::text AS unit, 'Warning'::text AS status FROM mv_hot.edge_oee_executive_summary_demo UNION ALL SELECT 3 AS sort_order, 'Coste estimado de pérdidas'::text AS kpi, edge_oee_executive_summary_demo.estimated_loss_cost_eur AS value, '€/mes'::text AS unit, 'Warning'::text AS status FROM mv_hot.edge_oee_executive_summary_demo UNION ALL SELECT 4 AS sort_order, 'Paros sin causa'::text AS kpi, edge_oee_executive_summary_demo.unclassified_stop_hours AS value, 'h/mes'::text AS unit, 'Warning'::text AS status FROM mv_hot.edge_oee_executive_summary_demo UNION ALL SELECT 5 AS sort_order, 'Órdenes con discrepancia Odoo/máquina'::text AS kpi, edge_oee_executive_summary_demo.orders_with_odoo_machine_discrepancy AS value, 'órdenes'::text AS unit, 'Warning'::text AS status FROM mv_hot.edge_oee_executive_summary_demo; ALTER VIEW mv_hot.edge_oee_kpi_cards_demo OWNER TO mesavault; -- -- Name: edge_oee_machine_stops_backup_cort00_20260622_175800; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_machine_stops_backup_cort00_20260622_175800 ( id bigint, tenant text, site text, vertical text, asset text, machine_id text, order_id text, started_at timestamp with time zone, ended_at timestamp with time zone, status text, classification_status text, cause_code text, operator_note text, value_hour_eur numeric(10,2), duration_s numeric(14,2), cost_eur numeric(14,2), start_event_name text, end_event_name text, start_payload_json jsonb, end_payload_json jsonb, created_at timestamp with time zone, updated_at timestamp with time zone ); ALTER TABLE mv_hot.edge_oee_machine_stops_backup_cort00_20260622_175800 OWNER TO mesavault; -- -- Name: edge_oee_machine_stops_id_seq; Type: SEQUENCE; Schema: mv_hot; Owner: mesavault -- CREATE SEQUENCE mv_hot.edge_oee_machine_stops_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_hot.edge_oee_machine_stops_id_seq OWNER TO mesavault; -- -- Name: edge_oee_machine_stops_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_hot; Owner: mesavault -- ALTER SEQUENCE mv_hot.edge_oee_machine_stops_id_seq OWNED BY mv_hot.edge_oee_machine_stops.id; -- -- Name: edge_oee_machines; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_machines ( machine_id text NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'demo_edge_oee'::text NOT NULL, name text NOT NULL, area text DEFAULT 'corte'::text NOT NULL, machine_type text DEFAULT 'cortadora'::text NOT NULL, value_hour_eur numeric(10,2) NOT NULL, standard_kg_h numeric(10,2), sale_price_eur_kg numeric(10,2), transformation_cost_eur_kg numeric(10,2), raw_material_cost_eur_kg numeric(10,2), notes text ); ALTER TABLE mv_hot.edge_oee_machines OWNER TO mesavault; -- -- Name: edge_oee_node_events_id_seq; Type: SEQUENCE; Schema: mv_hot; Owner: mesavault -- CREATE SEQUENCE mv_hot.edge_oee_node_events_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_hot.edge_oee_node_events_id_seq OWNER TO mesavault; -- -- Name: edge_oee_node_events_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_hot; Owner: mesavault -- ALTER SEQUENCE mv_hot.edge_oee_node_events_id_seq OWNED BY mv_hot.edge_oee_node_events.id; -- -- Name: edge_oee_orders_demo; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_orders_demo ( order_id text NOT NULL, tenant text DEFAULT 'ucepsa'::text NOT NULL, site text DEFAULT 'demo_edge_oee'::text NOT NULL, machine_id text NOT NULL, product text NOT NULL, odoo_start timestamp with time zone NOT NULL, odoo_end timestamp with time zone NOT NULL, qty_planned numeric(14,2), qty_done numeric(14,2), scrap_qty numeric(14,2), uom text DEFAULT 'unidades'::text, commercial_note text ); ALTER TABLE mv_hot.edge_oee_orders_demo OWNER TO mesavault; -- -- Name: edge_oee_order_timeline_demo; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_order_timeline_demo AS SELECT o.odoo_start AS "time", (o.odoo_start + '00:01:00'::interval) AS time_end, o.order_id, o.machine_id, m.name AS machine_name, o.product, 'ODOO'::text AS source, 'ODOO_START'::text AS state, 'Odoo inicia la orden'::text AS detail, (0)::numeric AS duration_min, (0)::numeric AS cost_eur, 1 AS sort_order FROM (mv_hot.edge_oee_orders_demo o JOIN mv_hot.edge_oee_machines m ON ((m.machine_id = o.machine_id))) UNION ALL SELECT e.start_time AS "time", e.end_time AS time_end, e.order_id, e.machine_id, m.name AS machine_name, COALESCE(o.product, 'Sin orden activa'::text) AS product, 'MESAVAULT'::text AS source, e.event_type AS state, e.cause AS detail, e.duration_min, e.cost_eur, 2 AS sort_order FROM ((mv_hot.edge_oee_events_demo e JOIN mv_hot.edge_oee_machines m ON ((m.machine_id = e.machine_id))) LEFT JOIN mv_hot.edge_oee_orders_demo o ON ((o.order_id = e.order_id))) UNION ALL SELECT o.odoo_end AS "time", (o.odoo_end + '00:01:00'::interval) AS time_end, o.order_id, o.machine_id, m.name AS machine_name, o.product, 'ODOO'::text AS source, 'ODOO_END'::text AS state, 'Odoo finaliza la orden'::text AS detail, (0)::numeric AS duration_min, (0)::numeric AS cost_eur, 3 AS sort_order FROM (mv_hot.edge_oee_orders_demo o JOIN mv_hot.edge_oee_machines m ON ((m.machine_id = o.machine_id))); ALTER VIEW mv_hot.edge_oee_order_timeline_demo OWNER TO mesavault; -- -- Name: edge_oee_pareto_demo; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_pareto_demo AS SELECT rank() OVER (ORDER BY monthly_cost_eur DESC) AS ranking, cause, hours_month, value_hour_eur, monthly_cost_eur, recommended_action, effort, priority, machine_focus FROM mv_hot.edge_oee_loss_summary_demo ORDER BY monthly_cost_eur DESC; ALTER VIEW mv_hot.edge_oee_pareto_demo OWNER TO mesavault; -- -- Name: edge_oee_quality_cases_demo; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.edge_oee_quality_cases_demo ( case_id text NOT NULL, order_id text, machine_id text, product text, claim text, sealing_adjustment_stops integer, sealing_adjustment_min numeric(10,2), microstops_count integer, scrap_pct numeric(10,2), energy_vs_avg_pct numeric(10,2), interpretation text, recommended_action text ); ALTER TABLE mv_hot.edge_oee_quality_cases_demo OWNER TO mesavault; -- -- Name: edge_oee_quality_case_demo; Type: VIEW; Schema: mv_hot; Owner: mesavault -- CREATE VIEW mv_hot.edge_oee_quality_case_demo AS SELECT qc.case_id, qc.order_id, m.name AS machine_name, qc.product, qc.claim, qc.sealing_adjustment_stops, qc.sealing_adjustment_min, qc.microstops_count, qc.scrap_pct, qc.energy_vs_avg_pct, qc.interpretation, qc.recommended_action FROM (mv_hot.edge_oee_quality_cases_demo qc JOIN mv_hot.edge_oee_machines m ON ((m.machine_id = qc.machine_id))); ALTER VIEW mv_hot.edge_oee_quality_case_demo OWNER TO mesavault; -- -- Name: odoo_order_state_current; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.odoo_order_state_current ( tenant text NOT NULL, site text NOT NULL, machine_id text NOT NULL, topic text, mqtt_ts timestamp with time zone, received_at timestamp with time zone DEFAULT now() NOT NULL, source text, workcenter_id bigint, workcenter_name text, workcenter_display_name text, order_present boolean, order_coherent boolean, odoo_state text, reason text, workorder_id text, production_order text, product text, waiting_count integer, ready_count integer, progress_count integer, payload_hash text, payload_json jsonb NOT NULL ); ALTER TABLE mv_hot.odoo_order_state_current OWNER TO mesavault; -- -- Name: odoo_order_state_events; Type: TABLE; Schema: mv_hot; Owner: mesavault -- CREATE TABLE mv_hot.odoo_order_state_events ( id bigint NOT NULL, tenant text NOT NULL, site text NOT NULL, machine_id text NOT NULL, topic text, mqtt_ts timestamp with time zone, received_at timestamp with time zone DEFAULT now() NOT NULL, odoo_state text, order_present boolean, order_coherent boolean, production_order text, product text, reason text, waiting_count integer, ready_count integer, progress_count integer, payload_hash text NOT NULL, payload_json jsonb NOT NULL ); ALTER TABLE mv_hot.odoo_order_state_events OWNER TO mesavault; -- -- Name: odoo_order_state_events_id_seq; Type: SEQUENCE; Schema: mv_hot; Owner: mesavault -- CREATE SEQUENCE mv_hot.odoo_order_state_events_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; ALTER SEQUENCE mv_hot.odoo_order_state_events_id_seq OWNER TO mesavault; -- -- Name: odoo_order_state_events_id_seq; Type: SEQUENCE OWNED BY; Schema: mv_hot; Owner: mesavault -- ALTER SEQUENCE mv_hot.odoo_order_state_events_id_seq OWNED BY mv_hot.odoo_order_state_events.id; -- -- Name: order_execution_report_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_execution_report_v1 AS WITH orders AS ( SELECT o_1.id, o_1.tenant, o_1.site, o_1.odoo_instance, o_1.odoo_workorder_id, o_1.odoo_production_id, o_1.odoo_order_ref, o_1.odoo_state, o_1.odoo_workcenter_code, o_1.odoo_workcenter_name, o_1.machine_id, o_1.asset, o_1.product, o_1.qty_planned, o_1.qty_done, o_1.uom, o_1.planned_cycles, o_1.target_cycle_rate_ppm, o_1.odoo_start, o_1.odoo_end, o_1.notes, o_1.snapshot_at, o_1.odoo_start AS start_ts, CASE WHEN (o_1.odoo_state = ANY (ARRAY['done'::text, 'to_close'::text, 'cancel'::text])) THEN COALESCE(o_1.odoo_end, o_1.snapshot_at) ELSE COALESCE(( SELECT max(r.ingest_ts) AS max FROM mv_hot.edge_oee_eastron_readings r WHERE ((r.machine_id = o_1.machine_id) AND (r.ingest_ts >= o_1.odoo_start) AND (r.comm_ok = true) AND (r.meter_model = 'Eastron SDM120-M'::text))), o_1.snapshot_at) END AS end_ts FROM mv_edge_oee_ucepsa_demo.odoo_workorders_demo o_1 WHERE ((o_1.odoo_instance = 'odoo_ucepsa_test'::text) AND (o_1.machine_id IS NOT NULL) AND (o_1.odoo_start IS NOT NULL)) ), energy AS ( SELECT o_1.id AS order_row_id, count(r.id) AS energy_samples, min(r.ingest_ts) AS energy_first_ts, max(r.ingest_ts) AS energy_last_ts, min(r.import_kwh) AS start_import_kwh, max(r.import_kwh) AS end_import_kwh, round((max(r.import_kwh) - min(r.import_kwh)), 3) AS kwh_consumed, round(avg(r.power_total_kw), 3) AS avg_kw, round(max(r.power_total_kw), 3) AS max_kw FROM (orders o_1 LEFT JOIN mv_hot.edge_oee_eastron_readings r ON (((r.machine_id = o_1.machine_id) AND (r.ingest_ts >= o_1.start_ts) AND (r.ingest_ts <= o_1.end_ts) AND (r.comm_ok = true) AND (r.meter_model = 'Eastron SDM120-M'::text)))) GROUP BY o_1.id ), cycles AS ( SELECT o_1.id AS order_row_id, count(r.id) AS telemetry_samples, min(r.ingest_ts) AS telemetry_first_ts, max(r.ingest_ts) AS telemetry_last_ts, min(((r.payload_json ->> 'cycle_pulse_count'::text))::bigint) AS min_cycle_pulse_count, max(((r.payload_json ->> 'cycle_pulse_count'::text))::bigint) AS max_cycle_pulse_count, GREATEST((max(((r.payload_json ->> 'cycle_pulse_count'::text))::bigint) - min(((r.payload_json ->> 'cycle_pulse_count'::text))::bigint)), (0)::bigint) AS real_cycle_delta, round(avg(((r.payload_json ->> 'cycle_rate_ppm'::text))::numeric), 2) AS avg_cycle_rate_ppm, round(avg(NULLIF(((r.payload_json ->> 'cycle_rate_ppm'::text))::numeric, (0)::numeric)), 2) AS avg_nonzero_cycle_rate_ppm FROM (orders o_1 LEFT JOIN mv_hot.edge_oee_eastron_readings r ON (((r.machine_id = o_1.machine_id) AND (r.ingest_ts >= o_1.start_ts) AND (r.ingest_ts <= o_1.end_ts) AND (r.comm_ok = true) AND (r.meter_model = 'Eastron SDM120-M'::text) AND (r.payload_json ? 'cycle_pulse_count'::text)))) GROUP BY o_1.id ), stops AS ( SELECT o_1.id AS order_row_id, count(ms.id) AS stop_count, round((COALESCE(sum(GREATEST(EXTRACT(epoch FROM (LEAST(COALESCE(ms.ended_at, o_1.end_ts), o_1.end_ts) - GREATEST(ms.started_at, o_1.start_ts))), (0)::numeric)), (0)::numeric) / 60.0), 2) AS stop_min, count(ms.id) FILTER (WHERE (ms.classification_status = 'PENDING'::text)) AS pending_stops, count(ms.id) FILTER (WHERE (ms.classification_status = 'CLASSIFIED'::text)) AS classified_stops, round(COALESCE(sum(((GREATEST(EXTRACT(epoch FROM (LEAST(COALESCE(ms.ended_at, o_1.end_ts), o_1.end_ts) - GREATEST(ms.started_at, o_1.start_ts))), (0)::numeric) / 3600.0) * ms.value_hour_eur)), (0)::numeric), 2) AS stop_cost_eur FROM (orders o_1 LEFT JOIN mv_hot.edge_oee_machine_stops ms ON (((ms.machine_id = o_1.machine_id) AND (ms.started_at < o_1.end_ts) AND (COALESCE(ms.ended_at, now()) > o_1.start_ts)))) GROUP BY o_1.id ) SELECT o.id AS order_row_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, o.start_ts, o.end_ts, round((EXTRACT(epoch FROM (o.end_ts - o.start_ts)) / 60.0), 2) AS window_min, COALESCE(c.telemetry_samples, (0)::bigint) AS telemetry_samples, c.telemetry_first_ts, c.telemetry_last_ts, COALESCE(c.min_cycle_pulse_count, (0)::bigint) AS min_cycle_pulse_count, COALESCE(c.max_cycle_pulse_count, (0)::bigint) AS max_cycle_pulse_count, COALESCE(c.real_cycle_delta, (0)::bigint) AS real_cycle_delta, c.avg_cycle_rate_ppm, c.avg_nonzero_cycle_rate_ppm, COALESCE(e.energy_samples, (0)::bigint) AS energy_samples, e.energy_first_ts, e.energy_last_ts, e.start_import_kwh, e.end_import_kwh, e.kwh_consumed, e.avg_kw, e.max_kw, COALESCE(s.stop_count, (0)::bigint) AS stop_count, COALESCE(s.stop_min, (0)::numeric) AS stop_min, COALESCE(s.classified_stops, (0)::bigint) AS classified_stops, COALESCE(s.pending_stops, (0)::bigint) AS pending_stops, COALESCE(s.stop_cost_eur, (0)::numeric) AS stop_cost_eur, CASE WHEN (COALESCE(c.telemetry_samples, (0)::bigint) = 0) THEN 'SIN_TELEMETRIA_EN_VENTANA'::text WHEN (COALESCE(e.energy_samples, (0)::bigint) = 0) THEN 'SIN_ENERGIA_EN_VENTANA'::text WHEN (o.odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text, 'started'::text])) THEN 'PARCIAL_ORDEN_EN_CURSO'::text WHEN (COALESCE(s.pending_stops, (0)::bigint) > 0) THEN 'PARCIAL_PAROS_PENDIENTES'::text ELSE 'CERRADO_CALCULABLE'::text END AS report_status, CASE WHEN (COALESCE(c.telemetry_samples, (0)::bigint) = 0) THEN 'No hay telemetría Edge-OEE dentro de la ventana de la orden.'::text WHEN (COALESCE(e.energy_samples, (0)::bigint) = 0) THEN 'No hay muestras energéticas válidas dentro de la ventana de la orden.'::text WHEN (o.odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text, 'started'::text])) THEN 'La orden sigue en curso. El informe es parcial.'::text WHEN (COALESCE(s.pending_stops, (0)::bigint) > 0) THEN 'Existen paros pendientes de clasificación.'::text ELSE 'Orden cerrada con datos suficientes para informe.'::text END AS report_status_description FROM (((orders o LEFT JOIN cycles c ON ((c.order_row_id = o.id))) LEFT JOIN energy e ON ((e.order_row_id = o.id))) LEFT JOIN stops s ON ((s.order_row_id = o.id))); ALTER VIEW mv_reports_ucepsa_demo.order_execution_report_v1 OWNER TO mesavault; -- -- Name: order_execution_energy_timeseries_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_execution_energy_timeseries_v1 AS WITH base AS ( SELECT r.order_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_workorder_id, r.odoo_production_id, r.odoo_order_ref, r.odoo_state, r.product, r.machine_id, r.asset, r.start_ts AS order_start_ts, r.end_ts AS order_end_ts, r.report_status, e.id AS reading_id, e.ts AS meter_ts, e.ingest_ts AS "time", e.voltage_l1_v, e.current_l1_a, e.power_total_kw, e.frequency_hz, e.import_kwh, e.export_kwh, e.comm_ok, e.error_text, CASE WHEN (e.payload_json ? 'machine_running'::text) THEN ((e.payload_json ->> 'machine_running'::text))::boolean ELSE NULL::boolean END AS machine_running, CASE WHEN (e.payload_json ? 'machine_auto_signal'::text) THEN ((e.payload_json ->> 'machine_auto_signal'::text))::boolean ELSE NULL::boolean END AS machine_auto_signal, CASE WHEN (e.payload_json ? 'cycle_pulse_count'::text) THEN (NULLIF((e.payload_json ->> 'cycle_pulse_count'::text), ''::text))::bigint ELSE NULL::bigint END AS cycle_pulse_count, CASE WHEN (e.payload_json ? 'cycle_rate_ppm'::text) THEN (NULLIF((e.payload_json ->> 'cycle_rate_ppm'::text), ''::text))::numeric ELSE NULL::numeric END AS cycle_rate_ppm, CASE WHEN (e.payload_json ? 'last_cycle_age_s'::text) THEN (NULLIF((e.payload_json ->> 'last_cycle_age_s'::text), ''::text))::numeric ELSE NULL::numeric END AS last_cycle_age_s, e.payload_json FROM (mv_reports_ucepsa_demo.order_execution_report_v1 r JOIN mv_hot.edge_oee_eastron_readings e ON (((e.machine_id = r.machine_id) AND (e.ingest_ts >= r.start_ts) AND (e.ingest_ts <= r.end_ts) AND (e.meter_model = 'Eastron SDM120-M'::text)))) ), enriched AS ( SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.product, b.machine_id, b.asset, b.order_start_ts, b.order_end_ts, b.report_status, b.reading_id, b.meter_ts, b."time", b.voltage_l1_v, b.current_l1_a, b.power_total_kw, b.frequency_hz, b.import_kwh, b.export_kwh, b.comm_ok, b.error_text, b.machine_running, b.machine_auto_signal, b.cycle_pulse_count, b.cycle_rate_ppm, b.last_cycle_age_s, b.payload_json, round((EXTRACT(epoch FROM (b."time" - b.order_start_ts)) / 60.0), 2) AS minute_from_order_start, round(EXTRACT(epoch FROM (b."time" - lag(b."time") OVER (PARTITION BY b.order_row_id ORDER BY b."time"))), 2) AS sample_gap_s, min(b.import_kwh) FILTER (WHERE ((b.comm_ok = true) AND (b.import_kwh IS NOT NULL))) OVER (PARTITION BY b.order_row_id) AS order_start_import_kwh, min(b.cycle_pulse_count) FILTER (WHERE (b.cycle_pulse_count IS NOT NULL)) OVER (PARTITION BY b.order_row_id) AS order_start_cycle_pulse_count FROM base b ) SELECT order_row_id, tenant, site, odoo_instance, odoo_workorder_id, odoo_production_id, odoo_order_ref, odoo_state, product, machine_id, asset, order_start_ts, order_end_ts, report_status, reading_id, meter_ts, "time", minute_from_order_start, sample_gap_s, voltage_l1_v, current_l1_a, power_total_kw, frequency_hz, import_kwh, export_kwh, round(GREATEST((import_kwh - order_start_import_kwh), (0)::numeric), 3) AS kwh_from_order_start, comm_ok, error_text, machine_running, machine_auto_signal, cycle_pulse_count, GREATEST((cycle_pulse_count - order_start_cycle_pulse_count), (0)::bigint) AS cycles_from_order_start, cycle_rate_ppm, last_cycle_age_s, CASE WHEN (comm_ok = false) THEN 'BAD_COMMUNICATION'::text WHEN ((sample_gap_s IS NOT NULL) AND (sample_gap_s > (30)::numeric)) THEN 'TELEMETRY_GAP'::text WHEN (power_total_kw IS NULL) THEN 'NO_POWER_VALUE'::text WHEN (import_kwh IS NULL) THEN 'NO_IMPORT_KWH'::text ELSE 'OK'::text END AS sample_quality_status, payload_json FROM enriched; ALTER VIEW mv_reports_ucepsa_demo.order_execution_energy_timeseries_v1 OWNER TO mesavault; -- -- Name: order_execution_data_quality_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_execution_data_quality_v1 AS WITH base AS ( SELECT r.order_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_workorder_id, r.odoo_production_id, r.odoo_order_ref, r.odoo_state, r.odoo_workcenter_code, r.odoo_workcenter_name, r.machine_id, r.asset, r.product, r.qty_planned, r.qty_done, r.uom, r.planned_cycles, r.target_cycle_rate_ppm, r.start_ts, r.end_ts, r.window_min, r.telemetry_samples, r.telemetry_first_ts, r.telemetry_last_ts, r.min_cycle_pulse_count, r.max_cycle_pulse_count, r.real_cycle_delta, r.avg_cycle_rate_ppm, r.avg_nonzero_cycle_rate_ppm, r.energy_samples, r.energy_first_ts, r.energy_last_ts, r.start_import_kwh, r.end_import_kwh, r.kwh_consumed, r.avg_kw, r.max_kw, r.stop_count, r.stop_min, r.classified_stops, r.pending_stops, r.stop_cost_eur, r.report_status, r.report_status_description, GREATEST(((floor((EXTRACT(epoch FROM (r.end_ts - r.start_ts)) / 10.0)))::integer + 1), 1) AS expected_samples_10s FROM mv_reports_ucepsa_demo.order_execution_report_v1 r ), gap_stats AS ( SELECT t.order_row_id, count(*) FILTER (WHERE ((t.sample_gap_s IS NOT NULL) AND (t.sample_gap_s > (30)::numeric))) AS telemetry_gap_count_30s, round(max(t.sample_gap_s), 2) AS max_sample_gap_s, round(avg(t.sample_gap_s) FILTER (WHERE (t.sample_gap_s IS NOT NULL)), 2) AS avg_sample_gap_s, count(*) FILTER (WHERE (t.sample_quality_status <> 'OK'::text)) AS non_ok_samples FROM mv_reports_ucepsa_demo.order_execution_energy_timeseries_v1 t GROUP BY t.order_row_id ), scored AS ( SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.product, b.machine_id, b.asset, b.start_ts, b.end_ts, b.window_min, b.qty_planned, b.qty_done, b.uom, b.planned_cycles, b.target_cycle_rate_ppm, b.telemetry_samples, b.energy_samples, b.expected_samples_10s, round((((COALESCE(b.telemetry_samples, (0)::bigint))::numeric / (NULLIF(b.expected_samples_10s, 0))::numeric) * 100.0), 2) AS telemetry_sample_coverage_pct, b.telemetry_first_ts, b.telemetry_last_ts, b.energy_first_ts, b.energy_last_ts, b.real_cycle_delta, b.avg_cycle_rate_ppm, b.avg_nonzero_cycle_rate_ppm, b.kwh_consumed, b.avg_kw, b.max_kw, b.stop_count, b.stop_min, b.classified_stops, b.pending_stops, b.stop_cost_eur, COALESCE(g.telemetry_gap_count_30s, (0)::bigint) AS telemetry_gap_count_30s, COALESCE(g.max_sample_gap_s, (0)::numeric) AS max_sample_gap_s, COALESCE(g.avg_sample_gap_s, (0)::numeric) AS avg_sample_gap_s, COALESCE(g.non_ok_samples, (0)::bigint) AS non_ok_samples, b.report_status, b.report_status_description, CASE WHEN (COALESCE(b.planned_cycles, (0)::numeric) <= (0)::numeric) THEN 'SIN_OBJETIVO_CICLOS'::text WHEN ((COALESCE(b.real_cycle_delta, (0)::bigint) = 0) AND (COALESCE(b.qty_done, (0)::numeric) > (0)::numeric)) THEN 'CANTIDAD_ODOO_SIN_CICLOS_EDGE'::text WHEN ((COALESCE(b.real_cycle_delta, (0)::bigint) > 0) AND (COALESCE(b.planned_cycles, (0)::numeric) > (0)::numeric) AND ((((COALESCE(b.real_cycle_delta, (0)::bigint))::numeric / NULLIF(b.planned_cycles, (0)::numeric)) >= 0.5) AND (((COALESCE(b.real_cycle_delta, (0)::bigint))::numeric / NULLIF(b.planned_cycles, (0)::numeric)) <= 1.5))) THEN 'CICLOS_COHERENTES_CON_OBJETIVO'::text ELSE 'REVISAR_CONVERSION_ODOO_CICLOS'::text END AS production_conversion_status, GREATEST(0, (((((((100 - CASE WHEN (COALESCE(b.telemetry_samples, (0)::bigint) = 0) THEN 60 ELSE 0 END) - CASE WHEN (COALESCE(b.energy_samples, (0)::bigint) = 0) THEN 50 ELSE 0 END) - CASE WHEN (b.odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text, 'started'::text])) THEN 20 ELSE 0 END) - CASE WHEN (COALESCE(b.pending_stops, (0)::bigint) > 0) THEN 20 ELSE 0 END) - CASE WHEN (COALESCE(g.telemetry_gap_count_30s, (0)::bigint) > 0) THEN LEAST(((COALESCE(g.telemetry_gap_count_30s, (0)::bigint))::integer * 2), 15) ELSE 0 END) - CASE WHEN (COALESCE(g.max_sample_gap_s, (0)::numeric) > (60)::numeric) THEN 10 ELSE 0 END) - CASE WHEN (COALESCE(g.non_ok_samples, (0)::bigint) > 0) THEN 10 ELSE 0 END)) AS technical_quality_score FROM (base b LEFT JOIN gap_stats g ON ((g.order_row_id = b.order_row_id))) ) SELECT order_row_id, tenant, site, odoo_instance, odoo_workorder_id, odoo_production_id, odoo_order_ref, odoo_state, product, machine_id, asset, start_ts, end_ts, window_min, qty_planned, qty_done, uom, planned_cycles, target_cycle_rate_ppm, telemetry_samples, energy_samples, expected_samples_10s, telemetry_sample_coverage_pct, telemetry_first_ts, telemetry_last_ts, energy_first_ts, energy_last_ts, real_cycle_delta, avg_cycle_rate_ppm, avg_nonzero_cycle_rate_ppm, kwh_consumed, avg_kw, max_kw, stop_count, stop_min, classified_stops, pending_stops, stop_cost_eur, telemetry_gap_count_30s, max_sample_gap_s, avg_sample_gap_s, non_ok_samples, report_status, report_status_description, production_conversion_status, technical_quality_score, CASE WHEN (technical_quality_score >= 90) THEN 'FIABLE'::text WHEN (technical_quality_score >= 70) THEN 'ACEPTABLE_CON_OBSERVACIONES'::text WHEN (technical_quality_score >= 40) THEN 'PARCIAL'::text ELSE 'NO_DEFENDIBLE'::text END AS technical_quality_level, CASE WHEN (COALESCE(telemetry_samples, (0)::bigint) = 0) THEN 'No hay telemetría Edge-OEE dentro de la ventana de la orden. El informe solo puede apoyarse en Odoo.'::text WHEN (COALESCE(energy_samples, (0)::bigint) = 0) THEN 'Faltan muestras energéticas válidas dentro de la ventana de la orden.'::text WHEN (odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text, 'started'::text])) THEN 'La orden sigue abierta. El informe debe tratarse como parcial.'::text WHEN (COALESCE(pending_stops, (0)::bigint) > 0) THEN 'Hay paros pendientes de clasificación. Conviene clasificarlos antes de cerrar el informe.'::text WHEN (COALESCE(telemetry_gap_count_30s, (0)::bigint) > 0) THEN 'Hay gaps de telemetría superiores a 30 segundos. Revisar continuidad de señal.'::text WHEN (production_conversion_status = 'REVISAR_CONVERSION_ODOO_CICLOS'::text) THEN 'El informe técnico es válido para paros, energía y ciclos reales; revisar la conversión entre cantidad Odoo y ciclos/golpes.'::text ELSE 'Datos suficientes para generar informe técnico de orden.'::text END AS recommended_action FROM scored; ALTER VIEW mv_reports_ucepsa_demo.order_execution_data_quality_v1 OWNER TO mesavault; -- -- Name: order_execution_stops_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_execution_stops_v1 AS SELECT r.order_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_workorder_id, r.odoo_production_id, r.odoo_order_ref, r.odoo_state, r.product, r.machine_id, r.asset, r.start_ts AS order_start_ts, r.end_ts AS order_end_ts, r.report_status AS order_report_status, ms.id AS stop_id, ms.started_at AS stop_started_at, ms.ended_at AS stop_ended_at, GREATEST(ms.started_at, r.start_ts) AS attributed_started_at, LEAST(COALESCE(ms.ended_at, r.end_ts), r.end_ts) AS attributed_ended_at, round(ms.duration_s, 2) AS original_duration_s, round((ms.duration_s / 60.0), 2) AS original_duration_min, round(EXTRACT(epoch FROM (LEAST(COALESCE(ms.ended_at, r.end_ts), r.end_ts) - GREATEST(ms.started_at, r.start_ts))), 2) AS attributed_duration_s, round((EXTRACT(epoch FROM (LEAST(COALESCE(ms.ended_at, r.end_ts), r.end_ts) - GREATEST(ms.started_at, r.start_ts))) / 60.0), 2) AS attributed_duration_min, ms.status AS stop_status, ms.classification_status, ms.cause_code, ms.operator_note, ms.value_hour_eur, round(((EXTRACT(epoch FROM (LEAST(COALESCE(ms.ended_at, r.end_ts), r.end_ts) - GREATEST(ms.started_at, r.start_ts))) / 3600.0) * ms.value_hour_eur), 2) AS attributed_cost_eur, ms.start_event_name, ms.end_event_name, ms.created_at, ms.updated_at, CASE WHEN (ms.status = 'OPEN'::text) THEN 'PARO_ABIERTO'::text WHEN (ms.classification_status = 'PENDING'::text) THEN 'PENDIENTE_CLASIFICACION'::text WHEN (ms.classification_status = 'CLASSIFIED'::text) THEN 'CLASIFICADO'::text ELSE 'SIN_ESTADO_CLARO'::text END AS stop_quality_status FROM (mv_reports_ucepsa_demo.order_execution_report_v1 r JOIN mv_hot.edge_oee_machine_stops ms ON (((ms.machine_id = r.machine_id) AND (ms.started_at < r.end_ts) AND (COALESCE(ms.ended_at, r.end_ts) > r.start_ts)))) WHERE (LEAST(COALESCE(ms.ended_at, r.end_ts), r.end_ts) > GREATEST(ms.started_at, r.start_ts)); ALTER VIEW mv_reports_ucepsa_demo.order_execution_stops_v1 OWNER TO mesavault; -- -- Name: order_execution_stop_causes_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_execution_stop_causes_v1 AS SELECT order_row_id, tenant, site, odoo_instance, odoo_workorder_id, odoo_production_id, odoo_order_ref, product, machine_id, cause_code, count(*) AS stop_count, round(sum(attributed_duration_min), 2) AS total_stop_min, round(sum(attributed_cost_eur), 2) AS total_stop_cost_eur, count(*) FILTER (WHERE (classification_status = 'CLASSIFIED'::text)) AS classified_stop_count, count(*) FILTER (WHERE (classification_status = 'PENDING'::text)) AS pending_stop_count, min(stop_started_at) AS first_stop_at, max(stop_ended_at) AS last_stop_at FROM mv_reports_ucepsa_demo.order_execution_stops_v1 GROUP BY order_row_id, tenant, site, odoo_instance, odoo_workorder_id, odoo_production_id, odoo_order_ref, product, machine_id, cause_code; ALTER VIEW mv_reports_ucepsa_demo.order_execution_stop_causes_v1 OWNER TO mesavault; -- -- Name: order_execution_timeline_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_execution_timeline_v1 AS SELECT r.order_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_workorder_id, r.odoo_production_id, r.odoo_order_ref, r.product, r.machine_id, r.asset, r.start_ts AS event_ts, 'ORDER_START'::text AS event_type, 'Inicio de orden'::text AS event_label, 'INFO'::text AS severity, NULL::bigint AS stop_id, NULL::bigint AS node_event_id, NULL::text AS cause_code, NULL::numeric AS duration_min, NULL::numeric AS cost_eur, 'Inicio de la ventana de ejecución de la orden según Odoo.'::text AS description, jsonb_build_object('source', 'mv_reports_ucepsa_demo.order_execution_report_v1', 'odoo_state', r.odoo_state, 'qty_planned', r.qty_planned, 'qty_done', r.qty_done, 'uom', r.uom) AS evidence_json FROM mv_reports_ucepsa_demo.order_execution_report_v1 r WHERE (r.start_ts IS NOT NULL) UNION ALL SELECT r.order_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_workorder_id, r.odoo_production_id, r.odoo_order_ref, r.product, r.machine_id, r.asset, r.telemetry_first_ts AS event_ts, 'FIRST_TELEMETRY'::text AS event_type, 'Primera telemetría Edge-OEE'::text AS event_label, 'INFO'::text AS severity, NULL::bigint AS stop_id, NULL::bigint AS node_event_id, NULL::text AS cause_code, NULL::numeric AS duration_min, NULL::numeric AS cost_eur, 'Primera muestra de telemetría recibida dentro de la ventana de la orden.'::text AS description, jsonb_build_object('source', 'mv_reports_ucepsa_demo.order_execution_report_v1', 'telemetry_samples', r.telemetry_samples, 'energy_samples', r.energy_samples) AS evidence_json FROM mv_reports_ucepsa_demo.order_execution_report_v1 r WHERE (r.telemetry_first_ts IS NOT NULL) UNION ALL SELECT s.order_row_id, s.tenant, s.site, s.odoo_instance, s.odoo_workorder_id, s.odoo_production_id, s.odoo_order_ref, s.product, s.machine_id, s.asset, s.attributed_started_at AS event_ts, 'STOP_START'::text AS event_type, 'Inicio de paro'::text AS event_label, CASE WHEN (s.classification_status = 'PENDING'::text) THEN 'WARNING'::text ELSE 'LOSS'::text END AS severity, s.stop_id, NULL::bigint AS node_event_id, s.cause_code, s.attributed_duration_min AS duration_min, s.attributed_cost_eur AS cost_eur, concat('Inicio de paro imputado a la orden. Causa: ', COALESCE(s.cause_code, 'sin clasificar'::text), '. Duración imputada: ', COALESCE((s.attributed_duration_min)::text, '0'::text), ' min.') AS description, jsonb_build_object('source', 'mv_reports_ucepsa_demo.order_execution_stops_v1', 'stop_id', s.stop_id, 'classification_status', s.classification_status, 'operator_note', s.operator_note, 'original_started_at', s.stop_started_at, 'original_ended_at', s.stop_ended_at) AS evidence_json FROM mv_reports_ucepsa_demo.order_execution_stops_v1 s UNION ALL SELECT s.order_row_id, s.tenant, s.site, s.odoo_instance, s.odoo_workorder_id, s.odoo_production_id, s.odoo_order_ref, s.product, s.machine_id, s.asset, s.attributed_ended_at AS event_ts, 'STOP_END'::text AS event_type, 'Fin de paro'::text AS event_label, CASE WHEN (s.classification_status = 'PENDING'::text) THEN 'WARNING'::text ELSE 'INFO'::text END AS severity, s.stop_id, NULL::bigint AS node_event_id, s.cause_code, s.attributed_duration_min AS duration_min, s.attributed_cost_eur AS cost_eur, concat('Fin de paro imputado a la orden. Causa: ', COALESCE(s.cause_code, 'sin clasificar'::text), '. Coste imputado: ', COALESCE((s.attributed_cost_eur)::text, '0'::text), ' €.') AS description, jsonb_build_object('source', 'mv_reports_ucepsa_demo.order_execution_stops_v1', 'stop_id', s.stop_id, 'classification_status', s.classification_status, 'operator_note', s.operator_note, 'value_hour_eur', s.value_hour_eur) AS evidence_json FROM mv_reports_ucepsa_demo.order_execution_stops_v1 s UNION ALL SELECT r.order_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_workorder_id, r.odoo_production_id, r.odoo_order_ref, r.product, r.machine_id, r.asset, r.telemetry_last_ts AS event_ts, 'LAST_TELEMETRY'::text AS event_type, 'Última telemetría Edge-OEE'::text AS event_label, CASE WHEN (r.report_status = 'PARCIAL_ORDEN_EN_CURSO'::text) THEN 'WARNING'::text ELSE 'INFO'::text END AS severity, NULL::bigint AS stop_id, NULL::bigint AS node_event_id, NULL::text AS cause_code, NULL::numeric AS duration_min, NULL::numeric AS cost_eur, 'Última muestra de telemetría recibida dentro de la ventana analizada.'::text AS description, jsonb_build_object('source', 'mv_reports_ucepsa_demo.order_execution_report_v1', 'real_cycle_delta', r.real_cycle_delta, 'kwh_consumed', r.kwh_consumed, 'avg_kw', r.avg_kw, 'max_kw', r.max_kw) AS evidence_json FROM mv_reports_ucepsa_demo.order_execution_report_v1 r WHERE (r.telemetry_last_ts IS NOT NULL) UNION ALL SELECT r.order_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_workorder_id, r.odoo_production_id, r.odoo_order_ref, r.product, r.machine_id, r.asset, r.end_ts AS event_ts, CASE WHEN (r.odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text, 'started'::text])) THEN 'REPORT_CUTOFF'::text ELSE 'ORDER_END'::text END AS event_type, CASE WHEN (r.odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text, 'started'::text])) THEN 'Corte provisional del informe'::text ELSE 'Fin de orden'::text END AS event_label, CASE WHEN (r.report_status = 'CERRADO_CALCULABLE'::text) THEN 'INFO'::text ELSE 'WARNING'::text END AS severity, NULL::bigint AS stop_id, NULL::bigint AS node_event_id, NULL::text AS cause_code, NULL::numeric AS duration_min, NULL::numeric AS cost_eur, r.report_status_description AS description, jsonb_build_object('source', 'mv_reports_ucepsa_demo.order_execution_report_v1', 'report_status', r.report_status, 'window_min', r.window_min, 'stop_count', r.stop_count, 'stop_min', r.stop_min, 'stop_cost_eur', r.stop_cost_eur) AS evidence_json FROM mv_reports_ucepsa_demo.order_execution_report_v1 r WHERE (r.end_ts IS NOT NULL); ALTER VIEW mv_reports_ucepsa_demo.order_execution_timeline_v1 OWNER TO mesavault; -- -- Name: order_execution_report_full_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_execution_report_full_v1 AS WITH stop_causes_json AS ( SELECT order_execution_stop_causes_v1.order_row_id, jsonb_agg(jsonb_build_object('cause_code', order_execution_stop_causes_v1.cause_code, 'stop_count', order_execution_stop_causes_v1.stop_count, 'total_stop_min', order_execution_stop_causes_v1.total_stop_min, 'total_stop_cost_eur', order_execution_stop_causes_v1.total_stop_cost_eur, 'classified_stop_count', order_execution_stop_causes_v1.classified_stop_count, 'pending_stop_count', order_execution_stop_causes_v1.pending_stop_count, 'first_stop_at', order_execution_stop_causes_v1.first_stop_at, 'last_stop_at', order_execution_stop_causes_v1.last_stop_at) ORDER BY order_execution_stop_causes_v1.total_stop_min DESC) AS stop_causes_json, string_agg(concat(COALESCE(order_execution_stop_causes_v1.cause_code, 'sin_clasificar'::text), ': ', order_execution_stop_causes_v1.stop_count, ' paros / ', order_execution_stop_causes_v1.total_stop_min, ' min / ', order_execution_stop_causes_v1.total_stop_cost_eur, ' €'), '; '::text ORDER BY order_execution_stop_causes_v1.total_stop_min DESC) AS stop_causes_summary FROM mv_reports_ucepsa_demo.order_execution_stop_causes_v1 GROUP BY order_execution_stop_causes_v1.order_row_id ), stops_json AS ( SELECT order_execution_stops_v1.order_row_id, jsonb_agg(jsonb_build_object('stop_id', order_execution_stops_v1.stop_id, 'stop_started_at', order_execution_stops_v1.stop_started_at, 'stop_ended_at', order_execution_stops_v1.stop_ended_at, 'attributed_started_at', order_execution_stops_v1.attributed_started_at, 'attributed_ended_at', order_execution_stops_v1.attributed_ended_at, 'attributed_duration_min', order_execution_stops_v1.attributed_duration_min, 'cause_code', order_execution_stops_v1.cause_code, 'operator_note', order_execution_stops_v1.operator_note, 'classification_status', order_execution_stops_v1.classification_status, 'attributed_cost_eur', order_execution_stops_v1.attributed_cost_eur, 'stop_quality_status', order_execution_stops_v1.stop_quality_status) ORDER BY order_execution_stops_v1.attributed_started_at) AS stops_json FROM mv_reports_ucepsa_demo.order_execution_stops_v1 GROUP BY order_execution_stops_v1.order_row_id ), timeline_json AS ( SELECT order_execution_timeline_v1.order_row_id, jsonb_agg(jsonb_build_object('event_ts', order_execution_timeline_v1.event_ts, 'event_type', order_execution_timeline_v1.event_type, 'event_label', order_execution_timeline_v1.event_label, 'severity', order_execution_timeline_v1.severity, 'stop_id', order_execution_timeline_v1.stop_id, 'cause_code', order_execution_timeline_v1.cause_code, 'duration_min', order_execution_timeline_v1.duration_min, 'cost_eur', order_execution_timeline_v1.cost_eur, 'description', order_execution_timeline_v1.description) ORDER BY order_execution_timeline_v1.event_ts, order_execution_timeline_v1.event_type) AS timeline_json FROM mv_reports_ucepsa_demo.order_execution_timeline_v1 GROUP BY order_execution_timeline_v1.order_row_id ) SELECT r.order_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_workorder_id, r.odoo_production_id, r.odoo_order_ref, r.odoo_state, r.odoo_workcenter_code, r.odoo_workcenter_name, r.machine_id, r.asset, r.product, r.qty_planned, r.qty_done, r.uom, r.planned_cycles, r.target_cycle_rate_ppm, r.start_ts, r.end_ts, r.window_min, GREATEST((r.window_min - r.stop_min), (0)::numeric) AS run_min, CASE WHEN (r.window_min > (0)::numeric) THEN round(((r.stop_min / r.window_min) * 100.0), 2) ELSE NULL::numeric END AS stop_pct, CASE WHEN (r.window_min > (0)::numeric) THEN round(((GREATEST((r.window_min - r.stop_min), (0)::numeric) / r.window_min) * 100.0), 2) ELSE NULL::numeric END AS availability_pct, r.telemetry_samples, r.telemetry_first_ts, r.telemetry_last_ts, r.energy_samples, r.energy_first_ts, r.energy_last_ts, r.start_import_kwh, r.end_import_kwh, r.kwh_consumed, r.avg_kw, r.max_kw, r.min_cycle_pulse_count, r.max_cycle_pulse_count, r.real_cycle_delta, r.avg_cycle_rate_ppm, r.avg_nonzero_cycle_rate_ppm, CASE WHEN (r.real_cycle_delta > 0) THEN round((r.kwh_consumed / (NULLIF(r.real_cycle_delta, 0))::numeric), 6) ELSE NULL::numeric END AS kwh_per_cycle, CASE WHEN (GREATEST((r.window_min - r.stop_min), (0)::numeric) > (0)::numeric) THEN round(((r.real_cycle_delta)::numeric / NULLIF(GREATEST((r.window_min - r.stop_min), (0)::numeric), (0)::numeric)), 2) ELSE NULL::numeric END AS cycles_per_run_min, r.stop_count, r.stop_min, r.classified_stops, r.pending_stops, r.stop_cost_eur, COALESCE(sc.stop_causes_summary, 'Sin paros imputados'::text) AS stop_causes_summary, COALESCE(sc.stop_causes_json, '[]'::jsonb) AS stop_causes_json, COALESCE(sj.stops_json, '[]'::jsonb) AS stops_json, COALESCE(tj.timeline_json, '[]'::jsonb) AS timeline_json, q.expected_samples_10s, q.telemetry_sample_coverage_pct, q.telemetry_gap_count_30s, q.max_sample_gap_s, q.avg_sample_gap_s, q.non_ok_samples, q.production_conversion_status, q.technical_quality_score, q.technical_quality_level, r.report_status, r.report_status_description, q.recommended_action, CASE WHEN ((r.report_status = 'CERRADO_CALCULABLE'::text) AND (q.technical_quality_level = 'FIABLE'::text) AND (q.production_conversion_status = 'CICLOS_COHERENTES_CON_OBJETIVO'::text)) THEN 'LISTO_INFORME_FINAL'::text WHEN ((r.report_status = 'CERRADO_CALCULABLE'::text) AND (q.technical_quality_level = 'FIABLE'::text) AND (q.production_conversion_status = 'REVISAR_CONVERSION_ODOO_CICLOS'::text)) THEN 'LISTO_TECNICO_REVISAR_CONVERSION'::text WHEN ((r.report_status = 'CERRADO_CALCULABLE'::text) AND (q.technical_quality_level = ANY (ARRAY['FIABLE'::text, 'ACEPTABLE_CON_OBSERVACIONES'::text]))) THEN 'LISTO_CON_OBSERVACIONES'::text WHEN (r.report_status = 'PARCIAL_ORDEN_EN_CURSO'::text) THEN 'INFORME_PARCIAL_ORDEN_EN_CURSO'::text WHEN (r.report_status = 'SIN_TELEMETRIA_EN_VENTANA'::text) THEN 'BLOQUEADO_SIN_TELEMETRIA'::text WHEN (r.report_status = 'SIN_ENERGIA_EN_VENTANA'::text) THEN 'BLOQUEADO_SIN_ENERGIA'::text WHEN (r.pending_stops > 0) THEN 'PENDIENTE_CLASIFICAR_PAROS'::text ELSE 'REVISAR'::text END AS final_report_status, concat('Orden ', r.odoo_order_ref, ' en ', r.machine_id, ': duración ', r.window_min, ' min; ciclos reales ', r.real_cycle_delta, '; energía ', COALESCE((r.kwh_consumed)::text, 'sin dato'::text), ' kWh; paros ', r.stop_count, ' (', r.stop_min, ' min); coste estimado ', r.stop_cost_eur, ' €. Estado técnico: ', q.technical_quality_level, '.') AS executive_summary FROM ((((mv_reports_ucepsa_demo.order_execution_report_v1 r LEFT JOIN mv_reports_ucepsa_demo.order_execution_data_quality_v1 q ON ((q.order_row_id = r.order_row_id))) LEFT JOIN stop_causes_json sc ON ((sc.order_row_id = r.order_row_id))) LEFT JOIN stops_json sj ON ((sj.order_row_id = r.order_row_id))) LEFT JOIN timeline_json tj ON ((tj.order_row_id = r.order_row_id))); ALTER VIEW mv_reports_ucepsa_demo.order_execution_report_full_v1 OWNER TO mesavault; -- -- Name: order_raw_material_costs_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_raw_material_costs_v1 AS WITH raw_moves AS ( SELECT c.id AS commercial_row_id, c.tenant, c.site, c.odoo_instance, c.odoo_production_id, c.odoo_order_ref, c.sale_order_ref, c.customer_name, c.product_default_code AS finished_product_default_code, c.product_name AS finished_product_name, ((rm.raw_move ->> 'id'::text))::integer AS raw_move_id, (NULLIF(((rm.raw_move -> 'product_id'::text) ->> 0), ''::text))::integer AS raw_product_id, ((rm.raw_move -> 'product_id'::text) ->> 1) AS raw_product_name, "substring"(((rm.raw_move -> 'product_id'::text) ->> 1), '\[([^\]]+)\]'::text) AS raw_product_default_code, (NULLIF((rm.raw_move ->> 'product_uom_qty'::text), ''::text))::numeric AS planned_qty, (NULLIF((rm.raw_move ->> 'quantity'::text), ''::text))::numeric AS consumed_qty, ((rm.raw_move -> 'product_uom'::text) ->> 1) AS raw_uom, (NULLIF((rm.raw_move ->> 'price_unit'::text), ''::text))::numeric AS odoo_price_unit, (NULLIF((rm.raw_move ->> 'value'::text), ''::text))::numeric AS odoo_value, (rm.raw_move ->> 'state'::text) AS move_state, rm.raw_move AS raw_move_json FROM (mv_edge_oee_ucepsa_demo.odoo_order_commercials c CROSS JOIN LATERAL jsonb_array_elements(c.stock_raw_moves_json) rm(raw_move)) ), costed AS ( SELECT r.commercial_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_production_id, r.odoo_order_ref, r.sale_order_ref, r.customer_name, r.finished_product_default_code, r.finished_product_name, r.raw_move_id, r.raw_product_id, r.raw_product_name, r.raw_product_default_code, r.planned_qty, r.consumed_qty, r.raw_uom, r.odoo_price_unit, r.odoo_value, r.move_state, r.raw_move_json, p.id AS raw_material_cost_parameter_id, p.material_cost_eur_per_kg, p.source AS raw_material_cost_source, p.notes AS raw_material_cost_notes, CASE WHEN (COALESCE(r.odoo_value, (0)::numeric) <> (0)::numeric) THEN abs(r.odoo_value) WHEN ((lower(COALESCE(r.raw_uom, ''::text)) = 'kg'::text) AND (p.material_cost_eur_per_kg IS NOT NULL) AND (r.consumed_qty IS NOT NULL)) THEN (r.consumed_qty * p.material_cost_eur_per_kg) ELSE NULL::numeric END AS material_cost_estimated_eur, CASE WHEN (COALESCE(r.odoo_value, (0)::numeric) <> (0)::numeric) THEN 'FROM_ODOO_STOCK_MOVE_VALUE'::text WHEN (r.raw_product_default_code IS NULL) THEN 'MISSING_RAW_PRODUCT_CODE'::text WHEN (lower(COALESCE(r.raw_uom, ''::text)) <> 'kg'::text) THEN 'UNSUPPORTED_RAW_UOM'::text WHEN (p.material_cost_eur_per_kg IS NULL) THEN 'MISSING_RAW_MATERIAL_COST_PARAMETER'::text WHEN (r.consumed_qty IS NULL) THEN 'MISSING_CONSUMED_QTY'::text ELSE 'FROM_RAW_MATERIAL_COST_PARAMETER'::text END AS material_cost_status FROM (raw_moves r LEFT JOIN LATERAL ( SELECT p_1.id, p_1.tenant, p_1.site, p_1.raw_product_default_code, p_1.raw_product_name, p_1.material_cost_eur_per_kg, p_1.source, p_1.valid_from, p_1.valid_to, p_1.is_active, p_1.notes, p_1.created_at FROM mv_edge_oee_ucepsa_demo.raw_material_cost_parameters p_1 WHERE ((p_1.tenant = r.tenant) AND (p_1.site = r.site) AND (p_1.is_active = true) AND (p_1.raw_product_default_code = r.raw_product_default_code) AND (p_1.valid_from <= now()) AND ((p_1.valid_to IS NULL) OR (p_1.valid_to > now()))) ORDER BY p_1.valid_from DESC, p_1.id DESC LIMIT 1) p ON (true)) ) SELECT commercial_row_id, tenant, site, odoo_instance, odoo_production_id, odoo_order_ref, sale_order_ref, customer_name, finished_product_default_code, finished_product_name, raw_move_id, raw_product_id, raw_product_name, raw_product_default_code, planned_qty, consumed_qty, raw_uom, odoo_price_unit, odoo_value, move_state, raw_move_json, raw_material_cost_parameter_id, material_cost_eur_per_kg, raw_material_cost_source, raw_material_cost_notes, material_cost_estimated_eur, material_cost_status, round(material_cost_estimated_eur, 4) AS material_cost_estimated_eur_rounded FROM costed; ALTER VIEW mv_reports_ucepsa_demo.order_raw_material_costs_v1 OWNER TO mesavault; -- -- Name: order_raw_material_costs_summary_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_raw_material_costs_summary_v1 AS SELECT tenant, site, odoo_instance, odoo_production_id, odoo_order_ref, sale_order_ref, customer_name, finished_product_default_code, finished_product_name, count(*) AS raw_material_line_count, round(sum(COALESCE(consumed_qty, (0)::numeric)), 3) AS total_consumed_qty, string_agg(concat(COALESCE(raw_product_default_code, 'sin_codigo'::text), ' - ', COALESCE(raw_product_name, 'sin_nombre'::text), ': ', COALESCE((consumed_qty)::text, 'sin_cantidad'::text), ' ', COALESCE(raw_uom, ''::text)), '; '::text ORDER BY raw_product_default_code) AS raw_materials_summary, round(sum(COALESCE(material_cost_estimated_eur, (0)::numeric)), 4) AS material_cost_estimated_eur, count(*) FILTER (WHERE (material_cost_estimated_eur IS NOT NULL)) AS costed_raw_material_line_count, count(*) FILTER (WHERE ((material_cost_status <> 'FROM_RAW_MATERIAL_COST_PARAMETER'::text) AND (material_cost_status <> 'FROM_ODOO_STOCK_MOVE_VALUE'::text))) AS missing_or_invalid_raw_material_cost_count, string_agg(DISTINCT material_cost_status, ', '::text ORDER BY material_cost_status) AS material_cost_status_summary FROM mv_reports_ucepsa_demo.order_raw_material_costs_v1 GROUP BY tenant, site, odoo_instance, odoo_production_id, odoo_order_ref, sale_order_ref, customer_name, finished_product_default_code, finished_product_name; ALTER VIEW mv_reports_ucepsa_demo.order_raw_material_costs_summary_v1 OWNER TO mesavault; -- -- Name: order_margin_report_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.order_margin_report_v1 AS WITH joined AS ( SELECT r.order_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_workorder_id, r.odoo_production_id, r.odoo_order_ref, r.odoo_state, r.machine_id, r.asset, r.product AS edge_product, r.start_ts, r.end_ts, r.window_min, r.run_min, r.stop_min, r.stop_cost_eur, r.real_cycle_delta, r.kwh_consumed, r.kwh_per_cycle, r.technical_quality_level, r.final_report_status, c.odoo_origin, c.sale_order_ref, c.customer_id, c.customer_name, c.sale_state, c.sale_date_order, c.currency, c.product_id, c.product_default_code, c.product_name, c.production_qty, c.qty_producing, c.production_uom, c.sale_line_id, c.sale_order_id, c.sale_line_qty, c.sale_line_qty_delivered, c.sale_price_unit, c.sale_discount_pct, c.revenue_net_eur, c.revenue_total_eur, c.product_standard_price, c.product_list_price, c.raw_material_value_eur, c.finished_value_eur, c.material_cost_status AS odoo_material_cost_status, c.snapshot_at AS commercial_snapshot_at, rms.raw_material_line_count, rms.total_consumed_qty AS raw_total_consumed_qty, rms.raw_materials_summary, rms.material_cost_estimated_eur AS raw_material_cost_estimated_eur, rms.costed_raw_material_line_count, rms.missing_or_invalid_raw_material_cost_count, rms.material_cost_status_summary AS raw_material_cost_status_summary FROM ((mv_reports_ucepsa_demo.order_execution_report_full_v1 r LEFT JOIN mv_edge_oee_ucepsa_demo.odoo_order_commercials c ON (((c.odoo_instance = r.odoo_instance) AND (c.odoo_production_id = r.odoo_production_id)))) LEFT JOIN mv_reports_ucepsa_demo.order_raw_material_costs_summary_v1 rms ON (((rms.odoo_instance = r.odoo_instance) AND (rms.odoo_production_id = r.odoo_production_id)))) ), with_params AS ( SELECT j.order_row_id, j.tenant, j.site, j.odoo_instance, j.odoo_workorder_id, j.odoo_production_id, j.odoo_order_ref, j.odoo_state, j.machine_id, j.asset, j.edge_product, j.start_ts, j.end_ts, j.window_min, j.run_min, j.stop_min, j.stop_cost_eur, j.real_cycle_delta, j.kwh_consumed, j.kwh_per_cycle, j.technical_quality_level, j.final_report_status, j.odoo_origin, j.sale_order_ref, j.customer_id, j.customer_name, j.sale_state, j.sale_date_order, j.currency, j.product_id, j.product_default_code, j.product_name, j.production_qty, j.qty_producing, j.production_uom, j.sale_line_id, j.sale_order_id, j.sale_line_qty, j.sale_line_qty_delivered, j.sale_price_unit, j.sale_discount_pct, j.revenue_net_eur, j.revenue_total_eur, j.product_standard_price, j.product_list_price, j.raw_material_value_eur, j.finished_value_eur, j.odoo_material_cost_status, j.commercial_snapshot_at, j.raw_material_line_count, j.raw_total_consumed_qty, j.raw_materials_summary, j.raw_material_cost_estimated_eur, j.costed_raw_material_line_count, j.missing_or_invalid_raw_material_cost_count, j.raw_material_cost_status_summary, p.id AS cost_parameter_id, p.scope_level AS cost_parameter_scope_level, p.energy_cost_eur_per_kwh, p.material_cost_eur_per_kg AS fallback_material_cost_eur_per_kg, p.machine_run_cost_eur_per_h, p.labor_cost_eur_per_h, p.overhead_cost_eur_per_h, p.notes AS cost_parameter_notes FROM (joined j LEFT JOIN LATERAL ( SELECT p_1.id, p_1.tenant, p_1.site, p_1.scope_level, p_1.machine_id, p_1.product_default_code, p_1.energy_cost_eur_per_kwh, p_1.material_cost_eur_per_kg, p_1.machine_run_cost_eur_per_h, p_1.labor_cost_eur_per_h, p_1.overhead_cost_eur_per_h, p_1.valid_from, p_1.valid_to, p_1.is_active, p_1.notes, p_1.created_at FROM mv_edge_oee_ucepsa_demo.margin_cost_parameters p_1 WHERE ((p_1.is_active = true) AND (p_1.tenant = j.tenant) AND (p_1.site = j.site) AND (p_1.valid_from <= now()) AND ((p_1.valid_to IS NULL) OR (p_1.valid_to > now())) AND ((p_1.machine_id IS NULL) OR (p_1.machine_id = j.machine_id)) AND ((p_1.product_default_code IS NULL) OR (p_1.product_default_code = j.product_default_code))) ORDER BY CASE WHEN ((p_1.product_default_code IS NOT NULL) AND (p_1.machine_id IS NOT NULL)) THEN 1 WHEN (p_1.product_default_code IS NOT NULL) THEN 2 WHEN (p_1.machine_id IS NOT NULL) THEN 3 ELSE 4 END, p_1.valid_from DESC, p_1.id DESC LIMIT 1) p ON (true)) ), costs AS ( SELECT with_params.order_row_id, with_params.tenant, with_params.site, with_params.odoo_instance, with_params.odoo_workorder_id, with_params.odoo_production_id, with_params.odoo_order_ref, with_params.odoo_state, with_params.machine_id, with_params.asset, with_params.edge_product, with_params.start_ts, with_params.end_ts, with_params.window_min, with_params.run_min, with_params.stop_min, with_params.stop_cost_eur, with_params.real_cycle_delta, with_params.kwh_consumed, with_params.kwh_per_cycle, with_params.technical_quality_level, with_params.final_report_status, with_params.odoo_origin, with_params.sale_order_ref, with_params.customer_id, with_params.customer_name, with_params.sale_state, with_params.sale_date_order, with_params.currency, with_params.product_id, with_params.product_default_code, with_params.product_name, with_params.production_qty, with_params.qty_producing, with_params.production_uom, with_params.sale_line_id, with_params.sale_order_id, with_params.sale_line_qty, with_params.sale_line_qty_delivered, with_params.sale_price_unit, with_params.sale_discount_pct, with_params.revenue_net_eur, with_params.revenue_total_eur, with_params.product_standard_price, with_params.product_list_price, with_params.raw_material_value_eur, with_params.finished_value_eur, with_params.odoo_material_cost_status, with_params.commercial_snapshot_at, with_params.raw_material_line_count, with_params.raw_total_consumed_qty, with_params.raw_materials_summary, with_params.raw_material_cost_estimated_eur, with_params.costed_raw_material_line_count, with_params.missing_or_invalid_raw_material_cost_count, with_params.raw_material_cost_status_summary, with_params.cost_parameter_id, with_params.cost_parameter_scope_level, with_params.energy_cost_eur_per_kwh, with_params.fallback_material_cost_eur_per_kg, with_params.machine_run_cost_eur_per_h, with_params.labor_cost_eur_per_h, with_params.overhead_cost_eur_per_h, with_params.cost_parameter_notes, COALESCE(NULLIF(with_params.qty_producing, (0)::numeric), NULLIF(with_params.production_qty, (0)::numeric)) AS costing_qty_kg, CASE WHEN ((with_params.raw_material_line_count > 0) AND (COALESCE(with_params.missing_or_invalid_raw_material_cost_count, (0)::bigint) = 0) AND (with_params.raw_material_cost_estimated_eur IS NOT NULL)) THEN with_params.raw_material_cost_estimated_eur WHEN ((with_params.raw_material_line_count > 0) AND (COALESCE(with_params.missing_or_invalid_raw_material_cost_count, (0)::bigint) > 0)) THEN NULL::numeric WHEN ((with_params.raw_material_value_eur IS NOT NULL) AND (with_params.raw_material_value_eur <> (0)::numeric)) THEN abs(with_params.raw_material_value_eur) WHEN ((with_params.product_standard_price IS NOT NULL) AND (with_params.product_standard_price <> (0)::numeric) AND (COALESCE(NULLIF(with_params.qty_producing, (0)::numeric), NULLIF(with_params.production_qty, (0)::numeric)) IS NOT NULL)) THEN (with_params.product_standard_price * COALESCE(NULLIF(with_params.qty_producing, (0)::numeric), NULLIF(with_params.production_qty, (0)::numeric))) WHEN ((with_params.fallback_material_cost_eur_per_kg IS NOT NULL) AND (COALESCE(NULLIF(with_params.qty_producing, (0)::numeric), NULLIF(with_params.production_qty, (0)::numeric)) IS NOT NULL)) THEN (with_params.fallback_material_cost_eur_per_kg * COALESCE(NULLIF(with_params.qty_producing, (0)::numeric), NULLIF(with_params.production_qty, (0)::numeric))) ELSE NULL::numeric END AS material_cost_estimated_eur, CASE WHEN ((with_params.raw_material_line_count > 0) AND (COALESCE(with_params.missing_or_invalid_raw_material_cost_count, (0)::bigint) = 0)) THEN 'FROM_RAW_MATERIAL_COSTS'::text WHEN ((with_params.raw_material_line_count > 0) AND (COALESCE(with_params.missing_or_invalid_raw_material_cost_count, (0)::bigint) > 0)) THEN with_params.raw_material_cost_status_summary WHEN ((with_params.raw_material_value_eur IS NOT NULL) AND (with_params.raw_material_value_eur <> (0)::numeric)) THEN 'FROM_ODOO_RAW_MATERIAL_VALUE'::text WHEN ((with_params.product_standard_price IS NOT NULL) AND (with_params.product_standard_price <> (0)::numeric)) THEN 'FROM_PRODUCT_STANDARD_PRICE'::text WHEN (with_params.fallback_material_cost_eur_per_kg IS NOT NULL) THEN 'FROM_FALLBACK_MARGIN_PARAMETER'::text ELSE 'MISSING_MATERIAL_COST'::text END AS material_cost_source_status, CASE WHEN ((with_params.kwh_consumed IS NOT NULL) AND (with_params.energy_cost_eur_per_kwh IS NOT NULL)) THEN (with_params.kwh_consumed * with_params.energy_cost_eur_per_kwh) ELSE NULL::numeric END AS energy_cost_estimated_eur, CASE WHEN ((with_params.run_min IS NOT NULL) AND (with_params.machine_run_cost_eur_per_h IS NOT NULL)) THEN ((with_params.run_min / 60.0) * with_params.machine_run_cost_eur_per_h) ELSE NULL::numeric END AS machine_run_cost_estimated_eur, CASE WHEN ((with_params.window_min IS NOT NULL) AND (with_params.labor_cost_eur_per_h IS NOT NULL)) THEN ((with_params.window_min / 60.0) * with_params.labor_cost_eur_per_h) ELSE NULL::numeric END AS labor_cost_estimated_eur, CASE WHEN ((with_params.window_min IS NOT NULL) AND (with_params.overhead_cost_eur_per_h IS NOT NULL)) THEN ((with_params.window_min / 60.0) * with_params.overhead_cost_eur_per_h) ELSE NULL::numeric END AS overhead_cost_estimated_eur FROM with_params ) SELECT order_row_id, tenant, site, odoo_instance, odoo_workorder_id, odoo_production_id, odoo_order_ref, odoo_state, odoo_origin, sale_order_ref, customer_id, customer_name, sale_state, sale_date_order, currency, machine_id, asset, product_id, product_default_code, COALESCE(product_name, edge_product) AS product_name, production_qty, qty_producing, production_uom, costing_qty_kg, sale_line_id, sale_order_id, sale_line_qty, sale_line_qty_delivered, sale_price_unit, sale_discount_pct, revenue_net_eur, revenue_total_eur, start_ts, end_ts, window_min, run_min, stop_min, stop_cost_eur, real_cycle_delta, kwh_consumed, kwh_per_cycle, product_standard_price, product_list_price, raw_material_value_eur, finished_value_eur, odoo_material_cost_status, raw_material_line_count, raw_total_consumed_qty, raw_materials_summary, raw_material_cost_status_summary, costed_raw_material_line_count, missing_or_invalid_raw_material_cost_count, cost_parameter_id, cost_parameter_scope_level, energy_cost_eur_per_kwh, fallback_material_cost_eur_per_kg, machine_run_cost_eur_per_h, labor_cost_eur_per_h, overhead_cost_eur_per_h, round(material_cost_estimated_eur, 4) AS material_cost_estimated_eur, material_cost_source_status, round(energy_cost_estimated_eur, 4) AS energy_cost_estimated_eur, round(machine_run_cost_estimated_eur, 4) AS machine_run_cost_estimated_eur, round(labor_cost_estimated_eur, 4) AS labor_cost_estimated_eur, round(overhead_cost_estimated_eur, 4) AS overhead_cost_estimated_eur, round((((((COALESCE(material_cost_estimated_eur, (0)::numeric) + COALESCE(energy_cost_estimated_eur, (0)::numeric)) + COALESCE(machine_run_cost_estimated_eur, (0)::numeric)) + COALESCE(labor_cost_estimated_eur, (0)::numeric)) + COALESCE(overhead_cost_estimated_eur, (0)::numeric)) + COALESCE(stop_cost_eur, (0)::numeric)), 4) AS known_or_estimated_cost_eur, round( CASE WHEN (revenue_net_eur IS NOT NULL) THEN (revenue_net_eur - (((((COALESCE(material_cost_estimated_eur, (0)::numeric) + COALESCE(energy_cost_estimated_eur, (0)::numeric)) + COALESCE(machine_run_cost_estimated_eur, (0)::numeric)) + COALESCE(labor_cost_estimated_eur, (0)::numeric)) + COALESCE(overhead_cost_estimated_eur, (0)::numeric)) + COALESCE(stop_cost_eur, (0)::numeric))) ELSE NULL::numeric END, 4) AS partial_margin_after_known_costs_eur, round( CASE WHEN ((revenue_net_eur IS NOT NULL) AND (material_cost_estimated_eur IS NOT NULL)) THEN (revenue_net_eur - (((((COALESCE(material_cost_estimated_eur, (0)::numeric) + COALESCE(energy_cost_estimated_eur, (0)::numeric)) + COALESCE(machine_run_cost_estimated_eur, (0)::numeric)) + COALESCE(labor_cost_estimated_eur, (0)::numeric)) + COALESCE(overhead_cost_estimated_eur, (0)::numeric)) + COALESCE(stop_cost_eur, (0)::numeric))) ELSE NULL::numeric END, 4) AS estimated_margin_eur, round( CASE WHEN ((revenue_net_eur IS NOT NULL) AND (revenue_net_eur <> (0)::numeric) AND (material_cost_estimated_eur IS NOT NULL)) THEN (((revenue_net_eur - (((((COALESCE(material_cost_estimated_eur, (0)::numeric) + COALESCE(energy_cost_estimated_eur, (0)::numeric)) + COALESCE(machine_run_cost_estimated_eur, (0)::numeric)) + COALESCE(labor_cost_estimated_eur, (0)::numeric)) + COALESCE(overhead_cost_estimated_eur, (0)::numeric)) + COALESCE(stop_cost_eur, (0)::numeric))) / revenue_net_eur) * 100.0) ELSE NULL::numeric END, 2) AS estimated_margin_pct, CASE WHEN (revenue_net_eur IS NULL) THEN 'NO_REVENUE_LINKED'::text ELSE 'REVENUE_LINKED'::text END AS revenue_status, CASE WHEN ((raw_material_line_count > 0) AND (COALESCE(missing_or_invalid_raw_material_cost_count, (0)::bigint) > 0)) THEN 'MISSING_RAW_MATERIAL_COST_PARAMETER'::text WHEN (material_cost_estimated_eur IS NULL) THEN 'MISSING_MATERIAL_COST'::text WHEN (energy_cost_eur_per_kwh IS NULL) THEN 'MISSING_ENERGY_COST'::text WHEN (machine_run_cost_eur_per_h IS NULL) THEN 'MISSING_MACHINE_RUN_COST'::text ELSE 'COST_PARAMETERS_AVAILABLE'::text END AS cost_status, CASE WHEN (revenue_net_eur IS NULL) THEN 'NO_MARGIN_WITHOUT_REVENUE'::text WHEN ((raw_material_line_count > 0) AND (COALESCE(missing_or_invalid_raw_material_cost_count, (0)::bigint) > 0)) THEN 'PARTIAL_MARGIN_MISSING_RAW_MATERIAL_COST'::text WHEN (material_cost_estimated_eur IS NULL) THEN 'PARTIAL_MARGIN_MISSING_MATERIAL'::text ELSE 'ESTIMATED_MARGIN_AVAILABLE'::text END AS margin_status, technical_quality_level, final_report_status, commercial_snapshot_at FROM costs; ALTER VIEW mv_reports_ucepsa_demo.order_margin_report_v1 OWNER TO mesavault; -- -- Name: cost_readiness_orders_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.cost_readiness_orders_v1 AS WITH base AS ( SELECT m.order_row_id, m.tenant, m.site, m.odoo_instance, m.odoo_workorder_id, m.odoo_production_id, m.odoo_order_ref, m.odoo_state, m.odoo_origin, m.sale_order_ref, m.customer_id, m.customer_name, m.sale_state, m.sale_date_order, m.currency, m.machine_id, m.asset, m.product_id, m.product_default_code, m.product_name, m.production_qty, m.qty_producing, m.production_uom, m.costing_qty_kg, m.sale_line_id, m.sale_order_id, m.sale_line_qty, m.sale_line_qty_delivered, m.sale_price_unit, m.sale_discount_pct, m.revenue_net_eur, m.revenue_total_eur, m.start_ts, m.end_ts, m.window_min, m.run_min, m.stop_min, m.stop_cost_eur, m.real_cycle_delta, m.kwh_consumed, m.kwh_per_cycle, m.product_standard_price, m.product_list_price, m.raw_material_value_eur, m.finished_value_eur, m.odoo_material_cost_status, m.raw_material_line_count, m.raw_total_consumed_qty, m.raw_materials_summary, m.raw_material_cost_status_summary, m.costed_raw_material_line_count, m.missing_or_invalid_raw_material_cost_count, m.cost_parameter_id, m.cost_parameter_scope_level, m.energy_cost_eur_per_kwh, m.fallback_material_cost_eur_per_kg, m.machine_run_cost_eur_per_h, m.labor_cost_eur_per_h, m.overhead_cost_eur_per_h, m.material_cost_estimated_eur, m.material_cost_source_status, m.energy_cost_estimated_eur, m.machine_run_cost_estimated_eur, m.labor_cost_estimated_eur, m.overhead_cost_estimated_eur, m.known_or_estimated_cost_eur, m.partial_margin_after_known_costs_eur, m.estimated_margin_eur, m.estimated_margin_pct, m.revenue_status, m.cost_status, m.margin_status, m.technical_quality_level, m.final_report_status, m.commercial_snapshot_at, CASE WHEN (m.revenue_net_eur IS NOT NULL) THEN true ELSE false END AS has_revenue, CASE WHEN (NULLIF(TRIM(BOTH FROM COALESCE(m.customer_name, ''::text)), ''::text) IS NOT NULL) THEN true ELSE false END AS has_customer, CASE WHEN (NULLIF(TRIM(BOTH FROM COALESCE(m.sale_order_ref, ''::text)), ''::text) IS NOT NULL) THEN true ELSE false END AS has_sale_order, CASE WHEN (COALESCE(m.raw_material_line_count, (0)::bigint) > 0) THEN true ELSE false END AS has_raw_materials, CASE WHEN ((COALESCE(m.raw_material_line_count, (0)::bigint) > 0) AND (COALESCE(m.missing_or_invalid_raw_material_cost_count, (0)::bigint) = 0) AND (m.material_cost_estimated_eur IS NOT NULL)) THEN true ELSE false END AS has_raw_material_cost, CASE WHEN (m.technical_quality_level = ANY (ARRAY['FIABLE'::text, 'ACEPTABLE_CON_OBSERVACIONES'::text])) THEN true ELSE false END AS has_usable_technical_data, CASE WHEN (m.final_report_status = ANY (ARRAY['LISTO_INFORME_FINAL'::text, 'LISTO_TECNICO_REVISAR_CONVERSION'::text, 'LISTO_CON_OBSERVACIONES'::text])) THEN true ELSE false END AS has_closed_or_usable_order_report, CASE WHEN ((m.kwh_consumed IS NULL) OR (m.energy_cost_eur_per_kwh IS NOT NULL)) THEN true ELSE false END AS has_energy_cost_parameter, CASE WHEN ((m.run_min IS NULL) OR (m.machine_run_cost_eur_per_h IS NOT NULL)) THEN true ELSE false END AS has_machine_cost_parameter FROM mv_reports_ucepsa_demo.order_margin_report_v1 m ), scored AS ( SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.odoo_origin, b.sale_order_ref, b.customer_id, b.customer_name, b.sale_state, b.sale_date_order, b.currency, b.machine_id, b.asset, b.product_id, b.product_default_code, b.product_name, b.production_qty, b.qty_producing, b.production_uom, b.costing_qty_kg, b.sale_line_id, b.sale_order_id, b.sale_line_qty, b.sale_line_qty_delivered, b.sale_price_unit, b.sale_discount_pct, b.revenue_net_eur, b.revenue_total_eur, b.start_ts, b.end_ts, b.window_min, b.run_min, b.stop_min, b.stop_cost_eur, b.real_cycle_delta, b.kwh_consumed, b.kwh_per_cycle, b.product_standard_price, b.product_list_price, b.raw_material_value_eur, b.finished_value_eur, b.odoo_material_cost_status, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.costed_raw_material_line_count, b.missing_or_invalid_raw_material_cost_count, b.cost_parameter_id, b.cost_parameter_scope_level, b.energy_cost_eur_per_kwh, b.fallback_material_cost_eur_per_kg, b.machine_run_cost_eur_per_h, b.labor_cost_eur_per_h, b.overhead_cost_eur_per_h, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_estimated_eur, b.machine_run_cost_estimated_eur, b.labor_cost_estimated_eur, b.overhead_cost_estimated_eur, b.known_or_estimated_cost_eur, b.partial_margin_after_known_costs_eur, b.estimated_margin_eur, b.estimated_margin_pct, b.revenue_status, b.cost_status, b.margin_status, b.technical_quality_level, b.final_report_status, b.commercial_snapshot_at, b.has_revenue, b.has_customer, b.has_sale_order, b.has_raw_materials, b.has_raw_material_cost, b.has_usable_technical_data, b.has_closed_or_usable_order_report, b.has_energy_cost_parameter, b.has_machine_cost_parameter, GREATEST(0, (((((((((100 - CASE WHEN (b.has_revenue = false) THEN 35 ELSE 0 END) - CASE WHEN (b.has_customer = false) THEN 5 ELSE 0 END) - CASE WHEN (b.has_sale_order = false) THEN 5 ELSE 0 END) - CASE WHEN (b.has_usable_technical_data = false) THEN 25 ELSE 0 END) - CASE WHEN (b.has_closed_or_usable_order_report = false) THEN 15 ELSE 0 END) - CASE WHEN (b.has_raw_materials = false) THEN 20 ELSE 0 END) - CASE WHEN ((b.has_raw_materials = true) AND (b.has_raw_material_cost = false)) THEN 35 ELSE 0 END) - CASE WHEN (b.has_energy_cost_parameter = false) THEN 5 ELSE 0 END) - CASE WHEN (b.has_machine_cost_parameter = false) THEN 5 ELSE 0 END)) AS cost_readiness_score, concat_ws('; '::text, CASE WHEN (b.has_revenue = false) THEN 'Falta ingreso de venta vinculado'::text ELSE NULL::text END, CASE WHEN (b.has_customer = false) THEN 'Falta cliente'::text ELSE NULL::text END, CASE WHEN (b.has_sale_order = false) THEN 'Falta pedido de venta'::text ELSE NULL::text END, CASE WHEN (b.has_usable_technical_data = false) THEN 'Datos técnicos no defendibles'::text ELSE NULL::text END, CASE WHEN (b.has_closed_or_usable_order_report = false) THEN 'Informe técnico parcial o bloqueado'::text ELSE NULL::text END, CASE WHEN (b.has_raw_materials = false) THEN 'No se detecta materia prima consumida'::text ELSE NULL::text END, CASE WHEN ((b.has_raw_materials = true) AND (b.has_raw_material_cost = false)) THEN 'Falta coste de materia prima'::text ELSE NULL::text END, CASE WHEN (b.has_energy_cost_parameter = false) THEN 'Falta coste €/kWh'::text ELSE NULL::text END, CASE WHEN (b.has_machine_cost_parameter = false) THEN 'Falta coste hora máquina'::text ELSE NULL::text END) AS cost_readiness_blockers FROM base b ) SELECT order_row_id, tenant, site, odoo_instance, odoo_order_ref, odoo_state, sale_order_ref, customer_name, product_default_code, product_name, machine_id, revenue_net_eur, revenue_total_eur, raw_material_line_count, raw_total_consumed_qty, raw_materials_summary, raw_material_cost_status_summary, missing_or_invalid_raw_material_cost_count, material_cost_estimated_eur, material_cost_source_status, stop_cost_eur, kwh_consumed, run_min, window_min, technical_quality_level, final_report_status, margin_status, has_revenue, has_customer, has_sale_order, has_raw_materials, has_raw_material_cost, has_usable_technical_data, has_closed_or_usable_order_report, has_energy_cost_parameter, has_machine_cost_parameter, cost_readiness_score, CASE WHEN (has_revenue = false) THEN 'BLOQUEADO_SIN_INGRESO'::text WHEN (has_usable_technical_data = false) THEN 'BLOQUEADO_DATOS_TECNICOS'::text WHEN (has_closed_or_usable_order_report = false) THEN 'PARCIAL_INFORME_TECNICO'::text WHEN (has_raw_materials = false) THEN 'BLOQUEADO_SIN_MATERIA_PRIMA'::text WHEN ((has_raw_materials = true) AND (has_raw_material_cost = false)) THEN 'BLOQUEADO_FALTA_COSTE_MATERIA_PRIMA'::text WHEN ((has_energy_cost_parameter = false) OR (has_machine_cost_parameter = false)) THEN 'PARCIAL_FALTAN_COSTES_OPERATIVOS'::text ELSE 'LISTO_PARA_MARGEN'::text END AS cost_readiness_status, CASE WHEN (cost_readiness_blockers = ''::text) THEN 'Orden lista para cálculo de margen estimado.'::text ELSE cost_readiness_blockers END AS cost_readiness_description FROM scored; ALTER VIEW mv_reports_ucepsa_demo.cost_readiness_orders_v1 OWNER TO mesavault; -- -- Name: cost_readiness_raw_materials_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.cost_readiness_raw_materials_v1 AS SELECT tenant, site, raw_product_default_code, raw_product_name, raw_uom, count(DISTINCT odoo_order_ref) AS affected_order_count, string_agg(DISTINCT odoo_order_ref, ', '::text ORDER BY odoo_order_ref) AS affected_orders, string_agg(DISTINCT COALESCE(sale_order_ref, 'sin_pedido_venta'::text), ', '::text ORDER BY COALESCE(sale_order_ref, 'sin_pedido_venta'::text)) AS affected_sale_orders, string_agg(DISTINCT COALESCE(customer_name, 'sin_cliente'::text), ', '::text ORDER BY COALESCE(customer_name, 'sin_cliente'::text)) AS affected_customers, round(sum(COALESCE(consumed_qty, (0)::numeric)), 3) AS total_consumed_qty, count(*) AS raw_material_line_count, count(*) FILTER (WHERE (material_cost_status = 'MISSING_RAW_MATERIAL_COST_PARAMETER'::text)) AS missing_cost_line_count, max(material_cost_eur_per_kg) AS current_material_cost_eur_per_kg, CASE WHEN (count(*) FILTER (WHERE (material_cost_status = 'MISSING_RAW_MATERIAL_COST_PARAMETER'::text)) > 0) THEN 'PENDIENTE_COSTE_MATERIA_PRIMA'::text ELSE 'COSTE_DISPONIBLE'::text END AS raw_material_readiness_status, CASE WHEN (count(*) FILTER (WHERE (material_cost_status = 'MISSING_RAW_MATERIAL_COST_PARAMETER'::text)) > 0) THEN concat('Falta coste €/kg para ', COALESCE(raw_product_default_code, 'sin_codigo'::text), ' - ', COALESCE(raw_product_name, 'sin_nombre'::text)) ELSE 'Coste de materia prima disponible.'::text END AS recommended_action FROM mv_reports_ucepsa_demo.order_raw_material_costs_v1 GROUP BY tenant, site, raw_product_default_code, raw_product_name, raw_uom; ALTER VIEW mv_reports_ucepsa_demo.cost_readiness_raw_materials_v1 OWNER TO mesavault; -- -- Name: cost_readiness_summary_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.cost_readiness_summary_v1 AS SELECT tenant, site, count(*) AS total_orders, count(*) FILTER (WHERE (has_revenue = true)) AS orders_with_revenue, count(*) FILTER (WHERE (has_revenue = false)) AS orders_without_revenue, count(*) FILTER (WHERE (has_raw_materials = true)) AS orders_with_raw_materials, count(*) FILTER (WHERE (has_raw_materials = false)) AS orders_without_raw_materials, count(*) FILTER (WHERE ((has_raw_materials = true) AND (has_raw_material_cost = false))) AS orders_missing_raw_material_cost, count(*) FILTER (WHERE (has_usable_technical_data = false)) AS orders_with_bad_technical_data, count(*) FILTER (WHERE (cost_readiness_status = 'LISTO_PARA_MARGEN'::text)) AS orders_ready_for_margin, count(*) FILTER (WHERE (cost_readiness_status = 'BLOQUEADO_FALTA_COSTE_MATERIA_PRIMA'::text)) AS orders_blocked_missing_raw_material_cost, count(*) FILTER (WHERE (cost_readiness_status = 'BLOQUEADO_SIN_INGRESO'::text)) AS orders_blocked_no_revenue, round(avg(cost_readiness_score), 2) AS avg_cost_readiness_score, min(cost_readiness_score) AS min_cost_readiness_score, max(cost_readiness_score) AS max_cost_readiness_score FROM mv_reports_ucepsa_demo.cost_readiness_orders_v1 GROUP BY tenant, site; ALTER VIEW mv_reports_ucepsa_demo.cost_readiness_summary_v1 OWNER TO mesavault; -- -- Name: cycle_rate_timeseries; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.cycle_rate_timeseries AS SELECT ts AS "time", cycle_rate_ppm, 10.0 AS target_cycle_rate_ppm FROM mv_hot.edge_oee_live_telemetry WHERE ((asset = 'revpi_oee_node_01'::text) AND (cycle_rate_ppm IS NOT NULL)) ORDER BY ts; ALTER VIEW mv_reports_ucepsa_demo.cycle_rate_timeseries OWNER TO mesavault; -- -- Name: data_quality_contract_order_checks_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.data_quality_contract_order_checks_v1 AS WITH raw_stats AS ( SELECT order_raw_material_costs_v1.odoo_instance, order_raw_material_costs_v1.odoo_production_id, count(*) AS raw_line_count, count(*) FILTER (WHERE ((order_raw_material_costs_v1.raw_product_default_code IS NULL) OR (TRIM(BOTH FROM order_raw_material_costs_v1.raw_product_default_code) = ''::text))) AS raw_missing_code_count, string_agg(DISTINCT concat(COALESCE(order_raw_material_costs_v1.raw_product_default_code, 'sin_codigo'::text), ' - ', COALESCE(order_raw_material_costs_v1.raw_product_name, 'sin_nombre'::text)), '; '::text ORDER BY (concat(COALESCE(order_raw_material_costs_v1.raw_product_default_code, 'sin_codigo'::text), ' - ', COALESCE(order_raw_material_costs_v1.raw_product_name, 'sin_nombre'::text)))) AS raw_materials_detected FROM mv_reports_ucepsa_demo.order_raw_material_costs_v1 GROUP BY order_raw_material_costs_v1.odoo_instance, order_raw_material_costs_v1.odoo_production_id ), base AS ( SELECT m.order_row_id, m.tenant, m.site, m.odoo_instance, m.odoo_workorder_id, m.odoo_production_id, m.odoo_order_ref, m.odoo_state, m.sale_order_ref, m.customer_name, m.revenue_net_eur, m.machine_id, m.asset, m.product_default_code, m.product_name, m.raw_material_line_count, m.raw_total_consumed_qty, m.raw_materials_summary, m.raw_material_cost_status_summary, m.missing_or_invalid_raw_material_cost_count, m.material_cost_estimated_eur, m.material_cost_source_status, m.energy_cost_eur_per_kwh, m.machine_run_cost_eur_per_h, m.kwh_consumed, m.run_min, m.stop_cost_eur, m.technical_quality_level, m.final_report_status, m.margin_status, r_1.pending_stops, r_1.production_conversion_status, COALESCE(rs.raw_line_count, (0)::bigint) AS dqc_raw_line_count, COALESCE(rs.raw_missing_code_count, (0)::bigint) AS dqc_raw_missing_code_count, rs.raw_materials_detected FROM ((mv_reports_ucepsa_demo.order_margin_report_v1 m LEFT JOIN mv_reports_ucepsa_demo.order_execution_report_full_v1 r_1 ON ((r_1.order_row_id = m.order_row_id))) LEFT JOIN raw_stats rs ON (((rs.odoo_instance = m.odoo_instance) AND (rs.odoo_production_id = m.odoo_production_id)))) ), evaluations AS ( SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-ODOO-001'::text AS rule_code, CASE WHEN ((b.odoo_order_ref IS NOT NULL) AND (b.odoo_production_id IS NOT NULL)) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN ((b.odoo_order_ref IS NOT NULL) AND (b.odoo_production_id IS NOT NULL)) THEN 'Orden de fabricación correctamente identificada.'::text ELSE 'Falta referencia de orden o identificador de producción Odoo.'::text END AS finding, CASE WHEN ((b.odoo_order_ref IS NOT NULL) AND (b.odoo_production_id IS NOT NULL)) THEN 'Sin acción.'::text ELSE 'Revisar sincronización de mrp.production / mrp.workorder desde Odoo.'::text END AS recommended_action, jsonb_build_object('odoo_order_ref', b.odoo_order_ref, 'odoo_production_id', b.odoo_production_id) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-ODOO-002'::text AS rule_code, CASE WHEN ((b.machine_id IS NOT NULL) AND (TRIM(BOTH FROM b.machine_id) <> ''::text)) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN ((b.machine_id IS NOT NULL) AND (TRIM(BOTH FROM b.machine_id) <> ''::text)) THEN 'Centro de trabajo mapeado a máquina MESAVAULT.'::text ELSE 'Falta machine_id o mapeo de centro de trabajo.'::text END AS finding, CASE WHEN ((b.machine_id IS NOT NULL) AND (TRIM(BOTH FROM b.machine_id) <> ''::text)) THEN 'Sin acción.'::text ELSE 'Revisar tabla de mapeo Odoo workcenter → machine_id.'::text END AS recommended_action, jsonb_build_object('machine_id', b.machine_id, 'asset', b.asset) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-ODOO-003'::text AS rule_code, CASE WHEN (COALESCE(NULLIF(TRIM(BOTH FROM b.product_name), ''::text), NULLIF(TRIM(BOTH FROM b.product_default_code), ''::text)) IS NULL) THEN 'FAIL'::text WHEN ((b.product_default_code IS NULL) OR (TRIM(BOTH FROM b.product_default_code) = ''::text)) THEN 'WARN'::text ELSE 'PASS'::text END AS check_status, CASE WHEN (COALESCE(NULLIF(TRIM(BOTH FROM b.product_name), ''::text), NULLIF(TRIM(BOTH FROM b.product_default_code), ''::text)) IS NULL) THEN 'Falta identificación del producto.'::text WHEN ((b.product_default_code IS NULL) OR (TRIM(BOTH FROM b.product_default_code) = ''::text)) THEN 'Producto identificado por nombre, pero sin código interno.'::text ELSE 'Producto identificado con nombre y código interno.'::text END AS finding, CASE WHEN (COALESCE(NULLIF(TRIM(BOTH FROM b.product_name), ''::text), NULLIF(TRIM(BOTH FROM b.product_default_code), ''::text)) IS NULL) THEN 'Revisar maestro de producto en Odoo.'::text WHEN ((b.product_default_code IS NULL) OR (TRIM(BOTH FROM b.product_default_code) = ''::text)) THEN 'Completar código interno/default_code del producto en Odoo.'::text ELSE 'Sin acción.'::text END AS recommended_action, jsonb_build_object('product_default_code', b.product_default_code, 'product_name', b.product_name) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-SALES-001'::text AS rule_code, CASE WHEN ((b.sale_order_ref IS NOT NULL) AND (b.revenue_net_eur IS NOT NULL)) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN ((b.sale_order_ref IS NOT NULL) AND (b.revenue_net_eur IS NOT NULL)) THEN 'Ingreso de venta vinculado a la orden.'::text ELSE 'La orden no tiene ingreso de venta vinculado.'::text END AS finding, CASE WHEN ((b.sale_order_ref IS NOT NULL) AND (b.revenue_net_eur IS NOT NULL)) THEN 'Sin acción.'::text ELSE 'Revisar sale_line_id, pedido de venta u origen de la orden de fabricación.'::text END AS recommended_action, jsonb_build_object('sale_order_ref', b.sale_order_ref, 'revenue_net_eur', b.revenue_net_eur) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-SALES-002'::text AS rule_code, CASE WHEN (b.sale_order_ref IS NULL) THEN 'NOT_APPLICABLE'::text WHEN ((b.customer_name IS NOT NULL) AND (TRIM(BOTH FROM b.customer_name) <> ''::text)) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN (b.sale_order_ref IS NULL) THEN 'No aplica porque no hay pedido de venta vinculado.'::text WHEN ((b.customer_name IS NOT NULL) AND (TRIM(BOTH FROM b.customer_name) <> ''::text)) THEN 'Cliente vinculado correctamente.'::text ELSE 'Hay pedido de venta, pero falta cliente.'::text END AS finding, CASE WHEN (b.sale_order_ref IS NULL) THEN 'Resolver primero el vínculo de venta.'::text WHEN ((b.customer_name IS NOT NULL) AND (TRIM(BOTH FROM b.customer_name) <> ''::text)) THEN 'Sin acción.'::text ELSE 'Revisar partner_id del pedido de venta en Odoo.'::text END AS recommended_action, jsonb_build_object('sale_order_ref', b.sale_order_ref, 'customer_name', b.customer_name) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-RAW-001'::text AS rule_code, CASE WHEN (COALESCE(b.raw_material_line_count, (0)::bigint) > 0) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN (COALESCE(b.raw_material_line_count, (0)::bigint) > 0) THEN 'Materia prima consumida detectada.'::text ELSE 'No se detecta materia prima consumida para la orden.'::text END AS finding, CASE WHEN (COALESCE(b.raw_material_line_count, (0)::bigint) > 0) THEN 'Sin acción.'::text ELSE 'Revisar movimientos de stock/MRP asociados a la orden.'::text END AS recommended_action, jsonb_build_object('raw_material_line_count', b.raw_material_line_count, 'raw_materials_summary', b.raw_materials_summary) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-RAW-002'::text AS rule_code, CASE WHEN (COALESCE(b.dqc_raw_line_count, (0)::bigint) = 0) THEN 'NOT_APPLICABLE'::text WHEN (COALESCE(b.dqc_raw_missing_code_count, (0)::bigint) = 0) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN (COALESCE(b.dqc_raw_line_count, (0)::bigint) = 0) THEN 'No aplica porque no hay materia prima detectada.'::text WHEN (COALESCE(b.dqc_raw_missing_code_count, (0)::bigint) = 0) THEN 'Todas las materias primas detectadas tienen código identificable.'::text ELSE 'Hay materias primas sin código identificable.'::text END AS finding, CASE WHEN (COALESCE(b.dqc_raw_line_count, (0)::bigint) = 0) THEN 'Resolver primero la detección de materia prima.'::text WHEN (COALESCE(b.dqc_raw_missing_code_count, (0)::bigint) = 0) THEN 'Sin acción.'::text ELSE 'Completar código interno/default_code de materias primas en Odoo.'::text END AS recommended_action, jsonb_build_object('raw_line_count', b.dqc_raw_line_count, 'raw_missing_code_count', b.dqc_raw_missing_code_count, 'raw_materials_detected', b.raw_materials_detected) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-COST-001'::text AS rule_code, CASE WHEN (b.material_cost_estimated_eur IS NOT NULL) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN (b.material_cost_estimated_eur IS NOT NULL) THEN 'Coste de materia prima disponible.'::text ELSE 'Falta coste de materia prima.'::text END AS finding, CASE WHEN (b.material_cost_estimated_eur IS NOT NULL) THEN 'Sin acción.'::text ELSE COALESCE(concat('Cargar coste €/kg para materia prima: ', b.raw_materials_summary), 'Cargar coste de materia prima o revisar valoración en Odoo.'::text) END AS recommended_action, jsonb_build_object('material_cost_estimated_eur', b.material_cost_estimated_eur, 'material_cost_source_status', b.material_cost_source_status, 'raw_materials_summary', b.raw_materials_summary) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-COST-002'::text AS rule_code, CASE WHEN (b.kwh_consumed IS NULL) THEN 'NOT_APPLICABLE'::text WHEN (b.energy_cost_eur_per_kwh IS NOT NULL) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN (b.kwh_consumed IS NULL) THEN 'No aplica porque no hay consumo energético medido.'::text WHEN (b.energy_cost_eur_per_kwh IS NOT NULL) THEN 'Coste energético parametrizado.'::text ELSE 'Hay consumo energético, pero falta coste €/kWh.'::text END AS finding, CASE WHEN (b.kwh_consumed IS NULL) THEN 'Sin acción.'::text WHEN (b.energy_cost_eur_per_kwh IS NOT NULL) THEN 'Sin acción.'::text ELSE 'Cargar coste €/kWh en margin_cost_parameters.'::text END AS recommended_action, jsonb_build_object('kwh_consumed', b.kwh_consumed, 'energy_cost_eur_per_kwh', b.energy_cost_eur_per_kwh) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-COST-003'::text AS rule_code, CASE WHEN (b.run_min IS NULL) THEN 'NOT_APPLICABLE'::text WHEN (b.machine_run_cost_eur_per_h IS NOT NULL) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN (b.run_min IS NULL) THEN 'No aplica porque no hay tiempo de máquina utilizable.'::text WHEN (b.machine_run_cost_eur_per_h IS NOT NULL) THEN 'Coste hora máquina parametrizado.'::text ELSE 'Hay tiempo de máquina, pero falta coste hora máquina.'::text END AS finding, CASE WHEN (b.run_min IS NULL) THEN 'Sin acción.'::text WHEN (b.machine_run_cost_eur_per_h IS NOT NULL) THEN 'Sin acción.'::text ELSE 'Cargar coste hora máquina para la máquina correspondiente.'::text END AS recommended_action, jsonb_build_object('machine_id', b.machine_id, 'run_min', b.run_min, 'machine_run_cost_eur_per_h', b.machine_run_cost_eur_per_h) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-EDGE-001'::text AS rule_code, CASE WHEN (b.technical_quality_level = ANY (ARRAY['FIABLE'::text, 'ACEPTABLE_CON_OBSERVACIONES'::text])) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN (b.technical_quality_level = ANY (ARRAY['FIABLE'::text, 'ACEPTABLE_CON_OBSERVACIONES'::text])) THEN 'Datos técnicos defendibles.'::text ELSE 'Datos técnicos no defendibles para análisis.'::text END AS finding, CASE WHEN (b.technical_quality_level = ANY (ARRAY['FIABLE'::text, 'ACEPTABLE_CON_OBSERVACIONES'::text])) THEN 'Sin acción.'::text ELSE 'Revisar telemetría, cobertura Edge-OEE y calidad del informe técnico.'::text END AS recommended_action, jsonb_build_object('technical_quality_level', b.technical_quality_level) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-EDGE-002'::text AS rule_code, CASE WHEN (b.final_report_status = ANY (ARRAY['LISTO_INFORME_FINAL'::text, 'LISTO_TECNICO_REVISAR_CONVERSION'::text, 'LISTO_CON_OBSERVACIONES'::text])) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN (b.final_report_status = ANY (ARRAY['LISTO_INFORME_FINAL'::text, 'LISTO_TECNICO_REVISAR_CONVERSION'::text, 'LISTO_CON_OBSERVACIONES'::text])) THEN 'Informe técnico cerrado o utilizable.'::text ELSE 'Informe técnico parcial o bloqueado.'::text END AS finding, CASE WHEN (b.final_report_status = ANY (ARRAY['LISTO_INFORME_FINAL'::text, 'LISTO_TECNICO_REVISAR_CONVERSION'::text, 'LISTO_CON_OBSERVACIONES'::text])) THEN 'Sin acción.'::text ELSE 'Cerrar orden, revisar telemetría o completar clasificación antes de análisis económico final.'::text END AS recommended_action, jsonb_build_object('final_report_status', b.final_report_status) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-STOPS-001'::text AS rule_code, CASE WHEN (COALESCE(b.pending_stops, (0)::bigint) = 0) THEN 'PASS'::text ELSE 'FAIL'::text END AS check_status, CASE WHEN (COALESCE(b.pending_stops, (0)::bigint) = 0) THEN 'No hay paros pendientes de clasificación.'::text ELSE 'Hay paros pendientes de clasificación.'::text END AS finding, CASE WHEN (COALESCE(b.pending_stops, (0)::bigint) = 0) THEN 'Sin acción.'::text ELSE 'Clasificar paros pendientes desde la consola de paros.'::text END AS recommended_action, jsonb_build_object('pending_stops', b.pending_stops) AS evidence_json FROM base b UNION ALL SELECT b.order_row_id, b.tenant, b.site, b.odoo_instance, b.odoo_workorder_id, b.odoo_production_id, b.odoo_order_ref, b.odoo_state, b.sale_order_ref, b.customer_name, b.revenue_net_eur, b.machine_id, b.asset, b.product_default_code, b.product_name, b.raw_material_line_count, b.raw_total_consumed_qty, b.raw_materials_summary, b.raw_material_cost_status_summary, b.missing_or_invalid_raw_material_cost_count, b.material_cost_estimated_eur, b.material_cost_source_status, b.energy_cost_eur_per_kwh, b.machine_run_cost_eur_per_h, b.kwh_consumed, b.run_min, b.stop_cost_eur, b.technical_quality_level, b.final_report_status, b.margin_status, b.pending_stops, b.production_conversion_status, b.dqc_raw_line_count, b.dqc_raw_missing_code_count, b.raw_materials_detected, 'DQC-CONV-001'::text AS rule_code, CASE WHEN (b.production_conversion_status = 'CICLOS_COHERENTES_CON_OBJETIVO'::text) THEN 'PASS'::text WHEN (b.production_conversion_status = 'CANTIDAD_ODOO_SIN_CICLOS_EDGE'::text) THEN 'FAIL'::text ELSE 'WARN'::text END AS check_status, CASE WHEN (b.production_conversion_status = 'CICLOS_COHERENTES_CON_OBJETIVO'::text) THEN 'Conversión producción-ciclos coherente.'::text WHEN (b.production_conversion_status = 'CANTIDAD_ODOO_SIN_CICLOS_EDGE'::text) THEN 'Odoo muestra cantidad producida, pero Edge no detecta ciclos.'::text ELSE 'Conversión producción-ciclos pendiente de revisión o no concluyente.'::text END AS finding, CASE WHEN (b.production_conversion_status = 'CICLOS_COHERENTES_CON_OBJETIVO'::text) THEN 'Sin acción.'::text ELSE 'Validar relación entre kg, bolsas, unidad comercial y ciclos/golpes.'::text END AS recommended_action, jsonb_build_object('production_conversion_status', b.production_conversion_status) AS evidence_json FROM base b ) SELECT e.order_row_id, e.tenant, e.site, e.odoo_instance, e.odoo_workorder_id, e.odoo_production_id, e.odoo_order_ref, e.odoo_state, e.sale_order_ref, e.customer_name, e.product_default_code, e.product_name, e.machine_id, r.rule_code, r.rule_name, r.domain, r.dimension, r.severity, r.owner_area, r.applies_to, r.blocking_for, e.check_status, CASE WHEN (e.check_status = 'PASS'::text) THEN true WHEN (e.check_status = 'NOT_APPLICABLE'::text) THEN NULL::boolean ELSE false END AS check_passed, e.finding, e.recommended_action, e.evidence_json, CASE WHEN ((e.check_status = 'FAIL'::text) AND (r.severity = 'CRITICAL'::text)) THEN 100 WHEN ((e.check_status = 'FAIL'::text) AND (r.severity = 'HIGH'::text)) THEN 75 WHEN ((e.check_status = 'FAIL'::text) AND (r.severity = 'MEDIUM'::text)) THEN 50 WHEN ((e.check_status = 'WARN'::text) AND (r.severity = 'CRITICAL'::text)) THEN 60 WHEN ((e.check_status = 'WARN'::text) AND (r.severity = 'HIGH'::text)) THEN 45 WHEN ((e.check_status = 'WARN'::text) AND (r.severity = 'MEDIUM'::text)) THEN 30 ELSE 0 END AS issue_score FROM (evaluations e JOIN mv_edge_oee_ucepsa_demo.data_quality_contract_rules r ON (((r.tenant = e.tenant) AND (r.site = e.site) AND (r.rule_code = e.rule_code) AND (r.is_active = true)))); ALTER VIEW mv_reports_ucepsa_demo.data_quality_contract_order_checks_v1 OWNER TO mesavault; -- -- Name: data_quality_contract_order_summary_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.data_quality_contract_order_summary_v1 AS WITH checks AS ( SELECT data_quality_contract_order_checks_v1.order_row_id, data_quality_contract_order_checks_v1.tenant, data_quality_contract_order_checks_v1.site, data_quality_contract_order_checks_v1.odoo_instance, data_quality_contract_order_checks_v1.odoo_workorder_id, data_quality_contract_order_checks_v1.odoo_production_id, data_quality_contract_order_checks_v1.odoo_order_ref, data_quality_contract_order_checks_v1.odoo_state, data_quality_contract_order_checks_v1.sale_order_ref, data_quality_contract_order_checks_v1.customer_name, data_quality_contract_order_checks_v1.product_default_code, data_quality_contract_order_checks_v1.product_name, data_quality_contract_order_checks_v1.machine_id, data_quality_contract_order_checks_v1.rule_code, data_quality_contract_order_checks_v1.rule_name, data_quality_contract_order_checks_v1.domain, data_quality_contract_order_checks_v1.dimension, data_quality_contract_order_checks_v1.severity, data_quality_contract_order_checks_v1.owner_area, data_quality_contract_order_checks_v1.applies_to, data_quality_contract_order_checks_v1.blocking_for, data_quality_contract_order_checks_v1.check_status, data_quality_contract_order_checks_v1.check_passed, data_quality_contract_order_checks_v1.finding, data_quality_contract_order_checks_v1.recommended_action, data_quality_contract_order_checks_v1.evidence_json, data_quality_contract_order_checks_v1.issue_score FROM mv_reports_ucepsa_demo.data_quality_contract_order_checks_v1 ), agg AS ( SELECT checks.order_row_id, checks.tenant, checks.site, checks.odoo_instance, checks.odoo_workorder_id, checks.odoo_production_id, checks.odoo_order_ref, checks.odoo_state, checks.sale_order_ref, checks.customer_name, checks.product_default_code, checks.product_name, checks.machine_id, count(*) AS total_rules, count(*) FILTER (WHERE (checks.check_status = 'PASS'::text)) AS passed_rules, count(*) FILTER (WHERE (checks.check_status = 'FAIL'::text)) AS failed_rules, count(*) FILTER (WHERE (checks.check_status = 'WARN'::text)) AS warn_rules, count(*) FILTER (WHERE (checks.check_status = 'NOT_APPLICABLE'::text)) AS not_applicable_rules, count(*) FILTER (WHERE ((checks.check_status = 'FAIL'::text) AND (checks.severity = 'CRITICAL'::text))) AS critical_failures, count(*) FILTER (WHERE ((checks.check_status = 'FAIL'::text) AND (checks.severity = 'HIGH'::text))) AS high_failures, count(*) FILTER (WHERE ((checks.check_status = 'FAIL'::text) AND (checks.severity = 'MEDIUM'::text))) AS medium_failures, count(*) FILTER (WHERE ((checks.check_status = 'WARN'::text) AND (checks.severity = 'CRITICAL'::text))) AS critical_warnings, count(*) FILTER (WHERE ((checks.check_status = 'WARN'::text) AND (checks.severity = 'HIGH'::text))) AS high_warnings, count(*) FILTER (WHERE ((checks.check_status = 'WARN'::text) AND (checks.severity = 'MEDIUM'::text))) AS medium_warnings, COALESCE(sum(checks.issue_score), (0)::bigint) AS total_issue_score, max(checks.issue_score) AS max_issue_score FROM checks GROUP BY checks.order_row_id, checks.tenant, checks.site, checks.odoo_instance, checks.odoo_workorder_id, checks.odoo_production_id, checks.odoo_order_ref, checks.odoo_state, checks.sale_order_ref, checks.customer_name, checks.product_default_code, checks.product_name, checks.machine_id ), main_issue AS ( SELECT DISTINCT ON (checks.order_row_id) checks.order_row_id, checks.rule_code AS main_blocker_rule_code, checks.rule_name AS main_blocker_rule_name, checks.domain AS main_blocker_domain, checks.severity AS main_blocker_severity, checks.owner_area AS owner_area_to_act, checks.blocking_for, checks.check_status AS main_blocker_status, checks.finding AS main_blocker_finding, checks.recommended_action AS main_recommended_action, checks.issue_score AS main_issue_score FROM checks WHERE (checks.check_status = ANY (ARRAY['FAIL'::text, 'WARN'::text])) ORDER BY checks.order_row_id, checks.issue_score DESC, CASE checks.severity WHEN 'CRITICAL'::text THEN 1 WHEN 'HIGH'::text THEN 2 WHEN 'MEDIUM'::text THEN 3 ELSE 4 END, checks.rule_code ) SELECT a.order_row_id, a.tenant, a.site, a.odoo_instance, a.odoo_workorder_id, a.odoo_production_id, a.odoo_order_ref, a.odoo_state, a.sale_order_ref, a.customer_name, a.product_default_code, a.product_name, a.machine_id, a.total_rules, a.passed_rules, a.failed_rules, a.warn_rules, a.not_applicable_rules, a.critical_failures, a.high_failures, a.medium_failures, a.critical_warnings, a.high_warnings, a.medium_warnings, a.total_issue_score, a.max_issue_score, GREATEST((0)::bigint, (100 - LEAST(a.total_issue_score, (100)::bigint))) AS contract_score, CASE WHEN (a.critical_failures > 0) THEN 'BLOQUEADO_CRITICO'::text WHEN (a.high_failures > 0) THEN 'BLOQUEADO_ALTO'::text WHEN (a.medium_failures > 0) THEN 'BLOQUEADO_MEDIO'::text WHEN (a.warn_rules > 0) THEN 'VALIDO_CON_OBSERVACIONES'::text WHEN ((a.failed_rules = 0) AND (a.warn_rules = 0)) THEN 'CONTRATO_CUMPLIDO'::text ELSE 'REVISAR'::text END AS contract_status, mi.main_blocker_rule_code, mi.main_blocker_rule_name, mi.main_blocker_domain, mi.main_blocker_severity, mi.owner_area_to_act, mi.blocking_for, mi.main_blocker_status, mi.main_blocker_finding, mi.main_recommended_action, mi.main_issue_score, CASE WHEN (a.critical_failures > 0) THEN concat('Contrato bloqueado por fallo crítico: ', COALESCE(mi.main_blocker_finding, 'sin detalle'::text)) WHEN (a.high_failures > 0) THEN concat('Contrato bloqueado por fallo alto: ', COALESCE(mi.main_blocker_finding, 'sin detalle'::text)) WHEN (a.medium_failures > 0) THEN concat('Contrato bloqueado por fallo medio: ', COALESCE(mi.main_blocker_finding, 'sin detalle'::text)) WHEN (a.warn_rules > 0) THEN concat('Contrato válido con observaciones: ', COALESCE(mi.main_blocker_finding, 'sin detalle'::text)) ELSE 'Contrato de datos cumplido para esta orden.'::text END AS contract_summary FROM (agg a LEFT JOIN main_issue mi ON ((mi.order_row_id = a.order_row_id))); ALTER VIEW mv_reports_ucepsa_demo.data_quality_contract_order_summary_v1 OWNER TO mesavault; -- -- Name: data_quality_contract_owner_summary_v1; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.data_quality_contract_owner_summary_v1 AS SELECT tenant, site, owner_area, count(*) FILTER (WHERE (check_status = 'FAIL'::text)) AS failed_checks, count(*) FILTER (WHERE (check_status = 'WARN'::text)) AS warn_checks, count(*) FILTER (WHERE ((check_status = 'FAIL'::text) AND (severity = 'CRITICAL'::text))) AS critical_failed_checks, count(*) FILTER (WHERE ((check_status = 'FAIL'::text) AND (severity = 'HIGH'::text))) AS high_failed_checks, count(DISTINCT odoo_order_ref) FILTER (WHERE (check_status = ANY (ARRAY['FAIL'::text, 'WARN'::text]))) AS affected_orders, sum(issue_score) FILTER (WHERE (check_status = ANY (ARRAY['FAIL'::text, 'WARN'::text]))) AS total_issue_score, string_agg(DISTINCT rule_code, ', '::text ORDER BY rule_code) FILTER (WHERE (check_status = ANY (ARRAY['FAIL'::text, 'WARN'::text]))) AS affected_rules, string_agg(DISTINCT odoo_order_ref, ', '::text ORDER BY odoo_order_ref) FILTER (WHERE (check_status = ANY (ARRAY['FAIL'::text, 'WARN'::text]))) AS affected_order_refs FROM mv_reports_ucepsa_demo.data_quality_contract_order_checks_v1 GROUP BY tenant, site, owner_area; ALTER VIEW mv_reports_ucepsa_demo.data_quality_contract_owner_summary_v1 OWNER TO mesavault; -- -- Name: energy_3phase_timeseries; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.energy_3phase_timeseries AS SELECT ingest_ts AS ts, ingest_ts, tenant, site, asset, machine_id, (EXTRACT(epoch FROM (now() - ingest_ts)))::double precision AS age_s, comm_ok, CASE WHEN (lower((payload_json ->> 'sample_valid'::text)) = ANY (ARRAY['true'::text, 't'::text, '1'::text, 'yes'::text])) THEN true WHEN (lower((payload_json ->> 'sample_valid'::text)) = ANY (ARRAY['false'::text, 'f'::text, '0'::text, 'no'::text])) THEN false ELSE NULL::boolean END AS sample_valid, (payload_json ->> 'energy_meter_model'::text) AS energy_meter_model, (payload_json ->> 'energy_map'::text) AS energy_map, voltage_l1_v, (NULLIF((payload_json ->> 'voltage_l2_v'::text), ''::text))::double precision AS voltage_l2_v, (NULLIF((payload_json ->> 'voltage_l3_v'::text), ''::text))::double precision AS voltage_l3_v, current_l1_a, (NULLIF((payload_json ->> 'current_l2_a'::text), ''::text))::double precision AS current_l2_a, (NULLIF((payload_json ->> 'current_l3_a'::text), ''::text))::double precision AS current_l3_a, (NULLIF((payload_json ->> 'active_power_l1_w'::text), ''::text))::double precision AS active_power_l1_w, (NULLIF((payload_json ->> 'active_power_l2_w'::text), ''::text))::double precision AS active_power_l2_w, (NULLIF((payload_json ->> 'active_power_l3_w'::text), ''::text))::double precision AS active_power_l3_w, COALESCE((NULLIF((payload_json ->> 'active_power_w'::text), ''::text))::double precision, ((power_total_kw * 1000.0))::double precision) AS active_power_w, power_total_kw, (NULLIF((payload_json ->> 'apparent_power_va'::text), ''::text))::double precision AS apparent_power_va, (NULLIF((payload_json ->> 'reactive_power_var'::text), ''::text))::double precision AS reactive_power_var, (NULLIF((payload_json ->> 'power_factor'::text), ''::text))::double precision AS power_factor, frequency_hz, import_kwh, (NULLIF((payload_json ->> 'export_kwh'::text), ''::text))::double precision AS export_kwh, (NULLIF((payload_json ->> 'total_active_energy_kwh'::text), ''::text))::double precision AS total_active_energy_kwh, payload_json FROM mv_hot.edge_oee_eastron_readings r; ALTER VIEW mv_reports_ucepsa_demo.energy_3phase_timeseries OWNER TO mesavault; -- -- Name: energy_3phase_latest; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.energy_3phase_latest AS SELECT DISTINCT ON (machine_id) ts, ingest_ts, tenant, site, asset, machine_id, age_s, comm_ok, sample_valid, energy_meter_model, energy_map, voltage_l1_v, voltage_l2_v, voltage_l3_v, current_l1_a, current_l2_a, current_l3_a, active_power_l1_w, active_power_l2_w, active_power_l3_w, active_power_w, power_total_kw, apparent_power_va, reactive_power_var, power_factor, frequency_hz, import_kwh, export_kwh, total_active_energy_kwh, payload_json FROM mv_reports_ucepsa_demo.energy_3phase_timeseries WHERE (site = 'ucepsa_onpremise'::text) ORDER BY machine_id, ingest_ts DESC; ALTER VIEW mv_reports_ucepsa_demo.energy_3phase_latest OWNER TO mesavault; -- -- Name: energy_diagnosis; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.energy_diagnosis AS SELECT sort_order, group_name, metric, value, unit, status, problem, likely_impact, recommended_action FROM mv_hot.edge_oee_eastron_diagnosis_latest; ALTER VIEW mv_reports_ucepsa_demo.energy_diagnosis OWNER TO mesavault; -- -- Name: energy_import_timeseries; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.energy_import_timeseries AS SELECT ingest_ts AS "time", round((import_kwh * (1000)::numeric), 2) AS import_wh FROM mv_hot.edge_oee_eastron_readings WHERE (asset = 'revpi_oee_node_01'::text) ORDER BY ingest_ts; ALTER VIEW mv_reports_ucepsa_demo.energy_import_timeseries OWNER TO mesavault; -- -- Name: energy_latest; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.energy_latest AS SELECT ts, ingest_ts, age_s, tenant, site, asset, meter_model, meter_id, machine_id, voltage_l1_v, current_l1_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, comm_risk_level, comm_status FROM mv_hot.edge_oee_eastron_dashboard WHERE (asset = 'revpi_oee_node_01'::text); ALTER VIEW mv_reports_ucepsa_demo.energy_latest OWNER TO mesavault; -- -- Name: energy_power_timeseries; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.energy_power_timeseries AS SELECT ingest_ts AS "time", round((power_total_kw * (1000)::numeric), 2) AS power_w FROM mv_hot.edge_oee_eastron_readings WHERE (asset = 'revpi_oee_node_01'::text) ORDER BY ingest_ts; ALTER VIEW mv_reports_ucepsa_demo.energy_power_timeseries OWNER TO mesavault; -- -- Name: latest_machine_snapshot; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.latest_machine_snapshot AS SELECT ts, ingest_ts, age_s, tenant, site, asset, machine_id, order_id, voltage_l1_v, current_l1_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, machine_auto_signal, machine_running, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, digital_inputs, payload_json FROM mv_hot.edge_oee_latest_machine_snapshot WHERE (asset = 'revpi_oee_node_01'::text); ALTER VIEW mv_reports_ucepsa_demo.latest_machine_snapshot OWNER TO mesavault; -- -- Name: latest_machine_state_fast; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.latest_machine_state_fast AS SELECT ts, ingest_ts, age_s, tenant, site, asset, machine_id, order_id, voltage_l1_v, current_l1_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, machine_auto_signal, machine_running, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, digital_inputs, payload_json FROM mv_reports_ucepsa_demo.latest_machine_snapshot; ALTER VIEW mv_reports_ucepsa_demo.latest_machine_state_fast OWNER TO mesavault; -- -- Name: live_telemetry; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.live_telemetry AS SELECT ts, ingest_ts, age_s, tenant, site, asset, machine_id, order_id, voltage_l1_v, current_l1_a, power_total_kw, frequency_hz, import_kwh, export_kwh, comm_ok, error_text, machine_auto_signal, machine_running, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, digital_inputs, payload_json FROM mv_hot.edge_oee_live_telemetry WHERE (asset = 'revpi_oee_node_01'::text); ALTER VIEW mv_reports_ucepsa_demo.live_telemetry OWNER TO mesavault; -- -- Name: odoo_current_order_demo; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.odoo_current_order_demo AS WITH latest AS ( SELECT w.id, w.tenant, w.site, w.odoo_instance, w.odoo_workorder_id, w.odoo_production_id, w.odoo_order_ref, w.odoo_state, w.odoo_workcenter_code, w.odoo_workcenter_name, w.machine_id, w.asset, w.product, w.qty_planned, w.qty_done, w.uom, w.planned_cycles, w.target_cycle_rate_ppm, w.odoo_start, w.odoo_end, w.notes, w.snapshot_at, row_number() OVER (PARTITION BY w.odoo_instance, w.odoo_workorder_id ORDER BY w.snapshot_at DESC) AS rn FROM mv_edge_oee_ucepsa_demo.odoo_workorders_demo w WHERE ((w.odoo_instance = 'odoo_ucepsa_test'::text) AND (w.machine_id = 'CORT-01'::text)) ), candidates AS ( SELECT latest.id, latest.tenant, latest.site, latest.odoo_instance, latest.odoo_workorder_id, latest.odoo_production_id, latest.odoo_order_ref, latest.odoo_state, latest.odoo_workcenter_code, latest.odoo_workcenter_name, latest.machine_id, latest.asset, latest.product, latest.qty_planned, latest.qty_done, latest.uom, latest.planned_cycles, latest.target_cycle_rate_ppm, latest.odoo_start, latest.odoo_end, latest.notes, latest.snapshot_at, latest.rn FROM latest WHERE ((latest.rn = 1) AND (COALESCE(latest.odoo_state, ''::text) <> ALL (ARRAY['done'::text, 'cancel'::text, 'cancelled'::text]))) ) SELECT id, tenant, site, odoo_instance, odoo_workorder_id, odoo_production_id, odoo_order_ref, odoo_state, odoo_workcenter_code, odoo_workcenter_name, machine_id, asset, product, qty_planned, qty_done, uom, planned_cycles, target_cycle_rate_ppm, odoo_start, odoo_start AS odoo_reference_start, CASE WHEN (odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text, 'done'::text])) THEN true ELSE false END AS odoo_is_started, odoo_end, notes, snapshot_at FROM candidates ORDER BY CASE WHEN (odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text])) THEN 1 WHEN (odoo_state = 'ready'::text) THEN 2 WHEN (odoo_state = ANY (ARRAY['waiting'::text, 'pending'::text, 'confirmed'::text, 'planned'::text])) THEN 3 ELSE 9 END, COALESCE(odoo_start, snapshot_at) DESC LIMIT 1; ALTER VIEW mv_reports_ucepsa_demo.odoo_current_order_demo OWNER TO mesavault; -- -- Name: stops_recent; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.stops_recent AS SELECT id, tenant, site, vertical, asset, machine_id, order_id, started_at, ended_at, duration_s, duration_min, cost_eur, status, classification_status, cause_code, cause_name, is_planned, operator_note, value_hour_eur, start_event_name, end_event_name, created_at, updated_at FROM mv_hot.edge_oee_stops_recent WHERE (asset = 'revpi_oee_node_01'::text); ALTER VIEW mv_reports_ucepsa_demo.stops_recent OWNER TO mesavault; -- -- Name: odoo_vs_machine_demo; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.odoo_vs_machine_demo AS WITH odoo AS ( SELECT odoo_current_order_demo.id, odoo_current_order_demo.tenant, odoo_current_order_demo.site, odoo_current_order_demo.odoo_instance, odoo_current_order_demo.odoo_workorder_id, odoo_current_order_demo.odoo_production_id, odoo_current_order_demo.odoo_order_ref, odoo_current_order_demo.odoo_state, odoo_current_order_demo.odoo_workcenter_code, odoo_current_order_demo.odoo_workcenter_name, odoo_current_order_demo.machine_id, odoo_current_order_demo.asset, odoo_current_order_demo.product, odoo_current_order_demo.qty_planned, odoo_current_order_demo.qty_done, odoo_current_order_demo.uom, odoo_current_order_demo.planned_cycles, odoo_current_order_demo.target_cycle_rate_ppm, odoo_current_order_demo.odoo_start, odoo_current_order_demo.odoo_reference_start, odoo_current_order_demo.odoo_is_started, odoo_current_order_demo.odoo_end, odoo_current_order_demo.notes, odoo_current_order_demo.snapshot_at FROM mv_reports_ucepsa_demo.odoo_current_order_demo ), machine AS ( SELECT latest_machine_state_fast.ts, latest_machine_state_fast.ingest_ts, latest_machine_state_fast.age_s, latest_machine_state_fast.tenant, latest_machine_state_fast.site, latest_machine_state_fast.asset, latest_machine_state_fast.machine_id, latest_machine_state_fast.order_id, latest_machine_state_fast.voltage_l1_v, latest_machine_state_fast.current_l1_a, latest_machine_state_fast.power_total_kw, latest_machine_state_fast.frequency_hz, latest_machine_state_fast.import_kwh, latest_machine_state_fast.export_kwh, latest_machine_state_fast.comm_ok, latest_machine_state_fast.error_text, latest_machine_state_fast.machine_auto_signal, latest_machine_state_fast.machine_running, latest_machine_state_fast.cycle_pulse_count, latest_machine_state_fast.cycle_rate_ppm, latest_machine_state_fast.last_cycle_age_s, latest_machine_state_fast.digital_inputs, latest_machine_state_fast.payload_json FROM mv_reports_ucepsa_demo.latest_machine_state_fast WHERE (latest_machine_state_fast.machine_id = 'CORT-01'::text) ORDER BY latest_machine_state_fast.ingest_ts DESC LIMIT 1 ), stops AS ( SELECT o_1.odoo_workorder_id, (count(s_1.*))::integer AS stop_count, COALESCE(round(sum(s_1.duration_min), 2), (0)::numeric) AS stop_min, COALESCE(round(sum(s_1.cost_eur), 2), (0)::numeric) AS stop_cost_eur FROM (odoo o_1 LEFT JOIN mv_reports_ucepsa_demo.stops_recent s_1 ON (((s_1.machine_id = o_1.machine_id) AND (s_1.started_at >= COALESCE(o_1.odoo_reference_start, o_1.odoo_start, o_1.snapshot_at)) AND (s_1.started_at <= COALESCE(o_1.odoo_end, now()))))) GROUP BY o_1.odoo_workorder_id ) 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, COALESCE(m.machine_running, false) AS machine_running, m.age_s AS telemetry_age_s, COALESCE(m.cycle_pulse_count, (0)::bigint) AS cycle_pulse_count, COALESCE(m.cycle_rate_ppm, (0)::numeric) AS cycle_rate_ppm, ma.first_machine_activity, CASE WHEN ((o.odoo_is_started = true) AND (ma.first_machine_activity IS NOT NULL) AND (COALESCE(o.odoo_reference_start, o.odoo_start) IS NOT NULL)) THEN round((GREATEST(EXTRACT(epoch FROM (ma.first_machine_activity - COALESCE(o.odoo_reference_start, o.odoo_start))), (0)::numeric) / 60.0), 2) ELSE NULL::numeric END AS start_delay_min, COALESCE(s.stop_count, 0) AS stop_count, COALESCE(s.stop_min, (0)::numeric) AS stop_min, COALESCE(s.stop_cost_eur, (0)::numeric) AS stop_cost_eur, (COALESCE(m.cycle_pulse_count, (0)::bigint))::numeric AS real_cycles, COALESCE(o.planned_cycles, o.qty_planned, (0)::numeric) AS planned_cycles, CASE WHEN (COALESCE(o.planned_cycles, o.qty_planned, (0)::numeric) > (0)::numeric) THEN round((((COALESCE(m.cycle_pulse_count, (0)::bigint))::numeric / COALESCE(o.planned_cycles, o.qty_planned, (0)::numeric)) * (100)::numeric), 2) ELSE (0)::numeric END AS cycle_completion_pct, CASE WHEN ((m.age_s IS NULL) OR (m.age_s > 120)) THEN 'SIN_TELEMETRIA'::text WHEN ((o.odoo_state = 'ready'::text) AND (COALESCE(m.machine_running, false) = true)) THEN 'MAQUINA_EN_MARCHA_SIN_ORDEN_INICIADA'::text WHEN ((o.odoo_state = 'ready'::text) AND (COALESCE(m.machine_running, false) = false)) THEN 'ORDEN_PREPARADA_MAQUINA_PARADA'::text WHEN ((o.odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text])) AND (COALESCE(m.machine_running, false) = false)) THEN 'ORDEN_EN_CURSO_MAQUINA_PARADA'::text ELSE 'OK'::text END AS status_check FROM (((odoo o LEFT JOIN machine m ON (true)) LEFT JOIN LATERAL ( SELECT min(r.ingest_ts) AS first_machine_activity FROM mv_hot.edge_oee_eastron_readings r WHERE ((r.machine_id = o.machine_id) AND (((r.payload_json ->> 'machine_running'::text))::boolean = true) AND (r.ingest_ts >= COALESCE(o.odoo_reference_start, o.odoo_start, o.snapshot_at)) AND (r.ingest_ts <= COALESCE(o.odoo_end, now())))) ma ON (true)) LEFT JOIN stops s ON ((s.odoo_workorder_id = o.odoo_workorder_id))); ALTER VIEW mv_reports_ucepsa_demo.odoo_vs_machine_demo OWNER TO mesavault; -- -- Name: open_stops; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.open_stops AS SELECT id, tenant, site, vertical, asset, machine_id, order_id, started_at, current_duration_s, current_duration_min, current_cost_eur, status, classification_status, cause_code, cause_name, operator_note, value_hour_eur FROM mv_hot.edge_oee_open_stops WHERE (asset = 'revpi_oee_node_01'::text); ALTER VIEW mv_reports_ucepsa_demo.open_stops OWNER TO mesavault; -- -- Name: loss_events_current; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.loss_events_current AS WITH open_stop_losses AS ( SELECT now() AS detected_at, s.machine_id, COALESCE(s.asset, ''::text) AS asset, COALESCE(s.order_id, ''::text) AS order_ref, 'OPEN_STOP'::text AS loss_type, CASE WHEN (COALESCE(s.current_duration_min, (0)::numeric) >= (15)::numeric) THEN 'ACTION_REQUIRED'::text WHEN (COALESCE(s.current_duration_min, (0)::numeric) >= (5)::numeric) THEN 'ATTENTION'::text ELSE 'INFO'::text END AS severity, CASE WHEN (COALESCE(s.current_duration_min, (0)::numeric) >= (15)::numeric) THEN 80 WHEN (COALESCE(s.current_duration_min, (0)::numeric) >= (5)::numeric) THEN 55 ELSE 30 END AS severity_score, COALESCE(s.current_duration_min, (0)::numeric) AS duration_min, COALESCE(s.current_cost_eur, (0)::numeric) AS cost_eur, COALESCE(s.status, 'OPEN'::text) AS status, 'Paro abierto pendiente de cierre o clasificación.'::text AS description, 'Comprobar causa en máquina y clasificar el paro desde la consola.'::text AS recommended_action, jsonb_build_object('stop_id', s.id, 'classification_status', s.classification_status, 'cause_name', s.cause_name, 'started_at', s.started_at, 'source', 'mv_reports_ucepsa_demo.open_stops') AS evidence_json FROM mv_reports_ucepsa_demo.open_stops s ), unclassified_closed_stop_losses AS ( SELECT now() AS detected_at, s.machine_id, COALESCE(s.asset, ''::text) AS asset, COALESCE(s.order_id, ''::text) AS order_ref, 'UNCLASSIFIED_STOP'::text AS loss_type, CASE WHEN (COALESCE(s.duration_min, (0)::numeric) >= (15)::numeric) THEN 'ACTION_REQUIRED'::text ELSE 'ATTENTION'::text END AS severity, CASE WHEN (COALESCE(s.duration_min, (0)::numeric) >= (15)::numeric) THEN 75 ELSE 55 END AS severity_score, COALESCE(s.duration_min, (0)::numeric) AS duration_min, COALESCE(s.cost_eur, (0)::numeric) AS cost_eur, COALESCE(s.status, 'CLOSED'::text) AS status, 'Paro cerrado pendiente de clasificación.'::text AS description, 'Asignar causa para evitar pérdida sin explicación.'::text AS recommended_action, jsonb_build_object('stop_id', s.id, 'classification_status', s.classification_status, 'cause_name', s.cause_name, 'started_at', s.started_at, 'ended_at', s.ended_at, 'source', 'mv_reports_ucepsa_demo.stops_recent') AS evidence_json FROM mv_reports_ucepsa_demo.stops_recent s WHERE ((s.status = 'CLOSED'::text) AND (s.classification_status = 'PENDING'::text)) ), odoo_machine_losses AS ( SELECT now() AS detected_at, o.machine_id, COALESCE(o.asset, ''::text) AS asset, COALESCE(o.odoo_order_ref, ''::text) AS order_ref, o.status_check AS loss_type, CASE WHEN (o.status_check = ANY (ARRAY['ORDEN_EN_CURSO_MAQUINA_PARADA'::text, 'MAQUINA_EN_MARCHA_SIN_ORDEN_INICIADA'::text])) THEN 'ACTION_REQUIRED'::text WHEN (o.status_check = 'SIN_TELEMETRIA'::text) THEN 'ATTENTION'::text ELSE 'INFO'::text END AS severity, CASE WHEN (o.status_check = 'ORDEN_EN_CURSO_MAQUINA_PARADA'::text) THEN 85 WHEN (o.status_check = 'MAQUINA_EN_MARCHA_SIN_ORDEN_INICIADA'::text) THEN 75 WHEN (o.status_check = 'SIN_TELEMETRIA'::text) THEN 60 ELSE 20 END AS severity_score, COALESCE(o.stop_min, (0)::numeric) AS duration_min, COALESCE(o.stop_cost_eur, (0)::numeric) AS cost_eur, o.status_check AS status, CASE WHEN (o.status_check = 'ORDEN_EN_CURSO_MAQUINA_PARADA'::text) THEN 'Odoo indica orden en curso, pero la máquina está parada.'::text WHEN (o.status_check = 'MAQUINA_EN_MARCHA_SIN_ORDEN_INICIADA'::text) THEN 'La máquina está en marcha, pero la orden no aparece iniciada en Odoo.'::text WHEN (o.status_check = 'SIN_TELEMETRIA'::text) THEN 'No hay telemetría reciente para contrastar Odoo contra máquina.'::text ELSE 'Sin discrepancia relevante.'::text END AS description, CASE WHEN (o.status_check = 'ORDEN_EN_CURSO_MAQUINA_PARADA'::text) THEN 'Revisar paro real, operario, causa pendiente y estado de máquina.'::text WHEN (o.status_check = 'MAQUINA_EN_MARCHA_SIN_ORDEN_INICIADA'::text) THEN 'Revisar disciplina de inicio de orden en Odoo o desfase de sincronización.'::text WHEN (o.status_check = 'SIN_TELEMETRIA'::text) THEN 'Revisar RevPi, MQTT, VPN/red, contador y sink.'::text ELSE 'Sin acción.'::text END AS recommended_action, jsonb_build_object('odoo_order_ref', o.odoo_order_ref, 'odoo_state', o.odoo_state, 'machine_running', o.machine_running, 'telemetry_age_s', o.telemetry_age_s, 'real_cycles', o.real_cycles, 'planned_cycles', o.planned_cycles, 'cycle_completion_pct', o.cycle_completion_pct, 'source', 'mv_reports_ucepsa_demo.odoo_vs_machine_demo') AS evidence_json FROM mv_reports_ucepsa_demo.odoo_vs_machine_demo o WHERE (o.status_check IS DISTINCT FROM 'OK'::text) ), telemetry_losses AS ( SELECT now() AS detected_at, l.machine_id, COALESCE(l.asset, ''::text) AS asset, COALESCE(l.order_id, ''::text) AS order_ref, 'STALE_OR_BAD_TELEMETRY'::text AS loss_type, CASE WHEN (COALESCE(l.comm_ok, false) = false) THEN 'ACTION_REQUIRED'::text WHEN (COALESCE(l.age_s, 999999) > 120) THEN 'ACTION_REQUIRED'::text WHEN (COALESCE(l.age_s, 999999) > 30) THEN 'ATTENTION'::text ELSE 'INFO'::text END AS severity, CASE WHEN (COALESCE(l.comm_ok, false) = false) THEN 80 WHEN (COALESCE(l.age_s, 999999) > 120) THEN 75 WHEN (COALESCE(l.age_s, 999999) > 30) THEN 45 ELSE 10 END AS severity_score, (0)::numeric AS duration_min, (0)::numeric AS cost_eur, CASE WHEN (COALESCE(l.comm_ok, false) = false) THEN 'BAD_COMMUNICATION'::text WHEN (COALESCE(l.age_s, 999999) > 120) THEN 'STALE_TELEMETRY'::text WHEN (COALESCE(l.age_s, 999999) > 30) THEN 'DELAYED_TELEMETRY'::text ELSE 'OK'::text END AS status, CASE WHEN (COALESCE(l.comm_ok, false) = false) THEN 'La RevPi publica, pero la lectura Modbus no es válida.'::text WHEN (COALESCE(l.age_s, 999999) > 120) THEN 'No hay telemetría reciente de máquina.'::text WHEN (COALESCE(l.age_s, 999999) > 30) THEN 'La telemetría llega con retraso.'::text ELSE 'Telemetría correcta.'::text END AS description, CASE WHEN (COALESCE(l.comm_ok, false) = false) THEN 'Revisar RS-485, SDM120-M, alimentación del contador y logs de la RevPi.'::text WHEN (COALESCE(l.age_s, 999999) > 120) THEN 'Revisar RevPi, red/VPN, Mosquitto y sink MQTT.'::text WHEN (COALESCE(l.age_s, 999999) > 30) THEN 'Revisar estabilidad de red y frecuencia de publicación.'::text ELSE 'Sin acción.'::text END AS recommended_action, jsonb_build_object('age_s', l.age_s, 'comm_ok', l.comm_ok, 'error_text', l.error_text, 'ingest_ts', l.ingest_ts, 'source', 'mv_reports_ucepsa_demo.latest_machine_state_fast') AS evidence_json FROM mv_reports_ucepsa_demo.latest_machine_state_fast l WHERE ((COALESCE(l.comm_ok, false) = false) OR (COALESCE(l.age_s, 999999) > 30)) ), low_cycle_rate_losses AS ( SELECT now() AS detected_at, l.machine_id, COALESCE(l.asset, ''::text) AS asset, COALESCE(o.odoo_order_ref, ''::text) AS order_ref, 'LOW_CYCLE_RATE'::text AS loss_type, CASE WHEN (COALESCE(l.cycle_rate_ppm, (0)::numeric) <= (0)::numeric) THEN 'ATTENTION'::text WHEN (COALESCE(l.cycle_rate_ppm, (0)::numeric) < (7)::numeric) THEN 'ATTENTION'::text ELSE 'INFO'::text END AS severity, CASE WHEN (COALESCE(l.cycle_rate_ppm, (0)::numeric) <= (0)::numeric) THEN 50 WHEN (COALESCE(l.cycle_rate_ppm, (0)::numeric) < (7)::numeric) THEN 40 ELSE 10 END AS severity_score, (0)::numeric AS duration_min, (0)::numeric AS cost_eur, 'LOW_RATE'::text AS status, 'La máquina aparece en marcha, pero la velocidad de ciclos/golpes es baja respecto al objetivo inicial.'::text AS description, 'Revisar golpes reales, sensor I_2, velocidad programada, material, ajuste de máquina y criterio de bolsas por golpe.'::text AS recommended_action, jsonb_build_object('cycle_rate_ppm', l.cycle_rate_ppm, 'cycle_pulse_count', l.cycle_pulse_count, 'machine_running', l.machine_running, 'target_cycle_rate_ppm_assumed', 10, 'odoo_order_ref', o.odoo_order_ref, 'source', 'mv_reports_ucepsa_demo.latest_machine_state_fast') AS evidence_json FROM (mv_reports_ucepsa_demo.latest_machine_state_fast l LEFT JOIN mv_reports_ucepsa_demo.odoo_current_order_demo o ON ((o.machine_id = l.machine_id))) WHERE ((COALESCE(l.age_s, 999999) <= 120) AND (COALESCE(l.machine_running, false) = true) AND (COALESCE(l.cycle_rate_ppm, (0)::numeric) < (7)::numeric)) ) SELECT open_stop_losses.detected_at, open_stop_losses.machine_id, open_stop_losses.asset, open_stop_losses.order_ref, open_stop_losses.loss_type, open_stop_losses.severity, open_stop_losses.severity_score, open_stop_losses.duration_min, open_stop_losses.cost_eur, open_stop_losses.status, open_stop_losses.description, open_stop_losses.recommended_action, open_stop_losses.evidence_json FROM open_stop_losses UNION ALL SELECT unclassified_closed_stop_losses.detected_at, unclassified_closed_stop_losses.machine_id, unclassified_closed_stop_losses.asset, unclassified_closed_stop_losses.order_ref, unclassified_closed_stop_losses.loss_type, unclassified_closed_stop_losses.severity, unclassified_closed_stop_losses.severity_score, unclassified_closed_stop_losses.duration_min, unclassified_closed_stop_losses.cost_eur, unclassified_closed_stop_losses.status, unclassified_closed_stop_losses.description, unclassified_closed_stop_losses.recommended_action, unclassified_closed_stop_losses.evidence_json FROM unclassified_closed_stop_losses UNION ALL SELECT odoo_machine_losses.detected_at, odoo_machine_losses.machine_id, odoo_machine_losses.asset, odoo_machine_losses.order_ref, odoo_machine_losses.loss_type, odoo_machine_losses.severity, odoo_machine_losses.severity_score, odoo_machine_losses.duration_min, odoo_machine_losses.cost_eur, odoo_machine_losses.status, odoo_machine_losses.description, odoo_machine_losses.recommended_action, odoo_machine_losses.evidence_json FROM odoo_machine_losses UNION ALL SELECT telemetry_losses.detected_at, telemetry_losses.machine_id, telemetry_losses.asset, telemetry_losses.order_ref, telemetry_losses.loss_type, telemetry_losses.severity, telemetry_losses.severity_score, telemetry_losses.duration_min, telemetry_losses.cost_eur, telemetry_losses.status, telemetry_losses.description, telemetry_losses.recommended_action, telemetry_losses.evidence_json FROM telemetry_losses UNION ALL SELECT low_cycle_rate_losses.detected_at, low_cycle_rate_losses.machine_id, low_cycle_rate_losses.asset, low_cycle_rate_losses.order_ref, low_cycle_rate_losses.loss_type, low_cycle_rate_losses.severity, low_cycle_rate_losses.severity_score, low_cycle_rate_losses.duration_min, low_cycle_rate_losses.cost_eur, low_cycle_rate_losses.status, low_cycle_rate_losses.description, low_cycle_rate_losses.recommended_action, low_cycle_rate_losses.evidence_json FROM low_cycle_rate_losses; ALTER VIEW mv_reports_ucepsa_demo.loss_events_current OWNER TO mesavault; -- -- Name: loss_priority_board; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.loss_priority_board AS WITH active_orders AS ( SELECT DISTINCT odoo_current_order_demo.machine_id FROM mv_reports_ucepsa_demo.odoo_current_order_demo ), filtered AS ( SELECT e.detected_at, e.machine_id, e.asset, e.order_ref, e.loss_type, e.severity, e.severity_score, e.duration_min, e.cost_eur, e.status, e.description, e.recommended_action, e.evidence_json FROM mv_reports_ucepsa_demo.loss_events_current e WHERE ((NOT ((e.loss_type = ANY (ARRAY['STALE_OR_BAD_TELEMETRY'::text, 'LOW_CYCLE_RATE'::text])) AND (NOT (EXISTS ( SELECT 1 FROM active_orders a WHERE (a.machine_id = e.machine_id)))))) AND (NOT ((e.loss_type = 'STALE_OR_BAD_TELEMETRY'::text) AND (EXISTS ( SELECT 1 FROM mv_reports_ucepsa_demo.loss_events_current x WHERE ((x.machine_id = e.machine_id) AND (x.loss_type = 'SIN_TELEMETRIA'::text))))))) ) SELECT row_number() OVER (ORDER BY ((severity_score + (LEAST((COALESCE(cost_eur, (0)::numeric) * (10)::numeric), (50)::numeric))::integer) + (LEAST((COALESCE(duration_min, (0)::numeric) * (2)::numeric), (40)::numeric))::integer) DESC, detected_at DESC) AS priority_rank, ((severity_score + (LEAST((COALESCE(cost_eur, (0)::numeric) * (10)::numeric), (50)::numeric))::integer) + (LEAST((COALESCE(duration_min, (0)::numeric) * (2)::numeric), (40)::numeric))::integer) AS priority_score, CASE WHEN (((severity_score + (LEAST((COALESCE(cost_eur, (0)::numeric) * (10)::numeric), (50)::numeric))::integer) + (LEAST((COALESCE(duration_min, (0)::numeric) * (2)::numeric), (40)::numeric))::integer) >= 90) THEN 'CRÍTICA'::text WHEN (((severity_score + (LEAST((COALESCE(cost_eur, (0)::numeric) * (10)::numeric), (50)::numeric))::integer) + (LEAST((COALESCE(duration_min, (0)::numeric) * (2)::numeric), (40)::numeric))::integer) >= 60) THEN 'ALTA'::text WHEN (((severity_score + (LEAST((COALESCE(cost_eur, (0)::numeric) * (10)::numeric), (50)::numeric))::integer) + (LEAST((COALESCE(duration_min, (0)::numeric) * (2)::numeric), (40)::numeric))::integer) >= 35) THEN 'MEDIA'::text ELSE 'BAJA'::text END AS priority_level, detected_at, machine_id, asset, order_ref, loss_type, severity, duration_min, cost_eur, status, description, recommended_action, evidence_json FROM filtered ORDER BY ((severity_score + (LEAST((COALESCE(cost_eur, (0)::numeric) * (10)::numeric), (50)::numeric))::integer) + (LEAST((COALESCE(duration_min, (0)::numeric) * (2)::numeric), (40)::numeric))::integer) DESC, detected_at DESC; ALTER VIEW mv_reports_ucepsa_demo.loss_priority_board OWNER TO mesavault; -- -- Name: machine_state_latest; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.machine_state_latest AS SELECT received_at, age_s, event_ts, tenant, site, vertical, asset, machine_id, event_name, previous_auto_signal, new_auto_signal, machine_running, reason_pending, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s FROM mv_hot.edge_oee_machine_state_latest WHERE (asset = 'revpi_oee_node_01'::text); ALTER VIEW mv_reports_ucepsa_demo.machine_state_latest OWNER TO mesavault; -- -- Name: machine_state_latest_multi; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.machine_state_latest_multi AS SELECT ingest_ts, ts, tenant, site, asset, machine_id, age_s, comm_ok, sample_valid, energy_map, CASE WHEN (lower((payload_json ->> 'machine_running'::text)) = ANY (ARRAY['true'::text, 't'::text, '1'::text, 'yes'::text])) THEN true WHEN (lower((payload_json ->> 'machine_running'::text)) = ANY (ARRAY['false'::text, 'f'::text, '0'::text, 'no'::text])) THEN false ELSE false END AS machine_running, COALESCE(((NULLIF((payload_json ->> 'cycle_pulse_count'::text), ''::text))::numeric)::bigint, (0)::bigint) AS cycle_pulse_count, COALESCE((NULLIF((payload_json ->> 'cycle_rate_ppm'::text), ''::text))::double precision, (0.0)::double precision) AS cycle_rate_ppm, ((NULLIF((payload_json ->> 'wise_cycle_counter_raw'::text), ''::text))::numeric)::bigint AS wise_cycle_counter_raw, CASE WHEN (lower((payload_json ->> 'cycle_input_state'::text)) = ANY (ARRAY['true'::text, 't'::text, '1'::text, 'yes'::text])) THEN true WHEN (lower((payload_json ->> 'cycle_input_state'::text)) = ANY (ARRAY['false'::text, 'f'::text, '0'::text, 'no'::text])) THEN false ELSE NULL::boolean END AS cycle_input_state, (payload_json -> 'digital_inputs'::text) AS digital_inputs, voltage_l1_v, voltage_l2_v, voltage_l3_v, current_l1_a, current_l2_a, current_l3_a, active_power_l1_w, active_power_l2_w, active_power_l3_w, power_total_kw, frequency_hz, import_kwh, payload_json FROM mv_reports_ucepsa_demo.energy_3phase_latest l; ALTER VIEW mv_reports_ucepsa_demo.machine_state_latest_multi OWNER TO mesavault; -- -- Name: machine_stops_grafana; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.machine_stops_grafana AS WITH base AS ( SELECT s.id, s.tenant, s.site, s.vertical, s.asset, s.machine_id, s.order_id, s.started_at, s.ended_at, s.status, s.classification_status, s.cause_code, s.operator_note, s.value_hour_eur, s.duration_s, s.cost_eur, s.start_event_name, s.end_event_name, s.start_payload_json, s.end_payload_json, s.created_at, s.updated_at, to_jsonb(s.*) AS sj, COALESCE((to_jsonb(s.*) ->> 'cause_code'::text), (to_jsonb(s.*) ->> 'stop_cause_code'::text), (to_jsonb(s.*) ->> 'reason_code'::text)) AS raw_cause_code, COALESCE((to_jsonb(s.*) ->> 'cause_id'::text), (to_jsonb(s.*) ->> 'stop_cause_id'::text), (to_jsonb(s.*) ->> 'reason_id'::text)) AS raw_cause_id, COALESCE((to_jsonb(s.*) ->> 'cause_name'::text), (to_jsonb(s.*) ->> 'stop_cause_name'::text), (to_jsonb(s.*) ->> 'reason_name'::text)) AS raw_cause_name FROM mv_hot.edge_oee_machine_stops s ), base_with_cause AS ( SELECT b_1.id, b_1.tenant, b_1.site, b_1.vertical, b_1.asset, b_1.machine_id, b_1.order_id, b_1.started_at, b_1.ended_at, b_1.status, b_1.classification_status, b_1.cause_code, b_1.operator_note, b_1.value_hour_eur, b_1.duration_s, b_1.cost_eur, b_1.start_event_name, b_1.end_event_name, b_1.start_payload_json, b_1.end_payload_json, b_1.created_at, b_1.updated_at, b_1.sj, b_1.raw_cause_code, b_1.raw_cause_id, b_1.raw_cause_name, cause.cj AS cause_json FROM (base b_1 LEFT JOIN LATERAL ( SELECT to_jsonb(sc.*) AS cj FROM mv_hot.edge_oee_stop_causes sc WHERE (((b_1.raw_cause_id IS NOT NULL) AND ((to_jsonb(sc.*) ->> 'id'::text) = b_1.raw_cause_id)) OR ((b_1.raw_cause_code IS NOT NULL) AND (((to_jsonb(sc.*) ->> 'code'::text) = b_1.raw_cause_code) OR ((to_jsonb(sc.*) ->> 'cause_code'::text) = b_1.raw_cause_code) OR ((to_jsonb(sc.*) ->> 'name'::text) = b_1.raw_cause_code)))) LIMIT 1) cause ON (true)) ) SELECT id, machine_id, started_at, ended_at, COALESCE(ended_at, now()) AS effective_ended_at, status, classification_status, start_event_name, end_event_name, COALESCE(duration_s, EXTRACT(epoch FROM (COALESCE(ended_at, now()) - started_at))) AS duration_s_current, round((COALESCE(duration_s, EXTRACT(epoch FROM (COALESCE(ended_at, now()) - started_at))) / 60.0), 2) AS duration_min, COALESCE(cost_eur, (0)::numeric) AS cost_eur, COALESCE(NULLIF(raw_cause_code, ''::text), NULLIF((cause_json ->> 'code'::text), ''::text), NULLIF((cause_json ->> 'cause_code'::text), ''::text), CASE WHEN (classification_status = 'PENDING'::text) THEN 'PENDIENTE'::text ELSE 'SIN_CAUSA'::text END) AS cause_code, COALESCE(NULLIF(raw_cause_name, ''::text), NULLIF((cause_json ->> 'name'::text), ''::text), NULLIF((cause_json ->> 'description'::text), ''::text), NULLIF((cause_json ->> 'label'::text), ''::text), CASE COALESCE(NULLIF(raw_cause_code, ''::text), NULLIF((cause_json ->> 'code'::text), ''::text)) WHEN 'cambio_bobina'::text THEN 'Cambio de bobina'::text WHEN 'espera_instrucciones'::text THEN 'Espera de instrucciones'::text WHEN 'fallo_empalme'::text THEN 'Fallo de empalme'::text WHEN 'falta_material'::text THEN 'Falta de material'::text WHEN 'ajuste_sellado'::text THEN 'Ajuste de sellado'::text ELSE NULL::text END, CASE WHEN (classification_status = 'PENDING'::text) THEN 'Pendiente de clasificar'::text ELSE 'Sin causa registrada'::text END) AS cause_name, (sj ->> 'operator_note'::text) AS operator_note, (sj ->> 'classified_by'::text) AS classified_by, (sj ->> 'classified_at'::text) AS classified_at, (sj ->> 'order_ref'::text) AS order_ref, (sj ->> 'production_order'::text) AS production_order, CASE WHEN (status = 'OPEN'::text) THEN true ELSE false END AS is_open, CASE WHEN (classification_status = 'PENDING'::text) THEN true ELSE false END AS is_pending_classification, CASE WHEN (status = 'OPEN'::text) THEN 'ABIERTO'::text WHEN (classification_status = 'PENDING'::text) THEN 'CERRADO SIN CLASIFICAR'::text WHEN (classification_status = 'CLASSIFIED'::text) THEN 'CLASIFICADO'::text ELSE COALESCE(status, 'SIN_ESTADO'::text) END AS stop_status_label, CASE WHEN (status = 'OPEN'::text) THEN 3 WHEN (classification_status = 'PENDING'::text) THEN 2 WHEN (classification_status = 'CLASSIFIED'::text) THEN 1 ELSE 0 END AS stop_priority_score FROM base_with_cause b; ALTER VIEW mv_reports_ucepsa_demo.machine_stops_grafana OWNER TO mesavault; -- -- Name: machine_targets; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.machine_targets AS SELECT machine_id, machine_name, asset, target_cycle_rate_ppm, value_hour_eur, quality_pct_default, notes FROM mv_hot.edge_oee_machine_targets WHERE (machine_id = 'CORT-01'::text); ALTER VIEW mv_reports_ucepsa_demo.machine_targets OWNER TO mesavault; -- -- Name: node_events_recent; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.node_events_recent AS SELECT received_at, age_s, event_ts, tenant, site, vertical, asset, machine_id, order_id, event_type, event_name, previous_auto_signal, new_auto_signal, machine_running, reason_pending, cycle_pulse_count, cycle_rate_ppm, last_cycle_age_s, topic, payload_json FROM mv_hot.edge_oee_node_events_recent WHERE (asset = 'revpi_oee_node_01'::text); ALTER VIEW mv_reports_ucepsa_demo.node_events_recent OWNER TO mesavault; -- -- Name: odoo_discrepancies_demo; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.odoo_discrepancies_demo AS SELECT now() AS checked_at, odoo_order_ref, product, machine_id, status_check, CASE WHEN (status_check = 'MAQUINA_EN_MARCHA_SIN_ORDEN_INICIADA'::text) THEN 'La máquina está en marcha, pero la orden de Odoo está preparada o en espera, no iniciada.'::text WHEN (status_check = 'ORDEN_PREPARADA_MAQUINA_PARADA'::text) THEN 'La orden está preparada/en espera y la máquina está parada. No hay desviación productiva activa.'::text WHEN (status_check = 'ORDEN_EN_CURSO_MAQUINA_PARADA'::text) THEN 'La orden está en curso en Odoo, pero la máquina está parada.'::text WHEN (status_check = 'SIN_TELEMETRIA'::text) THEN 'No hay telemetría reciente de máquina.'::text ELSE 'Sin discrepancia relevante.'::text 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; ALTER VIEW mv_reports_ucepsa_demo.odoo_discrepancies_demo OWNER TO mesavault; -- -- Name: odoo_workorders_reality_history; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.odoo_workorders_reality_history AS WITH orders AS ( SELECT o_1.id, o_1.tenant, o_1.site, o_1.odoo_instance, o_1.odoo_workorder_id, o_1.odoo_production_id, o_1.odoo_order_ref, o_1.odoo_state, o_1.odoo_workcenter_code, o_1.odoo_workcenter_name, o_1.machine_id, o_1.asset, o_1.product, o_1.qty_planned, o_1.qty_done, o_1.uom, o_1.planned_cycles, o_1.target_cycle_rate_ppm, o_1.odoo_start, o_1.odoo_end, o_1.notes, o_1.snapshot_at, CASE WHEN ((o_1.odoo_state = ANY (ARRAY['progress'::text, 'in_progress'::text, 'started'::text, 'done'::text, 'to_close'::text])) AND (o_1.odoo_start IS NOT NULL)) THEN true ELSE false END AS odoo_is_started_calc, COALESCE(o_1.odoo_end, now()) AS analysis_end FROM mv_edge_oee_ucepsa_demo.odoo_workorders_demo o_1 WHERE ((o_1.machine_id = 'CORT-01'::text) AND (o_1.odoo_instance = 'odoo_demo'::text) AND (o_1.odoo_workorder_id IS NOT NULL)) ), first_activity AS ( SELECT o_1.id AS order_row_id, min(l.ingest_ts) AS first_machine_activity FROM (orders o_1 LEFT JOIN mv_reports_ucepsa_demo.live_telemetry l ON (((o_1.odoo_is_started_calc = true) AND (l.asset = o_1.asset) AND (l.ingest_ts >= o_1.odoo_start) AND (l.ingest_ts <= o_1.analysis_end) AND ((l.machine_running = true) OR (COALESCE(l.cycle_pulse_count, (0)::bigint) > 0))))) GROUP BY o_1.id ), cycle_calc AS ( SELECT o_1.id AS order_row_id, (COALESCE(GREATEST((max(l.cycle_pulse_count) - min(l.cycle_pulse_count)), (0)::bigint), (0)::bigint))::numeric AS real_cycles FROM (orders o_1 LEFT JOIN mv_reports_ucepsa_demo.live_telemetry l ON (((o_1.odoo_is_started_calc = true) AND (l.asset = o_1.asset) AND (l.ingest_ts >= o_1.odoo_start) AND (l.ingest_ts <= o_1.analysis_end) AND (l.cycle_pulse_count IS NOT NULL)))) GROUP BY o_1.id ), stop_calc AS ( SELECT o_1.id AS order_row_id, count(s.stop_id) AS stop_count, round((COALESCE(sum(s.overlap_s), (0)::numeric) / 60.0), 2) AS stop_min, round(COALESCE(sum(((s.overlap_s / 3600.0) * s.value_hour_eur)), (0)::numeric), 2) AS stop_cost_eur FROM (orders o_1 LEFT JOIN LATERAL ( SELECT ms.id AS stop_id, ms.value_hour_eur, GREATEST(EXTRACT(epoch FROM (LEAST(COALESCE(ms.ended_at, o_1.analysis_end), o_1.analysis_end) - GREATEST( CASE WHEN (ms.started_at > (ms.created_at + '00:00:05'::interval)) THEN ms.created_at ELSE ms.started_at END, o_1.odoo_start))), (0)::numeric) AS overlap_s FROM mv_hot.edge_oee_machine_stops ms WHERE ((o_1.odoo_is_started_calc = true) AND (ms.machine_id = o_1.machine_id) AND ( CASE WHEN (ms.started_at > (ms.created_at + '00:00:05'::interval)) THEN ms.created_at ELSE ms.started_at END < o_1.analysis_end) AND (COALESCE(ms.ended_at, now()) > o_1.odoo_start))) s ON (true)) GROUP BY o_1.id ) 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, o.odoo_start, o.odoo_end, o.snapshot_at, o.odoo_is_started_calc AS odoo_is_started, fa.first_machine_activity, CASE WHEN (o.odoo_is_started_calc = false) THEN NULL::numeric WHEN (fa.first_machine_activity IS NULL) THEN NULL::numeric ELSE round((EXTRACT(epoch FROM (fa.first_machine_activity - o.odoo_start)) / 60.0), 2) END AS start_delay_min, COALESCE(sc.stop_count, (0)::bigint) AS stop_count, COALESCE(sc.stop_min, (0)::numeric) AS stop_min, COALESCE(sc.stop_cost_eur, (0)::numeric) AS stop_cost_eur, CASE WHEN (o.odoo_is_started_calc = true) THEN COALESCE(cc.real_cycles, (0)::numeric) ELSE (0)::numeric END AS real_cycles, CASE WHEN ((o.odoo_is_started_calc = true) AND (o.planned_cycles > (0)::numeric)) THEN round(((COALESCE(cc.real_cycles, (0)::numeric) / o.planned_cycles) * (100)::numeric), 2) WHEN (o.odoo_is_started_calc = false) THEN (0)::numeric ELSE NULL::numeric END AS cycle_completion_pct, CASE WHEN (o.odoo_state = ANY (ARRAY['ready'::text, 'waiting'::text])) THEN 'ORDEN_NO_INICIADA'::text WHEN ((o.odoo_is_started_calc = true) AND (fa.first_machine_activity IS NULL)) THEN 'ORDEN_SIN_ACTIVIDAD_REAL'::text WHEN ((o.odoo_is_started_calc = true) AND (COALESCE(sc.stop_count, (0)::bigint) > 0)) THEN 'OK_CON_PAROS'::text WHEN (o.odoo_is_started_calc = true) THEN 'OK'::text ELSE 'SIN_EVALUAR'::text END AS status_check, CASE WHEN (o.odoo_state = ANY (ARRAY['ready'::text, 'waiting'::text])) THEN 'Orden preparada o en espera. Todavía no debe imputar ciclos, paros ni retrasos.'::text WHEN ((o.odoo_is_started_calc = true) AND (fa.first_machine_activity IS NULL)) THEN 'La orden está iniciada/cerrada en Odoo, pero no se detectó actividad real de máquina en su ventana.'::text WHEN ((o.odoo_is_started_calc = true) AND (COALESCE(sc.stop_count, (0)::bigint) > 0)) THEN 'La orden tuvo actividad real y paros imputados durante su ventana.'::text WHEN (o.odoo_is_started_calc = true) THEN 'La orden tuvo actividad real sin paros imputados.'::text ELSE 'Orden sin evaluación suficiente.'::text END AS descripcion FROM (((orders o LEFT JOIN first_activity fa ON ((fa.order_row_id = o.id))) LEFT JOIN cycle_calc cc ON ((cc.order_row_id = o.id))) LEFT JOIN stop_calc sc ON ((sc.order_row_id = o.id))) ORDER BY COALESCE(o.odoo_end, o.odoo_start, o.snapshot_at) DESC, o.odoo_workorder_id DESC; ALTER VIEW mv_reports_ucepsa_demo.odoo_workorders_reality_history OWNER TO mesavault; -- -- Name: odoo_last_finished_order_demo; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.odoo_last_finished_order_demo AS SELECT id, tenant, site, odoo_instance, odoo_workorder_id, odoo_production_id, odoo_order_ref, odoo_state, odoo_workcenter_code, odoo_workcenter_name, machine_id, asset, product, qty_planned, qty_done, uom, planned_cycles, target_cycle_rate_ppm, odoo_start, odoo_end, snapshot_at, odoo_is_started, first_machine_activity, start_delay_min, stop_count, stop_min, stop_cost_eur, real_cycles, cycle_completion_pct, status_check, descripcion FROM mv_reports_ucepsa_demo.odoo_workorders_reality_history WHERE (odoo_state = ANY (ARRAY['done'::text, 'to_close'::text])) ORDER BY COALESCE(odoo_end, snapshot_at) DESC LIMIT 1; ALTER VIEW mv_reports_ucepsa_demo.odoo_last_finished_order_demo OWNER TO mesavault; -- -- Name: odoo_order_state_machine_grafana; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.odoo_order_state_machine_grafana AS SELECT COALESCE(m.machine_id, o.machine_id) AS machine_id, o.received_at AS odoo_state_received_at, o.mqtt_ts AS odoo_state_ts, (EXTRACT(epoch FROM (now() - o.received_at)))::double precision AS order_age_s, o.workcenter_id, o.workcenter_name, o.workcenter_display_name, o.production_order AS order_ref, o.product AS product_name, o.odoo_state, o.order_present, o.order_coherent, o.reason, o.waiting_count, o.ready_count, o.progress_count, m.ingest_ts AS telemetry_ingest_ts, m.age_s AS telemetry_age_s, m.comm_ok, m.sample_valid, m.machine_running, m.cycle_rate_ppm, m.cycle_pulse_count, m.digital_inputs, CASE WHEN (o.machine_id IS NULL) THEN 'SIN_ESTADO_ODOO'::text WHEN (EXTRACT(epoch FROM (now() - o.received_at)) > (30)::numeric) THEN 'ODOO_STATE_ANTIGUO'::text WHEN (o.odoo_state = 'multiple_loaded_orders'::text) THEN 'MULTIPLES_ORDENES_EN_PROGRESS'::text WHEN ((o.order_present = true) AND (o.order_coherent = true) AND (COALESCE(m.machine_running, false) = true)) THEN 'ORDEN_CARGADA_MAQUINA_EN_MARCHA'::text WHEN ((o.order_present = true) AND (o.order_coherent = true) AND (COALESCE(m.machine_running, false) = false)) THEN 'ORDEN_CARGADA_MAQUINA_PARADA'::text WHEN ((COALESCE(o.order_present, false) = false) AND (COALESCE(m.machine_running, false) = true)) THEN 'MAQUINA_EN_MARCHA_SIN_ORDEN_ODOO'::text WHEN ((COALESCE(o.order_present, false) = false) AND (COALESCE(m.machine_running, false) = false)) THEN 'SIN_ORDEN_MAQUINA_PARADA'::text ELSE 'REVISAR'::text END AS edge_odoo_status, o.payload_json AS odoo_payload_json FROM (mv_reports_ucepsa_demo.machine_state_latest_multi m FULL JOIN mv_hot.odoo_order_state_current o ON (((o.tenant = 'ucepsa'::text) AND (o.site = 'ucepsa_onpremise'::text) AND (o.machine_id = m.machine_id)))) WHERE (COALESCE(m.site, o.site) = 'ucepsa_onpremise'::text); ALTER VIEW mv_reports_ucepsa_demo.odoo_order_state_machine_grafana OWNER TO mesavault; -- -- Name: stop_summary; Type: VIEW; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_demo.stop_summary AS SELECT cause_name, cause_code, stop_count, total_min, total_cost_eur FROM mv_hot.edge_oee_stop_summary_demo; ALTER VIEW mv_reports_ucepsa_demo.stop_summary OWNER TO mesavault; -- -- Name: current_order_margin_readiness_v1; Type: VIEW; Schema: mv_reports_ucepsa_prod; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_prod.current_order_margin_readiness_v1 AS WITH current_orders AS ( SELECT odoo_order_state_current.tenant, odoo_order_state_current.site, odoo_order_state_current.machine_id, odoo_order_state_current.workcenter_id, odoo_order_state_current.workcenter_name, odoo_order_state_current.order_present, odoo_order_state_current.order_coherent, odoo_order_state_current.odoo_state AS order_state_from_shopfloor, odoo_order_state_current.workorder_id AS odoo_workorder_id, odoo_order_state_current.production_order AS odoo_order_ref, odoo_order_state_current.product AS order_state_product, odoo_order_state_current.waiting_count, odoo_order_state_current.ready_count, odoo_order_state_current.progress_count, odoo_order_state_current.mqtt_ts, odoo_order_state_current.received_at, odoo_order_state_current.payload_json, (NULLIF((odoo_order_state_current.payload_json ->> 'production_id'::text), ''::text))::integer AS odoo_production_id, (NULLIF((odoo_order_state_current.payload_json ->> 'product_id'::text), ''::text))::integer AS order_state_product_id, (NULLIF((odoo_order_state_current.payload_json ->> 'qty_production'::text), ''::text))::numeric AS order_state_qty_production, (odoo_order_state_current.payload_json ->> 'date_start'::text) AS order_state_date_start, (odoo_order_state_current.payload_json ->> 'date_finished'::text) AS order_state_date_finished FROM mv_hot.odoo_order_state_current WHERE (odoo_order_state_current.site = 'ucepsa_onpremise'::text) ), commercial AS ( SELECT odoo_order_commercials.id, odoo_order_commercials.tenant, odoo_order_commercials.site, odoo_order_commercials.odoo_instance, odoo_order_commercials.odoo_production_id, odoo_order_commercials.odoo_order_ref, odoo_order_commercials.odoo_origin, odoo_order_commercials.odoo_state, odoo_order_commercials.product_id, odoo_order_commercials.product_default_code, odoo_order_commercials.product_name, odoo_order_commercials.product_uom, odoo_order_commercials.product_standard_price, odoo_order_commercials.product_list_price, odoo_order_commercials.production_qty, odoo_order_commercials.qty_producing, odoo_order_commercials.production_uom, odoo_order_commercials.sale_line_id, odoo_order_commercials.sale_order_id, odoo_order_commercials.sale_order_ref, odoo_order_commercials.customer_id, odoo_order_commercials.customer_name, odoo_order_commercials.sale_state, odoo_order_commercials.sale_date_order, odoo_order_commercials.currency, odoo_order_commercials.sale_line_qty, odoo_order_commercials.sale_line_qty_delivered, odoo_order_commercials.sale_price_unit, odoo_order_commercials.sale_discount_pct, odoo_order_commercials.revenue_net_eur, odoo_order_commercials.revenue_total_eur, odoo_order_commercials.raw_material_value_eur, odoo_order_commercials.finished_value_eur, odoo_order_commercials.material_cost_status, odoo_order_commercials.stock_raw_moves_json, odoo_order_commercials.stock_finished_moves_json, odoo_order_commercials.raw_json, odoo_order_commercials.snapshot_at FROM mv_edge_oee_ucepsa_prod.odoo_order_commercials WHERE ((odoo_order_commercials.site = 'ucepsa_onpremise'::text) AND (odoo_order_commercials.odoo_instance = 'odoo_ucepsa_prod'::text)) ), joined AS ( SELECT co.tenant, co.site, co.machine_id, co.workcenter_id, co.workcenter_name, co.order_present, co.order_coherent, co.order_state_from_shopfloor, co.odoo_workorder_id, co.odoo_production_id, co.odoo_order_ref, co.order_state_product, co.order_state_product_id, co.order_state_qty_production, co.waiting_count, co.ready_count, co.progress_count, co.mqtt_ts, co.received_at, c.odoo_instance, c.odoo_state AS production_state, c.odoo_origin, c.product_id, c.product_default_code, COALESCE(c.product_name, co.order_state_product) AS product_name, c.product_uom, c.production_qty, c.qty_producing, c.production_uom, c.sale_line_id, c.sale_order_id, c.sale_order_ref, c.customer_id, c.customer_name, c.sale_state, c.sale_date_order, c.currency, c.sale_line_qty, c.sale_line_qty_delivered, c.sale_price_unit, c.sale_discount_pct, c.revenue_net_eur, c.revenue_total_eur, c.raw_material_value_eur, c.finished_value_eur, c.material_cost_status, jsonb_array_length(COALESCE(c.stock_raw_moves_json, '[]'::jsonb)) AS raw_material_line_count, jsonb_array_length(COALESCE(c.stock_finished_moves_json, '[]'::jsonb)) AS finished_move_line_count, c.stock_raw_moves_json, c.stock_finished_moves_json, c.snapshot_at AS commercial_snapshot_at FROM (current_orders co LEFT JOIN commercial c ON ((c.odoo_production_id = co.odoo_production_id))) ) SELECT tenant, site, machine_id, workcenter_id, workcenter_name, order_present, order_coherent, order_state_from_shopfloor, odoo_workorder_id, odoo_production_id, odoo_order_ref, order_state_product, order_state_product_id, order_state_qty_production, waiting_count, ready_count, progress_count, mqtt_ts, received_at, odoo_instance, production_state, odoo_origin, product_id, product_default_code, product_name, product_uom, production_qty, qty_producing, production_uom, sale_line_id, sale_order_id, sale_order_ref, customer_id, customer_name, sale_state, sale_date_order, currency, sale_line_qty, sale_line_qty_delivered, sale_price_unit, sale_discount_pct, revenue_net_eur, revenue_total_eur, raw_material_value_eur, finished_value_eur, material_cost_status, raw_material_line_count, finished_move_line_count, stock_raw_moves_json, stock_finished_moves_json, commercial_snapshot_at, CASE WHEN (order_present IS FALSE) THEN 'NO_ORDER_LOADED'::text WHEN (order_coherent IS FALSE) THEN 'ODOO_ORDER_INCOHERENT'::text WHEN (odoo_production_id IS NULL) THEN 'MISSING_PRODUCTION_ID_FROM_ORDER_STATE'::text WHEN (odoo_instance IS NULL) THEN 'MISSING_COMMERCIAL_SNAPSHOT'::text WHEN ((sale_order_ref IS NULL) OR (revenue_net_eur IS NULL)) THEN 'MISSING_REVENUE_LINK'::text WHEN (customer_name IS NULL) THEN 'MISSING_CUSTOMER'::text WHEN (raw_material_line_count = 0) THEN 'MISSING_RAW_MATERIALS'::text WHEN (material_cost_status = 'UNAVAILABLE_OR_ZERO'::text) THEN 'MISSING_MATERIAL_COST'::text ELSE 'READY_FOR_MARGIN_BASE'::text END AS margin_readiness_status, CASE WHEN (order_present IS FALSE) THEN 'No hay orden cargada en Odoo Shop Floor para esta máquina.'::text WHEN (order_coherent IS FALSE) THEN 'Hay estado Odoo incoherente para esta máquina.'::text WHEN (odoo_production_id IS NULL) THEN 'El order_state no trae production_id; revisar publicador Odoo.'::text WHEN (odoo_instance IS NULL) THEN 'La orden existe en order_state, pero aún no tiene snapshot comercial en Edge-OEE.'::text WHEN ((sale_order_ref IS NULL) OR (revenue_net_eur IS NULL)) THEN 'Falta vínculo económico con pedido/línea de venta.'::text WHEN (customer_name IS NULL) THEN 'Falta cliente asociado al pedido de venta.'::text WHEN (raw_material_line_count = 0) THEN 'No se detectan movimientos de materia prima para la orden.'::text WHEN (material_cost_status = 'UNAVAILABLE_OR_ZERO'::text) THEN 'Hay materia prima, pero Odoo no aporta valoración económica útil. Cargar coste €/kg o corregir valoración.'::text ELSE 'Datos comerciales mínimos disponibles para calcular margen base.'::text END AS margin_readiness_description, (((((( CASE WHEN (order_present IS TRUE) THEN 20 ELSE 0 END + CASE WHEN (order_coherent IS TRUE) THEN 15 ELSE 0 END) + CASE WHEN (odoo_instance IS NOT NULL) THEN 15 ELSE 0 END) + CASE WHEN ((sale_order_ref IS NOT NULL) AND (revenue_net_eur IS NOT NULL)) THEN 20 ELSE 0 END) + CASE WHEN (customer_name IS NOT NULL) THEN 10 ELSE 0 END) + CASE WHEN (raw_material_line_count > 0) THEN 10 ELSE 0 END) + CASE WHEN (material_cost_status <> 'UNAVAILABLE_OR_ZERO'::text) THEN 10 ELSE 0 END) AS margin_readiness_score FROM joined; ALTER VIEW mv_reports_ucepsa_prod.current_order_margin_readiness_v1 OWNER TO mesavault; -- -- Name: order_raw_material_costs_v1; Type: VIEW; Schema: mv_reports_ucepsa_prod; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_prod.order_raw_material_costs_v1 AS WITH raw_moves AS ( SELECT c.id AS commercial_row_id, c.tenant, c.site, c.odoo_instance, c.odoo_production_id, c.odoo_order_ref, c.sale_order_ref, c.customer_name, c.product_default_code AS finished_product_default_code, c.product_name AS finished_product_name, (NULLIF((rm.raw_move ->> 'id'::text), ''::text))::integer AS raw_move_id, (NULLIF(((rm.raw_move -> 'product_id'::text) ->> 0), ''::text))::integer AS raw_product_id, ((rm.raw_move -> 'product_id'::text) ->> 1) AS raw_product_name, "substring"(((rm.raw_move -> 'product_id'::text) ->> 1), '\[([^\]]+)\]'::text) AS raw_product_default_code, (NULLIF((rm.raw_move ->> 'product_uom_qty'::text), ''::text))::numeric AS planned_qty, (NULLIF((rm.raw_move ->> 'quantity'::text), ''::text))::numeric AS consumed_qty, ((rm.raw_move -> 'product_uom'::text) ->> 1) AS raw_uom, (NULLIF((rm.raw_move ->> 'price_unit'::text), ''::text))::numeric AS odoo_price_unit, (NULLIF((rm.raw_move ->> 'value'::text), ''::text))::numeric AS odoo_value, (rm.raw_move ->> 'state'::text) AS move_state, rm.raw_move AS raw_move_json FROM (mv_edge_oee_ucepsa_prod.odoo_order_commercials c CROSS JOIN LATERAL jsonb_array_elements(c.stock_raw_moves_json) rm(raw_move)) ), costed AS ( SELECT r.commercial_row_id, r.tenant, r.site, r.odoo_instance, r.odoo_production_id, r.odoo_order_ref, r.sale_order_ref, r.customer_name, r.finished_product_default_code, r.finished_product_name, r.raw_move_id, r.raw_product_id, r.raw_product_name, r.raw_product_default_code, r.planned_qty, r.consumed_qty, r.raw_uom, r.odoo_price_unit, r.odoo_value, r.move_state, r.raw_move_json, p.id AS raw_material_cost_parameter_id, p.material_cost_eur_per_kg, p.source AS raw_material_cost_source, p.notes AS raw_material_cost_notes, CASE WHEN (COALESCE(r.odoo_value, (0)::numeric) <> (0)::numeric) THEN abs(r.odoo_value) WHEN ((lower(COALESCE(r.raw_uom, ''::text)) = 'kg'::text) AND (p.material_cost_eur_per_kg IS NOT NULL) AND (r.consumed_qty IS NOT NULL)) THEN (r.consumed_qty * p.material_cost_eur_per_kg) ELSE NULL::numeric END AS material_cost_estimated_eur, CASE WHEN (COALESCE(r.odoo_value, (0)::numeric) <> (0)::numeric) THEN 'FROM_ODOO_STOCK_MOVE_VALUE'::text WHEN (r.raw_product_id IS NULL) THEN 'MISSING_RAW_PRODUCT_ID'::text WHEN (lower(COALESCE(r.raw_uom, ''::text)) <> 'kg'::text) THEN 'UNSUPPORTED_RAW_UOM'::text WHEN (p.material_cost_eur_per_kg IS NULL) THEN 'MISSING_RAW_MATERIAL_COST_PARAMETER'::text WHEN (r.consumed_qty IS NULL) THEN 'MISSING_CONSUMED_QTY'::text ELSE 'FROM_RAW_MATERIAL_COST_PARAMETER'::text END AS material_cost_status FROM (raw_moves r LEFT JOIN LATERAL ( SELECT p1.id, p1.tenant, p1.site, p1.raw_product_default_code, p1.raw_product_name, p1.material_cost_eur_per_kg, p1.source, p1.valid_from, p1.valid_to, p1.is_active, p1.notes, p1.created_at, p1.raw_product_id, p1.raw_uom FROM mv_edge_oee_ucepsa_prod.raw_material_cost_parameters p1 WHERE ((p1.tenant = r.tenant) AND (p1.site = r.site) AND (p1.is_active = true) AND (p1.valid_from <= now()) AND ((p1.valid_to IS NULL) OR (p1.valid_to > now())) AND (((p1.raw_product_id IS NOT NULL) AND (p1.raw_product_id = r.raw_product_id)) OR ((p1.raw_product_id IS NULL) AND (p1.raw_product_default_code IS NOT NULL) AND (p1.raw_product_default_code = r.raw_product_default_code)) OR ((p1.raw_product_id IS NULL) AND (p1.raw_product_default_code IS NULL) AND (p1.raw_product_name IS NOT NULL) AND (p1.raw_product_name = r.raw_product_name)))) ORDER BY CASE WHEN ((p1.raw_product_id IS NOT NULL) AND (p1.raw_product_id = r.raw_product_id)) THEN 1 WHEN ((p1.raw_product_default_code IS NOT NULL) AND (p1.raw_product_default_code = r.raw_product_default_code)) THEN 2 WHEN ((p1.raw_product_name IS NOT NULL) AND (p1.raw_product_name = r.raw_product_name)) THEN 3 ELSE 9 END, p1.valid_from DESC, p1.id DESC LIMIT 1) p ON (true)) ) SELECT commercial_row_id, tenant, site, odoo_instance, odoo_production_id, odoo_order_ref, sale_order_ref, customer_name, finished_product_default_code, finished_product_name, raw_move_id, raw_product_id, raw_product_name, raw_product_default_code, planned_qty, consumed_qty, raw_uom, odoo_price_unit, odoo_value, move_state, raw_material_cost_parameter_id, material_cost_eur_per_kg, raw_material_cost_source, raw_material_cost_notes, material_cost_estimated_eur, round(material_cost_estimated_eur, 4) AS material_cost_estimated_eur_rounded, material_cost_status, raw_move_json FROM costed; ALTER VIEW mv_reports_ucepsa_prod.order_raw_material_costs_v1 OWNER TO mesavault; -- -- Name: order_raw_material_costs_summary_v1; Type: VIEW; Schema: mv_reports_ucepsa_prod; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_prod.order_raw_material_costs_summary_v1 AS SELECT tenant, site, odoo_instance, odoo_production_id, odoo_order_ref, sale_order_ref, customer_name, finished_product_default_code, finished_product_name, count(*) AS raw_material_line_count, round(sum(COALESCE(consumed_qty, (0)::numeric)), 3) AS total_consumed_qty, string_agg(concat(COALESCE(raw_product_default_code, (raw_product_id)::text, 'sin_codigo'::text), ' - ', COALESCE(raw_product_name, 'sin_nombre'::text), ': ', COALESCE((consumed_qty)::text, 'sin_cantidad'::text), ' ', COALESCE(raw_uom, ''::text)), '; '::text ORDER BY raw_product_name) AS raw_materials_summary, round(sum(COALESCE(material_cost_estimated_eur, (0)::numeric)), 4) AS material_cost_estimated_eur, count(*) FILTER (WHERE (material_cost_estimated_eur IS NOT NULL)) AS costed_raw_material_line_count, count(*) FILTER (WHERE ((material_cost_status <> 'FROM_RAW_MATERIAL_COST_PARAMETER'::text) AND (material_cost_status <> 'FROM_ODOO_STOCK_MOVE_VALUE'::text))) AS missing_or_invalid_raw_material_cost_count, string_agg(DISTINCT material_cost_status, ', '::text ORDER BY material_cost_status) AS material_cost_status_summary FROM mv_reports_ucepsa_prod.order_raw_material_costs_v1 GROUP BY tenant, site, odoo_instance, odoo_production_id, odoo_order_ref, sale_order_ref, customer_name, finished_product_default_code, finished_product_name; ALTER VIEW mv_reports_ucepsa_prod.order_raw_material_costs_summary_v1 OWNER TO mesavault; -- -- Name: raw_material_cost_requirements_v1; Type: VIEW; Schema: mv_reports_ucepsa_prod; Owner: mesavault -- CREATE VIEW mv_reports_ucepsa_prod.raw_material_cost_requirements_v1 AS SELECT tenant, site, raw_product_id, raw_product_default_code, raw_product_name, raw_uom, count(*) AS affected_order_lines, count(DISTINCT odoo_order_ref) AS affected_orders, string_agg(DISTINCT odoo_order_ref, ', '::text ORDER BY odoo_order_ref) AS affected_order_refs, round(sum(COALESCE(consumed_qty, (0)::numeric)), 3) AS total_consumed_qty, string_agg(DISTINCT customer_name, ', '::text ORDER BY customer_name) AS affected_customers, max(material_cost_status) AS current_status, 'Cargar coste €/kg en mv_edge_oee_ucepsa_prod.raw_material_cost_parameters'::text AS recommended_action FROM mv_reports_ucepsa_prod.order_raw_material_costs_v1 WHERE (material_cost_status = ANY (ARRAY['MISSING_RAW_MATERIAL_COST_PARAMETER'::text, 'MISSING_RAW_PRODUCT_ID'::text, 'MISSING_CONSUMED_QTY'::text, 'UNSUPPORTED_RAW_UOM'::text])) GROUP BY tenant, site, raw_product_id, raw_product_default_code, raw_product_name, raw_uom; ALTER VIEW mv_reports_ucepsa_prod.raw_material_cost_requirements_v1 OWNER TO mesavault; -- -- Name: data_quality_contract_rules id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.data_quality_contract_rules ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_demo.data_quality_contract_rules_id_seq'::regclass); -- -- Name: margin_cost_parameters id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.margin_cost_parameters ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_demo.margin_cost_parameters_id_seq'::regclass); -- -- Name: odoo_order_commercials id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.odoo_order_commercials ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_demo.odoo_order_commercials_id_seq'::regclass); -- -- Name: odoo_workcenter_map id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.odoo_workcenter_map ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_demo.odoo_workcenter_map_id_seq'::regclass); -- -- Name: odoo_workorders_demo id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.odoo_workorders_demo ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_demo.odoo_workorders_demo_id_seq'::regclass); -- -- Name: raw_material_cost_parameters id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.raw_material_cost_parameters ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_demo.raw_material_cost_parameters_id_seq'::regclass); -- -- Name: data_quality_contract_rules id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.data_quality_contract_rules ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_prod.data_quality_contract_rules_id_seq'::regclass); -- -- Name: margin_cost_parameters id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.margin_cost_parameters ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_prod.margin_cost_parameters_id_seq'::regclass); -- -- Name: odoo_order_commercials id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.odoo_order_commercials ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_prod.odoo_order_commercials_id_seq'::regclass); -- -- Name: raw_material_cost_parameters id; Type: DEFAULT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.raw_material_cost_parameters ALTER COLUMN id SET DEFAULT nextval('mv_edge_oee_ucepsa_prod.raw_material_cost_parameters_id_seq'::regclass); -- -- Name: edge_oee_eastron_readings id; Type: DEFAULT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_eastron_readings ALTER COLUMN id SET DEFAULT nextval('mv_hot.edge_oee_eastron_readings_id_seq'::regclass); -- -- Name: edge_oee_events_demo event_id; Type: DEFAULT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_events_demo ALTER COLUMN event_id SET DEFAULT nextval('mv_hot.edge_oee_events_demo_event_id_seq'::regclass); -- -- Name: edge_oee_machine_stops id; Type: DEFAULT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_machine_stops ALTER COLUMN id SET DEFAULT nextval('mv_hot.edge_oee_machine_stops_id_seq'::regclass); -- -- Name: edge_oee_node_events id; Type: DEFAULT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_node_events ALTER COLUMN id SET DEFAULT nextval('mv_hot.edge_oee_node_events_id_seq'::regclass); -- -- Name: odoo_order_state_events id; Type: DEFAULT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.odoo_order_state_events ALTER COLUMN id SET DEFAULT nextval('mv_hot.odoo_order_state_events_id_seq'::regclass); -- -- Name: data_quality_contract_rules data_quality_contract_rules_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.data_quality_contract_rules ADD CONSTRAINT data_quality_contract_rules_pkey PRIMARY KEY (id); -- -- Name: margin_cost_parameters margin_cost_parameters_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.margin_cost_parameters ADD CONSTRAINT margin_cost_parameters_pkey PRIMARY KEY (id); -- -- Name: odoo_order_commercials odoo_order_commercials_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.odoo_order_commercials ADD CONSTRAINT odoo_order_commercials_pkey PRIMARY KEY (id); -- -- Name: odoo_workcenter_map odoo_workcenter_map_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.odoo_workcenter_map ADD CONSTRAINT odoo_workcenter_map_pkey PRIMARY KEY (id); -- -- Name: odoo_workcenter_map odoo_workcenter_map_tenant_site_machine_id_key; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.odoo_workcenter_map ADD CONSTRAINT odoo_workcenter_map_tenant_site_machine_id_key UNIQUE (tenant, site, machine_id); -- -- Name: odoo_workcenter_map odoo_workcenter_map_tenant_site_odoo_instance_odoo_workcent_key; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.odoo_workcenter_map ADD CONSTRAINT odoo_workcenter_map_tenant_site_odoo_instance_odoo_workcent_key UNIQUE (tenant, site, odoo_instance, odoo_workcenter_code); -- -- Name: odoo_workorders_demo odoo_workorders_demo_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.odoo_workorders_demo ADD CONSTRAINT odoo_workorders_demo_pkey PRIMARY KEY (id); -- -- Name: raw_material_cost_parameters raw_material_cost_parameters_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.raw_material_cost_parameters ADD CONSTRAINT raw_material_cost_parameters_pkey PRIMARY KEY (id); -- -- Name: data_quality_contract_rules ux_data_quality_contract_rules_code; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.data_quality_contract_rules ADD CONSTRAINT ux_data_quality_contract_rules_code UNIQUE (tenant, site, rule_code); -- -- Name: odoo_order_commercials ux_odoo_order_commercials_instance_production; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_demo.odoo_order_commercials ADD CONSTRAINT ux_odoo_order_commercials_instance_production UNIQUE (odoo_instance, odoo_production_id); -- -- Name: data_quality_contract_rules data_quality_contract_rules_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.data_quality_contract_rules ADD CONSTRAINT data_quality_contract_rules_pkey PRIMARY KEY (id); -- -- Name: data_quality_contract_rules data_quality_contract_rules_tenant_site_rule_code_key; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.data_quality_contract_rules ADD CONSTRAINT data_quality_contract_rules_tenant_site_rule_code_key UNIQUE (tenant, site, rule_code); -- -- Name: margin_cost_parameters margin_cost_parameters_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.margin_cost_parameters ADD CONSTRAINT margin_cost_parameters_pkey PRIMARY KEY (id); -- -- Name: odoo_order_commercials odoo_order_commercials_odoo_instance_odoo_production_id_key; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.odoo_order_commercials ADD CONSTRAINT odoo_order_commercials_odoo_instance_odoo_production_id_key UNIQUE (odoo_instance, odoo_production_id); -- -- Name: odoo_order_commercials odoo_order_commercials_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.odoo_order_commercials ADD CONSTRAINT odoo_order_commercials_pkey PRIMARY KEY (id); -- -- Name: raw_material_cost_parameters raw_material_cost_parameters_pkey; Type: CONSTRAINT; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- ALTER TABLE ONLY mv_edge_oee_ucepsa_prod.raw_material_cost_parameters ADD CONSTRAINT raw_material_cost_parameters_pkey PRIMARY KEY (id); -- -- Name: edge_oee_data_quality_demo edge_oee_data_quality_demo_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_data_quality_demo ADD CONSTRAINT edge_oee_data_quality_demo_pkey PRIMARY KEY (metric_id); -- -- Name: edge_oee_eastron_readings edge_oee_eastron_readings_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_eastron_readings ADD CONSTRAINT edge_oee_eastron_readings_pkey PRIMARY KEY (id); -- -- Name: edge_oee_events_demo edge_oee_events_demo_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_events_demo ADD CONSTRAINT edge_oee_events_demo_pkey PRIMARY KEY (event_id); -- -- Name: edge_oee_loss_summary_demo edge_oee_loss_summary_demo_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_loss_summary_demo ADD CONSTRAINT edge_oee_loss_summary_demo_pkey PRIMARY KEY (cause); -- -- Name: edge_oee_machine_stops edge_oee_machine_stops_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_machine_stops ADD CONSTRAINT edge_oee_machine_stops_pkey PRIMARY KEY (id); -- -- Name: edge_oee_machine_targets edge_oee_machine_targets_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_machine_targets ADD CONSTRAINT edge_oee_machine_targets_pkey PRIMARY KEY (machine_id); -- -- Name: edge_oee_machines edge_oee_machines_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_machines ADD CONSTRAINT edge_oee_machines_pkey PRIMARY KEY (machine_id); -- -- Name: edge_oee_node_events edge_oee_node_events_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_node_events ADD CONSTRAINT edge_oee_node_events_pkey PRIMARY KEY (id); -- -- Name: edge_oee_orders_demo edge_oee_orders_demo_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_orders_demo ADD CONSTRAINT edge_oee_orders_demo_pkey PRIMARY KEY (order_id); -- -- Name: edge_oee_quality_cases_demo edge_oee_quality_cases_demo_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_quality_cases_demo ADD CONSTRAINT edge_oee_quality_cases_demo_pkey PRIMARY KEY (case_id); -- -- Name: edge_oee_stop_causes edge_oee_stop_causes_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_stop_causes ADD CONSTRAINT edge_oee_stop_causes_pkey PRIMARY KEY (cause_code); -- -- Name: odoo_order_state_current odoo_order_state_current_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.odoo_order_state_current ADD CONSTRAINT odoo_order_state_current_pkey PRIMARY KEY (tenant, site, machine_id); -- -- Name: odoo_order_state_events odoo_order_state_events_pkey; Type: CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.odoo_order_state_events ADD CONSTRAINT odoo_order_state_events_pkey PRIMARY KEY (id); -- -- Name: idx_data_quality_contract_rules_active; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE INDEX idx_data_quality_contract_rules_active ON mv_edge_oee_ucepsa_demo.data_quality_contract_rules USING btree (tenant, site, is_active, domain, severity); -- -- Name: idx_margin_cost_parameters_scope; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE INDEX idx_margin_cost_parameters_scope ON mv_edge_oee_ucepsa_demo.margin_cost_parameters USING btree (tenant, site, is_active, machine_id, product_default_code); -- -- Name: idx_odoo_order_commercials_customer; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE INDEX idx_odoo_order_commercials_customer ON mv_edge_oee_ucepsa_demo.odoo_order_commercials USING btree (customer_name); -- -- Name: idx_odoo_order_commercials_order_ref; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE INDEX idx_odoo_order_commercials_order_ref ON mv_edge_oee_ucepsa_demo.odoo_order_commercials USING btree (odoo_order_ref); -- -- Name: idx_odoo_order_commercials_sale_order_ref; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE INDEX idx_odoo_order_commercials_sale_order_ref ON mv_edge_oee_ucepsa_demo.odoo_order_commercials USING btree (sale_order_ref); -- -- Name: idx_odoo_workorders_demo_machine_time; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE INDEX idx_odoo_workorders_demo_machine_time ON mv_edge_oee_ucepsa_demo.odoo_workorders_demo USING btree (machine_id, odoo_start DESC); -- -- Name: idx_odoo_workorders_demo_state; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE INDEX idx_odoo_workorders_demo_state ON mv_edge_oee_ucepsa_demo.odoo_workorders_demo USING btree (odoo_state); -- -- Name: idx_raw_material_cost_parameters_lookup; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE INDEX idx_raw_material_cost_parameters_lookup ON mv_edge_oee_ucepsa_demo.raw_material_cost_parameters USING btree (tenant, site, raw_product_default_code, is_active, valid_from DESC); -- -- Name: ux_odoo_workcenter_map_instance_workcenter; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE UNIQUE INDEX ux_odoo_workcenter_map_instance_workcenter ON mv_edge_oee_ucepsa_demo.odoo_workcenter_map USING btree (odoo_instance, odoo_workcenter_id); -- -- Name: ux_odoo_workcenter_map_tenant_site_instance_workcenter; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE UNIQUE INDEX ux_odoo_workcenter_map_tenant_site_instance_workcenter ON mv_edge_oee_ucepsa_demo.odoo_workcenter_map USING btree (tenant, site, odoo_instance, odoo_workcenter_id); -- -- Name: ux_odoo_workorders_demo_instance_workorder; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE UNIQUE INDEX ux_odoo_workorders_demo_instance_workorder ON mv_edge_oee_ucepsa_demo.odoo_workorders_demo USING btree (odoo_instance, odoo_workorder_id); -- -- Name: ux_odoo_workorders_demo_tenant_site_instance_workorder; Type: INDEX; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- CREATE UNIQUE INDEX ux_odoo_workorders_demo_tenant_site_instance_workorder ON mv_edge_oee_ucepsa_demo.odoo_workorders_demo USING btree (tenant, site, odoo_instance, odoo_workorder_id); -- -- Name: data_quality_contract_rules_tenant_site_is_active_domain_se_idx; Type: INDEX; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE INDEX data_quality_contract_rules_tenant_site_is_active_domain_se_idx ON mv_edge_oee_ucepsa_prod.data_quality_contract_rules USING btree (tenant, site, is_active, domain, severity); -- -- Name: idx_raw_material_cost_params_prod_code; Type: INDEX; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE INDEX idx_raw_material_cost_params_prod_code ON mv_edge_oee_ucepsa_prod.raw_material_cost_parameters USING btree (raw_product_default_code); -- -- Name: idx_raw_material_cost_params_prod_name; Type: INDEX; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE INDEX idx_raw_material_cost_params_prod_name ON mv_edge_oee_ucepsa_prod.raw_material_cost_parameters USING btree (raw_product_name); -- -- Name: idx_raw_material_cost_params_prod_product_id; Type: INDEX; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE INDEX idx_raw_material_cost_params_prod_product_id ON mv_edge_oee_ucepsa_prod.raw_material_cost_parameters USING btree (raw_product_id); -- -- Name: margin_cost_parameters_tenant_site_is_active_machine_id_pro_idx; Type: INDEX; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE INDEX margin_cost_parameters_tenant_site_is_active_machine_id_pro_idx ON mv_edge_oee_ucepsa_prod.margin_cost_parameters USING btree (tenant, site, is_active, machine_id, product_default_code); -- -- Name: odoo_order_commercials_customer_name_idx; Type: INDEX; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE INDEX odoo_order_commercials_customer_name_idx ON mv_edge_oee_ucepsa_prod.odoo_order_commercials USING btree (customer_name); -- -- Name: odoo_order_commercials_odoo_order_ref_idx; Type: INDEX; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE INDEX odoo_order_commercials_odoo_order_ref_idx ON mv_edge_oee_ucepsa_prod.odoo_order_commercials USING btree (odoo_order_ref); -- -- Name: odoo_order_commercials_sale_order_ref_idx; Type: INDEX; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE INDEX odoo_order_commercials_sale_order_ref_idx ON mv_edge_oee_ucepsa_prod.odoo_order_commercials USING btree (sale_order_ref); -- -- Name: raw_material_cost_parameters_tenant_site_raw_product_defaul_idx; Type: INDEX; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- CREATE INDEX raw_material_cost_parameters_tenant_site_raw_product_defaul_idx ON mv_edge_oee_ucepsa_prod.raw_material_cost_parameters USING btree (tenant, site, raw_product_default_code, is_active, valid_from DESC); -- -- Name: idx_edge_oee_eastron_readings_asset_ts; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_eastron_readings_asset_ts ON mv_hot.edge_oee_eastron_readings USING btree (asset, ts DESC); -- -- Name: idx_edge_oee_eastron_readings_ts; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_eastron_readings_ts ON mv_hot.edge_oee_eastron_readings USING btree (ts DESC); -- -- Name: idx_edge_oee_energy_demo_time; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_energy_demo_time ON mv_hot.edge_oee_energy_demo USING btree (ts DESC); -- -- Name: idx_edge_oee_events_demo_machine_time; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_events_demo_machine_time ON mv_hot.edge_oee_events_demo USING btree (machine_id, start_time DESC); -- -- Name: idx_edge_oee_events_demo_time; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_events_demo_time ON mv_hot.edge_oee_events_demo USING btree (start_time DESC); -- -- Name: idx_edge_oee_machine_stops_asset_status; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_machine_stops_asset_status ON mv_hot.edge_oee_machine_stops USING btree (asset, status); -- -- Name: idx_edge_oee_machine_stops_machine_started; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_machine_stops_machine_started ON mv_hot.edge_oee_machine_stops USING btree (machine_id, started_at DESC); -- -- Name: idx_edge_oee_machine_stops_started_at; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_machine_stops_started_at ON mv_hot.edge_oee_machine_stops USING btree (started_at DESC); -- -- Name: idx_edge_oee_node_events_asset_ts; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_node_events_asset_ts ON mv_hot.edge_oee_node_events USING btree (asset, event_ts DESC); -- -- Name: idx_edge_oee_node_events_event_ts; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_node_events_event_ts ON mv_hot.edge_oee_node_events USING btree (event_ts DESC); -- -- Name: idx_edge_oee_node_events_machine_ts; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_node_events_machine_ts ON mv_hot.edge_oee_node_events USING btree (machine_id, event_ts DESC); -- -- Name: idx_edge_oee_node_events_received_at; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE INDEX idx_edge_oee_node_events_received_at ON mv_hot.edge_oee_node_events USING btree (received_at DESC); -- -- Name: ux_odoo_order_state_events_state_hash; Type: INDEX; Schema: mv_hot; Owner: mesavault -- CREATE UNIQUE INDEX ux_odoo_order_state_events_state_hash ON mv_hot.odoo_order_state_events USING btree (tenant, site, machine_id, payload_hash); -- -- Name: edge_oee_energy_demo edge_oee_energy_demo_machine_id_fkey; Type: FK CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_energy_demo ADD CONSTRAINT edge_oee_energy_demo_machine_id_fkey FOREIGN KEY (machine_id) REFERENCES mv_hot.edge_oee_machines(machine_id); -- -- Name: edge_oee_energy_demo edge_oee_energy_demo_order_id_fkey; Type: FK CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_energy_demo ADD CONSTRAINT edge_oee_energy_demo_order_id_fkey FOREIGN KEY (order_id) REFERENCES mv_hot.edge_oee_orders_demo(order_id); -- -- Name: edge_oee_events_demo edge_oee_events_demo_machine_id_fkey; Type: FK CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_events_demo ADD CONSTRAINT edge_oee_events_demo_machine_id_fkey FOREIGN KEY (machine_id) REFERENCES mv_hot.edge_oee_machines(machine_id); -- -- Name: edge_oee_events_demo edge_oee_events_demo_order_id_fkey; Type: FK CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_events_demo ADD CONSTRAINT edge_oee_events_demo_order_id_fkey FOREIGN KEY (order_id) REFERENCES mv_hot.edge_oee_orders_demo(order_id); -- -- Name: edge_oee_machine_stops edge_oee_machine_stops_cause_code_fkey; Type: FK CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_machine_stops ADD CONSTRAINT edge_oee_machine_stops_cause_code_fkey FOREIGN KEY (cause_code) REFERENCES mv_hot.edge_oee_stop_causes(cause_code); -- -- Name: edge_oee_orders_demo edge_oee_orders_demo_machine_id_fkey; Type: FK CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_orders_demo ADD CONSTRAINT edge_oee_orders_demo_machine_id_fkey FOREIGN KEY (machine_id) REFERENCES mv_hot.edge_oee_machines(machine_id); -- -- Name: edge_oee_quality_cases_demo edge_oee_quality_cases_demo_machine_id_fkey; Type: FK CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_quality_cases_demo ADD CONSTRAINT edge_oee_quality_cases_demo_machine_id_fkey FOREIGN KEY (machine_id) REFERENCES mv_hot.edge_oee_machines(machine_id); -- -- Name: edge_oee_quality_cases_demo edge_oee_quality_cases_demo_order_id_fkey; Type: FK CONSTRAINT; Schema: mv_hot; Owner: mesavault -- ALTER TABLE ONLY mv_hot.edge_oee_quality_cases_demo ADD CONSTRAINT edge_oee_quality_cases_demo_order_id_fkey FOREIGN KEY (order_id) REFERENCES mv_hot.edge_oee_orders_demo(order_id); -- -- Name: SCHEMA mv_edge_oee_ucepsa_demo; Type: ACL; Schema: -; Owner: mesavault -- GRANT USAGE ON SCHEMA mv_edge_oee_ucepsa_demo TO grafana_ucepsa_ro; GRANT USAGE ON SCHEMA mv_edge_oee_ucepsa_demo TO edge_oee_odoo_sync_writer; GRANT USAGE ON SCHEMA mv_edge_oee_ucepsa_demo TO edge_oee_operator_writer; -- -- Name: SCHEMA mv_edge_oee_ucepsa_prod; Type: ACL; Schema: -; Owner: mesavault -- GRANT USAGE ON SCHEMA mv_edge_oee_ucepsa_prod TO grafana_ucepsa_ro; GRANT USAGE ON SCHEMA mv_edge_oee_ucepsa_prod TO edge_oee_odoo_sync_writer; -- -- Name: SCHEMA mv_hot; Type: ACL; Schema: -; Owner: mesavault -- GRANT USAGE ON SCHEMA mv_hot TO grafana_ucepsa_ro; GRANT USAGE ON SCHEMA mv_hot TO edge_oee_odoo_sync_writer; GRANT USAGE ON SCHEMA mv_hot TO edge_oee_operator_writer; -- -- Name: SCHEMA mv_reports_ucepsa_demo; Type: ACL; Schema: -; Owner: mesavault -- GRANT USAGE ON SCHEMA mv_reports_ucepsa_demo TO grafana_ucepsa_ro; GRANT USAGE ON SCHEMA mv_reports_ucepsa_demo TO edge_oee_odoo_sync_writer; GRANT USAGE ON SCHEMA mv_reports_ucepsa_demo TO edge_oee_operator_writer; -- -- Name: SCHEMA mv_reports_ucepsa_prod; Type: ACL; Schema: -; Owner: mesavault -- GRANT USAGE ON SCHEMA mv_reports_ucepsa_prod TO grafana_ucepsa_ro; -- -- Name: FUNCTION oee_kpis(p_from timestamp with time zone, p_to timestamp with time zone, p_machine_id text, p_asset text); Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT ALL ON FUNCTION mv_reports_ucepsa_demo.oee_kpis(p_from timestamp with time zone, p_to timestamp with time zone, p_machine_id text, p_asset text) TO grafana_ucepsa_ro; -- -- Name: FUNCTION oee_operational_data(p_from timestamp with time zone, p_to timestamp with time zone, p_machine_id text, p_asset text); Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT ALL ON FUNCTION mv_reports_ucepsa_demo.oee_operational_data(p_from timestamp with time zone, p_to timestamp with time zone, p_machine_id text, p_asset text) TO grafana_ucepsa_ro; -- -- Name: TABLE data_quality_contract_rules; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.data_quality_contract_rules TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.data_quality_contract_rules TO edge_oee_odoo_sync_writer; -- -- Name: SEQUENCE data_quality_contract_rules_id_seq; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_edge_oee_ucepsa_demo.data_quality_contract_rules_id_seq TO edge_oee_odoo_sync_writer; -- -- Name: TABLE edge_oee_eastron_readings; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_readings TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_readings TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_readings TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_eastron_latest; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_latest TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_latest TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_latest TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_eastron_dashboard; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_dashboard TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_dashboard TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_dashboard TO edge_oee_operator_writer; -- -- Name: TABLE eastron_dashboard; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.eastron_dashboard TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.eastron_dashboard TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.eastron_dashboard TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_eastron_diagnosis_latest; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_diagnosis_latest TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_diagnosis_latest TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_eastron_diagnosis_latest TO edge_oee_operator_writer; -- -- Name: TABLE eastron_diagnosis_latest; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.eastron_diagnosis_latest TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.eastron_diagnosis_latest TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.eastron_diagnosis_latest TO edge_oee_operator_writer; -- -- Name: TABLE eastron_latest; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.eastron_latest TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.eastron_latest TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.eastron_latest TO edge_oee_operator_writer; -- -- Name: TABLE eastron_readings; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.eastron_readings TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.eastron_readings TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.eastron_readings TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_live_telemetry; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_live_telemetry TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_live_telemetry TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_live_telemetry TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_latest_machine_snapshot; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_latest_machine_snapshot TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_latest_machine_snapshot TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_latest_machine_snapshot TO edge_oee_operator_writer; -- -- Name: TABLE latest_machine_snapshot; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.latest_machine_snapshot TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.latest_machine_snapshot TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.latest_machine_snapshot TO edge_oee_operator_writer; -- -- Name: TABLE live_telemetry; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.live_telemetry TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.live_telemetry TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.live_telemetry TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_node_events; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_node_events TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_node_events TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_node_events TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_machine_state_latest; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_machine_state_latest TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_machine_state_latest TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_machine_state_latest TO edge_oee_operator_writer; -- -- Name: TABLE machine_state_latest; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.machine_state_latest TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.machine_state_latest TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.machine_state_latest TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_machine_stops; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_machine_stops TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_machine_stops TO edge_oee_odoo_sync_writer; GRANT SELECT,UPDATE ON TABLE mv_hot.edge_oee_machine_stops TO edge_oee_operator_writer; -- -- Name: TABLE machine_stops; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.machine_stops TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.machine_stops TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.machine_stops TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_machine_targets; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_machine_targets TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_machine_targets TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_machine_targets TO edge_oee_operator_writer; -- -- Name: TABLE machine_targets; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.machine_targets TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.machine_targets TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.machine_targets TO edge_oee_operator_writer; -- -- Name: TABLE margin_cost_parameters; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.margin_cost_parameters TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.margin_cost_parameters TO edge_oee_odoo_sync_writer; -- -- Name: SEQUENCE margin_cost_parameters_id_seq; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_edge_oee_ucepsa_demo.margin_cost_parameters_id_seq TO edge_oee_odoo_sync_writer; -- -- Name: TABLE node_events; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.node_events TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.node_events TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.node_events TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_node_events_recent; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_node_events_recent TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_node_events_recent TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_node_events_recent TO edge_oee_operator_writer; -- -- Name: TABLE node_events_recent; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.node_events_recent TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.node_events_recent TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.node_events_recent TO edge_oee_operator_writer; -- -- Name: TABLE odoo_order_commercials; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.odoo_order_commercials TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.odoo_order_commercials TO edge_oee_odoo_sync_writer; -- -- Name: SEQUENCE odoo_order_commercials_id_seq; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_edge_oee_ucepsa_demo.odoo_order_commercials_id_seq TO edge_oee_odoo_sync_writer; -- -- Name: TABLE odoo_workcenter_map; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.odoo_workcenter_map TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.odoo_workcenter_map TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.odoo_workcenter_map TO edge_oee_operator_writer; -- -- Name: SEQUENCE odoo_workcenter_map_id_seq; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_edge_oee_ucepsa_demo.odoo_workcenter_map_id_seq TO edge_oee_odoo_sync_writer; -- -- Name: TABLE odoo_workorders_demo; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.odoo_workorders_demo TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.odoo_workorders_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.odoo_workorders_demo TO edge_oee_operator_writer; -- -- Name: SEQUENCE odoo_workorders_demo_id_seq; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_edge_oee_ucepsa_demo.odoo_workorders_demo_id_seq TO edge_oee_odoo_sync_writer; -- -- Name: TABLE edge_oee_stop_causes; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_stop_causes TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_stop_causes TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_stop_causes TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_open_stops; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_open_stops TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_open_stops TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_open_stops TO edge_oee_operator_writer; -- -- Name: TABLE open_stops; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.open_stops TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.open_stops TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.open_stops TO edge_oee_operator_writer; -- -- Name: TABLE raw_material_cost_parameters; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.raw_material_cost_parameters TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.raw_material_cost_parameters TO edge_oee_odoo_sync_writer; -- -- Name: SEQUENCE raw_material_cost_parameters_id_seq; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_edge_oee_ucepsa_demo.raw_material_cost_parameters_id_seq TO edge_oee_odoo_sync_writer; -- -- Name: TABLE edge_oee_stop_cause_options; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_stop_cause_options TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_stop_cause_options TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_stop_cause_options TO edge_oee_operator_writer; -- -- Name: TABLE stop_cause_options; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.stop_cause_options TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.stop_cause_options TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.stop_cause_options TO edge_oee_operator_writer; -- -- Name: TABLE stop_causes; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.stop_causes TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.stop_causes TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.stop_causes TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_stop_summary_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_stop_summary_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_stop_summary_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_stop_summary_demo TO edge_oee_operator_writer; -- -- Name: TABLE stop_summary; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.stop_summary TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.stop_summary TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.stop_summary TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_stops_recent; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_stops_recent TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_stops_recent TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_stops_recent TO edge_oee_operator_writer; -- -- Name: TABLE stops_recent; Type: ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.stops_recent TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_demo.stops_recent TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_edge_oee_ucepsa_demo.stops_recent TO edge_oee_operator_writer; -- -- Name: TABLE data_quality_contract_rules; Type: ACL; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_prod.data_quality_contract_rules TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_prod.data_quality_contract_rules TO edge_oee_odoo_sync_writer; -- -- Name: TABLE margin_cost_parameters; Type: ACL; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_prod.margin_cost_parameters TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_prod.margin_cost_parameters TO edge_oee_odoo_sync_writer; -- -- Name: TABLE odoo_order_commercials; Type: ACL; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_prod.odoo_order_commercials TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_prod.odoo_order_commercials TO edge_oee_odoo_sync_writer; -- -- Name: SEQUENCE odoo_order_commercials_id_seq; Type: ACL; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_edge_oee_ucepsa_prod.odoo_order_commercials_id_seq TO edge_oee_odoo_sync_writer; -- -- Name: TABLE raw_material_cost_parameters; Type: ACL; Schema: mv_edge_oee_ucepsa_prod; Owner: mesavault -- GRANT SELECT ON TABLE mv_edge_oee_ucepsa_prod.raw_material_cost_parameters TO grafana_ucepsa_ro; GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE mv_edge_oee_ucepsa_prod.raw_material_cost_parameters TO edge_oee_odoo_sync_writer; -- -- Name: TABLE edge_oee_loss_summary_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_loss_summary_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_loss_summary_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_loss_summary_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_actions_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_actions_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_actions_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_actions_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_data_quality_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_data_quality_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_data_quality_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_data_quality_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_data_quality_dashboard_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_data_quality_dashboard_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_data_quality_dashboard_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_data_quality_dashboard_demo TO edge_oee_operator_writer; -- -- Name: SEQUENCE edge_oee_eastron_readings_id_seq; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_hot.edge_oee_eastron_readings_id_seq TO edge_oee_odoo_sync_writer; GRANT ALL ON SEQUENCE mv_hot.edge_oee_eastron_readings_id_seq TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_energy_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_energy_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_energy_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_energy_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_events_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_events_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_events_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_events_demo TO edge_oee_operator_writer; -- -- Name: SEQUENCE edge_oee_events_demo_event_id_seq; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_hot.edge_oee_events_demo_event_id_seq TO edge_oee_odoo_sync_writer; GRANT ALL ON SEQUENCE mv_hot.edge_oee_events_demo_event_id_seq TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_executive_summary_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_executive_summary_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_executive_summary_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_executive_summary_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_kpi_cards_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_kpi_cards_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_kpi_cards_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_kpi_cards_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_machine_stops_backup_cort00_20260622_175800; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_machine_stops_backup_cort00_20260622_175800 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_machine_stops_backup_cort00_20260622_175800 TO edge_oee_odoo_sync_writer; -- -- Name: SEQUENCE edge_oee_machine_stops_id_seq; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_hot.edge_oee_machine_stops_id_seq TO edge_oee_odoo_sync_writer; GRANT ALL ON SEQUENCE mv_hot.edge_oee_machine_stops_id_seq TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_machines; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_machines TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_machines TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_machines TO edge_oee_operator_writer; -- -- Name: SEQUENCE edge_oee_node_events_id_seq; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_hot.edge_oee_node_events_id_seq TO edge_oee_odoo_sync_writer; GRANT ALL ON SEQUENCE mv_hot.edge_oee_node_events_id_seq TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_orders_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_orders_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_orders_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_orders_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_order_timeline_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_order_timeline_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_order_timeline_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_order_timeline_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_pareto_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_pareto_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_pareto_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_pareto_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_quality_cases_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_quality_cases_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_quality_cases_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_quality_cases_demo TO edge_oee_operator_writer; -- -- Name: TABLE edge_oee_quality_case_demo; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.edge_oee_quality_case_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.edge_oee_quality_case_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_hot.edge_oee_quality_case_demo TO edge_oee_operator_writer; -- -- Name: TABLE odoo_order_state_current; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.odoo_order_state_current TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.odoo_order_state_current TO edge_oee_odoo_sync_writer; -- -- Name: TABLE odoo_order_state_events; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT SELECT ON TABLE mv_hot.odoo_order_state_events TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_hot.odoo_order_state_events TO edge_oee_odoo_sync_writer; -- -- Name: SEQUENCE odoo_order_state_events_id_seq; Type: ACL; Schema: mv_hot; Owner: mesavault -- GRANT ALL ON SEQUENCE mv_hot.odoo_order_state_events_id_seq TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_execution_report_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_report_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_report_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_execution_energy_timeseries_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_energy_timeseries_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_energy_timeseries_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_execution_data_quality_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_data_quality_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_data_quality_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_execution_stops_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_stops_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_stops_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_execution_stop_causes_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_stop_causes_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_stop_causes_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_execution_timeline_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_timeline_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_timeline_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_execution_report_full_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_report_full_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_execution_report_full_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_raw_material_costs_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_raw_material_costs_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_raw_material_costs_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_raw_material_costs_summary_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_raw_material_costs_summary_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_raw_material_costs_summary_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE order_margin_report_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_margin_report_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.order_margin_report_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE cost_readiness_orders_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.cost_readiness_orders_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.cost_readiness_orders_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE cost_readiness_raw_materials_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.cost_readiness_raw_materials_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.cost_readiness_raw_materials_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE cost_readiness_summary_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.cost_readiness_summary_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.cost_readiness_summary_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE cycle_rate_timeseries; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.cycle_rate_timeseries TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.cycle_rate_timeseries TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.cycle_rate_timeseries TO edge_oee_operator_writer; -- -- Name: TABLE data_quality_contract_order_checks_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.data_quality_contract_order_checks_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.data_quality_contract_order_checks_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE data_quality_contract_order_summary_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.data_quality_contract_order_summary_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.data_quality_contract_order_summary_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE data_quality_contract_owner_summary_v1; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.data_quality_contract_owner_summary_v1 TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.data_quality_contract_owner_summary_v1 TO edge_oee_odoo_sync_writer; -- -- Name: TABLE energy_3phase_timeseries; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_3phase_timeseries TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_3phase_timeseries TO edge_oee_odoo_sync_writer; -- -- Name: TABLE energy_3phase_latest; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_3phase_latest TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_3phase_latest TO edge_oee_odoo_sync_writer; -- -- Name: TABLE energy_diagnosis; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_diagnosis TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_diagnosis TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_diagnosis TO edge_oee_operator_writer; -- -- Name: TABLE energy_import_timeseries; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_import_timeseries TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_import_timeseries TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_import_timeseries TO edge_oee_operator_writer; -- -- Name: TABLE energy_latest; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_latest TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_latest TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_latest TO edge_oee_operator_writer; -- -- Name: TABLE energy_power_timeseries; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_power_timeseries TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_power_timeseries TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.energy_power_timeseries TO edge_oee_operator_writer; -- -- Name: TABLE latest_machine_snapshot; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.latest_machine_snapshot TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.latest_machine_snapshot TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.latest_machine_snapshot TO edge_oee_operator_writer; -- -- Name: TABLE latest_machine_state_fast; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.latest_machine_state_fast TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.latest_machine_state_fast TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.latest_machine_state_fast TO edge_oee_operator_writer; -- -- Name: TABLE live_telemetry; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.live_telemetry TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.live_telemetry TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.live_telemetry TO edge_oee_operator_writer; -- -- Name: TABLE odoo_current_order_demo; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_current_order_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_current_order_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_current_order_demo TO edge_oee_operator_writer; -- -- Name: TABLE stops_recent; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.stops_recent TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.stops_recent TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.stops_recent TO edge_oee_operator_writer; -- -- Name: TABLE odoo_vs_machine_demo; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_vs_machine_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_vs_machine_demo TO edge_oee_odoo_sync_writer; -- -- Name: TABLE open_stops; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.open_stops TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.open_stops TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.open_stops TO edge_oee_operator_writer; -- -- Name: TABLE loss_events_current; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.loss_events_current TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.loss_events_current TO edge_oee_odoo_sync_writer; -- -- Name: TABLE loss_priority_board; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.loss_priority_board TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.loss_priority_board TO edge_oee_odoo_sync_writer; -- -- Name: TABLE machine_state_latest; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_state_latest TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_state_latest TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_state_latest TO edge_oee_operator_writer; -- -- Name: TABLE machine_state_latest_multi; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_state_latest_multi TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_state_latest_multi TO edge_oee_odoo_sync_writer; -- -- Name: TABLE machine_stops_grafana; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_stops_grafana TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_stops_grafana TO edge_oee_odoo_sync_writer; -- -- Name: TABLE machine_targets; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_targets TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_targets TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.machine_targets TO edge_oee_operator_writer; -- -- Name: TABLE node_events_recent; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.node_events_recent TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.node_events_recent TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.node_events_recent TO edge_oee_operator_writer; -- -- Name: TABLE odoo_discrepancies_demo; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_discrepancies_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_discrepancies_demo TO edge_oee_odoo_sync_writer; -- -- Name: TABLE odoo_workorders_reality_history; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_workorders_reality_history TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_workorders_reality_history TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_workorders_reality_history TO edge_oee_operator_writer; -- -- Name: TABLE odoo_last_finished_order_demo; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_last_finished_order_demo TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_last_finished_order_demo TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_last_finished_order_demo TO edge_oee_operator_writer; -- -- Name: TABLE odoo_order_state_machine_grafana; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_order_state_machine_grafana TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.odoo_order_state_machine_grafana TO edge_oee_odoo_sync_writer; -- -- Name: TABLE stop_summary; Type: ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_demo.stop_summary TO grafana_ucepsa_ro; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.stop_summary TO edge_oee_odoo_sync_writer; GRANT SELECT ON TABLE mv_reports_ucepsa_demo.stop_summary TO edge_oee_operator_writer; -- -- Name: TABLE current_order_margin_readiness_v1; Type: ACL; Schema: mv_reports_ucepsa_prod; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_prod.current_order_margin_readiness_v1 TO grafana_ucepsa_ro; -- -- Name: TABLE order_raw_material_costs_v1; Type: ACL; Schema: mv_reports_ucepsa_prod; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_prod.order_raw_material_costs_v1 TO grafana_ucepsa_ro; -- -- Name: TABLE order_raw_material_costs_summary_v1; Type: ACL; Schema: mv_reports_ucepsa_prod; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_prod.order_raw_material_costs_summary_v1 TO grafana_ucepsa_ro; -- -- Name: TABLE raw_material_cost_requirements_v1; Type: ACL; Schema: mv_reports_ucepsa_prod; Owner: mesavault -- GRANT SELECT ON TABLE mv_reports_ucepsa_prod.raw_material_cost_requirements_v1 TO grafana_ucepsa_ro; -- -- Name: DEFAULT PRIVILEGES FOR SEQUENCES; Type: DEFAULT ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER DEFAULT PRIVILEGES FOR ROLE mesavault IN SCHEMA mv_edge_oee_ucepsa_demo GRANT ALL ON SEQUENCES TO edge_oee_odoo_sync_writer; -- -- Name: DEFAULT PRIVILEGES FOR TABLES; Type: DEFAULT ACL; Schema: mv_edge_oee_ucepsa_demo; Owner: mesavault -- ALTER DEFAULT PRIVILEGES FOR ROLE mesavault IN SCHEMA mv_edge_oee_ucepsa_demo GRANT SELECT ON TABLES TO grafana_ucepsa_ro; ALTER DEFAULT PRIVILEGES FOR ROLE mesavault IN SCHEMA mv_edge_oee_ucepsa_demo GRANT SELECT,INSERT,DELETE,UPDATE ON TABLES TO edge_oee_odoo_sync_writer; -- -- Name: DEFAULT PRIVILEGES FOR SEQUENCES; Type: DEFAULT ACL; Schema: mv_hot; Owner: mesavault -- ALTER DEFAULT PRIVILEGES FOR ROLE mesavault IN SCHEMA mv_hot GRANT ALL ON SEQUENCES TO edge_oee_odoo_sync_writer; -- -- Name: DEFAULT PRIVILEGES FOR TABLES; Type: DEFAULT ACL; Schema: mv_hot; Owner: mesavault -- ALTER DEFAULT PRIVILEGES FOR ROLE mesavault IN SCHEMA mv_hot GRANT SELECT ON TABLES TO grafana_ucepsa_ro; ALTER DEFAULT PRIVILEGES FOR ROLE mesavault IN SCHEMA mv_hot GRANT SELECT ON TABLES TO edge_oee_odoo_sync_writer; -- -- Name: DEFAULT PRIVILEGES FOR FUNCTIONS; Type: DEFAULT ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- ALTER DEFAULT PRIVILEGES FOR ROLE mesavault IN SCHEMA mv_reports_ucepsa_demo GRANT ALL ON FUNCTIONS TO grafana_ucepsa_ro; -- -- Name: DEFAULT PRIVILEGES FOR TABLES; Type: DEFAULT ACL; Schema: mv_reports_ucepsa_demo; Owner: mesavault -- ALTER DEFAULT PRIVILEGES FOR ROLE mesavault IN SCHEMA mv_reports_ucepsa_demo GRANT SELECT ON TABLES TO grafana_ucepsa_ro; ALTER DEFAULT PRIVILEGES FOR ROLE mesavault IN SCHEMA mv_reports_ucepsa_demo GRANT SELECT ON TABLES TO edge_oee_odoo_sync_writer; -- -- PostgreSQL database dump complete -- \unrestrict 1wX0I2K6nLSszbhqDMaBaJRF13jG1hT3a3HKImFGiykK1wx4riB6Rf5OY4lcf06