@scell/sdk 1.2.0 → 1.4.0
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 +61 -2
- package/dist/index.d.mts +2318 -235
- package/dist/index.d.ts +2318 -235
- package/dist/index.js +1261 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1261 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +3 -1
- package/src/index.ts +17 -1
- package/src/resources/billing.ts +49 -0
- package/src/resources/fiscal.ts +128 -0
- package/src/resources/stats.ts +29 -0
- package/src/resources/sub-tenants.ts +41 -0
- package/src/resources/tenant-credit-notes.ts +301 -0
- package/src/resources/tenant-direct-credit-notes.ts +360 -0
- package/src/resources/tenant-direct-invoices.ts +424 -0
- package/src/resources/tenant-incoming-invoices.ts +429 -0
- package/src/tenant-client.ts +105 -0
- package/src/types/billing.ts +73 -0
- package/src/types/fiscal.ts +251 -0
- package/src/types/index.ts +103 -0
- package/src/types/stats.ts +37 -0
- package/src/types/sub-tenants.ts +57 -0
- package/src/types/tenant-credit-notes.ts +128 -0
- package/src/types/tenant-invoices.ts +390 -0
- package/src/types/tenant-profile.ts +51 -0
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { withRetry, type RetryOptions } from './utils/retry.js';
|
|
|
14
14
|
/**
|
|
15
15
|
* Authentication mode
|
|
16
16
|
*/
|
|
17
|
-
export type AuthMode = 'bearer' | 'api-key';
|
|
17
|
+
export type AuthMode = 'bearer' | 'api-key' | 'tenant-key';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Client configuration options
|
|
@@ -116,6 +116,8 @@ export class HttpClient {
|
|
|
116
116
|
|
|
117
117
|
if (this.authMode === 'bearer') {
|
|
118
118
|
headers['Authorization'] = `Bearer ${this.authToken}`;
|
|
119
|
+
} else if (this.authMode === 'tenant-key') {
|
|
120
|
+
headers['X-Tenant-Key'] = this.authToken;
|
|
119
121
|
} else {
|
|
120
122
|
headers['X-API-Key'] = this.authToken;
|
|
121
123
|
}
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```typescript
|
|
8
|
-
* import { ScellClient, ScellApiClient, ScellAuth, ScellWebhooks } from '@scell/sdk';
|
|
8
|
+
* import { ScellClient, ScellApiClient, ScellTenantClient, ScellAuth, ScellWebhooks } from '@scell/sdk';
|
|
9
9
|
*
|
|
10
10
|
* // Dashboard client (Bearer token)
|
|
11
11
|
* const auth = await ScellAuth.login({ email, password });
|
|
@@ -14,9 +14,15 @@
|
|
|
14
14
|
* // API client (X-API-Key)
|
|
15
15
|
* const apiClient = new ScellApiClient('your-api-key');
|
|
16
16
|
*
|
|
17
|
+
* // Tenant client (X-Tenant-Key) - for multi-tenant operations
|
|
18
|
+
* const tenantClient = new ScellTenantClient('your-tenant-key');
|
|
19
|
+
*
|
|
17
20
|
* // Create invoice
|
|
18
21
|
* const invoice = await apiClient.invoices.create({...});
|
|
19
22
|
*
|
|
23
|
+
* // Create direct invoice (tenant)
|
|
24
|
+
* const directInvoice = await tenantClient.directInvoices.create({...});
|
|
25
|
+
*
|
|
20
26
|
* // Verify webhook
|
|
21
27
|
* const isValid = await ScellWebhooks.verifySignature(payload, signature, secret);
|
|
22
28
|
* ```
|
|
@@ -25,6 +31,9 @@
|
|
|
25
31
|
// Client
|
|
26
32
|
import { HttpClient, type ClientConfig } from './client.js';
|
|
27
33
|
|
|
34
|
+
// Tenant Client
|
|
35
|
+
import { ScellTenantClient } from './tenant-client.js';
|
|
36
|
+
|
|
28
37
|
// Resources
|
|
29
38
|
import { ApiKeysResource } from './resources/api-keys.js';
|
|
30
39
|
import { AuthResource, ScellAuth } from './resources/auth.js';
|
|
@@ -32,6 +41,7 @@ import { BalanceResource } from './resources/balance.js';
|
|
|
32
41
|
import { CompaniesResource } from './resources/companies.js';
|
|
33
42
|
import { InvoicesResource } from './resources/invoices.js';
|
|
34
43
|
import { SignaturesResource } from './resources/signatures.js';
|
|
44
|
+
import { TenantCreditNotesResource } from './resources/tenant-credit-notes.js';
|
|
35
45
|
import { WebhooksResource } from './resources/webhooks.js';
|
|
36
46
|
|
|
37
47
|
// Utilities
|
|
@@ -143,6 +153,8 @@ export class ScellApiClient {
|
|
|
143
153
|
public readonly invoices: InvoicesResource;
|
|
144
154
|
/** Signature operations (create, download, remind, cancel) */
|
|
145
155
|
public readonly signatures: SignaturesResource;
|
|
156
|
+
/** Tenant credit notes operations (create, send, download) */
|
|
157
|
+
public readonly tenantCreditNotes: TenantCreditNotesResource;
|
|
146
158
|
|
|
147
159
|
/**
|
|
148
160
|
* Create a new Scell API Client
|
|
@@ -166,12 +178,16 @@ export class ScellApiClient {
|
|
|
166
178
|
|
|
167
179
|
this.invoices = new InvoicesResource(this.http);
|
|
168
180
|
this.signatures = new SignaturesResource(this.http);
|
|
181
|
+
this.tenantCreditNotes = new TenantCreditNotesResource(this.http);
|
|
169
182
|
}
|
|
170
183
|
}
|
|
171
184
|
|
|
172
185
|
// Re-export utilities
|
|
173
186
|
export { ScellAuth, ScellWebhooks, withRetry, createRetryWrapper };
|
|
174
187
|
|
|
188
|
+
// Re-export tenant client
|
|
189
|
+
export { ScellTenantClient };
|
|
190
|
+
|
|
175
191
|
// Re-export types
|
|
176
192
|
export type { ClientConfig } from './client.js';
|
|
177
193
|
export type { RetryOptions } from './utils/retry.js';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Billing Resource
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { HttpClient, RequestOptions } from '../client.js';
|
|
7
|
+
import type { MessageResponse, PaginatedResponse, SingleResponse } from '../types/common.js';
|
|
8
|
+
import type {
|
|
9
|
+
BillingInvoice,
|
|
10
|
+
BillingInvoiceListOptions,
|
|
11
|
+
BillingTopUpConfirmInput,
|
|
12
|
+
BillingTopUpInput,
|
|
13
|
+
BillingTransaction,
|
|
14
|
+
BillingTransactionListOptions,
|
|
15
|
+
BillingUsage,
|
|
16
|
+
BillingUsageOptions,
|
|
17
|
+
} from '../types/billing.js';
|
|
18
|
+
|
|
19
|
+
export class BillingResource {
|
|
20
|
+
constructor(private readonly http: HttpClient) {}
|
|
21
|
+
|
|
22
|
+
async invoices(options: BillingInvoiceListOptions = {}, requestOptions?: RequestOptions): Promise<PaginatedResponse<BillingInvoice>> {
|
|
23
|
+
return this.http.get<PaginatedResponse<BillingInvoice>>('/tenant/billing/invoices', options as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async showInvoice(invoiceId: string, requestOptions?: RequestOptions): Promise<SingleResponse<BillingInvoice>> {
|
|
27
|
+
return this.http.get<SingleResponse<BillingInvoice>>(`/tenant/billing/invoices/${invoiceId}`, undefined, requestOptions);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async downloadInvoice(invoiceId: string, requestOptions?: RequestOptions): Promise<ArrayBuffer> {
|
|
31
|
+
return this.http.getRaw(`/tenant/billing/invoices/${invoiceId}/download`, undefined, requestOptions);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async usage(options: BillingUsageOptions = {}, requestOptions?: RequestOptions): Promise<SingleResponse<BillingUsage>> {
|
|
35
|
+
return this.http.get<SingleResponse<BillingUsage>>('/tenant/billing/usage', options as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async topUp(input: BillingTopUpInput, requestOptions?: RequestOptions): Promise<MessageResponse> {
|
|
39
|
+
return this.http.post<MessageResponse>('/tenant/billing/top-up', input, requestOptions);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async confirmTopUp(input: BillingTopUpConfirmInput, requestOptions?: RequestOptions): Promise<MessageResponse> {
|
|
43
|
+
return this.http.post<MessageResponse>('/tenant/billing/top-up/confirm', input, requestOptions);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async transactions(options: BillingTransactionListOptions = {}, requestOptions?: RequestOptions): Promise<PaginatedResponse<BillingTransaction>> {
|
|
47
|
+
return this.http.get<PaginatedResponse<BillingTransaction>>('/tenant/billing/transactions', options as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fiscal Compliance Resource
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { HttpClient, RequestOptions } from '../client.js';
|
|
7
|
+
import type { MessageResponse, PaginatedResponse, SingleResponse } from '../types/common.js';
|
|
8
|
+
import type {
|
|
9
|
+
FiscalAnchor,
|
|
10
|
+
FiscalAnchorsOptions,
|
|
11
|
+
FiscalAttestation,
|
|
12
|
+
FiscalClosing,
|
|
13
|
+
FiscalClosingsOptions,
|
|
14
|
+
FiscalComplianceData,
|
|
15
|
+
FiscalCreateRuleInput,
|
|
16
|
+
FiscalDailyClosingInput,
|
|
17
|
+
FiscalEntriesOptions,
|
|
18
|
+
FiscalEntry,
|
|
19
|
+
FiscalExportRulesOptions,
|
|
20
|
+
FiscalFecExportOptions,
|
|
21
|
+
FiscalFecExportResult,
|
|
22
|
+
FiscalForensicExportOptions,
|
|
23
|
+
FiscalIntegrityHistoryOptions,
|
|
24
|
+
FiscalIntegrityOptions,
|
|
25
|
+
FiscalIntegrityReport,
|
|
26
|
+
FiscalKillSwitchActivateInput,
|
|
27
|
+
FiscalKillSwitchStatus,
|
|
28
|
+
FiscalReplayRulesInput,
|
|
29
|
+
FiscalRule,
|
|
30
|
+
FiscalRulesOptions,
|
|
31
|
+
FiscalUpdateRuleInput,
|
|
32
|
+
} from '../types/fiscal.js';
|
|
33
|
+
|
|
34
|
+
export class FiscalResource {
|
|
35
|
+
constructor(private readonly http: HttpClient) {}
|
|
36
|
+
|
|
37
|
+
async compliance(requestOptions?: RequestOptions): Promise<SingleResponse<FiscalComplianceData>> {
|
|
38
|
+
return this.http.get<SingleResponse<FiscalComplianceData>>('/tenant/fiscal/compliance', undefined, requestOptions);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async integrity(options: FiscalIntegrityOptions = {}, requestOptions?: RequestOptions): Promise<SingleResponse<FiscalIntegrityReport>> {
|
|
42
|
+
return this.http.get<SingleResponse<FiscalIntegrityReport>>('/tenant/fiscal/integrity', options as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async integrityHistory(options: FiscalIntegrityHistoryOptions = {}, requestOptions?: RequestOptions): Promise<PaginatedResponse<FiscalIntegrityReport>> {
|
|
46
|
+
return this.http.get<PaginatedResponse<FiscalIntegrityReport>>('/tenant/fiscal/integrity/history', options as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async integrityForDate(date: string, requestOptions?: RequestOptions): Promise<SingleResponse<FiscalIntegrityReport>> {
|
|
50
|
+
return this.http.get<SingleResponse<FiscalIntegrityReport>>(`/tenant/fiscal/integrity/${date}`, undefined, requestOptions);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async closings(options: FiscalClosingsOptions = {}, requestOptions?: RequestOptions): Promise<PaginatedResponse<FiscalClosing>> {
|
|
54
|
+
return this.http.get<PaginatedResponse<FiscalClosing>>('/tenant/fiscal/closings', options as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async performDailyClosing(input: FiscalDailyClosingInput = {}, requestOptions?: RequestOptions): Promise<MessageResponse> {
|
|
58
|
+
return this.http.post<MessageResponse>('/tenant/fiscal/closings/daily', input, requestOptions);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async fecExport(options: FiscalFecExportOptions, requestOptions?: RequestOptions): Promise<SingleResponse<FiscalFecExportResult>> {
|
|
62
|
+
return this.http.get<SingleResponse<FiscalFecExportResult>>('/tenant/fiscal/fec', options as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async fecDownload(options: FiscalFecExportOptions, requestOptions?: RequestOptions): Promise<ArrayBuffer> {
|
|
66
|
+
return this.http.getRaw('/tenant/fiscal/fec', { ...options, download: true } as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async attestation(year: number, requestOptions?: RequestOptions): Promise<SingleResponse<FiscalAttestation>> {
|
|
70
|
+
return this.http.get<SingleResponse<FiscalAttestation>>(`/tenant/fiscal/attestation/${year}`, undefined, requestOptions);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async attestationDownload(year: number, requestOptions?: RequestOptions): Promise<ArrayBuffer> {
|
|
74
|
+
return this.http.getRaw(`/tenant/fiscal/attestation/${year}/download`, undefined, requestOptions);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async entries(options: FiscalEntriesOptions = {}, requestOptions?: RequestOptions): Promise<PaginatedResponse<FiscalEntry>> {
|
|
78
|
+
return this.http.get<PaginatedResponse<FiscalEntry>>('/tenant/fiscal/entries', options as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async killSwitchStatus(requestOptions?: RequestOptions): Promise<SingleResponse<FiscalKillSwitchStatus>> {
|
|
82
|
+
return this.http.get<SingleResponse<FiscalKillSwitchStatus>>('/tenant/fiscal/kill-switch/status', undefined, requestOptions);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async killSwitchActivate(input: FiscalKillSwitchActivateInput, requestOptions?: RequestOptions): Promise<MessageResponse> {
|
|
86
|
+
return this.http.post<MessageResponse>('/tenant/fiscal/kill-switch/activate', input, requestOptions);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async killSwitchDeactivate(requestOptions?: RequestOptions): Promise<MessageResponse> {
|
|
90
|
+
return this.http.post<MessageResponse>('/tenant/fiscal/kill-switch/deactivate', undefined, requestOptions);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async anchors(options: FiscalAnchorsOptions = {}, requestOptions?: RequestOptions): Promise<PaginatedResponse<FiscalAnchor>> {
|
|
94
|
+
return this.http.get<PaginatedResponse<FiscalAnchor>>('/tenant/fiscal/anchors', options as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async rules(options: FiscalRulesOptions = {}, requestOptions?: RequestOptions): Promise<PaginatedResponse<FiscalRule>> {
|
|
98
|
+
return this.http.get<PaginatedResponse<FiscalRule>>('/tenant/fiscal/rules', options as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async ruleDetail(key: string, requestOptions?: RequestOptions): Promise<SingleResponse<FiscalRule>> {
|
|
102
|
+
return this.http.get<SingleResponse<FiscalRule>>(`/tenant/fiscal/rules/${key}`, undefined, requestOptions);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async ruleHistory(key: string, requestOptions?: RequestOptions): Promise<PaginatedResponse<FiscalRule>> {
|
|
106
|
+
return this.http.get<PaginatedResponse<FiscalRule>>(`/tenant/fiscal/rules/${key}/history`, undefined, requestOptions);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async createRule(input: FiscalCreateRuleInput, requestOptions?: RequestOptions): Promise<SingleResponse<FiscalRule>> {
|
|
110
|
+
return this.http.post<SingleResponse<FiscalRule>>('/tenant/fiscal/rules', input, requestOptions);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async updateRule(id: string, input: FiscalUpdateRuleInput, requestOptions?: RequestOptions): Promise<SingleResponse<FiscalRule>> {
|
|
114
|
+
return this.http.post<SingleResponse<FiscalRule>>(`/tenant/fiscal/rules/${id}`, input, requestOptions);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async exportRules(options: FiscalExportRulesOptions, requestOptions?: RequestOptions): Promise<SingleResponse<Record<string, unknown>>> {
|
|
118
|
+
return this.http.get<SingleResponse<Record<string, unknown>>>('/tenant/fiscal/rules/export', options as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async replayRules(input: FiscalReplayRulesInput, requestOptions?: RequestOptions): Promise<MessageResponse> {
|
|
122
|
+
return this.http.post<MessageResponse>('/tenant/fiscal/rules/replay', input, requestOptions);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async forensicExport(options: FiscalForensicExportOptions, requestOptions?: RequestOptions): Promise<SingleResponse<Record<string, unknown>>> {
|
|
126
|
+
return this.http.get<SingleResponse<Record<string, unknown>>>('/tenant/fiscal/forensic-export', options as unknown as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stats Resource
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { HttpClient, RequestOptions } from '../client.js';
|
|
7
|
+
import type { SingleResponse } from '../types/common.js';
|
|
8
|
+
import type {
|
|
9
|
+
StatsMonthly,
|
|
10
|
+
StatsMonthlyOptions,
|
|
11
|
+
StatsOverview,
|
|
12
|
+
StatsOverviewOptions,
|
|
13
|
+
} from '../types/stats.js';
|
|
14
|
+
|
|
15
|
+
export class StatsResource {
|
|
16
|
+
constructor(private readonly http: HttpClient) {}
|
|
17
|
+
|
|
18
|
+
async overview(options: StatsOverviewOptions = {}, requestOptions?: RequestOptions): Promise<SingleResponse<StatsOverview>> {
|
|
19
|
+
return this.http.get<SingleResponse<StatsOverview>>('/tenant/stats/overview', options as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async monthly(options: StatsMonthlyOptions = {}, requestOptions?: RequestOptions): Promise<SingleResponse<StatsMonthly[]>> {
|
|
23
|
+
return this.http.get<SingleResponse<StatsMonthly[]>>('/tenant/stats/monthly', options as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async subTenantOverview(subTenantId: string, options: StatsOverviewOptions = {}, requestOptions?: RequestOptions): Promise<SingleResponse<StatsOverview>> {
|
|
27
|
+
return this.http.get<SingleResponse<StatsOverview>>(`/tenant/sub-tenants/${subTenantId}/stats/overview`, options as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sub-Tenants Resource
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { HttpClient, RequestOptions } from '../client.js';
|
|
7
|
+
import type { MessageResponse, PaginatedResponse, SingleResponse } from '../types/common.js';
|
|
8
|
+
import type {
|
|
9
|
+
CreateSubTenantInput,
|
|
10
|
+
SubTenant,
|
|
11
|
+
SubTenantListOptions,
|
|
12
|
+
UpdateSubTenantInput,
|
|
13
|
+
} from '../types/sub-tenants.js';
|
|
14
|
+
|
|
15
|
+
export class SubTenantsResource {
|
|
16
|
+
constructor(private readonly http: HttpClient) {}
|
|
17
|
+
|
|
18
|
+
async list(options: SubTenantListOptions = {}, requestOptions?: RequestOptions): Promise<PaginatedResponse<SubTenant>> {
|
|
19
|
+
return this.http.get<PaginatedResponse<SubTenant>>('/tenant/sub-tenants', options as Record<string, string | number | boolean | undefined>, requestOptions);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async create(input: CreateSubTenantInput, requestOptions?: RequestOptions): Promise<SingleResponse<SubTenant>> {
|
|
23
|
+
return this.http.post<SingleResponse<SubTenant>>('/tenant/sub-tenants', input, requestOptions);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async get(id: string, requestOptions?: RequestOptions): Promise<SingleResponse<SubTenant>> {
|
|
27
|
+
return this.http.get<SingleResponse<SubTenant>>(`/tenant/sub-tenants/${id}`, undefined, requestOptions);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async update(id: string, input: UpdateSubTenantInput, requestOptions?: RequestOptions): Promise<SingleResponse<SubTenant>> {
|
|
31
|
+
return this.http.patch<SingleResponse<SubTenant>>(`/tenant/sub-tenants/${id}`, input, requestOptions);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async delete(id: string, requestOptions?: RequestOptions): Promise<MessageResponse> {
|
|
35
|
+
return this.http.delete<MessageResponse>(`/tenant/sub-tenants/${id}`, requestOptions);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async findByExternalId(externalId: string, requestOptions?: RequestOptions): Promise<SingleResponse<SubTenant>> {
|
|
39
|
+
return this.http.get<SingleResponse<SubTenant>>(`/tenant/sub-tenants/by-external-id/${externalId}`, undefined, requestOptions);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tenant Credit Notes Resource
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { HttpClient, RequestOptions } from '../client.js';
|
|
8
|
+
import type {
|
|
9
|
+
MessageResponse,
|
|
10
|
+
PaginatedResponse,
|
|
11
|
+
SingleResponse,
|
|
12
|
+
} from '../types/common.js';
|
|
13
|
+
import type {
|
|
14
|
+
CreateTenantCreditNoteInput,
|
|
15
|
+
RemainingCreditable,
|
|
16
|
+
TenantCreditNote,
|
|
17
|
+
TenantCreditNoteListOptions,
|
|
18
|
+
UpdateTenantCreditNoteInput,
|
|
19
|
+
} from '../types/tenant-credit-notes.js';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Tenant Credit Notes API resource
|
|
23
|
+
*
|
|
24
|
+
* Manage credit notes for sub-tenant invoices.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // List credit notes for a sub-tenant
|
|
29
|
+
* const { data, meta } = await client.tenantCreditNotes.list('sub-tenant-uuid', {
|
|
30
|
+
* status: 'sent'
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* // Create a credit note
|
|
34
|
+
* const creditNote = await client.tenantCreditNotes.create('sub-tenant-uuid', {
|
|
35
|
+
* invoice_id: 'invoice-uuid',
|
|
36
|
+
* reason: 'Product returned',
|
|
37
|
+
* type: 'partial',
|
|
38
|
+
* items: [{ invoice_line_id: 'line-uuid', quantity: 1 }]
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export class TenantCreditNotesResource {
|
|
43
|
+
constructor(private readonly http: HttpClient) {}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* List credit notes for a sub-tenant
|
|
47
|
+
*
|
|
48
|
+
* @param subTenantId - Sub-tenant UUID
|
|
49
|
+
* @param options - Filter and pagination options
|
|
50
|
+
* @param requestOptions - Request options
|
|
51
|
+
* @returns Paginated list of credit notes
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const { data, meta } = await client.tenantCreditNotes.list('sub-tenant-uuid', {
|
|
56
|
+
* status: 'sent',
|
|
57
|
+
* date_from: '2024-01-01',
|
|
58
|
+
* per_page: 50
|
|
59
|
+
* });
|
|
60
|
+
* console.log(`Found ${meta.total} credit notes`);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
async list(
|
|
64
|
+
subTenantId: string,
|
|
65
|
+
options: TenantCreditNoteListOptions = {},
|
|
66
|
+
requestOptions?: RequestOptions
|
|
67
|
+
): Promise<PaginatedResponse<TenantCreditNote>> {
|
|
68
|
+
return this.http.get<PaginatedResponse<TenantCreditNote>>(
|
|
69
|
+
`/tenant/sub-tenants/${subTenantId}/credit-notes`,
|
|
70
|
+
options as Record<string, string | number | boolean | undefined>,
|
|
71
|
+
requestOptions
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Create a new credit note for a sub-tenant invoice
|
|
77
|
+
*
|
|
78
|
+
* @param subTenantId - Sub-tenant UUID
|
|
79
|
+
* @param input - Credit note creation data
|
|
80
|
+
* @param requestOptions - Request options
|
|
81
|
+
* @returns Created credit note
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* // Create a partial credit note
|
|
86
|
+
* const { data: creditNote } = await client.tenantCreditNotes.create(
|
|
87
|
+
* 'sub-tenant-uuid',
|
|
88
|
+
* {
|
|
89
|
+
* invoice_id: 'invoice-uuid',
|
|
90
|
+
* reason: 'Product returned - damaged item',
|
|
91
|
+
* type: 'partial',
|
|
92
|
+
* items: [
|
|
93
|
+
* { invoice_line_id: 'line-uuid-1', quantity: 2 }
|
|
94
|
+
* ]
|
|
95
|
+
* }
|
|
96
|
+
* );
|
|
97
|
+
*
|
|
98
|
+
* // Create a total credit note
|
|
99
|
+
* const { data: totalCreditNote } = await client.tenantCreditNotes.create(
|
|
100
|
+
* 'sub-tenant-uuid',
|
|
101
|
+
* {
|
|
102
|
+
* invoice_id: 'invoice-uuid',
|
|
103
|
+
* reason: 'Order cancelled',
|
|
104
|
+
* type: 'total'
|
|
105
|
+
* }
|
|
106
|
+
* );
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
async create(
|
|
110
|
+
subTenantId: string,
|
|
111
|
+
input: CreateTenantCreditNoteInput,
|
|
112
|
+
requestOptions?: RequestOptions
|
|
113
|
+
): Promise<SingleResponse<TenantCreditNote>> {
|
|
114
|
+
return this.http.post<SingleResponse<TenantCreditNote>>(
|
|
115
|
+
`/tenant/sub-tenants/${subTenantId}/credit-notes`,
|
|
116
|
+
input,
|
|
117
|
+
requestOptions
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get a specific credit note by ID
|
|
123
|
+
*
|
|
124
|
+
* @param creditNoteId - Credit note UUID
|
|
125
|
+
* @param requestOptions - Request options
|
|
126
|
+
* @returns Credit note details
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const { data: creditNote } = await client.tenantCreditNotes.get('credit-note-uuid');
|
|
131
|
+
* console.log('Credit note number:', creditNote.credit_note_number);
|
|
132
|
+
* console.log('Total:', creditNote.total, creditNote.currency);
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
async get(
|
|
136
|
+
creditNoteId: string,
|
|
137
|
+
requestOptions?: RequestOptions
|
|
138
|
+
): Promise<SingleResponse<TenantCreditNote>> {
|
|
139
|
+
return this.http.get<SingleResponse<TenantCreditNote>>(
|
|
140
|
+
`/tenant/credit-notes/${creditNoteId}`,
|
|
141
|
+
undefined,
|
|
142
|
+
requestOptions
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Update a credit note
|
|
148
|
+
*
|
|
149
|
+
* Only credit notes in 'draft' status can be updated.
|
|
150
|
+
*
|
|
151
|
+
* @param creditNoteId - Credit note UUID
|
|
152
|
+
* @param input - Update data
|
|
153
|
+
* @param requestOptions - Request options
|
|
154
|
+
* @returns Updated credit note
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* const { data: creditNote } = await client.tenantCreditNotes.update(
|
|
159
|
+
* 'credit-note-uuid',
|
|
160
|
+
* {
|
|
161
|
+
* reason: 'Updated reason: Customer complaint resolved',
|
|
162
|
+
* items: [
|
|
163
|
+
* { invoice_line_id: 'line-uuid', quantity: 3 }
|
|
164
|
+
* ]
|
|
165
|
+
* }
|
|
166
|
+
* );
|
|
167
|
+
* console.log('Credit note updated:', creditNote.reason);
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
async update(
|
|
171
|
+
creditNoteId: string,
|
|
172
|
+
input: UpdateTenantCreditNoteInput,
|
|
173
|
+
requestOptions?: RequestOptions
|
|
174
|
+
): Promise<SingleResponse<TenantCreditNote>> {
|
|
175
|
+
return this.http.patch<SingleResponse<TenantCreditNote>>(
|
|
176
|
+
`/tenant/credit-notes/${creditNoteId}`,
|
|
177
|
+
input,
|
|
178
|
+
requestOptions
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Send a credit note
|
|
184
|
+
*
|
|
185
|
+
* Changes the status from 'draft' to 'sent'.
|
|
186
|
+
*
|
|
187
|
+
* @param creditNoteId - Credit note UUID
|
|
188
|
+
* @param requestOptions - Request options
|
|
189
|
+
* @returns Updated credit note
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const { data: sentCreditNote } = await client.tenantCreditNotes.send('credit-note-uuid');
|
|
194
|
+
* console.log('Status:', sentCreditNote.status); // 'sent'
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
async send(
|
|
198
|
+
creditNoteId: string,
|
|
199
|
+
requestOptions?: RequestOptions
|
|
200
|
+
): Promise<SingleResponse<TenantCreditNote>> {
|
|
201
|
+
return this.http.post<SingleResponse<TenantCreditNote>>(
|
|
202
|
+
`/tenant/credit-notes/${creditNoteId}/send`,
|
|
203
|
+
undefined,
|
|
204
|
+
requestOptions
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Delete a credit note (draft only)
|
|
210
|
+
*
|
|
211
|
+
* Only credit notes with status 'draft' can be deleted.
|
|
212
|
+
*
|
|
213
|
+
* @param creditNoteId - Credit note UUID
|
|
214
|
+
* @param requestOptions - Request options
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```typescript
|
|
218
|
+
* await client.tenantCreditNotes.delete('credit-note-uuid');
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
async delete(
|
|
222
|
+
creditNoteId: string,
|
|
223
|
+
requestOptions?: RequestOptions
|
|
224
|
+
): Promise<MessageResponse> {
|
|
225
|
+
return this.http.delete<MessageResponse>(
|
|
226
|
+
`/tenant/credit-notes/${creditNoteId}`,
|
|
227
|
+
requestOptions
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Download credit note as PDF
|
|
233
|
+
*
|
|
234
|
+
* @param creditNoteId - Credit note UUID
|
|
235
|
+
* @param requestOptions - Request options
|
|
236
|
+
* @returns ArrayBuffer containing the PDF file
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* // Download credit note PDF
|
|
241
|
+
* const pdfBuffer = await client.tenantCreditNotes.download('credit-note-uuid');
|
|
242
|
+
*
|
|
243
|
+
* // In Node.js, save to file:
|
|
244
|
+
* import { writeFileSync } from 'fs';
|
|
245
|
+
* writeFileSync('credit-note.pdf', Buffer.from(pdfBuffer));
|
|
246
|
+
*
|
|
247
|
+
* // In browser, trigger download:
|
|
248
|
+
* const blob = new Blob([pdfBuffer], { type: 'application/pdf' });
|
|
249
|
+
* const url = URL.createObjectURL(blob);
|
|
250
|
+
* const a = document.createElement('a');
|
|
251
|
+
* a.href = url;
|
|
252
|
+
* a.download = 'credit-note.pdf';
|
|
253
|
+
* a.click();
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
256
|
+
async download(
|
|
257
|
+
creditNoteId: string,
|
|
258
|
+
requestOptions?: RequestOptions
|
|
259
|
+
): Promise<ArrayBuffer> {
|
|
260
|
+
return this.http.getRaw(
|
|
261
|
+
`/tenant/credit-notes/${creditNoteId}/download`,
|
|
262
|
+
undefined,
|
|
263
|
+
requestOptions
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Get remaining creditable amount for an invoice
|
|
269
|
+
*
|
|
270
|
+
* Returns information about how much can still be credited for an invoice,
|
|
271
|
+
* including per-line breakdown.
|
|
272
|
+
*
|
|
273
|
+
* @param invoiceId - Invoice UUID
|
|
274
|
+
* @param requestOptions - Request options
|
|
275
|
+
* @returns Remaining creditable information
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* const remaining = await client.tenantCreditNotes.remainingCreditable('invoice-uuid');
|
|
280
|
+
*
|
|
281
|
+
* console.log('Invoice total:', remaining.invoice_total);
|
|
282
|
+
* console.log('Already credited:', remaining.credited_total);
|
|
283
|
+
* console.log('Remaining to credit:', remaining.remaining_total);
|
|
284
|
+
*
|
|
285
|
+
* // Check remaining quantity per line
|
|
286
|
+
* remaining.lines.forEach(line => {
|
|
287
|
+
* console.log(`${line.description}: ${line.remaining_quantity} remaining`);
|
|
288
|
+
* });
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
async remainingCreditable(
|
|
292
|
+
invoiceId: string,
|
|
293
|
+
requestOptions?: RequestOptions
|
|
294
|
+
): Promise<RemainingCreditable> {
|
|
295
|
+
return this.http.get<RemainingCreditable>(
|
|
296
|
+
`/tenant/invoices/${invoiceId}/remaining-creditable`,
|
|
297
|
+
undefined,
|
|
298
|
+
requestOptions
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
}
|