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,235 @@
|
|
|
1
|
+
-- Ekwo OS — the reports the schema exists for.
|
|
2
|
+
--
|
|
3
|
+
-- Every one of them filters posted entries in the WHERE clause, never in a
|
|
4
|
+
-- LEFT JOIN condition: a draft line that survives an outer join is how a
|
|
5
|
+
-- trial balance silently stops tying out.
|
|
6
|
+
|
|
7
|
+
-- ---------------------------------------------------------------------------
|
|
8
|
+
-- trial_balance
|
|
9
|
+
-- ---------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
create or replace function trial_balance(
|
|
12
|
+
p_company_id uuid,
|
|
13
|
+
p_from date,
|
|
14
|
+
p_to date
|
|
15
|
+
)
|
|
16
|
+
returns table (
|
|
17
|
+
account_id uuid,
|
|
18
|
+
account_code text,
|
|
19
|
+
account_name text,
|
|
20
|
+
account_type account_type,
|
|
21
|
+
internal_group text,
|
|
22
|
+
opening_balance numeric,
|
|
23
|
+
debit numeric,
|
|
24
|
+
credit numeric,
|
|
25
|
+
closing_balance numeric
|
|
26
|
+
)
|
|
27
|
+
language sql
|
|
28
|
+
stable
|
|
29
|
+
as $$
|
|
30
|
+
select a.id,
|
|
31
|
+
a.code,
|
|
32
|
+
a.name,
|
|
33
|
+
a.account_type,
|
|
34
|
+
a.internal_group,
|
|
35
|
+
coalesce(sum(l.balance) filter (where e.entry_date < p_from), 0)::numeric as opening_balance,
|
|
36
|
+
coalesce(sum(l.debit) filter (where e.entry_date between p_from and p_to), 0)::numeric as debit,
|
|
37
|
+
coalesce(sum(l.credit) filter (where e.entry_date between p_from and p_to), 0)::numeric as credit,
|
|
38
|
+
coalesce(sum(l.balance) filter (where e.entry_date <= p_to), 0)::numeric as closing_balance
|
|
39
|
+
from accounts a
|
|
40
|
+
left join entry_lines l on l.account_id = a.id
|
|
41
|
+
left join entries e on e.id = l.entry_id and e.state = 'posted'
|
|
42
|
+
where a.company_id = p_company_id
|
|
43
|
+
-- Kill the outer-join leak: a line whose entry is not posted is dropped.
|
|
44
|
+
and (l.id is null or e.id is not null)
|
|
45
|
+
and (e.id is null or e.entry_date <= p_to)
|
|
46
|
+
group by a.id, a.code, a.name, a.account_type, a.internal_group
|
|
47
|
+
order by a.code;
|
|
48
|
+
$$;
|
|
49
|
+
|
|
50
|
+
comment on function trial_balance(uuid, date, date) is
|
|
51
|
+
'Opening balance, movements of the period and closing balance per account, posted entries only.';
|
|
52
|
+
|
|
53
|
+
-- ---------------------------------------------------------------------------
|
|
54
|
+
-- general_ledger
|
|
55
|
+
-- ---------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
create or replace function general_ledger(
|
|
58
|
+
p_company_id uuid,
|
|
59
|
+
p_from date,
|
|
60
|
+
p_to date,
|
|
61
|
+
p_account_ids uuid[] default null
|
|
62
|
+
)
|
|
63
|
+
returns table (
|
|
64
|
+
account_id uuid,
|
|
65
|
+
account_code text,
|
|
66
|
+
account_name text,
|
|
67
|
+
entry_line_id uuid,
|
|
68
|
+
entry_id uuid,
|
|
69
|
+
entry_number text,
|
|
70
|
+
entry_date date,
|
|
71
|
+
journal_code text,
|
|
72
|
+
reference text,
|
|
73
|
+
line_name text,
|
|
74
|
+
contact_name text,
|
|
75
|
+
debit numeric,
|
|
76
|
+
credit numeric,
|
|
77
|
+
matching_number text,
|
|
78
|
+
running_balance numeric
|
|
79
|
+
)
|
|
80
|
+
language sql
|
|
81
|
+
stable
|
|
82
|
+
as $$
|
|
83
|
+
with opening as (
|
|
84
|
+
select l.account_id, sum(l.balance) as balance
|
|
85
|
+
from entry_lines l
|
|
86
|
+
join entries e on e.id = l.entry_id
|
|
87
|
+
where l.company_id = p_company_id
|
|
88
|
+
and e.state = 'posted'
|
|
89
|
+
and e.entry_date < p_from
|
|
90
|
+
group by l.account_id
|
|
91
|
+
),
|
|
92
|
+
movements as (
|
|
93
|
+
select l.id, l.account_id, l.entry_id, e.number, e.entry_date, j.code as journal_code,
|
|
94
|
+
e.reference, l.name, c.name as contact_name, l.debit, l.credit, l.balance,
|
|
95
|
+
l.matching_number, l.sequence
|
|
96
|
+
from entry_lines l
|
|
97
|
+
join entries e on e.id = l.entry_id
|
|
98
|
+
join journals j on j.id = e.journal_id
|
|
99
|
+
left join contacts c on c.id = l.contact_id
|
|
100
|
+
where l.company_id = p_company_id
|
|
101
|
+
and e.state = 'posted'
|
|
102
|
+
and e.entry_date between p_from and p_to
|
|
103
|
+
)
|
|
104
|
+
select a.id, a.code, a.name,
|
|
105
|
+
m.id, m.entry_id, m.number, m.entry_date, m.journal_code, m.reference,
|
|
106
|
+
m.name, m.contact_name, m.debit, m.credit, m.matching_number,
|
|
107
|
+
(coalesce(o.balance, 0)
|
|
108
|
+
+ sum(m.balance) over (partition by a.id
|
|
109
|
+
order by m.entry_date, m.number, m.sequence, m.id
|
|
110
|
+
rows between unbounded preceding and current row))::numeric
|
|
111
|
+
from movements m
|
|
112
|
+
join accounts a on a.id = m.account_id
|
|
113
|
+
left join opening o on o.account_id = a.id
|
|
114
|
+
where p_account_ids is null or a.id = any (p_account_ids)
|
|
115
|
+
order by a.code, m.entry_date, m.number, m.sequence, m.id;
|
|
116
|
+
$$;
|
|
117
|
+
|
|
118
|
+
comment on function general_ledger(uuid, date, date, uuid[]) is
|
|
119
|
+
'Posted lines of a period per account, with the balance carried forward from before the period.';
|
|
120
|
+
|
|
121
|
+
-- ---------------------------------------------------------------------------
|
|
122
|
+
-- aged_balance
|
|
123
|
+
--
|
|
124
|
+
-- Read from the ledger and from what is still unmatched, not from documents.
|
|
125
|
+
-- An aged balance built on invoices can never tie back to the balance sheet.
|
|
126
|
+
-- ---------------------------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
create or replace function aged_balance(
|
|
129
|
+
p_company_id uuid,
|
|
130
|
+
p_at date default current_date,
|
|
131
|
+
p_group text default 'receivable'
|
|
132
|
+
)
|
|
133
|
+
returns table (
|
|
134
|
+
contact_id uuid,
|
|
135
|
+
contact_name text,
|
|
136
|
+
account_id uuid,
|
|
137
|
+
account_code text,
|
|
138
|
+
not_due numeric,
|
|
139
|
+
days_1_30 numeric,
|
|
140
|
+
days_31_60 numeric,
|
|
141
|
+
days_61_90 numeric,
|
|
142
|
+
days_over_90 numeric,
|
|
143
|
+
total numeric
|
|
144
|
+
)
|
|
145
|
+
language sql
|
|
146
|
+
stable
|
|
147
|
+
as $$
|
|
148
|
+
with open_lines as (
|
|
149
|
+
select l.contact_id,
|
|
150
|
+
l.account_id,
|
|
151
|
+
case when p_group = 'payable' then -l.balance else l.balance end
|
|
152
|
+
* (case when abs(l.balance) = 0 then 0
|
|
153
|
+
else (abs(l.balance) - l.matched_amount) / abs(l.balance) end) as residual,
|
|
154
|
+
coalesce(l.date_maturity, e.entry_date) as due_date
|
|
155
|
+
from entry_lines l
|
|
156
|
+
join entries e on e.id = l.entry_id
|
|
157
|
+
join accounts a on a.id = l.account_id
|
|
158
|
+
where l.company_id = p_company_id
|
|
159
|
+
and e.state = 'posted'
|
|
160
|
+
and e.entry_date <= p_at
|
|
161
|
+
and a.reconcilable
|
|
162
|
+
and a.account_type = case when p_group = 'payable'
|
|
163
|
+
then 'liability_payable'::account_type
|
|
164
|
+
else 'asset_receivable'::account_type end
|
|
165
|
+
and abs(l.balance) - l.matched_amount > 0.005
|
|
166
|
+
)
|
|
167
|
+
select o.contact_id,
|
|
168
|
+
c.name,
|
|
169
|
+
o.account_id,
|
|
170
|
+
a.code,
|
|
171
|
+
round(sum(o.residual) filter (where o.due_date >= p_at), 2),
|
|
172
|
+
round(sum(o.residual) filter (where p_at - o.due_date between 1 and 30), 2),
|
|
173
|
+
round(sum(o.residual) filter (where p_at - o.due_date between 31 and 60), 2),
|
|
174
|
+
round(sum(o.residual) filter (where p_at - o.due_date between 61 and 90), 2),
|
|
175
|
+
round(sum(o.residual) filter (where p_at - o.due_date > 90), 2),
|
|
176
|
+
round(sum(o.residual), 2)
|
|
177
|
+
from open_lines o
|
|
178
|
+
left join contacts c on c.id = o.contact_id
|
|
179
|
+
join accounts a on a.id = o.account_id
|
|
180
|
+
group by o.contact_id, c.name, o.account_id, a.code
|
|
181
|
+
order by c.name nulls last;
|
|
182
|
+
$$;
|
|
183
|
+
|
|
184
|
+
comment on function aged_balance(uuid, date, text) is
|
|
185
|
+
'Open receivables (or payables) by age, from unmatched ledger lines. p_group is ''receivable'' or ''payable''.';
|
|
186
|
+
|
|
187
|
+
-- ---------------------------------------------------------------------------
|
|
188
|
+
-- vat_return
|
|
189
|
+
--
|
|
190
|
+
-- Aggregates whatever the tax postings wrote on the lines. No country rule
|
|
191
|
+
-- lives here: boxes come from the data.
|
|
192
|
+
--
|
|
193
|
+
-- This function was published with the two balance boxes of the Belgian frame
|
|
194
|
+
-- VI computed inline, behind a test on the company's fiscal country. That was
|
|
195
|
+
-- the one country rule left in the core, and it was removed from this file on
|
|
196
|
+
-- 12 September 2026 rather than only overridden later: no installation
|
|
197
|
+
-- anywhere had run it, and a country literal in a published migration is a
|
|
198
|
+
-- country literal in the repository. The totals now come from the declaration
|
|
199
|
+
-- form of the country pack, in `20260912090407_tax_report_boxes`, which
|
|
200
|
+
-- replaces this function.
|
|
201
|
+
-- ---------------------------------------------------------------------------
|
|
202
|
+
|
|
203
|
+
create or replace function vat_return(
|
|
204
|
+
p_company_id uuid,
|
|
205
|
+
p_from date,
|
|
206
|
+
p_to date
|
|
207
|
+
)
|
|
208
|
+
returns table (
|
|
209
|
+
box text,
|
|
210
|
+
kind text,
|
|
211
|
+
amount numeric,
|
|
212
|
+
computed boolean
|
|
213
|
+
)
|
|
214
|
+
language sql
|
|
215
|
+
stable
|
|
216
|
+
as $$
|
|
217
|
+
with boxes as (
|
|
218
|
+
select l.declaration_box as box,
|
|
219
|
+
case when l.tax_line then 'tax' else 'base' end as kind,
|
|
220
|
+
round(sum(l.box_amount), 2) as amount
|
|
221
|
+
from entry_lines l
|
|
222
|
+
join entries e on e.id = l.entry_id
|
|
223
|
+
where l.company_id = p_company_id
|
|
224
|
+
and e.state = 'posted'
|
|
225
|
+
and e.entry_date between p_from and p_to
|
|
226
|
+
and l.declaration_box is not null
|
|
227
|
+
group by 1, 2
|
|
228
|
+
having round(sum(l.box_amount), 2) <> 0
|
|
229
|
+
)
|
|
230
|
+
select b.box, b.kind, b.amount, false from boxes b
|
|
231
|
+
order by 1, 2;
|
|
232
|
+
$$;
|
|
233
|
+
|
|
234
|
+
comment on function vat_return(uuid, date, date) is
|
|
235
|
+
'VAT return boxes for a period, summed from the declaration boxes written on the ledger lines.';
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
-- Ekwo OS — country templates.
|
|
2
|
+
--
|
|
3
|
+
-- The chart of accounts, the journals and the taxes of a country are
|
|
4
|
+
-- reference data, not code. `install_country_template()` copies them into a
|
|
5
|
+
-- company. Seeds fill the templates; nothing here is country specific.
|
|
6
|
+
|
|
7
|
+
create table account_templates (
|
|
8
|
+
id uuid primary key default gen_random_uuid(),
|
|
9
|
+
country char(2) not null,
|
|
10
|
+
code text not null,
|
|
11
|
+
name text not null,
|
|
12
|
+
account_type account_type not null,
|
|
13
|
+
reconcilable boolean not null default false,
|
|
14
|
+
parent_code text,
|
|
15
|
+
sequence integer not null default 10,
|
|
16
|
+
unique (country, code),
|
|
17
|
+
constraint account_templates_country_format check (country ~ '^[A-Z]{2}$'),
|
|
18
|
+
constraint account_templates_third_party_reconcilable check (
|
|
19
|
+
account_type not in ('asset_receivable', 'liability_payable') or reconcilable
|
|
20
|
+
)
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
comment on table account_templates is 'Reference charts of accounts, one set per country.';
|
|
24
|
+
|
|
25
|
+
create table journal_templates (
|
|
26
|
+
id uuid primary key default gen_random_uuid(),
|
|
27
|
+
country char(2) not null,
|
|
28
|
+
code text not null,
|
|
29
|
+
name text not null,
|
|
30
|
+
journal_type journal_type not null,
|
|
31
|
+
sequence integer not null default 10,
|
|
32
|
+
unique (country, code)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
create table tax_templates (
|
|
36
|
+
id uuid primary key default gen_random_uuid(),
|
|
37
|
+
country char(2) not null,
|
|
38
|
+
code text not null,
|
|
39
|
+
name text not null,
|
|
40
|
+
description text,
|
|
41
|
+
amount_type tax_amount_type not null default 'percent',
|
|
42
|
+
amount numeric(12, 4) not null default 0,
|
|
43
|
+
applies_to tax_scope not null default 'both',
|
|
44
|
+
treatment tax_treatment not null default 'domestic',
|
|
45
|
+
valid_from date not null default date '1970-01-01',
|
|
46
|
+
valid_to date,
|
|
47
|
+
legal_reference text,
|
|
48
|
+
vat_category char(2),
|
|
49
|
+
exemption_code text,
|
|
50
|
+
sequence integer not null default 10,
|
|
51
|
+
unique (country, code)
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
comment on table tax_templates is 'Reference taxes per country, with their period of validity.';
|
|
55
|
+
|
|
56
|
+
create table tax_posting_templates (
|
|
57
|
+
id uuid primary key default gen_random_uuid(),
|
|
58
|
+
tax_template_id uuid not null references tax_templates(id) on delete cascade,
|
|
59
|
+
document_kind tax_document_kind not null default 'invoice',
|
|
60
|
+
posting_type tax_posting_type not null,
|
|
61
|
+
factor_percent numeric(7, 3) not null default 100,
|
|
62
|
+
account_code text,
|
|
63
|
+
declaration_box text,
|
|
64
|
+
box_factor_percent numeric(7, 3) not null default 100,
|
|
65
|
+
sequence integer not null default 10,
|
|
66
|
+
constraint tax_posting_templates_base_has_no_account check (
|
|
67
|
+
posting_type <> 'base' or account_code is null
|
|
68
|
+
),
|
|
69
|
+
constraint tax_posting_templates_tax_has_account check (
|
|
70
|
+
posting_type <> 'tax' or account_code is not null
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
create unique index tax_posting_templates_one_base_idx
|
|
75
|
+
on tax_posting_templates (tax_template_id, document_kind) where posting_type = 'base';
|
|
76
|
+
|
|
77
|
+
create table country_defaults (
|
|
78
|
+
country char(2) primary key,
|
|
79
|
+
name text not null,
|
|
80
|
+
currency_code char(3) not null default 'EUR',
|
|
81
|
+
receivable_code text not null,
|
|
82
|
+
payable_code text not null,
|
|
83
|
+
suspense_code text,
|
|
84
|
+
rounding_code text,
|
|
85
|
+
retained_earnings_code text,
|
|
86
|
+
sales_account_code text,
|
|
87
|
+
purchase_account_code text,
|
|
88
|
+
bank_account_code text,
|
|
89
|
+
sales_journal_code text not null default 'SAL',
|
|
90
|
+
purchase_journal_code text not null default 'PUR',
|
|
91
|
+
misc_journal_code text not null default 'MISC'
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
comment on table country_defaults is 'Which template account plays which role, per country.';
|
|
95
|
+
|
|
96
|
+
-- ---------------------------------------------------------------------------
|
|
97
|
+
-- Helpers
|
|
98
|
+
-- ---------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
create or replace function account_id_by_code(p_company_id uuid, p_code text)
|
|
101
|
+
returns uuid
|
|
102
|
+
language sql
|
|
103
|
+
stable
|
|
104
|
+
as $$
|
|
105
|
+
select id from accounts where company_id = p_company_id and code = p_code;
|
|
106
|
+
$$;
|
|
107
|
+
|
|
108
|
+
comment on function account_id_by_code(uuid, text) is 'Account of a company by its code, or NULL.';
|
|
109
|
+
|
|
110
|
+
-- ---------------------------------------------------------------------------
|
|
111
|
+
-- install_country_template
|
|
112
|
+
-- ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
create or replace function install_country_template(
|
|
115
|
+
p_company_id uuid,
|
|
116
|
+
p_country char(2)
|
|
117
|
+
)
|
|
118
|
+
returns void
|
|
119
|
+
language plpgsql
|
|
120
|
+
as $$
|
|
121
|
+
declare
|
|
122
|
+
v_defaults country_defaults%rowtype;
|
|
123
|
+
r record;
|
|
124
|
+
v_tax_id uuid;
|
|
125
|
+
begin
|
|
126
|
+
if not exists (select 1 from companies where id = p_company_id) then
|
|
127
|
+
raise exception 'unknown_company: %', p_company_id;
|
|
128
|
+
end if;
|
|
129
|
+
if not exists (select 1 from account_templates where country = p_country) then
|
|
130
|
+
raise exception 'unknown_country_template: no chart of accounts seeded for %', p_country;
|
|
131
|
+
end if;
|
|
132
|
+
|
|
133
|
+
-- 1. Accounts, without the hierarchy.
|
|
134
|
+
insert into accounts (company_id, code, name, account_type, reconcilable)
|
|
135
|
+
select p_company_id, t.code, t.name, t.account_type, t.reconcilable
|
|
136
|
+
from account_templates t
|
|
137
|
+
where t.country = p_country
|
|
138
|
+
on conflict (company_id, code) do nothing;
|
|
139
|
+
|
|
140
|
+
-- 2. Hierarchy, now that every code exists.
|
|
141
|
+
update accounts a
|
|
142
|
+
set parent_id = p.id
|
|
143
|
+
from account_templates t
|
|
144
|
+
join accounts p on p.company_id = p_company_id and p.code = t.parent_code
|
|
145
|
+
where a.company_id = p_company_id
|
|
146
|
+
and a.code = t.code
|
|
147
|
+
and t.country = p_country
|
|
148
|
+
and t.parent_code is not null
|
|
149
|
+
and a.parent_id is null;
|
|
150
|
+
|
|
151
|
+
-- 3. Journals.
|
|
152
|
+
insert into journals (company_id, code, name, journal_type)
|
|
153
|
+
select p_company_id, t.code, t.name, t.journal_type
|
|
154
|
+
from journal_templates t
|
|
155
|
+
where t.country = p_country
|
|
156
|
+
on conflict (company_id, code) do nothing;
|
|
157
|
+
|
|
158
|
+
-- 4. Taxes and their postings.
|
|
159
|
+
for r in
|
|
160
|
+
select * from tax_templates where country = p_country order by sequence, code
|
|
161
|
+
loop
|
|
162
|
+
v_tax_id := null;
|
|
163
|
+
insert into taxes (company_id, code, name, description, amount_type, amount,
|
|
164
|
+
applies_to, treatment, country, valid_from, valid_to,
|
|
165
|
+
legal_reference, vat_category, exemption_code, sequence)
|
|
166
|
+
values (p_company_id, r.code, r.name, r.description, r.amount_type, r.amount,
|
|
167
|
+
r.applies_to, r.treatment, p_country, r.valid_from, r.valid_to,
|
|
168
|
+
r.legal_reference, r.vat_category, r.exemption_code, r.sequence)
|
|
169
|
+
on conflict (company_id, code) do nothing
|
|
170
|
+
returning id into v_tax_id;
|
|
171
|
+
|
|
172
|
+
if v_tax_id is null then
|
|
173
|
+
continue;
|
|
174
|
+
end if;
|
|
175
|
+
|
|
176
|
+
insert into tax_postings (tax_id, company_id, document_kind, posting_type,
|
|
177
|
+
factor_percent, account_id, declaration_box,
|
|
178
|
+
box_factor_percent, sequence)
|
|
179
|
+
select v_tax_id, p_company_id, tp.document_kind, tp.posting_type,
|
|
180
|
+
tp.factor_percent, account_id_by_code(p_company_id, tp.account_code),
|
|
181
|
+
tp.declaration_box, tp.box_factor_percent, tp.sequence
|
|
182
|
+
from tax_posting_templates tp
|
|
183
|
+
where tp.tax_template_id = r.id
|
|
184
|
+
order by tp.sequence;
|
|
185
|
+
end loop;
|
|
186
|
+
|
|
187
|
+
-- 5. Roles.
|
|
188
|
+
select * into v_defaults from country_defaults where country = p_country;
|
|
189
|
+
if found then
|
|
190
|
+
update companies c
|
|
191
|
+
set receivable_account_id = coalesce(c.receivable_account_id, account_id_by_code(p_company_id, v_defaults.receivable_code)),
|
|
192
|
+
payable_account_id = coalesce(c.payable_account_id, account_id_by_code(p_company_id, v_defaults.payable_code)),
|
|
193
|
+
suspense_account_id = coalesce(c.suspense_account_id, account_id_by_code(p_company_id, v_defaults.suspense_code)),
|
|
194
|
+
rounding_account_id = coalesce(c.rounding_account_id, account_id_by_code(p_company_id, v_defaults.rounding_code)),
|
|
195
|
+
retained_earnings_account_id = coalesce(c.retained_earnings_account_id, account_id_by_code(p_company_id, v_defaults.retained_earnings_code)),
|
|
196
|
+
sales_journal_id = coalesce(c.sales_journal_id, (select id from journals where company_id = p_company_id and code = v_defaults.sales_journal_code)),
|
|
197
|
+
purchase_journal_id = coalesce(c.purchase_journal_id, (select id from journals where company_id = p_company_id and code = v_defaults.purchase_journal_code)),
|
|
198
|
+
miscellaneous_journal_id = coalesce(c.miscellaneous_journal_id, (select id from journals where company_id = p_company_id and code = v_defaults.misc_journal_code))
|
|
199
|
+
where c.id = p_company_id;
|
|
200
|
+
end if;
|
|
201
|
+
end;
|
|
202
|
+
$$;
|
|
203
|
+
|
|
204
|
+
comment on function install_country_template(uuid, char) is
|
|
205
|
+
'Copies a country chart of accounts, journals and taxes into a company and wires the default roles.';
|
|
206
|
+
|
|
207
|
+
-- ---------------------------------------------------------------------------
|
|
208
|
+
-- Row level security
|
|
209
|
+
-- ---------------------------------------------------------------------------
|
|
210
|
+
|
|
211
|
+
alter table account_templates enable row level security;
|
|
212
|
+
alter table journal_templates enable row level security;
|
|
213
|
+
alter table tax_templates enable row level security;
|
|
214
|
+
alter table tax_posting_templates enable row level security;
|
|
215
|
+
alter table country_defaults enable row level security;
|
|
216
|
+
|
|
217
|
+
create policy account_templates_select on account_templates
|
|
218
|
+
for select using (auth.uid() is not null);
|
|
219
|
+
create policy journal_templates_select on journal_templates
|
|
220
|
+
for select using (auth.uid() is not null);
|
|
221
|
+
create policy tax_templates_select on tax_templates
|
|
222
|
+
for select using (auth.uid() is not null);
|
|
223
|
+
create policy tax_posting_templates_select on tax_posting_templates
|
|
224
|
+
for select using (auth.uid() is not null);
|
|
225
|
+
create policy country_defaults_select on country_defaults
|
|
226
|
+
for select using (auth.uid() is not null);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
-- Ekwo OS — the French FEC, as a query.
|
|
2
|
+
--
|
|
3
|
+
-- Eighteen columns fixed by the arrete du 29 juillet 2013 (art. A. 47 A-1 du
|
|
4
|
+
-- LPF). The schema was shaped so this needs no application logic: the letter
|
|
5
|
+
-- comes from `reconciliations`, the sub-ledger code from
|
|
6
|
+
-- `contacts.auxiliary_code`, the validation date from `entries.posted_at`.
|
|
7
|
+
|
|
8
|
+
create or replace function fec_lines(
|
|
9
|
+
p_company_id uuid,
|
|
10
|
+
p_from date,
|
|
11
|
+
p_to date
|
|
12
|
+
)
|
|
13
|
+
returns table (
|
|
14
|
+
journal_code text,
|
|
15
|
+
journal_lib text,
|
|
16
|
+
ecriture_num text,
|
|
17
|
+
ecriture_date date,
|
|
18
|
+
compte_num text,
|
|
19
|
+
compte_lib text,
|
|
20
|
+
comp_aux_num text,
|
|
21
|
+
comp_aux_lib text,
|
|
22
|
+
piece_ref text,
|
|
23
|
+
piece_date date,
|
|
24
|
+
ecriture_lib text,
|
|
25
|
+
debit numeric,
|
|
26
|
+
credit numeric,
|
|
27
|
+
ecriture_let text,
|
|
28
|
+
date_let date,
|
|
29
|
+
valid_date date,
|
|
30
|
+
montant_devise numeric,
|
|
31
|
+
idevise text
|
|
32
|
+
)
|
|
33
|
+
language sql
|
|
34
|
+
stable
|
|
35
|
+
as $$
|
|
36
|
+
select j.code,
|
|
37
|
+
j.name,
|
|
38
|
+
e.number,
|
|
39
|
+
e.entry_date,
|
|
40
|
+
a.code,
|
|
41
|
+
a.name,
|
|
42
|
+
c.auxiliary_code,
|
|
43
|
+
case when c.auxiliary_code is not null then c.name end,
|
|
44
|
+
coalesce(d.number, d.supplier_reference, e.reference, e.number),
|
|
45
|
+
coalesce(d.document_date, e.entry_date),
|
|
46
|
+
coalesce(nullif(l.name, ''), e.description, a.name),
|
|
47
|
+
l.debit,
|
|
48
|
+
l.credit,
|
|
49
|
+
l.matching_number,
|
|
50
|
+
(select max(r.matched_at) from reconciliations r
|
|
51
|
+
where r.debit_line_id = l.id or r.credit_line_id = l.id),
|
|
52
|
+
coalesce(e.posted_at::date, e.entry_date),
|
|
53
|
+
case when l.currency_code is not null and l.currency_code <> co.currency_code
|
|
54
|
+
then l.amount_currency end,
|
|
55
|
+
case when l.currency_code is not null and l.currency_code <> co.currency_code
|
|
56
|
+
then l.currency_code end
|
|
57
|
+
from entry_lines l
|
|
58
|
+
join entries e on e.id = l.entry_id
|
|
59
|
+
join journals j on j.id = e.journal_id
|
|
60
|
+
join accounts a on a.id = l.account_id
|
|
61
|
+
join companies co on co.id = l.company_id
|
|
62
|
+
left join contacts c on c.id = l.contact_id
|
|
63
|
+
left join documents d on d.id = e.document_id
|
|
64
|
+
where l.company_id = p_company_id
|
|
65
|
+
and e.state = 'posted'
|
|
66
|
+
and e.entry_date between p_from and p_to
|
|
67
|
+
order by e.entry_date, e.number, l.sequence, l.id;
|
|
68
|
+
$$;
|
|
69
|
+
|
|
70
|
+
comment on function fec_lines(uuid, date, date) is
|
|
71
|
+
'The eighteen columns of the French FEC for a period, in chronological order.';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
-- Ekwo OS — the instance itself.
|
|
2
|
+
--
|
|
3
|
+
-- One installation belongs to one customer, so the installation is a fact
|
|
4
|
+
-- worth recording: who it belongs to, which country's rules it was set up
|
|
5
|
+
-- for, which edition it runs, and which schema version it was installed at.
|
|
6
|
+
-- Exactly one row, forever. There is no `tenant_id` anywhere in this schema
|
|
7
|
+
-- and this table is the reason: the instance IS the tenant.
|
|
8
|
+
--
|
|
9
|
+
-- Registration with Ekwo is an opt-in. `contact_email` and `registered_at`
|
|
10
|
+
-- are empty on a fresh install, nothing writes them without the operator
|
|
11
|
+
-- asking, and nothing in the software checks them. Community works
|
|
12
|
+
-- unregistered, forever.
|
|
13
|
+
|
|
14
|
+
-- The instance-level role. A new enum value cannot be used in the same
|
|
15
|
+
-- transaction that adds it, so the table that constrains it lives in the
|
|
16
|
+
-- next migration.
|
|
17
|
+
alter type member_role add value if not exists 'instance_admin';
|
|
18
|
+
|
|
19
|
+
create type instance_edition as enum ('community', 'cloud');
|
|
20
|
+
|
|
21
|
+
-- The schema version this release ships. Bumped by a migration at each
|
|
22
|
+
-- release; `ekwo migrate` writes it back onto the instance row.
|
|
23
|
+
create or replace function ekwo_schema_version()
|
|
24
|
+
returns text
|
|
25
|
+
language sql
|
|
26
|
+
immutable
|
|
27
|
+
as $$
|
|
28
|
+
select '0.1.0'::text;
|
|
29
|
+
$$;
|
|
30
|
+
|
|
31
|
+
comment on function ekwo_schema_version() is
|
|
32
|
+
'Schema version of the installed release. Bumped by a migration, never by hand.';
|
|
33
|
+
|
|
34
|
+
create table instance (
|
|
35
|
+
-- Singleton. The primary key and the check together make a second row
|
|
36
|
+
-- impossible, rather than merely unusual.
|
|
37
|
+
id smallint primary key default 1,
|
|
38
|
+
instance_id uuid not null unique default gen_random_uuid(),
|
|
39
|
+
organization_name text not null,
|
|
40
|
+
country char(2) not null,
|
|
41
|
+
edition instance_edition not null default 'community',
|
|
42
|
+
schema_version text not null default ekwo_schema_version(),
|
|
43
|
+
installed_at timestamptz not null default now(),
|
|
44
|
+
-- Opt-in registration with Ekwo. Empty by default, never a condition of
|
|
45
|
+
-- use, never checked by anything in this repository.
|
|
46
|
+
contact_email text,
|
|
47
|
+
registered_at timestamptz,
|
|
48
|
+
updated_at timestamptz not null default now(),
|
|
49
|
+
constraint instance_singleton check (id = 1),
|
|
50
|
+
constraint instance_country_format check (country ~ '^[A-Z]{2}$'),
|
|
51
|
+
constraint instance_registration_needs_an_address check (
|
|
52
|
+
registered_at is null or contact_email is not null
|
|
53
|
+
)
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
comment on table instance is
|
|
57
|
+
'The installation itself. Exactly one row. Registration with Ekwo is optional and empty by default.';
|
|
58
|
+
comment on column instance.instance_id is
|
|
59
|
+
'Stable identifier of this installation, generated locally. Never a licence key.';
|
|
60
|
+
comment on column instance.edition is
|
|
61
|
+
'community when you run it yourself, cloud when Ekwo operates it. Gates nothing in this repository.';
|
|
62
|
+
comment on column instance.schema_version is
|
|
63
|
+
'Version of the schema at install, updated by migrations.';
|
|
64
|
+
comment on column instance.contact_email is
|
|
65
|
+
'Opt-in only: an address to reach the operator. Empty unless they asked to register.';
|
|
66
|
+
comment on column instance.registered_at is
|
|
67
|
+
'Opt-in only: when the operator registered with Ekwo. Empty means not registered, which is a supported state.';
|
|
68
|
+
|
|
69
|
+
create trigger instance_set_updated_at
|
|
70
|
+
before update on instance
|
|
71
|
+
for each row execute function set_updated_at();
|
|
72
|
+
|
|
73
|
+
alter table instance enable row level security;
|
|
74
|
+
|
|
75
|
+
-- Anyone signed into this installation may see which installation it is.
|
|
76
|
+
create policy instance_select on instance
|
|
77
|
+
for select using (auth.uid() is not null);
|