/******************************************************************************/
/****      Generated by IBExpert 2007.07.20 04/11/2007 11:01:09 a.m.       ****/
/******************************************************************************/

SET SQL DIALECT 3;

SET NAMES NONE;

CREATE DATABASE 'ubandres:sgme'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE 1024
DEFAULT CHARACTER SET NONE;



/******************************************************************************/
/****                               Domains                                ****/
/******************************************************************************/

CREATE DOMAIN D_BOOL AS
CHAR(1)
default 'F'
NOT NULL
check(value in ('T', 'F'));

CREATE DOMAIN D_DESCRIPICION AS
VARCHAR(255)
NOT NULL;

CREATE DOMAIN D_ELIMINADO AS
INTEGER
default 0
NOT NULL;

CREATE DOMAIN D_FECHA AS
TIMESTAMP
DEFAULT 'NOW'
NOT NULL;

CREATE DOMAIN D_ID AS
INTEGER;

CREATE DOMAIN D_NOMBRE AS
VARCHAR(20)
NOT NULL;

CREATE DOMAIN D_TIPO_ATRIB AS
CHAR(1)
default 'C'
NOT NULL
CHECK (value in ('T', 'B', 'C', 'M', 'F', 'I'));

CREATE DOMAIN D_TIPO_CAMBIO AS
CHAR(1)
DEFAULT 'I'
NOT NULL
CHECK (value in ('I'));

CREATE DOMAIN D_TIPO_CAMBIO_PARTE AS
CHAR(1)
NOT NULL
CHECK (VALUE IN ('+','-'));

CREATE DOMAIN D_TIPO_OPERACION AS
CHAR(1)
DEFAULT 'I'
NOT NULL
CHECK (value in ('I','A','B','C','D'));

CREATE DOMAIN D_USER_NAME AS
VARCHAR(128)
NOT NULL;

CREATE DOMAIN D_VALOR_ATRIB AS
VARCHAR(255)
default 'C0'
NOT NULL
CHECK (value starting with 'T'
or value starting with 'B'      
or value starting with 'C'     
or value starting with 'M'     
or value starting with 'F'
or value starting with 'I');



/******************************************************************************/
/****                              Generators                              ****/
/******************************************************************************/

CREATE GENERATOR GEN_TO_ARTICULOS_ID;
SET GENERATOR GEN_TO_ARTICULOS_ID TO 690;

CREATE GENERATOR GEN_TO_CAMBIO_ID;
SET GENERATOR GEN_TO_CAMBIO_ID TO 4083;

CREATE GENERATOR GEN_TO_INFORMES_ID;
SET GENERATOR GEN_TO_INFORMES_ID TO 181;

CREATE GENERATOR GEN_TO_OPERACIONES_ID;
SET GENERATOR GEN_TO_OPERACIONES_ID TO 831;

CREATE GENERATOR GEN_TO_SUCESOS_ID;
SET GENERATOR GEN_TO_SUCESOS_ID TO 425;

CREATE GENERATOR GEN_TP_ARTICULOS_ID;
SET GENERATOR GEN_TP_ARTICULOS_ID TO 1038;

CREATE GENERATOR GEN_TP_ATRIBUTOS_ID;
SET GENERATOR GEN_TP_ATRIBUTOS_ID TO 1023;

CREATE GENERATOR GEN_TP_PARTES_ID;
SET GENERATOR GEN_TP_PARTES_ID TO 1043;



/******************************************************************************/
/****                              Exceptions                              ****/
/******************************************************************************/

CREATE EXCEPTION EX_ADMINCLAVES_NO 'AdminClaves no puede realizar otras tareas que administrar usuarios';

CREATE EXCEPTION EX_CLASE_ID_DESCONOCIDA 'Error al intentar obtener el ID, no se reconoce el tipo';

CREATE EXCEPTION EX_CONTE_Y_UBI 'Un articulo no puede ser a la vez ubicable y contenible.';

CREATE EXCEPTION EX_CONTI_CONTE_INVALIDOS 'Las especificaciones indicadas como continente o contenible no corresponden.';

CREATE EXCEPTION EX_CONTI_Y_CONTE 'Una articulo no puede ser continente y contenible.';

CREATE EXCEPTION EX_CONTI_Y_NOUBI 'Una articulo no puede ser continente y no ubicable.';

CREATE EXCEPTION EX_NO_ENCONTRADO 'No se encontro el objeto correspondiente a ese nombre.';

CREATE EXCEPTION EX_TRANSICION_INVALIDA 'La transicion de estados que se intenta realizar no es valida';



SET TERM ^ ; 



/******************************************************************************/
/****                          Stored Procedures                           ****/
/******************************************************************************/

CREATE PROCEDURE SPC_ADD_PARTE_ART (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    ID_CONTIENTE INTEGER,
    NB_PARTE VARCHAR(20),
    ID_CONTENIBLE INTEGER)
RETURNS (
    ID_OPERACION_O INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPC_EDT_ATRIB_ART (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    ID_ARTICULO INTEGER,
    NB_ATRIBUTO VARCHAR(20),
    VALOR_ANTERIOR VARCHAR(255),
    VALOR_NUEVO VARCHAR(255))
RETURNS (
    ID_OPERACION_O INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPC_NEW_ARTICULOS (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    NBP_ARTICULO VARCHAR(20),
    CANTIDAD INTEGER,
    ID INTEGER)
RETURNS (
    ID_ARTICULO INTEGER,
    ID_OPERACION_O INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPC_REM_PARTES_ART_1 (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    ID_CONTENIBLE INTEGER)
RETURNS (
    ID_OPERACION_O INTEGER,
    ID_CONTINENTE INTEGER,
    ID_PARTE INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPC_REM_PARTES_ART_2 (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    ID_CONTINENTE INTEGER,
    NB_PARTE VARCHAR(20))
RETURNS (
    ID_OPERACION_O INTEGER,
    ID_CONTENIBLE INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPE_GET_CONTENIDO_CONTE (
    FECHA TIMESTAMP,
    ID_CONTENIBLE INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    VALOR CHAR(1),
    ID_CONTINENTE INTEGER,
    ID_PARTE INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPE_GET_DISP_PARTE_CONTI (
    FECHA TIMESTAMP,
    ID_CONTINENTE INTEGER,
    ID_PARTE INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    TIPO_CAMBIO CHAR(1))
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPE_GET_VALOR_ATRIB_ART (
    FECHA TIMESTAMP,
    ID_ARTICULO INTEGER,
    ID_ATRIBUTO INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    VALOR VARCHAR(255))
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPE_LST_CONTE_PARTE_CONTI (
    FECHA TIMESTAMP,
    ID_CONTINENTE INTEGER,
    ID_PARTE INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    ID_CONTENIBLE INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPE_LST_DISP_PARTE_CONTI (
    FECHA TIMESTAMP,
    ID_CONTINENTE INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    ID_PARTE INTEGER,
    MULTIPLE CHAR(1))
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPE_LST_ID_ARTICULOS (
    FECHA TIMESTAMP)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    ID_ARTICULO INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPE_LST_VALORES_ATRIB_ART (
    FECHA TIMESTAMP)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    ID_ARTICULO INTEGER,
    ID_ATRIBUTO INTEGER,
    VALOR VARCHAR(255))
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPI_SEL_OPERACION (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    TIPO_OPERACION CHAR(1))
RETURNS (
    ID_OPERACION_O INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPO_NEW_INFORME (
    FECHA_RECEPCION TIMESTAMP,
    DESCRIPCION VARCHAR(255))
RETURNS (
    ID_INFORME INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPO_NEW_SUCESO (
    ID_INFORME INTEGER,
    FECHA_SUCESO TIMESTAMP,
    DESCRIPCION VARCHAR(255))
RETURNS (
    ID_SUCESO INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPP_DEL_ARTICULO (
    NBP_ARTICULO VARCHAR(20))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPP_DEL_ATRIB_ART (
    NB_ATRIBUTO VARCHAR(20),
    NBP_ARTICULO VARCHAR(20))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPP_DEL_ATRIBUTO (
    NB_ATRIBUTO VARCHAR(20))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPP_DEL_PARTE (
    NB_PARTE VARCHAR(20),
    NBP_CONTINENTE VARCHAR(20))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPP_EDT_ATRIB_ART (
    NB_ATRIBUTO VARCHAR(20),
    NBP_ARTICULO VARCHAR(20),
    DEFECTO VARCHAR(255))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPP_EDT_ATRIBUTO (
    NB_ATRIBUTO_ACTUAL VARCHAR(20),
    NB_ATRIBUTO_NUEVO VARCHAR(20),
    DEFECTONUEVO VARCHAR(255))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPP_LST_ARTICULOS (
    FESPECIFICACION VARCHAR(20),
    FUBICABLE CHAR(1),
    FCONTENIBLE CHAR(1),
    FCONTINENTE CHAR(1))
RETURNS (
    IDP_ARTICULO INTEGER,
    NBP_ARTICULO VARCHAR(20),
    UBICABLE CHAR(1),
    CONTENIBLE CHAR(1),
    CONTINENTE CHAR(1))
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPP_LST_ATRIB_ART (
    ESPECIFICACION VARCHAR(20))
RETURNS (
    NBP_ARTICULO VARCHAR(20),
    NB_ATRIBUTO VARCHAR(20),
    TIPO CHAR(1),
    DEFECTO VARCHAR(255))
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPP_LST_ATRIBUTOS (
    FATRIBUTOPOS VARCHAR(20),
    FTIPO CHAR(1))
RETURNS (
    ID_ATRIBUTO INTEGER,
    NB_ATRIBUTO VARCHAR(20),
    TIPO CHAR(1),
    DEFECTO VARCHAR(255))
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPP_LST_PARTES (
    NCONTINENTE VARCHAR(20))
RETURNS (
    NB_PARTE VARCHAR(20),
    MULTIPLE CHAR(1),
    NBP_CONTINENTE VARCHAR(20),
    NBP_CONTENIBLE VARCHAR(20))
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPP_NEW_ARTICULO (
    NBP_ARTICULO VARCHAR(20),
    UBICABLE CHAR(1),
    CONTENIBLE CHAR(1),
    CONTINENTE CHAR(1))
RETURNS (
    IDP_ARTICULO INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPP_NEW_ATRIB_ART (
    NB_ATRIBUTO VARCHAR(20),
    NBP_ARTICULO VARCHAR(20),
    DEFECTO VARCHAR(255))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPP_NEW_ATRIBUTO (
    NB_ATRIBUTO VARCHAR(20),
    TIPO CHAR(1),
    DEFECTO VARCHAR(255))
RETURNS (
    IDATRIBUTO INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPP_NEW_PARTE (
    NB_PARTE VARCHAR(20),
    MULTIPLE CHAR(1),
    NBP_CONTINENTE VARCHAR(20),
    NBP_CONTENIBLE VARCHAR(20))
RETURNS (
    ID_PARTE INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPP_REN_ARTICULO (
    NBP_ARTICULO_ACTUAL VARCHAR(20),
    NBP_ARTICULO_NUEVO VARCHAR(20))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPP_REN_PARTE (
    NB_PARTE VARCHAR(20),
    NBP_CONTINENTE VARCHAR(20),
    NB_PARTE_NUEVO VARCHAR(20))
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPS_GET_ID (
    NOMBRE VARCHAR(20),
    CLASE VARCHAR(20))
RETURNS (
    ID INTEGER)
AS
BEGIN
  SUSPEND;
END^


CREATE PROCEDURE SPS_VRF_ADMINCLAVES
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPS_VRF_ROL_CONFIGURADOR
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SPS_VRF_ROL_USUARIO
AS
BEGIN
  EXIT;
END^


CREATE PROCEDURE SZ_LIMPIAR_CAMBIOS
AS
BEGIN
  EXIT;
END^



SET TERM ; ^


/******************************************************************************/
/****                                Tables                                ****/
/******************************************************************************/



CREATE TABLE TC_ATRIB_ART (
    ID_CAMBIO       D_ID NOT NULL,
    ID_ATRIBUTO     D_ID NOT NULL,
    ID_ARTICULO     D_ID NOT NULL,
    VALOR_ANTERIOR  D_VALOR_ATRIB DEFAULT 'I',
    VALOR_NUEVO     D_VALOR_ATRIB,
    ID_OPERACION    D_ID NOT NULL,
    FECHA_SUCESO    TIMESTAMP NOT NULL,
    ELIMINADO       D_ELIMINADO
);


CREATE TABLE TC_PARTE_ART (
    ID_CAMBIO      D_ID NOT NULL,
    ID_PARTE       D_ID NOT NULL,
    ID_CONTINENTE  D_ID NOT NULL,
    TIPO           D_TIPO_CAMBIO_PARTE,
    ID_CONTENIBLE  D_ID NOT NULL,
    ID_OPERACION   D_ID NOT NULL,
    FECHA_SUCESO   TIMESTAMP NOT NULL,
    ELIMINADO      D_ELIMINADO
);


CREATE TABLE TO_ARTICULOS (
    ID_ARTICULO            D_ID NOT NULL,
    IDP_ARTICULO           D_ID NOT NULL,
    CREACION_ID_CAMBIO     D_ID NOT NULL,
    CREACION_ID_OPERACION  D_ID NOT NULL,
    CREACION_FECHA_SUCESO  D_FECHA NOT NULL,
    CREACION_ELIMINADO     D_ELIMINADO
);


CREATE TABLE TO_INFORMES (
    ID_INFORME       D_ID NOT NULL,
    FECHA_RECEPCION  D_FECHA,
    FECHA_CARGA      D_FECHA DEFAULT CURRENT_TIMESTAMP,
    DESCRIPCION      D_DESCRIPICION,
    USER_NAME        D_USER_NAME DEFAULT CURRENT_USER,
    ELIMINADO        D_ELIMINADO
);


CREATE TABLE TO_OPERACIONES (
    ID_OPERACION  D_ID NOT NULL,
    ID_SUCESO     D_ID NOT NULL,
    TIPO          D_TIPO_OPERACION,
    ELIMINADO     D_ELIMINADO
);


CREATE TABLE TO_SUCESOS (
    ID_SUCESO     D_ID NOT NULL,
    ID_INFORME    D_ID NOT NULL,
    FECHA_SUCESO  D_FECHA,
    DESCRIPCION   D_DESCRIPICION,
    ELIMINADO     D_ELIMINADO
);


CREATE TABLE TP_ARTICULOS (
    IDP_ARTICULO  D_ID NOT NULL,
    NBP_ARTICULO  D_NOMBRE NOT NULL,
    UBICABLE      D_BOOL,
    CONTENIBLE    D_BOOL,
    CONTINENTE    D_BOOL,
    ELIMINADO     D_ELIMINADO
);


CREATE TABLE TP_ATRIB_ART (
    IDP_ARTICULO  D_ID NOT NULL,
    ID_ATRIBUTO   D_ID NOT NULL,
    DEFECTO       D_VALOR_ATRIB
);


CREATE TABLE TP_ATRIBUTOS (
    ID_ATRIBUTO  D_ID NOT NULL,
    NB_ATRIBUTO  D_NOMBRE NOT NULL,
    TIPO         D_TIPO_ATRIB,
    ELIMINADO    D_ELIMINADO,
    DEFECTO      D_VALOR_ATRIB
);


CREATE TABLE TP_PARTES (
    ID_PARTE        D_ID NOT NULL,
    NB_PARTE        D_NOMBRE,
    MULTIPLE        D_BOOL default 'F' NOT NULL,
    IDP_CONTINENTE  D_ID NOT NULL,
    IDP_CONTENIBLE  D_ID,
    ELIMINADO       D_ELIMINADO
);


INSERT INTO TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, UBICABLE, CONTENIBLE, CONTINENTE, ELIMINADO) VALUES (1020, 'CPUINTERNET', 'T', 'F', 'T', 0);
INSERT INTO TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, UBICABLE, CONTENIBLE, CONTINENTE, ELIMINADO) VALUES (1021, 'MONITOR', 'T', 'F', 'F', 0);
INSERT INTO TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, UBICABLE, CONTENIBLE, CONTINENTE, ELIMINADO) VALUES (1023, 'MEMORIA', 'F', 'T', 'F', 0);
INSERT INTO TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, UBICABLE, CONTENIBLE, CONTINENTE, ELIMINADO) VALUES (1033, 'IMPRESORA', 'T', 'F', 'F', 0);
INSERT INTO TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, UBICABLE, CONTENIBLE, CONTINENTE, ELIMINADO) VALUES (1034, 'PLACA VIDEO', 'F', 'T', 'F', 0);
INSERT INTO TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, UBICABLE, CONTENIBLE, CONTINENTE, ELIMINADO) VALUES (1038, 'borrara', 'T', 'F', 'T', 1038);
INSERT INTO TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, UBICABLE, CONTENIBLE, CONTINENTE, ELIMINADO) VALUES (1029, 'MICRO', 'F', 'T', 'F', 0);
INSERT INTO TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, UBICABLE, CONTENIBLE, CONTINENTE, ELIMINADO) VALUES (1030, 'DISCO_RIGIDO', 'F', 'T', 'F', 0);
INSERT INTO TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, UBICABLE, CONTENIBLE, CONTINENTE, ELIMINADO) VALUES (1031, 'CPUJUEGOS', 'T', 'F', 'T', 0);

COMMIT WORK;

INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1, 'CONTENIDO', 'B', 1, 'BF');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1015, 'FEO', 'B', 1015, 'BF');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1016, 'SERIENRO', 'T', 0, 'T00000');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1010, 'FUNCIONANDO', 'B', 0, 'BT');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1011, '*DUDOSO', 'B', 1011, 'BF');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1012, 'COLOR', 'T', 0, 'TBLANCO');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1013, 'COSTO', 'C', 0, 'C0');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1014, 'ASEGURADOPOR', 'C', 0, 'C0');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1017, '*hghgdhg', 'T', 1017, 'Tfgfg');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1018, 'DESCRIPCION', 'T', 0, 'T');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1019, 'erewrwefwf', 'T', 1019, 'Tfweffew');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1020, 'MARCA', 'T', 0, 'TSIN MARCA');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1021, 'PROVEEDOR', 'T', 0, 'T');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1022, 'DIAGONAL', 'C', 0, 'C15');
INSERT INTO TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, TIPO, ELIMINADO, DEFECTO) VALUES (1023, 'MEGABYTES', 'C', 0, 'C128');

COMMIT WORK;

INSERT INTO TP_PARTES (ID_PARTE, NB_PARTE, MULTIPLE, IDP_CONTINENTE, IDP_CONTENIBLE, ELIMINADO) VALUES (1035, 'DISCO_RIGIDO', 'F', 1020, 1030, 1035);
INSERT INTO TP_PARTES (ID_PARTE, NB_PARTE, MULTIPLE, IDP_CONTINENTE, IDP_CONTENIBLE, ELIMINADO) VALUES (1036, 'MEMORIAS', 'T', 1020, 1023, 0);
INSERT INTO TP_PARTES (ID_PARTE, NB_PARTE, MULTIPLE, IDP_CONTINENTE, IDP_CONTENIBLE, ELIMINADO) VALUES (1037, 'DISCO_RIGIDO', 'F', 1020, 1030, 0);
INSERT INTO TP_PARTES (ID_PARTE, NB_PARTE, MULTIPLE, IDP_CONTINENTE, IDP_CONTENIBLE, ELIMINADO) VALUES (1038, 'MICRO', 'F', 1020, 1029, 0);
INSERT INTO TP_PARTES (ID_PARTE, NB_PARTE, MULTIPLE, IDP_CONTINENTE, IDP_CONTENIBLE, ELIMINADO) VALUES (1039, 'PLACA VIDEO', 'F', 1020, 1034, 0);
INSERT INTO TP_PARTES (ID_PARTE, NB_PARTE, MULTIPLE, IDP_CONTINENTE, IDP_CONTENIBLE, ELIMINADO) VALUES (1040, 'DISCORIGIDO', 'F', 1031, 1030, 0);
INSERT INTO TP_PARTES (ID_PARTE, NB_PARTE, MULTIPLE, IDP_CONTINENTE, IDP_CONTENIBLE, ELIMINADO) VALUES (1041, 'MICRO', 'F', 1031, 1029, 0);
INSERT INTO TP_PARTES (ID_PARTE, NB_PARTE, MULTIPLE, IDP_CONTINENTE, IDP_CONTENIBLE, ELIMINADO) VALUES (1042, 'PLACA VIDEO', 'F', 1031, 1034, 0);
INSERT INTO TP_PARTES (ID_PARTE, NB_PARTE, MULTIPLE, IDP_CONTINENTE, IDP_CONTENIBLE, ELIMINADO) VALUES (1043, 'MEMORIAS', 'T', 1031, 1023, 0);

COMMIT WORK;

INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1020, 1014, 'C0');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1020, 1012, 'TBLANCO');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1020, 1018, 'Teffe');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1023, 1020, 'TBRAND');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1030, 1020, 'TSIN MARCA');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1023, 1010, 'BT');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1023, 1021, 'T');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1023, 1013, 'C0');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1021, 1010, 'BT');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1021, 1012, 'TBLANCO');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1021, 1021, 'T');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1021, 1020, 'TSIN MARCA');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1021, 1013, 'C0');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1021, 1022, 'C15');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1023, 1023, 'C128');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1030, 1013, 'C0');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1030, 1021, 'T');
INSERT INTO TP_ATRIB_ART (IDP_ARTICULO, ID_ATRIBUTO, DEFECTO) VALUES (1030, 1023, 'C40000');

COMMIT WORK;



/******************************************************************************/
/****                          Unique Constraints                          ****/
/******************************************************************************/

ALTER TABLE TP_ARTICULOS ADD CONSTRAINT UNQ1_TP_ARTICULOS UNIQUE (NBP_ARTICULO, ELIMINADO);
ALTER TABLE TP_ATRIBUTOS ADD CONSTRAINT UNQ1_TP_ATRIBUTOS UNIQUE (NB_ATRIBUTO, ELIMINADO);
ALTER TABLE TP_PARTES ADD CONSTRAINT UNQ1_TP_PARTES UNIQUE (NB_PARTE, IDP_CONTINENTE, ELIMINADO);


/******************************************************************************/
/****                             Primary Keys                             ****/
/******************************************************************************/

ALTER TABLE TC_ATRIB_ART ADD CONSTRAINT PK_TC_ATRIB_ART PRIMARY KEY (ID_CAMBIO);
ALTER TABLE TC_PARTE_ART ADD CONSTRAINT PK_TC_PARTE_ART PRIMARY KEY (ID_CAMBIO);
ALTER TABLE TO_ARTICULOS ADD CONSTRAINT PK_TO_ARTICULOS PRIMARY KEY (ID_ARTICULO);
ALTER TABLE TO_INFORMES ADD CONSTRAINT PK_TO_INFORMES PRIMARY KEY (ID_INFORME);
ALTER TABLE TO_OPERACIONES ADD CONSTRAINT PK_TO_OPERACIONES PRIMARY KEY (ID_OPERACION);
ALTER TABLE TO_SUCESOS ADD CONSTRAINT PK_TO_SUCESOS PRIMARY KEY (ID_SUCESO);
ALTER TABLE TP_ARTICULOS ADD CONSTRAINT PK_TP_ARTICULOS PRIMARY KEY (IDP_ARTICULO);
ALTER TABLE TP_ATRIBUTOS ADD CONSTRAINT PK_TP_ATRIBUTOS PRIMARY KEY (ID_ATRIBUTO);
ALTER TABLE TP_ATRIB_ART ADD CONSTRAINT PK_TP_ATRIB_ART PRIMARY KEY (IDP_ARTICULO, ID_ATRIBUTO);
ALTER TABLE TP_PARTES ADD CONSTRAINT PK_TP_PARTES PRIMARY KEY (ID_PARTE);


/******************************************************************************/
/****                             Foreign Keys                             ****/
/******************************************************************************/

ALTER TABLE TC_ATRIB_ART ADD CONSTRAINT FK_TC_ATRIB_ART_2 FOREIGN KEY (ID_ATRIBUTO) REFERENCES TP_ATRIBUTOS (ID_ATRIBUTO);
ALTER TABLE TC_ATRIB_ART ADD CONSTRAINT FK_TC_ATRIB_ART_3 FOREIGN KEY (ID_ARTICULO) REFERENCES TO_ARTICULOS (ID_ARTICULO);
ALTER TABLE TC_ATRIB_ART ADD CONSTRAINT FK_TC_ATRIB_ART_4 FOREIGN KEY (ID_OPERACION) REFERENCES TO_OPERACIONES (ID_OPERACION);
ALTER TABLE TC_PARTE_ART ADD CONSTRAINT FK_TC_PARTE_ART_2 FOREIGN KEY (ID_PARTE) REFERENCES TP_PARTES (ID_PARTE);
ALTER TABLE TC_PARTE_ART ADD CONSTRAINT FK_TC_PARTE_ART_3 FOREIGN KEY (ID_CONTINENTE) REFERENCES TO_ARTICULOS (ID_ARTICULO);
ALTER TABLE TC_PARTE_ART ADD CONSTRAINT FK_TC_PARTE_ART_4 FOREIGN KEY (ID_CONTENIBLE) REFERENCES TO_ARTICULOS (ID_ARTICULO);
ALTER TABLE TC_PARTE_ART ADD CONSTRAINT FK_TC_PARTE_ART_5 FOREIGN KEY (ID_OPERACION) REFERENCES TO_OPERACIONES (ID_OPERACION);
ALTER TABLE TO_ARTICULOS ADD CONSTRAINT FK_TO_ARTICULOS_2 FOREIGN KEY (IDP_ARTICULO) REFERENCES TP_ARTICULOS (IDP_ARTICULO);
ALTER TABLE TO_OPERACIONES ADD CONSTRAINT FK_TO_OPERACIONES_1 FOREIGN KEY (ID_SUCESO) REFERENCES TO_SUCESOS (ID_SUCESO);
ALTER TABLE TO_SUCESOS ADD CONSTRAINT FK_TO_SUCESOS_1 FOREIGN KEY (ID_INFORME) REFERENCES TO_INFORMES (ID_INFORME);
ALTER TABLE TP_ATRIB_ART ADD CONSTRAINT FK_TP_ATRIB_ART_1 FOREIGN KEY (IDP_ARTICULO) REFERENCES TP_ARTICULOS (IDP_ARTICULO);
ALTER TABLE TP_ATRIB_ART ADD CONSTRAINT FK_TP_ATRIB_ART_2 FOREIGN KEY (ID_ATRIBUTO) REFERENCES TP_ATRIBUTOS (ID_ATRIBUTO);
ALTER TABLE TP_PARTES ADD CONSTRAINT FK_TP_PARTES_1 FOREIGN KEY (IDP_CONTENIBLE) REFERENCES TP_ARTICULOS (IDP_ARTICULO);
ALTER TABLE TP_PARTES ADD CONSTRAINT FK_TP_PARTES_3 FOREIGN KEY (IDP_CONTINENTE) REFERENCES TP_ARTICULOS (IDP_ARTICULO);


/******************************************************************************/
/****                               Triggers                               ****/
/******************************************************************************/


SET TERM ^ ;


/******************************************************************************/
/****                         Triggers for tables                          ****/
/******************************************************************************/



/* Trigger: TC_ATRIB_ART_BI */
CREATE TRIGGER TC_ATRIB_ART_BI FOR TC_ATRIB_ART
ACTIVE BEFORE INSERT POSITION 0
AS
declare variable anterior_id_operacion integer;
declare variable anterior_fecha_suceso timestamp;
declare variable anterior_valor varchar(255);
BEGIN
  --Asigno Id del cambio
  IF (NEW.ID_CAMBIO IS NULL) THEN
    NEW.ID_CAMBIO = GEN_ID(GEN_TO_CAMBIO_ID,1);

  -- Asigna fecha de suceso (SIEMPRE, SI SE SETEO LA SOBREESCRIBE)
  select
    to_sucesos.fecha_suceso
  from
    to_sucesos
    inner join to_operaciones on to_sucesos.id_suceso = to_operaciones.id_suceso
  where
    to_operaciones.id_operacion = new.id_operacion
  into
    new.fecha_suceso;

  --Compruebo que en la fecha del suceso exista el articulo
  if (not exists (
    select *
    from SPE_LST_ID_ARTICULOS(new.fecha_suceso)
    where SPE_LST_ID_ARTICULOS.id_articulo = new.id_articulo
  )) then
    exception EX_TRANSICION_INVALIDA 'El artículo no existe en la fecha del suceso';

  --Compruebo que la plantilla de artículo tenga el atributo indicado
  if (not exists (
    select
        *
    from
        TO_ARTICULOS
        inner join TP_ATRIB_ART on TP_ATRIB_ART.IDP_ARTICULO = TO_ARTICULOS.IDP_ARTICULO
    where
        TO_ARTICULOS.ID_ARTICULO = new.ID_ARTICULO and
        TP_ATRIB_ART.ID_ATRIBUTO = new.ID_ATRIBUTO
  )) then
    exception EX_TRANSICION_INVALIDA 'El artículo no tiene el atributo indicado.';

  --Compruebo la validez de la insercion  con respecto a cambios previos
  execute procedure spe_get_valor_atrib_art (
        null, --La última
        new.id_articulo,
        new.id_atributo)
  returning_values (
        :anterior_id_operacion,
        :anterior_fecha_suceso,
        :anterior_valor);

  if ((:anterior_valor is not null) and (:anterior_valor <> 'I')) then
  begin --Si ya habia un cambio previo
    if (new.valor_anterior = 'I') then
        new.valor_anterior = :anterior_valor;
    if (:anterior_fecha_suceso > new.fecha_suceso) then
        exception EX_TRANSICION_INVALIDA 'Existe un cambio para este atributo para este artículo con fecha posterior.';
    else if (:anterior_valor <> new.valor_anterior) then
        exception EX_TRANSICION_INVALIDA 'El valor anterior ingresado no corresponde con el último.';
  end
  else
  begin --Si no habia un cambio previo
    if (new.valor_anterior <> 'I') then
        exception EX_TRANSICION_INVALIDA 'El valor anterior ingresado no es valido ya que no existia un valor previo.';
  end
END
^


/* Trigger: TC_PARTE_ART_BI */
CREATE TRIGGER TC_PARTE_ART_BI FOR TC_PARTE_ART
ACTIVE BEFORE INSERT POSITION 0
AS
declare variable anterior_id_operacion integer;
declare variable anterior_fecha_suceso timestamp;
declare variable anterior_valor varchar(255);
declare variable anterior_id_continente integer;
declare variable anterior_id_parte integer;


BEGIN
  --Asigno Id del cambio
  IF (NEW.ID_CAMBIO IS NULL) THEN
    NEW.ID_CAMBIO = GEN_ID(GEN_TO_CAMBIO_ID,1);

  -- Asigna fecha de suceso (SIEMPRE, SI SE SETEO LA SOBREESCRIBE)
  SELECT
    to_sucesos.fecha_suceso
  FROM
    to_sucesos
    INNER JOIN to_operaciones ON to_sucesos.id_suceso = to_operaciones.id_suceso
  WHERE
    to_operaciones.id_operacion = NEW.id_operacion
  INTO
    NEW.fecha_suceso;

  --Compruebo que en la fecha del suceso existan los articulos
  IF (NOT EXISTS (
    SELECT *
    FROM SPE_LST_ID_ARTICULOS(NEW.fecha_suceso)
    WHERE SPE_LST_ID_ARTICULOS.id_articulo = NEW.ID_CONTINENTE
  )) THEN
    EXCEPTION EX_TRANSICION_INVALIDA 'El artículo continente no existe en la fecha del suceso';
  IF (NOT EXISTS (
    SELECT *
    FROM SPE_LST_ID_ARTICULOS(NEW.fecha_suceso)
    WHERE SPE_LST_ID_ARTICULOS.id_articulo = NEW.ID_CONTENIBLE
  )) THEN
    EXCEPTION EX_TRANSICION_INVALIDA 'El artículo contenible no existe en la fecha del suceso';

  --Compruebo que la plantilla del contenible tenga la parte y corresponda a la plantilla del contenible
  IF (NOT EXISTS (
    SELECT
        *
    FROM
        TP_PARTES
        INNER JOIN TO_ARTICULOS CONTINENTES ON CONTINENTES.IDP_ARTICULO = TP_PARTES.IDP_CONTINENTE
        INNER JOIN TO_ARTICULOS CONTENIBLES ON CONTENIBLES.IDP_ARTICULO = TP_PARTES.IDP_CONTENIBLE
    WHERE
        TP_PARTES.ID_PARTE = NEW.ID_PARTE AND
        CONTINENTES.ID_ARTICULO = NEW.ID_CONTINENTE AND
        CONTENIBLES.ID_ARTICULO = NEW.ID_CONTENIBLE
  )) THEN
    EXCEPTION EX_TRANSICION_INVALIDA 'La parte no es valida para los archivos indicados.';

--SI ESTOY AGREGANDO UN COMPONENTE
if (new.TIPO = '+') then
begin
  -- Compruebo que el articulo contenible este disponible
  execute procedure SPE_GET_CONTENIDO_CONTE (
    null, --la ultima fecha
    new.ID_CONTENIBLE)
  returning_values (
    :anterior_id_operacion,
    :anterior_fecha_suceso,
    :ANTERIOR_VALOR,
    :anterior_id_continente,
    :anterior_id_parte);
  if (:ANTERIOR_VALOR = '+') then
    exception EX_TRANSICION_INVALIDA 'El contenible no está disponible';
  else if (:ANTERIOR_FECHA_SUCESO > new.FECHA_SUCESO) then
    exception EX_TRANSICION_INVALIDA 'El contenible tiene movimientos posteriores.';

  -- compruebo que la parte del continente este disponible
  execute procedure SPE_GET_DISP_PARTE_CONTI (
    null, 
    new.ID_CONTINENTE,
    new.ID_PARTE)
  returning_values (
    :ANTERIOR_ID_OPERACION,
    :ANTERIOR_FECHA_SUCESO,
    :ANTERIOR_VALOR);
  if (:ANTERIOR_VALOR = '+') then
    exception EX_TRANSICION_INVALIDA 'La parte del continente está ocupada';
  else if (:ANTERIOR_FECHA_SUCESO > new.FECHA_SUCESO) then
    exception EX_TRANSICION_INVALIDA 'El continente fue disponible posteriormente a la operación.';
end
else if (new.TIPO = '-') then
begin
   --compruebo que el articulo contenible este asociado a la parte correspondiente del continente
    execute procedure SPE_GET_CONTENIDO_CONTE (null, NEW.ID_CONTENIBLE)
    returning_values (
        :ANTERIOR_ID_OPERACION,
        :ANTERIOR_FECHA_SUCESO,
        :ANTERIOR_VALOR,
        :ANTERIOR_ID_CONTINENTE,
        :ANTERIOR_ID_PARTE);
    if ((:ANTERIOR_ID_CONTINENTE <> NEW.ID_CONTINENTE) or (:ANTERIOR_VALOR = '-')) then
        exception EX_TRANSICION_INVALIDA 'El contenible no esta asociado a la parte del continente';
end
END
^


/* Trigger: TO_ARTICULOS_AI0 */
CREATE TRIGGER TO_ARTICULOS_AI0 FOR TO_ARTICULOS
ACTIVE AFTER INSERT POSITION 0
AS
    declare variable id_atributo integer;
    declare variable defecto varchar(255);
begin
  --Creo los atributos que corresponden al articulo segun su plantilla
  for select 
    TP_ATRIB_ART.id_atributo,
    TP_ATRIB_ART.defecto
  from
    TP_ATRIB_ART
  where
    TP_ATRIB_ART.idp_articulo = new.idp_articulo
  into
    :id_atributo, :defecto
  do
  begin
    insert into tc_atrib_art (
        tc_atrib_art.id_atributo,
        tc_atrib_art.id_articulo,
        tc_atrib_art.valor_nuevo,
        tc_atrib_art.id_operacion)
    values (
        :id_atributo,
        new.id_articulo,
        :defecto,
        new.creacion_id_operacion);
  end

end
^


/* Trigger: TO_ARTICULOS_BI */
CREATE TRIGGER TO_ARTICULOS_BI FOR TO_ARTICULOS
ACTIVE BEFORE INSERT POSITION 0
as
begin
  -- Asigna id de artículo (SOLO SI NO SE ESPECIFICO)
  if (new.id_articulo is null) then
    new.id_articulo = gen_id(gen_to_articulos_id,1);

  -- Asigna id de operacion (SOLO SI NO SE ESPECIFICO)
  IF (NEW.CREACION_ID_CAMBIO IS NULL) THEN
    NEW.CREACION_ID_CAMBIO = GEN_ID(GEN_TO_CAMBIO_ID,1);

  -- Asigna fecha de suceso (SIEMPRE, SI SE SETEO LA SOBREESCRIBE)
  select
    to_sucesos.fecha_suceso
  from
    to_sucesos
    inner join to_operaciones on to_sucesos.id_suceso = to_operaciones.id_suceso
  where
    to_operaciones.id_operacion = new.creacion_id_operacion
  into
    new.creacion_fecha_suceso;
end
^


/* Trigger: TO_INFORMES_BI */
CREATE TRIGGER TO_INFORMES_BI FOR TO_INFORMES
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id_informe is null) then
    new.id_informe = gen_id(gen_to_informes_id,1);
end
^


/* Trigger: TO_OPERACIONES_BI */
CREATE TRIGGER TO_OPERACIONES_BI FOR TO_OPERACIONES
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id_operacion is null) then
    new.id_operacion = gen_id(gen_to_operaciones_id,1);
end
^


/* Trigger: TO_SUCESOS_BI */
CREATE TRIGGER TO_SUCESOS_BI FOR TO_SUCESOS
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id_suceso is null) then
    new.id_suceso = gen_id(gen_to_sucesos_id,1);
end
^


/* Trigger: TP_ARTICULOS_DBR13 */
CREATE TRIGGER TP_ARTICULOS_DBR13 FOR TP_ARTICULOS
ACTIVE BEFORE INSERT POSITION 10
as
begin
/*
    if ((new.CONTINENTE='T') and (new.UBICABLE='F')) then
    begin
        exception EX_CONTI_Y_NOUBI;
    end
*/
    if ((new.CONTINENTE='T') and (new.CONTENIBLE='T')) then
    begin
        exception EX_CONTI_Y_CONTE;
    end
/*
    if ((new.UBICABLE='T') and (new.CONTENIBLE='T')) then
    begin
        exception EX_CONTE_Y_UBI;
    end
*/
end
^


/* Trigger: TP_ARTICULOS_NUM */
CREATE TRIGGER TP_ARTICULOS_NUM FOR TP_ARTICULOS
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.IDP_ARTICULO is null) then
    new.IDP_ARTICULO = gen_id(GEN_TP_ARTICULOS_ID,1);
end
^


/* Trigger: TP_ATRIBUTOS_NUM */
CREATE TRIGGER TP_ATRIBUTOS_NUM FOR TP_ATRIBUTOS
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.ID_ATRIBUTO is null) then
    new.ID_ATRIBUTO = gen_id(GEN_TP_ATRIBUTOS_ID,1);
end
^


/* Trigger: TP_ATRIB_ART_AI0 */
CREATE TRIGGER TP_ATRIB_ART_AI0 FOR TP_ATRIB_ART
ACTIVE AFTER INSERT POSITION 0
AS
declare variable ID_ARTICULO integer;
declare variable ID_OPERACION integer;
declare variable FECHA_SUCESO timestamp;
begin
    --Cuando se asocia un atributo a una plantilla de artículos
    --se debe crear el atributo para los artículos de la especificación
    for select 
        TO_ARTICULOS.ID_ARTICULO,
        TO_ARTICULOS.CREACION_ID_OPERACION,
        TO_ARTICULOS.CREACION_FECHA_SUCESO
    from
        TO_ARTICULOS
    where
        TO_ARTICULOS.IDP_ARTICULO = new.IDP_ARTICULO
    into
        :ID_ARTICULO, :ID_OPERACION, :FECHA_SUCESO
    do
    begin
        insert into
            TC_ATRIB_ART (
                TC_ATRIB_ART.ID_ATRIBUTO,
                TC_ATRIB_ART.ID_ARTICULO,
                TC_ATRIB_ART.VALOR_NUEVO,
                TC_ATRIB_ART.ID_OPERACION,
                TC_ATRIB_ART.FECHA_SUCESO)
            values (
                new.ID_ATRIBUTO,
                :ID_ARTICULO,
                new.DEFECTO,
                :ID_OPERACION,
                :FECHA_SUCESO);
    end
end
^


/* Trigger: TP_ATRIB_ART_DBR09 */
CREATE TRIGGER TP_ATRIB_ART_DBR09 FOR TP_ATRIB_ART
ACTIVE BEFORE INSERT POSITION 10
as
begin
    /* #DBR09#
    CUANDO SE ASOCIA UNA ESPECIFICACION DE ARTICULOS A UN ATRIBUTO SIN
    UN VALOR POR DEFECTO, SE PONE EL VALOR POR DEFECTO DEL ATRIBUTO POSIBLE */
    if (new.DEFECTO is null) then
    begin
        select DEFECTO
           from TP_ATRIBUTOS
           where ID_ATRIBUTO = new.ID_ATRIBUTO
           into new.DEFECTO;
    end
end
^


/* Trigger: TP_PARTES_DBR11 */
CREATE TRIGGER TP_PARTES_DBR11 FOR TP_PARTES
ACTIVE BEFORE INSERT OR UPDATE POSITION 10
as
    declare variable CONTIESCONTI char = 'F';
    declare variable CONTEESCONTE char = 'F';
begin
    select (CONTINENTE)
        from TP_ARTICULOS
        where TP_ARTICULOS.IDP_ARTICULO = new.IDP_CONTINENTE
    into :CONTIESCONTI;
    select (CONTENIBLE)
        from TP_ARTICULOS
        where TP_ARTICULOS.IDP_ARTICULO = new.IDP_CONTENIBLE
    into :CONTEESCONTE;
    if ((CONTIESCONTI='F') or (CONTEESCONTE='F')) then
        exception EX_CONTI_CONTE_INVALIDOS;
    exit;
end
^


/* Trigger: TP_PARTES_NUM */
CREATE TRIGGER TP_PARTES_NUM FOR TP_PARTES
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.ID_PARTE is null) then
    new.ID_PARTE = gen_id(GEN_TP_PARTES_ID,1);
end
^


SET TERM ; ^



/******************************************************************************/
/****                          Stored Procedures                           ****/
/******************************************************************************/


SET TERM ^ ;

ALTER PROCEDURE SPC_ADD_PARTE_ART (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    ID_CONTIENTE INTEGER,
    NB_PARTE VARCHAR(20),
    ID_CONTENIBLE INTEGER)
RETURNS (
    ID_OPERACION_O INTEGER)
AS
declare variable ID_PARTE integer;
begin
    execute procedure SPI_SEL_OPERACION (:ID_SUCESO, :ID_OPERACION, 'C')
    returning_values (:ID_OPERACION_O);

    select
        TP_PARTES.ID_PARTE
    from
        TP_PARTES
        inner join TO_ARTICULOS on TO_ARTICULOS.IDP_ARTICULO = TP_PARTES.IDP_CONTINENTE
    where
        TO_ARTICULOS.ID_ARTICULO = :ID_CONTIENTE and
        TP_PARTES.NB_PARTE = :NB_PARTE and
        TP_PARTES.ELIMINADO = 0
    into
        :id_parte;

    insert into TC_PARTE_ART (
        TC_PARTE_ART.ID_OPERACION,
        TC_PARTE_ART.ID_CONTINENTE,
        TC_PARTE_ART.ID_PARTE,
        TC_PARTE_ART.TIPO,
        TC_PARTE_ART.ID_CONTENIBLE)
    values (
        :ID_OPERACION_O,
        :ID_CONTIENTE,
        :ID_PARTE,
        '+',
        :ID_CONTENIBLE);
  exit;
end
^

ALTER PROCEDURE SPC_EDT_ATRIB_ART (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    ID_ARTICULO INTEGER,
    NB_ATRIBUTO VARCHAR(20),
    VALOR_ANTERIOR VARCHAR(255),
    VALOR_NUEVO VARCHAR(255))
RETURNS (
    ID_OPERACION_O INTEGER)
AS
declare variable ID_ATRIBUTO integer;
begin
    execute procedure SPI_SEL_OPERACION (:ID_SUCESO, :ID_OPERACION, 'B')
    returning_values (:ID_OPERACION_O);

    select tp_atributos.id_atributo
    from tp_atributos
    where tp_atributos.nb_atributo = :nb_atributo
    into :id_atributo;

    insert into tc_atrib_art (
        tc_atrib_art.id_operacion,
        tc_atrib_art.id_articulo,
        tc_atrib_art.id_atributo,
        tc_atrib_art.valor_anterior,
        tc_atrib_art.valor_nuevo)
    values (
        :ID_OPERACION_O,
        :id_articulo,
        :id_atributo,
        :valor_anterior,
        :valor_nuevo);

  exit;
end
^

ALTER PROCEDURE SPC_NEW_ARTICULOS (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    NBP_ARTICULO VARCHAR(20),
    CANTIDAD INTEGER,
    ID INTEGER)
RETURNS (
    ID_ARTICULO INTEGER,
    ID_OPERACION_O INTEGER)
AS
declare variable IDP_ARTICULO integer;
declare variable EXISTE_ID char(1) character set NONE;
begin
    execute procedure SPI_SEL_OPERACION (:ID_SUCESO, :ID_OPERACION, 'A')
    returning_values (:ID_OPERACION_O);

    select tp_articulos.idp_articulo
    from tp_articulos
    where tp_articulos.nbp_articulo = :nbp_articulo
    into :idp_articulo;

    WHILE (:cantidad > 0) DO
    BEGIN

        if (:ID = 0) then
        begin --hay que elegir un id de artículo
            EXISTE_ID = 'T';
            while (EXISTE_ID = 'T') do
            begin
                id_articulo = gen_id(gen_to_articulos_id,1);
                if (exists (
                    select * from TO_ARTICULOS where TO_ARTICULOS.ID_ARTICULO = :ID_ARTICULO
                )) then
                    EXISTE_ID = 'T';
                else
                    EXISTE_ID = 'F';
            end
        end
        else
        begin
        /*
            if (exists(
                select * from TO_ARTICULOS where TO_ARTICULOS.ID_ARTICULO = :ID
            )) then
                exception EX_NO_ENCONTRADO 'Ya existe un artículo con el ID indicado';
            else

--POR ALGUNA RAZON NI LA EXCEPCION DE ARRIBA FALLA, NI LA DE UNIQUE CUANDO
--SE INTENTAN CREAR VARIOS ARTICULOS CON IDS DEFINIDOS Y EL PRIMERO NO COINCIDE CON
--UNO EXISTENTE, PERO ALGUNO DE LOS OTROS SI.

        */
                ID_ARTICULO = :ID;
        end

        insert into to_articulos (
            to_articulos.id_articulo,
            to_articulos.idp_articulo,
            to_articulos.creacion_id_operacion)
        values (
            :id_articulo,
            :idp_articulo,
            :ID_OPERACION_O);

        suspend;

        cantidad = :cantidad - 1;
        if (:ID <> 0) then
            id = :ID + 1;
    END

    exit;
end
^

ALTER PROCEDURE SPC_REM_PARTES_ART_1 (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    ID_CONTENIBLE INTEGER)
RETURNS (
    ID_OPERACION_O INTEGER,
    ID_CONTINENTE INTEGER,
    ID_PARTE INTEGER)
AS
declare variable TEMP_ID_OPERACION integer;
declare variable TEMP_FECHA_SUCESO timestamp;
declare variable TEMP_VALOR char(1);
begin
    execute procedure SPI_SEL_OPERACION (:ID_SUCESO, :ID_OPERACION, 'D')
    returning_values (:ID_OPERACION_O);

    --obtengo el continente al que esta asociada la parte
    execute procedure SPE_GET_CONTENIDO_CONTE (null, :ID_CONTENIBLE)
    returning_values (
        :TEMP_ID_OPERACION,
        :TEMP_FECHA_SUCESO,
        :TEMP_VALOR,
        :ID_CONTINENTE,
        :ID_PARTE);

    --verifico que esté asociado
    if (:TEMP_VALOR = '-') then
        exception EX_NO_ENCONTRADO 'El contenido no esta asociado a la parte de un continente';



    insert into TC_PARTE_ART (
        TC_PARTE_ART.ID_OPERACION,
        TC_PARTE_ART.ID_CONTINENTE,
        TC_PARTE_ART.ID_PARTE,
        TC_PARTE_ART.TIPO,
        TC_PARTE_ART.ID_CONTENIBLE)
    values (
        :ID_OPERACION_O,
        :ID_CONTINENTE,
        :ID_PARTE,
        '-',
        :ID_CONTENIBLE);



    suspend;
end
^

ALTER PROCEDURE SPC_REM_PARTES_ART_2 (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    ID_CONTINENTE INTEGER,
    NB_PARTE VARCHAR(20))
RETURNS (
    ID_OPERACION_O INTEGER,
    ID_CONTENIBLE INTEGER)
AS
declare variable ID_PARTE integer;
begin
    execute procedure SPI_SEL_OPERACION (:ID_SUCESO, :ID_OPERACION, 'D')
    returning_values (:ID_OPERACION_O);


    select
        TP_PARTES.ID_PARTE
    from
        TP_PARTES
        inner join TO_ARTICULOS on TO_ARTICULOS.IDP_ARTICULO = TP_PARTES.IDP_CONTINENTE
    where
        TO_ARTICULOS.ID_ARTICULO = :ID_CONTINENTE and
        TP_PARTES.NB_PARTE = :NB_PARTE and
        TP_PARTES.ELIMINADO = 0
    into
        :ID_PARTE;


    if (:ID_PARTE is null) then
        exception EX_NO_ENCONTRADO 'El continente y parte no corresponden o no existen';

    for select
        SPE_LST_CONTE_PARTE_CONTI.ID_CONTENIBLE
    from
        SPE_LST_CONTE_PARTE_CONTI(null, :ID_CONTINENTE, :ID_PARTE)
    into
        :ID_CONTENIBLE
    do
    begin
        insert into TC_PARTE_ART (
            TC_PARTE_ART.ID_OPERACION,
            TC_PARTE_ART.ID_CONTINENTE,
            TC_PARTE_ART.ID_PARTE,
            TC_PARTE_ART.TIPO,
            TC_PARTE_ART.ID_CONTENIBLE)
        values (
            :ID_OPERACION_O,
            :ID_CONTINENTE,
            :ID_PARTE,
            '-',
            :ID_CONTENIBLE);


        suspend;
    end
  exit;
end
^

ALTER PROCEDURE SPE_GET_CONTENIDO_CONTE (
    FECHA TIMESTAMP,
    ID_CONTENIBLE INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    VALOR CHAR(1),
    ID_CONTINENTE INTEGER,
    ID_PARTE INTEGER)
AS
begin
    VALOR = '-';

    --verifico la existencia del articulo en el momento indicado
    --obtengo la operacion y fecha de creación por si nunca estuvo contenido
    select
        TO_ARTICULOS.CREACION_ID_OPERACION,
        TO_ARTICULOS.CREACION_FECHA_SUCESO
    from
        TO_ARTICULOS
    inner join
        TP_ARTICULOS on TP_ARTICULOS.IDP_ARTICULO = TO_ARTICULOS.IDP_ARTICULO
    where
        TO_ARTICULOS.CREACION_ELIMINADO = 0 and
        ((:fecha is null) or (TO_ARTICULOS.CREACION_FECHA_SUCESO <= :FECHA)) and
        TO_ARTICULOS.ID_ARTICULO = :ID_CONTENIBLE and
        TP_ARTICULOS.CONTENIBLE = 'T'
    into
        :ID_OPERACION,
        :FECHA_SUCESO;
    if (:FECHA_SUCESO is null) then
        exception EX_NO_ENCONTRADO 'No existe el artículo contenible en la fecha indicada o no es contenible';
        
    --Obtengo datos de la ultima vez que se asocio/desasocio de una parte
    select first 1
        TC_PARTE_ART.ID_OPERACION,
        TC_PARTE_ART.FECHA_SUCESO,
        TC_PARTE_ART.TIPO,
        TC_PARTE_ART.ID_CONTINENTE,
        TC_PARTE_ART.ID_PARTE
    from
        TC_PARTE_ART
    where
        TC_PARTE_ART.ELIMINADO = 0 and
        ((:fecha is null) or (TC_PARTE_ART.FECHA_SUCESO <= :FECHA)) and
        TC_PARTE_ART.ID_CONTENIBLE = :ID_CONTENIBLE
    order by
        TC_PARTE_ART.ID_CAMBIO descending
    into
        :ID_OPERACION,
        :FECHA_SUCESO, 
        :VALOR,
        :ID_CONTINENTE,
        :ID_PARTE;
    exit;
end
^

ALTER PROCEDURE SPE_GET_DISP_PARTE_CONTI (
    FECHA TIMESTAMP,
    ID_CONTINENTE INTEGER,
    ID_PARTE INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    TIPO_CAMBIO CHAR(1))
AS
declare variable MULTIPLE char(1) character set NONE;
begin
    TIPO_CAMBIO = '-';

    select first 1
        TP_PARTES.MULTIPLE,
        TO_ARTICULOS.CREACION_ID_OPERACION,
        TO_ARTICULOS.CREACION_FECHA_SUCESO
    from
        TO_ARTICULOS
        inner join TP_ARTICULOS on TP_ARTICULOS.IDP_ARTICULO = TO_ARTICULOS.IDP_ARTICULO
        inner join TP_PARTES on TP_PARTES.IDP_CONTINENTE = TO_ARTICULOS.IDP_ARTICULO
    where
        TO_ARTICULOS.CREACION_ELIMINADO = 0 and
        ((:fecha is null) or (TO_ARTICULOS.CREACION_FECHA_SUCESO <= :FECHA)) and
        TO_ARTICULOS.ID_ARTICULO = :ID_CONTINENTE and
        TP_PARTES.ID_PARTE = :ID_PARTE and
        TP_ARTICULOS.CONTINENTE = 'T'
    into
        :MULTIPLE,
        :ID_OPERACION,
        :FECHA_SUCESO;

    if (:MULTIPLE is null) then
        exception EX_NO_ENCONTRADO 'El artículo o la parte no existen o no corresponden.';

    else if (:MULTIPLE = 'T') then
    begin -- la parte es multiple
        -- no hago nada esta disponible desde que se creo el artículo
    end
    else --if (:MULTIPLE = 'F') then
    begin --la parte es simple
        select first 1
            TC_PARTE_ART.ID_OPERACION,
            TC_PARTE_ART.FECHA_SUCESO,
            TC_PARTE_ART.TIPO
        from
            TC_PARTE_ART
        where
            TC_PARTE_ART.ELIMINADO = 0 and
            ((:fecha is null) or (TC_PARTE_ART.FECHA_SUCESO <= :FECHA)) and
            TC_PARTE_ART.ID_CONTINENTE = :ID_CONTINENTE and
            TC_PARTE_ART.ID_PARTE = :ID_PARTE
        order by
            TC_PARTE_ART.ID_CAMBIO descending
        into
            :ID_OPERACION,
            :FECHA_SUCESO,
            :TIPO_CAMBIO;
        -- si no hay nada, esta disponible desde que se creo el artículo
        -- sino depende de lo que resulte en tipo_cambio
    end

    exit;
end
^

ALTER PROCEDURE SPE_GET_VALOR_ATRIB_ART (
    FECHA TIMESTAMP,
    ID_ARTICULO INTEGER,
    ID_ATRIBUTO INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    VALOR VARCHAR(255))
AS
begin
    if (not exists (
        select * from   
            TO_ARTICULOS
            inner join TP_ATRIB_ART on TP_ATRIB_ART.IDP_ARTICULO = TO_ARTICULOS.IDP_ARTICULO
        where

            TO_ARTICULOS.CREACION_ELIMINADO = 0 and
            ((:fecha is null) or (TO_ARTICULOS.CREACION_FECHA_SUCESO <= :FECHA)) and
            TO_ARTICULOS.ID_ARTICULO = :ID_ARTICULO and
            TP_ATRIB_ART.ID_ATRIBUTO = :ID_ATRIBUTO
    )) then
        exception EX_NO_ENCONTRADO 'El artículo o el atributo indicados no existen';

    select first 1
        TC_ATRIB_ART.ID_OPERACION,
        TC_ATRIB_ART.FECHA_SUCESO,
        TC_ATRIB_ART.VALOR_NUEVO
    from
        TC_ATRIB_ART
    where
        TC_ATRIB_ART.ELIMINADO = 0 and
        ((:fecha is null) or (TC_ATRIB_ART.FECHA_SUCESO <= :FECHA)) and
        TC_ATRIB_ART.ID_ARTICULO = :ID_ARTICULO and
        TC_ATRIB_ART.ID_ATRIBUTO = :ID_ATRIBUTO
    order by
        TC_ATRIB_ART.ID_CAMBIO descending
    into
        :ID_OPERACION,
        :FECHA_SUCESO, 
        :VALOR;
    exit;
end
^

ALTER PROCEDURE SPE_LST_CONTE_PARTE_CONTI (
    FECHA TIMESTAMP,
    ID_CONTINENTE INTEGER,
    ID_PARTE INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    ID_CONTENIBLE INTEGER)
AS
declare variable MULTIPLE char(1) character set NONE;
declare variable TIPO_CAMBIO char(1) character set NONE;
begin
    --verifico la existencia del articulo en el momento indicado y de la parte
    select first 1
        TP_PARTES.MULTIPLE
    from
        TO_ARTICULOS
        inner join TP_ARTICULOS on TP_ARTICULOS.IDP_ARTICULO = TO_ARTICULOS.IDP_ARTICULO
        inner join TP_PARTES on TP_PARTES.IDP_CONTINENTE = TO_ARTICULOS.IDP_ARTICULO
    where
        TO_ARTICULOS.CREACION_ELIMINADO = 0 and
        ((:fecha is null) or (TO_ARTICULOS.CREACION_FECHA_SUCESO <= :FECHA)) and
        TO_ARTICULOS.ID_ARTICULO = :ID_CONTINENTE and
        TP_PARTES.ID_PARTE = :ID_PARTE and
        TP_ARTICULOS.CONTINENTE = 'T'
    into
        :MULTIPLE;
    if (:MULTIPLE = 'F') then
    begin --ES UNA PARTE SIMPLE
        --Obtengo datos de la ultima vez que se le asocio/desasocio un contenible
        select first 1
            TC_PARTE_ART.ID_OPERACION,
            TC_PARTE_ART.FECHA_SUCESO,
            TC_PARTE_ART.TIPO,
            TC_PARTE_ART.ID_CONTENIBLE
        from
            TC_PARTE_ART
        where
            TC_PARTE_ART.ELIMINADO = 0 and
            ((:fecha is null) or (TC_PARTE_ART.FECHA_SUCESO <= :FECHA)) and
            TC_PARTE_ART.ID_CONTINENTE = :ID_CONTINENTE and
            TC_PARTE_ART.ID_PARTE = :ID_PARTE
        order by
            TC_PARTE_ART.ID_CAMBIO descending
        into
            :ID_OPERACION,
            :FECHA_SUCESO, 
            :TIPO_CAMBIO,
            :ID_CONTENIBLE;
        if (:TIPO_CAMBIO = '+') then
            suspend; --SI SE AGREGO SALE UNA LINEA, SINO NO SALE NADA
    end
    else if (:MULTIPLE = 'T') then
    begin --ES UNA PARTE MULTIPLE

        --DEBERIA EXISTIR UNA MEJOR FORMA DE HACER LO SIGUIENTE, TAL VEZ CON UNA
        --FUNCION DE AGREGACION FIRST() NOS AHORRARIAMOS HACER DOS BUSQUEDAS SOBRE
        --LA MISMA TABLA

        --ACTUALMENTE LO QUE HACE ES LO SIGUIENTE:
        --SELECCIONA TODOS LOS ARTICULOS QUE FORMARON PARTE DE LA PARTE
        --LUEGO VERIFICA SI EL ULTIMO MOVIMIENTO FUE DE AGREGADO O QUITADO
        --Y EN BASE A ESO INDICA SI LA PARTE ESTA OCUPADA POR DICHO ARTÍCULO

        for select
            TC_PARTE_ART.ID_CONTENIBLE
        from
            TC_PARTE_ART
        where
            TC_PARTE_ART.ELIMINADO = 0 and
            ((:fecha is null) or (TC_PARTE_ART.FECHA_SUCESO <= :FECHA)) and
            TC_PARTE_ART.ID_CONTINENTE = :ID_CONTINENTE and
            TC_PARTE_ART.ID_PARTE = :ID_PARTE
        group by
            TC_PARTE_ART.ID_CONTENIBLE
        into
            :ID_CONTENIBLE
        do
        begin
            select first 1
                TC_PARTE_ART.ID_OPERACION,
                TC_PARTE_ART.FECHA_SUCESO,
                TC_PARTE_ART.TIPO
            from
                TC_PARTE_ART
            where
                TC_PARTE_ART.ELIMINADO = 0 and
                ((:fecha is null) or (TC_PARTE_ART.FECHA_SUCESO <= :FECHA)) and
                TC_PARTE_ART.ID_CONTINENTE = :ID_CONTINENTE and
                TC_PARTE_ART.ID_PARTE = :ID_PARTE and
                TC_PARTE_ART.ID_CONTENIBLE = :ID_CONTENIBLE
            into
                :ID_OPERACION,
                :FECHA_SUCESO,
                :TIPO_CAMBIO;
                
            if (:TIPO_CAMBIO = '+') then
                suspend;
        end
    end
    else -- NO EXISTE EL ARTICULO O LA PARTE
        exception EX_NO_ENCONTRADO 'El artículo o la parte indicados no existen';

    exit;
end
^

ALTER PROCEDURE SPE_LST_DISP_PARTE_CONTI (
    FECHA TIMESTAMP,
    ID_CONTINENTE INTEGER)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    ID_PARTE INTEGER,
    MULTIPLE CHAR(1))
AS
declare variable TIPO_CAMBIO char(1) character set NONE;
declare variable ID_OPERACION_T integer;
declare variable FECHA_SUCESO_T timestamp;
begin
    for select
        TP_PARTES.ID_PARTE,
        TP_PARTES.MULTIPLE,
        TO_ARTICULOS.CREACION_ID_OPERACION,
        TO_ARTICULOS.CREACION_FECHA_SUCESO
    from
        TO_ARTICULOS
        inner join TP_ARTICULOS on TP_ARTICULOS.IDP_ARTICULO = TO_ARTICULOS.IDP_ARTICULO
        inner join TP_PARTES on TP_PARTES.IDP_CONTINENTE = TO_ARTICULOS.IDP_ARTICULO
    where
        TO_ARTICULOS.CREACION_ELIMINADO = 0 and
        ((:fecha is null) or (TO_ARTICULOS.CREACION_FECHA_SUCESO <= :FECHA)) and
        TO_ARTICULOS.ID_ARTICULO = :ID_CONTINENTE and
        TP_ARTICULOS.CONTINENTE = 'T'
    into
        :ID_PARTE,
        :MULTIPLE,
        :ID_OPERACION_T,
        :FECHA_SUCESO_T
    do
    begin
        if (:MULTIPLE = 'T') then
        begin  --LA PARTE ES MULTIPLE, ENTONCES ESTA DISPONIBLE DESDE QUE SE CREO
            ID_OPERACION = :ID_OPERACION_T;
            FECHA_SUCESO = :FECHA_SUCESO_T;
            suspend;
        end
        else
        begin --LA PARTE ES SIMPLE, ENTONCES SOLO ESTA DISPONIBLE SI NUNCA SE ASOCIO NADA O SI SE LE QUITO
            TIPO_CAMBIO = 'I';
            select first 1
                TC_PARTE_ART.ID_OPERACION,
                TC_PARTE_ART.FECHA_SUCESO,
                TC_PARTE_ART.TIPO
            from
                TC_PARTE_ART
            where
                TC_PARTE_ART.ELIMINADO = 0 and
                ((:fecha is null) or (TC_PARTE_ART.FECHA_SUCESO <= :FECHA)) and
                TC_PARTE_ART.ID_CONTINENTE = :ID_CONTINENTE and
                TC_PARTE_ART.ID_PARTE = :ID_PARTE
            order by
                TC_PARTE_ART.ID_CAMBIO descending
            into
                :ID_OPERACION,
                :FECHA_SUCESO, 
                :TIPO_CAMBIO;
            if  (:TIPO_CAMBIO = '+') then
            begin
                -- Si se agrego no sale
            end
            else if  (:TIPO_CAMBIO = '-') then
            begin
                -- Si se quito sale con los datos de la ultima quitada
                suspend;
            end
            else
            begin
                -- Si nunca tuvo nada sale con los datos de la creacion
                ID_OPERACION = :ID_OPERACION_T;
                FECHA_SUCESO = :FECHA_SUCESO_T;
                suspend;
            end
        end
    end
    if (:MULTIPLE IS NULL) then
        exception EX_NO_ENCONTRADO 'El continente no existe o no tiene partes';

    exit;
end
^

ALTER PROCEDURE SPE_LST_ID_ARTICULOS (
    FECHA TIMESTAMP)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    ID_ARTICULO INTEGER)
AS
begin
    for select
        to_articulos.creacion_id_operacion,
        to_articulos.creacion_fecha_suceso,
        to_articulos.id_articulo
    from
        to_articulos
    where
        to_articulos.creacion_eliminado = 0 and
        ((:fecha is null) or (to_articulos.creacion_fecha_suceso <= :fecha))
    into
        :id_operacion,
        :fecha_suceso,
        :id_articulo

    do
        suspend;
    exit;
end
^

ALTER PROCEDURE SPE_LST_VALORES_ATRIB_ART (
    FECHA TIMESTAMP)
RETURNS (
    ID_OPERACION INTEGER,
    FECHA_SUCESO TIMESTAMP,
    ID_ARTICULO INTEGER,
    ID_ATRIBUTO INTEGER,
    VALOR VARCHAR(255))
AS
begin
    for select
        TO_ARTICULOS.ID_ARTICULO,
        TP_ATRIB_ART.ID_ATRIBUTO
    from
        SPE_LST_ID_ARTICULOS(:fecha)
        inner join TO_ARTICULOS on TO_ARTICULOS.ID_ARTICULO = SPE_LST_ID_ARTICULOS.ID_ARTICULO
        inner join TP_ATRIB_ART on TP_ATRIB_ART.IDP_ARTICULO = TO_ARTICULOS.IDP_ARTICULO
    into
        :id_articulo,
        :id_atributo
    do
    begin
        execute procedure SPE_GET_VALOR_ATRIB_ART (
            :fecha,
            :id_articulo,
            :id_atributo)
        returning_values (
            :id_operacion,
            :fecha_suceso,
            :valor);
        suspend;
    end
    exit;
end
^

ALTER PROCEDURE SPI_SEL_OPERACION (
    ID_SUCESO INTEGER,
    ID_OPERACION INTEGER,
    TIPO_OPERACION CHAR(1))
RETURNS (
    ID_OPERACION_O INTEGER)
AS
begin
    if ((:ID_OPERACION is null) or (:ID_OPERACION = 0)) then
    begin
        ID_OPERACION_O = gen_id(gen_to_operaciones_id,1);
        insert into to_operaciones (
            to_operaciones.id_operacion,
            to_operaciones.id_suceso,
            to_operaciones.tipo)
        values (
            :ID_OPERACION_O,
            :id_suceso,
            :TIPO_OPERACION);
    end
    else
        ID_OPERACION_O = :ID_OPERACION;
  exit;
end
^

ALTER PROCEDURE SPO_NEW_INFORME (
    FECHA_RECEPCION TIMESTAMP,
    DESCRIPCION VARCHAR(255))
RETURNS (
    ID_INFORME INTEGER)
AS
begin
    ID_INFORME = gen_id(gen_TO_INFORMES_id,1);
    insert into TO_INFORMES (
        ID_INFORME,
        fecha_recepcion,
        DESCRIPCION,
        user_name
        )
    values     (
        :ID_INFORME,
        :fecha_recepcion,
        :DESCRIPCION,
        current_user);
  exit;
end
^

ALTER PROCEDURE SPO_NEW_SUCESO (
    ID_INFORME INTEGER,
    FECHA_SUCESO TIMESTAMP,
    DESCRIPCION VARCHAR(255))
RETURNS (
    ID_SUCESO INTEGER)
AS
begin
    ID_SUCESO = gen_id(gen_TO_SUCESOS_id,1);
    insert into TO_SUCESOS (
        ID_SUCESO,
        ID_INFORME,
        FECHA_SUCESO,
        DESCRIPCION)
    values     (
        :id_suceso, 
        :ID_INFORME,
        :fecha_SUCESO,
        :DESCRIPCION);
  exit;
end
^

ALTER PROCEDURE SPP_DEL_ARTICULO (
    NBP_ARTICULO VARCHAR(20))
AS
begin
    update TP_ARTICULOS
    set
        TP_ARTICULOS.ELIMINADO = TP_ARTICULOS.IDP_ARTICULO
    where TP_ARTICULOS.NBP_ARTICULO = :NBP_ARTICULO;
  EXIT;
end
^

ALTER PROCEDURE SPP_DEL_ATRIB_ART (
    NB_ATRIBUTO VARCHAR(20),
    NBP_ARTICULO VARCHAR(20))
AS
declare variable IDP_ARTICULO varchar(20) character set none;
declare variable idatributo varchar(20) character set none;
begin
    EXECUTE PROCEDURE SPS_GET_ID(:NBP_ARTICULO,'ESPECIF') RETURNING_VALUES :IDP_ARTICULO;
    EXECUTE PROCEDURE SPS_GET_ID(:NB_ATRIBUTO,'ATRIBUTO') RETURNING_VALUES :IDATRIBUTO;
    DELETE FROM TP_ATRIB_ART
    WHERE
        TP_ATRIB_ART.ID_ATRIBUTO = :IDATRIBUTO
        AND TP_ATRIB_ART.IDP_ARTICULO = :IDP_ARTICULO;
  EXIT;
end
^

ALTER PROCEDURE SPP_DEL_ATRIBUTO (
    NB_ATRIBUTO VARCHAR(20))
AS
begin
    update TP_ATRIBUTOS
    set
        TP_ATRIBUTOS.ELIMINADO = TP_ATRIBUTOS.ID_ATRIBUTO
    where TP_ATRIBUTOS.NB_ATRIBUTO = :NB_ATRIBUTO;
  suspend;
end
^

ALTER PROCEDURE SPP_DEL_PARTE (
    NB_PARTE VARCHAR(20),
    NBP_CONTINENTE VARCHAR(20))
AS
declare variable IDP_CONTINENTE integer;
begin
    EXECUTE PROCEDURE SPS_GET_ID(:NBP_CONTINENTE,'ESPECIF') RETURNING_VALUES :IDP_CONTINENTE;
    update TP_PARTES
    set
        TP_PARTES.ELIMINADO = TP_PARTES.ID_PARTE
    where TP_PARTES.NB_PARTE = :NB_PARTE and TP_PARTES.IDP_CONTINENTE = :IDP_CONTINENTE;
  EXIT;
end
^

ALTER PROCEDURE SPP_EDT_ATRIB_ART (
    NB_ATRIBUTO VARCHAR(20),
    NBP_ARTICULO VARCHAR(20),
    DEFECTO VARCHAR(255))
AS
declare variable idatributo integer;
declare variable IDP_ARTICULO integer;
begin
    EXECUTE PROCEDURE SPS_GET_ID(:NBP_ARTICULO,'ESPECIF') RETURNING_VALUES :IDP_ARTICULO;
    EXECUTE PROCEDURE SPS_GET_ID(:NB_ATRIBUTO,'ATRIBUTO') RETURNING_VALUES :IDATRIBUTO;
    update TP_ATRIB_ART
    SET DEFECTO = :defecto
    WHERE
        TP_ATRIB_ART.ID_ATRIBUTO = :IDATRIBUTO
        AND TP_ATRIB_ART.IDP_ARTICULO = :IDP_ARTICULO;
  EXIT;
end
^

ALTER PROCEDURE SPP_EDT_ATRIBUTO (
    NB_ATRIBUTO_ACTUAL VARCHAR(20),
    NB_ATRIBUTO_NUEVO VARCHAR(20),
    DEFECTONUEVO VARCHAR(255))
AS
begin
    update TP_ATRIBUTOS
    set
        TP_ATRIBUTOS.NB_ATRIBUTO = :NB_ATRIBUTO_NUEVO,
        TP_ATRIBUTOS.defecto = :DEFECTONUEVO

    where TP_ATRIBUTOS.NB_ATRIBUTO = :NB_ATRIBUTO_ACTUAL;
  exit;
end
^

ALTER PROCEDURE SPP_LST_ARTICULOS (
    FESPECIFICACION VARCHAR(20),
    FUBICABLE CHAR(1),
    FCONTENIBLE CHAR(1),
    FCONTINENTE CHAR(1))
RETURNS (
    IDP_ARTICULO INTEGER,
    NBP_ARTICULO VARCHAR(20),
    UBICABLE CHAR(1),
    CONTENIBLE CHAR(1),
    CONTINENTE CHAR(1))
AS
begin
    FOR select
            TP_ARTICULOS.IDP_ARTICULO,
            TP_ARTICULOS.NBP_ARTICULO,
            TP_ARTICULOS.ubicable,
            TP_ARTICULOS.contenible,
            TP_ARTICULOS.continente
        from
            TP_ARTICULOS
        where
            TP_ARTICULOS.eliminado = 0
        --FILTRO POR nombre
        and (:fespecificacion is null or :fespecificacion = '' or
            TP_ARTICULOS.NBP_ARTICULO like :fespecificacion
            )
        --FILTRO POR UBICABLE
        and (:fubicable is null or :fubicable = 'I' or
            TP_ARTICULOS.ubicable = :fubicable
            )
        --FILTRO POR CONTENIBLE
        and (:fcontenible is null or :fcontenible = 'I' or
            TP_ARTICULOS.contenible = :fcontenible
            )
        --FILTRO POR CONTINENTE
        and (:fcontinente is null or :fcontinente = 'I' or
            TP_ARTICULOS.continente = :fcontinente
            )
     into
        :IDP_ARTICULO,
        :NBP_ARTICULO,
        :ubicable,
        :contenible,
        :continente
     DO
        suspend;
     EXIT;
end
^

ALTER PROCEDURE SPP_LST_ATRIB_ART (
    ESPECIFICACION VARCHAR(20))
RETURNS (
    NBP_ARTICULO VARCHAR(20),
    NB_ATRIBUTO VARCHAR(20),
    TIPO CHAR(1),
    DEFECTO VARCHAR(255))
AS
declare variable IDP_ARTICULO integer;
begin
    FOR SELECT
        TP_ARTICULOS.NBP_ARTICULO,
        TP_ATRIBUTOS.NB_ATRIBUTO,
        TP_ATRIBUTOS.tipo,
        TP_ATRIB_ART.defecto
    FROM
        TP_ATRIBUTOS
        inner JOIN TP_ATRIB_ART ON TP_ATRIBUTOS.ID_ATRIBUTO = TP_ATRIB_ART.ID_ATRIBUTO
        inner JOIN TP_ARTICULOS ON TP_ARTICULOS.IDP_ARTICULO = TP_ATRIB_ART.IDP_ARTICULO
    where
        :especificacion IS NULL or
        :especificacion = '' or
        TP_ARTICULOS.NBP_ARTICULO = :especificacion
    into
        :NBP_ARTICULO,
        :NB_ATRIBUTO,
        :tipo,
        :defecto
    DO
        SUSPEND;
  EXIT;
end
^

ALTER PROCEDURE SPP_LST_ATRIBUTOS (
    FATRIBUTOPOS VARCHAR(20),
    FTIPO CHAR(1))
RETURNS (
    ID_ATRIBUTO INTEGER,
    NB_ATRIBUTO VARCHAR(20),
    TIPO CHAR(1),
    DEFECTO VARCHAR(255))
AS
begin
    FOR select
            TP_ATRIBUTOS.ID_ATRIBUTO,
            TP_ATRIBUTOS.NB_ATRIBUTO,
            TP_ATRIBUTOS.tipo,
            TP_ATRIBUTOS.defecto
        from
            TP_ATRIBUTOS
        where
            TP_ATRIBUTOS.eliminado = 0
        --FILTRO POR nombre
        and (:fatributopos is null or :fatributopos = '' or
            TP_ATRIBUTOS.NB_ATRIBUTO like :fatributopos
            )
        --FILTRO POR TIPO
        and (:ftipo is null or :ftipo = 'I' or
            TP_ATRIBUTOS.tipo = :ftipo
            )
     into
        :ID_ATRIBUTO,
        :NB_ATRIBUTO,
        :tipo,
        :defecto
     DO
        suspend;
     EXIT;
end
^

ALTER PROCEDURE SPP_LST_PARTES (
    NCONTINENTE VARCHAR(20))
RETURNS (
    NB_PARTE VARCHAR(20),
    MULTIPLE CHAR(1),
    NBP_CONTINENTE VARCHAR(20),
    NBP_CONTENIBLE VARCHAR(20))
AS
begin
    FOR
    SELECT
        TP_PARTES.NB_PARTE,
        TP_PARTES.multiple,
        ECONTI.NBP_ARTICULO,
        ECONTE.NBP_ARTICULO
    FROM
        TP_PARTES
    INNER JOIN
        TP_ARTICULOS ECONTI
        ON
        ECONTI.IDP_ARTICULO = TP_PARTES.IDP_CONTINENTE
        INNER JOIN
            TP_ARTICULOS ECONTE
            ON ECONTE.IDP_ARTICULO = TP_PARTES.IDP_CONTENIBLE
    WHERE
        TP_PARTES.ELIMINADO = 0 and (
            (((:ncontinente is null) or (:ncontinente = '')) and (ECONTI.eliminado = 'F'))
            OR ECONTI.NBP_ARTICULO = :ncontinente)
    INTO :NB_PARTE, :multiple, :NBP_CONTINENTE, :NBP_CONTENIBLE
    DO
      suspend;
end
^

ALTER PROCEDURE SPP_NEW_ARTICULO (
    NBP_ARTICULO VARCHAR(20),
    UBICABLE CHAR(1),
    CONTENIBLE CHAR(1),
    CONTINENTE CHAR(1))
RETURNS (
    IDP_ARTICULO INTEGER)
AS
begin
    IDP_ARTICULO = gen_id(gen_TP_ARTICULOS_id,1);
    insert into TP_ARTICULOS (IDP_ARTICULO, NBP_ARTICULO, ubicable, contenible, continente)
        values     (:IDP_ARTICULO, :NBP_ARTICULO, :ubicable, :contenible, :continente);
  exit;
end
^

ALTER PROCEDURE SPP_NEW_ATRIB_ART (
    NB_ATRIBUTO VARCHAR(20),
    NBP_ARTICULO VARCHAR(20),
    DEFECTO VARCHAR(255))
AS
declare variable idatributo integer;
declare variable IDP_ARTICULO integer;
begin
    EXECUTE PROCEDURE SPS_GET_ID(:NBP_ARTICULO,'ESPECIF') RETURNING_VALUES :IDP_ARTICULO;
    EXECUTE PROCEDURE SPS_GET_ID(:NB_ATRIBUTO,'ATRIBUTO') RETURNING_VALUES :IDATRIBUTO;
    insert into TP_ATRIB_ART
        (IDP_ARTICULO, ID_ATRIBUTO, defecto)
        values (:IDP_ARTICULO, :idatributo, :defecto);
  EXIT;
end
^

ALTER PROCEDURE SPP_NEW_ATRIBUTO (
    NB_ATRIBUTO VARCHAR(20),
    TIPO CHAR(1),
    DEFECTO VARCHAR(255))
RETURNS (
    IDATRIBUTO INTEGER)
AS
begin
    idATRIBUTO = gen_id(gen_TP_ATRIBUTOS_id,1);
    insert into TP_ATRIBUTOS (ID_ATRIBUTO, NB_ATRIBUTO, tipo, DEFECTO)
        values     (:idATRIBUTO, :NB_ATRIBUTO, :tipo, :DEFECTO);
  exit;
end
^

ALTER PROCEDURE SPP_NEW_PARTE (
    NB_PARTE VARCHAR(20),
    MULTIPLE CHAR(1),
    NBP_CONTINENTE VARCHAR(20),
    NBP_CONTENIBLE VARCHAR(20))
RETURNS (
    ID_PARTE INTEGER)
AS
declare variable IDP_CONTINENTE integer;
declare variable IDP_CONTENIBLE integer;
begin
    EXECUTE PROCEDURE SPS_GET_ID(:NBP_CONTINENTE,'ESPECIF') RETURNING_VALUES :IDP_CONTINENTE;
    EXECUTE PROCEDURE SPS_GET_ID(:NBP_CONTENIBLE,'ESPECIF') RETURNING_VALUES :IDP_CONTENIBLE;
    ID_PARTE = GEN_ID(gen_TP_PARTES_id,1);
    INSERT INTO TP_PARTES (
        ID_PARTE, 
        NB_PARTE,
        multiple, 
        IDP_CONTINENTE,
        IDP_CONTENIBLE)
    VALUES (
        :ID_PARTE,
        :NB_PARTE,
        :multiple,
        :IDP_CONTINENTE,
        :IDP_CONTENIBLE);
  EXIT;
end
^

ALTER PROCEDURE SPP_REN_ARTICULO (
    NBP_ARTICULO_ACTUAL VARCHAR(20),
    NBP_ARTICULO_NUEVO VARCHAR(20))
AS
begin
    update TP_ARTICULOS
    set
        TP_ARTICULOS.NBP_ARTICULO = :NBP_ARTICULO_nuevo
    where TP_ARTICULOS.NBP_ARTICULO = :NBP_ARTICULO_actual;
  EXIT;
end
^

ALTER PROCEDURE SPP_REN_PARTE (
    NB_PARTE VARCHAR(20),
    NBP_CONTINENTE VARCHAR(20),
    NB_PARTE_NUEVO VARCHAR(20))
AS
declare variable IDP_CONTINENTE integer;
begin
    EXECUTE PROCEDURE SPS_GET_ID(:NBP_CONTINENTE,'ESPECIF') RETURNING_VALUES :IDP_CONTINENTE;
    update TP_PARTES
    set
        TP_PARTES.NB_PARTE = :NB_PARTE_NUEVO
    where TP_PARTES.NB_PARTE = :NB_PARTE and TP_PARTES.IDP_CONTINENTE = :IDP_CONTINENTE;
  EXIT;
end
^

ALTER PROCEDURE SPS_GET_ID (
    NOMBRE VARCHAR(20),
    CLASE VARCHAR(20))
RETURNS (
    ID INTEGER)
AS
begin
    begin
        if (CLASE='ESPECIF') then
        begin
                select IDP_ARTICULO
                    from TP_ARTICULOS
                    where NBP_ARTICULO=:NOMBRE
                    into :id;
        end
        else
        begin
            if (CLASE='ATRIBUTO') then
            begin
                select ID_ATRIBUTO
                from TP_ATRIBUTOS
                where NB_ATRIBUTO = :NOMBRE
                into :id;
            end
            else
            begin
                exception EX_CLASE_ID_DESCONOCIDA;
            end
        end
    end
    if (:id is null) then
    begin
        exception EX_NO_ENCONTRADO;
    end
    exit;
end
^

ALTER PROCEDURE SPS_VRF_ADMINCLAVES
AS
begin
  exit;
end
^

ALTER PROCEDURE SPS_VRF_ROL_CONFIGURADOR
AS
begin
    if (current_user = 'ADMINCLAVES') then
        exception EX_ADMINCLAVES_NO;
  exit;
end
^

ALTER PROCEDURE SPS_VRF_ROL_USUARIO
AS
begin
    if (current_user = 'ADMINCLAVES') then
        exception EX_ADMINCLAVES_NO;
  exit;
end
^

ALTER PROCEDURE SZ_LIMPIAR_CAMBIOS
AS
begin
    delete from TC_ATRIB_ART;
    delete from TC_PARTE_ART;
    delete from TO_ARTICULOS;
    delete from TO_OPERACIONES;
    delete from TO_SUCESOS;
    delete from TO_INFORMES;
  exit;
end
^


SET TERM ; ^


/******************************************************************************/
/****                                Roles                                 ****/
/******************************************************************************/

CREATE ROLE ROL_CONFIGURADOR;
CREATE ROLE ROL_USUARIO;


/******************************************************************************/
/****                             Descriptions                             ****/
/******************************************************************************/

DESCRIBE DOMAIN D_TIPO_ATRIB
'I deberia significar indeterminado';

DESCRIBE DOMAIN D_TIPO_CAMBIO
'I deberia significar indeterminado';

DESCRIBE DOMAIN D_TIPO_OPERACION
'I deberia significar indeterminado
A SIGNIFICA CREACION DE ARTICULOS
B CAMBIAR ATRIBUTO DE ARTICULOS
C AGREGAR COMPONENTE
D QUITAR COMPONENTE';

DESCRIBE DOMAIN D_VALOR_ATRIB
'I es indeterminado';



/******************************************************************************/
/****                             Descriptions                             ****/
/******************************************************************************/

DESCRIBE PROCEDURE SPC_REM_PARTES_ART_1
'Este sp sirve para quitar el contenible indicado de la parte de continente a
la que está asociado
Se executa con execute';

DESCRIBE PROCEDURE SPE_GET_CONTENIDO_CONTE
'Obtiene el estado contenido (o no de un artículo contenible)
Valor + significa contenido
Valor - significa no contenido';

DESCRIBE PROCEDURE SPE_LST_CONTE_PARTE_CONTI
'Devuelve los articulos contenidos de la parte de un artículo continente
valor no va ya que si esta vacia no se devuelve nada.';



/* Fields descriptions */

DESCRIBE FIELD TIPO TABLE TO_OPERACIONES
'I deberia significar indeterminado
A SIGNIFICA CREACION DE ARTICULOS
B CAMBIAR ATRIBUTO DE ARTICULOS
C AGREGAR COMPONENTE
D QUITAR COMPONENTE';



/******************************************************************************/
/****                              Privileges                              ****/
/******************************************************************************/


/* Privileges of users */
GRANT EXECUTE ON PROCEDURE SPS_VRF_ADMINCLAVES TO ADMINCLAVES;
GRANT ROL_CONFIGURADOR TO ADMINCLAVES WITH ADMIN OPTION;
GRANT ROL_USUARIO TO ADMINCLAVES WITH ADMIN OPTION;
GRANT ROL_CONFIGURADOR TO CFG;
GRANT SELECT ON RDB$ROLES TO PUBLIC;
GRANT EXECUTE ON PROCEDURE SPP_LST_ARTICULOS TO PUBLIC;
GRANT EXECUTE ON PROCEDURE SPP_LST_ATRIBUTOS TO PUBLIC;
GRANT EXECUTE ON PROCEDURE SPP_LST_ATRIB_ART TO PUBLIC;
GRANT EXECUTE ON PROCEDURE SPP_LST_PARTES TO PUBLIC;
GRANT EXECUTE ON PROCEDURE SPS_GET_ID TO PUBLIC;
GRANT ROL_USUARIO TO USR;
GRANT SELECT ON TP_ARTICULOS TO VTP_ARTICULOS;
GRANT SELECT ON TP_ATRIBUTOS TO VTP_ATRIBUTOS;
GRANT SELECT ON TP_ARTICULOS TO VTP_PARTES_ART;
GRANT SELECT ON TP_PARTES TO VTP_PARTES_ART;

/* Privileges of roles */
GRANT EXECUTE ON PROCEDURE SPP_DEL_ARTICULO TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_DEL_ATRIBUTO TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_DEL_ATRIB_ART TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_DEL_PARTE TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_EDT_ATRIBUTO TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_EDT_ATRIB_ART TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_LST_ATRIB_ART TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_NEW_ARTICULO TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_NEW_ATRIBUTO TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_NEW_ATRIB_ART TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_NEW_PARTE TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_REN_ARTICULO TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPP_REN_PARTE TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPS_VRF_ROL_CONFIGURADOR TO ROL_CONFIGURADOR;
GRANT EXECUTE ON PROCEDURE SPC_ADD_PARTE_ART TO ROL_USUARIO;
GRANT EXECUTE ON PROCEDURE SPC_EDT_ATRIB_ART TO ROL_USUARIO;
GRANT EXECUTE ON PROCEDURE SPC_NEW_ARTICULOS TO ROL_USUARIO;
GRANT EXECUTE ON PROCEDURE SPC_REM_PARTES_ART_1 TO ROL_USUARIO;
GRANT EXECUTE ON PROCEDURE SPC_REM_PARTES_ART_2 TO ROL_USUARIO;
GRANT EXECUTE ON PROCEDURE SPO_NEW_INFORME TO ROL_USUARIO;
GRANT EXECUTE ON PROCEDURE SPO_NEW_SUCESO TO ROL_USUARIO;
GRANT EXECUTE ON PROCEDURE SPS_VRF_ROL_USUARIO TO ROL_USUARIO;

/* Privileges of triggers */
GRANT SELECT, UPDATE ON TC_ATRIB_ART TO TRIGGER TC_ATRIB_ART_BI;
GRANT SELECT ON TO_ARTICULOS TO TRIGGER TC_ATRIB_ART_BI;
GRANT SELECT ON TO_OPERACIONES TO TRIGGER TC_ATRIB_ART_BI;
GRANT SELECT ON TO_SUCESOS TO TRIGGER TC_ATRIB_ART_BI;
GRANT SELECT ON TP_ATRIB_ART TO TRIGGER TC_ATRIB_ART_BI;
GRANT EXECUTE ON PROCEDURE SPE_GET_VALOR_ATRIB_ART TO TRIGGER TC_ATRIB_ART_BI;
GRANT EXECUTE ON PROCEDURE SPE_LST_ID_ARTICULOS TO TRIGGER TC_ATRIB_ART_BI;
GRANT UPDATE ON TC_PARTE_ART TO TRIGGER TC_PARTE_ART_BI;
GRANT SELECT ON TO_ARTICULOS TO TRIGGER TC_PARTE_ART_BI;
GRANT SELECT ON TO_OPERACIONES TO TRIGGER TC_PARTE_ART_BI;
GRANT SELECT, UPDATE ON TO_SUCESOS TO TRIGGER TC_PARTE_ART_BI;
GRANT SELECT ON TP_PARTES TO TRIGGER TC_PARTE_ART_BI;
GRANT EXECUTE ON PROCEDURE SPE_GET_CONTENIDO_CONTE TO TRIGGER TC_PARTE_ART_BI;
GRANT EXECUTE ON PROCEDURE SPE_GET_DISP_PARTE_CONTI TO TRIGGER TC_PARTE_ART_BI;
GRANT EXECUTE ON PROCEDURE SPE_LST_ID_ARTICULOS TO TRIGGER TC_PARTE_ART_BI;
GRANT INSERT ON TC_ATRIB_ART TO TRIGGER TO_ARTICULOS_AI0;
GRANT SELECT ON TO_ARTICULOS TO TRIGGER TO_ARTICULOS_AI0;
GRANT SELECT ON TP_ATRIB_ART TO TRIGGER TO_ARTICULOS_AI0;
GRANT SELECT, UPDATE ON TO_ARTICULOS TO TRIGGER TO_ARTICULOS_BI;
GRANT SELECT ON TO_OPERACIONES TO TRIGGER TO_ARTICULOS_BI;
GRANT SELECT ON TO_SUCESOS TO TRIGGER TO_ARTICULOS_BI;
GRANT SELECT ON TP_ARTICULOS TO TRIGGER TP_ARTICULOS_DBR13;
GRANT SELECT, INSERT ON TP_ARTICULOS TO TRIGGER TP_ARTICULOS_NUM;
GRANT INSERT ON TC_ATRIB_ART TO TRIGGER TP_ATRIB_ART_AI0;
GRANT SELECT ON TO_ARTICULOS TO TRIGGER TP_ATRIB_ART_AI0;
GRANT SELECT ON TP_ATRIBUTOS TO TRIGGER TP_ATRIB_ART_DBR09;
GRANT SELECT, UPDATE ON TP_ATRIB_ART TO TRIGGER TP_ATRIB_ART_DBR09;
GRANT SELECT ON TP_ARTICULOS TO TRIGGER TP_PARTES_DBR11;

/* Privileges of procedures */
GRANT INSERT ON TC_PARTE_ART TO PROCEDURE SPC_ADD_PARTE_ART;
GRANT SELECT ON TO_ARTICULOS TO PROCEDURE SPC_ADD_PARTE_ART;
GRANT SELECT ON TP_PARTES TO PROCEDURE SPC_ADD_PARTE_ART;
GRANT EXECUTE ON PROCEDURE SPI_SEL_OPERACION TO PROCEDURE SPC_ADD_PARTE_ART;
GRANT INSERT ON TC_ATRIB_ART TO PROCEDURE SPC_EDT_ATRIB_ART;
GRANT INSERT ON TO_OPERACIONES TO PROCEDURE SPC_EDT_ATRIB_ART;
GRANT SELECT ON TP_ATRIBUTOS TO PROCEDURE SPC_EDT_ATRIB_ART;
GRANT EXECUTE ON PROCEDURE SPI_SEL_OPERACION TO PROCEDURE SPC_EDT_ATRIB_ART;
GRANT SELECT, INSERT ON TO_ARTICULOS TO PROCEDURE SPC_NEW_ARTICULOS;
GRANT SELECT, INSERT ON TO_OPERACIONES TO PROCEDURE SPC_NEW_ARTICULOS;
GRANT SELECT ON TP_ARTICULOS TO PROCEDURE SPC_NEW_ARTICULOS;
GRANT EXECUTE ON PROCEDURE SPI_SEL_OPERACION TO PROCEDURE SPC_NEW_ARTICULOS;
GRANT INSERT ON TC_PARTE_ART TO PROCEDURE SPC_REM_PARTES_ART_1;
GRANT EXECUTE ON PROCEDURE SPE_GET_CONTENIDO_CONTE TO PROCEDURE SPC_REM_PARTES_ART_1;
GRANT EXECUTE ON PROCEDURE SPI_SEL_OPERACION TO PROCEDURE SPC_REM_PARTES_ART_1;
GRANT INSERT ON TC_PARTE_ART TO PROCEDURE SPC_REM_PARTES_ART_2;
GRANT SELECT ON TO_ARTICULOS TO PROCEDURE SPC_REM_PARTES_ART_2;
GRANT SELECT ON TP_PARTES TO PROCEDURE SPC_REM_PARTES_ART_2;
GRANT EXECUTE ON PROCEDURE SPE_LST_CONTE_PARTE_CONTI TO PROCEDURE SPC_REM_PARTES_ART_2;
GRANT EXECUTE ON PROCEDURE SPI_SEL_OPERACION TO PROCEDURE SPC_REM_PARTES_ART_2;
GRANT SELECT ON TC_PARTE_ART TO PROCEDURE SPE_GET_CONTENIDO_CONTE;
GRANT SELECT ON TO_ARTICULOS TO PROCEDURE SPE_GET_CONTENIDO_CONTE;
GRANT SELECT ON TP_ARTICULOS TO PROCEDURE SPE_GET_CONTENIDO_CONTE;
GRANT SELECT ON TC_PARTE_ART TO PROCEDURE SPE_GET_DISP_PARTE_CONTI;
GRANT SELECT ON TO_ARTICULOS TO PROCEDURE SPE_GET_DISP_PARTE_CONTI;
GRANT SELECT ON TP_ARTICULOS TO PROCEDURE SPE_GET_DISP_PARTE_CONTI;
GRANT SELECT ON TP_PARTES TO PROCEDURE SPE_GET_DISP_PARTE_CONTI;
GRANT SELECT ON TC_ATRIB_ART TO PROCEDURE SPE_GET_VALOR_ATRIB_ART;
GRANT SELECT ON TO_ARTICULOS TO PROCEDURE SPE_GET_VALOR_ATRIB_ART;
GRANT SELECT ON TP_ATRIB_ART TO PROCEDURE SPE_GET_VALOR_ATRIB_ART;
GRANT SELECT ON TC_PARTE_ART TO PROCEDURE SPE_LST_CONTE_PARTE_CONTI;
GRANT SELECT ON TO_ARTICULOS TO PROCEDURE SPE_LST_CONTE_PARTE_CONTI;
GRANT SELECT ON TP_ARTICULOS TO PROCEDURE SPE_LST_CONTE_PARTE_CONTI;
GRANT SELECT ON TP_PARTES TO PROCEDURE SPE_LST_CONTE_PARTE_CONTI;
GRANT SELECT ON TC_PARTE_ART TO PROCEDURE SPE_LST_DISP_PARTE_CONTI;
GRANT SELECT ON TO_ARTICULOS TO PROCEDURE SPE_LST_DISP_PARTE_CONTI;
GRANT SELECT ON TP_ARTICULOS TO PROCEDURE SPE_LST_DISP_PARTE_CONTI;
GRANT SELECT ON TP_PARTES TO PROCEDURE SPE_LST_DISP_PARTE_CONTI;
GRANT SELECT ON TO_ARTICULOS TO PROCEDURE SPE_LST_ID_ARTICULOS;
GRANT SELECT ON TO_ARTICULOS TO PROCEDURE SPE_LST_VALORES_ATRIB_ART;
GRANT SELECT ON TP_ATRIB_ART TO PROCEDURE SPE_LST_VALORES_ATRIB_ART;
GRANT EXECUTE ON PROCEDURE SPE_LST_ID_ARTICULOS TO PROCEDURE SPE_LST_VALORES_ATRIB_ART;
GRANT SELECT, INSERT ON TO_OPERACIONES TO PROCEDURE SPI_SEL_OPERACION;
GRANT INSERT ON TO_INFORMES TO PROCEDURE SPO_NEW_INFORME;
GRANT SELECT, INSERT ON TO_SUCESOS TO PROCEDURE SPO_NEW_SUCESO;
GRANT SELECT, UPDATE ON TP_ARTICULOS TO PROCEDURE SPP_DEL_ARTICULO;
GRANT SELECT, UPDATE ON TP_ATRIBUTOS TO PROCEDURE SPP_DEL_ATRIBUTO;
GRANT SELECT, DELETE ON TP_ATRIB_ART TO PROCEDURE SPP_DEL_ATRIB_ART;
GRANT SELECT, UPDATE ON TP_PARTES TO PROCEDURE SPP_DEL_PARTE;
GRANT SELECT, UPDATE ON TP_ATRIBUTOS TO PROCEDURE SPP_EDT_ATRIBUTO;
GRANT SELECT, UPDATE ON TP_ATRIB_ART TO PROCEDURE SPP_EDT_ATRIB_ART;
GRANT SELECT ON TP_ARTICULOS TO PROCEDURE SPP_LST_ARTICULOS;
GRANT SELECT ON TP_ATRIBUTOS TO PROCEDURE SPP_LST_ATRIBUTOS;
GRANT SELECT ON TP_ARTICULOS TO PROCEDURE SPP_LST_ATRIB_ART;
GRANT SELECT ON TP_ATRIBUTOS TO PROCEDURE SPP_LST_ATRIB_ART;
GRANT SELECT ON TP_ATRIB_ART TO PROCEDURE SPP_LST_ATRIB_ART;
GRANT SELECT ON TP_ARTICULOS TO PROCEDURE SPP_LST_PARTES;
GRANT SELECT ON TP_PARTES TO PROCEDURE SPP_LST_PARTES;
GRANT INSERT ON TP_ARTICULOS TO PROCEDURE SPP_NEW_ARTICULO;
GRANT INSERT ON TP_ATRIBUTOS TO PROCEDURE SPP_NEW_ATRIBUTO;
GRANT INSERT ON TP_ATRIB_ART TO PROCEDURE SPP_NEW_ATRIB_ART;
GRANT INSERT ON TP_PARTES TO PROCEDURE SPP_NEW_PARTE;
GRANT SELECT, UPDATE ON TP_ARTICULOS TO PROCEDURE SPP_REN_ARTICULO;
GRANT SELECT, UPDATE ON TP_PARTES TO PROCEDURE SPP_REN_PARTE;
GRANT SELECT ON TP_ARTICULOS TO PROCEDURE SPS_GET_ID;
GRANT SELECT ON TP_ATRIBUTOS TO PROCEDURE SPS_GET_ID;
