[MINOR] Add JP Regime#729
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #729 +/- ##
========================================
Coverage 92.86% 92.86%
========================================
Files 331 335 +4
Lines 17260 17373 +113
========================================
+ Hits 16029 16134 +105
- Misses 867 871 +4
- Partials 364 368 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
samlown
left a comment
There was a problem hiding this comment.
Thanks for this! Very difficult regime to tackle :-) A few changes requested to be more aligned with existing regimes, or at least, where we want to go. I'd reconsider using the VAT code, it looks like Japan uses something else, and I'd double check the reverse-charge usage.
| return validation.ValidateStruct(p, | ||
| validation.Field(&p.TaxID, | ||
| validation.Required, | ||
| tax.RequireIdentityCode, |
There was a problem hiding this comment.
The simplified tag is normally only used for B2C scenarios and not the type of issuing party. Do Japanese entities need to include some kind of ID in invoices even if not registered for VAT? That determines what validations should take place.
There was a problem hiding this comment.
Good catch. I think enforcing the tax ID could make sense for QIS registered entities, but for a simplified invoice, it probably doesn't make sense to enforce the issuer to have a registration number. So what about having a simplified tag for B2C scenarios and create another custom tag for QIS something like qualified or qis?
| TaxRatePro cbc.Key = "pro" // Professional services (≤ ¥1,000,000) | ||
| TaxRateProOver cbc.Key = "pro-over" // Professional services (> ¥1,000,000) |
There was a problem hiding this comment.
Why did experiment with withholding/retained tax rates, but recently this is something we try to avoid and just let the user put in what makes sense for them. It avoids hard to understand keys like "pro-over", whose meaning is not obvious at first glance.
| Name: i18n.String{ | ||
| i18n.EN: "Japan", | ||
| i18n.JA: "日本", | ||
| }, |
There was a problem hiding this comment.
Would be great to have the key details from the README here in the description.
There was a problem hiding this comment.
I think most of the details here can be added to the regime description and comments.
| Note: &tax.ScenarioNote{ | ||
| Key: org.NoteKeyLegal, | ||
| Src: tax.TagReverseCharge, | ||
| Text: "Reverse Charge: The recipient is liable for the consumption tax on this transaction", |
There was a problem hiding this comment.
There is no JP translation required here? Does JP actually support Reverse Charge? Would be useful to have comments indicating the source of details.
There was a problem hiding this comment.
Hi @samlown. Thanks for reviewing the PR!
For this specific scenario, I was trying to understand how they apply at other countries to check if it could be applicable for JP. As far as I understood, Japan does have a reverse charge mechanism, but it's quite limited in scope compared to EU-style reverse charge. It applies specifically to cross-border digital services when a foreign provider sells digital services to a Japanese business.
You are right a source is missing. Not sure if you understand the same than me for example from this link: https://www.nta.go.jp/english/taxes/consumption_tax/cross-kokugai-en.pdf#:~:text=Under%20Consumption%20Tax%20Act%2C%20when%20a%20business,receives%20electronic%20services%20from%20a%20foreign%20business.
These concepts are somehow new to me. To keep it simple I can remove this tag for now. wdyt?
| // Consumption Tax (消費税) | ||
| // | ||
| { | ||
| Code: tax.CategoryVAT, |
There was a problem hiding this comment.
Is VAT the correct code here? The key detail with VAT is that expenses can be claimed back, a consumption or sales tax cannot.
| URL: "https://taxsummaries.pwc.com/japan/corporate/withholding-taxes", | ||
| }, | ||
| }, | ||
| Rates: []*tax.RateDef{ |
There was a problem hiding this comment.
As stated earlier, I don't think I'd worry about the income tax rates, its usually easier just to enter the values manually.
There was a problem hiding this comment.
ok I will remove the support for withholding taxes
There was a problem hiding this comment.
I'd put this in a separate PR to discuss independently.
There was a problem hiding this comment.
Pull request overview
This pull request adds comprehensive support for the Japanese tax regime (JP) to GOBL, implementing Japan's Consumption Tax (JCT), Withholding Income Tax system, and the Qualified Invoice System (QIS). The implementation follows established GOBL patterns and includes extensive test coverage, documentation, and working examples.
Changes:
- Added complete Japanese tax regime with Consumption Tax (10% standard, 8% reduced) and Withholding Income Tax (10.21% and 20.42% rates including reconstruction surtax)
- Implemented Corporate Number validation with checksum verification and Invoice Registration Number support for the Qualified Invoice System
- Created comprehensive documentation in
regimes/README.mdproviding step-by-step guide for adding new tax regimes
Reviewed changes
Copilot reviewed 21 out of 26 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| regimes/regimes.go | Registers JP regime via blank import |
| regimes/jp/jp.go | Main regime definition with Normalize and Validate functions |
| regimes/jp/tax_categories.go | Defines Consumption Tax and Withholding Income Tax categories with historical rates |
| regimes/jp/tax_identity.go | Corporate Number validation with checksum algorithm |
| regimes/jp/identities.go | Invoice Registration Number identity type |
| regimes/jp/invoices.go | Invoice-level validation requiring supplier tax ID (except for simplified invoices) |
| regimes/jp/scenarios.go | Reverse charge and simplified invoice scenarios |
| regimes/jp/*_test.go | Comprehensive test coverage for all components |
| regimes/jp/README.md | Detailed regime documentation with tax system explanations |
| regimes/README.md | New comprehensive guide for creating tax regimes |
| examples/jp/*.yaml | Four example invoices demonstrating standard, freelance, reverse charge, and simplified scenarios |
| examples/jp/out/*.json | Generated JSON output for all example invoices |
| data/regimes/jp.json | Generated regime data |
| data/schemas/tax/regime-code.json | Updated regime code schema |
| CHANGELOG.md | Updated with JP regime addition |
| .gitignore | Added .idea directory for JetBrains IDEs |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,68 @@ | |||
| # GOBL Japan Tax Regime — `JP` | |||
|
|
|||
| Japan's tax regime for GOBL covering the Consumption Tax, Withholding Incom and the Qualified Invoice System. | |||
There was a problem hiding this comment.
There is a typo in "Withholding Incom" which should be "Withholding Income Tax". Also, there are extra spaces before "and".
| Japan's tax regime for GOBL covering the Consumption Tax, Withholding Incom and the Qualified Invoice System. | |
| Japan's tax regime for GOBL covering the Consumption Tax, Withholding Income Tax and the Qualified Invoice System. |
|
|
||
| - [EU-Japan Centre - Qualified Invoice System](https://www.eu-japan.eu/qualified-invoice-system) | ||
| - [Qualified Invoice System Instructions](https://www.nta.go.jp/taxes/shiraberu/zeimokubetsu/shohi/keigenzeiritsu/pdf/0024006-039_01.pdf) | ||
| - |
There was a problem hiding this comment.
There is an incomplete bullet point with just a dash and no text. This appears to be an unfinished entry in the reference list.
| - |
| {name: "valid sony corporate number", code: "5010401067252"}, // https://www.houjin-bangou.nta.go.jp/henkorireki-johoto.html?selHouzinNo=1130001011420 | ||
| {name: "valid nintendo corporate number", code: "1130001011420"}, |
There was a problem hiding this comment.
The comment shows a URL for Nintendo's corporate number (1130001011420) but is placed on the line testing Sony's number (5010401067252). The URL should either be removed or corrected to match the Sony corporate number, or moved to the next line.
| {name: "valid sony corporate number", code: "5010401067252"}, // https://www.houjin-bangou.nta.go.jp/henkorireki-johoto.html?selHouzinNo=1130001011420 | |
| {name: "valid nintendo corporate number", code: "1130001011420"}, | |
| {name: "valid sony corporate number", code: "5010401067252"}, | |
| {name: "valid nintendo corporate number", code: "1130001011420"}, // https://www.houjin-bangou.nta.go.jp/henkorireki-johoto.html?selHouzinNo=1130001011420 |
| | `it` | Italy | | ||
| | `mx` | Mexico | | ||
| | `nl` | Netherlands | | ||
| | `pl` | Poland | | ||
| | `pt` | Portugal | | ||
| | `se` | Sweden | | ||
| | `sg` | Singapore | | ||
| | `us` | United States | |
There was a problem hiding this comment.
The JP regime should be added to the "Existing Regimes" table in the regimes/README.md file. It should be inserted in alphabetical order between IT (Italy) and MX (Mexico) as: | jp | Japan |
Summary
Tax Categories
Tax Identity
Qualified Invoice System (QIS)
T+ 13 digits) as an organization identity (jp-invoice-registration-number), required since October 2023 for input tax credit claims.Scenarios
reverse-charge) — Adds legal note for reverse charge mechanism on cross-border B2B services.simplified) — Supports simplified invoices for transactions under ¥10,000.Corrections
credit-noteanddebit-noteextension types.Examples
invoice-jp-jp.yaml— Standard domestic B2B invoiceinvoice-jp-freelance.yaml— Freelancer invoice with withholding taxinvoice-jp-reverse-charge.yaml— Cross-border reverse charge invoiceinvoice-jp-simplified.yaml— Simplified invoiceFiles Added
regimes/jp/jp.goregimes/jp/tax_categories.goregimes/jp/tax_identity.goregimes/jp/scenarios.goregimes/jp/invoices.goregimes/jp/identities.goregimes/jp/README.mdregimes/jp/*_test.goexamples/jp/*.yamldata/regimes/jp.jsonTest plan
go test ./regimes/jp/...passesgo test ./...passes (no regressions)Pre-Review Checklist
go generate .to ensure that the Schemas and Regime data are up to date.Only after checking off all the previous items: