shutro-erp 0.2.1 → 0.3.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 +74 -67
- package/dist/account_portal/.kosh/bindings.d.ts +22 -0
- package/dist/account_portal/.kosh/bindings.js +15 -0
- package/dist/account_portal/.kosh/schema.d.ts +1380 -0
- package/dist/account_portal/index.d.ts +3 -0
- package/dist/account_portal/index.js +73 -0
- package/dist/account_portal/module.d.ts +5983 -0
- package/dist/account_portal/module.js +18 -0
- package/dist/accounting/.kosh/bindings.js +1 -1
- package/dist/accounting/.kosh/schema.d.ts +172 -9
- package/dist/accounting/chart.d.ts +40 -8
- package/dist/accounting/chart.js +124 -30
- package/dist/accounting/closing.d.ts +6 -1
- package/dist/accounting/closing.js +5 -1
- package/dist/accounting/demo.js +6 -5
- package/dist/accounting/index.d.ts +3 -3
- package/dist/accounting/index.js +200 -23
- package/dist/accounting/module.d.ts +3326 -1086
- package/dist/accounting/module.js +408 -66
- package/dist/accounting/payments.d.ts +25 -0
- package/dist/accounting/payments.js +96 -4
- package/dist/accounting/web/RegisterPayment.d.ts +3 -2
- package/dist/accounting/web/RegisterPayment.js +39 -6
- package/dist/accounting/web/SettingsPage.js +5 -1
- package/dist/accounting/web/messages.js +10 -0
- package/dist/assistant/routes.js +1 -1
- package/dist/automation/engine.js +1 -1
- package/dist/automation/web/messages.js +2 -2
- package/dist/cli/apps.d.ts +1 -1
- package/dist/cli/apps.js +14 -14
- package/dist/cli/bin.js +3 -0
- package/dist/cli/index.js +11 -11
- package/dist/cli/init.d.ts +1 -1
- package/dist/cli/init.js +224 -78
- package/dist/cli/launch.d.ts +16 -0
- package/dist/cli/launch.js +138 -0
- package/dist/cli/project.d.ts +7 -7
- package/dist/cli/project.js +25 -25
- package/dist/cli/prompt.d.ts +35 -0
- package/dist/cli/prompt.js +48 -2
- package/dist/cli/templates.d.ts +14 -6
- package/dist/cli/templates.js +61 -34
- package/dist/cli/tui.d.ts +7 -0
- package/dist/cli/tui.js +254 -0
- package/dist/cli/ui.d.ts +21 -8
- package/dist/cli/ui.js +65 -19
- package/dist/contacts/.kosh/bindings.js +1 -1
- package/dist/contacts/.kosh/schema.d.ts +33 -1
- package/dist/contacts/index.js +24 -1
- package/dist/contacts/module.d.ts +42 -0
- package/dist/contacts/module.js +3 -1
- package/dist/import/convert.d.ts +55 -0
- package/dist/import/convert.js +224 -0
- package/dist/import/csv.d.ts +28 -0
- package/dist/import/csv.js +115 -0
- package/dist/import/index.d.ts +33 -0
- package/dist/import/index.js +60 -0
- package/dist/import/mapping.d.ts +15 -0
- package/dist/import/mapping.js +33 -0
- package/dist/import/match.d.ts +24 -0
- package/dist/import/match.js +60 -0
- package/dist/import/models.d.ts +2 -0
- package/dist/import/models.js +102 -0
- package/dist/import/routes.d.ts +13 -0
- package/dist/import/routes.js +392 -0
- package/dist/import/run.d.ts +131 -0
- package/dist/import/run.js +568 -0
- package/dist/import/service.d.ts +153 -0
- package/dist/import/service.js +367 -0
- package/dist/import/web/ImportButton.d.ts +7 -0
- package/dist/import/web/ImportButton.js +31 -0
- package/dist/import/web/ImportWizard.d.ts +75 -0
- package/dist/import/web/ImportWizard.js +217 -0
- package/dist/import/web/index.d.ts +13 -0
- package/dist/import/web/index.js +18 -0
- package/dist/import/web/messages.d.ts +2 -0
- package/dist/import/web/messages.js +139 -0
- package/dist/import/worker.d.ts +3 -0
- package/dist/import/worker.js +52 -0
- package/dist/import/xlsx.d.ts +20 -0
- package/dist/import/xlsx.js +192 -0
- package/dist/l10n_bd/.kosh/bindings.d.ts +22 -0
- package/dist/l10n_bd/.kosh/bindings.js +15 -0
- package/dist/l10n_bd/.kosh/schema.d.ts +1311 -0
- package/dist/l10n_bd/documents.d.ts +8 -0
- package/dist/l10n_bd/documents.js +183 -0
- package/dist/l10n_bd/index.d.ts +8 -0
- package/dist/l10n_bd/index.js +156 -0
- package/dist/l10n_bd/module.d.ts +5705 -0
- package/dist/l10n_bd/module.js +163 -0
- package/dist/l10n_bd/mushak.d.ts +67 -0
- package/dist/l10n_bd/mushak.js +139 -0
- package/dist/l10n_bd/routes.d.ts +3 -0
- package/dist/l10n_bd/routes.js +205 -0
- package/dist/l10n_bd/web/MushakPage.d.ts +7 -0
- package/dist/l10n_bd/web/MushakPage.js +53 -0
- package/dist/l10n_bd/web/index.d.ts +13 -0
- package/dist/l10n_bd/web/index.js +18 -0
- package/dist/l10n_bd/web/messages.d.ts +2 -0
- package/dist/l10n_bd/web/messages.js +101 -0
- package/dist/l10n_in/.kosh/bindings.d.ts +22 -0
- package/dist/l10n_in/.kosh/bindings.js +15 -0
- package/dist/l10n_in/.kosh/schema.d.ts +1373 -0
- package/dist/l10n_in/documents.d.ts +8 -0
- package/dist/l10n_in/documents.js +114 -0
- package/dist/l10n_in/einvoice.d.ts +253 -0
- package/dist/l10n_in/einvoice.js +485 -0
- package/dist/l10n_in/gstr.d.ts +109 -0
- package/dist/l10n_in/gstr.js +430 -0
- package/dist/l10n_in/index.d.ts +20 -0
- package/dist/l10n_in/index.js +232 -0
- package/dist/l10n_in/module.d.ts +7823 -0
- package/dist/l10n_in/module.js +427 -0
- package/dist/l10n_in/routes-einvoice.d.ts +15 -0
- package/dist/l10n_in/routes-einvoice.js +124 -0
- package/dist/l10n_in/routes.d.ts +17 -0
- package/dist/l10n_in/routes.js +282 -0
- package/dist/l10n_in/web/EInvoicePanel.d.ts +8 -0
- package/dist/l10n_in/web/EInvoicePanel.js +63 -0
- package/dist/l10n_in/web/GstPage.d.ts +7 -0
- package/dist/l10n_in/web/GstPage.js +57 -0
- package/dist/l10n_in/web/GstSettings.d.ts +10 -0
- package/dist/l10n_in/web/GstSettings.js +36 -0
- package/dist/l10n_in/web/index.d.ts +15 -0
- package/dist/l10n_in/web/index.js +22 -0
- package/dist/l10n_in/web/messages.d.ts +2 -0
- package/dist/l10n_in/web/messages.js +166 -0
- package/dist/mail/index.js +2 -2
- package/dist/modules-sdk/demo.d.ts +2 -0
- package/dist/modules-sdk/demo.js +7 -3
- package/dist/modules-sdk/index.d.ts +2 -2
- package/dist/modules-sdk/index.js +1 -1
- package/dist/modules-sdk/loader.js +2 -2
- package/dist/modules-sdk/manifest.d.ts +132 -0
- package/dist/modules-sdk/manifest.js +22 -0
- package/dist/notify/inbox.js +21 -0
- package/dist/notify/messages.js +7 -3
- package/dist/notify/models.d.ts +1 -1
- package/dist/notify/models.js +2 -0
- package/dist/notify/routes.js +1 -1
- package/dist/notify/web/messages.js +5 -1
- package/dist/portal/.kosh/bindings.d.ts +22 -0
- package/dist/portal/.kosh/bindings.js +15 -0
- package/dist/portal/.kosh/schema.d.ts +376 -0
- package/dist/portal/announce.d.ts +16 -0
- package/dist/portal/announce.js +117 -0
- package/dist/portal/documents.d.ts +17 -0
- package/dist/portal/documents.js +61 -0
- package/dist/portal/index.d.ts +20 -0
- package/dist/portal/index.js +65 -0
- package/dist/portal/module.d.ts +1405 -0
- package/dist/portal/module.js +84 -0
- package/dist/portal/routes-documents.d.ts +2 -0
- package/dist/portal/routes-documents.js +391 -0
- package/dist/portal/routes.d.ts +13 -0
- package/dist/portal/routes.js +313 -0
- package/dist/portal/rules.d.ts +11 -0
- package/dist/portal/rules.js +25 -0
- package/dist/portal/web/PortalAccess.d.ts +8 -0
- package/dist/portal/web/PortalAccess.js +66 -0
- package/dist/portal/web/index.d.ts +12 -0
- package/dist/portal/web/index.js +17 -0
- package/dist/portal/web/messages.d.ts +2 -0
- package/dist/portal/web/messages.js +33 -0
- package/dist/product/.kosh/bindings.js +1 -1
- package/dist/product/.kosh/schema.d.ts +42 -3
- package/dist/product/demo.js +6 -5
- package/dist/product/index.d.ts +1 -0
- package/dist/product/index.js +17 -4
- package/dist/product/module.d.ts +346 -14
- package/dist/product/module.js +48 -18
- package/dist/product/taxes.d.ts +59 -0
- package/dist/product/taxes.js +61 -0
- package/dist/project/.kosh/bindings.js +1 -1
- package/dist/project/.kosh/schema.d.ts +33 -1
- package/dist/project/module.d.ts +20 -0
- package/dist/project_portal/.kosh/bindings.d.ts +22 -0
- package/dist/project_portal/.kosh/bindings.js +15 -0
- package/dist/project_portal/.kosh/schema.d.ts +701 -0
- package/dist/project_portal/index.d.ts +9 -0
- package/dist/project_portal/index.js +42 -0
- package/dist/project_portal/module.d.ts +2142 -0
- package/dist/project_portal/module.js +22 -0
- package/dist/purchase/.kosh/bindings.js +1 -1
- package/dist/purchase/.kosh/schema.d.ts +45 -4
- package/dist/purchase/demo.js +3 -3
- package/dist/purchase/index.js +1 -1
- package/dist/purchase/module.d.ts +232 -8
- package/dist/purchase/module.js +51 -9
- package/dist/purchase_account/.kosh/bindings.js +1 -1
- package/dist/purchase_account/.kosh/schema.d.ts +174 -10
- package/dist/purchase_account/module.d.ts +2008 -641
- package/dist/purchase_account/module.js +2 -2
- package/dist/purchase_portal/.kosh/bindings.d.ts +22 -0
- package/dist/purchase_portal/.kosh/bindings.js +15 -0
- package/dist/purchase_portal/.kosh/schema.d.ts +852 -0
- package/dist/purchase_portal/index.d.ts +9 -0
- package/dist/purchase_portal/index.js +53 -0
- package/dist/purchase_portal/module.d.ts +2758 -0
- package/dist/purchase_portal/module.js +18 -0
- package/dist/reporting/documents.js +20 -3
- package/dist/reporting/index.d.ts +1 -0
- package/dist/reporting/index.js +1 -0
- package/dist/reporting/routes-documents.js +9 -2
- package/dist/reporting/words.d.ts +11 -0
- package/dist/reporting/words.js +229 -0
- package/dist/sale_account/.kosh/bindings.js +1 -1
- package/dist/sale_account/.kosh/schema.d.ts +174 -10
- package/dist/sale_account/module.d.ts +2008 -641
- package/dist/sale_account/module.js +3 -3
- package/dist/sale_portal/.kosh/bindings.d.ts +22 -0
- package/dist/sale_portal/.kosh/bindings.js +15 -0
- package/dist/sale_portal/.kosh/schema.d.ts +766 -0
- package/dist/sale_portal/index.d.ts +9 -0
- package/dist/sale_portal/index.js +71 -0
- package/dist/sale_portal/module.d.ts +2718 -0
- package/dist/sale_portal/module.js +19 -0
- package/dist/sale_project/.kosh/bindings.js +1 -1
- package/dist/sale_project/.kosh/schema.d.ts +45 -4
- package/dist/sale_project/module.d.ts +390 -10
- package/dist/sales/.kosh/bindings.js +1 -1
- package/dist/sales/.kosh/schema.d.ts +45 -4
- package/dist/sales/demo.js +3 -3
- package/dist/sales/index.js +67 -1
- package/dist/sales/module.d.ts +232 -8
- package/dist/sales/module.js +51 -12
- package/dist/server/api/client.js +1 -1
- package/dist/server/api/openapi.js +17 -1
- package/dist/server/apps.js +5 -5
- package/dist/server/auth/api-keys.d.ts +13 -0
- package/dist/server/auth/api-keys.js +65 -0
- package/dist/server/auth/base.js +26 -0
- package/dist/server/auth/crypto.js +1 -1
- package/dist/server/auth/scopes.d.ts +12 -0
- package/dist/server/auth/scopes.js +51 -0
- package/dist/server/auth/service.d.ts +59 -1
- package/dist/server/auth/service.js +236 -6
- package/dist/server/demo.d.ts +1 -1
- package/dist/server/demo.js +1 -1
- package/dist/server/env-names.d.ts +2 -0
- package/dist/server/env-names.js +16 -0
- package/dist/server/host.js +5 -1
- package/dist/server/identity.d.ts +7 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +2 -1
- package/dist/server/registry.js +1 -1
- package/dist/server/server.d.ts +5 -0
- package/dist/server/server.js +71 -6
- package/dist/settings/routes.js +1 -1
- package/dist/settings/web/ApiKeysPage.d.ts +8 -0
- package/dist/settings/web/ApiKeysPage.js +70 -0
- package/dist/settings/web/index.d.ts +1 -0
- package/dist/settings/web/index.js +4 -0
- package/dist/settings/web/messages.js +62 -0
- package/dist/storage/routes.js +1 -1
- package/dist/studio/build.js +1 -1
- package/dist/studio/generate.js +4 -4
- package/dist/studio/module.js +5 -5
- package/dist/studio/web/messages.js +2 -2
- package/dist/ui/api.d.ts +2 -0
- package/dist/ui/app.js +27 -4
- package/dist/ui/context.d.ts +3 -1
- package/dist/ui/context.js +2 -2
- package/dist/ui/i18n/messages.js +2 -2
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/lib/format.d.ts +2 -0
- package/dist/ui/lib/format.js +3 -1
- package/dist/ui/pwa/worker.js +2 -2
- package/dist/ui/registry.d.ts +15 -0
- package/dist/ui/registry.js +20 -0
- package/dist/ui/views/FormView.js +19 -6
- package/package.json +52 -4
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The data layer of Accounting in the portal (RFC 0015 §5.4): portal users read the posted invoices, credit notes
|
|
3
|
+
* and bills of their contact and company (the portal's record rule) and nothing else of the ledger.
|
|
4
|
+
*/
|
|
5
|
+
import { accountingShutro } from '../accounting/index.js';
|
|
6
|
+
import { portalRule, portalShutro } from '../portal/index.js';
|
|
7
|
+
import { defineModule, extendModel } from './.kosh/bindings.js';
|
|
8
|
+
export const MovePortal = extendModel('account.move', {
|
|
9
|
+
access: { 'portal.user': ['read'] },
|
|
10
|
+
rules: { portal: portalRule('partner') },
|
|
11
|
+
});
|
|
12
|
+
export const accountPortalShutro = defineModule({
|
|
13
|
+
name: 'account_portal',
|
|
14
|
+
version: '0.1.0',
|
|
15
|
+
depends: [accountingShutro, portalShutro],
|
|
16
|
+
models: [],
|
|
17
|
+
extensions: [MovePortal],
|
|
18
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash:
|
|
1
|
+
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: c83d584195f8dd43
|
|
2
2
|
// Bindings of module `accounting`: import the definition API from here to get types scoped to what it can see.
|
|
3
3
|
export { defineModel, defineModule, extendModel, f, replace } from '../../server/orm.js';
|
|
4
4
|
import { definitions } from '../../server/orm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash:
|
|
1
|
+
// GENERATED by `pnpm generate:models` (Shutro’s generator). Do not edit. definitions-hash: c83d584195f8dd43
|
|
2
2
|
// Schema view of module `accounting` (RFC 0002 §7.7): the models it owns or depends on, with the extensions it can see.
|
|
3
3
|
import type { F } from '../../server/orm.js';
|
|
4
4
|
|
|
@@ -14,11 +14,15 @@ export interface SchemaView {
|
|
|
14
14
|
readonly 'account.payment': AccountPayment;
|
|
15
15
|
readonly 'account.payment.term': AccountPaymentTerm;
|
|
16
16
|
readonly 'account.payment.term.line': AccountPaymentTermLine;
|
|
17
|
+
readonly 'account.payment.withholding': AccountPaymentWithholding;
|
|
17
18
|
readonly 'account.tax': AccountTax;
|
|
19
|
+
readonly 'account.tax.component': AccountTaxComponent;
|
|
20
|
+
readonly 'account.withholding': AccountWithholding;
|
|
18
21
|
readonly 'approval.level': ApprovalLevel;
|
|
19
22
|
readonly 'approval.policy': ApprovalPolicy;
|
|
20
23
|
readonly 'approval.request': ApprovalRequest;
|
|
21
24
|
readonly 'audit.event': AuditEvent;
|
|
25
|
+
readonly 'auth.api_key': AuthApiKey;
|
|
22
26
|
readonly 'auth.credential': AuthCredential;
|
|
23
27
|
readonly 'auth.session': AuthSession;
|
|
24
28
|
readonly 'auth.user_grant': AuthUserGrant;
|
|
@@ -38,6 +42,7 @@ export interface SchemaView {
|
|
|
38
42
|
readonly 'report.schedule': ReportSchedule;
|
|
39
43
|
readonly 'report.spreadsheet': ReportSpreadsheet;
|
|
40
44
|
readonly 'report.template': ReportTemplate;
|
|
45
|
+
readonly 'res.bank.account': ResBankAccount;
|
|
41
46
|
readonly 'res.company': ResCompany;
|
|
42
47
|
readonly 'res.currency': ResCurrency;
|
|
43
48
|
readonly 'res.currency.rate': ResCurrencyRate;
|
|
@@ -163,7 +168,7 @@ export interface AccountMove {
|
|
|
163
168
|
readonly numberGeneral: F.Char<{ readonly readonly: true; readonly sequence: true }>;
|
|
164
169
|
readonly journal: F.Many2one<'account.journal', { readonly required: true }>;
|
|
165
170
|
readonly date: F.DateOnly<{ readonly required: true; readonly default: true }>;
|
|
166
|
-
readonly kind: F.Selection<'entry' | 'out_invoice' | 'out_refund' | 'in_invoice' | 'in_refund', { readonly required: true; readonly default: true }>;
|
|
171
|
+
readonly kind: F.Selection<'entry' | 'out_invoice' | 'out_refund' | 'in_invoice' | 'in_refund' | 'out_debit' | 'in_debit', { readonly required: true; readonly default: true }>;
|
|
167
172
|
readonly partner: F.Many2one<'res.partner'>;
|
|
168
173
|
readonly ref: F.Char;
|
|
169
174
|
readonly currency: F.Many2one<'res.currency', { readonly required: true }>;
|
|
@@ -175,6 +180,7 @@ export interface AccountMove {
|
|
|
175
180
|
readonly amountDebit: F.Monetary<'companyCurrency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
176
181
|
readonly amountCredit: F.Monetary<'companyCurrency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
177
182
|
readonly dateDue: F.DateOnly;
|
|
183
|
+
readonly paymentDetails: F.Text<{ readonly readonly: true; readonly compute: true }>;
|
|
178
184
|
readonly paymentTerm: F.Many2one<'account.payment.term'>;
|
|
179
185
|
readonly invoiceOrigin: F.Char;
|
|
180
186
|
readonly amountUntaxed: F.Monetary<'currency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
@@ -187,6 +193,8 @@ export interface AccountMove {
|
|
|
187
193
|
readonly postedAt: F.Datetime;
|
|
188
194
|
readonly postedTx: F.Char;
|
|
189
195
|
readonly reversalOf: F.Many2one<'account.move'>;
|
|
196
|
+
readonly debitOf: F.Many2one<'account.move'>;
|
|
197
|
+
readonly placeOfSupply: F.Char;
|
|
190
198
|
readonly reversedBy: F.Many2one<'account.move'>;
|
|
191
199
|
};
|
|
192
200
|
readonly methods: AccountMoveMethods;
|
|
@@ -228,10 +236,14 @@ export interface AccountMoveLine {
|
|
|
228
236
|
readonly quantity: F.Decimal<{ readonly default: true }>;
|
|
229
237
|
readonly priceUnit: F.Decimal<{ readonly default: true }>;
|
|
230
238
|
readonly discount: F.Decimal<{ readonly default: true }>;
|
|
231
|
-
readonly
|
|
239
|
+
readonly taxes: F.Many2many<'account.tax', { readonly required: true }>;
|
|
240
|
+
readonly tax: F.Many2one<'account.tax', { readonly readonly: true }>;
|
|
232
241
|
readonly subtotal: F.Monetary<'currency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
233
242
|
readonly taxAmount: F.Monetary<'currency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
234
243
|
readonly taxLineOf: F.Many2one<'account.tax'>;
|
|
244
|
+
readonly taxComponent: F.Many2one<'account.tax.component'>;
|
|
245
|
+
readonly taxReverseCharge: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
246
|
+
readonly taxBase: F.Monetary<'currency'>;
|
|
235
247
|
readonly balance: F.Monetary<'companyCurrency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
236
248
|
readonly posted: F.Bool<{ readonly required: true; readonly readonly: true; readonly default: true; readonly compute: true; readonly store: true }>;
|
|
237
249
|
readonly accountType: F.Selection<'asset_receivable' | 'asset_cash' | 'asset_current' | 'asset_prepayments' | 'asset_fixed' | 'asset_non_current' | 'liability_payable' | 'liability_current' | 'liability_non_current' | 'equity' | 'equity_unaffected' | 'income' | 'income_other' | 'expense' | 'expense_direct_cost' | 'expense_depreciation' | 'off_balance', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
@@ -295,6 +307,8 @@ export interface AccountPayment {
|
|
|
295
307
|
readonly amount: F.Monetary<'currency', { readonly required: true }>;
|
|
296
308
|
readonly memo: F.Char;
|
|
297
309
|
readonly documents: F.Many2many<'account.move', { readonly required: true }>;
|
|
310
|
+
readonly withholdings: F.One2many<'account.payment.withholding', { readonly required: true }>;
|
|
311
|
+
readonly amountWithheld: F.Monetary<'currency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
298
312
|
readonly move: F.Many2one<'account.move'>;
|
|
299
313
|
readonly state: F.State<'draft' | 'posted' | 'cancel', { readonly required: true; readonly readonly: true; readonly default: true }>;
|
|
300
314
|
};
|
|
@@ -351,6 +365,29 @@ export interface AccountPaymentTermLine {
|
|
|
351
365
|
export interface AccountPaymentTermLineMethods extends F.Methods<typeof import('../module.js').accountingShutro, 'account.payment.term.line'> {
|
|
352
366
|
}
|
|
353
367
|
|
|
368
|
+
/** `account.payment.withholding` (owner: accounting). */
|
|
369
|
+
export interface AccountPaymentWithholding {
|
|
370
|
+
readonly name: 'account.payment.withholding';
|
|
371
|
+
readonly fields: {
|
|
372
|
+
readonly id: F.Id<'account.payment.withholding'>;
|
|
373
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
374
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
375
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
376
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
377
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
378
|
+
readonly payment: F.Many2one<'account.payment', { readonly required: true }>;
|
|
379
|
+
readonly withholding: F.Many2one<'account.withholding', { readonly required: true }>;
|
|
380
|
+
readonly currency: F.Many2one<'res.currency', { readonly readonly: true; readonly compute: true; readonly store: true }>;
|
|
381
|
+
readonly base: F.Monetary<'currency'>;
|
|
382
|
+
readonly amount: F.Monetary<'currency', { readonly required: true }>;
|
|
383
|
+
};
|
|
384
|
+
readonly methods: AccountPaymentWithholdingMethods;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** Methods of `account.payment.withholding`: declared ones and transitions. */
|
|
388
|
+
export interface AccountPaymentWithholdingMethods extends F.Methods<typeof import('../module.js').accountingShutro, 'account.payment.withholding'> {
|
|
389
|
+
}
|
|
390
|
+
|
|
354
391
|
/** `account.tax` (owner: product; extended by: accounting). */
|
|
355
392
|
export interface AccountTax {
|
|
356
393
|
readonly name: 'account.tax';
|
|
@@ -364,10 +401,17 @@ export interface AccountTax {
|
|
|
364
401
|
readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
365
402
|
readonly name: F.Char<{ readonly required: true; readonly translate: true }>;
|
|
366
403
|
readonly use: F.Selection<'sale' | 'purchase', { readonly required: true; readonly default: true }>;
|
|
404
|
+
readonly sequence: F.Integer<{ readonly required: true; readonly default: true }>;
|
|
405
|
+
readonly amountType: F.Selection<'percent' | 'fixed', { readonly required: true; readonly default: true }>;
|
|
367
406
|
readonly rate: F.Decimal<{ readonly required: true; readonly default: true }>;
|
|
407
|
+
readonly fixedAmount: F.Decimal<{ readonly required: true; readonly default: true }>;
|
|
408
|
+
readonly affectsBase: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
409
|
+
readonly priceIncluded: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
410
|
+
readonly reverseCharge: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
368
411
|
readonly account: F.Many2one<'account.account'>; // accounting
|
|
369
412
|
readonly refundAccount: F.Many2one<'account.account'>; // accounting
|
|
370
|
-
readonly
|
|
413
|
+
readonly reverseChargeAccount: F.Many2one<'account.account'>; // accounting
|
|
414
|
+
readonly components: F.One2many<'account.tax.component', { readonly required: true }>; // accounting
|
|
371
415
|
};
|
|
372
416
|
readonly methods: AccountTaxMethods;
|
|
373
417
|
}
|
|
@@ -376,6 +420,60 @@ export interface AccountTax {
|
|
|
376
420
|
export interface AccountTaxMethods extends F.Methods<typeof import('../../product/index.js').productShutro, 'account.tax'>, F.Methods<typeof import('../module.js').accountingShutro, 'account.tax'> {
|
|
377
421
|
}
|
|
378
422
|
|
|
423
|
+
/** `account.tax.component` (owner: accounting). */
|
|
424
|
+
export interface AccountTaxComponent {
|
|
425
|
+
readonly name: 'account.tax.component';
|
|
426
|
+
readonly fields: {
|
|
427
|
+
readonly id: F.Id<'account.tax.component'>;
|
|
428
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
429
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
430
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
431
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
432
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
433
|
+
readonly tax: F.Many2one<'account.tax', { readonly required: true }>;
|
|
434
|
+
readonly sequence: F.Integer<{ readonly required: true; readonly default: true }>;
|
|
435
|
+
readonly name: F.Char<{ readonly required: true; readonly translate: true }>;
|
|
436
|
+
readonly share: F.Decimal<{ readonly required: true; readonly default: true }>;
|
|
437
|
+
readonly scope: F.Selection<'always' | 'intra' | 'inter', { readonly required: true; readonly default: true }>;
|
|
438
|
+
readonly code: F.Char;
|
|
439
|
+
readonly account: F.Many2one<'account.account'>;
|
|
440
|
+
readonly refundAccount: F.Many2one<'account.account'>;
|
|
441
|
+
readonly reverseChargeAccount: F.Many2one<'account.account'>;
|
|
442
|
+
};
|
|
443
|
+
readonly methods: AccountTaxComponentMethods;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/** Methods of `account.tax.component`: declared ones and transitions. */
|
|
447
|
+
export interface AccountTaxComponentMethods extends F.Methods<typeof import('../module.js').accountingShutro, 'account.tax.component'> {
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/** `account.withholding` (owner: accounting). */
|
|
451
|
+
export interface AccountWithholding {
|
|
452
|
+
readonly name: 'account.withholding';
|
|
453
|
+
readonly fields: {
|
|
454
|
+
readonly id: F.Id<'account.withholding'>;
|
|
455
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
456
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
457
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
458
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
459
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
460
|
+
readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
461
|
+
readonly company: F.Many2one<'res.company', { readonly required: true; readonly default: true }>;
|
|
462
|
+
readonly name: F.Char<{ readonly required: true; readonly translate: true }>;
|
|
463
|
+
readonly sequence: F.Integer<{ readonly required: true; readonly default: true }>;
|
|
464
|
+
readonly direction: F.Selection<'vendor' | 'customer', { readonly required: true; readonly default: true }>;
|
|
465
|
+
readonly base: F.Selection<'untaxed' | 'tax' | 'total', { readonly required: true; readonly default: true }>;
|
|
466
|
+
readonly rate: F.Decimal<{ readonly required: true; readonly default: true }>;
|
|
467
|
+
readonly threshold: F.Decimal<{ readonly required: true; readonly default: true }>;
|
|
468
|
+
readonly account: F.Many2one<'account.account', { readonly required: true }>;
|
|
469
|
+
};
|
|
470
|
+
readonly methods: AccountWithholdingMethods;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/** Methods of `account.withholding`: declared ones and transitions. */
|
|
474
|
+
export interface AccountWithholdingMethods extends F.Methods<typeof import('../module.js').accountingShutro, 'account.withholding'> {
|
|
475
|
+
}
|
|
476
|
+
|
|
379
477
|
/** `approval.level` (owner: permissions). */
|
|
380
478
|
export interface ApprovalLevel {
|
|
381
479
|
readonly name: 'approval.level';
|
|
@@ -482,6 +580,34 @@ export interface AuditEvent {
|
|
|
482
580
|
export interface AuditEventMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'audit.event'> {
|
|
483
581
|
}
|
|
484
582
|
|
|
583
|
+
/** `auth.api_key` (owner: base). */
|
|
584
|
+
export interface AuthApiKey {
|
|
585
|
+
readonly name: 'auth.api_key';
|
|
586
|
+
readonly fields: {
|
|
587
|
+
readonly id: F.Id<'auth.api_key'>;
|
|
588
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
589
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
590
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
591
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
592
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
593
|
+
readonly name: F.Char<{ readonly required: true }>;
|
|
594
|
+
readonly user: F.Many2one<'res.users', { readonly required: true }>;
|
|
595
|
+
readonly tokenHash: F.Char<{ readonly required: true }>;
|
|
596
|
+
readonly prefix: F.Char<{ readonly required: true }>;
|
|
597
|
+
readonly scopes: F.Text<{ readonly required: true }>;
|
|
598
|
+
readonly expiresAt: F.Datetime<{ readonly required: true }>;
|
|
599
|
+
readonly lastUsedAt: F.Datetime;
|
|
600
|
+
readonly lastUsedIp: F.Char;
|
|
601
|
+
readonly revoked: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
602
|
+
readonly issuedBy: F.Many2one<'res.users'>;
|
|
603
|
+
};
|
|
604
|
+
readonly methods: AuthApiKeyMethods;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/** Methods of `auth.api_key`: declared ones and transitions. */
|
|
608
|
+
export interface AuthApiKeyMethods extends F.Methods<typeof import('../../server/index.js').baseShutro, 'auth.api_key'> {
|
|
609
|
+
}
|
|
610
|
+
|
|
485
611
|
/** `auth.credential` (owner: base). */
|
|
486
612
|
export interface AuthCredential {
|
|
487
613
|
readonly name: 'auth.credential';
|
|
@@ -820,8 +946,10 @@ export interface ProductProduct {
|
|
|
820
946
|
readonly standardPrice: F.Decimal<{ readonly required: true; readonly default: true }>;
|
|
821
947
|
readonly saleOk: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
822
948
|
readonly purchaseOk: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
823
|
-
readonly
|
|
824
|
-
readonly
|
|
949
|
+
readonly taxes: F.Many2many<'account.tax', { readonly required: true }>;
|
|
950
|
+
readonly purchaseTaxes: F.Many2many<'account.tax', { readonly required: true }>;
|
|
951
|
+
readonly tax: F.Many2one<'account.tax', { readonly readonly: true }>;
|
|
952
|
+
readonly purchaseTax: F.Many2one<'account.tax', { readonly readonly: true }>;
|
|
825
953
|
readonly description: F.Text<{ readonly translate: true }>;
|
|
826
954
|
};
|
|
827
955
|
readonly methods: ProductProductMethods;
|
|
@@ -956,6 +1084,34 @@ export interface ReportTemplate {
|
|
|
956
1084
|
export interface ReportTemplateMethods extends F.Methods<typeof import('../../reporting/index.js').reportingShutro, 'report.template'> {
|
|
957
1085
|
}
|
|
958
1086
|
|
|
1087
|
+
/** `res.bank.account` (owner: accounting). */
|
|
1088
|
+
export interface ResBankAccount {
|
|
1089
|
+
readonly name: 'res.bank.account';
|
|
1090
|
+
readonly fields: {
|
|
1091
|
+
readonly id: F.Id<'res.bank.account'>;
|
|
1092
|
+
readonly createdAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
1093
|
+
readonly updatedAt: F.Datetime<{ readonly required: true; readonly readonly: true }>;
|
|
1094
|
+
readonly createdBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
1095
|
+
readonly updatedBy: F.Many2one<'res.users', { readonly readonly: true }>;
|
|
1096
|
+
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
1097
|
+
readonly active: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
1098
|
+
readonly company: F.Many2one<'res.company', { readonly required: true; readonly default: true }>;
|
|
1099
|
+
readonly sequence: F.Integer<{ readonly required: true; readonly default: true }>;
|
|
1100
|
+
readonly bank: F.Char<{ readonly required: true }>;
|
|
1101
|
+
readonly branch: F.Char;
|
|
1102
|
+
readonly number: F.Char<{ readonly required: true }>;
|
|
1103
|
+
readonly holder: F.Char;
|
|
1104
|
+
readonly routing: F.Char;
|
|
1105
|
+
readonly swift: F.Char;
|
|
1106
|
+
readonly currency: F.Many2one<'res.currency'>;
|
|
1107
|
+
};
|
|
1108
|
+
readonly methods: ResBankAccountMethods;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
/** Methods of `res.bank.account`: declared ones and transitions. */
|
|
1112
|
+
export interface ResBankAccountMethods extends F.Methods<typeof import('../module.js').accountingShutro, 'res.bank.account'> {
|
|
1113
|
+
}
|
|
1114
|
+
|
|
959
1115
|
/** `res.company` (owner: base; extended by: accounting). */
|
|
960
1116
|
export interface ResCompany {
|
|
961
1117
|
readonly name: 'res.company';
|
|
@@ -968,7 +1124,11 @@ export interface ResCompany {
|
|
|
968
1124
|
readonly displayName: F.Char<{ readonly required: true; readonly readonly: true; readonly compute: true }>;
|
|
969
1125
|
readonly name: F.Char<{ readonly required: true }>;
|
|
970
1126
|
readonly currency: F.Many2one<'res.currency', { readonly required: true }>;
|
|
971
|
-
readonly
|
|
1127
|
+
readonly numberGrouping: F.Selection<'international' | 'lakh', { readonly required: true; readonly default: true }>;
|
|
1128
|
+
readonly fiscalYearStart: F.Integer<{ readonly required: true; readonly default: true }>; // accounting
|
|
1129
|
+
readonly chartTemplate: F.Char; // accounting
|
|
1130
|
+
readonly country: F.Char; // accounting
|
|
1131
|
+
readonly state: F.Char; // accounting
|
|
972
1132
|
readonly lockDate: F.DateOnly; // accounting
|
|
973
1133
|
readonly taxLockDate: F.DateOnly; // accounting
|
|
974
1134
|
readonly accountReceivable: F.Many2one<'account.account'>; // accounting
|
|
@@ -1027,7 +1187,7 @@ export interface ResCurrencyRate {
|
|
|
1027
1187
|
export interface ResCurrencyRateMethods extends F.Methods<typeof import('../module.js').accountingShutro, 'res.currency.rate'> {
|
|
1028
1188
|
}
|
|
1029
1189
|
|
|
1030
|
-
/** `res.partner` (owner: contacts). */
|
|
1190
|
+
/** `res.partner` (owner: contacts; extended by: accounting). */
|
|
1031
1191
|
export interface ResPartner {
|
|
1032
1192
|
readonly name: 'res.partner';
|
|
1033
1193
|
readonly fields: {
|
|
@@ -1051,17 +1211,19 @@ export interface ResPartner {
|
|
|
1051
1211
|
readonly city: F.Char;
|
|
1052
1212
|
readonly zip: F.Char;
|
|
1053
1213
|
readonly country: F.Char;
|
|
1214
|
+
readonly state: F.Char;
|
|
1054
1215
|
readonly taxId: F.Char;
|
|
1055
1216
|
readonly isCustomer: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
1056
1217
|
readonly isVendor: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
1057
1218
|
readonly currency: F.Many2one<'res.currency'>;
|
|
1058
1219
|
readonly notes: F.Text;
|
|
1220
|
+
readonly withholdings: F.Many2many<'account.withholding', { readonly required: true }>; // accounting
|
|
1059
1221
|
};
|
|
1060
1222
|
readonly methods: ResPartnerMethods;
|
|
1061
1223
|
}
|
|
1062
1224
|
|
|
1063
1225
|
/** Methods of `res.partner`: declared ones and transitions. */
|
|
1064
|
-
export interface ResPartnerMethods extends F.Methods<typeof import('../../contacts/index.js').contactsShutro, 'res.partner'> {
|
|
1226
|
+
export interface ResPartnerMethods extends F.Methods<typeof import('../../contacts/index.js').contactsShutro, 'res.partner'>, F.Methods<typeof import('../module.js').accountingShutro, 'res.partner'> {
|
|
1065
1227
|
}
|
|
1066
1228
|
|
|
1067
1229
|
/** `res.users` (owner: base). */
|
|
@@ -1083,6 +1245,7 @@ export interface ResUsers {
|
|
|
1083
1245
|
readonly companies: F.Many2many<'res.company', { readonly required: true }>;
|
|
1084
1246
|
readonly lang: F.Char<{ readonly default: true }>;
|
|
1085
1247
|
readonly tz: F.Char<{ readonly default: true }>;
|
|
1248
|
+
readonly isService: F.Bool<{ readonly required: true; readonly default: true }>;
|
|
1086
1249
|
};
|
|
1087
1250
|
readonly methods: ResUsersMethods;
|
|
1088
1251
|
}
|
|
@@ -1,14 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Charts of accounts (RFC 0009 §5.6) and localizations (RFC 0016 §5.2): the generic template lives here; a country's
|
|
3
|
+
* comes with its localization module (`l10n_bd`). Installing a template for a company creates its accounts and
|
|
4
|
+
* journals, links the company's default accounts, and points the taxes at their accounts; installing a
|
|
5
|
+
* localization also sets the accounts of its own taxes, its withholdings, the fiscal year and the number grouping.
|
|
6
|
+
* Each is applied once per company. Also here: the database triggers that keep posted entries immutable below the
|
|
7
|
+
* ORM (raw SQL, deletes), created idempotently with the module's defaults.
|
|
8
|
+
*/
|
|
9
|
+
import type { KoshModule, LocalizationSpec } from '../modules-sdk/index.js';
|
|
1
10
|
import type { Env } from './.kosh/bindings.js';
|
|
2
|
-
import type
|
|
3
|
-
|
|
4
|
-
|
|
11
|
+
import { type AccountType } from './module.js';
|
|
12
|
+
/** A chart's code: `generic`, or a localization's key (`bd`). */
|
|
13
|
+
export type ChartTemplate = string;
|
|
14
|
+
export interface AccountSpec {
|
|
5
15
|
readonly code: string;
|
|
6
16
|
readonly name: string;
|
|
7
17
|
readonly type: AccountType;
|
|
8
18
|
readonly reconcile?: boolean;
|
|
9
19
|
}
|
|
10
20
|
/** Which accounts the company's defaults point to, by code. */
|
|
11
|
-
interface Defaults {
|
|
21
|
+
export interface Defaults {
|
|
12
22
|
readonly receivable: string;
|
|
13
23
|
readonly payable: string;
|
|
14
24
|
readonly exchangeGain: string;
|
|
@@ -19,7 +29,7 @@ interface Defaults {
|
|
|
19
29
|
readonly income: string;
|
|
20
30
|
readonly expense: string;
|
|
21
31
|
}
|
|
22
|
-
interface Chart {
|
|
32
|
+
export interface Chart {
|
|
23
33
|
readonly label: string;
|
|
24
34
|
readonly accounts: readonly AccountSpec[];
|
|
25
35
|
readonly defaults: Defaults;
|
|
@@ -29,7 +39,16 @@ interface Chart {
|
|
|
29
39
|
readonly purchase: string;
|
|
30
40
|
};
|
|
31
41
|
}
|
|
32
|
-
|
|
42
|
+
/** The accounts every chart starts from (a localization adds its own). */
|
|
43
|
+
export declare const COMMON_ACCOUNTS: readonly AccountSpec[];
|
|
44
|
+
/** The default accounts of the common set, by code. */
|
|
45
|
+
export declare const DEFAULT_ACCOUNTS: Defaults;
|
|
46
|
+
/** The charts Accounting ships: the generic one. Countries bring theirs (`chartsOf`). */
|
|
47
|
+
export declare const CHARTS: Readonly<Record<string, Chart>>;
|
|
48
|
+
/** Every chart the installed modules offer: the generic one and the localizations'. */
|
|
49
|
+
export declare function chartsOf(modules: readonly KoshModule[]): ReadonlyMap<string, Chart>;
|
|
50
|
+
/** The localizations of the installed modules, by key. */
|
|
51
|
+
export declare function localizationsOf(modules: readonly KoshModule[]): ReadonlyMap<string, LocalizationSpec>;
|
|
33
52
|
export interface ChartInstalled {
|
|
34
53
|
readonly template: ChartTemplate;
|
|
35
54
|
readonly accounts: number;
|
|
@@ -43,7 +62,21 @@ export declare function installedChart(env: Env): Promise<ChartTemplate | null>;
|
|
|
43
62
|
* and the tax accounts of the product module's taxes.
|
|
44
63
|
* @throws {Error} when the company already has a chart (the caller turns it into a 409)
|
|
45
64
|
*/
|
|
46
|
-
export declare function installChart(env: Env, template: ChartTemplate): Promise<ChartInstalled>;
|
|
65
|
+
export declare function installChart(env: Env, template: ChartTemplate, chart?: Chart): Promise<ChartInstalled>;
|
|
66
|
+
export interface LocalizationInstalled {
|
|
67
|
+
readonly localization: string;
|
|
68
|
+
/** The chart, when the company had none yet. */
|
|
69
|
+
readonly chart: ChartInstalled | null;
|
|
70
|
+
readonly taxes: number;
|
|
71
|
+
readonly withholdings: number;
|
|
72
|
+
readonly fiscalYear: string | null;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Sets a company up for a country (RFC 0016 §5.2), once and idempotently: its chart (unless it has one), the
|
|
76
|
+
* accounts of the localization's taxes, its withholdings (those it lacks, by name), the fiscal year's first month and
|
|
77
|
+
* the number grouping, and the current fiscal year when there is none. Everything is the company's data afterwards.
|
|
78
|
+
*/
|
|
79
|
+
export declare function installLocalization(env: Env, localization: LocalizationSpec): Promise<LocalizationInstalled>;
|
|
47
80
|
export declare class ChartInstalledError extends Error {
|
|
48
81
|
readonly template: ChartTemplate;
|
|
49
82
|
constructor(template: ChartTemplate);
|
|
@@ -54,4 +87,3 @@ export declare class ChartInstalledError extends Error {
|
|
|
54
87
|
* reversal link, reconciliation marks) stay open.
|
|
55
88
|
*/
|
|
56
89
|
export declare function installImmutability(env: Env): Promise<void>;
|
|
57
|
-
export {};
|
package/dist/accounting/chart.js
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Charts of accounts (RFC 0009 §5.6): the generic template and the Bangladesh one (RFC 0008 decision 2; VAT accounts
|
|
3
|
-
* follow the Mushak structure: output VAT, input VAT, VAT payable, AT, SD). Installing a template for a company
|
|
4
|
-
* creates its accounts and journals, links the company's default accounts, and points the taxes at their accounts.
|
|
5
|
-
* A template is applied once per company. Also here: the database triggers that keep posted entries immutable
|
|
6
|
-
* below the ORM (raw SQL, deletes), created idempotently with the module's defaults.
|
|
7
|
-
*/
|
|
8
1
|
import { orm } from '../server/orm.js';
|
|
9
|
-
|
|
2
|
+
import { fiscalYearOf } from './module.js';
|
|
3
|
+
/** The accounts every chart starts from (a localization adds its own). */
|
|
4
|
+
export const COMMON_ACCOUNTS = [
|
|
10
5
|
{ code: '1000', name: 'Cash', type: 'asset_cash' },
|
|
11
6
|
{ code: '1010', name: 'Bank', type: 'asset_cash' },
|
|
12
7
|
{ code: '1100', name: 'Accounts receivable', type: 'asset_receivable', reconcile: true },
|
|
@@ -35,7 +30,8 @@ const COMMON = [
|
|
|
35
30
|
{ code: '6900', name: 'Exchange loss', type: 'expense' },
|
|
36
31
|
{ code: '9999', name: 'Suspense', type: 'asset_current', reconcile: true },
|
|
37
32
|
];
|
|
38
|
-
|
|
33
|
+
/** The default accounts of the common set, by code. */
|
|
34
|
+
export const DEFAULT_ACCOUNTS = {
|
|
39
35
|
receivable: '1100',
|
|
40
36
|
payable: '2000',
|
|
41
37
|
exchangeGain: '4910',
|
|
@@ -46,32 +42,16 @@ const DEFAULTS = {
|
|
|
46
42
|
income: '4000',
|
|
47
43
|
expense: '6300',
|
|
48
44
|
};
|
|
45
|
+
/** The charts Accounting ships: the generic one. Countries bring theirs (`chartsOf`). */
|
|
49
46
|
export const CHARTS = {
|
|
50
47
|
generic: {
|
|
51
48
|
label: 'Generic',
|
|
52
49
|
accounts: [
|
|
53
|
-
...
|
|
50
|
+
...COMMON_ACCOUNTS,
|
|
54
51
|
{ code: '2200', name: 'VAT collected', type: 'liability_current' },
|
|
55
52
|
{ code: '1300', name: 'VAT paid', type: 'asset_current' },
|
|
56
53
|
],
|
|
57
|
-
defaults:
|
|
58
|
-
taxAccounts: { sale: '2200', purchase: '1300' },
|
|
59
|
-
},
|
|
60
|
-
bd: {
|
|
61
|
-
label: 'Bangladesh',
|
|
62
|
-
accounts: [
|
|
63
|
-
...COMMON,
|
|
64
|
-
// VAT and SD Act 2012 (Mushak): output and input VAT, the net payable, advance tax, supplementary duty.
|
|
65
|
-
{ code: '2200', name: 'Output VAT (Mushak)', type: 'liability_current' },
|
|
66
|
-
{ code: '1300', name: 'Input VAT (Mushak)', type: 'asset_current' },
|
|
67
|
-
{ code: '2210', name: 'VAT payable', type: 'liability_current' },
|
|
68
|
-
{ code: '1310', name: 'Advance tax (AT) receivable', type: 'asset_current' },
|
|
69
|
-
{ code: '2220', name: 'Supplementary duty (SD) payable', type: 'liability_current' },
|
|
70
|
-
{ code: '1320', name: 'Advance income tax (AIT) receivable', type: 'asset_current' },
|
|
71
|
-
{ code: '2230', name: 'Tax deducted at source (TDS) payable', type: 'liability_current' },
|
|
72
|
-
{ code: '2240', name: 'VAT deducted at source (VDS) payable', type: 'liability_current' },
|
|
73
|
-
],
|
|
74
|
-
defaults: DEFAULTS,
|
|
54
|
+
defaults: DEFAULT_ACCOUNTS,
|
|
75
55
|
taxAccounts: { sale: '2200', purchase: '1300' },
|
|
76
56
|
},
|
|
77
57
|
};
|
|
@@ -82,6 +62,20 @@ const JOURNALS = [
|
|
|
82
62
|
{ code: 'BNK', name: 'Bank', type: 'bank', account: 'bank' },
|
|
83
63
|
{ code: 'MISC', name: 'Miscellaneous', type: 'general', account: null },
|
|
84
64
|
];
|
|
65
|
+
/** Every chart the installed modules offer: the generic one and the localizations'. */
|
|
66
|
+
export function chartsOf(modules) {
|
|
67
|
+
const out = new Map(Object.entries(CHARTS));
|
|
68
|
+
for (const m of modules) {
|
|
69
|
+
const l = m.localization;
|
|
70
|
+
if (l !== undefined)
|
|
71
|
+
out.set(l.key, { ...l.chart, label: l.label });
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
/** The localizations of the installed modules, by key. */
|
|
76
|
+
export function localizationsOf(modules) {
|
|
77
|
+
return new Map(modules.flatMap((m) => m.localization === undefined ? [] : [[m.localization.key, m.localization]]));
|
|
78
|
+
}
|
|
85
79
|
/** Already-installed template of the environment's company, or null. */
|
|
86
80
|
export async function installedChart(env) {
|
|
87
81
|
const [company] = await env.model('res.company').browse([env.companyId]).load({});
|
|
@@ -92,8 +86,7 @@ export async function installedChart(env) {
|
|
|
92
86
|
* and the tax accounts of the product module's taxes.
|
|
93
87
|
* @throws {Error} when the company already has a chart (the caller turns it into a 409)
|
|
94
88
|
*/
|
|
95
|
-
export async function installChart(env, template) {
|
|
96
|
-
const chart = CHARTS[template];
|
|
89
|
+
export async function installChart(env, template, chart = CHARTS[template]) {
|
|
97
90
|
const company = env.companyRef;
|
|
98
91
|
const existing = await installedChart(env);
|
|
99
92
|
if (existing !== null)
|
|
@@ -149,6 +142,107 @@ export async function installChart(env, template) {
|
|
|
149
142
|
}
|
|
150
143
|
return { template, accounts: accounts.length, journals: journals.length, taxes: linked };
|
|
151
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Sets a company up for a country (RFC 0016 §5.2), once and idempotently: its chart (unless it has one), the
|
|
147
|
+
* accounts of the localization's taxes, its withholdings (those it lacks, by name), the fiscal year's first month and
|
|
148
|
+
* the number grouping, and the current fiscal year when there is none. Everything is the company's data afterwards.
|
|
149
|
+
*/
|
|
150
|
+
export async function installLocalization(env, localization) {
|
|
151
|
+
const company = env.companyRef;
|
|
152
|
+
const chartSpec = {
|
|
153
|
+
...localization.chart,
|
|
154
|
+
label: localization.label,
|
|
155
|
+
};
|
|
156
|
+
const chart = (await installedChart(env)) === null
|
|
157
|
+
? await installChart(env, localization.key, chartSpec)
|
|
158
|
+
: null;
|
|
159
|
+
const accountOf = async (code) => {
|
|
160
|
+
const found = await env.model('account.account').search({ where: { code, company }, limit: 1 });
|
|
161
|
+
const id = found.ids[0];
|
|
162
|
+
if (id === undefined)
|
|
163
|
+
throw new Error(`The ${localization.label} chart has no account ${code}.`);
|
|
164
|
+
return id;
|
|
165
|
+
};
|
|
166
|
+
let taxes = 0;
|
|
167
|
+
for (const [externalId, code] of Object.entries(localization.taxes ?? {})) {
|
|
168
|
+
let tax;
|
|
169
|
+
try {
|
|
170
|
+
tax = Number(await env.refId('account.tax', externalId));
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (error instanceof orm.UnknownExternalIdError)
|
|
174
|
+
continue; // removed by the users
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
await env
|
|
178
|
+
.model('account.tax')
|
|
179
|
+
.browse([orm.asId(tax, 'account.tax')])
|
|
180
|
+
.write({ account: await accountOf(code) });
|
|
181
|
+
taxes += 1;
|
|
182
|
+
}
|
|
183
|
+
for (const [externalId, target] of Object.entries(localization.components ?? {})) {
|
|
184
|
+
let component;
|
|
185
|
+
try {
|
|
186
|
+
component = Number(await env.refId('account.tax.component', externalId));
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
if (error instanceof orm.UnknownExternalIdError)
|
|
190
|
+
continue; // removed by the users
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
const codes = typeof target === 'string' ? { account: target } : target;
|
|
194
|
+
await env
|
|
195
|
+
.model('account.tax.component')
|
|
196
|
+
.browse([orm.asId(component, 'account.tax.component')])
|
|
197
|
+
.write({
|
|
198
|
+
account: await accountOf(codes.account),
|
|
199
|
+
...(codes.reverseCharge === undefined
|
|
200
|
+
? {}
|
|
201
|
+
: { reverseChargeAccount: await accountOf(codes.reverseCharge) }),
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
let withholdings = 0;
|
|
205
|
+
for (const w of localization.withholdings ?? []) {
|
|
206
|
+
const exists = await env
|
|
207
|
+
.model('account.withholding')
|
|
208
|
+
.search({ where: { name: w.name, company }, limit: 1 });
|
|
209
|
+
if (exists.length > 0)
|
|
210
|
+
continue;
|
|
211
|
+
await env.model('account.withholding').create([
|
|
212
|
+
{
|
|
213
|
+
name: w.name,
|
|
214
|
+
direction: w.direction,
|
|
215
|
+
base: w.base,
|
|
216
|
+
rate: w.rate,
|
|
217
|
+
threshold: w.threshold ?? '0',
|
|
218
|
+
account: await accountOf(w.account),
|
|
219
|
+
company,
|
|
220
|
+
},
|
|
221
|
+
]);
|
|
222
|
+
withholdings += 1;
|
|
223
|
+
}
|
|
224
|
+
const start = localization.fiscalYearStart ?? 1;
|
|
225
|
+
await env.asSuperuser({ reason: `localize the company for ${localization.label}` }, (su) => su
|
|
226
|
+
.model('res.company')
|
|
227
|
+
.browse([company])
|
|
228
|
+
.write({
|
|
229
|
+
fiscalYearStart: start,
|
|
230
|
+
numberGrouping: localization.grouping ?? 'international',
|
|
231
|
+
country: localization.country,
|
|
232
|
+
}));
|
|
233
|
+
let fiscalYear = null;
|
|
234
|
+
const years = await env.model('account.fiscal.year').search({ where: { company }, limit: 1 });
|
|
235
|
+
if (years.length === 0) {
|
|
236
|
+
const { dateFrom, dateTo } = fiscalYearOf(env.today(), start);
|
|
237
|
+
const [y, m] = dateFrom.split('-').map(Number);
|
|
238
|
+
fiscalYear = m === 1 ? String(y) : `${y}–${String(y + 1).slice(2)}`;
|
|
239
|
+
await env
|
|
240
|
+
.model('account.fiscal.year')
|
|
241
|
+
.create([{ name: fiscalYear, dateFrom, dateTo, company }]);
|
|
242
|
+
}
|
|
243
|
+
await env.flush(); // the checks run in the caller's scope, not at commit (Shutro request #11)
|
|
244
|
+
return { localization: localization.key, chart, taxes, withholdings, fiscalYear };
|
|
245
|
+
}
|
|
152
246
|
export class ChartInstalledError extends Error {
|
|
153
247
|
template;
|
|
154
248
|
constructor(template) {
|
|
@@ -18,13 +18,18 @@ export interface Settings {
|
|
|
18
18
|
readonly chartTemplate: string | null;
|
|
19
19
|
readonly lockDate: string | null;
|
|
20
20
|
readonly taxLockDate: string | null;
|
|
21
|
+
/** Where the company is registered (ISO 3166 / 3166-2): taxes split by place of supply compare against it. */
|
|
22
|
+
readonly country: string | null;
|
|
23
|
+
readonly state: string | null;
|
|
21
24
|
readonly accounts: Readonly<Record<string, number | null>>;
|
|
22
25
|
}
|
|
23
26
|
export declare function readSettings(env: Env): Promise<Settings>;
|
|
24
|
-
/** The lock dates (managers). */
|
|
27
|
+
/** The lock dates, the company's country and state (managers). */
|
|
25
28
|
export declare function updateSettings(env: Env, input: {
|
|
26
29
|
readonly lockDate?: string | null;
|
|
27
30
|
readonly taxLockDate?: string | null;
|
|
31
|
+
readonly country?: string | null;
|
|
32
|
+
readonly state?: string | null;
|
|
28
33
|
}): Promise<Settings>;
|
|
29
34
|
export interface AgingRow {
|
|
30
35
|
readonly partner: number | null;
|