FUNCTION busca_prod(pinventario) DEFINE arr_prod DYNAMIC ARRAY OF RECORD cod_n INTEGER, cod_grupo INTEGER, cod_tipo INTEGER, cod_sec INTEGER, descrip_esp CHAR(50), unidad_med CHAR(4), existencia1 DEC(18, 4), cantidad_o DEC(18, 4), cantidad_c DEC(18, 4), existencia DEC(18, 4) END RECORD, selec_pt, criterio STRING, f, pinventario, idx SMALLINT, pcodn, pcodgrupo, pcodtipo, pcodsec INT, pdescripcion CHAR(100) OPEN WINDOW busca_2 AT 8, 4 WITH FORM "vefmwd100" ATTRIBUTE(BORDER, FORM LINE FIRST + 1, PROMPT LINE LAST) CONSTRUCT criterio ON a.cod_n, a.cod_grupo, a.cod_tipo, a.descrip_esp FROM cod_n, cod_grupo, cod_tipo, descrip_esp IF pinventario = '02' THEN LET selec_pt = "SELECT a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,a.unidad_med,SUM(b.cantidad_2),'0','0',SUM(b.cantidad_2) ", " FROM iptb00002 AS a INNER JOIN iptb00001 AS c ON a.cod_n = c.cod_n AND a.cod_grupo = c.cod_grupo AND ", " a.cod_tipo = c.cod_tipo and a.cod_Sec = c.cod_Sec LEFT OUTER JOIN ", " iptb00006 AS b ON a.cod_n = b.cod_n AND a.cod_grupo = b.cod_grupo AND ", " a.cod_tipo = b.cod_tipo AND a.cod_sec = b.cod_sec AND b.status_t IS NULL ", " WHERE a.status_t IS NULL AND ", CRITERIO CLIPPED, " GROUP BY a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,a.unidad_med ", " ORDER BY a.descrip_esp " END IF IF pinventario = '01' THEN LET selec_pt = "SELECT a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,a.unidad_med,'0','0','0',SUM(b.cantidad_2) ", " FROM intb00001 AS a ", " LEFT OUTER JOIN ", " intb00006 AS b ON a.cod_n = b.cod_n AND a.cod_grupo = b.cod_grupo AND ", " a.cod_tipo = b.cod_tipo AND a.cod_sec = b.cod_sec AND b.status_t IS NULL ", " WHERE a.status_t IS NULL AND ", CRITERIO CLIPPED, " GROUP BY a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,a.unidad_med ", " ORDER BY a.descrip_esp " END IF IF pinventario = '03' THEN LET selec_pt = "SELECT a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,a.unidad_med,'0','0','0',SUM(b.cantidad_2) ", " FROM irtb00002 AS a ", " LEFT OUTER JOIN ", " irtb00006 AS b ON a.cod_n = b.cod_n AND a.cod_grupo = b.cod_grupo AND ", " a.cod_tipo = b.cod_tipo AND a.cod_sec = b.cod_sec AND b.status_t IS NULL ", " WHERE a.status_t IS NULL AND ", CRITERIO CLIPPED, " GROUP BY a.cod_n,a.cod_grupo,a.cod_tipo,a.cod_sec,a.descrip_esp,a.unidad_med ", " ORDER BY a.descrip_esp " END IF IF int_flag THEN LET Int_flag = FALSE CLOSE WINDOW busca_2 RETURN pcodn, pcodgrupo, pcodtipo, pcodsec, pdescripcion END IF PREPARE comando_p FROM selec_pt DECLARE busca_2 CURSOR FOR comando_p LET idx = 1 FOREACH busca_2 INTO arr_prod[idx].* LET idx = idx + 1 END FOREACH CALL SET_COUNT(idx - 1) DISPLAY ARRAY arr_prod TO s_prod.* AFTER ROW LET idx = arr_curr() LET pcodn = arr_prod[idx].cod_n LET pcodgrupo = arr_prod[idx].cod_grupo LET pcodtipo = arr_prod[idx].cod_tipo LET pcodsec = arr_prod[idx].cod_sec LET pdescripcion = arr_prod[idx].descrip_esp AFTER DISPLAY EXIT DISPLAY END DISPLAY CLOSE WINDOW busca_2 RETURN pcodn, pcodgrupo, pcodtipo, pcodsec, pdescripcion END FUNCTION FUNCTION bodegas(cb2) DEFINE ketiquetas SMALLINT, detiquetas CHAR(30), cbodegas ui.ComboBox, cb2 CHAR(2) LET cbodegas = ui.combobox.forname("formonly.bodega") DECLARE bbodegas CURSOR FOR SELECT a.cod_bodega, a.descripcion FROM intb00009 a WHERE a.status_t IS NULL ORDER BY a.descripcion CALL cbodegas.clear() FOREACH bbodegas INTO ketiquetas, detiquetas CALL cbodegas.additem(ketiquetas, detiquetas) END FOREACH IF cb2 = '2' THEN LET cbodegas = ui.combobox.forname("formonly.bodega_destino") DECLARE bbodegas2 CURSOR FOR SELECT a.cod_bodega, a.descripcion FROM intb00009 a WHERE a.status_t IS NULL ORDER BY a.descripcion CALL cbodegas.clear() FOREACH bbodegas2 INTO ketiquetas, detiquetas CALL cbodegas.additem(ketiquetas, detiquetas) END FOREACH END IF END FUNCTION { ------------------------------------------------------------------------------- FUNCTION disponibles() -- VERSION OPTIMIZADA v2 (drop-in, misma firma) ------------------------------------------------------------------------------- CAMBIOS respecto al original: 1. SUSTITUTOS (intb00003) incorporados CORRECTAMENTE en existencia, orden y conduce: ahora suman el propio producto MAS sus equivalentes (que no reciben ventas por si mismos). El original hacia un LEFT JOIN a intb00003 que no usaba ninguna columna de e, por lo que NO traia el sustituto y solo podia duplicar filas. 2. FECHA DE CORTE: se aplica fecha <= pfecha en los movimientos/documentos. En la reserva se usa pfecha como referencia (linea marcada). 3. Manejo de NULL consistente. Firma y 6 valores de retorno IDENTICOS. RECOMENDACION: pcodn..pcodsec estan declarados SMALLINT, pero en las tablas los codigos son INT. Si algun codigo supera 32767 habra overflow; considerar cambiarlos a INTEGER. NOTA: esta version por fila sigue siendo mas lenta que precalcular con sp_llenar_disponibles. Usar esta solo si no se puede cambiar el flujo del reporte; de lo contrario, usar el SP. ------------------------------------------------------------------------------- } FUNCTION disponibles(pcodn, pcodgrupo, pcodtipo, pcodsec, pfecha) DEFINE pcodn, pcodgrupo, pcodtipo, pcodsec, dias SMALLINT, pfecha DATE, reservado, existencia, transito, cantidad_orden, pcantidadconduce, cantidad_ordenada, cantidad_recibida DEC(12, 5), selec STRING, valorOrdenes, valorConduces DEC(16, 2) SELECT a.dias_vence_reservas INTO dias FROM companias a # RESERVADO -- usa pfecha como referencia de corte LET reservado = 0 LET selec = " SELECT ISNULL(SUM(a.cantidad_reservada),0) FROM vetb00051 a, vetb00050 b WHERE a.status_t IS NULL AND a.cotizacion_no = b.cotizacion_no AND a.cod_n = ? AND a.cod_grupo = ? AND a.cod_tipo = ? AND a.cod_sec = ? AND a.cantidad_reservada IS NOT NULL AND a.fecha_inicio_reserva <= ? AND a.fecha_vence_reserva >= ? AND DATEDIFF(day, a.fecha_vence_reserva, a.fecha_inicio_reserva) <= ? " PREPARE comando1 FROM selec EXECUTE comando1 INTO reservado USING pcodn, pcodgrupo, pcodtipo, pcodsec, pfecha, pfecha, dias IF reservado IS NULL THEN LET reservado = 0 END IF # EXISTENCIA -- propio + sustitutos, al corte pfecha LET existencia = 0 LET selec = " SELECT ISNULL(SUM(a.cantidad_2),0) FROM iptb00006 a WHERE a.status_t IS NULL AND a.fecha <= ? AND ( (a.cod_n=? AND a.cod_grupo=? AND a.cod_tipo=? AND a.cod_sec=?) OR EXISTS ( SELECT 1 FROM intb00003 e WHERE e.status_t IS NULL AND e.cod_n=? AND e.cod_grupo=? AND e.cod_tipo=? AND e.cod_sec=? AND a.cod_n=e.cod_n_s AND a.cod_grupo=e.cod_grupo_s AND a.cod_tipo=e.cod_tipo_s AND a.cod_sec=e.cod_sec_s ) ) " PREPARE comando2 FROM selec EXECUTE comando2 INTO existencia USING pfecha, pcodn,pcodgrupo,pcodtipo,pcodsec, pcodn,pcodgrupo,pcodtipo,pcodsec # ORDEN DE PRODUCCION -- propio + sustitutos, al corte LET cantidad_orden = 0 LET selec = " SELECT ISNULL(SUM(a.cantidad),0), ISNULL(SUM(a.cantidad*a.precio),0) FROM prtb00013 a, prtb00012 b WHERE a.num_oc=b.num_oc AND b.cerrada='N' AND b.status_t IS NULL AND b.fecha_oc <= ? AND ( (a.cod_n=? AND a.cod_grupo=? AND a.cod_tipo=? AND a.cod_sec=?) OR EXISTS ( SELECT 1 FROM intb00003 e WHERE e.status_t IS NULL AND e.cod_n=? AND e.cod_grupo=? AND e.cod_tipo=? AND e.cod_sec=? AND a.cod_n=e.cod_n_s AND a.cod_grupo=e.cod_grupo_s AND a.cod_tipo=e.cod_tipo_s AND a.cod_sec=e.cod_sec_s ) ) " PREPARE comando3 FROM selec EXECUTE comando3 INTO cantidad_orden, valorOrdenes USING pfecha, pcodn,pcodgrupo,pcodtipo,pcodsec, pcodn,pcodgrupo,pcodtipo,pcodsec # CONDUCE / CONSUMO -- propio + sustitutos, al corte LET pcantidadConduce = 0 LET selec = " SELECT ISNULL(SUM(c.cantidad_2*-1),0), ISNULL(SUM(c.cantidad_2*(a.precio*b.prima_us)),0) FROM prtb00013 a, prtb00012 b, iptb00006 c, iptb00005 d WHERE a.num_oc=b.num_oc AND b.cerrada='N' AND b.status_t IS NULL AND a.num_oc=c.num_oc AND a.cod_n=c.cod_n AND a.cod_grupo=c.cod_grupo AND a.cod_tipo=c.cod_tipo AND a.cod_sec=c.cod_sec AND c.cod_mov=d.cod_mov AND (d.control_despacho='SI' OR d.control_devolucion='SI') AND c.status_t IS NULL AND c.fecha <= ? AND ( (a.cod_n=? AND a.cod_grupo=? AND a.cod_tipo=? AND a.cod_sec=?) OR EXISTS ( SELECT 1 FROM intb00003 e WHERE e.status_t IS NULL AND e.cod_n=? AND e.cod_grupo=? AND e.cod_tipo=? AND e.cod_sec=? AND a.cod_n=e.cod_n_s AND a.cod_grupo=e.cod_grupo_s AND a.cod_tipo=e.cod_tipo_s AND a.cod_sec=e.cod_sec_s ) ) " PREPARE comando4 FROM selec EXECUTE comando4 INTO pcantidadConduce, valorConduces USING pfecha, pcodn,pcodgrupo,pcodtipo,pcodsec, pcodn,pcodgrupo,pcodtipo,pcodsec LET valorOrdenes = valorOrdenes + valorConduces # TRANSITO = ordenado - recibido (sin sustitutos, como el original; al corte) LET cantidad_ordenada = 0 SELECT ISNULL(SUM(a.cantidad),0) INTO cantidad_ordenada FROM cotb00015 a, cotb00014 b WHERE a.cod_n=pcodn AND a.cod_grupo=pcodgrupo AND a.cod_tipo=pcodtipo AND a.cod_sec=pcodsec AND a.num_oc=b.num_oc AND b.cierre='N' AND a.status_t IS NULL AND b.fech_oc <= pfecha LET cantidad_recibida = 0 SELECT ISNULL(SUM(a.cantidad_2),0) INTO cantidad_recibida FROM iptb00006 a, cotb00015 b, cotb00014 c WHERE a.cod_n=pcodn AND a.cod_grupo=pcodgrupo AND a.cod_tipo=pcodtipo AND a.cod_sec=pcodsec AND a.cod_n=b.cod_n AND a.cod_grupo=b.cod_grupo AND a.cod_tipo=b.cod_tipo AND a.orden_compra=b.num_oc AND b.num_oc=c.num_oc AND c.cierre='N' AND a.status_t IS NULL AND a.fecha <= pfecha LET transito = cantidad_ordenada - cantidad_recibida IF cantidad_orden IS NULL THEN LET cantidad_orden = 0 END IF IF transito IS NULL THEN LET transito = 0 END IF IF pcantidadconduce IS NULL THEN LET pcantidadconduce = 0 END IF RETURN cantidad_orden, pcantidadConduce, transito, existencia, reservado, valorOrdenes END FUNCTION FUNCTION busca_reservas(pcodn, pcodgrupo, pcodtipo, pcodsec) DEFINE idx, pcodn, pcodgrupo, pcodtipo, pcodsec, dias SMALLINT, arr_reserva DYNAMIC ARRAY OF RECORD cotizacion_no INT, vendedor VARCHAR(100), nombre VARCHAR(100), cantidad DEC(12, 5), fecha CHAR(10) END RECORD, selec STRING, fecha DATE SELECT a.dias_vence_reservas INTO dias FROM companias a LET fecha = TODAY LET selec = " SELECT a.cotizacion_no,RTRIM(c.nom1_emp)||' '||RTRIM(c.apell1_emp),b.nombre_cliente,a.cantidad_reservada,CONVERT(CHAR(10),a.fecha_vence_reserva,103) FROM vetb00051 a,vetb00050 b,adtb00003 c WHERE a.status_t IS NULL AND b.sec_vend = c.num_emp AND a.cotizacion_no = b.cotizacion_no AND a.cod_n = ? AND a.cod_grupo=? AND a.cod_tipo=? AND a.cod_sec=? AND a.cantidad_reservada IS NOT NULL AND a.fecha_vence_reserva >= ? AND DATEDIFF(DAY,a.fecha_vence_reserva ,a.fecha_inicio_reserva) <=? " PREPARE comando FROM selec DECLARE busca_reserva CURSOR FOR comando OPEN busca_reserva USING pcodn, pcodgrupo, pcodtipo, pcodsec, fecha, dias DISPLAY selec LET idx = 1 FOREACH busca_reserva INTO arr_reserva[idx].* LET idx = idx + 1 END FOREACH OPEN WINDOW ipfmwd012 WITH FORM "ipfmwd012" DISPLAY ARRAY arr_reserva TO s_reserva.* CLOSE WINDOW ipfmwd012 END FUNCTION FUNCTION almacenes(pcodn, pcodgrupo, pcodtipo, pcodsec) DEFINE pcodn, pcodgrupo, pcodtipo, pcodsec SMALLINT, arr_existencia DYNAMIC ARRAY OF RECORD almacen VARCHAR(30), existencia DEC(12, 2) END RECORD, idx SMALLINT OPEN WINDOW w1 AT 1, 1 WITH FORM "almacenes" DECLARE busca_a CURSOR FOR SELECT b.descripcion, SUM(c.cantidad_2) FROM intb00009 b, iptb00006 c WHERE b.cod_bodega = c.bodega AND c.cod_n = pcodn AND c.cod_grupo = pcodgrupo AND c.cod_tipo = pcodtipo AND c.cod_sec = pcodsec AND c.status_t IS NULL GROUP BY b.descripcion LET idx = 1 FOREACH busca_a INTO arr_existencia[idx].* LET idx = idx + 1 END FOREACH DISPLAY ARRAY arr_existencia TO sexistencia.* CLOSE WINDOW w1 END FUNCTION { ESTA FUNCION PARA BUSCAR LAS ORDENES QUE TIENE DISPONIBLES TODAVIA ESTA EN PROCESO DE DESARRLLO FECHA : 27/5/2016} FUNCTION busca_ordenes_reservadas(pcodn, pcodgrupo, pcodtipo, pcodsec) DEFINE pcodn, pcodgrupo, pcodtipo, pcodsec INT, ordenes DYNAMIC ARRAY OF RECORD num_oc INT, fecha DATE, vendedor VARCHAR(100), cantidad DEC(12, 5), cantidad_Desp DEC(12, 5), disponible, pendiente, balance DEC(12, 5), codigo VARCHAR(25) END RECORD, i SMALLINT, cantidad_desp1, total_cantidad, total_desp, existencia DEC(12, 5) OPEN WINDOW w2 WITH FORM "ipfmwd017" # BUSCA EXISTENCIA SELECT ISNULL(SUM(a.cantidad_2), 0) INTO existencia FROM iptb00006 a WHERE (a.cod_n = pcodn AND a.cod_grupo = pcodgrupo AND a.cod_tipo = pcodtipo AND a.cod_sec = pcodsec) AND a.status_t IS NULL DECLARE busca_orden CURSOR FOR SELECT a.num_oc, CONVERT(char(10), b.fecha_oc, 103), c.nom1_emp || ' ' || c.apell1_emp, sum(a.cantidad), '0' FROM prtb00013 a, prtb00012 b, adtb00003 c WHERE a.num_oc = b.num_oc AND b.cerrada = 'N' AND b.sec_vend = c.num_emp AND b.status_t IS NULL AND (a.cod_n = pcodn AND a.cod_grupo = pcodgrupo AND a.cod_tipo = pcodtipo AND a.cod_sec = pcodsec) group by a.num_oc,b.fecha_oc,c.nom1_emp,c.apell1_emp UNION SELECT a.num_oc, CONVERT(char(10), b.fecha_oc, 103), c.nom1_emp || ' ' || c.apell1_emp, sum(a.cantidad), '0' FROM prtb00013 a, prtb00012 b, adtb00003 c, intb00003 e WHERE a.num_oc = b.num_oc AND b.cerrada = 'N' AND b.sec_vend = c.num_emp AND b.status_t IS NULL AND (e.cod_n = pcodn AND e.cod_grupo = pcodgrupo AND e.cod_tipo = pcodtipo AND e.cod_sec = pcodsec) AND (a.cod_n = e.cod_n_s AND a.cod_grupo = e.cod_grupo_s AND a.cod_tipo = e.cod_tipo_s AND a.cod_sec = e.cod_sec_s) group by a.num_oc,b.fecha_oc,c.nom1_emp,c.apell1_emp LET i = 1 LET ordenes[i].vendedor = 'EXISTENCIA: ' LET ordenes[i].balance = existencia LET i = i + 1 LET total_desp = 0 LET total_cantidad = 0 FOREACH busca_orden INTO ordenes[i].* LET ordenes[i].cantidad_Desp = 0 SELECT ISNULL(SUM(c.cantidad_2), 0) INTO ordenes[i].cantidad_Desp FROM prtb00012 b, iptb00006 c, iptb00005 d WHERE (b.num_oc = c.num_oc) AND (c.num_oc = ordenes[i].num_oc) AND b.cerrada = 'N' AND b.status_t IS NULL AND (c.cod_n = pcodn AND c.cod_grupo = pcodgrupo AND c.cod_tipo = pcodtipo AND c.cod_sec = pcodsec) AND c.cod_mov = d.cod_mov AND (d.control_despacho = 'SI' OR d.control_devolucion = 'SI') AND c.status_t IS NULL LET cantidad_Desp1 = 0 SELECT ISNULL(SUM(c.cantidad_2), 0) INTO cantidad_Desp1 FROM prtb00012 b, iptb00006 c, iptb00005 d, intb00003 e WHERE (b.num_oc = c.num_oc) AND (c.num_oc = ordenes[i].num_oc) AND b.cerrada = 'N' AND b.status_t IS NULL AND (e.cod_n = pcodn AND e.cod_grupo = pcodgrupo AND e.cod_tipo = pcodtipo AND e.cod_sec = pcodsec) AND (c.cod_n = e.cod_n_s AND c.cod_grupo = e.cod_grupo_s AND c.cod_tipo = e.cod_tipo_s AND c.cod_sec = e.cod_sec_s) AND c.cod_mov = d.cod_mov AND (d.control_despacho = 'SI' OR d.control_devolucion = 'SI') AND c.status_t IS NULL LET ordenes[i].cantidad_Desp = ordenes[i].cantidad_Desp + cantidad_desp1 IF ordenes[i].cantidad > 0 THEN LET total_cantidad = total_cantidad + ordenes[i].cantidad END IF LET total_desp = total_desp + ordenes[i].cantidad_Desp LET ordenes[i].pendiente = ordenes[i].cantidad + ordenes[i].cantidad_Desp IF ordenes[i - 1].balance IS NOT NULL THEN LET ordenes[i].balance = ordenes[i - 1].balance - ordenes[i].pendiente END IF LET i = i + 1 END FOREACH IF i > 1 THEN LET i = i + 1 LET ordenes[i].vendedor = "TOTALES=====> " LET ordenes[i].cantidad = total_cantidad LET ordenes[i].cantidad_Desp = total_desp # LET ordenes[i].disponible = total_cantidad + total_desp END IF DISPLAY ARRAY ordenes TO sordenes.* CLOSE WINDOW w2 END FUNCTION