CREATE TABLE t_solicitante ( id_solicitante serial NOT NULL, dni_tipo numeric(3), dni_nro character varying(8), apellido character varying(150), nombre character varying(150), fecha_nac date, id_sexo numeric(3), domicilio character varying, id_localidad integer, fecha_hora_aud timestamp without time zone DEFAULT now(), id_usuario integer, CONSTRAINT key_sol PRIMARY KEY (id_solicitante) ) WITH OIDS; CREATE TABLE t_feriados ( id_feriado serial NOT NULL, fecha_feriado date, descripcion character varying(150), fecha_hora_aud timestamp without time zone DEFAULT now(), usuario_aud character varying(20), CONSTRAINT t_feriados_pkey PRIMARY KEY (id_feriado) ) WITHOUT OIDS; CREATE TABLE t_turnos ( id_turno integer NOT NULL DEFAULT nextval('t_turnos_id_turno_seq1'::regclass), fecha_turno date, hora_turno time without time zone, num_turno integer, estado integer, pg_usuario character varying DEFAULT "current_user"(), fecha_hora timestamp without time zone DEFAULT now(), id_usuario integer, id_turneable integer, id_tipo_turno integer, CONSTRAINT t_turnos_pkey PRIMARY KEY (id_turno) ) WITHOUT OIDS; CREATE TABLE t_turnos_parametros ( id_parametros serial NOT NULL, fecha_desde date, fecha_hasta date, hora_desde time without time zone, hora_hasta time without time zone, puestos integer, tiempo_atencion integer, intervalo integer, apartirde integer, cant_turnos integer, fin_de_semana integer, id_tipo_turno integer, id_usuario integer, pg_usuario character varying DEFAULT "current_user"(), fecha_hora timestamp without time zone DEFAULT now(), CONSTRAINT tturnos_parametros_pkey PRIMARY KEY (id_parametros), CONSTRAINT fk_idusuario FOREIGN KEY (id_usuario) REFERENCES sistema.t_usuarios (idusuario) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE NO ACTION ) WITHOUT OIDS; CREATE TYPE d_turno AS (idturno integer, fecha date, hora time without time zone, numero integer, estado integer, fechahora timestamp without time zone, idusuario integer, idturneable integer, idtipoturno integer); CREATE OR REPLACE FUNCTION f_turnos_asignar(p_id_turno integer, p_idturneable integer, p_idusuario integer, p_tabla character varying) RETURNS integer AS $BODY$ declare estado integer; c integer; begin /* Asigna el turno p_id_turno al Turneable p_idturneable */ execute 'select estado from '||p_tabla ||' where id_turno='||p_id_turno ||' for update' into estado; if estado=0 OR estado=1 then execute 'update '||p_tabla ||' set estado=2, id_turneable='|| p_idturneable ||',id_usuario='||p_idusuario||',pg_usuario=CURRENT_USER, fecha_hora=now() where id_turno=' ||p_id_turno; GET DIAGNOSTICS c= ROW_COUNT; if (c>0) then return 1; else return 0; end if; else return 0; end if; end; $BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER; CREATE OR REPLACE FUNCTION f_turnos_dame_parametros(p_turno_tipo integer, p_cuando date, tabla_parametros character varying) RETURNS SETOF t_turnos_parametros AS $BODY$declare -- Obtengo los parametros para un turno_tipo y una fecha determinada resultado t_turnos_parametros%ROWTYPE; begin for resultado in execute 'select * from '||tabla_parametros||' p where p.id_tipo_turno='||p_turno_tipo||' and p.fecha_desde <= '''||p_cuando||''' and (p.fecha_hasta >='''||p_cuando||''' or p.fecha_hasta is null)' loop return next resultado; end loop; end; $BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER; CREATE OR REPLACE FUNCTION f_turnos_guardarparametros(p_tipo_turno integer, p_fecha_dsd date, p_fecha_hst date, p_hora_dsd time without time zone, p_hora_hst time without time zone, p_intervalo smallint, p_t_atencion integer, p_apartirde integer, p_fin_de_semana integer, p_puestos integer, p_id_usuario smallint, tabla_parametros character varying, tabla_turnos character varying) RETURNS integer AS $BODY$ declare r_t_turnosparam t_turnos_parametros%rowtype; wid_turnos_param bigint; i integer ; begin set datestyle = 'sql,dmy'; -- nuevo ID execute 'select nextval(\''||tabla_parametros||'_idparametros_seq\')' into wid_turnos_param ; if(wid_turnos_param>0) then -- inserto los parametros --insert into tturnos_parametros (idparametros, fecha_desde, fecha_hasta, hora_desde, hora_hasta, puestos, tiempo_atencion, fechahora, fin_de_semana, idusuario, pgusuario) --values (wid_turnos_param,desde, hasta, hora_dsd, hora_hst, cant_puestos, periodicidad, now(),op_fin_d_semana,id_usuario, current_user); execute 'insert into '||tabla_parametros ||'(id_parametros, fecha_desde, fecha_hasta, hora_desde, hora_hasta,intervalo,apartirde, fecha_hora, fin_de_semana,id_tipo_turno,puestos,tiempo_atencion, id_usuario, pg_usuario) values ('||wid_turnos_param||',\''||p_fecha_dsd||'\',\''||p_fecha_hst||'\',\''||p_hora_dsd||'\',\''||p_hora_hst||'\','|| p_intervalo||','|| p_apartirde||',now(),'||p_fin_de_semana||','||p_tipo_turno||','||p_puestos||','||p_t_atencion||','||p_id_usuario||', current_user)'; execute 'select * from '|| tabla_parametros ||' where id_parametros = '|| wid_turnos_param into r_t_turnosparam ; -- exploto los paramatros perform f_turnosexplotar(r_t_turnosparam, tabla_turnos); return 1; else RAISE EXCEPTION 'No se pede generar nuevo idparametro'; return 0; end if; end;$BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER; CREATE OR REPLACE FUNCTION f_turnos_hay(p_turno_tipo integer, p_tabla character varying) RETURNS integer AS $BODY$ declare idturno integer; c integer; resultado t_turnos_parametros%ROWTYPE; begin /* Reserva el primer turno disponible a partir de "p_lapso" dias a partir de la fecha actual */ perform f_turnos_refresh(p_tabla); execute 'select * from f_turnos_dame_parametros('||p_turno_tipo||',now()::date,'||p_tabla||')' into resultado; if(resultado.id_parametros is not null) then execute 'select id_turno from '|| p_tabla ||' where id_turno=(select f_turnos_siguiente('||p_turno_tipo||','||resultado.apartirde ||',\''|| p_tabla||'\')) ' into idturno; if(idturno>0) then return idturno; else return 0; end if; else return 0; end if; end; $BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER; CREATE OR REPLACE FUNCTION f_turnos_ofid(id integer) RETURNS SETOF d_turno AS $BODY$ /* New function body */ DECLARE r public.d_turno; BEGIN select id_turno as idturno , fecha_turno as fecha, hora_turno as hora, num_turno as numero, estado as estado, fecha_hora as fechahora, id_usuario as idusuario, id_turneable as idturneable, id_tipo_turno as idtipoturno from public.t_turnos t where t.id_turno=$1 into r ; return next r; end $BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER; CREATE OR REPLACE FUNCTION f_turnos_refresh(p_tabla character varying) RETURNS integer AS $BODY$ declare i integer; c integer; begin /* Pone en 1 el campo disponible de la tabla tturnos_credito de los registros que lo tienen en 1 y pasaron 5 minutos dedesde la hora registrada en el campo fechahora RETORNA 1 si se modifico algun registro 0 si no se modifico algun registro */ execute 'update ' || p_tabla || ' set estado=0,fecha_hora=now(), id_usuario=NULL where id_turno in( select id_turno from '|| p_tabla ||' tc where estado=1 and (select (5-(select extract(epoch from ((select now()) - tc.fecha_hora::timestamp)) / 60)))<0 )'; --select * from tturnos_credito GET DIAGNOSTICS c= ROW_COUNT; if (c>0) then return 1; else return 0; end if; end;$BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER; CREATE OR REPLACE FUNCTION f_turnos_reservar(p_turno_tipo integer, p_tabla character varying, p_tabla_parametros character varying, p_id_usuario integer) RETURNS integer AS $BODY$ declare idturno integer; c integer; resultado t_turnos_parametros%ROWTYPE; begin /* Reserva el primer turno disponible a partir de "p_lapso" dias a partir de la fecha actual */ perform f_turnos_refresh(p_tabla); execute 'select * from f_turnos_dame_parametros('||p_turno_tipo||', now()::date,'''|| p_tabla_parametros ||''')' into resultado; if(resultado.id_parametros is not null) then execute 'select id_turno from '|| p_tabla ||' where id_turno=(select f_turnos_siguiente('||p_turno_tipo||','||resultado.apartirde ||','''|| p_tabla||''')) for update' into idturno; if(idturno>0) then execute 'update '||p_tabla||' set estado=1, id_usuario='||p_id_usuario||', fecha_hora=now() where id_turno='||idturno; GET DIAGNOSTICS c= ROW_COUNT; if (c>0) then return idturno; else return 0; end if; else return 0; end if; else return 0; end if; end; $BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER; CREATE OR REPLACE FUNCTION f_turnos_siguiente(p_turno_tipo integer, p_lapso integer, p_tabla character varying) RETURNS integer AS $BODY$ declare idturno integer; begin /* Devuelve el id del primer turno disponible a partir de "p_lapso" dias a partir de la fecha actual */ execute 'select id_turno from '|| p_tabla||' where (fecha_turno || \' \' || hora_turno)::timestamp =( select min((fecha_turno || \' \' || hora_turno)::timestamp) from '|| p_tabla||' where estado=0 and fecha_turno>=(now()::date+('||p_lapso||'|| \' day\')::interval) and id_tipo_turno='||p_turno_tipo||' ) and id_tipo_turno='||p_turno_tipo||' and id_turneable is null limit 1 for update ' into idturno ; return idturno; end; $BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER; CREATE OR REPLACE FUNCTION f_turnos_turneable_tieneturno(p_id_turneable integer, t_turneable character varying, t_tabla character varying) RETURNS SETOF d_turno AS $BODY$ /* New function body */ DECLARE r d_turno; BEGIN FOR r IN execute 'select tt.* from '||t_turneable||' ts inner join '||t_tabla||' tt ON (tt.id_turneable=ts.id) where id=p_id_turneable' LOOP return NEXT r; END LOOP; END $BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER; CREATE OR REPLACE FUNCTION f_turnosexplotar(t_parametro t_turnos_parametros, tabla_turnos character varying) RETURNS void AS $BODY$ declare cturnos integer; cdias integer; dia_d_semana integer; v_incluyedia boolean; fecha date; hora time; divs integer; en_horario integer; new_id int4; c_esferiado integer; num_turno integer; begin set datestyle = 'sql,dmy'; cdias := (t_parametro.fecha_hasta - t_parametro.fecha_desde) + 1; fecha := t_parametro.fecha_desde; -- borra los libres execute 'delete from '||tabla_turnos||' where id_turneable is null and fecha_turno >=\''|| t_parametro.fecha_desde ||'\' and fecha_turno <=\''|| t_parametro.fecha_hasta ||'\' and hora_turno >= \''||t_parametro.hora_desde||'\' and hora_turno <= \''||t_parametro.hora_hasta ||'\' and id_tipo_turno='||t_parametro.id_tipo_turno||''; for i in 1..cdias loop --es feriado el dia o fin de semana? select into dia_d_semana extract(dow from fecha); raise notice 'dia d semana: %', dia_d_semana; -- Controla que no sea feriado c_esferiado := 0; select count(*) into c_esferiado from t_feriados where t_feriados.fecha_feriado = fecha; -- op_fin_d_semana, -- Sab =6 Dom = 0 -- valores: 0: Lunes a Viernes Sab6no Dom0no -- 1: Lunes a Sabados 6si 0no -- 2: sabados y domingos 6si 0si v_incluyedia := true ; if t_parametro.fin_de_semana = 0 and (dia_d_semana = 0 or dia_d_semana = 6) then v_incluyedia := false; end if; if t_parametro.fin_de_semana = 1 and (dia_d_semana = 0) then v_incluyedia := false; end if; if t_parametro.fin_de_semana = 2 and (dia_d_semana = 0 or dia_d_semana = 6) then v_incluyedia := true; end if; if (c_esferiado = 0) and v_incluyedia then hora := t_parametro.hora_desde; num_turno:=0; --si pongo <= da turnos hasta hora_hasta 'osea que tengo turno despues de hora hasta' while hora < t_parametro.hora_hasta loop -- cant de turnos disponibles en esa hora execute 'select count(*) from '|| tabla_turnos ||' tt where tt.hora_turno = \''|| hora ||'\' and tt.fecha_turno = \''||fecha ||'\' and tt.id_tipo_turno='||t_parametro.id_tipo_turno into cturnos ; if cturnos < t_parametro.puestos then cturnos := t_parametro.puestos - cturnos - 1; for nturno in 0..cturnos loop num_turno:=num_turno+1; --puedo usar como num de box a nturno execute 'insert into '||tabla_turnos||'(fecha_turno, hora_turno, num_turno,estado, fecha_hora, id_tipo_turno,id_usuario) values (\''||fecha||'\',\''|| hora ||'\','|| num_turno ||', 0, now(),'|| t_parametro.id_tipo_turno ||','|| t_parametro.id_usuario ||')'; end loop; end if; --hora := hora + ('00:' || t_parametro.tiempo_atencion || ':00')::interval; hora := hora + (t_parametro.tiempo_atencion || ' min')::interval; end loop; end if; fecha := fecha + 1; end loop; return ; end; $BODY$ LANGUAGE 'plpgsql' VOLATILE SECURITY DEFINER;