roshkadev / rshk-jsifenlib

Librería de código abierto para interactuar con SIFEN de la SET.
100 stars 42 forks source link

Error de calculo de iva cuando la base no es 100 #50

Open trinidadmarcelo opened 1 year ago

trinidadmarcelo commented 1 year ago

En la línea 34 de TgCamIVA esta redondeando un calculo que no tiene que redondear. Si la base es 30 por ejemplo, lo quehace es 30/100 y queda en 0, en vez de quedar 0.30, solo en caso de que sea 100 queda bien, o sea 1

A continuación el método con las correcciones propuestas:

public void setupSOAPElements(GenerationCtx generationCtx, SOAPElement gCamItem, CMondT cMoneOpe, BigDecimal dTotOpeItem) throws SOAPException {
        SOAPElement gCamIVA = gCamItem.addChildElement("gCamIVA");
        gCamIVA.addChildElement("iAfecIVA").setTextContent(String.valueOf(this.iAfecIVA.getVal()));
        gCamIVA.addChildElement("dDesAfecIVA").setTextContent(this.iAfecIVA.getDescripcion());
        gCamIVA.addChildElement("dPropIVA").setTextContent(String.valueOf(this.dPropIVA));
        gCamIVA.addChildElement("dTasaIVA").setTextContent(String.valueOf(this.dTasaIVA));
        int scale = cMoneOpe.name().equals("PYG") ? 0 : 2;

        dTotOpeItem = dTotOpeItem.setScale(scale, RoundingMode.HALF_UP);

        BigDecimal hundred = BigDecimal.valueOf(100);
        //AQUI ESTAN REDONDEANDO ERRONEAMENTE
        //BigDecimal propIVA = this.dPropIVA.divide(hundred, scale, RoundingMode.HALF_UP);
        BigDecimal propIVA = this.dPropIVA.divide(hundred, 3, RoundingMode.HALF_UP);
        BigDecimal tasaIvaCoef = this.dTasaIVA.divide(hundred, 3, RoundingMode.HALF_UP).add(BigDecimal.ONE);

        if (this.iAfecIVA.getVal() == 1 || this.iAfecIVA.getVal() == 4) {
            dBasGravIVA = dTotOpeItem
                    .multiply(propIVA)
                    .divide(tasaIvaCoef, scale, RoundingMode.HALF_UP);
            dLiqIVAItem = dTotOpeItem.multiply(propIVA).subtract(dBasGravIVA);

//            if (this.dTasaIVA.equals(BigDecimal.valueOf(10))) {
//                //(total)*1/1.1 
//
//                this.dBasGravIVA = dTotOpeItem.multiply(propIVA).divide(BigDecimal.valueOf(1.1), scale, RoundingMode.HALF_UP);
//                //(preciovta*cantidad)*1/11
//                this.dLiqIVAItem = dTotOpeItem.multiply(propIVA).divide(BigDecimal.valueOf(11), scale, RoundingMode.HALF_UP);
//            } else if (this.dTasaIVA.equals(BigDecimal.valueOf(5))) {
//                this.dBasGravIVA = dTotOpeItem.multiply(propIVA).divide(BigDecimal.valueOf(1.05), scale, RoundingMode.HALF_UP);
//                this.dLiqIVAItem = dTotOpeItem.multiply(propIVA).divide(BigDecimal.valueOf(21), scale, RoundingMode.HALF_UP);
//            }
        } else {
            this.dBasGravIVA = BigDecimal.ZERO;
            this.dLiqIVAItem = BigDecimal.ZERO;
        }

        gCamIVA.addChildElement("dBasGravIVA").setTextContent(String.valueOf(this.dBasGravIVA));
        gCamIVA.addChildElement("dLiqIVAItem").setTextContent(String.valueOf(this.dLiqIVAItem));

        if (generationCtx.isHabilitarNotaTecnica13()) {
            if (this.iAfecIVA.getVal() == 4) {
                // Actualización: https://ekuatia.set.gov.py/portal/ekuatia/detail?content-id=/repository/collaboration/sites/ekuatia/documents/documentacion/documentacion-tecnica/NT_E_KUATIA_013_MT_V150.pdf
                // E737 = [100 * EA008 * (100 – E733)] / [10000 + (E734 * E733)]
                //this.dBasExe = (dTotOpeItem.multiply(hundred.subtract(dPropIVA)).multiply(hundred)).divide((this.dTasaIVA.multiply(dPropIVA)).add(BigDecimal.valueOf(10000)), scale, RoundingMode.HALF_UP);

                //Mas simple y claro  exento = total-basegravada-iva
                this.dBasExe = dTotOpeItem.subtract(this.dBasGravIVA).subtract(this.dLiqIVAItem);
            } else {
                this.dBasExe = BigDecimal.valueOf(0);
            }
            gCamIVA.addChildElement("dBasExe").setTextContent(String.valueOf(this.dBasExe));
        }

    }
jencisopy commented 1 year ago

Y hay que corregir tambien la sumatoria en TgTotSub

Por ejemplo en los casos que la base no es el 100% como es en el rubro inmobiliario que es 5% sobre una base grabada del 30%. Entonces de un monto de 1.000.000.- se calcula el iva 5% sobre el 30% y queda mas o menos asi

                                Base Gravada =    285.714   dBasGravIVA - dBaseGrav10 o dBaseGrav5 (aqui no calcula bien)
                                IVA                 =      14.286   dLiqIVAItem  - dIVA10     
                                Base Exento   =    700.000   dBasExe  - dSubExe (aqui no calcula bien)
                                                         =======
                                Total               = 1.000.000

Asi debe figurar en los xmls

Para esta situación se agrego la nt 13

Abajo una solución propuesta en TgTotSub

            if (gCamIVA.getiAfecIVA().getVal() == 1 || gCamIVA.getiAfecIVA().getVal() == 4) {
                if (gCamIVA.getdTasaIVA().equals(BigDecimal.valueOf(10))) {
                    //Se Agrego
                    this.dSubExe = this.dSubExe.add(dBasExe).setScale(scale);
                    //Correccin
                    this.dSub10 = this.dSub10.add(dTotOpeItem.subtract(dBasExe)).setScale(scale);
                    this.dIVA10 = this.dIVA10.add(dLiqIVAItem);
                    this.dBaseGrav10 = this.dBaseGrav10.add(dBasGravIVA);
                    this.dLiqTotIVA10 = BigDecimal.ZERO;
                } else if (gCamIVA.getdTasaIVA().equals(BigDecimal.valueOf(5))) {
                    //Se agrego
                    this.dSubExe = this.dSubExe.add(dBasExe).setScale(scale);                        
                    //Correccin
                    this.dSub5 = this.dSub5.add(dTotOpeItem.subtract(dBasExe)).setScale(scale);
                    this.dIVA5 = this.dIVA5.add(dLiqIVAItem);
                    this.dBaseGrav5 = this.dBaseGrav5.add(dBasGravIVA);
                    this.dLiqTotIVA5 = BigDecimal.ZERO;
                }
jencisopy commented 1 year ago

Al final esto es lo que me funciono y ya esta aprobando las facturas.

Cambios en TgCamIVA

public void setupSOAPElements(GenerationCtx generationCtx, SOAPElement gCamItem, CMondT cMoneOpe, BigDecimal dTotOpeItem) throws SOAPException { SOAPElement gCamIVA = gCamItem.addChildElement("gCamIVA"); gCamIVA.addChildElement("iAfecIVA").setTextContent(String.valueOf(this.iAfecIVA.getVal())); gCamIVA.addChildElement("dDesAfecIVA").setTextContent(this.iAfecIVA.getDescripcion()); gCamIVA.addChildElement("dPropIVA").setTextContent(String.valueOf(this.dPropIVA)); gCamIVA.addChildElement("dTasaIVA").setTextContent(String.valueOf(this.dTasaIVA)); int scale = cMoneOpe.name().equals("PYG") ? 0 : 2;

    dTotOpeItem = dTotOpeItem.setScale(scale, RoundingMode.HALF_UP);

    BigDecimal hundred = BigDecimal.valueOf(100);
    //AQUI ESTAN REDONDEANDO ERRONEAMENTE
    //BigDecimal propIVA = this.dPropIVA.divide(hundred, scale, RoundingMode.HALF_UP);
    BigDecimal propIVA = this.dPropIVA.divide(hundred, 3, RoundingMode.HALF_UP);
    BigDecimal tasaIvaCoef = this.dTasaIVA.divide(hundred, 3, RoundingMode.HALF_UP).multiply(propIVA).add(BigDecimal.ONE);
    BigDecimal montoSinIva;
    if (this.iAfecIVA.getVal() == 1 || this.iAfecIVA.getVal() == 4) {
        montoSinIva = dTotOpeItem.divide(tasaIvaCoef, scale, RoundingMode.HALF_UP);
        dLiqIVAItem = dTotOpeItem.subtract(montoSinIva).setScale(scale, RoundingMode.HALF_UP);
        dBasGravIVA = montoSinIva.multiply(propIVA).setScale(scale, RoundingMode.HALF_UP);

// if (this.dTasaIVA.equals(BigDecimal.valueOf(10))) { // //(total)1/1.1 // // this.dBasGravIVA = dTotOpeItem.multiply(propIVA).divide(BigDecimal.valueOf(1.1), scale, RoundingMode.HALF_UP); // //(preciovtacantidad)*1/11 // this.dLiqIVAItem = dTotOpeItem.multiply(propIVA).divide(BigDecimal.valueOf(11), scale, RoundingMode.HALF_UP); // } else if (this.dTasaIVA.equals(BigDecimal.valueOf(5))) { // this.dBasGravIVA = dTotOpeItem.multiply(propIVA).divide(BigDecimal.valueOf(1.05), scale, RoundingMode.HALF_UP); // this.dLiqIVAItem = dTotOpeItem.multiply(propIVA).divide(BigDecimal.valueOf(21), scale, RoundingMode.HALF_UP); // } } else { this.dBasGravIVA = BigDecimal.ZERO; this.dLiqIVAItem = BigDecimal.ZERO; }

    gCamIVA.addChildElement("dBasGravIVA").setTextContent(String.valueOf(this.dBasGravIVA));
    gCamIVA.addChildElement("dLiqIVAItem").setTextContent(String.valueOf(this.dLiqIVAItem));

    if (generationCtx.isHabilitarNotaTecnica13()) {
        if (this.iAfecIVA.getVal() == 4) {
            // Actualización: https://ekuatia.set.gov.py/portal/ekuatia/detail?content-id=/repository/collaboration/sites/ekuatia/documents/documentacion/documentacion-tecnica/NT_E_KUATIA_013_MT_V150.pdf
            // E737 = [100 * EA008 * (100 – E733)] / [10000 + (E734 * E733)]
            //this.dBasExe = (dTotOpeItem.multiply(hundred.subtract(dPropIVA)).multiply(hundred)).divide((this.dTasaIVA.multiply(dPropIVA)).add(BigDecimal.valueOf(10000)), scale, RoundingMode.HALF_UP);

            //Mas simple y claro  exento = total-basegravada-iva
            this.dBasExe = dTotOpeItem.subtract(this.dBasGravIVA).subtract(this.dLiqIVAItem).setScale(scale, RoundingMode.HALF_UP);
        } else {
            this.dBasExe = BigDecimal.valueOf(0);
        }
        gCamIVA.addChildElement("dBasExe").setTextContent(String.valueOf(this.dBasExe));
    }

}
garak92 commented 6 months ago

Muchas gracias @jencisopy, tuve exactamente el mismo issue con una factura con gravado parcial y esta fue la solución

pablo commented 6 months ago

Pueden enviar un PULL REQUEST?

On Mon, Mar 11, 2024 at 11:51 AM Elim Garak @.***> wrote:

Muchas gracias @jencisopy https://github.com/jencisopy jencisopy, tuve exactamente el mismo issue con una factura con gravado parcial y esta fue la solución

— Reply to this email directly, view it on GitHub https://github.com/roshkadev/rshk-jsifenlib/issues/50#issuecomment-1988627422, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIUGHCGQHIUEGN3GEOCBA3YXXAHZAVCNFSM6AAAAAAZO4WO3KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOBYGYZDONBSGI . You are receiving this because you are subscribed to this thread.Message ID: @.***>