40-clients/ucepsa/edge-oee-demo/db/schema/postgres_schema_latest.sql
2026-06-25 18:51:33 +02:00

8743 lines
329 KiB
PL/PgSQL

--
-- 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