Skip to content

Fix PLN amount rounding for compliance with PL tax rules 💰#181

Open
mbronk wants to merge 3 commits intoRustInFinance:mainfrom
mbronk:personal/mbronk/pl-tax-currency-values-rounding
Open

Fix PLN amount rounding for compliance with PL tax rules 💰#181
mbronk wants to merge 3 commits intoRustInFinance:mainfrom
mbronk:personal/mbronk/pl-tax-currency-values-rounding

Conversation

@mbronk
Copy link
Copy Markdown
Contributor

@mbronk mbronk commented Mar 10, 2026

Polish tax law requires different rounding methods depending on income type, which was not previously implemented. This change (hopefully1) brings the calculation into compliance with Art. 63 Ordynacji Podatkowej (OP).

  1. Each currency-converted tax event (i.e. stock sales, dividend...) is expressed with "grosz" (0,01) precision - at the time of FX calculation, before aggregating further.
    Basis:
    • Art. 11a Ustawy o PIT only defines the FX conversion formula (NBP@T-1), but the Act does NOT prescribe special rounding rules,
    • 0,01zł is the lowest monetary value and sub-grosz values cannot be reported on any tax forms,
    • Therefore: Mathematical rounding rules apply ( >= 0.005zł --> 0.01zł).2
  1. Interests and dividends are separated as they follow different rounding rules when calculating the lump-sum tax
    1. Interests aggregate (art. 30a ust. 1 pkt 3 PIT) as well as their resulting lump-sum tax, are rounded ⬆️UP to the full "grosz" 🪙 (0,00001zł -> 0,01zł) — art. 63 §1a OP
    2. Dividends aggregate (art. 30a ust. 1 pkt 4 PIT) as well as their resulting lump-sum tax, are rounded to the nearest full ZŁOTY 💵 (0,50zł -> 1zł) — art. 63 §1 OP
    3. Foreign tax withholding: no rounding; the standard FX rule to round to grosz (0,01) precision - rule 1 (above)
    4. Net/gross/cost stock proceeds are not subject to lump-sum tax calculations and reported in full on PIT-38 form, hence only standard FX rules (no. 1-above) applies and they are reported with "grosz" precision.

Warning

Footnotes

  1. Disclaimer: the stated interpretation of the rules reflects my best understanding of the current Polish tax acts and - in some cases - some non-binding advice I've received at Krajowa Informacja Skarbowa (KAS). I'm neither a tax professional, nor an accountant/financial advisor, so do NOT take these as source of "truth" as these clearly are just "works for my personal tax reports", not a tax or legal advice. In fact, I highly suggest reviewing the relevant acts (and/or reaching out to your Tax Office, etc.) and drawing own conclusions.

  2. § 5 ust. 6 rozporządzenia MF z 28 listopada 2008 r for VAT states:
    "Kwoty podatku wykazuje się w złotych bez względu na to, w jakiej walucie określona jest kwota należności w fakturze. Kwoty wykazywane w fakturze zaokrągla się do pełnych groszy, przy czym końcówki poniżej 0,5 grosza pomija się, a końcówki 0,5 grosza i wyższe zaokrągla się do 1 grosza."

@mbronk
Copy link
Copy Markdown
Contributor Author

mbronk commented Mar 10, 2026

@jczaja jczaja self-requested a review March 12, 2026 07:39
Copy link
Copy Markdown
Collaborator

@jczaja jczaja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had talked to tax advisor who then called "Naczelna izba skarbowa" to disscuss the matter of rounding. He told me that we should not round every single transaction just a sum of transactions.

Polish tax law requires different rounding methods depending on income type,
which was not previously implemented. This change brings the calculation into
compliance with Art. 63 Ordynacji Podatkowej (OP).

1. Per currency-converted "tax event" (i.e. stock sales, dividend...),
   convert each result to full "grosz" (0,01 precision) - before
   summing.
   Basis: Mathematical rounding rules (0,01zł is the lowest monetary
   value)

2. Interests and dividends are separated as they follow different
   rounding rules when calculating the lump-sum tax

   a) Interests aggregate (art. 30a ust. 1 pkt 3 PIT) as well as
      their resulting lump-sum tax, are rounded UP to the nearest
      full "grosz" — art. 63 §1a OP
   b) Dividends aggregate (art. 30a ust. 1 pkt 4 PIT) as well
      as their resulting lump-sum tax, are rounded to the nearest
      full ZLOTY (0,50zl -> 1zl)  — art. 63 §1 OP
   c) Foreign tax withholding: no rounding the standard FX rule
      to round to grosz (0,01) precision - rule #1 (above)
   d) Net/gross/cost stock proceeds are not subject to lump-sum
      tax calculations and reported in full on PIT-38 form, hence
      only standard FX rules (#1-above) applies and they are reported
      with "grosz" precision.

Signed-off-by: Mateusz Bronk <mbronk@users.noreply.github.com>
@mbronk mbronk force-pushed the personal/mbronk/pl-tax-currency-values-rounding branch from ff2d46e to 6bf387a Compare April 4, 2026 15:06
@mbronk
Copy link
Copy Markdown
Contributor Author

mbronk commented Apr 4, 2026

I had talked to tax advisor who then called "Naczelna izba skarbowa" to disscuss the matter of rounding. He told me that we should not round every single transaction just a sum of transactions.

Thanks for looking into this! I was aware of it being a little sketchy, but I haven't found any written rule preventing the rounding, and my objective was for the values to match the pen and paper calculations I was doing on a side, to confirm.1

I've now changed the default so there's no per-transaction rounding now, consistent with what your advisor confirmed.

Since, to my knowledge, that guidance isn't formally documented anywhere, I kept per-transaction rounding as an opt-in2 (--round-per-transaction / GUI Options toggle) for anyone who wants to match pen-and-paper calculations (it helps me be consistent with my own past-years calculations). It's off by default.

Footnotes

  1. On a separate topic, I think use of f32 for financial data is a little risky, given the possible accumulated rounding error. I've switched to 'decimal' on my fork - will add it as a PR for your consideration.

  2. Of course, if there are reliable/quotable references proving my method is invalid, the extra option makes no sense and should be deleted. If you find anything - please do share! As long as it is "sketchy", I hope you'd be OK with this remaining an option for the user to select (aka. I prefer to continue to run my own reports w/ this enabled)

Per tax advisor consultation with Naczelna Izba Skarbowa and Art. 63
Ordynacja Podatkowa, rounding should only be applied to final tax base
and tax amount sums, not to individual transactions.

Change default behavior to carry full f32 precision through per-transaction
FX conversions. The previous per-transaction rounding to grosz is preserved
as an opt-in flag:
  - CLI: --round-per-transaction
  - GUI: Options menu toggle (MenuBar)

Also add default-run to Cargo.toml to resolve binary ambiguity.

Signed-off-by: Mateusz Bronk <mbronk@users.noreply.github.com>
@mbronk mbronk force-pushed the personal/mbronk/pl-tax-currency-values-rounding branch from 6bf387a to 1096aa5 Compare April 4, 2026 15:19
Signed-off-by: Mateusz Bronk <mbronk@users.noreply.github.com>
@mbronk mbronk force-pushed the personal/mbronk/pl-tax-currency-values-rounding branch from e10ff1e to f74f7bd Compare April 4, 2026 16:49
@jczaja
Copy link
Copy Markdown
Collaborator

jczaja commented Apr 9, 2026

@mbronk Hi, thanks for your effort but I'm not going to merge this PR. The reason is that it introduces significant changes that will have to be maintained and tested. Moreover option in GUI will confuse many users who will keep coming for explanation as not all of them are familiar with details of tax calculation that are disscussed in this PR. So after all I do not think there is a valid cause to have this PR merged. Thanks for your effort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants