Git Product home page Git Product logo

lstgen's People

Contributors

0xccd avatar antonio-masotti avatar jenner avatar knipknap avatar pierre-jochem avatar tburschka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lstgen's Issues

Validation of reference data

Hi, first of all thank you for a quick update!

My next steps are now to check the codes against other sources to get an idea whether there could be a match. So, my assumption is that if I take an example from my own loan sheet or a reference loan sheet, it should have "more or less" same numbers like LstGen, or?

So my first example is here: https://www.lohnexperte.de/files/root-pdfs/pdf/Muster.pdf

There is a Steuer-Brutto 4926.59, resulting in LSt 1000.75 and SoliZ 42.20 as test data.


Python code ( a unit test method):

def test_lohnexample1(self):

        # source: https://www.lohnexperte.de/files/root-pdfs/pdf/Muster.pdf

        brutto = 4926.59 * 100 # Brutto in ¢ent

        l = Lohnsteuer2018()
        l.setRe4(brutto) # cent
        l.setPkv(1)
        l.setAlter1(0)
        l.setAf(0)
        l.setF(1)
        l.setPvs(0)
        l.setR(0)
        l.setLzzhinzu(0)
        l.setPvz(0)
        l.setStkl(1)
        l.setLzz(2)
        l.setKrv(2)
        l.MAIN()
        print("results lohnexample1:")
        print_lst(l)

        steuer = math.floor(float(l.getLstlzz()) + float(l.getStv()) + float(l.getSts())) / 100.0
        soli = math.floor(float(l.getSolzlzz()) + float(l.getSolzs()) + float(l.getSolzv())) / 100
        stges = steuer + soli

        assert steuer == 1000.75
        assert soli == 42.20


Asserts fail, as the output of LstGen class is:

results lohnexample1:

steuer: 1247.91
soli: 68.63
stges: 1316.54

Do you have an idea why is so?

Same Steuer-Brutto put into , here I get:

Solidaritätszuschlag: 55,18 € 
Lohnsteuer: 1.003,41 €

Actually LstGen seems to be best source of truth as we have evidence that it uses algorithms our government provides us with. :-)

Finally, the formula given in wikipedia provides the following values:

soli   51.53 
lohnsteuer   936.91

See also:
https://money.stackexchange.com/questions/102867/which-is-the-correct-source-is-the-correct-german-lohnsteuer-deduction

Ergebnisse der generierten py-Datei entsprechen nicht Validierungstests

Ich hab mittels

lstgen -x Lohnsteuer2017.xml -l python --class-name Lohnsteuer2017 --outfile lst2017.py

die Lohnsteuer-Datei geniert und teste sie, wie hier beschrieben, gegen die externe Programmierschnittstelle
https://www.bmf-steuerrechner.de/interface/schnittstelle.jsp

und bekomme leider nicht die selben Ergebnisse. Mein Code

from lst.lst2017 import Lohnsteuer2017

def print_lst(lst):
    BK = lst.getBk()
    BKS = lst.getBks()
    LSTLZZ = lst.getLstlzz()
    SOLZLZZ = lst.getSolzlzz()
    WVFRB = lst.getWvfrb()
    
    print(('BK: %i\n' + 
           'BKS: %i\n' + 
           'LSTLZZ: %i\n' + 
           'SOLZLZZ: %i\n' + 
           'WVFRB: %i') % (BK, BKS, LSTLZZ, SOLZLZZ, WVFRB))
    
def test_simple():
    brutto = 2500000 # Brutto in ¢ent
    lst2017 = Lohnsteuer2017(
        RE4=brutto,
        LZZ=1,
        STKL=1
    )
    lst2017.MAIN()
    print_lst(lst2017)

if __name__ == '__main__':
    test_simple()

liefert zum Beispiel
LSTLZZ: -1782700

aber

https://www.bmf-steuerrechner.de/interface/LSt2017.jsp?LZZ=1&RE4=2500000&STKL=1

liefert

LSTLZZ: 260100

Irgendeine Idee, was ich falsch mache?

Rounding in go code

Hello Igor,
first of all, thanks for this library. It saves a lot of time...
We are having a problem with the go implementation. I'm pertty sure it's related to the roundings (see the FIXIT code parts), thus the missing ROUND_DOWN in the github.com/shopspring/decimal lib.
E.G. the calculation like:
https://www.bmf-steuerrechner.de/interface/2021Version1.xhtml?code=eP2021&PVZ=1&R=1&RE4=207753&LZZ=2&STKL=1&AF=0&AJAHR=0&ALTER1=0&ENTSCH=0&F=0&JFREIB=0&JHINZU=0&JRE4=0&JVBEZ=0&KRV=0&KVZ=0.9&LZZFREIB=0&LZZHINZU=0&PKPV=0&PKV=0&PVS=0&SONSTB=0&STERBE=0&VBEZ=0&VBEZM=0&VBEZS=0&VBS=0&VJAHR=0&VKAPA=0&VMT=0&ZKF=0&ZMVB=0&JRE4ENT=0&SONSTENT=0

returns a drifference of 22 cents compared to the www.bmf-steuerrechner.de output.

For now we overcome this by using the javascript output and running it in a v8 engine inside our app, with this BigDecimal class:
`
// http://mikemcl.github.io/big.js/#toN
let BigDecimal = class extends Number {
static ROUND_DOWN = 0
static ROUND_UP = 3

constructor(value) {
    super(value)
}

static valueOf(value){
    return new BigDecimal(value)
}

divide(other, scale, rounding){
    if(scale==undefined || rounding==undefined){
        return new BigDecimal(this/other)
    }
    return new BigDecimal(this / other).setScale(scale, rounding)
}

multiply(other){
    return new BigDecimal(this*other)
}


setScale(scale, rounding){
    let b = Big(this)
    return new BigDecimal(b.round(scale, rounding).toNumber())
}

add(other){
    return new BigDecimal(this+other)
}

subtract(other){
    return new BigDecimal(this-other)
}

longValue(){
    return this.abs().toNumber();
}

compareTo(other){
    if(this>other){
        return new BigDecimal(1)
    }else if (this<other){
        return new BigDecimal(-1)
    }else{
        return new BigDecimal(0)
    }
}


static ZERO() {
    return new BigDecimal(0);
}
static ONE() {
    return new BigDecimal(1);
}
static TEN() {
    return new BigDecimal(10);
}

}
`

This works ok, but requires e.g. "rogchap.com/v8go" which uses cgo, which i would like to avoid.

Is there any chance to get this rounding thing fixed, so we can use the pure go implementation?
I belive, that using something like the BigDecimal class in go as an abstraction should work. As far as i can see, we don't need that complicated function, just add/mul/div/sub and round and those 2 rounding functions should be easily implementable in go:
up: math.Ceil(value10^scale)/10^scale
down: math.Floor(value
10^scale)/10^scale
right?

And one more question. Are you going to add the 2022 calculation also? The BFM allready released a pre version:
(https://www.bundesfinanzministerium.de/Content/DE/Downloads/Steuern/Steuerarten/Lohnsteuer/Programmablaufplan/2021-10-05-PAP-2022-entwuerfe.html)

Thank you

CLI examples from readme seem to be missing arguments

When I try to execute the code examples as they are shown in the Readme, they throw an error

% lstgen 2014 python --class-name Lohnsteuer2014 --outfile lst2014.py   
usage: lstgen [-h] [-V] [-l LANG] [-p PAP] [-x XML_PATH] [--pap-versions]
              [--outfile OUTFILE] [--class-name CLASS_NAME] [--indent INDENT]
              [--java-package-name JAVA_PACKAGE] [--php-ns PHP_NAMESPACE]
lstgen: error: unrecognized arguments: 2014 python

It does work with extra -p and -l arguments

lstgen -p 2014 -l python --class-name Lohnsteuer2014 --outfile lst2014.py

Perhaps the readme could be ammended to include that.

Incomplete --pap-versions output

While the source BMF site has XML files also for both 2018 and 2019, the tool does not list all of them:

> lstgen --pap-versions
Verfügbare PAP Versionen:
2006
2007
2008
2009
2010
2011bisNov
2011Dez
2012
2013
2014
2015bisNov
2015Dez
2016
2017

Very small precision problem

I tried both the python and the javascript generations. And the calculations are correct in comparison to the BMF online calculator. But, for example,

RE4 = 195000
KVZ = 1.1
LZZ = 2
PVZ = 1
STKL = 1
R = 0
KRV = 0

I get:

steuer = 161.83
soli = 8.90

in the online calculator:

Ergebnis der Berechnung der Lohnsteuer für 2020
Die Lohnsteuer beträgt: 161,75 Euro
Der Solidaritätszuschlag beträgt: 8,89 Euro

Any help to find the issue is greatly appreciated :)

Startup errors with Python3

Hi,

following the README I can't get the tool running with Python 3 for a Python generation.

Example Dockerfile:

FROM python:3.6

RUN pip3 install lstgen &&\
    lstgen 2014 python --class-name Lohnsteuer2014 --outfile lst2014.py

Error:

usage: lstgen [-h] [-l LANG] [-p PAP] [-x XML_PATH] [--pap-versions]
              [--outfile OUTFILE] [--class-name CLASS_NAME] [--indent INDENT]
              [--java-package-name JAVA_PACKAGE] [--php-ns PHP_NAMESPACE]
lstgen: error: unrecognized arguments: 2014 python

Following the help, I have also tried:


FROM python:3.6

RUN pip3 install lstgen &&\
    lstgen -p 2017 -l python

but then get the following error:

/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
Traceback (most recent call last):
  File "/usr/local/bin/lstgen", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.6/site-packages/lstgen/cli.py", line 113, in main
    pap_parser = PapParser(etree.fromstring(xml_content))
  File "/usr/local/lib/python3.6/site-packages/lstgen/__init__.py", line 253, in __init__
    self.parse()
  File "/usr/local/lib/python3.6/site-packages/lstgen/__init__.py", line 259, in parse
    main_element = self.tree_root.xpath('/PAP/METHODS/MAIN')[0]
IndexError: list index out of range

Naming of PAP versions

First of all, Thanks a lot for putting in the work and making it available for everyone, really awesome.

It would be very helpful if the PAP versions were named in a way that they can be selected automatically. Currently they look like this:

Verfügbare PAP Versionen:
2006
2007
2008
2009
2010
2011bisNov
2011Dez
2012
2013
2014
2015bisNov
2015Dez
2016
2017
2018
2019
2020

Better would be (IMO):

2006
2007
2008
2009
2010
2011-1
2011-12
2012
2013
2014
2015-1
2015-12
2016
2017
2018
2019
2020

So each version is named according to the time where the rules come into effect. This would also be future-proof in case rules are changed mid-month in the future, e.g.

2020-11-15

2010 generator: AttributeError: 'NoneType' object has no attribute 'replace'

The 2010 generator is causing an exception:

lstgen -p 2010 -l python --class-name BmfTax --outfile app/bmf/tax2010.py
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:999: InsecureRequestWarning: Unverified HTTPS request is being made to host 'www.bmf-st
euerrechner.de'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warn
ings
  warnings.warn(
Traceback (most recent call last):
  File "/usr/local/bin/lstgen", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.8/dist-packages/lstgen/cli.py", line 161, in main
    generator.generate()
  File "/usr/local/lib/python3.8/dist-packages/lstgen/generators/python/__init__.py", line 67, in generate
    self._write_constructor()
  File "/usr/local/lib/python3.8/dist-packages/lstgen/generators/python/__init__.py", line 102, in _write_constructor
    value=self.convert_to_python(var.default)
  File "/usr/local/lib/python3.8/dist-packages/lstgen/generators/python/__init__.py", line 168, in convert_to_python
    tree = ast.parse(prepare_expr(value))
  File "/usr/local/lib/python3.8/dist-packages/lstgen/__init__.py", line 26, in prepare_expr
    source = source.replace(key, repl)
AttributeError: 'NoneType' object has no attribute 'replace'

The resulting Python module is then incomplete.

SSL error

Hi,

I tried to create the python class. Nothing changed in the library.
While grabbing the XML, Python raised the SSL error.
Is it possible to fix that?

Best,
Tino

AttributeError: 'Name' object has no attribute 'value'

Hi,

I'm try to generate the classes (2020, 2021) for php, but i always get the same issue:

lstgen -p 2021_1 -l php --class-name Lohnsteuer2021 --outfile Lohnsteuer2021.php
/usr/local/lib/python3.9/site-packages/urllib3/connectionpool.py:979: InsecureRequestWarning: Unverified HTTPS request is being made to host 'www.bmf-steuerrechner.de'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  warnings.warn(
Traceback (most recent call last):
  File "/usr/local/bin/lstgen", line 33, in <module>
    sys.exit(load_entry_point('LstGen==0.5.2', 'console_scripts', 'lstgen')())
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/cli.py", line 175, in main
    generator.generate()
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 112, in generate
    self._write_method(method)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 166, in _write_method
    self._write_stmt_body(method)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 185, in _write_stmt_body
    self._write_if(part)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 194, in _write_if
    self._write_stmt_body(stmt)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 187, in _write_stmt_body
    self._write_else(part)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 203, in _write_else
    self._write_stmt_body(stmt)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 185, in _write_stmt_body
    self._write_if(part)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 194, in _write_if
    self._write_stmt_body(stmt)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 189, in _write_stmt_body
    self._write_stmt_body(part)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 181, in _write_stmt_body
    self.writer.writeln(self._convert_exec(part.expr))
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 209, in _convert_exec
    ret += self.to_code(parsed_stmt)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/ast2code.py", line 225, in to_code
    return self._conv_call(node)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/ast2code.py", line 143, in _conv_call
    caller = self.to_code(node.func)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/ast2code.py", line 204, in to_code
    return self._conv_attribute(node)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 229, in _conv_attribute
    val = self.to_code(node.value)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/ast2code.py", line 225, in to_code
    return self._conv_call(node)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/ast2code.py", line 143, in _conv_call
    caller = self.to_code(node.func)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/ast2code.py", line 204, in to_code
    return self._conv_attribute(node)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/php/__init__.py", line 229, in _conv_attribute
    val = self.to_code(node.value)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/ast2code.py", line 222, in to_code
    return self._conv_list_subscript(node)
  File "/usr/local/lib/python3.9/site-packages/LstGen-0.5.2-py3.9.egg/lstgen/generators/ast2code.py", line 137, in _conv_list_subscript
    self.to_code(node.slice.value) +
AttributeError: 'Name' object has no attribute 'value'

Error Message Fatal error: Uncaught Error: Call to undefined method BigDecimal::toFloat() in ...

Hi Jenner, thank you for your great work on making this Software.

I have a problem with the implementation of the sample PHP-Code:

$brutto = 500000; // Brutto in ¢ent
$lst = new Lohnsteuer2023();
$lst->setRe4($brutto);
$lst->setPkv(1);
$lst->setAlter1(0);
$lst->setAf(0);
$lst->setF(1);
$lst->setPvs(0);
$lst->setR(0);
$lst->setLzzhinzu(0);
$lst->setPvz(0);
$lst->setStkl(1);
$lst->setLzz(2);
$lst->setKrv(2);
$lst->main();
$steuer = floor($lst->getLstlzz()->toFloat() + $lst->getStv()->toFloat() + $lst->getSts()->toFloat());
$soli = floor($lst->getSolzlzz()->toFloat() + $lst->getSolzs()->toFloat() + $lst->getSolzv()->toFloat()) / 100;
$stges = $steuer + $soli;
echo "steuer: $steuer\nsoli: $soli\nstges: $stges\n";`

I always get the error message: Fatal error: Uncaught Error: Call to undefined method BigDecimal::toFloat() in ... on line x, where x is the line where toFloat() is first used in the sample code.

I am convinced that i produce these error through something myself, but did you have an idea what i could change to get it up and running?

Thank you very much!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.