{ FUNCION : costoLiquidacion OBJETIVO : Determinar el costo unitario que debe tener un producto terminado o un repuesto para valorizar el asiento de inventario en linea, de acuerdo a la liquidacion de mercancia (cttb00013) o al costo estandard. Centraliza el criterio de costeo que antes aplicaba el usuario de forma manual. DESARROLLADO : Equipo Tecnologia (Juan Soto) FECHA : 14 Septiembre 2026 REGLA DE COSTO (definida por el usuario): - Repuestos (ptipoInv = 'R'): Siempre costo estandard irtb00013.costo_st (ano del documento, mes_fin = 12). - Terminados (ptipoInv = 'P'): * iptb00002.es_produccion = TRUE -> SIEMPRE costo estandard iptb00004 (material + labor + gastos, mes_fin = 12). * es_produccion = FALSE (compra/venta): - Se busca la ULTIMA liquidacion DEL MES del documento en cttb00013. (Solo el mes: si la liquidacion fue en un mes anterior, lqprrp004 ya actualizo el costo estandard, por lo que ese ya lo refleja.) - Si hay liquidacion del mes Y su cantidad liquidada > existencia actual (SUM iptb00006.cantidad_2 WHERE status_t IS NULL) -> costo_lq. - En caso contrario (existencia >= liquidada, o no hay liquidacion del mes) -> costo estandard iptb00004. NOTA: usa nombres calificados marmotech.dbo.* igual que GeneraEntradaDiario.4gl y controlNumericoED.4gl, para leer siempre la BD correcta sin depender de la conexion del programa llamador. } FUNCTION costoLiquidacion(pcod_n, pcod_grupo, pcod_tipo, pcod_sec, pfecha, ptipoInv) DEFINE pcod_n, pcod_grupo, pcod_tipo, pcod_sec INT, pfecha DATE, ptipoInv CHAR(1), costo DEC(18, 4), costo_std DEC(18, 4), xcosto_lq DEC(18, 4), cant_lq DEC(18, 4), existencia DEC(18, 4), es_prod SMALLINT, qsql STRING LET costo = 0 LET costo_std = 0 LET xcosto_lq = 0 LET cant_lq = 0 LET existencia = 0 LET es_prod = 0 #------------------------------------------------------------------------- # REPUESTOS -> costo estandard irtb00013.costo_st #------------------------------------------------------------------------- IF ptipoInv = 'R' THEN LET qsql = "SELECT ISNULL(a.costo_st,0) FROM marmotech.dbo.irtb00013 a WHERE a.cod_n = ? AND a.cod_grupo = ? AND a.cod_tipo = ? AND a.cod_sec = ? AND a.ano = YEAR(?) AND a.mes_fin = 12 AND a.status_t IS NULL" PREPARE sc_rep FROM qsql EXECUTE sc_rep INTO costo USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec, pfecha FREE sc_rep IF costo IS NULL THEN LET costo = 0 END IF RETURN costo END IF #------------------------------------------------------------------------- # TERMINADOS -> costo estandard iptb00004 (material + labor + gastos) # Se calcula siempre porque es el respaldo y el valor para es_produccion. #------------------------------------------------------------------------- LET qsql = "SELECT ISNULL(AVG(ISNULL(a.material,0)+ISNULL(a.labor,0)+ISNULL(a.gastos,0)),0) FROM marmotech.dbo.iptb00004 a WHERE a.cod_n = ? AND a.cod_grupo = ? AND a.cod_tipo = ? AND a.cod_sec = ? AND a.ano = YEAR(?) AND a.mes_fin = 12 AND a.status_t IS NULL" PREPARE sc_std FROM qsql EXECUTE sc_std INTO costo_std USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec, pfecha FREE sc_std IF costo_std IS NULL THEN LET costo_std = 0 END IF # es_produccion del articulo LET qsql = "SELECT TOP 1 ISNULL(a.es_produccion,0) FROM marmotech.dbo.iptb00002 a WHERE a.cod_n = ? AND a.cod_grupo = ? AND a.cod_tipo = ? AND a.cod_sec = ?" PREPARE sc_esp FROM qsql EXECUTE sc_esp INTO es_prod USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec FREE sc_esp IF es_prod IS NULL THEN LET es_prod = 0 END IF # Producto de produccion -> siempre estandard IF es_prod = 1 THEN RETURN costo_std END IF #------------------------------------------------------------------------- # COMPRA/VENTA -> ultima liquidacion DEL MES vs existencia #------------------------------------------------------------------------- LET qsql = "SELECT TOP 1 ISNULL(a.costo_lq,0), ISNULL(a.cantidad,0) FROM marmotech.dbo.cttb00013 a WHERE a.cod_n = ? AND a.cod_grupo = ? AND a.cod_tipo = ? AND a.cod_sec = ? AND YEAR(a.fecha_lq) = YEAR(?) AND MONTH(a.fecha_lq) = MONTH(?) AND a.fecha_lq <= ? AND a.status_t IS NULL ORDER BY a.fecha_lq DESC, a.fech_crea DESC" PREPARE sc_lq FROM qsql EXECUTE sc_lq INTO xcosto_lq, cant_lq USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec, pfecha, pfecha, pfecha FREE sc_lq # No hay liquidacion en el mes -> estandard IF STATUS = NOTFOUND OR xcosto_lq IS NULL THEN RETURN costo_std END IF # Existencia actual del articulo (solo movimientos vigentes) LET qsql = "SELECT ISNULL(SUM(a.cantidad_2),0) FROM marmotech.dbo.iptb00006 a WHERE a.cod_n = ? AND a.cod_grupo = ? AND a.cod_tipo = ? AND a.cod_sec = ? AND a.status_t IS NULL" PREPARE sc_exi FROM qsql EXECUTE sc_exi INTO existencia USING pcod_n, pcod_grupo, pcod_tipo, pcod_sec FREE sc_exi IF existencia IS NULL THEN LET existencia = 0 END IF # Cantidad liquidada mayor que la existencia -> costo liquidado IF cant_lq > existencia THEN RETURN xcosto_lq END IF # Existencia mayor o igual -> costo estandard RETURN costo_std END FUNCTION