Bases de Datos > SQL Server

 montos erroneos en informe ventas por producto

(1/1)

NICOWEZ:
resulta que tengo un software que genera variados informes de las ventas que este mismo realiza...


informe de ventas por cliente, ventas por vendedor, ventas anuales y ventas por producto.

en este ultimo me entrega datos erroneos, especificamente un valor mas alto al correspondiente.

les dejo el procedimiento almacenado que genera ese informe

estructura de las tablas
img220.imageshack.us/img220/4199/estructuratablas.th.png


editado codigo comentado y resumido solo a boletas de venta

--- Código: Text ---     --sintaxis de tablas--MAE = maestra (encabezado)--DET = detalle--ej. mae_boleta_Venta : guarda encabezados de las boletas de venta--det_boleta_venta : guarda las lineas de detalle de las boletas de venta --sintaxis para los campos de cada tabla--InicialesDeNombreDeTabla_DescripcionCampo--ej. mps_id_producto_servicio--mps viene de la tabla Mae_Producto_Servicio --sintaxis del procedimiento almacenado (sp_tipo_nombre)--tipos de procedimientos almacenados--sel : seleccion--ins : insercion--del : delete -- he estado realizando las pruebas con los 2 primeros parametros en 0-- y con distintas fechas de inicio y final alter PROCEDURE [dbo].[sp_SEL_InfoVentasPorProducto]                @IdProducto numeric, --parametro recibido para filtrar por un producto en especifico, cuando no se filtra recibe un 0        @IdCategoria numeric, --parametro recibido para filtrar por una categoria de producto en especifico, cuando no se filtra recibe un 0             @FechasDesde datetime, --parametro recibido desde el formulario para filtrar las ventas (fecha inicio)        @FechasHasta datetime  --parametro recibido desde el formulario para filtrar las ventas (fecha final)             AS                  declare @MontoBoletas  decimal (26,8)   --variable que almacena el monto total neto de boletas de venta por producto declare @CantidadProductoBOV numeric  --variable almacena cantidad vendida de productos en boleta          --los montos netos deben ser calculados, ya que los precios de venta se almacenan con iva    set @FechasHasta = dateadd(dd,1,@FechasHasta)             --los documentos de venta cuentan con un descuento general (encabezado) y un descuento por linea de detalle--los siguientes 2 updates de las tablas mae_boleta_venta (encabezado boleta) y det_boleta_venta (glosa detalle -- de boleta) calculan el factor de descuento del encabezado que le corresponde a cada detalle para saber-- realmente a cuanto se vendio el producto efectivamente --solo por asegurarme vuelvo a calcular el subtotal bruto de la boleta, correspondiente al total con descuento mas el descuentoupdate mae_boleta_venta  set mbv_subtotal_bruto = mbv_total + mbv_monto_descuento   --el descuento de encabezado es un factor que se calcula dividiendo el monto de descuento general de la boleta por el subtotal de la boleta, --el subtotal de la boleta corresponde a la suma de todos los totales de las lineas o tuplas del detalle de la boleta--el total de la linea, corresponde a el subtotal de la linea menos el descuento de la linea--el subtotal de la linea corresponde a la cantidad vendida por el valor unitario bruto de producto --procedo a calcular el factor que le corresponde a cada linea por descuento general de boleta update det_boleta_venta  set dbv_descuento_encabezado = mae_boleta_venta.mbv_monto_descuento / mae_boleta_venta.mbv_subtotal_bruto  from det_boleta_venta  join mae_boleta_venta   on det_boleta_venta.dbv_id_boleta_venta = mae_boleta_venta.mbv_id_boleta_venta  where mbv_subtotal_bruto > 0     ----------------------------------------------------------------------------------    IF(@IdCategoria=0 AND @IdProducto > 0)     --si no se ingreso categoria de producto y si se ingreso id de producto en formulario BEGIN          --asigno al monto de las boletas el neto de la suma de los detalles con el descuento por encabezado y ya aplicado mediante el calculoset @MontoBoletas = (SELECT  sum(((D.dbv_total*100)/(b.mbv_porcentaje_iva + 100))* (1 - isnull(d.dbv_descuento_encabezado,0)))        FROM MAE_BOLETA_VENTA B --tabla maestra de la boleta (encabezado)           JOIN DET_BOLETA_VENTA D  --tabla detalles de boleta (almacena todas las lineas de productos vendidos)          ON (B.mbv_id_boleta_venta = D.dbv_id_boleta_venta)           JOIN MAE_PRODUCTO_SERVICIO P           ON (P.mps_id_producto_SErvicio = D.dbv_id_producto_servicio)           WHERE (D.dbv_id_producto_servicio = @IdProducto OR @IdProducto=0)  --filtro segun el id de producto ingresado          AND (B.mbv_fecha>=@FechasDesde AND B.mbv_fecha<=@FechasHasta)     --filtro segun rango de fechas ingresadas                      AND  (P.mps_id_categoria_producto_servicio = @IdCategoria OR @IdCategoria=0) --filtro segun id de categorias de producto ingresado          AND B.mbv_nula = 0)    --selecciono solo las boletas que no son nulas             set @CantidadProductoBOV = (SELECT SUM(D.dbv_cantidad)   --sumo la cantidad de productos en el detalle y la asigno a la variable           FROM MAE_BOLETA_VENTA B              JOIN DET_BOLETA_VENTA D              ON (B.mbv_id_boleta_venta = D.dbv_id_boleta_venta)             JOIN MAE_PRODUCTO_SERVICIO P             ON (P.mps_id_producto_SErvicio = D.dbv_id_producto_servicio)             WHERE (D.dbv_id_producto_servicio = @IdProducto OR @IdProducto=0) --filtro segun el id de producto ingresado                    AND (B.mbv_fecha>=@FechasDesde AND B.mbv_fecha<=@FechasHasta) --filtro segun rango de fechas ingresado                                  AND  (p.mps_id_categoria_producto_servicio = @IdCategoria OR @IdCategoria=0) --filtro segun el id de categoria de producto ingresado             AND B.mbv_nula = 0) --selecciono solo las boletas que no son nulas                   if(@MontoBoletas is null)   --si el monto de las boletas es nulo le asigno un 0 set @MontoBoletas = 0            if(@CantidadProductoBOV is null)      --si la cantidad de productos en boleta es nulo le asigno un 0 set @MontoBoletas = 0                  SELECT       MAE_PRODUCTO_SERVICIO.mps_id_producto_servicio AS IdProducto, --id producto para manejo interno de consultas (llave primaria)     MAE_PRODUCTO_SERVICIO.mps_descripcion AS NombreProducto, --el nombre del producto p ej.: 'Coca Cola'     MAE_PRODUCTO_SERVICIO.mps_codigo_barra AS CodigoProducto, --codigo producto manejado por usuario de sw  (codigo barras)   isnull(@MontoBoletas,0) AS MontoBoletas,      isnull(@MontoFacturas,0) AS MontoFacturas,      isnull(@MontoNotaCreditoVenta,0) AS MontoNotaCreditoVenta,      isnull(@MontoTotalVentas,0) AS MontoTotalVentas,      isnull(@CantidadProducto,0) as Cantidad,      isnull(mps_precio_venta,0) as PrecioVenta --precio bruto unitario del producto      FROM MAE_PRODUCTO_SERVICIO    --table donde se guardan todos los datos que corresponden al producto  WHERE      (MAE_PRODUCTO_SERVICIO.mps_id_producto_servicio = @IdProducto or @IdProducto=0) AND  --que el id del producto sea igual al que me ingresaron o el parametro venga en 0 lo                                                                                     ---que hace que el informe liste todos los productos y no un producto especifico    (MAE_PRODUCTO_SERVICIO.mps_id_categoria_producto_servicio=@IdCategoria OR @IdCategoria=0) --y que este en la categoria ingresada o que no filtre categorias                   END                  IF(@IdCategoria>=0 AND @IdProducto=0)  --si no me ingresaron id de producto y me ingresaron o no un id de categoria de producto   BEGIN            declare @TotalProdCat numeric   -- variable para almecenar la cantidad de tuplas en #TempIdProddeclare @Contador numeric  --contador para recorrer la tabla  #TempIdProd  declare @IdProd numeric   --variable auxiliar para filtr        declare @PrecioVenta numeric  --almacena el precio del producto                CREATE TABLE #TempVentasProd    (  --tabla temporal para almacenar los detalles de la venta del producto       IdProducto numeric,   --pk del producto      NombreProducto varchar(55),      --descripcion del producto CodigoProducto varchar(55),     --codigo de barras del producto MontoBoletas decimal(26,8),      -- monto neto vendido del producto en boletas  MontoTotalVentas decimal (26,8),   -- monto neto vendido del producto incluye facturas, notas de credito y boletas (en este caso es irrelevante xq solo mostrate la consulta que tiene q ver con las boletas)   Cantidad numeric,  --cantidad vendida del producto correspondiente entre boletas, facturas y notas de credito.     PrecioVenta numeric  --precio unitario bruto del producto    )             CREATE TABLE #TempIdProd --almacena id o pk de los productos vendidos       (          id int IDENTITY (1, 1),      --genero un id autoincremental para poder usarlo como identificador de lineas  IdProd numeric,        --campo para guardar el id del producto encontrado )                                                  INSERT #TempIdProd     --guarda los id de los productos vendidos SELECT DISTINCT DET_BOLETA_VENTA.dbv_id_producto_servicio  --trae las distintas pk de producto en detalles de boleta   FROM MAE_PRODUCTO_SERVICIO --desde la tabla maestra de productos JOIN DET_BOLETA_VENTA --unida con el detalle de la boleta de venta (productos vendidos) ON MAE_PRODUCTO_SERVICIO.mps_id_producto_servicio = DET_BOLETA_VENTA.dbv_id_producto_servicio JOIN MAE_BOLETA_VENTA --y unida con la cabecera de la boleta donde se vendio el producto ON DET_BOLETA_VENTA.dbv_id_boleta_venta = MAE_BOLETA_VENTA.mbv_id_boleta_venta WHERE (DET_BOLETA_VENTA.dbv_id_producto_servicio = @IdProducto OR @IdProducto=0) --donde el id del producto este en el detalle de la boleta            AND (MAE_BOLETA_VENTA.mbv_fecha>=@FechasDesde AND MAE_BOLETA_VENTA.mbv_fecha<=@FechasHasta) --y la boleta haya sido generada en el rango de fecha ingresado por usuario          AND  (MAE_PRODUCTO_SERVICIO.mps_id_categoria_producto_servicio = @IdCategoria OR @IdCategoria=0) --y que el producto este en la categoria seleccionada AND mbv_nula = 0    --donde la boleta no este anulada (mbv_nula es un bit donde 0 significa que la boleta no ha sido anulada)                        set @TotalProdCat= (Select count(*) from #TempIdProd) --total de lineas en tabla temporal #TempIdProd      set @Contador=1         --mientras el contador sea menor a la cantidad total de registros en  #TempIdProd    WHILE (@Contador <= @TotalProdCat)   --recorre la tabla temporal #TempIdProd     BEGIN               --extrae  el id de producto correspondiente a la linea segun indique el contador      set @IdProd = (Select IdProd from #TempIdProd where id=@Contador)            --asigno el neto de la suma de las lineas de detalle de la boleta sin el descuento que corresponde por el encabezado--a la variable '@MontoBoletas'   set @MontoBoletas = (SELECT sum(((D.dbv_total*100)/(b.mbv_porcentaje_iva + 100)) --el neto de la suma de las lineas de detalle de la boleta                                *(1- isnull(d.dbv_descuento_encabezado,0)))   --calcula el valor segun lo que le corresponde de descuento por el encabezado de la boleta         FROM DET_BOLETA_VENTA  D    --tabla que almacena los detalles de la boleta de venta          JOIN MAE_BOLETA_VENTA b       --unida a la tabla del encabezado de boleta de venta         ON (b.mbv_id_boleta_Venta = D.dbv_id_boleta_venta)      --las uno por su clave primaria y foranea respectivamente correspondiente al id interno de la boleta de venta         WHERE (D.dbv_id_producto_servicio = @IdProd)    --y filtro segun el id del producto  ...          AND (b.mbv_fecha>=@FechasDesde AND b.mbv_fecha<=@FechasHasta)   --  ...segun el rango de fechas ingresados...         AND b.mbv_nula = 0)      --...y que la boleta no este anulada.            --asigno la cantidad de productos        set @CantidadProductoBOV = (SELECT SUM(DET_BOLETA_VENTA.dbv_cantidad)  --suma la cantidad de productos vendidos segun lo que indica la linea de detalle               FROM DET_BOLETA_VENTA --detalle de boleta de venta            join MAE_BOLETA_VENTA   --unido con el encabezado            on  DET_BOLETA_VENTA.dbv_id_boleta_venta = MAE_BOLETA_VENTA.mbv_id_boleta_venta --a traves de la clave primaria del encabezado de la boleta de venta              WHERE (DET_BOLETA_VENTA.dbv_id_producto_servicio = @IdProd) --filtrado por el producto que me ingresaron a traves de formulario                      AND (MAE_BOLETA_VENTA.mbv_fecha>=@FechasDesde AND MAE_BOLETA_VENTA.mbv_fecha<=@FechasHasta)  --y que haya sido vendido en el rango de fechas indicado por el usuario              AND mbv_nula = 0 ) --donde la boleta no hata sido anulada              if(@MontoBoletas is null)                  begin          set @MontoBoletas = 0  --si el monto de boletas es nulo le asigno un 0       end          if(@CantidadProductoBOV is null)                  begin          set @CantidadProductoBOV = 0   --y si la cantidad es nula asigno un 0      end                     set @MontoTotalVentas = @MontoBoletas    --  se asigna a @MontoTotalVentas todo lo que se vendio del producto entre                                            --boletas, facturas y notas de credito.. en este caso solo lo mostrare con boletas para q veas una consulta mas corta         set @CantidadProducto = @CantidadProductoBOV  -- se asigna el total de productos vendidos (en este caso solo boletas por lo explicado anteriormente)                     set @PrecioVenta = (SELECT isnull(mps_precio_venta,0) -- consulta el precio unitario bruto de venta del producto, y si es nulo le asigna un 0               FROM MAE_PRODUCTO_SERVICIO   -- de la tabla maestra de productos            WHERE mps_id_producto_servicio=@IdProd)      --donde el id del producto sea igual al almacenado en la tabla temporal                  INSERT #TempVentasProd     --guarda los montos de venta segun el producto   SELECT          MAE_PRODUCTO_SERVICIO.mps_id_producto_servicio,  --pk de producto       MAE_PRODUCTO_SERVICIO.mps_descripcion,      --nombre de producto   MAE_PRODUCTO_SERVICIO.mps_codigo_barra,       --codigo de producto   isnull(@MontoBoletas,0) AS MontoBoletas,     --monto vendido del producto en boletas    (neto)   isnull(@MontoTotalVentas,0) AS MontoTotalVentas,  --monto total vendido del producto    (neto)            isnull(@CantidadProducto,0) as Cantidad, --cantidad de productos vendidos                  isnull(@PrecioVenta,0) as PrecioVenta     --precio unitario de venta de producto (bruto)   FROM MAE_PRODUCTO_SERVICIO         WHERE (MAE_PRODUCTO_SERVICIO.mps_id_producto_servicio = @IdProd)     --filtra segun el id que se este filtrando entre los productos vendidos                    set @Contador = @Contador + 1    --suma 1 al contador para poder avanzar una tupla en  #TempIdProd         END                         SELECT DISTINCT *     --selecciona los distintos registros que se guardaron en la tabla y con eso genera el informe   FROM #TempVentasProd             DROP TABLE #TempIdProd   --borra la tabla temporal    DROP TABLE #TempVentasProd --bora la tbla temporal que almacena el informe (quedo cargado en grilla del formulario)                END             
Pantallazos de Software
img216.imageshack.us/img216/9055/informeclientes.th.png

img213.imageshack.us/img213/7987/informevendedor.th.png

img216.imageshack.us/img216/5647/informeproductos.th.png

espero que me puedan ayudar... me he craneado bastante con esto y no se como arreglarlo..

saludos.. y gracias de antemano

Navegación

[0] Índice de Mensajes

Ir a la versión completa