CREATE OR REPLACE PACKAGE ESTUTL IS
   PINI1    NUMBER(8);
   PFIN1    NUMBER(8);
   PINI2    NUMBER(8);
   PFIN2    NUMBER(8);
   FINI1    DATE;
   FFIN1    DATE;
   FINI2    DATE;
   FFIN2    DATE;

   PROCEDURE INICIAR(TIPOPER IN CHAR, 
                     VINI1 DATE, VFIN1 DATE,
                     VINI2 DATE default NULL,
                     VFIN2 DATE default NULL);

   FUNCTION NUMPER(PERIODO IN NUMBER) RETURN NUMBER;
      PRAGMA RESTRICT_REFERENCES (NUMPER, WNDS, WNPS);

   FUNCTION INICIO(LIM IN NUMBER) RETURN NUMBER;
      PRAGMA RESTRICT_REFERENCES (INICIO, WNDS, WNPS);

   FUNCTION FINAL(LIM IN NUMBER) RETURN NUMBER;
      PRAGMA RESTRICT_REFERENCES (FINAL, WNDS, WNPS);

   FUNCTION NUMPER(PERIODO IN DATE) RETURN NUMBER;
      PRAGMA RESTRICT_REFERENCES (NUMPER, WNDS, WNPS);

   FUNCTION INICIOF(LIM IN NUMBER) RETURN DATE;
      PRAGMA RESTRICT_REFERENCES (INICIOF, WNDS, WNPS);

   FUNCTION FINALF(LIM IN NUMBER) RETURN DATE;
    PRAGMA RESTRICT_REFERENCES (FINALF, WNDS, WNPS);

   FUNCTION TRIMESTRE(PERIODO IN NUMBER) RETURN NUMBER;
    PRAGMA RESTRICT_REFERENCES (TRIMESTRE, WNDS, WNPS);

   Procedure FiscalAEst(pCia in Varchar2, pPeriodo in Number, pPerIni out Number, 
                        pPerFin out Number);
  	                   
   Function FiscalAEst(pCia in Varchar2, pPeriodo in Number) Return Number;

END;
/

CREATE OR REPLACE PACKAGE BODY ESTUTL IS

   kTipoEst     Varchar2(1) := 'N';
   kConvertible Boolean;
   kCia         Varchar2(3);

   PROCEDURE INICIAR(TIPOPER IN CHAR,
                     VINI1 DATE, VFIN1 DATE,
                     VINI2 DATE default NULL,
                     VFIN2 DATE default NULL) IS
      vFACTOR  NUMBER(3):=100;
      vFORMATO VARCHAR2(8):='YYYYMM';
   BEGIN
      IF TIPOPER = 'D' THEN
   	 vFACTOR:=1;
         vFORMATO:='YYYYMMDD';
      END IF;
      PINI1:=to_char(VINI1, vFORMATO)*vFACTOR;
      PFIN1:=to_char(VFIN1, vFORMATO)*vFACTOR;
      FINI1:=VINI1;
      FFIN1:=VFIN1;
      IF VINI2 IS NOT NULL THEN
         PINI2:=to_char(VINI2, vFORMATO)*vFACTOR;
       	 PFIN2:=to_char(VFIN2, vFORMATO)*vFACTOR;
         FINI2:=VINI2;
         FFIN2:=VFIN2;
      ELSE
         PINI2:=null;
         PFIN2:=null;
         FINI2:=null;
         FFIN2:=null;
      END IF;
   END;

   FUNCTION NUMPER(PERIODO IN NUMBER) RETURN NUMBER IS
   BEGIN
      IF PERIODO BETWEEN PINI1 AND PFIN1 THEN
   	 RETURN 1;
      ELSIF PERIODO BETWEEN PINI2 AND PFIN2 THEN
         RETURN 2;
      ELSE
   	 RETURN 0;
      END IF;
   END;

   FUNCTION INICIO(LIM IN NUMBER) RETURN NUMBER IS
   BEGIN
      IF LIM=1 THEN
         RETURN PINI1;
      ELSIF LIM=2 THEN
         RETURN PINI2;
      END IF;
   END;

   FUNCTION FINAL(LIM IN NUMBER) RETURN NUMBER IS
   BEGIN
      IF LIM=1 THEN
         RETURN PFIN1;
      ELSIF LIM=2 THEN
         RETURN PFIN2;
      END IF;
   END;

   FUNCTION NUMPER(PERIODO IN DATE) RETURN NUMBER IS
   BEGIN
      IF PERIODO BETWEEN FINI1 AND FFIN1 THEN
   	 RETURN 1;
      ELSIF PERIODO BETWEEN FINI2 AND FFIN2 THEN
         RETURN 2;
      ELSE
   	 RETURN 0;
      END IF;
   END;

   FUNCTION INICIOF(LIM IN NUMBER) RETURN DATE IS
   BEGIN
      IF LIM=1 THEN
         RETURN FINI1;
      ELSIF LIM=2 THEN
         RETURN FINI2;
      END IF;
   END;

   FUNCTION FINALF(LIM IN NUMBER) RETURN DATE IS
   BEGIN
      IF LIM=1 THEN
         RETURN FFIN1;
      ELSIF LIM=2 THEN
         RETURN FFIN2;
      END IF;
   END;

   FUNCTION TRIMESTRE(PERIODO IN NUMBER) RETURN NUMBER IS
   BEGIN
      return trunc(periodo/10000)*100+trunc((mod(periodo,10000)+200)/300);
   END;

   Procedure Inicializa(pCia in Varchar2) Is
   Begin
      If Nvl(kCia, 'xxx') != pCia Then
         kTipoEst := Estadisticas.ObtTipoEst(pCia);
	 kConvertible := Null;
	 kCia := pCia;
      End If;
   End Inicializa;

   Procedure FiscalAEst(pCia in Varchar2, pPeriodo in Number, pPerIni out Number, 
                        pPerFin out Number) IS                      
      vFecIni Date;
      vFecFin Date;                      
   BEGIN
      Inicializa(pCia);
		  
      If kTipoEst = 'F' Then
         pPerIni := pPeriodo*100;
  	 pPerFin := pPerIni;
      Else  
	 vFecIni := CalcGen.InicioPeriodo(pCia, pPeriodo);
  	 vFecFin := CalcGen.FinPeriodo(pCia, pPeriodo);
	  	
  	 If kTipoEst = 'N' Then
	    pPerIni := To_Char(vFecIni, 'YYYYMM')||'00';
  	    pPerFin := To_Char(vFecFin, 'YYYYMM')||'00';
  	 Else
	    pPerIni := To_Char(vFecIni, 'YYYYMMDD');
  	    pPerFin := To_Char(vFecFin, 'YYYYMMDD');
  	 End If;
      End If;  	
   End FiscalAEst;
	
   Function ConvFiscalNatural(pCia in Varchar2, pPeriodo in Number) Return Boolean Is
      vAno          Gen_Periodo.Ano_Fiscal%Type := Trunc(pPeriodo/100);
      vPerAnoFiscal Gen_Periodo.Per_Ano_Fiscal%Type;
      vFecIni       Gen_Periodo_Rango.Fec_Inicio%Type;
   Begin
      If kConvertible Is Null Then
         Select Per_Ano_Fiscal
	   Into vPerAnoFiscal
	 From Gen_Periodo
	 Where Cod_Cia    = pCia
	   And Ano_Fiscal = vAno;
			
	 If vPerAnoFiscal = 12 Then
	    vFecIni := CalcGen.InicioPeriodo(pCia, pPeriodo);			
					
	    If vFecIni = Trunc(vFecIni, 'MONTH') Then
	       kConvertible := True;
	    End If;
	 End If;
      End If;
		
      kConvertible := Nvl(kConvertible, False);
		
      Return kConvertible;
   End ConvFiscalNatural;
	
   Function FiscalAEst(pCia in Varchar2, pPeriodo in Number) Return Number Is
      vFecIni Gen_Periodo_Rango.Fec_Inicio%Type;
   Begin
      Inicializa(pCia);
		
      If kTipoEst In ('F', 'D') Or Not ConvFiscalNatural(pCia, pPeriodo) Then
         Return pPeriodo;
      End If;
		
      vFecIni := CalcGen.InicioPeriodo(pCia, pPeriodo);
			
      Return To_Char(vFecIni, 'YYYYMM');		
   End FiscalAEst;

END;
/
