• Este debate está vacío.
Viendo 1 entrada (de un total de 1)
  • Autor
    Entradas
  • #31787
    Javier Ader
    Participante

    Buenas, estoy intentando trasladar las funciones PL/Java a PL/PGSql (ya hice las bomXXX y las currencyXXXX); llegue a las invoice; en particular InvoiceOpen, y esta todo medio emarañado….
    El tema es que estas funciones dependen de C_Invoice_V, las cual en mismo esta medio dudosa… (por ej, multiplica un monto dos veces por 1, o dos veces por -1, lo cual es lo mismo que no mulitplicarlo: -1 * -1 = 1….).
    Ademas, se empieza a relacionar con “Multiplicadores”, que no se entiende muy bine para que sirven (uno de los dos, MultiplierCM, tiene sentido, supongo que es para negar por ej, las nota de credito en una sumatorio de “cuanto nos debe”…)

    Las tablas que están en juego son:
    -C_Invoice: en particular el campo de GranTotal y IsPayscheduleValid
    -C_InvoicePaySchedule: en particular campos DueAmt y DueDate
    -C_AllocationLine: en particular C_Invoice_ID,C_Invoice_Credit_ID; y los montos Amount, DiscountAmt y WriteOffAmt (lo alocadado por una linea en particular es simplemente Amount + DiscountAmt + WriteOffAmt)
    -C_DocType: en particular Signo_IsSOTrx (que deberia tomar solo los valores 1 o -1), usado para inferir el MultiplerCM y DocBaseType, una string de 3 caracteres usada para inferir MultiplierAP (también tomando los valores 1 o -1); ambos se infieren en C_Invoice_V; pero el ultimo de manera incorrecta (es un bug que genera que este siempre sea 1, pero tal vez por este bug, otros bugs no sean visibles…)

    El tema principal (y creo que por ahi viene varias de estas cosas raras) es que los montos (de la factura, de los vencimientos y de lo pagos) creo que algun momento en el pasado podian tener valores negativos, pero despues se paso solo a montos positivos, pero partes de la logica no se traslado…. a esto creo que hay que sumarle que se agregaron notas de credito que se podian usar como medio de pago…

    Me gustaría saber cual de estos montos puede ser negativo y cuales no…. Yo preferia que todos sean positivos siempre… Lo que mire es:
    C_Invoice.GranTotal: tiene que ser positivo, salvo que se hagan cosas raras como utilizar precios negativos (en realidad, creo que por las dudas se deberia poner un chequeo en el completeIt o prepareIt para asegurar que este monto siempre es estrictamente positivo); no tiene mucho sentido un precio negativo (y legalmente, al menos en Argentina, creo que esto no se puede), salvo que se haya querido modelar de cosas como descuentos. Este es así (o deberia serlo, al menos a mi manera de ver las cosas) incluso para notas de crédito.
    C_InvoicePaySchedule.DueAmt: en la logica actual es simplemente calculado como un porcentaje de C_Invoice.GrandTotal; por lo tanto (salvo que el porcentaje sea negativo!) este monto tambien deberia ser al menos, no negativo.

    C_AllocationLine: aca no ya estoy más perdido; pero lo ideal es que se siga la misma logica y que Amount sea estrictamente positivo; y también la suma Amount + DiscountAmt + WriteOffAmt. Alguien sabe si esto se cumple siempre? o si debería cumplir? Hice un par de selets sobre base de libertya y estos montos siempre eran positivos (salvo un monto es un cliente que viene de antes; ahi hay una entrada negativa), pero tampoco hice todas la pruebas.

    Ok, se puede suponer que todos estos montos son positivos? (de nuevo, preferiria que sea asi y que se chequen a nivel de modelo antes de completar los documentos…)

    Suponiendo lo anterior, paso a invoiceOpen(C_Invoice_ID, C_invoicePaySchedule_ID). Para mi, ya que todos los montos son positivos, esta funcion deberia retornar siemrpe un monto positivo o 0. El significado es simplemente cuanto se adeudad de una deterinada factura (en caso de que el sengundo parametro sea 0 o null), o cuando se debe de un terminado pago/cuota del esquema de pago (retornando 0 si lo que se pago hasta el momento de la factura salda el pago/cuota y todas las anteriores); esto es, siempre se retorna un valor en el intervalo [0…GrandTotal] (el grandTotal actualmente se calcula a veces como la suma de las cuotas, pero no tiene mucho sentido, ya que este monto siempre debe ser indentico al GranTotal de la factura….). Si despues esto montos no negativos se utilizan de manera directa o negandolos, se manejaria externamente (ahi si, utilizando los multiplicadores); aunque aca surgen dos cuestiones medio extrañas debido a que las notas de credito son modelasdas como facturas; habria que responder:
    -que significado tiene invoiceOpen sobre n. de credito?
    y
    -como “se paga” una nota de crédito? Se puede pagar, al menos desde el punto de vista conceptual, como si fuese una factura común? Por ej, una nota de crédito a cliente, se “paga” (la pagamos nosotros al cliente) simplemente dandole dinero del monto (esto es, se pagaría tal como se paga una factura a proveedor), o solo se puede saldar “usandola como forma de pago de otra factura al mismo cliente”?

    Quisiera creer que en estos casos , se debería (creo que es la idea que persigue el codigo…..) tener la siguiente semantica:
    – invoiceOpen sobre nota de credito: retorna el monto disponible de GranTotal que se puede usar para saldar otra factura (o falta “pagar” si esto se puede); y de nuevo deberia estar entre [0..GrandTotal], esto es, no negativo. Por ej, un n.c de cliente, de granTotal 100 que retorna 30 en invoiceOpen signficia que “aun le debemos 30”; esto tambien significa que 70 ya fue usados como pago (o se pago, si se puede….); y por ej, la puede usar para pagar este monto de otra factura (al mismo cliente); si retorna 0, significa que esta “pagada” (como en todas las facturas) y como tal no se puede usar como medio de pago a futuro. Las n.c de proveedor idem.
    -si se puede pagar como una factura normal, bueno, habra que tener en cuenta esto como en las facturas normales; cuando se utiliza como medio de pago: se suma los montos de las alocaciones de otras facturas que la referencia como medio de pago.

    Ok….. suponiendo todo esto, DocType.signoIsSoTrx se usa SOLO para distinguir Facturas y NOtas de Debito de Notas de Credito (si 1, es normal, si -1 es nota de credito, o en general un saldo en sentido inverso) y las siguientes facturas y n.c a cliente:

    F1: GrandTotal 100
    NC1: GrandTotal 50 (generada como NC de F1 pero no asociada como un pago)
    F2: GrandTotal 75

    Ningun pago a ninguna de las facturas (ni uso como medio de pago de NC1), el calculo del credito usado pro el cliente (o dicho de otra manera, los que nos debe), seria simplemente (asumiendo una sola moneda claro; si no habria que hacer conversión de los montos)

    SingoIsSoTrx(F1)*InvoiceOpen(F1,0) +
    SignoIsSoTrx(NC2)*InvoiceOpen(NC2,0) +
    SingoIsSoTrx(F2)*InvoiceOpen(F2,0)
    =
    1* 100+
    -1 * 50 +
    1 * 75
    = 100 – 50 + 75
    = 125
    Lo cual supongo que es conceptualmente correcto. Hay que tener en cuenta que en el calculo real, se deberia filtra las facturas/nc por IsSoTrx y por IsPaid <> Y (esto es, no esta “pagada”; se debería asegurar claro, que IsPaid siempre se setea a Y cuando se salda completamente un factura/n.c); el segundo parametro de InvoiceOpen en 0 es adrede (no tiene sentido hacer otro calculo más complejo si se sabe que las cuotas son siempre igual al GranTotal de la factura), esto es, no importa si la factura tiene un solo vencimiento por el total o varios para cuotas.

    Si por ej, el cliente paga 25 de F2 con la mitad de NC1, el resultado quedaria asi
    F1: GrandTotal 100 , ninguna alocación
    NC2: GrandTotal 50, ninguna alcoacion directa , pero si una alocacion por 25 apuntandole (C_AllocationLIne.C_Incoice_Credit_ID = NC2)
    F2: GranTotal 75, con una alocacion directa de 25, justamente la que apunta a NC2.

    Ok, bajo esta situación, el “credito usuado” (lo que nos debe) debería ser exactamente lo mismo; lo único que debería cambiar son los saldos delas facturas y notas de credito de manera individual.
    La suma seria

    SingoIsSoTrx(F1)*InvoiceOpen(F1,0) +
    SignoIsSoTrx(NC2)*InvoiceOpen(NC2,0) +
    SingoIsSoTrx(F2)*InvoiceOpen(F2,0)
    =
    1* 100 +
    -1* 25 + (25 porque es GranTotal=50 de NC2 menos alocacion que le apunta de 25)
    1* 50 (50 ; GranTotal – alocacion que le apunta = 75 – 25)
    = 100 – 25 + 50 =
    125

    Es claro que los InvoiceOpen por separado se reflejan el estado de cada factura y nc por separado.

    Bueno, si todo esto tiene sentido, habria que entrar en lo detalles de como determinar el “signo”, lo cual determinaria a su vez si es alguna forma de nota de crédito y como se implemetaria InvoiceOpen (tal como esta ahora en PL/Java creo que sigue esta idea, pero a veces utiliza esos extraños “multiplicadores” que confunde muchísimo…. ). Todo esto ademas se agrava en el calculo del credito usado en Bpartner.setTotalOpenBalance (que no solo vuelve a usar C_Invoice_V y los mulitplicadores, si no que ademas tiene en cuenta pedidos y calcula el “ActualLifeTimeValue”….). En cuanto al “signo” y si es “nota de credito” creo que el algoritmo deberia ser simplemente (y creo que reseta los tipos de documentos actuales):

    Code:
    //facturas,n.d,n.c a clietne
    if Invoice.IsSoTrx = Y y Invoice->DocType.signo_IsSoTrx >1
    {
    signo = 1;
    esNotaDeCredito = false;
    }

    if Invoice.IsSoTrx = Y y Invoice->DocType.signo_IsSoTrx <1
    {
    signo = -1;
    esNotaDeCredito = true;

    }

    //facturas,n.d,n.c de proveedor; no lo pense mucho, pero no entiendo porque tiene
    //que inferirse de otra manera (actualmente, creo que las facturas a proveedor normales
    //tienden signo_isSoTrx -1
    if Invoice.IsSoTrx = Y y Invoice->DocType.signo_IsSoTrx <1
    {//factura a proveedor normal
    signo = -1; //esto para reflejar que es una deuda nuestra; no afecta al calculo de credito de los clientes
    esNotaDeCredito = false;
    }

    if Invoice.IsSoTrx = Y y Invoice->DocType.signo_IsSoTrx <1
    {
    signo = 1;
    esNotaDeCredito = true;

    }

    Lo que tiene de bueno esta forma de calcular el signo es que si un cliente es tambien un proveedor, “el saldo” con respecto al mismo se puede hacer con la misma sumatoria basica pero sin filtrar por IsSoTrx; si el resultado es positivo no debe, si no le debemos.

    Si todas mis suposiciones son validas, creo que se simplificaría mucho no solo la función en PL/PgSql, si no también el código de MBPartner, y que se deje usar la C_Invoice_V para estas cosas… Esta bien encaminado el tema? o no estoy teniendo en cuenta algo?

    PD: en el caso de una entidad que es a la vez proveedor…. se permite o se deeria permitir que nos pague ya no con n.c que le damos en carácter de cliente, si no con sus propias factura en caracter de proveedor? (y viceversa; pagarle a el con facturas comunes nuestras). Pienso que complica mucho las cosas…bah, tal vez no. Otra cosa que no estoy teniendo en cuetna es todo el tema de la contabilización que seguro que tiene en cuenta en algun momento estos “signos” (de ahí deben venir los multiplicadores….), pero bueno, no deberia afectarle al procesador contable, ya si hace uso de la vista C_Invoice_V, esta no va a ser modificada.

Viendo 1 entrada (de un total de 1)
  • Debes estar registrado para responder a este debate.