#38165
Gabriel Bocalandro
Participante

Exacto. Hice eso

Lo que actualicé fue…

en SQL

— 20140219-1235 Correccion en funcion para el calculo de facturas anuladas (signo negativo) y con c_invoicepayschedule
CREATE OR REPLACE FUNCTION invoiceopen(p_c_invoice_id integer, p_c_invoicepayschedule_id integer)
RETURNS numeric AS
$BODY$
/*************************************************************************
* The contents of this file are subject to the Compiere License. You may
* obtain a copy of the License at http://www.compiere.org/license.html
* Software is on an “AS IS” basis, WITHOUT WARRANTY OF ANY KIND, either
* express or implied. See the License for details. Code: Compiere ERP+CRM
* Copyright (C) 1999-2001 Jorg Janke, ComPiere, Inc. All Rights Reserved.
*
* converted to postgreSQL by Karsten Thiemann (Schaeffer AG),
* kthiemann@adempiere.org
*************************************************************************
***
* Title: Calculate Open Item Amount in Invoice Currency
* Description:
* Add up total amount open for C_Invoice_ID if no split payment.
* Grand Total minus Sum of Allocations in Invoice Currency
*
* For Split Payments:
* Allocate Payments starting from first schedule.
* Cannot be used for IsPaid as mutating
*
* Test:
* SELECT C_InvoicePaySchedule_ID, DueAmt FROM C_InvoicePaySchedule WHERE C_Invoice_ID=109 ORDER BY DueDate;
* SELECT invoiceOpen (109, null) FROM AD_System; – converted to default client currency
* SELECT invoiceOpen (109, 11) FROM AD_System; – converted to default client currency
* SELECT invoiceOpen (109, 102) FROM AD_System;
* SELECT invoiceOpen (109, 103) FROM AD_System;
***
* Pasado a Libertya a partir de Adempiere 360LTS
* – ids son de tipo integer, no numeric
* – TODO : tema de las zonas en los timestamp
* – Excepciones en SELECT INTO requieren modificador STRICT bajo PostGreSQL o usar
* NOT FOUND
* – Por ahora, el “ignore rounding” se hace como en libertya (-0.01,0.01),
* en vez de usar la precisión de la moneda
* – Se toma el tipo de conversion de la factura, auqneu esto es dudosamente correcto
* ya que otras funciones , en particular currencyBase nunca tiene en cuenta
* este valor
* – Como en Libertya se tiene en cuenta tambien C_Invoice_Credit_ID para calcular
* la cantidad alocada a una factura (aunque esto es medio dudoso….)
* – No se soporta la fecha como 3er parametro (en realidad, tampoco se esta
* usando actualmente, y se deberia poder resolver de otra manera)
* – Libertya parece tener un bug al filtrar por C_InvoicePaySchedule_ID al calcular
* el granTotal (el granTotal SIEMPRE es el total de la factura, tomada directamente
* de C_Invoice.GranTotal o a partir de la suma de los DueAmt en C_InvoicePaySchedule);
* se usa la sentencia como esta en Adempeire (esto es, solo se filtra por C_Invoice_ID)
* – Nuevo enfoque: NO se usa ni la vista C_Invoice_V ni multiplicadores
* se asume todo positivo…
* – El resultado SIEMPRE deberia ser positivo y en el intervalo [0..GrandTotal]
* – 03 julio: se pasa a usar getAllocatedAmt para hacer esta funcion consistente
* con invoicePaid
* – 03 julio: se pasa de usar STRICT a NOT FOUND; es mas eficiente
************************************************************************/
DECLARE
v_Currency_ID INTEGER;
v_TotalOpenAmt NUMERIC := 0;
v_PaidAmt NUMERIC := 0;
v_Remaining NUMERIC := 0;
v_Precision NUMERIC := 0;
v_Min NUMERIC := 0.01; — en Adempiere inferido desde Currency
s RECORD;
v_ConversionType_ID INTEGER; — NO en Adempiere

BEGIN
— Get Currency, GranTotal, MulitplerAP , MutiplierCM, ConversionType, and precision
SELECT C_Currency_ID, GrandTotal, C_ConversionType_ID,
(SELECT StdPrecision FROM C_Currency C WHERE C.C_Currency_ID = I.C_Currency_ID)
AS StdPrecision
INTO v_Currency_ID, v_TotalOpenAmt, v_ConversionType_ID,v_Precision
FROM C_Invoice I — NO se corrige por CM o SpliPayment; se usa directamente C_Inovoice y ningun multiplicador
WHERE I.C_Invoice_ID = p_C_Invoice_ID;

IF NOT FOUND THEN
RAISE NOTICE ‘Invoice no econtrada – %’, p_C_Invoice_ID;
RETURN NULL;
END IF;

— se saca lo siguiente para hacerlo tal como lo hace Libertya; igual tiene cierto sentido usar estos limites, sal vo que en Libertya
— se usa 2 decimales en todos los montos….
–SELECT 1/10^v_Precision INTO v_Min;

— Calculate Allocated Amount : SIEMPRE 1 como multiplicador
v_PaidAmt := getAllocatedAmt(p_C_Invoice_ID,v_Currency_ID,v_ConversionType_ID,1);

— Do we have a Payment Schedule ?
IF (p_C_InvoicePaySchedule_ID > 0) THEN — if not valid = lists invoice amount
v_Remaining := v_PaidAmt;
FOR s IN
SELECT C_InvoicePaySchedule_ID, DueAmt, sign(DueAmt) as signo
FROM C_InvoicePaySchedule
WHERE C_Invoice_ID = p_C_Invoice_ID
AND IsValid=’Y’
ORDER BY DueDate
LOOP
IF (s.C_InvoicePaySchedule_ID = p_C_InvoicePaySchedule_ID) THEN
v_TotalOpenAmt := abs(s.DueAmt) – v_Remaining;
IF (v_TotalOpenAmt < 0) THEN
v_TotalOpenAmt := 0; — Pagado totalmente
END IF;
v_TotalOpenAmt := s.signo * v_TotalOpenAmt;
EXIT; — se sale del loop, ya que ya se encontro
ELSE — calculate amount, which can be allocated to next schedule
v_Remaining := v_Remaining – abs(s.DueAmt);
IF (v_Remaining < 0) THEN
v_Remaining := 0;
END IF;
END IF;
END LOOP;
ELSE
v_TotalOpenAmt := v_TotalOpenAmt – v_PaidAmt;
END IF;
— RAISE NOTICE ”== Total=” || v_TotalOpenAmt;

— Ignore Rounding
IF (v_TotalOpenAmt >= -v_Min AND v_TotalOpenAmt <= v_Min) THEN
v_TotalOpenAmt := 0;
END IF;

— Round to currency precision
v_TotalOpenAmt := ROUND(COALESCE(v_TotalOpenAmt,0), v_Precision);
RETURN v_TotalOpenAmt;
END;

$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION invoiceopen(integer, integer)
OWNER TO libertya;

En Libertya, el archivo CurrentAccountReport.java

Aun así me sigue dando el error.

Les puedo mandar algo o quieren que haga alguna prueba para mostrarles?

Muchas gracias