ekwo-os 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +873 -0
- package/dist/args.d.ts +57 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +134 -0
- package/dist/args.js.map +1 -0
- package/dist/assets/expected-objects.json +9432 -0
- package/dist/assets/migrations/20260911120000_core_companies.sql +260 -0
- package/dist/assets/migrations/20260911120100_accounts_journals.sql +211 -0
- package/dist/assets/migrations/20260911120200_contacts.sql +90 -0
- package/dist/assets/migrations/20260911120300_taxes.sql +146 -0
- package/dist/assets/migrations/20260911120400_entries.sql +338 -0
- package/dist/assets/migrations/20260911120500_documents.sql +279 -0
- package/dist/assets/migrations/20260911120600_payments_reconciliation.sql +251 -0
- package/dist/assets/migrations/20260911120700_bank.sql +178 -0
- package/dist/assets/migrations/20260911120800_analytics_attachments.sql +128 -0
- package/dist/assets/migrations/20260911120900_post_document.sql +279 -0
- package/dist/assets/migrations/20260911121000_reporting.sql +235 -0
- package/dist/assets/migrations/20260911121100_country_templates.sql +226 -0
- package/dist/assets/migrations/20260911121200_fec.sql +71 -0
- package/dist/assets/migrations/20260911130000_instance.sql +77 -0
- package/dist/assets/migrations/20260911130100_instance_members.sql +224 -0
- package/dist/assets/migrations/20260911140000_instance_admins.sql +112 -0
- package/dist/assets/migrations/20260911160000_tax_posting_templates_unique.sql +17 -0
- package/dist/assets/migrations/20260911170000_document_amount_paid.sql +82 -0
- package/dist/assets/migrations/20260911173000_post_payment.sql +122 -0
- package/dist/assets/migrations/20260911173100_sequence_counters_under_rls.sql +84 -0
- package/dist/assets/migrations/20260911183000_country_journal_defaults.sql +143 -0
- package/dist/assets/migrations/20260911193853_line_account_defaults.sql +274 -0
- package/dist/assets/migrations/20260911195054_products.sql +221 -0
- package/dist/assets/migrations/20260911210131_anon_surface.sql +85 -0
- package/dist/assets/migrations/20260912074712_country_packs.sql +318 -0
- package/dist/assets/migrations/20260912080311_report_code_and_region.sql +198 -0
- package/dist/assets/migrations/20260912081014_pack_certification_maintained.sql +31 -0
- package/dist/assets/migrations/20260912081015_pack_certification_backfill.sql +16 -0
- package/dist/assets/migrations/20260912090407_tax_report_boxes.sql +329 -0
- package/dist/assets/migrations/20260912091917_tax_on_base_value.sql +25 -0
- package/dist/assets/migrations/20260912091918_tax_engine_columns.sql +776 -0
- package/dist/assets/migrations/20260912094412_opening_and_closing.sql +759 -0
- package/dist/assets/migrations/20260912095825_charts_of_accounts.sql +326 -0
- package/dist/assets/migrations/20260912100412_financial_statements.sql +632 -0
- package/dist/assets/migrations/20260912104719_one_formula_evaluator.sql +209 -0
- package/dist/assets/migrations/20260912105720_entry_kind_appropriation.sql +26 -0
- package/dist/assets/migrations/20260912105721_appropriation_entry_kind.sql +444 -0
- package/dist/assets/migrations/20260912111751_document_rules.sql +274 -0
- package/dist/assets/migrations/20260912112132_cash_basis_vat_and_fx.sql +1189 -0
- package/dist/assets/migrations/20260913074512_modules.sql +493 -0
- package/dist/assets/migrations/20260913075903_asset_disposal_roles.sql +47 -0
- package/dist/assets/migrations/20260913083216_capabilities.sql +637 -0
- package/dist/assets/migrations/20260913083901_company_invitations.sql +262 -0
- package/dist/assets/migrations/20260913084402_user_preferences.sql +376 -0
- package/dist/assets/migrations/20260913084847_company_profile.sql +261 -0
- package/dist/assets/migrations/20260913085436_numbering_reads_the_pack.sql +235 -0
- package/dist/assets/migrations/20260913085932_api_keys.sql +303 -0
- package/dist/assets/migrations/20260913090216_fiscal_year_bounds.sql +159 -0
- package/dist/assets/migrations/20260913092527_entries_import.sql +219 -0
- package/dist/assets/migrations/20260913101536_null_safe_guards.sql +188 -0
- package/dist/assets/migrations/20260913102115_installer_is_named.sql +462 -0
- package/dist/assets/migrations/20260913102758_no_currency_default.sql +138 -0
- package/dist/assets/migrations/20260913103355_cash_basis_needs_a_box.sql +453 -0
- package/dist/assets/migrations/20260913104014_aged_balance_named_group.sql +79 -0
- package/dist/assets/migrations/20260913104232_foreign_key_indexes.sql +144 -0
- package/dist/assets/migrations/20260913105120_declared_no_reader.sql +41 -0
- package/dist/assets/migrations/20260913111407_pack_languages.sql +223 -0
- package/dist/assets/migrations/20260913112233_schema_comments_for_a_reader.sql +27 -0
- package/dist/assets/migrations/20260913114535_fec_opening_balances.sql +307 -0
- package/dist/assets/migrations/20260914103412_audit_log.sql +509 -0
- package/dist/assets/migrations/20260914111907_pack_upgrade.sql +428 -0
- package/dist/assets/migrations/20260914120500_rounding_reads_the_currency.sql +206 -0
- package/dist/assets/migrations/20260914121200_amounts_round_at_the_currency.sql +2403 -0
- package/dist/assets/migrations/20260914134325_schema_version_0_2_0.sql +36 -0
- package/dist/assets/migrations/20260914143915_accounts_in_use.sql +428 -0
- package/dist/assets/migrations/20260914144731_account_code_frozen.sql +99 -0
- package/dist/assets/migrations/20260914151207_schema_grants_its_own_rights.sql +284 -0
- package/dist/assets/migrations/20260914152840_pack_upgrade_records_its_own_line.sql +237 -0
- package/dist/assets/migrations/20260914163943_declaration_periodicity.sql +349 -0
- package/dist/assets/migrations/20260915094000_foreign_services_received.sql +37 -0
- package/dist/assets/migrations/20260915094500_mentions_read_a_foreign_service.sql +72 -0
- package/dist/assets/migrations/20260915153000_document_shares.sql +568 -0
- package/dist/assets/migrations/20260915160000_ec_sales_list.sql +181 -0
- package/dist/assets/migrations/20260915161842_pack_sources.sql +56 -0
- package/dist/assets/migrations/20260915170500_schema_version_0_3_0.sql +45 -0
- package/dist/assets/migrations/20260915174500_a_vat_category_is_a_code.sql +177 -0
- package/dist/assets/migrations/20260915180000_document_rule_references.sql +85 -0
- package/dist/assets/migrations/20260915181000_territories.sql +342 -0
- package/dist/assets/migrations/20260915181500_ec_sales_list_reads_the_territories.sql +222 -0
- package/dist/assets/migrations/20260915182000_intracom_triangular.sql +53 -0
- package/dist/assets/migrations/20260915182500_a_triangular_supply_says_reverse_charge.sql +99 -0
- package/dist/assets/migrations/20260915191200_a_document_knows_its_language.sql +633 -0
- package/dist/assets/migrations/20260915195000_a_price_that_holds_its_tax.sql +649 -0
- package/dist/assets/migrations/20260915200000_a_posting_names_its_boxes.sql +1004 -0
- package/dist/assets/migrations/20260916094500_a_company_files_more_than_one_declaration.sql +795 -0
- package/dist/assets/migrations/20260916103000_a_ledger_line_names_its_posting.sql +902 -0
- package/dist/assets/migrations/20260916123000_a_vocabulary_for_a_tax_that_is_not_a_vat.sql +144 -0
- package/dist/assets/migrations/20260916124000_a_box_can_be_a_rate_of_a_box.sql +525 -0
- package/dist/assets/migrations/20260916125000_a_tax_follows_the_territory.sql +1318 -0
- package/dist/assets/migrations/20260916126000_a_tax_point_and_its_exception.sql +1211 -0
- package/dist/assets/migrations/20260917090000_a_counterparty_that_learns.sql +561 -0
- package/dist/assets/migrations/20260917120000_what_the_money_pays.sql +545 -0
- package/dist/assets/migrations/20260917150000_a_filing_is_a_row.sql +488 -0
- package/dist/assets/migrations/20260917170000_when_it_is_due.sql +194 -0
- package/dist/assets/migrations/20260917180000_a_box_is_a_number_and_a_kind.sql +213 -0
- package/dist/assets/migrations/20260917190000_what_a_declaration_owes.sql +486 -0
- package/dist/assets/migrations/20260917200000_what_moved_after_it_went.sql +227 -0
- package/dist/assets/migrations/20260918090000_a_form_names_its_file.sql +27 -0
- package/dist/assets/migrations/20260918110000_a_deposit_and_what_came_back.sql +286 -0
- package/dist/assets/migrations/20260918113741_a_fourth_preset_is_named.sql +9 -0
- package/dist/assets/migrations/20260918113807_a_client_reads_and_hands_over.sql +96 -0
- package/dist/assets/migrations/20260918114322_two_definer_functions_check_their_caller.sql +75 -0
- package/dist/assets/migrations/20260918130000_every_company_somebody_keeps.sql +177 -0
- package/dist/assets/migrations/20260918140000_a_session_nobody_prepared.sql +40 -0
- package/dist/assets/migrations/20260918141107_a_line_keeps_the_tax_it_was_posted_with.sql +256 -0
- package/dist/assets/migrations/20260918141342_a_company_has_an_electronic_address.sql +66 -0
- package/dist/assets/migrations/20260918141605_an_invoice_reads_whole_from_the_views.sql +313 -0
- package/dist/assets/migrations/20260918141627_a_policy_asks_once.sql +132 -0
- package/dist/assets/migrations/20260918143352_a_suggestion_reads_the_words_once.sql +204 -0
- package/dist/assets/migrations/20260918143417_a_reference_of_the_caller_and_a_rehearsal.sql +115 -0
- package/dist/assets/migrations/20260918150712_a_company_leaves_with_its_books.sql +1119 -0
- package/dist/assets/migrations/20260918150931_a_statement_is_imported_once.sql +654 -0
- package/dist/assets/migrations/20260918161204_a_posted_document_does_not_move.sql +437 -0
- package/dist/assets/migrations/20260918161538_a_posted_entry_does_not_move.sql +252 -0
- package/dist/assets/migrations/20260918171946_an_entry_is_posted_by_post_entry.sql +289 -0
- package/dist/assets/migrations/20260918174312_schema_version_0_4_0.sql +53 -0
- package/dist/assets/modules/assets/module.json +13 -0
- package/dist/assets/modules/assets/supabase/migrations/20260913081447_assets.sql +1190 -0
- package/dist/assets/modules/assets/supabase/migrations/20260913104234_foreign_key_indexes.sql +47 -0
- package/dist/assets/modules/assets/supabase/migrations/20260913104500_assets_capabilities.sql +145 -0
- package/dist/assets/modules/assets/supabase/migrations/20260914122100_assets_round_at_the_currency.sql +564 -0
- package/dist/assets/modules/assets/supabase/migrations/20260914145012_assets_accounts_in_use.sql +37 -0
- package/dist/assets/modules/assets/supabase/migrations/20260914151530_assets_grants_its_own_rights.sql +63 -0
- package/dist/assets/modules/assets/supabase/migrations/20260918113912_assets_client_reads.sql +20 -0
- package/dist/assets/modules/assets/supabase/migrations/20260918150801_assets_leave_with_the_company.sql +41 -0
- package/dist/assets/modules/budgets/module.json +12 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260913083012_budgets.sql +210 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260913104233_foreign_key_indexes.sql +37 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260913104501_budgets_capabilities.sql +72 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260914122400_budgets_round_at_the_currency.sql +68 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260914145048_budgets_accounts_in_use.sql +30 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260914151812_budgets_grants_its_own_rights.sql +31 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260918113954_budgets_client_reads.sql +20 -0
- package/dist/assets/modules/budgets/supabase/migrations/20260918150823_budgets_leave_with_the_company.sql +37 -0
- package/dist/assets/modules/schema/module.1.json +69 -0
- package/dist/assets/seed/00_currencies.sql +15 -0
- package/dist/assets/seed/00_territories.sql +280 -0
- package/dist/assets/seed/05_framework_generic.sql +110 -0
- package/dist/assets/seed/10_pack_be.sql +1284 -0
- package/dist/assets/seed/11_pack_fr.sql +1112 -0
- package/dist/assets/seed/12_pack_lu.sql +2484 -0
- package/dist/assets/seed/13_pack_ee.sql +733 -0
- package/dist/assets/seed/14_pack_gb.sql +796 -0
- package/dist/assets/seed/15_pack_us.sql +751 -0
- package/dist/assets/seed/90_demo_company.sql +368 -0
- package/dist/assets/seed/modules/assets/10_pack_be.sql +58 -0
- package/dist/assets/seed/modules/assets/11_pack_fr.sql +57 -0
- package/dist/assets/seed/modules/assets/14_pack_gb.sql +58 -0
- package/dist/assets/seed/modules/assets/15_pack_us.sql +60 -0
- package/dist/auth.d.ts +59 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +134 -0
- package/dist/auth.js.map +1 -0
- package/dist/bin.d.ts +6 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +8 -0
- package/dist/bin.js.map +1 -0
- package/dist/books.d.ts +60 -0
- package/dist/books.d.ts.map +1 -0
- package/dist/books.js +168 -0
- package/dist/books.js.map +1 -0
- package/dist/bootstrap.d.ts +236 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +459 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/bundle.d.ts +27 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +47 -0
- package/dist/bundle.js.map +1 -0
- package/dist/checklist.d.ts +35 -0
- package/dist/checklist.d.ts.map +1 -0
- package/dist/checklist.js +64 -0
- package/dist/checklist.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +318 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/company.d.ts +59 -0
- package/dist/commands/company.d.ts.map +1 -0
- package/dist/commands/company.js +287 -0
- package/dist/commands/company.js.map +1 -0
- package/dist/commands/contact.d.ts +9 -0
- package/dist/commands/contact.d.ts.map +1 -0
- package/dist/commands/contact.js +82 -0
- package/dist/commands/contact.js.map +1 -0
- package/dist/commands/demo.d.ts +19 -0
- package/dist/commands/demo.d.ts.map +1 -0
- package/dist/commands/demo.js +72 -0
- package/dist/commands/demo.js.map +1 -0
- package/dist/commands/doctor.d.ts +12 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +68 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/document.d.ts +17 -0
- package/dist/commands/document.d.ts.map +1 -0
- package/dist/commands/document.js +217 -0
- package/dist/commands/document.js.map +1 -0
- package/dist/commands/init.d.ts +31 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +535 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +24 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +128 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/migrate.d.ts +30 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +115 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/module.d.ts +32 -0
- package/dist/commands/module.d.ts.map +1 -0
- package/dist/commands/module.js +285 -0
- package/dist/commands/module.js.map +1 -0
- package/dist/commands/pack.d.ts +22 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +481 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/payment.d.ts +15 -0
- package/dist/commands/payment.d.ts.map +1 -0
- package/dist/commands/payment.js +97 -0
- package/dist/commands/payment.js.map +1 -0
- package/dist/commands/register.d.ts +20 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +134 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +134 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/whoami.d.ts +21 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +133 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/company.d.ts +16 -0
- package/dist/company.d.ts.map +1 -0
- package/dist/company.js +26 -0
- package/dist/company.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +50 -0
- package/dist/config.js.map +1 -0
- package/dist/connection.d.ts +79 -0
- package/dist/connection.d.ts.map +1 -0
- package/dist/connection.js +116 -0
- package/dist/connection.js.map +1 -0
- package/dist/context.d.ts +47 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +93 -0
- package/dist/context.js.map +1 -0
- package/dist/doctor.d.ts +45 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +448 -0
- package/dist/doctor.js.map +1 -0
- package/dist/grants.d.ts +88 -0
- package/dist/grants.d.ts.map +1 -0
- package/dist/grants.js +174 -0
- package/dist/grants.js.map +1 -0
- package/dist/identity.d.ts +54 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +132 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +155 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +303 -0
- package/dist/inventory.js.map +1 -0
- package/dist/migrations.d.ts +76 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +226 -0
- package/dist/migrations.js.map +1 -0
- package/dist/module/read.d.ts +91 -0
- package/dist/module/read.d.ts.map +1 -0
- package/dist/module/read.js +172 -0
- package/dist/module/read.js.map +1 -0
- package/dist/output.d.ts +110 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +173 -0
- package/dist/output.js.map +1 -0
- package/dist/pack/certification.d.ts +27 -0
- package/dist/pack/certification.d.ts.map +1 -0
- package/dist/pack/certification.js +38 -0
- package/dist/pack/certification.js.map +1 -0
- package/dist/pack/compile.d.ts +75 -0
- package/dist/pack/compile.d.ts.map +1 -0
- package/dist/pack/compile.js +801 -0
- package/dist/pack/compile.js.map +1 -0
- package/dist/pack/filing.d.ts +48 -0
- package/dist/pack/filing.d.ts.map +1 -0
- package/dist/pack/filing.js +56 -0
- package/dist/pack/filing.js.map +1 -0
- package/dist/pack/read.d.ts +766 -0
- package/dist/pack/read.d.ts.map +1 -0
- package/dist/pack/read.js +2336 -0
- package/dist/pack/read.js.map +1 -0
- package/dist/pack/schema.d.ts +26 -0
- package/dist/pack/schema.d.ts.map +1 -0
- package/dist/pack/schema.js +181 -0
- package/dist/pack/schema.js.map +1 -0
- package/dist/pack/territories.d.ts +98 -0
- package/dist/pack/territories.d.ts.map +1 -0
- package/dist/pack/territories.js +0 -0
- package/dist/pack/territories.js.map +1 -0
- package/dist/pack/upgrade.d.ts +86 -0
- package/dist/pack/upgrade.d.ts.map +1 -0
- package/dist/pack/upgrade.js +76 -0
- package/dist/pack/upgrade.js.map +1 -0
- package/dist/pack/vat-codes.d.ts +273 -0
- package/dist/pack/vat-codes.d.ts.map +1 -0
- package/dist/pack/vat-codes.js +513 -0
- package/dist/pack/vat-codes.js.map +1 -0
- package/dist/profiles.d.ts +67 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +187 -0
- package/dist/profiles.js.map +1 -0
- package/dist/prompt.d.ts +40 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +120 -0
- package/dist/prompt.js.map +1 -0
- package/dist/registry.d.ts +84 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +104 -0
- package/dist/registry.js.map +1 -0
- package/dist/rest.d.ts +81 -0
- package/dist/rest.d.ts.map +1 -0
- package/dist/rest.js +245 -0
- package/dist/rest.js.map +1 -0
- package/dist/schema.d.ts +15 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +15 -0
- package/dist/schema.js.map +1 -0
- package/dist/seeds.d.ts +27 -0
- package/dist/seeds.d.ts.map +1 -0
- package/dist/seeds.js +47 -0
- package/dist/seeds.js.map +1 -0
- package/dist/session.d.ts +39 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +92 -0
- package/dist/session.js.map +1 -0
- package/dist/sql.d.ts +48 -0
- package/dist/sql.d.ts.map +1 -0
- package/dist/sql.js +112 -0
- package/dist/sql.js.map +1 -0
- package/dist/status.d.ts +94 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +120 -0
- package/dist/status.js.map +1 -0
- package/dist/ui.d.ts +55 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +114 -0
- package/dist/ui.js.map +1 -0
- package/package.json +29 -0
- package/schema/output.1.json +613 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a treatment obliges a tax to say on an invoice, and where.
|
|
3
|
+
*
|
|
4
|
+
* A tax carries three things that are three tellings of one fact: its
|
|
5
|
+
* `treatment`, which is Ekwo's own word for what the operation is; its
|
|
6
|
+
* `vat_category`, which is BT-118 and BT-151 of EN 16931, taken from the
|
|
7
|
+
* UNCL5305 subset the standard publishes; and its `exemption_code`, which is
|
|
8
|
+
* BT-121, taken from the VATEX list. Nothing until now compared them, so a
|
|
9
|
+
* pack could declare an export taxed at the standard rate, or an
|
|
10
|
+
* intra-Community supply with the reverse-charge reason code, and every test
|
|
11
|
+
* in the repository would pass — because neither column is read by the ledger
|
|
12
|
+
* or by the declaration. They are read by whoever renders the invoice, which
|
|
13
|
+
* is the one reader that is not in this repository.
|
|
14
|
+
*
|
|
15
|
+
* The tables below are transcribed, not decided. Three sources say all of it:
|
|
16
|
+
*
|
|
17
|
+
* - **UNCL5305 (UN/CEFACT D.16B, OpenPEPPOL subset)** for what each category
|
|
18
|
+
* code means. `K` is *VAT exempt for EEA intra-community supply of goods and
|
|
19
|
+
* services* — goods **and services**, which is what settles the question the
|
|
20
|
+
* Ekwo vocabulary asks twice; `AE` is *VAT reverse charge*; `G` is *free
|
|
21
|
+
* export item, VAT not charged*; `O` is *services outside scope of tax*.
|
|
22
|
+
* - **Technical guidance for tax codes in EN 16931, version 1** (European
|
|
23
|
+
* Commission, Technical Advisory Group on Electronic Invoicing, use cases
|
|
24
|
+
* dated 1 July 2024), whose six use cases give the pair to use for each
|
|
25
|
+
* case: exemption in general `E` + a VATEX code, intra-Community supply
|
|
26
|
+
* between Member States `K` + `VATEX-EU-IC`, reverse charge **within** a
|
|
27
|
+
* Member State `AE` + `VATEX-EU-AE`, and the case it calls export outside the
|
|
28
|
+
* Union `G` + `VATEX-EU-G` — which is the Union's border because the seller
|
|
29
|
+
* the guidance addresses is established in a Member State. What UNCL5305
|
|
30
|
+
* itself says of `G` is *free export item, VAT not charged*: the goods leave
|
|
31
|
+
* the territory of whoever levies the tax.
|
|
32
|
+
* - **The VATEX code list itself**, which carries the pairing as a remark on
|
|
33
|
+
* eight of its codes: `VATEX-EU-AE` *only use with category code AE*,
|
|
34
|
+
* `VATEX-EU-IC` with `K`, `VATEX-EU-G` with `G`, `VATEX-EU-O` with `O`, and
|
|
35
|
+
* `VATEX-EU-D`, `-F`, `-I`, `-J` with `E`.
|
|
36
|
+
*
|
|
37
|
+
* Four decisions were taken where the sources leave a choice, and all four are
|
|
38
|
+
* written up in `docs/packs.md`.
|
|
39
|
+
*
|
|
40
|
+
* **The table above is the Union's, and it applies where the Union's VAT
|
|
41
|
+
* does.** EN 16931 is a European standard and the VATEX list is published by
|
|
42
|
+
* the European Commission: its own codes name articles of Directive
|
|
43
|
+
* 2006/112/EC and its national codes belong to Member States that publish
|
|
44
|
+
* them. A pack for a country the common system does not reach may therefore
|
|
45
|
+
* carry no code from it — `VATEX-EU-G` on an export from a third country
|
|
46
|
+
* claims an article of the Directive that does not bind the seller — and what
|
|
47
|
+
* an exempt line states there is its own article, in `legal_reference`, with
|
|
48
|
+
* BT-121 left empty. The categories are unaffected: UNCL5305 is a UN/CEFACT
|
|
49
|
+
* list, `E`, `G`, `O` and `AE` keep their meanings, and a pack outside the
|
|
50
|
+
* Union goes on being held to them. The treatments of the common system
|
|
51
|
+
* itself — the five `intracom_*` values — are refused there outright, because
|
|
52
|
+
* an intra-Community supply is an operation of a system the country is not in.
|
|
53
|
+
* Whether it is in it is not a fact this file holds: it is a row of
|
|
54
|
+
* `territories`, read through `./territories.js`, on the day the pack's
|
|
55
|
+
* manifest says it speaks of.
|
|
56
|
+
*
|
|
57
|
+
* **A category is required where a category is read.** The rule above says
|
|
58
|
+
* what a category may be, and it holds everywhere. What does not is the
|
|
59
|
+
* obligation to name one: BT-151 is a term of an invoice governed by EN 16931,
|
|
60
|
+
* and the first pack of a country that levies no value added tax was asked for
|
|
61
|
+
* one on every tax that can reach a sale although no American invoice carries
|
|
62
|
+
* the field, no administration there publishes a category list, and nobody
|
|
63
|
+
* would have read the answer. So the requirement is asked where the invoice
|
|
64
|
+
* exists — inside the common system, or where the pack declares an e-invoicing
|
|
65
|
+
* profile, each of which carries BT-151 — and `readsCategories` is the
|
|
66
|
+
* caller's answer. Outside both, the column is free and everything it may say
|
|
67
|
+
* is unchanged: a value that contradicts the treatment is refused there
|
|
68
|
+
* exactly as it is here. This is the same border ST38-1 drew for the reason
|
|
69
|
+
* code, one field over: the Union's lists reach the packs the Union's law
|
|
70
|
+
* reaches.
|
|
71
|
+
*
|
|
72
|
+
* **A category is a term of the invoice, so on a purchase it is the
|
|
73
|
+
* supplier's.** An Ekwo purchase tax describes how the buyer books and
|
|
74
|
+
* declares somebody else's invoice; BT-151 on that invoice was chosen by the
|
|
75
|
+
* seller. An intra-Community acquisition is therefore `K`, because the
|
|
76
|
+
* supplier made an intra-Community supply and rule BR-IC-10 binds them to `K`
|
|
77
|
+
* and `VATEX-EU-IC` — not `AE`, which is the guidance's case for a reverse
|
|
78
|
+
* charge *within* one Member State. A pack that does not want to record the
|
|
79
|
+
* seller's category may leave it null on a purchase-only tax; a value that
|
|
80
|
+
* contradicts the treatment is refused either way.
|
|
81
|
+
*
|
|
82
|
+
* **Where no invoice governed by the standard exists, the category is
|
|
83
|
+
* absent.** An import of goods is assessed on a customs document, and a
|
|
84
|
+
* service received from a supplier the Union's rules do not reach comes on an
|
|
85
|
+
* invoice the Directive does not govern. There is no seller's category to
|
|
86
|
+
* record, so `import` and `foreign_services_received` carry none: `S` there
|
|
87
|
+
* would claim the supplier levied the standard rate, which is the one thing
|
|
88
|
+
* that certainly did not happen.
|
|
89
|
+
*
|
|
90
|
+
* **A triangular supply is `K`, not `AE`.** The guidance gives `AE` for a
|
|
91
|
+
* reverse charge *within* one Member State, where the supplier is established
|
|
92
|
+
* in the buyer's country and national law moves the liability. The middle
|
|
93
|
+
* supply of a triangular arrangement is the opposite shape: the goods leave
|
|
94
|
+
* the seller's State, article 141 of Directive 2006/112/EC relieves the seller
|
|
95
|
+
* of registering where they arrive, and article 197 puts the tax on a customer
|
|
96
|
+
* in a third State. What the line is, in the words of UNCL5305, is *VAT exempt
|
|
97
|
+
* for EEA intra-community supply of goods and services* — `K`, with
|
|
98
|
+
* `VATEX-EU-IC`, which the VATEX list reserves for it. That the *sentence* on
|
|
99
|
+
* that invoice is the reverse-charge one is a different question in a different
|
|
100
|
+
* vocabulary, and it is answered by `applies_when`.
|
|
101
|
+
*
|
|
102
|
+
* The rate is checked on the sale side only. On a sale the pack's `rate` is
|
|
103
|
+
* the BT-152 the seller prints, and the business rules of EN 16931 fix it per
|
|
104
|
+
* category — BR-S-05 wants a standard-rated line above zero, BR-Z-05,
|
|
105
|
+
* BR-E-05, BR-AE-05, BR-IC-05, BR-G-05 and BR-O-05 want zero everywhere else.
|
|
106
|
+
* On a purchase the rate is the one the buyer self-assesses at, which is
|
|
107
|
+
* 21 % on a line the supplier invoiced at zero, so the same rule applied there
|
|
108
|
+
* would refuse every reverse charge in every pack.
|
|
109
|
+
*
|
|
110
|
+
* What this does **not** do is hold a copy of the VATEX list. The list grows,
|
|
111
|
+
* two published renderings of it already disagree on which codes it holds, and
|
|
112
|
+
* a code this file has not heard of is not a contradiction — it is a code this
|
|
113
|
+
* file has not heard of. So an exemption code is checked for its shape, and
|
|
114
|
+
* for the pairings the list itself states.
|
|
115
|
+
*
|
|
116
|
+
* The same limit applies to the other end. No country outside the Union
|
|
117
|
+
* publishes a list of exemption reason codes today; one may, and PINT is where
|
|
118
|
+
* it would surface. So the field is provided for and the content is not: a pack
|
|
119
|
+
* outside the common system may carry a reason code that is not a VATEX one,
|
|
120
|
+
* on the condition that its register declares a published list — the entry of
|
|
121
|
+
* `certification.sources` that says so of itself, with `reason_codes`. What is
|
|
122
|
+
* checked is that a list is named, not that the code is in it, which is exactly
|
|
123
|
+
* what is checked of a VATEX code inside the Union.
|
|
124
|
+
*
|
|
125
|
+
* That flag is new and it closes a trap. `reasonList` used to be the title of
|
|
126
|
+
* the **first** entry whose `kind` was `standard`, and `standard` means "a
|
|
127
|
+
* technical norm or code list" — which the FASB Accounting Standards
|
|
128
|
+
* Codification and FRS 102 both are. Naming an accounting standard therefore
|
|
129
|
+
* authorised a reason code on any tax of the pack, silently, in declaration
|
|
130
|
+
* order. No pack ever carried one and nothing wrong was emitted; an entry now
|
|
131
|
+
* says which list it is, and `ekwo pack check` refuses a second one.
|
|
132
|
+
*/
|
|
133
|
+
/** A source, quoted in the refusal so a reader can go and check it. */
|
|
134
|
+
const UNCL5305 = 'UNCL5305, the VAT category codes of EN 16931 (UN/CEFACT D.16B)';
|
|
135
|
+
const GUIDANCE = 'Technical guidance for tax codes in EN 16931, version 1';
|
|
136
|
+
const VATEX_LIST = 'the VATEX code list of EN 16931';
|
|
137
|
+
/**
|
|
138
|
+
* Treatment to category, keyed by the values of the `tax_treatment` enum.
|
|
139
|
+
*
|
|
140
|
+
* A treatment missing from here is a gap the check cannot see, so
|
|
141
|
+
* `tests/vat_codes.test.ts` asks the database for the enum and refuses a
|
|
142
|
+
* value this table does not cover.
|
|
143
|
+
*/
|
|
144
|
+
export const TREATMENT_CODES = {
|
|
145
|
+
domestic: {
|
|
146
|
+
scopes: ['sale', 'purchase'],
|
|
147
|
+
categories: ['S', 'Z'],
|
|
148
|
+
because: `a taxed supply is S at a rate above zero and Z at a rate of zero (${UNCL5305})`,
|
|
149
|
+
},
|
|
150
|
+
domestic_reverse_charge: {
|
|
151
|
+
scopes: ['sale', 'purchase'],
|
|
152
|
+
categories: ['AE'],
|
|
153
|
+
because: `a reverse charge within one Member State is AE (${GUIDANCE}, use case 3)`,
|
|
154
|
+
},
|
|
155
|
+
self_assessed: {
|
|
156
|
+
scopes: ['purchase'],
|
|
157
|
+
categories: [],
|
|
158
|
+
because: "a buyer assessing a tax on themselves under the levying administration's own law holds no " +
|
|
159
|
+
'invoice EN 16931 governs — there may be no supplier that administration can reach at all — ' +
|
|
160
|
+
"so there is no category of a supplier's to record",
|
|
161
|
+
},
|
|
162
|
+
intracom_goods: {
|
|
163
|
+
commonSystem: true,
|
|
164
|
+
goods: true,
|
|
165
|
+
scopes: ['sale'],
|
|
166
|
+
categories: ['K'],
|
|
167
|
+
because: `an intra-Community supply is K (${GUIDANCE}, use case 2, and rule BR-IC-10)`,
|
|
168
|
+
},
|
|
169
|
+
intracom_services: {
|
|
170
|
+
commonSystem: true,
|
|
171
|
+
scopes: ['sale'],
|
|
172
|
+
categories: ['K'],
|
|
173
|
+
because: `K is VAT exempt for EEA intra-community supply of goods and services (${UNCL5305}); ` +
|
|
174
|
+
`AE is the case of a reverse charge within one Member State (${GUIDANCE}, use case 3)`,
|
|
175
|
+
},
|
|
176
|
+
intracom_triangular: {
|
|
177
|
+
commonSystem: true,
|
|
178
|
+
goods: true,
|
|
179
|
+
scopes: ['sale'],
|
|
180
|
+
categories: ['K'],
|
|
181
|
+
because: 'the middle supply of a triangular arrangement is an exempt supply of goods between two ' +
|
|
182
|
+
`Member States, which is what K names — VAT exempt for EEA intra-community supply (${UNCL5305}); ` +
|
|
183
|
+
`AE is reserved for a reverse charge within one Member State (${GUIDANCE}, use case 3), and this ` +
|
|
184
|
+
"one is not: the goods leave the seller's State and article 197 of Directive 2006/112/EC puts " +
|
|
185
|
+
'the tax on a customer in a third',
|
|
186
|
+
},
|
|
187
|
+
intracom_acquisition_goods: {
|
|
188
|
+
commonSystem: true,
|
|
189
|
+
goods: true,
|
|
190
|
+
scopes: ['purchase'],
|
|
191
|
+
categories: ['K'],
|
|
192
|
+
because: 'a category is a term of the invoice, and the supplier of an intra-Community acquisition ' +
|
|
193
|
+
`made an intra-Community supply, which is K (${GUIDANCE}, use case 2)`,
|
|
194
|
+
},
|
|
195
|
+
intracom_acquisition_services: {
|
|
196
|
+
commonSystem: true,
|
|
197
|
+
scopes: ['purchase'],
|
|
198
|
+
categories: ['K'],
|
|
199
|
+
because: 'a category is a term of the invoice, and a supplier established in another Member State ' +
|
|
200
|
+
`invoices a supply of services as K (${UNCL5305}, which names services)`,
|
|
201
|
+
},
|
|
202
|
+
foreign_services_received: {
|
|
203
|
+
scopes: ['purchase'],
|
|
204
|
+
categories: [],
|
|
205
|
+
because: 'the supplier is not established here and their invoice is not governed by EN 16931, ' +
|
|
206
|
+
'so there is no category of theirs to record',
|
|
207
|
+
},
|
|
208
|
+
export: {
|
|
209
|
+
scopes: ['sale'],
|
|
210
|
+
categories: ['G'],
|
|
211
|
+
because: `G is free export item, VAT not charged (${UNCL5305}) — goods leaving the territory of ` +
|
|
212
|
+
`whoever levies the tax, which for a seller in a Member State is the Union's border ` +
|
|
213
|
+
`(${GUIDANCE}, use case 4) and for a seller outside it is that country's own`,
|
|
214
|
+
},
|
|
215
|
+
import: {
|
|
216
|
+
scopes: ['purchase'],
|
|
217
|
+
categories: [],
|
|
218
|
+
because: 'import tax is assessed on a customs document and not on an invoice governed by EN 16931, ' +
|
|
219
|
+
'so there is no category of the supplier to record',
|
|
220
|
+
},
|
|
221
|
+
exempt: {
|
|
222
|
+
scopes: ['sale', 'purchase'],
|
|
223
|
+
categories: ['E'],
|
|
224
|
+
because: `an exemption is E with the article that grants it as the reason (${GUIDANCE}, use case 1)`,
|
|
225
|
+
},
|
|
226
|
+
not_subject: {
|
|
227
|
+
scopes: ['sale', 'purchase'],
|
|
228
|
+
categories: ['O'],
|
|
229
|
+
because: `something outside the scope of the tax is O (${UNCL5305})`,
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
/**
|
|
233
|
+
* Category to exemption reason and to rate.
|
|
234
|
+
*
|
|
235
|
+
* The four reserved codes are the pairings the VATEX list publishes as a
|
|
236
|
+
* remark on the code itself. `E` takes any other reason, because the whole
|
|
237
|
+
* point of the general case is that the seller picks the article.
|
|
238
|
+
*/
|
|
239
|
+
export const CATEGORY_CODES = {
|
|
240
|
+
S: { exemption: null, needsReason: false, rate: 'positive', rateRule: 'BR-S-05' },
|
|
241
|
+
Z: { exemption: null, needsReason: false, rate: 'zero', rateRule: 'BR-Z-05' },
|
|
242
|
+
E: { exemption: null, needsReason: true, rate: 'zero', rateRule: 'BR-E-05' },
|
|
243
|
+
AE: { exemption: 'VATEX-EU-AE', needsReason: true, rate: 'zero', rateRule: 'BR-AE-05' },
|
|
244
|
+
K: { exemption: 'VATEX-EU-IC', needsReason: true, rate: 'zero', rateRule: 'BR-IC-05' },
|
|
245
|
+
G: { exemption: 'VATEX-EU-G', needsReason: true, rate: 'zero', rateRule: 'BR-G-05' },
|
|
246
|
+
O: { exemption: 'VATEX-EU-O', needsReason: true, rate: 'zero', rateRule: 'BR-O-05' },
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* A reason code of the VATEX list: the Union's own codes, and the national
|
|
250
|
+
* ones a Member State publishes beside them.
|
|
251
|
+
*
|
|
252
|
+
* The shape, and not the membership. A national list grows without this
|
|
253
|
+
* repository hearing of it, and the core has no business holding one country's
|
|
254
|
+
* codes anyway.
|
|
255
|
+
*/
|
|
256
|
+
const EXEMPTION_SHAPE = /^VATEX-(?:EU|[A-Z]{2})-[0-9A-Z][0-9A-Z-]*$/;
|
|
257
|
+
/**
|
|
258
|
+
* Anything that looks like a code rather than a sentence.
|
|
259
|
+
*
|
|
260
|
+
* All that can be said about a reason code from a list nobody has published
|
|
261
|
+
* yet. It keeps `legal_reference` and `exemption_code` from being written into
|
|
262
|
+
* each other, which is the mistake this column actually attracts.
|
|
263
|
+
*/
|
|
264
|
+
const CODE_SHAPE = /^[0-9A-Z][0-9A-Z._/-]*$/;
|
|
265
|
+
/** The categories another category's reserved code may not be borrowed by. */
|
|
266
|
+
const RESERVED = new Map(Object.entries(CATEGORY_CODES)
|
|
267
|
+
.filter(([, codes]) => codes.exemption !== null)
|
|
268
|
+
.map(([category, codes]) => [codes.exemption, category]));
|
|
269
|
+
/**
|
|
270
|
+
* The regime every pack was held to until a country outside the Union arrived.
|
|
271
|
+
*
|
|
272
|
+
* The default of `taxCodes`, so that a caller with no opinion gets the table as
|
|
273
|
+
* the European Commission publishes it. `readPack` always has an opinion.
|
|
274
|
+
*/
|
|
275
|
+
export const COMMON_SYSTEM = {
|
|
276
|
+
commonSystem: true,
|
|
277
|
+
because: 'the common system of VAT applies here',
|
|
278
|
+
readsCategories: true,
|
|
279
|
+
reasonList: null,
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* Whether a tax of this scope can end up on an invoice the company issues.
|
|
283
|
+
*
|
|
284
|
+
* `both` counts: a tax offered on both sides will be put on a sale one day,
|
|
285
|
+
* and that is the day BT-151 has to be there and has to be right.
|
|
286
|
+
*/
|
|
287
|
+
function isSale(scope) {
|
|
288
|
+
return scope === 'sale' || scope === 'both';
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* What BT-121 may say on a tax of a country the common system does not reach.
|
|
292
|
+
*
|
|
293
|
+
* Three answers, and the first is the one every pack will use: nothing, with
|
|
294
|
+
* the article in `legal_reference`. The second is a VATEX code, which is
|
|
295
|
+
* refused by name — the list belongs to a system this country is not in. The
|
|
296
|
+
* third is a code from some other published list, which is provided for and
|
|
297
|
+
* has no content yet: it is accepted where the pack's register declares the
|
|
298
|
+
* list, and refused with the way to declare it where it does not.
|
|
299
|
+
*/
|
|
300
|
+
function reasonOutside(where, category, rules, tax, regime) {
|
|
301
|
+
const reason = tax.exemption_code;
|
|
302
|
+
if (reason === null) {
|
|
303
|
+
// The article is what the invoice states, so it has to be there.
|
|
304
|
+
const article = (tax.legal_reference ?? '').trim();
|
|
305
|
+
if (rules.needsReason && article === '') {
|
|
306
|
+
return [
|
|
307
|
+
{
|
|
308
|
+
path: where,
|
|
309
|
+
message: `vat_category ${category} names no exemption_code and no legal_reference; ` +
|
|
310
|
+
`${regime.because}, so ${VATEX_LIST} does not reach this tax and the article it is ` +
|
|
311
|
+
'exempt under is what the invoice has instead',
|
|
312
|
+
},
|
|
313
|
+
];
|
|
314
|
+
}
|
|
315
|
+
return [];
|
|
316
|
+
}
|
|
317
|
+
if (!rules.needsReason) {
|
|
318
|
+
return [
|
|
319
|
+
{
|
|
320
|
+
path: where,
|
|
321
|
+
message: `vat_category ${category} carries exemption_code ${reason}; a line that is taxed is ` +
|
|
322
|
+
'exempt under nothing',
|
|
323
|
+
},
|
|
324
|
+
];
|
|
325
|
+
}
|
|
326
|
+
if (reason.startsWith('VATEX-')) {
|
|
327
|
+
return [
|
|
328
|
+
{
|
|
329
|
+
path: where,
|
|
330
|
+
message: `exemption_code ${reason} is a code of ${VATEX_LIST}, whose codes name articles of ` +
|
|
331
|
+
'Directive 2006/112/EC and whose national codes are published by Member States; ' +
|
|
332
|
+
`${regime.because}. State the article in legal_reference and leave exemption_code null`,
|
|
333
|
+
},
|
|
334
|
+
];
|
|
335
|
+
}
|
|
336
|
+
if (regime.reasonList === null) {
|
|
337
|
+
return [
|
|
338
|
+
{
|
|
339
|
+
path: where,
|
|
340
|
+
message: `exemption_code ${reason} comes from no list this pack names; ${regime.because}, so ` +
|
|
341
|
+
'BT-121 has no code list here. Either state the article in legal_reference and leave ' +
|
|
342
|
+
'exemption_code null, or declare the list this code belongs to in ' +
|
|
343
|
+
'certification.sources, as a standard carrying reason_codes true',
|
|
344
|
+
},
|
|
345
|
+
];
|
|
346
|
+
}
|
|
347
|
+
if (!CODE_SHAPE.test(reason)) {
|
|
348
|
+
return [
|
|
349
|
+
{
|
|
350
|
+
path: where,
|
|
351
|
+
message: `exemption_code ${reason} is not a code; ${regime.reasonList} publishes codes, and the ` +
|
|
352
|
+
'article an exemption is granted by belongs in legal_reference',
|
|
353
|
+
},
|
|
354
|
+
];
|
|
355
|
+
}
|
|
356
|
+
return [];
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* The taxes of a pack, against the three code lists.
|
|
360
|
+
*
|
|
361
|
+
* Every refusal names the tax, the treatment, what the tax says, what the
|
|
362
|
+
* source says instead, and the source. A pack author who has never read
|
|
363
|
+
* EN 16931 should be able to fix the line from the message alone.
|
|
364
|
+
*
|
|
365
|
+
* `regime` says whether the Union's own lists reach this pack at all. It
|
|
366
|
+
* defaults to the case every pack was in before a third country arrived.
|
|
367
|
+
*/
|
|
368
|
+
export function taxCodes(taxes, regime = COMMON_SYSTEM) {
|
|
369
|
+
const issues = [];
|
|
370
|
+
const regimeOf = typeof regime === 'function' ? regime : () => regime;
|
|
371
|
+
for (const tax of taxes) {
|
|
372
|
+
const where = `taxes.json ${tax.code}`;
|
|
373
|
+
const expected = TREATMENT_CODES[tax.treatment];
|
|
374
|
+
if (expected === undefined)
|
|
375
|
+
continue; // the schema already refused the value
|
|
376
|
+
const regimeHere = regimeOf(tax);
|
|
377
|
+
// An operation of the common system, in a country the system does not
|
|
378
|
+
// reach. Before anything else: what the invoice says about a supply that
|
|
379
|
+
// cannot happen is not the interesting half of the mistake.
|
|
380
|
+
if (expected.commonSystem === true && !regimeHere.commonSystem) {
|
|
381
|
+
issues.push({
|
|
382
|
+
path: where,
|
|
383
|
+
message: `treatment ${tax.treatment} is an operation of the common system of VAT — a supply ` +
|
|
384
|
+
`between two Member States under Directive 2006/112/EC — and ${regimeHere.because}`,
|
|
385
|
+
});
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
// The side. A treatment that exists on one side only, declared on the
|
|
389
|
+
// other, is a pack saying two different things about one operation.
|
|
390
|
+
if (tax.scope !== 'both' && !expected.scopes.includes(tax.scope)) {
|
|
391
|
+
issues.push({
|
|
392
|
+
path: where,
|
|
393
|
+
message: `treatment ${tax.treatment} is a ${expected.scopes.join(' or ')} operation, ` +
|
|
394
|
+
`and this tax has scope ${tax.scope}`,
|
|
395
|
+
});
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
const category = tax.vat_category;
|
|
399
|
+
// No invoice under the standard means no category. Saying one is claiming
|
|
400
|
+
// something about a document nobody governed.
|
|
401
|
+
if (expected.categories.length === 0) {
|
|
402
|
+
if (category !== null) {
|
|
403
|
+
issues.push({
|
|
404
|
+
path: where,
|
|
405
|
+
message: `treatment ${tax.treatment} carries vat_category ${category}; it carries none, because ` +
|
|
406
|
+
`${expected.because}`,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
if (tax.exemption_code !== null) {
|
|
410
|
+
issues.push({
|
|
411
|
+
path: where,
|
|
412
|
+
message: `treatment ${tax.treatment} carries exemption_code ${tax.exemption_code}; it carries ` +
|
|
413
|
+
`none, because ${expected.because}`,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
if (category === null) {
|
|
419
|
+
// Required on anything that can reach an invoice this company issues —
|
|
420
|
+
// and only where such an invoice carries BT-151 at all. Optional on a
|
|
421
|
+
// purchase-only tax, where it is the seller's answer and the pack may
|
|
422
|
+
// simply not record it, and optional everywhere in a country whose
|
|
423
|
+
// sellers issue no invoice the standard governs.
|
|
424
|
+
if (isSale(tax.scope) && regimeHere.readsCategories) {
|
|
425
|
+
issues.push({
|
|
426
|
+
path: where,
|
|
427
|
+
message: `treatment ${tax.treatment} names no vat_category; an invoice carries BT-151, and ` +
|
|
428
|
+
`${expected.because}`,
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
if (tax.exemption_code !== null) {
|
|
432
|
+
issues.push({
|
|
433
|
+
path: where,
|
|
434
|
+
message: `exemption_code ${tax.exemption_code} with no vat_category to belong to`,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
if (!expected.categories.includes(category)) {
|
|
440
|
+
issues.push({
|
|
441
|
+
path: where,
|
|
442
|
+
message: `treatment ${tax.treatment} carries vat_category ${category}; expected ` +
|
|
443
|
+
`${expected.categories.join(' or ')}, because ${expected.because}`,
|
|
444
|
+
});
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
const rules = CATEGORY_CODES[category];
|
|
448
|
+
if (rules === undefined)
|
|
449
|
+
continue;
|
|
450
|
+
// The reason code, its shape, and the pairing the VATEX list publishes —
|
|
451
|
+
// where that list is the one this country's invoices are written against.
|
|
452
|
+
const reason = tax.exemption_code;
|
|
453
|
+
if (!regimeHere.commonSystem) {
|
|
454
|
+
issues.push(...reasonOutside(where, category, rules, tax, regimeHere));
|
|
455
|
+
}
|
|
456
|
+
else if (reason === null) {
|
|
457
|
+
if (rules.needsReason) {
|
|
458
|
+
issues.push({
|
|
459
|
+
path: where,
|
|
460
|
+
message: `vat_category ${category} names no exemption_code; ` +
|
|
461
|
+
(rules.exemption === null
|
|
462
|
+
? `an exempt line states the article it is exempt under (${GUIDANCE}, use case 1)`
|
|
463
|
+
: `${VATEX_LIST} reserves ${rules.exemption} for category ${category}`),
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
else if (!rules.needsReason) {
|
|
468
|
+
issues.push({
|
|
469
|
+
path: where,
|
|
470
|
+
message: `vat_category ${category} carries exemption_code ${reason}; a line that is taxed is ` +
|
|
471
|
+
'exempt under nothing',
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
else if (!EXEMPTION_SHAPE.test(reason)) {
|
|
475
|
+
issues.push({
|
|
476
|
+
path: where,
|
|
477
|
+
message: `exemption_code ${reason} is not a VATEX code; ${VATEX_LIST} writes them ` +
|
|
478
|
+
'VATEX-EU-<article> and VATEX-<country>-<article>',
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
else if (rules.exemption !== null && reason !== rules.exemption) {
|
|
482
|
+
issues.push({
|
|
483
|
+
path: where,
|
|
484
|
+
message: `vat_category ${category} carries exemption_code ${reason}; ${VATEX_LIST} reserves ` +
|
|
485
|
+
`${rules.exemption} for it`,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
else if (rules.exemption === null && RESERVED.has(reason)) {
|
|
489
|
+
issues.push({
|
|
490
|
+
path: where,
|
|
491
|
+
message: `exemption_code ${reason} on category ${category}; ${VATEX_LIST} says to use it only ` +
|
|
492
|
+
`with category ${RESERVED.get(reason)}`,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
// The rate, where the pack's rate is the one the seller prints.
|
|
496
|
+
if (isSale(tax.scope) && tax.amount_type === 'percent') {
|
|
497
|
+
if (rules.rate === 'positive' && !(tax.rate > 0)) {
|
|
498
|
+
issues.push({
|
|
499
|
+
path: where,
|
|
500
|
+
message: `vat_category ${category} at a rate of ${tax.rate}; ${rules.rateRule} wants a rate above zero`,
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
if (rules.rate === 'zero' && tax.rate !== 0) {
|
|
504
|
+
issues.push({
|
|
505
|
+
path: where,
|
|
506
|
+
message: `vat_category ${category} at a rate of ${tax.rate}; ${rules.rateRule} wants a rate of zero`,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return issues;
|
|
512
|
+
}
|
|
513
|
+
//# sourceMappingURL=vat-codes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vat-codes.js","sourceRoot":"","sources":["../../src/pack/vat-codes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profiles: which instance, as whom, for which company — kept between commands.
|
|
3
|
+
*
|
|
4
|
+
* `ekwo.json` is the file of an installation and it is safe to commit, which
|
|
5
|
+
* is why it may never hold a token. What is kept here is the file of a
|
|
6
|
+
* person: it lives in their own configuration directory, outside any
|
|
7
|
+
* repository, and the CLI refuses to write it anywhere else.
|
|
8
|
+
*
|
|
9
|
+
* Two files, because they are not the same kind of thing. `profiles.json`
|
|
10
|
+
* says where each profile points — the instance URL, its publishable key, the
|
|
11
|
+
* address that signed in, the company in use — and holds nothing a dashboard
|
|
12
|
+
* does not already show. `credentials.json` holds the session: an access
|
|
13
|
+
* token that lasts an hour and the refresh token that renews it. Both are
|
|
14
|
+
* written `0600` in a `0700` directory. The password is never written at all:
|
|
15
|
+
* it is sent once, to the instance, and forgotten.
|
|
16
|
+
*
|
|
17
|
+
* The environment is not read here. A CI job sets its variables and never
|
|
18
|
+
* touches this directory; see `identity.ts` for the order.
|
|
19
|
+
*/
|
|
20
|
+
export declare const ENV_CONFIG_DIR = "EKWO_CONFIG_DIR";
|
|
21
|
+
export declare const ENV_PROFILE = "EKWO_PROFILE";
|
|
22
|
+
/** The name a first `ekwo login` gives its profile when none is asked for. */
|
|
23
|
+
export declare const FIRST_PROFILE = "default";
|
|
24
|
+
export interface CompanyRef {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
}
|
|
28
|
+
export interface Profile {
|
|
29
|
+
supabase_url: string;
|
|
30
|
+
anon_key: string;
|
|
31
|
+
email?: string;
|
|
32
|
+
user_id?: string;
|
|
33
|
+
/** The company commands run on, until `ekwo use` names another. */
|
|
34
|
+
company?: CompanyRef;
|
|
35
|
+
}
|
|
36
|
+
export interface ProfilesFile {
|
|
37
|
+
/** The profile a command uses when neither `--profile` nor `EKWO_PROFILE` names one. */
|
|
38
|
+
current?: string;
|
|
39
|
+
profiles: Record<string, Profile>;
|
|
40
|
+
}
|
|
41
|
+
export interface StoredSession {
|
|
42
|
+
access_token: string;
|
|
43
|
+
refresh_token: string;
|
|
44
|
+
/** Seconds since the epoch, as the instance gave it. */
|
|
45
|
+
expires_at: number;
|
|
46
|
+
}
|
|
47
|
+
/** `EKWO_CONFIG_DIR`, else `$XDG_CONFIG_HOME/ekwo`, else `~/.config/ekwo`. */
|
|
48
|
+
export declare function configDir(env?: NodeJS.ProcessEnv): string;
|
|
49
|
+
export declare function assertProfileName(name: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Refuses a directory that sits inside a repository.
|
|
52
|
+
*
|
|
53
|
+
* A token in a working tree is one `git add .` away from being published,
|
|
54
|
+
* and nothing about a file called `credentials.json` would stop it. The check
|
|
55
|
+
* is the plain one — a `.git` in the directory or above it — and the way out
|
|
56
|
+
* is named in the refusal.
|
|
57
|
+
*/
|
|
58
|
+
export declare function assertOutsideRepository(dir: string): void;
|
|
59
|
+
export declare function readProfiles(dir: string): Promise<ProfilesFile>;
|
|
60
|
+
export declare function writeProfiles(dir: string, file: ProfilesFile): Promise<void>;
|
|
61
|
+
export declare function readSession(dir: string, profile: string): Promise<StoredSession | undefined>;
|
|
62
|
+
export declare function writeSession(dir: string, profile: string, session: StoredSession): Promise<void>;
|
|
63
|
+
/** True when there was a session to forget. */
|
|
64
|
+
export declare function forgetSession(dir: string, profile: string): Promise<boolean>;
|
|
65
|
+
/** True when somebody other than the owner can read the session file. */
|
|
66
|
+
export declare function credentialsAreExposed(dir: string): Promise<boolean>;
|
|
67
|
+
//# sourceMappingURL=profiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAChD,eAAO,MAAM,WAAW,iBAAiB,CAAC;AAE1C,8EAA8E;AAC9E,eAAO,MAAM,aAAa,YAAY,CAAC;AAKvC,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAMtE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOtD;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAYzD;AAgDD,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAYrE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAOlF;AA0BD,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAElG;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAItG;AAED,+CAA+C;AAC/C,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMlF;AAED,yEAAyE;AACzE,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQzE"}
|