SET TERM ^ ;

CREATE OR ALTER PROCEDURE MGETIQ_GET_DSCTOS_POL_VOL (
    v_politica_id integer,
    v_articulo_id integer)
returns (
    unidades numeric(18,5),
    descuento numeric(9,6))
as
declare variable encontrado char(1);
declare variable linea_articulo_id integer;
declare variable grupo_linea_id integer;
BEGIN
  /* Obtener la tabla de descuentos por volumen que aplica para el artÃÂÃÂ­culo
     dado, segÃÂÃÂºn la polÃÂÃÂ­tica de descuentos por volumen dada.
     Se utiliza en la consulta de precios y existencias para informar
     el descuento que se puede obtener si se compran mÃÂÃÂ¡s unidades. */
  /* Ubicamos al artÃÂÃÂ­culo en la estructura de excepciones */
  ENCONTRADO = 'N';
  /* Primero buscamos a nivel artÃÂÃÂ­culo */
  FOR SELECT UNIDADES, DESCUENTO
      FROM DSCTOS_VOL_ARTS
      WHERE POLITICA_DSCTO_VOLUMEN_ID = :V_POLITICA_ID
            AND ARTICULO_ID = :V_ARTICULO_ID
      INTO UNIDADES, DESCUENTO
  DO
  BEGIN
   ENCONTRADO = 'S';
   SUSPEND;
  END /* for */
  IF (ENCONTRADO = 'S') THEN EXIT;
  /* Buscar a nivel lÃÂÃÂ­nea */
  /* Obtenemos la lÃÂÃÂ­nea del artÃÂÃÂ­culo */
  SELECT LINEA_ARTICULO_ID
  FROM ARTICULOS
  WHERE ARTICULO_ID = :V_ARTICULO_ID
  INTO LINEA_ARTICULO_ID;
  IF (LINEA_ARTICULO_ID IS NOT NULL) THEN
  BEGIN
    FOR SELECT UNIDADES, DESCUENTO
        FROM DSCTOS_VOL_LINEAS
        WHERE POLITICA_DSCTO_VOLUMEN_ID = :V_POLITICA_ID
              AND LINEA_ARTICULO_ID = :LINEA_ARTICULO_ID
        INTO UNIDADES, DESCUENTO
    DO
    BEGIN
     ENCONTRADO = 'S';
     SUSPEND;
    END /* for */
    IF (ENCONTRADO = 'S') THEN EXIT;
    /* Buscar a nivel grupo */
    /* Obtenemos el grupo de la lÃÂÃÂ­nea (puede no tener) */
    SELECT GRUPO_LINEA_ID
    FROM LINEAS_ARTICULOS
    WHERE LINEA_ARTICULO_ID = :LINEA_ARTICULO_ID
    INTO GRUPO_LINEA_ID;
    IF (GRUPO_LINEA_ID IS NOT NULL) THEN
    BEGIN
      FOR SELECT UNIDADES, DESCUENTO
          FROM DSCTOS_VOL_GRUPOS
               WHERE POLITICA_DSCTO_VOLUMEN_ID = :V_POLITICA_ID
                     AND GRUPO_LINEA_ID = :GRUPO_LINEA_ID
          INTO UNIDADES, DESCUENTO
      DO
      BEGIN
       ENCONTRADO = 'S';
       SUSPEND;
      END /* for */
      IF (ENCONTRADO = 'S') THEN EXIT;
    END /* if Grupo <> Null */
  END /* if Linea <> Null */
  /* Utilizar el nivel global */
 /* FOR SELECT UNIDADES, DESCUENTO
      FROM DSCTOS_VOL_GLOBALES
      WHERE POLITICA_DSCTO_VOLUMEN_ID = :V_POLITICA_ID
      INTO UNIDADES, DESCUENTO
  DO
   SUSPEND;  */
END
^

SET TERM ; ^



SET TERM ^ ;

CREATE OR ALTER PROCEDURE MGETIQ_GET_POLS_DSCTO_VOL_2 (
    v_articulo_id integer,
    v_fecha_venta date)
returns (
    politica_id integer,
    nombre_politica varchar(50),
    descuento numeric(9,6),
    es_exclusivo char(1),
    unidades numeric(18,5))
as
BEGIN 
   /* Este procedimiento obtiene la lista de politicas de descuentos por
      volumen vigentes a la fecha dada, y junto con cada una, el 
      descuento que corresponde al articulo segun se ubique este en la
      estructura de excepciones. */ 
   /* Correccion: Ahora se regresa tambien el Id de la politica de descuentos
      ya que se necesiti para la consulta de precios y existencias.  */
   /* Obtenemos todas las politicas vigentes */
   FOR SELECT POLITICA_DSCTO_VOLUMEN_ID, NOMBRE, ES_DSCTO_EXCLUSIVO 
       FROM POLITICAS_DSCTOS_VOLUMEN 
       WHERE HABILITADA = 'S' AND 
             (ES_PERMANENTE = 'S' OR 
              FECHA_INI_VIGENCIA IS NOT NULL AND 
              :V_FECHA_VENTA BETWEEN FECHA_INI_VIGENCIA AND FECHA_FIN_VIGENCIA) 
       INTO POLITICA_ID, NOMBRE_POLITICA, ES_EXCLUSIVO 
   DO 
   BEGIN 
 /* En este punto tenemos una politica de descuentos por volumen vigente. Obtener de ella el descuento del articulo. */
       FOR 
       SELECT UNIDADES, DESCUENTO 
       FROM MGETIQ_GET_DSCTOS_POL_VOL(:POLITICA_ID, :V_ARTICULO_ID)
       INTO UNIDADES, DESCUENTO 
       DO SUSPEND; 
   END /* for de politicas */
 END
^

SET TERM ; ^


----------*-*-**-*-**-*-**-*-**-*-**-*-**-*-**-*-**-*-**-*-**-*-**-*-*------
SET TERM ^ ;

CREATE OR ALTER PROCEDURE MGETIQ_GET_DSCTO_VOL2 (
    v_articulo_id integer,
    v_fecha_venta date)
returns (
    descuento numeric(9,6),
    fue_topado char(1),
    unidades numeric(18,5))
as
declare variable dscto_mayor_excl numeric(9,6);
declare variable factor double precision;
declare variable es_exclusivo char(1);
declare variable descuento_maximo numeric(9,6);
declare variable unidades_group numeric(18,5);
BEGIN 
   /* Este procedimiento calcula el descuento compuesto que se debe aplicar 
 al articulo segun todas las politicas definidas. Tambien se informa si
 el descuento tuvo que ser topado con el descuento maximo. */
 /* La logica consiste en obtener todos los descuentos que aplican, e ir
 calculando el compuesto. Si hay descuentos exclusivos, se toma el mayor.*/ 
/* Correccion: Ahora regresa ademas los 3 tipos de descuento que componen
 el unificado. */ 
 FOR SELECT UNIDADES 
     FROM MGETIQ_GET_POLS_DSCTO_VOL_2(:V_ARTICULO_ID, :V_FECHA_VENTA)
     GROUP BY UNIDADES ORDER BY UNIDADES 
     INTO UNIDADES_GROUP 
 DO 
 BEGIN 
   DSCTO_MAYOR_EXCL = 0; 
   FACTOR = 1.0; /* para calcular el descuento compuesto */ 
   FOR SELECT DESCUENTO, ES_EXCLUSIVO, UNIDADES 
       FROM MGETIQ_GET_POLS_DSCTO_VOL_2(:V_ARTICULO_ID, :V_FECHA_VENTA)
       WHERE UNIDADES= :UNIDADES_GROUP 
       INTO DESCUENTO, ES_EXCLUSIVO, UNIDADES 
   DO 
   BEGIN 
     IF (ES_EXCLUSIVO = 'S') THEN 
     BEGIN 
       IF (DESCUENTO > DSCTO_MAYOR_EXCL) THEN 
         DSCTO_MAYOR_EXCL = DESCUENTO; 
     END /* if es exclusivo */ 
     ELSE /* no es exclusivo. Solo procesarlo si aun no hay exclusivos. */
       IF (DSCTO_MAYOR_EXCL = 0 AND DESCUENTO > 0) THEN 
         FACTOR = FACTOR * (1.0 - DESCUENTO/100.0); 
   END /* for de descuentos */ 
   /* Si hubo descuento exclusivo, lo tomamos */ 
   IF (DSCTO_MAYOR_EXCL > 0) THEN 
      DESCUENTO = DSCTO_MAYOR_EXCL; 
   ELSE 
     DESCUENTO = (1.0 - FACTOR) * 100.0; 
   /* En este punto tenemos el descuento compuesto. Checar si se debe topar.*/ 
   EXECUTE PROCEDURE MGETIQ_GET_DSCTO_MAX_ART V_ARTICULO_ID, V_FECHA_VENTA
   RETURNING_VALUES DESCUENTO_MAXIMO; 
   IF (DESCUENTO > DESCUENTO_MAXIMO) THEN 
   BEGIN 
     DESCUENTO = DESCUENTO_MAXIMO; 
     FUE_TOPADO = 'S'; 
   END 
   ELSE 
     FUE_TOPADO = 'N'; 
   if ((DESCUENTO<>0) AND (UNIDADES <> 0)) then 
      SUSPEND; 
 END /*FIN GROUP BY*/ 
 END
^

SET TERM ; ^


--*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
SET TERM ^ ;

CREATE OR ALTER PROCEDURE MGETIQ_FORMA_DESCTO (
    articulo_id integer)
returns (
    precio_con_impto numeric(18,6),
    descuento numeric(9,6),
    unidades numeric(18,5),
    precio_con_dscto numeric(18,6))
as
BEGIN

    FOR SELECT DESCUENTO, UNIDADES
    FROM MGETIQ_GET_DSCTO_VOL2 (:ARTICULO_ID, 'NOW')
    INTO DESCUENTO, UNIDADES
    DO
    BEGIN

    SELECT PRECIO_CON_IMPTO
    FROM ORSP_VE_PRECIOS_ART(:ARTICULO_ID, 'N')
    WHERE UPPER(NOMBRE_PRECIO) = 'PRECIO DE LISTA'
    INTO PRECIO_CON_IMPTO;


    PRECIO_CON_DSCTO = (PRECIO_CON_IMPTO * DESCUENTO);

    PRECIO_CON_DSCTO = PRECIO_CON_DSCTO / 100;

    PRECIO_CON_DSCTO = PRECIO_CON_IMPTO - PRECIO_CON_DSCTO;
    
    SUSPEND;
    END


END
^

SET TERM ; ^

