-- ===============================================================
-- SuiteCoffee — Template de inicialización por tenant
-- Archivo: 01_init.sql
-- Uso (psql):
--   \set SCHEMA_NAME schema_tenant_12345678abcd
--   CREATE SCHEMA IF NOT EXISTS :"SCHEMA_NAME";
--   -- Opcional: SET ROLE <rol_del_tenant>;
--   \i 01_init.sql
-- ===============================================================

BEGIN;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;

-- establece el schema de destino
SET search_path = :"SCHEMA_NAME", public;

--
-- PostgreSQL database dump
--

\restrict londHmqT4llS8Wof4ZnceO2dyFhn4jiR5xbaszMgZpMczgr6aVW6xQJxeUdqJwa

-- Dumped from database version 16.10 (Debian 16.10-1.pgdg13+1)
-- Dumped by pg_dump version 16.10 (Debian 16.10-1.pgdg13+1)

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

--
-- Name: asistencia_delete_raw(bigint, text); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION asistencia_delete_raw(p_id_raw bigint, p_tz text DEFAULT 'America/Montevideo'::text) RETURNS jsonb
    LANGUAGE plpgsql
    AS $$
DECLARE
  v_id_usuario INT;
  v_ts         TIMESTAMPTZ;
  v_t0         TIMESTAMPTZ;
  v_t1         TIMESTAMPTZ;
  v_del_raw    INT;
  v_del        INT;
  v_ins        INT;
BEGIN
  SELECT id_usuario, ts INTO v_id_usuario, v_ts
  FROM asistencia_raw WHERE id_raw = p_id_raw;
  IF v_id_usuario IS NULL THEN
    RETURN jsonb_build_object('deleted',0,'msg','id_raw inexistente');
  END IF;

  v_t0 := v_ts - INTERVAL '1 day';
  v_t1 := v_ts + INTERVAL '1 day';

  -- borrar raw
  DELETE FROM asistencia_raw WHERE id_raw = p_id_raw;
  GET DIAGNOSTICS v_del_raw = ROW_COUNT;

  -- recomputar pares en ventana
  WITH tl AS (
    SELECT ar.ts,
           ROW_NUMBER() OVER (ORDER BY ar.ts) AS rn
    FROM asistencia_raw ar
    WHERE ar.id_usuario = v_id_usuario
      AND ar.ts BETWEEN v_t0 AND v_t1
  ),
  ready AS (
    SELECT (t1.ts AT TIME ZONE p_tz)::date AS fecha,
           t1.ts AS desde,
           t2.ts AS hasta,
           EXTRACT(EPOCH FROM (t2.ts - t1.ts))/60.0 AS dur_min
    FROM tl t1
    JOIN tl t2 ON t2.rn = t1.rn + 1
    WHERE (t1.rn % 2) = 1 AND t2.ts > t1.ts
  ),
  del AS (
    DELETE FROM asistencia_intervalo ai
    WHERE ai.id_usuario = v_id_usuario
      AND (ai.desde BETWEEN v_t0 AND v_t1 OR ai.hasta BETWEEN v_t0 AND v_t1)
    RETURNING 1
  ),
  ins AS (
    INSERT INTO asistencia_intervalo (id_usuario, fecha, desde, hasta, dur_min, origen)
    SELECT v_id_usuario, r.fecha, r.desde, r.hasta, r.dur_min, 'delete_adjust'
    FROM ready r
    ON CONFLICT (id_usuario, desde, hasta) DO NOTHING
    RETURNING 1
  )
  SELECT (SELECT COUNT(*) FROM del), (SELECT COUNT(*) FROM ins) INTO v_del, v_ins;

  RETURN jsonb_build_object('deleted',v_del_raw,'deleted_pairs',v_del,'inserted_pairs',v_ins);
END;
$$;

--
-- Name: asistencia_get(text, date, date, text); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION asistencia_get(p_doc text, p_desde date, p_hasta date, p_tz text DEFAULT 'America/Montevideo'::text) RETURNS jsonb
    LANGUAGE sql
    AS $$
WITH u AS (
  SELECT id_usuario, documento, nombre, apellido
  FROM usuarios
  WHERE regexp_replace(documento,'^\s*0+','','g') = regexp_replace(p_doc,'^\s*0+','','g')
  LIMIT 1
),
r AS (
  SELECT ar.id_raw,
         (ar.ts AT TIME ZONE p_tz)::date                         AS fecha,
         to_char(ar.ts AT TIME ZONE p_tz,'HH24:MI:SS')           AS hora,
         COALESCE(ar.modo,'')                                    AS modo,
         COALESCE(ar.origen,'')                                  AS origen,
         ar.ts
  FROM asistencia_raw ar
  JOIN u USING (id_usuario)
  WHERE (ar.ts AT TIME ZONE p_tz)::date BETWEEN p_desde AND p_hasta
),
i AS (
  SELECT ai.id_intervalo,
         ai.fecha,
         to_char(ai.desde AT TIME ZONE p_tz,'HH24:MI:SS')        AS desde_hora,
         to_char(ai.hasta AT TIME ZONE p_tz,'HH24:MI:SS')        AS hasta_hora,
         ai.dur_min
  FROM asistencia_intervalo ai
  JOIN u USING (id_usuario)
  WHERE ai.fecha BETWEEN p_desde AND p_hasta
)
SELECT jsonb_build_object(
  'usuario', (SELECT to_jsonb(u.*) FROM u),
  'raw',     COALESCE((SELECT jsonb_agg(to_jsonb(r.*) ORDER BY r.ts) FROM r),'[]'::jsonb),
  'intervalos', COALESCE((SELECT jsonb_agg(to_jsonb(i.*) ORDER BY i.fecha, i.id_intervalo) FROM i),'[]'::jsonb)
);
$$;

--
-- Name: asistencia_update_raw(bigint, date, text, text, text); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION asistencia_update_raw(p_id_raw bigint, p_fecha date, p_hora text, p_modo text, p_tz text DEFAULT 'America/Montevideo'::text) RETURNS jsonb
    LANGUAGE plpgsql
    AS $$
DECLARE
  v_id_usuario INT;
  v_ts_old     TIMESTAMPTZ;
  v_ts_new     TIMESTAMPTZ;
  v_t0         TIMESTAMPTZ;
  v_t1         TIMESTAMPTZ;
  v_del        INT;
  v_ins        INT;
BEGIN
  -- leer estado previo
  SELECT id_usuario, ts INTO v_id_usuario, v_ts_old
  FROM asistencia_raw WHERE id_raw = p_id_raw;
  IF v_id_usuario IS NULL THEN
    RETURN jsonb_build_object('updated',0,'msg','id_raw inexistente');
  END IF;

  -- construir ts nuevo
  v_ts_new := make_timestamptz(
               EXTRACT(YEAR FROM p_fecha)::INT,
               EXTRACT(MONTH FROM p_fecha)::INT,
               EXTRACT(DAY FROM p_fecha)::INT,
               split_part(p_hora,':',1)::INT,
               split_part(p_hora,':',2)::INT,
               COALESCE(NULLIF(split_part(p_hora,':',3),''), '0')::INT,
               p_tz);

  -- aplicar update
  UPDATE asistencia_raw
  SET ts = v_ts_new,
      modo = COALESCE(p_modo, modo)
  WHERE id_raw = p_id_raw;

  -- ventana de recálculo
  v_t0 := LEAST(v_ts_old, v_ts_new) - INTERVAL '1 day';
  v_t1 := GREATEST(v_ts_old, v_ts_new) + INTERVAL '1 day';

  -- recomputar pares en la ventana: borrar los del rango y reinsertar
  WITH tl AS (
    SELECT ar.ts,
           ROW_NUMBER() OVER (ORDER BY ar.ts) AS rn
    FROM asistencia_raw ar
    WHERE ar.id_usuario = v_id_usuario
      AND ar.ts BETWEEN v_t0 AND v_t1
  ),
  ready AS (
    SELECT (t1.ts AT TIME ZONE p_tz)::date AS fecha,
           t1.ts AS desde,
           t2.ts AS hasta,
           EXTRACT(EPOCH FROM (t2.ts - t1.ts))/60.0 AS dur_min
    FROM tl t1
    JOIN tl t2 ON t2.rn = t1.rn + 1
    WHERE (t1.rn % 2) = 1 AND t2.ts > t1.ts
  ),
  del AS (
    DELETE FROM asistencia_intervalo ai
    WHERE ai.id_usuario = v_id_usuario
      AND (ai.desde BETWEEN v_t0 AND v_t1 OR ai.hasta BETWEEN v_t0 AND v_t1)
    RETURNING 1
  ),
  ins AS (
    INSERT INTO asistencia_intervalo (id_usuario, fecha, desde, hasta, dur_min, origen)
    SELECT v_id_usuario, r.fecha, r.desde, r.hasta, r.dur_min, 'edit_manual'
    FROM ready r
    ON CONFLICT (id_usuario, desde, hasta) DO NOTHING
    RETURNING 1
  )
  SELECT (SELECT COUNT(*) FROM del), (SELECT COUNT(*) FROM ins) INTO v_del, v_ins;

  RETURN jsonb_build_object('updated',1,'deleted_pairs',v_del,'inserted_pairs',v_ins);
END;
$$;

--
-- Name: delete_compra(integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION delete_compra(p_id_compra integer) RETURNS void
    LANGUAGE plpgsql
    AS $$
BEGIN
  DELETE FROM deta_comp_materias WHERE id_compra = p_id_compra;
  DELETE FROM deta_comp_producto WHERE id_compra = p_id_compra;
  DELETE FROM compras WHERE id_compra = p_id_compra;
END;
$$;

--
-- Name: f_abrir_comanda(integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION f_abrir_comanda(p_id integer) RETURNS jsonb
    LANGUAGE plpgsql
    AS $$
DECLARE r jsonb;
BEGIN
  UPDATE comandas
     SET estado    = 'abierta',
         fec_cierre = NULL
   WHERE id_comanda = p_id;

  IF NOT FOUND THEN
    RETURN NULL;
  END IF;

  SELECT to_jsonb(v) INTO r
    FROM v_comandas_resumen v
   WHERE v.id_comanda = p_id;

  RETURN r;
END;
$$;

--
-- Name: f_cerrar_comanda(integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION f_cerrar_comanda(p_id integer) RETURNS jsonb
    LANGUAGE plpgsql
    AS $$
DECLARE r jsonb;
BEGIN
  UPDATE comandas
     SET estado    = 'cerrada',
         fec_cierre = COALESCE(fec_cierre, NOW())
   WHERE id_comanda = p_id;

  IF NOT FOUND THEN
    RETURN NULL;
  END IF;

  SELECT to_jsonb(v) INTO r
    FROM v_comandas_resumen v
   WHERE v.id_comanda = p_id;

  RETURN r;
END;
$$;

--
-- Name: f_comanda_detalle_json(integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION f_comanda_detalle_json(p_id_comanda integer) RETURNS jsonb
    LANGUAGE sql
    AS $$
WITH base AS (
  SELECT
    c.id_comanda,
    c.fec_creacion,
    c.estado,
    c.observaciones,
    u.id_usuario,
    u.nombre   AS usuario_nombre,
    u.apellido AS usuario_apellido,
    m.id_mesa,
    m.numero   AS mesa_numero,
    m.apodo    AS mesa_apodo,
    d.id_producto,
    p.nombre   AS producto_nombre,
    d.cantidad,
    d.pre_unitario,
    (d.cantidad * d.pre_unitario) AS subtotal
  FROM comandas c
  JOIN usuarios  u ON u.id_usuario = c.id_usuario
  JOIN mesas     m ON m.id_mesa     = c.id_mesa
  LEFT JOIN deta_comandas d ON d.id_comanda = c.id_comanda
  LEFT JOIN productos     p ON p.id_producto = d.id_producto
  WHERE c.id_comanda = p_id_comanda
),
hdr AS (
  -- 1 sola fila con los datos de cabecera
  SELECT DISTINCT
    id_comanda, fec_creacion, estado, observaciones,
    id_usuario, usuario_nombre, usuario_apellido,
    id_mesa, mesa_numero, mesa_apodo
  FROM base
),
agg_items AS (
  SELECT
    COALESCE(
      jsonb_agg(
        jsonb_build_object(
          'producto_id',   b.id_producto,
          'producto',      b.producto_nombre,
          'cantidad',      b.cantidad,
          'pre_unitario',  b.pre_unitario,
          'subtotal',      b.subtotal
        )
        ORDER BY b.producto_nombre NULLS LAST
      ) FILTER (WHERE b.id_producto IS NOT NULL),
      '[]'::jsonb
    ) AS items
  FROM base b
),
tot AS (
  SELECT
    COUNT(*) FILTER (WHERE id_producto IS NOT NULL) AS items,
    COALESCE(SUM(subtotal), 0)::numeric            AS total
  FROM base
)
SELECT
  CASE
    WHEN EXISTS (SELECT 1 FROM hdr) THEN
      jsonb_build_object(
        'id_comanda',   h.id_comanda,
        'fec_creacion', h.fec_creacion,
        'estado',       h.estado,
        'observaciones',h.observaciones,
        'usuario', jsonb_build_object(
          'id_usuario',      h.id_usuario,
          'nombre',          h.usuario_nombre,
          'apellido',        h.usuario_apellido
        ),
        'mesa', jsonb_build_object(
          'id_mesa',         h.id_mesa,
          'numero',          h.mesa_numero,
          'apodo',           h.mesa_apodo
        ),
        'items',   i.items,
        'totales', jsonb_build_object(
          'items', t.items,
          'total', t.total
        )
      )
    ELSE NULL
  END
FROM hdr h, agg_items i, tot t;
$$;

--
-- Name: f_comanda_detalle_rows(integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION f_comanda_detalle_rows(p_id_comanda integer) RETURNS TABLE(id_comanda integer, fec_creacion timestamp without time zone, estado text, observaciones text, id_usuario integer, usuario_nombre text, usuario_apellido text, id_mesa integer, mesa_numero integer, mesa_apodo text, producto_id integer, producto_nombre text, cantidad numeric, pre_unitario numeric, subtotal numeric, items integer, total numeric)
    LANGUAGE sql
    AS $$
WITH base AS (
  SELECT
    c.id_comanda, c.fec_creacion, c.estado, c.observaciones,
    u.id_usuario, u.nombre AS usuario_nombre, u.apellido AS usuario_apellido,
    m.id_mesa, m.numero AS mesa_numero, m.apodo AS mesa_apodo,
    d.id_producto, p.nombre AS producto_nombre,
    d.cantidad, d.pre_unitario,
    (d.cantidad * d.pre_unitario) AS subtotal
  FROM comandas c
  JOIN usuarios u ON u.id_usuario = c.id_usuario
  JOIN mesas    m ON m.id_mesa     = c.id_mesa
  LEFT JOIN deta_comandas d ON d.id_comanda = c.id_comanda
  LEFT JOIN productos     p ON p.id_producto = d.id_producto
  WHERE c.id_comanda = p_id_comanda
),
tot AS (
  SELECT
    COUNT(*) FILTER (WHERE id_producto IS NOT NULL) AS items,
    COALESCE(SUM(subtotal), 0) AS total
  FROM base
)
SELECT
  b.id_comanda, b.fec_creacion, b.estado, b.observaciones,
  b.id_usuario, b.usuario_nombre, b.usuario_apellido,
  b.id_mesa, b.mesa_numero, b.mesa_apodo,
  b.id_producto, b.producto_nombre,
  b.cantidad, b.pre_unitario, b.subtotal,
  t.items, t.total
FROM base b CROSS JOIN tot t
ORDER BY b.producto_nombre NULLS LAST;
$$;

SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: comandas; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE comandas (
    id_comanda integer NOT NULL,
    id_usuario integer NOT NULL,
    id_mesa integer NOT NULL,
    fec_creacion timestamp without time zone DEFAULT now() NOT NULL,
    estado text NOT NULL,
    observaciones text,
    fec_cierre timestamp with time zone,
    CONSTRAINT comandas_estado_check CHECK ((estado = ANY (ARRAY['abierta'::text, 'cerrada'::text, 'pagada'::text, 'anulada'::text])))
);

--
-- Name: COLUMN comandas.fec_cierre; Type: COMMENT; Schema: public; Owner: manso
--

COMMENT ON COLUMN comandas.fec_cierre IS 'Fecha/hora de cierre de la comanda (NULL si está abierta)';

--
-- Name: deta_comandas; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE deta_comandas (
    id_det_comanda integer NOT NULL,
    id_comanda integer NOT NULL,
    id_producto integer NOT NULL,
    cantidad numeric(12,3) NOT NULL,
    pre_unitario numeric(12,2) NOT NULL,
    observaciones text,
    CONSTRAINT deta_comandas_cantidad_check CHECK ((cantidad > (0)::numeric)),
    CONSTRAINT deta_comandas_pre_unitario_check CHECK ((pre_unitario >= (0)::numeric))
);

--
-- Name: mesas; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE mesas (
    id_mesa integer NOT NULL,
    numero integer NOT NULL,
    apodo text NOT NULL,
    estado text DEFAULT 'libre'::text NOT NULL,
    CONSTRAINT mesas_estado_check CHECK ((estado = ANY (ARRAY['libre'::text, 'ocupada'::text, 'reservada'::text])))
);

--
-- Name: usuarios; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE usuarios (
    id_usuario integer NOT NULL,
    documento text,
    img_perfil character varying(255) DEFAULT 'img_perfil.png'::character varying NOT NULL,
    nombre text NOT NULL,
    apellido text NOT NULL,
    correo text,
    telefono text,
    fec_nacimiento date,
    activo boolean DEFAULT true
);

--
-- Name: v_comandas_resumen; Type: VIEW; Schema: public; Owner: manso
--

CREATE VIEW v_comandas_resumen AS
 WITH items AS (
         SELECT d.id_comanda,
            count(*) AS items,
            sum((d.cantidad * d.pre_unitario)) AS total
           FROM deta_comandas d
          GROUP BY d.id_comanda
        )
 SELECT c.id_comanda,
    c.fec_creacion,
    c.estado,
    c.observaciones,
    u.id_usuario,
    u.nombre AS usuario_nombre,
    u.apellido AS usuario_apellido,
    m.id_mesa,
    m.numero AS mesa_numero,
    m.apodo AS mesa_apodo,
    COALESCE(i.items, (0)::bigint) AS items,
    COALESCE(i.total, (0)::numeric) AS total,
    c.fec_cierre,
        CASE
            WHEN (c.fec_cierre IS NOT NULL) THEN round((EXTRACT(epoch FROM (c.fec_cierre - (c.fec_creacion)::timestamp with time zone)) / 60.0), 1)
            ELSE NULL::numeric
        END AS duracion_min
   FROM (((comandas c
     JOIN usuarios u ON ((u.id_usuario = c.id_usuario)))
     JOIN mesas m ON ((m.id_mesa = c.id_mesa)))
     LEFT JOIN items i ON ((i.id_comanda = c.id_comanda)));

--
-- Name: f_comandas_resumen(text, integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION f_comandas_resumen(p_estado text DEFAULT NULL::text, p_limit integer DEFAULT 200) RETURNS SETOF v_comandas_resumen
    LANGUAGE sql
    AS $$
  SELECT *
  FROM v_comandas_resumen
  WHERE (p_estado IS NULL OR estado = p_estado)
  ORDER BY id_comanda DESC
  LIMIT p_limit;
$$;

--
-- Name: find_usuarios_por_documentos(jsonb); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION find_usuarios_por_documentos(p_docs jsonb) RETURNS jsonb
    LANGUAGE sql
    AS $$
WITH docs AS (
  SELECT DISTINCT
         regexp_replace(value::text, '^\s*0+', '', 'g') AS doc_clean,
         value::text                                  AS original
  FROM jsonb_array_elements_text(COALESCE(p_docs,'[]'))
),
rows AS (
  SELECT d.original                             AS documento,
         u.nombre,
         u.apellido,
         (u.id_usuario IS NOT NULL)             AS found
  FROM docs d
  LEFT JOIN usuarios u
    ON regexp_replace(u.documento, '^\s*0+', '', 'g') = d.doc_clean
)
SELECT COALESCE(
  jsonb_object_agg(
    documento,
    jsonb_build_object(
      'nombre',   COALESCE(nombre, ''),
      'apellido', COALESCE(apellido, ''),
      'found',    found
    )
  ),
  '{}'::jsonb
)
FROM rows;
$$;

--
-- Name: get_compra(integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION get_compra(p_id_compra integer) RETURNS jsonb
    LANGUAGE sql
    AS $$
WITH cab AS (
  SELECT c.id_compra, c.id_proveedor, c.fec_compra, c.total
  FROM compras c
  WHERE c.id_compra = p_id_compra
),
dm AS (
  SELECT 'MAT'::text AS tipo, d.id_mat_prima AS id,
         d.cantidad, d.pre_unitario AS precio
  FROM deta_comp_materias d WHERE d.id_compra = p_id_compra
),
dp AS (
  SELECT 'PROD'::text AS tipo, d.id_producto AS id,
         d.cantidad, d.pre_unitario AS precio
  FROM deta_comp_producto d WHERE d.id_compra = p_id_compra
),
det AS (
  SELECT jsonb_agg(to_jsonb(x.*)) AS detalles
  FROM (
    SELECT * FROM dm
    UNION ALL
    SELECT * FROM dp
  ) x
)
SELECT jsonb_build_object(
  'id_compra', (SELECT id_compra FROM cab),
  'id_proveedor',(SELECT id_proveedor FROM cab),
  'fec_compra', to_char((SELECT fec_compra FROM cab),'YYYY-MM-DD HH24:MI:SS'),
  'total', (SELECT total FROM cab),
  'detalles', COALESCE((SELECT detalles FROM det),'[]'::jsonb)
);
$$;

--
-- Name: get_materia_prima(integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION get_materia_prima(p_id integer) RETURNS jsonb
    LANGUAGE sql
    AS $$
SELECT jsonb_build_object(
  'materia', to_jsonb(mp),
  'proveedores', COALESCE(
    (
      SELECT jsonb_agg(
               jsonb_build_object(
                 'id_proveedor', pr.id_proveedor,
                 'raz_social', pr.raz_social,
                 'rut', pr.rut,
                 'contacto', pr.contacto,
                 'direccion', pr.direccion
               )
             )
      FROM prov_mate_prima pmp
      JOIN proveedores pr ON pr.id_proveedor = pmp.id_proveedor
      WHERE pmp.id_mat_prima = mp.id_mat_prima
    ),
    '[]'::jsonb
  )
)
FROM mate_primas mp
WHERE mp.id_mat_prima = p_id;
$$;

--
-- Name: get_producto(integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION get_producto(p_id integer) RETURNS jsonb
    LANGUAGE sql
    AS $$
SELECT jsonb_build_object(
  'producto', to_jsonb(p),       -- el registro completo del producto en JSONB
  'receta', COALESCE(
    (
      SELECT jsonb_agg(
               jsonb_build_object(
                 'id_mat_prima', rp.id_mat_prima,
                 'qty_por_unidad', rp.qty_por_unidad,
                 'nombre', mp.nombre,
                 'unidad', mp.unidad
               )
             )
      FROM receta_producto rp
      LEFT JOIN mate_primas mp USING (id_mat_prima)
      WHERE rp.id_producto = p.id_producto
    ),
    '[]'::jsonb
  )
)
FROM productos p
WHERE p.id_producto = p_id;
$$;

--
-- Name: import_asistencia(jsonb, text, text); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION import_asistencia(p_registros jsonb, p_origen text, p_tz text DEFAULT 'America/Montevideo'::text) RETURNS jsonb
    LANGUAGE plpgsql
    AS $_$
DECLARE
  v_ins_raw   INT;
  v_ins_pairs INT;
  v_miss      JSONB;
BEGIN
  WITH
  -- 1) JSON -> filas
  j AS (
    SELECT
      regexp_replace(elem->>'doc','^\s*0+','','g')::TEXT AS doc_clean,
      (elem->>'isoDate')::DATE                            AS d,
      elem->>'time'                                       AS time_str,
      NULLIF(elem->>'mode','')                            AS modo
    FROM jsonb_array_elements(COALESCE(p_registros,'[]')) elem
  ),
  -- 2) Vincular a usuarios
  u AS (
    SELECT j.*, u.id_usuario
    FROM j
    LEFT JOIN usuarios u
      ON regexp_replace(u.documento,'^\s*0+','','g') = j.doc_clean
  ),
  -- 3) Documentos faltantes
  miss AS (
    SELECT jsonb_agg(doc_clean) AS missing
    FROM u WHERE id_usuario IS NULL
  ),
  -- 4) TS determinista en TZ del negocio
  parsed AS (
    SELECT
      u.id_usuario,
      u.modo,
      make_timestamptz(
        EXTRACT(YEAR  FROM u.d)::INT,
        EXTRACT(MONTH FROM u.d)::INT,
        EXTRACT(DAY   FROM u.d)::INT,
        split_part(u.time_str,':',1)::INT,
        split_part(u.time_str,':',2)::INT,
        COALESCE(NULLIF(split_part(u.time_str,':',3),''),'0')::INT,
        p_tz
      ) AS ts_calc
    FROM u
    WHERE u.id_usuario IS NOT NULL
  ),
  -- 5) Ventana por usuario (±1 día de lo importado)
  win AS (
    SELECT id_usuario,
           (MIN(ts_calc) - INTERVAL '1 day') AS t0,
           (MAX(ts_calc) + INTERVAL '1 day') AS t1
    FROM parsed
    GROUP BY id_usuario
  ),
  -- 6) Lo existente en BD dentro de la ventana
  existing AS (
    SELECT ar.id_usuario, ar.ts
    FROM asistencia_raw ar
    JOIN win w ON w.id_usuario = ar.id_usuario
              AND ar.ts BETWEEN w.t0 AND w.t1
  ),
  -- 7) CANDIDATE = existente ∪ archivo (sin duplicados)
  candidate AS (
    SELECT id_usuario, ts FROM existing
    UNION                                   -- ¡clave para evitar doble click!
    SELECT id_usuario, ts_calc AS ts FROM parsed
  ),
  -- 8) Paridad previa (cuántas marcas había ANTES de la ventana)
  before_cnt AS (
    SELECT w.id_usuario, COUNT(*)::int AS cnt
    FROM win w
    JOIN asistencia_raw ar
      ON ar.id_usuario = w.id_usuario
     AND ar.ts < w.t0
    GROUP BY w.id_usuario
  ),
  -- 9) Línea de tiempo candidata y pares (1→2, 3→4…), jornada = día local del inicio
  timeline AS (
    SELECT
      c.id_usuario,
      c.ts,
      ROW_NUMBER() OVER (PARTITION BY c.id_usuario ORDER BY c.ts) AS rn
    FROM candidate c
  ),
  ready AS (
    SELECT
      t1.id_usuario,
      (t1.ts AT TIME ZONE p_tz)::date AS fecha,
      t1.ts AS desde,
      t2.ts AS hasta,
      EXTRACT(EPOCH FROM (t2.ts - t1.ts))/60.0 AS dur_min
    FROM timeline t1
    JOIN timeline t2
      ON t2.id_usuario = t1.id_usuario
     AND t2.rn = t1.rn + 1
    LEFT JOIN before_cnt b ON b.id_usuario = t1.id_usuario
    WHERE ((COALESCE(b.cnt,0) + t1.rn) % 2) = 1   -- t1 es IN global
      AND t2.ts > t1.ts
  ),
  -- 10) INSERT crudo (dedupe)
  ins_raw AS (
    INSERT INTO asistencia_raw (id_usuario, ts, modo, origen)
    SELECT id_usuario, ts_calc,
           NULLIF(modo,'')::text,   -- puede quedar NULL para auto-etiquetado
           p_origen
    FROM parsed
    ON CONFLICT (id_usuario, ts) DO NOTHING
    RETURNING 1
  ),
  -- 11) Auto-etiquetar IN/OUT en BD para filas con modo vacío/'1' (tras insertar)
  before_cnt2 AS (
    SELECT w.id_usuario, COUNT(*)::int AS cnt
    FROM win w
    JOIN asistencia_raw ar
      ON ar.id_usuario = w.id_usuario
     AND ar.ts < w.t0
    GROUP BY w.id_usuario
  ),
  tl2 AS (
    SELECT
      ar.id_usuario, ar.ts,
      ROW_NUMBER() OVER (PARTITION BY ar.id_usuario ORDER BY ar.ts) AS rn
    FROM asistencia_raw ar
    JOIN win w ON w.id_usuario = ar.id_usuario
              AND ar.ts BETWEEN w.t0 AND w.t1
  ),
  label2 AS (
    SELECT
      t.id_usuario,
      t.ts,
      CASE WHEN ((COALESCE(b.cnt,0) + t.rn) % 2) = 1 THEN 'IN' ELSE 'OUT' END AS new_mode
    FROM tl2 t
    LEFT JOIN before_cnt2 b ON b.id_usuario = t.id_usuario
  ),
  set_mode AS (
    UPDATE asistencia_raw ar
       SET modo = l.new_mode
      FROM label2 l
     WHERE ar.id_usuario = l.id_usuario
       AND ar.ts         = l.ts
       AND (ar.modo IS NULL OR btrim(ar.modo) = '' OR ar.modo ~ '^\s*1\s*$')
    RETURNING 1
  ),
  -- 12) INSERT pares (dedupe) calculados desde CANDIDATE (ya tiene todo el contexto)
  ins_pairs AS (
    INSERT INTO asistencia_intervalo (id_usuario, fecha, desde, hasta, dur_min, origen)
    SELECT id_usuario, fecha, desde, hasta, dur_min, p_origen
    FROM ready
    ON CONFLICT (id_usuario, desde, hasta) DO NOTHING
    RETURNING 1
  )
  SELECT
    (SELECT COUNT(*) FROM ins_raw),
    (SELECT COUNT(*) FROM ins_pairs),
    (SELECT COALESCE(missing,'[]'::jsonb) FROM miss)
  INTO v_ins_raw, v_ins_pairs, v_miss;

  RETURN jsonb_build_object(
    'inserted_raw',   v_ins_raw,
    'inserted_pairs', v_ins_pairs,
    'missing_docs',   v_miss
  );
END;
$_$;

--
-- Name: report_asistencia(date, date); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION report_asistencia(p_desde date, p_hasta date) RETURNS TABLE(documento text, nombre text, apellido text, fecha date, desde_hora text, hasta_hora text, dur_min numeric)
    LANGUAGE sql
    AS $$
  SELECT
    u.documento, u.nombre, u.apellido,
    ai.fecha,
    to_char(ai.desde AT TIME ZONE 'America/Montevideo','HH24:MI:SS') AS desde_hora,
    to_char(ai.hasta AT TIME ZONE 'America/Montevideo','HH24:MI:SS') AS hasta_hora,
    ai.dur_min
  FROM asistencia_intervalo ai
  JOIN usuarios u USING (id_usuario)
  WHERE ai.fecha BETWEEN p_desde AND p_hasta
  ORDER BY u.documento, ai.fecha, ai.desde;
$$;

--
-- Name: report_gastos(integer); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION report_gastos(p_year integer) RETURNS jsonb
    LANGUAGE sql STABLE
    AS $$
WITH mdata AS (
  SELECT date_trunc('month', c.fec_compra)::date AS m,
         SUM(c.total)::numeric AS importe
  FROM compras c
  WHERE EXTRACT(YEAR FROM c.fec_compra) = p_year
  GROUP BY 1
),
mm AS (
  SELECT EXTRACT(MONTH FROM m)::int AS mes, importe
  FROM mdata
)
SELECT jsonb_build_object(
  'year', p_year,
  'total', COALESCE((SELECT SUM(importe) FROM mdata), 0),
  'avg',   COALESCE((SELECT AVG(importe) FROM mdata), 0),
  'months',
    (SELECT jsonb_agg(
       jsonb_build_object(
         'mes', gs,
         'nombre', to_char(to_date(gs::text,'MM'),'Mon'),
         'importe', COALESCE(mm.importe,0)
       )
       ORDER BY gs
     )
     FROM generate_series(1,12) gs
     LEFT JOIN mm ON mm.mes = gs)
);
$$;

--
-- Name: report_tickets_year(integer, text); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION report_tickets_year(p_year integer, p_tz text DEFAULT 'America/Montevideo'::text) RETURNS jsonb
    LANGUAGE sql STABLE
    AS $$
WITH bounds AS (
  SELECT
    make_timestamp(p_year,   1, 1, 0,0,0)  AS d0,
    make_timestamp(p_year+1, 1, 1, 0,0,0)  AS d1,
    make_timestamptz(p_year,   1, 1, 0,0,0, p_tz) AS t0,
    make_timestamptz(p_year+1, 1, 1, 0,0,0, p_tz) AS t1
),
base AS (
  SELECT
    c.id_comanda,
    CASE WHEN c.fec_cierre IS NOT NULL
         THEN (c.fec_cierre AT TIME ZONE p_tz)
         ELSE c.fec_creacion
    END AS fec_local,
    v.total
  FROM comandas c
  JOIN vw_ticket_total v ON v.id_comanda = c.id_comanda
  JOIN bounds b ON TRUE
  WHERE
    (c.fec_cierre IS NOT NULL AND c.fec_cierre  >= b.t0 AND c.fec_cierre  < b.t1)
    OR
    (c.fec_cierre IS     NULL AND c.fec_creacion >= b.d0 AND c.fec_creacion < b.d1)
),
m AS (
  SELECT
    EXTRACT(MONTH FROM fec_local)::int AS mes,
    COUNT(*)::int                      AS cant,
    SUM(total)::numeric                AS importe,
    AVG(total)::numeric                AS avg
  FROM base
  GROUP BY 1
),
ytd AS (
  SELECT COUNT(*)::int AS total_ytd,
         AVG(total)::numeric AS avg_ticket,
         SUM(total)::numeric AS to_date
  FROM base
)
SELECT jsonb_build_object(
  'year', p_year,
  'total_ytd', (SELECT total_ytd FROM ytd),
  'avg_ticket', (SELECT avg_ticket FROM ytd),
  'to_date',    (SELECT to_date FROM ytd),
  'months',
    (SELECT jsonb_agg(
       jsonb_build_object(
         'mes', mes,
         'nombre', to_char(to_date(mes::text,'MM'),'Mon'),
         'cant', cant,
         'importe', importe,
         'avg', avg
       )
       ORDER BY mes
     )
     FROM m)
);
$$;

--
-- Name: save_compra(integer, integer, timestamp with time zone, jsonb); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION save_compra(p_id_compra integer, p_id_proveedor integer, p_fec_compra timestamp with time zone, p_detalles jsonb) RETURNS TABLE(id_compra integer, total numeric)
    LANGUAGE plpgsql
    AS $$
DECLARE
  v_id    INT;
  v_total numeric := 0;
BEGIN
  IF COALESCE(jsonb_array_length(p_detalles),0) = 0 THEN
    RAISE EXCEPTION 'No hay renglones en la compra';
  END IF;

  -- Cabecera (insert/update)
  IF p_id_compra IS NULL THEN
    INSERT INTO compras (id_proveedor, fec_compra, total)
    VALUES (p_id_proveedor, COALESCE(p_fec_compra, now()), 0)
    RETURNING compras.id_compra INTO v_id;
  ELSE
    UPDATE compras c
       SET id_proveedor = p_id_proveedor,
           fec_compra   = COALESCE(p_fec_compra, c.fec_compra)
     WHERE c.id_compra = p_id_compra
    RETURNING c.id_compra INTO v_id;

    -- Reemplazamos los renglones
    DELETE FROM deta_comp_materias d WHERE d.id_compra = v_id;
    DELETE FROM deta_comp_producto  p WHERE p.id_compra = v_id;
  END IF;

  -- Materias primas (sin CTE: parseo JSON inline)
  INSERT INTO deta_comp_materias (id_compra, id_mat_prima, cantidad, pre_unitario)
  SELECT
    v_id,
    x.id,
    x.cantidad,
    x.precio
  FROM jsonb_to_recordset(COALESCE(p_detalles, '[]'::jsonb))
       AS x(tipo text, id int, cantidad numeric, precio numeric)
  WHERE UPPER(TRIM(x.tipo)) = 'MAT';

  -- Productos (sin CTE)
  INSERT INTO deta_comp_producto (id_compra, id_producto, cantidad, pre_unitario)
  SELECT
    v_id,
    x.id,
    x.cantidad,
    x.precio
  FROM jsonb_to_recordset(COALESCE(p_detalles, '[]'::jsonb))
       AS x(tipo text, id int, cantidad numeric, precio numeric)
  WHERE UPPER(TRIM(x.tipo)) = 'PROD';

  -- Recalcular total (calificado) y redondear a ENTERO
  SELECT
    COALESCE( (SELECT SUM(dcm.cantidad*dcm.pre_unitario)
               FROM deta_comp_materias dcm
               WHERE dcm.id_compra = v_id), 0)
  + COALESCE( (SELECT SUM(dcp.cantidad*dcp.pre_unitario)
               FROM deta_comp_producto dcp
               WHERE dcp.id_compra = v_id), 0)
  INTO v_total;

  UPDATE compras c
     SET total = round(v_total, 0)
   WHERE c.id_compra = v_id;

  RETURN QUERY SELECT v_id, round(v_total, 0);
END;
$$;

--
-- Name: save_materia_prima(integer, text, text, boolean, jsonb); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION save_materia_prima(p_id_mat_prima integer, p_nombre text, p_unidad text, p_activo boolean, p_proveedores jsonb DEFAULT '[]'::jsonb) RETURNS integer
    LANGUAGE plpgsql
    AS $_$
DECLARE
  v_id INT;
BEGIN
  IF p_id_mat_prima IS NULL THEN
    INSERT INTO mate_primas (nombre, unidad, activo)
    VALUES (p_nombre, p_unidad, COALESCE(p_activo, TRUE))
    RETURNING mate_primas.id_mat_prima INTO v_id;
  ELSE
    UPDATE mate_primas mp
       SET nombre = p_nombre,
           unidad = p_unidad,
           activo = COALESCE(p_activo, TRUE)
     WHERE mp.id_mat_prima = p_id_mat_prima;
    v_id := p_id_mat_prima;
  END IF;

  -- Sincronizar proveedores: borrar todos y re-crear a partir de JSONB
  DELETE FROM prov_mate_prima pmp WHERE pmp.id_mat_prima = v_id;

  INSERT INTO prov_mate_prima (id_proveedor, id_mat_prima)
  SELECT (e->>0)::INT    AS id_proveedor,    -- elementos JSON como enteros (array simple)
         v_id            AS id_mat_prima
  FROM jsonb_array_elements(COALESCE(p_proveedores, '[]'::jsonb)) AS e
  WHERE (e->>0) ~ '^\d+$'; -- solo enteros

  RETURN v_id;
END;
$_$;

--
-- Name: save_producto(integer, text, text, numeric, boolean, integer, jsonb); Type: FUNCTION; Schema: public; Owner: manso
--

CREATE FUNCTION save_producto(p_id_producto integer, p_nombre text, p_img_producto text, p_precio numeric, p_activo boolean, p_id_categoria integer, p_receta jsonb DEFAULT '[]'::jsonb) RETURNS integer
    LANGUAGE plpgsql
    AS $_$
DECLARE
  v_id INT;
BEGIN
  IF p_id_producto IS NULL THEN
    INSERT INTO productos (nombre, img_producto, precio, activo, id_categoria)
    VALUES (p_nombre, p_img_producto, p_precio, COALESCE(p_activo, TRUE), p_id_categoria)
    RETURNING productos.id_producto INTO v_id;
  ELSE
    UPDATE productos p
       SET nombre       = p_nombre,
           img_producto = p_img_producto,
           precio       = p_precio,
           activo       = COALESCE(p_activo, TRUE),
           id_categoria = p_id_categoria
     WHERE p.id_producto = p_id_producto;
    v_id := p_id_producto;
  END IF;

  -- Limpia receta actual
  DELETE FROM receta_producto rp WHERE rp.id_producto = v_id;

  -- Inserta SOLO ítems válidos (id entero positivo y cantidad > 0), redondeo a 3 decimales
  INSERT INTO receta_producto (id_producto, id_mat_prima, qty_por_unidad)
  SELECT 
    v_id,
    (rec->>'id_mat_prima')::INT,
    ROUND((rec->>'qty_por_unidad')::NUMERIC, 3)
  FROM jsonb_array_elements(COALESCE(p_receta, '[]'::jsonb)) AS rec
  WHERE
    (rec->>'id_mat_prima') ~ '^\d+$'
    AND (rec->>'id_mat_prima')::INT > 0
    AND (rec->>'qty_por_unidad') ~ '^\d+(\.\d+)?$'
    AND (rec->>'qty_por_unidad')::NUMERIC > 0;

  RETURN v_id;
END;
$_$;

--
-- Name: asistencia_intervalo; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE asistencia_intervalo (
    id_intervalo bigint NOT NULL,
    id_usuario integer NOT NULL,
    fecha date NOT NULL,
    desde timestamp with time zone NOT NULL,
    hasta timestamp with time zone NOT NULL,
    dur_min numeric(10,2) NOT NULL,
    origen text,
    created_at timestamp with time zone DEFAULT now() NOT NULL,
    CONSTRAINT chk_ai_orden CHECK ((hasta > desde))
);

--
-- Name: asistencia_intervalo_id_intervalo_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE asistencia_intervalo_id_intervalo_seq
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: asistencia_intervalo_id_intervalo_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE asistencia_intervalo_id_intervalo_seq OWNED BY asistencia_intervalo.id_intervalo;

--
-- Name: asistencia_raw; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE asistencia_raw (
    id_raw bigint NOT NULL,
    id_usuario integer NOT NULL,
    ts timestamp with time zone NOT NULL,
    modo text,
    origen text,
    created_at timestamp with time zone DEFAULT now() NOT NULL
);

--
-- Name: asistencia_raw_id_raw_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE asistencia_raw_id_raw_seq
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: asistencia_raw_id_raw_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE asistencia_raw_id_raw_seq OWNED BY asistencia_raw.id_raw;

--
-- Name: asistencia_resumen_diario; Type: VIEW; Schema: public; Owner: manso
--

CREATE VIEW asistencia_resumen_diario AS
 SELECT ai.id_usuario,
    u.documento,
    u.nombre,
    u.apellido,
    ai.fecha,
    sum(ai.dur_min) AS minutos_dia,
    round((sum(ai.dur_min) / 60.0), 2) AS horas_dia,
    count(*) AS pares_dia
   FROM (asistencia_intervalo ai
     JOIN usuarios u USING (id_usuario))
  GROUP BY ai.id_usuario, u.documento, u.nombre, u.apellido, ai.fecha
  ORDER BY ai.id_usuario, ai.fecha;

--
-- Name: categorias; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE categorias (
    id_categoria integer NOT NULL,
    nombre text NOT NULL,
    visible boolean DEFAULT true
);

--
-- Name: categorias_id_categoria_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE categorias_id_categoria_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: categorias_id_categoria_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE categorias_id_categoria_seq OWNED BY categorias.id_categoria;

--
-- Name: clientes; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE clientes (
    id_cliente integer NOT NULL,
    nombre text NOT NULL,
    correo text,
    telefono text,
    fec_nacimiento date,
    activo boolean DEFAULT true
);

--
-- Name: clientes_id_cliente_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE clientes_id_cliente_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: clientes_id_cliente_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE clientes_id_cliente_seq OWNED BY clientes.id_cliente;

--
-- Name: comandas_id_comanda_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE comandas_id_comanda_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: comandas_id_comanda_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE comandas_id_comanda_seq OWNED BY comandas.id_comanda;

--
-- Name: compras; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE compras (
    id_compra integer NOT NULL,
    id_proveedor integer NOT NULL,
    fec_compra timestamp without time zone NOT NULL,
    total numeric(14,2)
);

--
-- Name: compras_id_compra_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE compras_id_compra_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: compras_id_compra_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE compras_id_compra_seq OWNED BY compras.id_compra;

--
-- Name: deta_comandas_id_det_comanda_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE deta_comandas_id_det_comanda_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: deta_comandas_id_det_comanda_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE deta_comandas_id_det_comanda_seq OWNED BY deta_comandas.id_det_comanda;

--
-- Name: deta_comp_materias; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE deta_comp_materias (
    id_compra integer NOT NULL,
    id_mat_prima integer NOT NULL,
    cantidad numeric(12,3) NOT NULL,
    pre_unitario numeric(12,2) NOT NULL,
    CONSTRAINT deta_comp_materias_cantidad_check CHECK ((cantidad > (0)::numeric)),
    CONSTRAINT deta_comp_materias_pre_unitario_check CHECK ((pre_unitario >= (0)::numeric))
);

--
-- Name: deta_comp_producto; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE deta_comp_producto (
    id_compra integer NOT NULL,
    id_producto integer NOT NULL,
    cantidad numeric(12,3) NOT NULL,
    pre_unitario numeric(12,2) NOT NULL,
    CONSTRAINT deta_comp_producto_cantidad_check CHECK ((cantidad > (0)::numeric)),
    CONSTRAINT deta_comp_producto_pre_unitario_check CHECK ((pre_unitario >= (0)::numeric))
);

--
-- Name: mate_primas; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE mate_primas (
    id_mat_prima integer NOT NULL,
    nombre text NOT NULL,
    unidad text NOT NULL,
    activo boolean DEFAULT true
);

--
-- Name: mate_primas_id_mat_prima_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE mate_primas_id_mat_prima_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: mate_primas_id_mat_prima_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE mate_primas_id_mat_prima_seq OWNED BY mate_primas.id_mat_prima;

--
-- Name: mesas_id_mesa_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE mesas_id_mesa_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: mesas_id_mesa_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE mesas_id_mesa_seq OWNED BY mesas.id_mesa;

--
-- Name: productos; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE productos (
    id_producto integer NOT NULL,
    nombre text NOT NULL,
    img_producto character varying(255) DEFAULT 'img/productos/img_producto.png'::character varying NOT NULL,
    precio integer NOT NULL,
    activo boolean DEFAULT true,
    id_categoria integer NOT NULL,
    CONSTRAINT productos_precio_check CHECK (((precio)::numeric >= (0)::numeric)),
    CONSTRAINT productos_precio_nn CHECK ((precio >= 0))
);

--
-- Name: productos_id_producto_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE productos_id_producto_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: productos_id_producto_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE productos_id_producto_seq OWNED BY productos.id_producto;

--
-- Name: prov_mate_prima; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE prov_mate_prima (
    id_proveedor integer NOT NULL,
    id_mat_prima integer NOT NULL
);

--
-- Name: prov_producto; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE prov_producto (
    id_proveedor integer NOT NULL,
    id_producto integer NOT NULL
);

--
-- Name: proveedores; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE proveedores (
    id_proveedor integer NOT NULL,
    rut text,
    raz_social text NOT NULL,
    direccion text,
    contacto text
);

--
-- Name: proveedores_id_proveedor_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE proveedores_id_proveedor_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: proveedores_id_proveedor_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE proveedores_id_proveedor_seq OWNED BY proveedores.id_proveedor;

--
-- Name: receta_producto; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE receta_producto (
    id_producto integer NOT NULL,
    id_mat_prima integer NOT NULL,
    qty_por_unidad numeric(12,3) NOT NULL,
    CONSTRAINT receta_producto_qty_por_unidad_check CHECK ((qty_por_unidad > (0)::numeric))
);

--
-- Name: roles; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE roles (
    id_rol integer NOT NULL,
    nombre text NOT NULL
);

--
-- Name: roles_id_rol_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE roles_id_rol_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: roles_id_rol_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE roles_id_rol_seq OWNED BY roles.id_rol;

--
-- Name: usua_roles; Type: TABLE; Schema: public; Owner: manso
--

CREATE TABLE usua_roles (
    id_usuario integer NOT NULL,
    id_rol integer NOT NULL,
    fec_asignacion timestamp without time zone DEFAULT now(),
    autor integer,
    activo boolean DEFAULT true
);

--
-- Name: usuarios_id_usuario_seq; Type: SEQUENCE; Schema: public; Owner: manso
--

CREATE SEQUENCE usuarios_id_usuario_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

--
-- Name: usuarios_id_usuario_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: manso
--

ALTER SEQUENCE usuarios_id_usuario_seq OWNED BY usuarios.id_usuario;

--
-- Name: v_comandas_detalle_base; Type: VIEW; Schema: public; Owner: manso
--

CREATE VIEW v_comandas_detalle_base AS
 SELECT c.id_comanda,
    c.fec_creacion,
    c.fec_cierre,
    c.estado,
    c.observaciones,
    u.id_usuario,
    u.nombre AS usuario_nombre,
    u.apellido AS usuario_apellido,
    m.id_mesa,
    m.numero AS mesa_numero,
    m.apodo AS mesa_apodo,
    d.id_producto,
    p.nombre AS producto_nombre,
    d.cantidad,
    d.pre_unitario,
    (d.cantidad * d.pre_unitario) AS subtotal
   FROM ((((comandas c
     JOIN usuarios u ON ((u.id_usuario = c.id_usuario)))
     JOIN mesas m ON ((m.id_mesa = c.id_mesa)))
     LEFT JOIN deta_comandas d ON ((d.id_comanda = c.id_comanda)))
     LEFT JOIN productos p ON ((p.id_producto = d.id_producto)));

--
-- Name: v_comandas_detalle_items; Type: VIEW; Schema: public; Owner: manso
--

CREATE VIEW v_comandas_detalle_items AS
 SELECT d.id_comanda,
    d.id_det_comanda,
    d.id_producto,
    p.nombre AS producto_nombre,
    d.cantidad,
    d.pre_unitario,
    (d.cantidad * d.pre_unitario) AS subtotal,
    d.observaciones
   FROM (deta_comandas d
     JOIN productos p ON ((p.id_producto = d.id_producto)));

--
-- Name: v_comandas_detalle_json; Type: VIEW; Schema: public; Owner: manso
--

CREATE VIEW v_comandas_detalle_json AS
 SELECT id_comanda,
    jsonb_build_object('id_comanda', id_comanda, 'fec_creacion', fec_creacion, 'fec_cierre', fec_cierre, 'estado', estado, 'observaciones', observaciones, 'usuario', jsonb_build_object('id_usuario', id_usuario, 'nombre', usuario_nombre, 'apellido', usuario_apellido), 'mesa', jsonb_build_object('id_mesa', id_mesa, 'numero', mesa_numero, 'apodo', mesa_apodo), 'items', COALESCE(( SELECT jsonb_agg(jsonb_build_object('producto_id', b.id_producto, 'producto', b.producto_nombre, 'cantidad', b.cantidad, 'pre_unitario', b.pre_unitario, 'subtotal', b.subtotal) ORDER BY b.producto_nombre) AS jsonb_agg
           FROM v_comandas_detalle_base b
          WHERE ((b.id_comanda = h.id_comanda) AND (b.id_producto IS NOT NULL))), '[]'::jsonb), 'totales', jsonb_build_object('items', COALESCE(( SELECT count(*) AS count
           FROM v_comandas_detalle_base b
          WHERE ((b.id_comanda = h.id_comanda) AND (b.id_producto IS NOT NULL))), (0)::bigint), 'total', COALESCE(( SELECT sum(b.subtotal) AS sum
           FROM v_comandas_detalle_base b
          WHERE (b.id_comanda = h.id_comanda)), (0)::numeric))) AS data
   FROM ( SELECT DISTINCT v_comandas_detalle_base.id_comanda,
            v_comandas_detalle_base.fec_creacion,
            v_comandas_detalle_base.fec_cierre,
            v_comandas_detalle_base.estado,
            v_comandas_detalle_base.observaciones,
            v_comandas_detalle_base.id_usuario,
            v_comandas_detalle_base.usuario_nombre,
            v_comandas_detalle_base.usuario_apellido,
            v_comandas_detalle_base.id_mesa,
            v_comandas_detalle_base.mesa_numero,
            v_comandas_detalle_base.mesa_apodo
           FROM v_comandas_detalle_base) h;

--
-- Name: vw_compras; Type: VIEW; Schema: public; Owner: manso
--

CREATE VIEW vw_compras AS
 SELECT c.id_compra,
    c.id_proveedor,
    p.raz_social AS proveedor,
    c.fec_compra,
    c.total
   FROM (compras c
     JOIN proveedores p USING (id_proveedor))
  ORDER BY c.fec_compra DESC, c.id_compra DESC;

--
-- Name: vw_ticket_total; Type: VIEW; Schema: public; Owner: manso
--

CREATE VIEW vw_ticket_total AS
 WITH lineas AS (
         SELECT c.id_comanda,
            COALESCE(c.fec_cierre, (c.fec_creacion)::timestamp with time zone) AS fec_ticket,
            (COALESCE(dc.pre_unitario, (p.precio)::numeric, (0)::numeric))::numeric(14,2) AS pu,
            (COALESCE(dc.cantidad, (1)::numeric))::numeric(14,3) AS qty
           FROM ((comandas c
             JOIN deta_comandas dc ON ((dc.id_comanda = c.id_comanda)))
             LEFT JOIN productos p ON ((p.id_producto = dc.id_producto)))
        )
 SELECT id_comanda,
    fec_ticket,
    (sum((qty * pu)))::numeric(14,2) AS total
   FROM lineas
  GROUP BY id_comanda, fec_ticket;

--
-- Name: asistencia_intervalo id_intervalo; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY asistencia_intervalo ALTER COLUMN id_intervalo SET DEFAULT nextval('asistencia_intervalo_id_intervalo_seq'::regclass);

--
-- Name: asistencia_raw id_raw; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY asistencia_raw ALTER COLUMN id_raw SET DEFAULT nextval('asistencia_raw_id_raw_seq'::regclass);

--
-- Name: categorias id_categoria; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY categorias ALTER COLUMN id_categoria SET DEFAULT nextval('categorias_id_categoria_seq'::regclass);

--
-- Name: clientes id_cliente; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY clientes ALTER COLUMN id_cliente SET DEFAULT nextval('clientes_id_cliente_seq'::regclass);

--
-- Name: comandas id_comanda; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY comandas ALTER COLUMN id_comanda SET DEFAULT nextval('comandas_id_comanda_seq'::regclass);

--
-- Name: compras id_compra; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY compras ALTER COLUMN id_compra SET DEFAULT nextval('compras_id_compra_seq'::regclass);

--
-- Name: deta_comandas id_det_comanda; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comandas ALTER COLUMN id_det_comanda SET DEFAULT nextval('deta_comandas_id_det_comanda_seq'::regclass);

--
-- Name: mate_primas id_mat_prima; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY mate_primas ALTER COLUMN id_mat_prima SET DEFAULT nextval('mate_primas_id_mat_prima_seq'::regclass);

--
-- Name: mesas id_mesa; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY mesas ALTER COLUMN id_mesa SET DEFAULT nextval('mesas_id_mesa_seq'::regclass);

--
-- Name: productos id_producto; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY productos ALTER COLUMN id_producto SET DEFAULT nextval('productos_id_producto_seq'::regclass);

--
-- Name: proveedores id_proveedor; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY proveedores ALTER COLUMN id_proveedor SET DEFAULT nextval('proveedores_id_proveedor_seq'::regclass);

--
-- Name: roles id_rol; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY roles ALTER COLUMN id_rol SET DEFAULT nextval('roles_id_rol_seq'::regclass);

--
-- Name: usuarios id_usuario; Type: DEFAULT; Schema: public; Owner: manso
--

ALTER TABLE ONLY usuarios ALTER COLUMN id_usuario SET DEFAULT nextval('usuarios_id_usuario_seq'::regclass);

--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
--
-- Name: asistencia_intervalo_id_intervalo_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('asistencia_intervalo_id_intervalo_seq', 108, true);

--
-- Name: asistencia_raw_id_raw_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('asistencia_raw_id_raw_seq', 88, true);

--
-- Name: categorias_id_categoria_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('categorias_id_categoria_seq', 4, true);

--
-- Name: clientes_id_cliente_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('clientes_id_cliente_seq', 1, true);

--
-- Name: comandas_id_comanda_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('comandas_id_comanda_seq', 55, true);

--
-- Name: compras_id_compra_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('compras_id_compra_seq', 66, true);

--
-- Name: deta_comandas_id_det_comanda_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('deta_comandas_id_det_comanda_seq', 117, true);

--
-- Name: mate_primas_id_mat_prima_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('mate_primas_id_mat_prima_seq', 10, true);

--
-- Name: mesas_id_mesa_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('mesas_id_mesa_seq', 14, true);

--
-- Name: productos_id_producto_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('productos_id_producto_seq', 52, true);

--
-- Name: proveedores_id_proveedor_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('proveedores_id_proveedor_seq', 4, true);

--
-- Name: roles_id_rol_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('roles_id_rol_seq', 6, true);

--
-- Name: usuarios_id_usuario_seq; Type: SEQUENCE SET; Schema: public; Owner: manso
--

SELECT pg_catalog.setval('usuarios_id_usuario_seq', 3, true);

--
-- Name: asistencia_intervalo asistencia_intervalo_id_usuario_desde_hasta_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY asistencia_intervalo
    ADD CONSTRAINT asistencia_intervalo_id_usuario_desde_hasta_key UNIQUE (id_usuario, desde, hasta);

--
-- Name: asistencia_intervalo asistencia_intervalo_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY asistencia_intervalo
    ADD CONSTRAINT asistencia_intervalo_pkey PRIMARY KEY (id_intervalo);

--
-- Name: asistencia_raw asistencia_raw_id_usuario_ts_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY asistencia_raw
    ADD CONSTRAINT asistencia_raw_id_usuario_ts_key UNIQUE (id_usuario, ts);

--
-- Name: asistencia_raw asistencia_raw_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY asistencia_raw
    ADD CONSTRAINT asistencia_raw_pkey PRIMARY KEY (id_raw);

--
-- Name: categorias categorias_nombre_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY categorias
    ADD CONSTRAINT categorias_nombre_key UNIQUE (nombre);

--
-- Name: categorias categorias_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY categorias
    ADD CONSTRAINT categorias_pkey PRIMARY KEY (id_categoria);

--
-- Name: clientes clientes_correo_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY clientes
    ADD CONSTRAINT clientes_correo_key UNIQUE (correo);

--
-- Name: clientes clientes_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY clientes
    ADD CONSTRAINT clientes_pkey PRIMARY KEY (id_cliente);

--
-- Name: clientes clientes_telefono_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY clientes
    ADD CONSTRAINT clientes_telefono_key UNIQUE (telefono);

--
-- Name: comandas comandas_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY comandas
    ADD CONSTRAINT comandas_pkey PRIMARY KEY (id_comanda);

--
-- Name: compras compras_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY compras
    ADD CONSTRAINT compras_pkey PRIMARY KEY (id_compra);

--
-- Name: deta_comandas deta_comandas_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comandas
    ADD CONSTRAINT deta_comandas_pkey PRIMARY KEY (id_det_comanda);

--
-- Name: deta_comp_materias deta_comp_materias_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comp_materias
    ADD CONSTRAINT deta_comp_materias_pkey PRIMARY KEY (id_compra, id_mat_prima);

--
-- Name: deta_comp_producto deta_comp_producto_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comp_producto
    ADD CONSTRAINT deta_comp_producto_pkey PRIMARY KEY (id_compra, id_producto);

--
-- Name: mate_primas mate_primas_nombre_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY mate_primas
    ADD CONSTRAINT mate_primas_nombre_key UNIQUE (nombre);

--
-- Name: mate_primas mate_primas_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY mate_primas
    ADD CONSTRAINT mate_primas_pkey PRIMARY KEY (id_mat_prima);

--
-- Name: mesas mesas_apodo_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY mesas
    ADD CONSTRAINT mesas_apodo_key UNIQUE (apodo);

--
-- Name: mesas mesas_numero_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY mesas
    ADD CONSTRAINT mesas_numero_key UNIQUE (numero);

--
-- Name: mesas mesas_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY mesas
    ADD CONSTRAINT mesas_pkey PRIMARY KEY (id_mesa);

--
-- Name: productos productos_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY productos
    ADD CONSTRAINT productos_pkey PRIMARY KEY (id_producto);

--
-- Name: prov_mate_prima prov_mate_prima_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY prov_mate_prima
    ADD CONSTRAINT prov_mate_prima_pkey PRIMARY KEY (id_proveedor, id_mat_prima);

--
-- Name: prov_producto prov_producto_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY prov_producto
    ADD CONSTRAINT prov_producto_pkey PRIMARY KEY (id_proveedor, id_producto);

--
-- Name: proveedores proveedores_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY proveedores
    ADD CONSTRAINT proveedores_pkey PRIMARY KEY (id_proveedor);

--
-- Name: proveedores proveedores_rut_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY proveedores
    ADD CONSTRAINT proveedores_rut_key UNIQUE (rut);

--
-- Name: receta_producto receta_producto_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY receta_producto
    ADD CONSTRAINT receta_producto_pkey PRIMARY KEY (id_producto, id_mat_prima);

--
-- Name: roles roles_nombre_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY roles
    ADD CONSTRAINT roles_nombre_key UNIQUE (nombre);

--
-- Name: roles roles_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY roles
    ADD CONSTRAINT roles_pkey PRIMARY KEY (id_rol);

--
-- Name: usua_roles usua_roles_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY usua_roles
    ADD CONSTRAINT usua_roles_pkey PRIMARY KEY (id_usuario, id_rol);

--
-- Name: usuarios usuarios_documento_key; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY usuarios
    ADD CONSTRAINT usuarios_documento_key UNIQUE (documento);

--
-- Name: usuarios usuarios_pkey; Type: CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY usuarios
    ADD CONSTRAINT usuarios_pkey PRIMARY KEY (id_usuario);

--
-- Name: compras_fec_compra_idx; Type: INDEX; Schema: public; Owner: manso
--

CREATE INDEX compras_fec_compra_idx ON compras USING btree (fec_compra);

--
-- Name: idx_asist_int_usuario_fecha; Type: INDEX; Schema: public; Owner: manso
--

CREATE INDEX idx_asist_int_usuario_fecha ON asistencia_intervalo USING btree (id_usuario, fecha);

--
-- Name: idx_asist_raw_usuario_ts; Type: INDEX; Schema: public; Owner: manso
--

CREATE INDEX idx_asist_raw_usuario_ts ON asistencia_raw USING btree (id_usuario, ts);

--
-- Name: idx_detalle_comanda_comanda; Type: INDEX; Schema: public; Owner: manso
--

CREATE INDEX idx_detalle_comanda_comanda ON deta_comandas USING btree (id_comanda);

--
-- Name: idx_detalle_comanda_producto; Type: INDEX; Schema: public; Owner: manso
--

CREATE INDEX idx_detalle_comanda_producto ON deta_comandas USING btree (id_producto);

--
-- Name: ix_comandas_fec_cierre; Type: INDEX; Schema: public; Owner: manso
--

CREATE INDEX ix_comandas_fec_cierre ON comandas USING btree (fec_cierre);

--
-- Name: ix_comandas_id; Type: INDEX; Schema: public; Owner: manso
--

CREATE INDEX ix_comandas_id ON comandas USING btree (id_comanda);

--
-- Name: ix_deta_comandas_id_comanda; Type: INDEX; Schema: public; Owner: manso
--

CREATE INDEX ix_deta_comandas_id_comanda ON deta_comandas USING btree (id_comanda);

--
-- Name: ix_deta_comandas_id_producto; Type: INDEX; Schema: public; Owner: manso
--

CREATE INDEX ix_deta_comandas_id_producto ON deta_comandas USING btree (id_producto);

--
-- Name: asistencia_intervalo asistencia_intervalo_id_usuario_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY asistencia_intervalo
    ADD CONSTRAINT asistencia_intervalo_id_usuario_fkey FOREIGN KEY (id_usuario) REFERENCES usuarios(id_usuario) ON DELETE CASCADE;

--
-- Name: asistencia_raw asistencia_raw_id_usuario_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY asistencia_raw
    ADD CONSTRAINT asistencia_raw_id_usuario_fkey FOREIGN KEY (id_usuario) REFERENCES usuarios(id_usuario) ON DELETE CASCADE;

--
-- Name: comandas comandas_id_mesa_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY comandas
    ADD CONSTRAINT comandas_id_mesa_fkey FOREIGN KEY (id_mesa) REFERENCES mesas(id_mesa);

--
-- Name: comandas comandas_id_usuario_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY comandas
    ADD CONSTRAINT comandas_id_usuario_fkey FOREIGN KEY (id_usuario) REFERENCES usuarios(id_usuario);

--
-- Name: compras compras_id_proveedor_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY compras
    ADD CONSTRAINT compras_id_proveedor_fkey FOREIGN KEY (id_proveedor) REFERENCES proveedores(id_proveedor);

--
-- Name: deta_comandas deta_comandas_id_comanda_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comandas
    ADD CONSTRAINT deta_comandas_id_comanda_fkey FOREIGN KEY (id_comanda) REFERENCES comandas(id_comanda) ON DELETE CASCADE;

--
-- Name: deta_comandas deta_comandas_id_producto_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comandas
    ADD CONSTRAINT deta_comandas_id_producto_fkey FOREIGN KEY (id_producto) REFERENCES productos(id_producto);

--
-- Name: deta_comp_materias deta_comp_materias_id_compra_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comp_materias
    ADD CONSTRAINT deta_comp_materias_id_compra_fkey FOREIGN KEY (id_compra) REFERENCES compras(id_compra) ON DELETE CASCADE;

--
-- Name: deta_comp_materias deta_comp_materias_id_mat_prima_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comp_materias
    ADD CONSTRAINT deta_comp_materias_id_mat_prima_fkey FOREIGN KEY (id_mat_prima) REFERENCES mate_primas(id_mat_prima);

--
-- Name: deta_comp_producto deta_comp_producto_id_compra_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comp_producto
    ADD CONSTRAINT deta_comp_producto_id_compra_fkey FOREIGN KEY (id_compra) REFERENCES compras(id_compra) ON DELETE CASCADE;

--
-- Name: deta_comp_producto deta_comp_producto_id_producto_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY deta_comp_producto
    ADD CONSTRAINT deta_comp_producto_id_producto_fkey FOREIGN KEY (id_producto) REFERENCES productos(id_producto);

--
-- Name: productos productos_id_categoria_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY productos
    ADD CONSTRAINT productos_id_categoria_fkey FOREIGN KEY (id_categoria) REFERENCES categorias(id_categoria);

--
-- Name: prov_mate_prima prov_mate_prima_id_mat_prima_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY prov_mate_prima
    ADD CONSTRAINT prov_mate_prima_id_mat_prima_fkey FOREIGN KEY (id_mat_prima) REFERENCES mate_primas(id_mat_prima);

--
-- Name: prov_mate_prima prov_mate_prima_id_proveedor_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY prov_mate_prima
    ADD CONSTRAINT prov_mate_prima_id_proveedor_fkey FOREIGN KEY (id_proveedor) REFERENCES proveedores(id_proveedor) ON DELETE CASCADE;

--
-- Name: prov_producto prov_producto_id_producto_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY prov_producto
    ADD CONSTRAINT prov_producto_id_producto_fkey FOREIGN KEY (id_producto) REFERENCES productos(id_producto);

--
-- Name: prov_producto prov_producto_id_proveedor_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY prov_producto
    ADD CONSTRAINT prov_producto_id_proveedor_fkey FOREIGN KEY (id_proveedor) REFERENCES proveedores(id_proveedor) ON DELETE CASCADE;

--
-- Name: receta_producto receta_producto_id_mat_prima_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY receta_producto
    ADD CONSTRAINT receta_producto_id_mat_prima_fkey FOREIGN KEY (id_mat_prima) REFERENCES mate_primas(id_mat_prima);

--
-- Name: receta_producto receta_producto_id_producto_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY receta_producto
    ADD CONSTRAINT receta_producto_id_producto_fkey FOREIGN KEY (id_producto) REFERENCES productos(id_producto) ON DELETE CASCADE;

--
-- Name: usua_roles usua_roles_autor_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY usua_roles
    ADD CONSTRAINT usua_roles_autor_fkey FOREIGN KEY (autor) REFERENCES usuarios(id_usuario);

--
-- Name: usua_roles usua_roles_id_rol_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY usua_roles
    ADD CONSTRAINT usua_roles_id_rol_fkey FOREIGN KEY (id_rol) REFERENCES roles(id_rol);

--
-- Name: usua_roles usua_roles_id_usuario_fkey; Type: FK CONSTRAINT; Schema: public; Owner: manso
--

ALTER TABLE ONLY usua_roles
    ADD CONSTRAINT usua_roles_id_usuario_fkey FOREIGN KEY (id_usuario) REFERENCES usuarios(id_usuario) ON DELETE CASCADE;

--
-- PostgreSQL database dump complete
--

\unrestrict londHmqT4llS8Wof4ZnceO2dyFhn4jiR5xbaszMgZpMczgr6aVW6xQJxeUdqJwa


COMMIT;
