create or replace procedure SPAD_GuardaPlanInvenMens(pplan number,pfechaInicial date,pfechaFinal date,particulo varchar2,
								pintervalo number,pescalar number,pdia number) is
	VResSet sys_refcursor;
	pidplan number;
	pfecha date;
	pfecha2 date;
	pdia2 number;
	pdia3 number;
	pconteo number;
	pagregar number;
	pmes1 number;
	pmes2 number;
	pDiaAgregado number;
begin
	--verifica si existe el plan de inventario
	--si no existe, lo agrega
	--si existe, lo actualiza
	--si el plan es de otro tipo, lo transforma.
	--primero verifico que ya tiene un id
	if pplan=0 then
		--hay que agregarlo, por lo que obtengo el id siguiente
		select nvl(max(ID_PLAN),0)+1 into pidplan from CAB_PLANIFICA_INVENTARIO; 
	else
		--es una actualizacion
		pidplan:=pplan;
	end if;
	open vresset for select '1' from CAB_PLANIFICA_INVENTARIO where ID_PLAN=pidplan;
	if not existe(vresset) then
		--no existe, por lo que hay que agregarlo
		insert into CAB_PLANIFICA_INVENTARIO
		(ID_PLAN,cve_articulo,ID_PERIODO,DESCRIPCION,FECHA_INI,FECHA_FIN,INTERVALO,ID_EXCALAR,DIA_MES,MES_YEAR,DIAS_LABORABLES)
		values(pidplan,particulo,4,'',pfechaInicial,pfechaFinal,pintervalo,pescalar,pdia,0,'N');
		--agrego la lista de dias de la semana que hay que tomar encuenta
		if pescalar>0 then
			--se elijio la opcion de escalar (primer, segundo,ultimo,etc)
			if pdia >=1 and pdia <=7 then
				insert into REL_DS_PLAN (ID_PLAN,ID_DIA)values(pidplan,pdia);
			end if;
			--si es es uno de los dias especiales como dia,dia de la semana,dia del fin de semana, 
			--no agrega nada a la relacion de dias de semana
		end if;
		--agrego los detalles
--		SET DATEFIRST 1
		pfecha:=pfechaInicial;
		pconteo:=0; --el conteo es mensual
		pDiaAgregado:=0;
		while pfechaFinal>=pfecha
		loop
			pdia2:=to_char(pfecha,'DD'); --extraigo el dia del mes
			if(pconteo mod pintervalo)=0 then --se deve tomar encuenta la fecha
				--APLICO LA RESTRICCION DE LOS DIAS FESTIVOS QUE NO SE TRABAJAN
				open vresset for SELECT '1' FROM CAT_DIAS_FESTIVOS WHERE to_char(FECHA,'dd/mm/yy')=to_char(pfecha,'dd/mm/yy');
				IF NOT EXISTE(VRESSET) THEN
					--checo si se selecciono por dias de la semana
					if pescalar>0 then
						--es por escalar
						--veo si es por dia de la semana
						if pdia>=1 and pdia<=7 then
							--si es por dia de la semana, por lo que le aplico las restricciones
--							--SET DATEFIRST 1
							pdia3:=DiaSem(pfecha);
							open vresset for SELECT '1' FROM REL_DS_PLAN WHERE ID_DIA=pdia3 AND ID_PLAN=pidplan;
							IF EXISTe(vresset) then
								--aplico el escalar
								pagregar:=0;
								if pescalar=1 then --es el primer
									if pdia2<8 then
										pagregar:=1;
									end if;
								end if;
								if pescalar=2 then --es el seguundo
									if pdia2>7 and pdia2<15	then
										pagregar:=1;
									end if;
								end if;
								if pescalar=3 then --es el tercer
									if pdia2>14 and pdia2<22 then
										pagregar:=1;
									end if;
								end if;
								if pescalar=4 then --es el cuarto
									if pdia2>21 and pdia2<29 then
										pagregar:=1;
									end if;
								end if;
								if pescalar=5 then --es el ultimo
									pmes1:=substr(to_char(pfecha,'dd/mm/yy'),4,2);
									pfecha2:=pfecha+7;
									pmes2:=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
									if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
										pagregar:=1;
									end if;
								end if;
								if pagregar=1 then
								--si hay que agrgarlo
									insert into DET_PLANIFICA_INVENTARIO
									(ID_PLAN,FECHA_APLICA,cve_articulo,status)
									values (pidplan,pfecha,particulo,'A');
								end if;
							END if;						
						else
							--como no es por dia de la semana, tengo que checar las demas
							--OPCIONES
							pagregar:=0;
------------------------------------------
							if pescalar=1 then --es el primer		
								if pdia=8 then --es el primer dia del mes
									if pdia2=1 then
										pagregar:=1;
  									end if;
								end if;
								if pdia=9 then --primer dia de la semana
									if pdia2<8 then --no ha pasado la primer semana
										--SET DATEFIRST 1
										pdia3:=DiaSem(pfecha);
										if pdia3<6 then --no es ni sabado ni domingo
											--ya se agrego el primer dia
											if pDiaAgregado=0 then
												pagregar:=1;
												pDiaAgregado:=1;
											end if;
										end if;
									end if;
								end if;						
								if pdia=10 then --es el primer fin de semana
									if pdia2<8 then --no ha pasado la primer semana
										--SET DATEFIRST 1
										pdia3:=DiaSem(pfecha);
										if pdia3=6 or pdia3=7 then --Es sabado o domingo
											pagregar:=1;
										end if;
									end if;
								end if;						
							end if;
							-------------------------------------
							if pescalar=2 then --es el seguundo		
								if pdia=8 then --es el segundo dia del mes
									if pdia2=2 then
										pagregar:=1;
									end if;
								end if;
								if pdia=9 then --segundo dia de la semana
									if pdia2<8 then --no ha pasado la primer semana
										--SET DATEFIRST 1
										pdia3:=DiaSem(pfecha);
										if pdia3<6 then --no es ni sabado ni domingo
											--ya se agrego el primer dia
											if pDiaAgregado=1 then
												pagregar:=1;
												pDiaAgregado:=pDiaAgregado+1;
											else
												pDiaAgregado:=pDiaAgregado+1;
											end if;
										end if;
									end if;
								end if;						
								if pdia=10 then --es el segundo fin de semana
									if pdia2>7 and pdia2<15 then --estoy en el rango de la segunda semana
										--SET DATEFIRST 1
										pdia3:=DiaSem(pfecha);
										if pdia3=6 or pdia3=7 then --Es sabado o domingo												
											pagregar:=1;
										end if;
									end if;
								end if;						
							end if;
							-------------------------------------------------------------
							if pescalar=3 then --es el tercer		
								if pdia=8 then --es el tercer dia del mes
									if pdia2=3 then
										pagregar:=1;
									end if;
								end if;
								if pdia=9 then --tercer dia de la semana
									if pdia2<8 then --no ha pasado la primer semana
										--SET DATEFIRST 1
										pdia3:=DiaSem(pfecha);
										if pdia3<6 then --no es ni sabado ni domingo
											--pasaron el primero y segundo dia
											if pDiaAgregado=2 then
												pagregar:=1;
												pDiaAgregado:=pDiaAgregado+1;
											else
												pDiaAgregado:=pDiaAgregado+1;
											end if;
										end if;
									end if;
								end if;						
								if pdia=10 then --es el tercer fin de semana
									if pdia2>14 and pdia2<22 then --estoy en el rango de la tercer semana
										--SET DATEFIRST 1
										pdia3:=DiaSem(pfecha);
										if pdia3=6 or pdia3=7 then --Es sabado o domingo												
											pagregar:=1;
										end if;
									end if;
								end if;						
							end if;
							-----------------------------------------------------------------
							if pescalar=4 then --es el cuarto		
								if pdia=8 then --es el cuarto dia del mes
									if pdia2=4 then
										pagregar:=1;
									end if;
								end if;
								if pdia=9 then --cuarto dia de la semana
									if pdia2<8 then --no ha pasado la primer semana
										--SET DATEFIRST 1
										pdia3:=DiaSem(pfecha);
										if pdia3<6 then --no es ni sabado ni domingo
											--pasaron el primero y segundo dia
											if pDiaAgregado=3 then
												pagregar:=1;
												pDiaAgregado:=pDiaAgregado+1;
											else
												pDiaAgregado:=pDiaAgregado+1;
											end if;
										end if;
									end if;
								end if;						
								if pdia=10 then --es el cuarto fin de semana
									if pdia2>21 and pdia2<29 then --estoy en el rango de la tercer semana
										--SET DATEFIRST 1
										pdia3:=DiaSem(pfecha);
										if pdia3=6 or pdia3=7 then --Es sabado o domingo												
											pagregar:=1;
										end if;
									end if;
								end if;						
							end if;
							-----------------------------------------------------------------
							if pescalar=5 then --es el ultimo		
								if pdia=8 then --es el ultimo dia del mes
									pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
									pfecha2:=pfecha+1;
									pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
									if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
										pagregar:=1;
									end if;
								end if;
								if pdia=9 then --ultimo dia de la semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3<5 then --no es ni viernes ni sabado ni domingo
										pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
										pfecha2:=pfecha+1;
										pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
										if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
											pagregar:=1;
										end if;
									elsif pdia3=5 then -- es viernes
										pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
										pfecha2:=pfecha+3;
										pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
										if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
											pagregar:=1;
										end if;
									end if;
								end if;						
								if pdia=10 then --es el ultimo fin de semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3=6 or pdia3=7 then --Es sabado o domingo
										pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
										pfecha2:=pfecha+7;
										pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
										if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
											pagregar:=1;
										end if;
									end if;
								end if;						
							end if;
							if pagregar=1 then --si hay que agrgarlo
								insert into DET_PLANIFICA_INVENTARIO
								(ID_PLAN,FECHA_APLICA,cve_articulo,status)
								values (pidplan,pfecha,particulo,'A');
							end if;
							-----------------------------------------------------------------
						end if;
					else
						--es un dia del mes en especifico por ejemplo los 21 de cada mes
						if pdia2=pdia then
							insert into DET_PLANIFICA_INVENTARIO
							(ID_PLAN,FECHA_APLICA,cve_articulo,status)
							values (pidplan,pfecha,particulo,'A');
						end if;
					end if;
				END if;
			end if;
-------------------------
			pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
			pfecha2:=pfecha+1;
			pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
			if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
				pconteo:=pconteo+1;
				pDiaAgregado :=0;
			end if;
			pfecha:=pfecha+1;
		end loop;
		return;
	end if;


	--como si existe, elimino los detalles que pertenescan a id
	delete DET_PLANIFICA_INVENTARIO where ID_PLAN=pidplan;
	--veo si tiene relacion de semanas y las elimino
	delete REL_DS_PLAN where ID_PLAN=pidplan;
	--actualizo el registro maestro
	update CAB_PLANIFICA_INVENTARIO 
	set 
		cve_articulo=particulo
		,ID_PERIODO=4
		,DESCRIPCION=''
		,FECHA_INI=pfechaInicial
		,FECHA_FIN=pfechaFinal
		,INTERVALO=pintervalo
		,ID_EXCALAR=pescalar
		,DIA_MES=pdia
		,MES_YEAR=0
		,DIAS_LABORABLES='N'
	where 
		ID_PLAN=pidplan;
		--agrego la lista de dias de la semana que hay que tomar encuenta
	if pescalar>0 then
		--se elijio la opcion de escalar (primer, segundo,ultimo,etc)
		if pdia >=1 and pdia <=7 then
			insert into REL_DS_PLAN (ID_PLAN,ID_DIA)values(pidplan,pdia);
		end if;
		--si es es uno de los dias especiales como dia,dia de la semana,dia del fin de semana, 
		--no agrega nada a la relacion de dias de semana
	end if;
	--agrego los detalles
	--SET DATEFIRST 1
	pfecha:=pfechaInicial;
	pconteo:=0; --el conteo es mensual
	while pfechaFinal>=pfecha
	loop
		pdia2:=to_char(sysdate,'dd'); --extraigo el dia del mes
		if(pdia2=1) then --es primero de mes
			pconteo:=pconteo+1;
			pDiaAgregado :=0;
		end if;
		if(pconteo mod pintervalo)=0 then --se deve tomar encuenta la fecha
			--APLICO LA RESTRICCION DE LOS DIAS FESTIVOS QUE NO SE TRABAJAN
			open vresset for SELECT '1' FROM CAT_DIAS_FESTIVOS 
                                         WHERE to_char(FECHA,'dd/mm/yy')=to_char(pfecha,'dd/mm/yy');
			IF NOT EXISTe(vresset) then
				--checo si se selecciono por dias de la semana
				if pescalar>0 then
					--es por escalar
					--veo si es por dia de la semana
					if pdia>=1 and pdia<=7 then
						--si es por dia de la semana, por lo que le aplico las restricciones
						open vresset for SELECT '1' FROM REL_DS_PLAN WHERE ID_DIA=pdia AND ID_PLAN=pidplan;
						IF EXISTe(vresset) then
							--aplico el escalar
							pagregar:=0;
							if pescalar=1 then --es el primer
								if pdia2<8 then
									pagregar:=1;
								end if;
							end if;
							if pescalar=2 then --es el seguundo
								if pdia2<15 then	
									pagregar:=1;
								end if;
							end if;
							if pescalar=3 then --es el tercer
								if pdia2<22 then
									pagregar:=1;
								end if;
							end if;
							if pescalar=4 then --es el cuarto
								if pdia2<29 then
									pagregar:=1;
								end if;
							end if;
							if pescalar=5 then --es el ultimo
								pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
								pfecha2:=pfecha+7;
								pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
								if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
									pagregar:=1;
								end if;
							end if;
							if pagregar=1 then
							--si hay que agrgarlo
								insert into DET_PLANIFICA_INVENTARIO
								(ID_PLAN,FECHA_APLICA,cve_articulo,status)
								values (pidplan,pfecha,particulo,'A');
							end if;
						END if;
					else
						--como no es por dia de la semana, tengo que checar las demas
						--OPCIONES
						pagregar:=0;
-----------------------------------------
						if pescalar=1 then --es el primer		
							if pdia=8 then --es el primer dia del mes
								if pdia2=1 then
									pagregar:=1; 
								end if;
							end if;
							if pdia=9 then --primer dia de la semana
								if pdia2<8 then --no ha pasado la primer semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3<6 then --no es ni sabado ni domingo
										--ya se agrego el primer dia
										if pDiaAgregado=0 then
											pagregar:=1;
											pDiaAgregado:=0;
										end if;
									end if;
								end if;
							end if;						
							if pdia=10 then --es el primer fin de semana
								if pdia2<8 then --no ha pasado la primer semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3=6 or pdia3=7 then --Es sabado o domingo
										pagregar:=1;
									end if;
								end if;
							end if;						
						end if;
						-------------------------------------
						if pescalar=2 then --es el seguundo		
							if pdia=8 then --es el segundo dia del mes
								if pdia2=2 then
									pagregar:=1;
								end if;
							end if;
							if pdia=9 then --segundo dia de la semana
								if pdia2<8 then --no ha pasado la primer semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3<6 then --no es ni sabado ni domingo
										--ya se agrego el primer dia
										if pDiaAgregado=1 then
											pagregar:=1;
										else
											pDiaAgregado:=pDiaAgregado+1;
										end if;
									end if;
								end if;
							end if;						
							if pdia=10 then --es el segundo fin de semana
								if pdia2>7 and pdia2<15 then --estoy en el rango de la segunda semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3=6 or pdia3=7 then --Es sabado o domingo												
										pagregar:=1;
									end if;
								end if;
							end if;						
						end if;
						-------------------------------------------------------------
						if pescalar=3 then --es el tercer		
							if pdia=8 then --es el tercer dia del mes
								if pdia2=3 then
									pagregar:=1;
								end if;	
							end if;
							if pdia=9 then --tercer dia de la semana
								if pdia2<8 then --no ha pasado la primer semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3<6 then --no es ni sabado ni domingo
										--pasaron el primero y segundo dia
										if pDiaAgregado=2 then
											pagregar:=1;
										else
											pDiaAgregado:=pDiaAgregado+1;
										end if;
									end if;
								end if;
							end if;				
							if pdia=10 then --es el tercer fin de semana
								if pdia2>14 and pdia2<22 then --estoy en el rango de la tercer semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3=6 or pdia3=7 then --Es sabado o domingo												
										pagregar:=1;
									end if;
								end if;
							end if;						
						end if;
						-----------------------------------------------------------------
						if pescalar=4 then --es el cuarto		
							if pdia=8 then --es el cuarto dia del mes
								if pdia2=4 then
									pagregar:=1;
								end if;
							end if;
							if pdia=9 then --cuarto dia de la semana
								if pdia2<8 then --no ha pasado la primer semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3<6 then --no es ni sabado ni domingo
										--pasaron el primero y segundo dia
										if pDiaAgregado=3 then
											pagregar:=1;
										else
											pDiaAgregado:=pDiaAgregado+1;
										end if;
									end if;
								end if;
							end if;						
							if pdia=10 then --es el cuarto fin de semana
								if pdia2>21 and pdia2<29 then --estoy en el rango de la tercer semana
									--SET DATEFIRST 1
									pdia3:=DiaSem(pfecha);
									if pdia3=6 or pdia3=7 then --Es sabado o domingo												
										pagregar:=1;
									end if;
								end if;
							end if;						
						end if;
						-----------------------------------------------------------------
						if pescalar=5 then --es el ultimo		
							if pdia=8 then --es el ultimo dia del mes
								pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
								pfecha2:=pfecha+1;
								pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
								if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
									pagregar:=1;
								end if;
							end if;
							if pdia=9 then --ultimo dia de la semana
								--SET DATEFIRST 1
								pdia3:=DiaSem(pfecha);
								if pdia3<5 then --no es ni viernes ni sabado ni domingo
									pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
									pfecha2:=pfecha+1;
									pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
									if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
										pagregar:=1;
									end if;
								elsif pdia=6 then -- es viernes
									pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
									pfecha2:=pfecha+2;
									pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
									if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
										pagregar:=1;
									end if;
								end if;
							end if;						
							if pdia=10 then --es el ultimo fin de semana
								if pdia3=6 or pdia3=7 then --Es sabado o domingo												
									pmes1 :=substr(to_char(pfecha,'dd/mm/yy'),4,2);
									pfecha2:=pfecha+7;
									pmes2 :=substr(to_char(pfecha2,'dd/mm/yy'),4,2);
									if pmes1<>pmes2 then --como cambio de mes, significa que si es el ultimo de mes
										pagregar:=1;
									end if;
								end if;
							end if;						
						end if;
						if pagregar=1 then --si hay que agrgarlo
							insert into DET_PLANIFICA_INVENTARIO
							(ID_PLAN,FECHA_APLICA,cve_articulo,status)
							values (pidplan,pfecha,particulo,'A');
						end if;
						-----------------------------------------------------------------
					end if;
				else
					--es un dia del mes en especifico por ejemplo los 21 de cada mes
					if pdia2=pdia then
						insert into DET_PLANIFICA_INVENTARIO
						(ID_PLAN,FECHA_APLICA,cve_articulo,status)
						values (pidplan,pfecha,particulo,'A');
					end if;
				end if;
			END if;
		end if;
		pfecha:=pfecha+1;
	end loop;
end;

/