zata-vsdc-sdk 1.0.3 → 1.1.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 +64 -815
- package/dist/index.d.ts +118 -0
- package/dist/index.js +240 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,859 +1,108 @@
|
|
|
1
1
|
# zata-vsdc-sdk
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/zata-vsdc-sdk)
|
|
4
|
-
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://www.typescriptlang.org/)
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
TypeScript SDK for the Zata API, aligned with the latest OpenAPI documentation.
|
|
8
6
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
- ✅ **Full TypeScript Support** – Complete type definitions for all API resources
|
|
12
|
-
- ✅ **Lightweight & Fast** – Minimal dependencies, optimized for performance
|
|
13
|
-
- ✅ **Comprehensive Coverage** – Support for all Zata API endpoints
|
|
14
|
-
- ✅ **Error Handling** – Built-in error interceptors with detailed error messages
|
|
15
|
-
- ✅ **Promise-Based** – Modern async/await API
|
|
16
|
-
- ✅ **Well Documented** – Extensive JSDoc comments and examples
|
|
17
|
-
- ✅ **Open Source** – Community-driven development
|
|
18
|
-
|
|
19
|
-
## 📚 Resources
|
|
20
|
-
|
|
21
|
-
- **Official Website**: [https://zata.rw](https://zata.rw)
|
|
22
|
-
- **API Documentation**: [https://docs.zata.rw](https://docs.zata.rw)
|
|
23
|
-
- **Installation Guide**: [https://zata.lovable.app](https://zata.lovable.app)
|
|
24
|
-
- **npm Package**: [zata-vsdc-sdk on npm](https://www.npmjs.com/package/zata-vsdc-sdk)
|
|
25
|
-
- **GitHub Repository**: [HiQ-Africa/zata-npm](https://github.com/HiQ-Africa/zata-npm)
|
|
26
|
-
|
|
27
|
-
## 📦 Installation
|
|
7
|
+
## Installation
|
|
28
8
|
|
|
29
9
|
```bash
|
|
30
10
|
npm install zata-vsdc-sdk
|
|
31
11
|
```
|
|
32
12
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
yarn add zata-vsdc-sdk
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Or with pnpm:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
pnpm add zata-vsdc-sdk
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## 🚀 Quick Start
|
|
46
|
-
|
|
47
|
-
### TypeScript/ES Modules
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
import { ZataClient } from 'zata-vsdc-sdk';
|
|
51
|
-
|
|
52
|
-
// Initialize the client
|
|
53
|
-
const client = new ZataClient({
|
|
54
|
-
apiKey: 'your-api-key-here',
|
|
55
|
-
baseUrl: 'https://api.zata.rw/v1', // Optional, defaults to production
|
|
56
|
-
timeout: 30000 // Optional, defaults to 30000ms
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Example: Get all companies
|
|
60
|
-
async function example() {
|
|
61
|
-
try {
|
|
62
|
-
const companies = await client.getCompanies();
|
|
63
|
-
console.log('Companies:', companies);
|
|
64
|
-
} catch (error) {
|
|
65
|
-
console.error('Error:', error.message);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### JavaScript/CommonJS
|
|
13
|
+
## Initialize Client
|
|
71
14
|
|
|
72
|
-
```
|
|
73
|
-
|
|
15
|
+
```ts
|
|
16
|
+
import { ZataClient } from "zata-vsdc-sdk";
|
|
74
17
|
|
|
75
18
|
const client = new ZataClient({
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
client.getCompanies().then(companies => {
|
|
81
|
-
console.log('Companies:', companies);
|
|
82
|
-
}).catch(error => {
|
|
83
|
-
console.error('Error:', error.message);
|
|
19
|
+
token: process.env.ZATA_TOKEN,
|
|
20
|
+
companyId: 1,
|
|
21
|
+
branchId: 1,
|
|
22
|
+
baseUrl: "https://api.zata.rw",
|
|
84
23
|
});
|
|
85
24
|
```
|
|
86
25
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
### Initialization
|
|
90
|
-
|
|
91
|
-
#### `new ZataClient(options: ZataClientOptions)`
|
|
92
|
-
|
|
93
|
-
Creates a new Zata API client instance.
|
|
94
|
-
|
|
95
|
-
**Parameters:**
|
|
96
|
-
- `options.apiKey` (string, required) – Your Zata API key
|
|
97
|
-
- `options.baseUrl` (string, optional) – API base URL (default: `'https://api.zata.rw/v1'`)
|
|
98
|
-
- `options.timeout` (number, optional) – Request timeout in milliseconds (default: `30000`)
|
|
99
|
-
|
|
100
|
-
**Example:**
|
|
101
|
-
```typescript
|
|
102
|
-
const client = new ZataClient({
|
|
103
|
-
apiKey: process.env.ZATA_API_KEY!,
|
|
104
|
-
baseUrl: 'https://api.zata.rw/v1',
|
|
105
|
-
timeout: 30000
|
|
106
|
-
});
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
### Companies
|
|
112
|
-
|
|
113
|
-
Manage company information and settings.
|
|
114
|
-
|
|
115
|
-
#### `getCompanies(): Promise<Company[]>`
|
|
116
|
-
|
|
117
|
-
Retrieves a list of all companies.
|
|
118
|
-
|
|
119
|
-
**Returns:** Promise resolving to an array of `Company` objects.
|
|
120
|
-
|
|
121
|
-
**Example:**
|
|
122
|
-
```typescript
|
|
123
|
-
const companies = await client.getCompanies();
|
|
124
|
-
console.log(`Found ${companies.length} companies`);
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
#### `getCompany(id: string): Promise<Company>`
|
|
128
|
-
|
|
129
|
-
Retrieves a specific company by ID.
|
|
130
|
-
|
|
131
|
-
**Parameters:**
|
|
132
|
-
- `id` (string) – Company ID
|
|
133
|
-
|
|
134
|
-
**Returns:** Promise resolving to a `Company` object.
|
|
135
|
-
|
|
136
|
-
**Example:**
|
|
137
|
-
```typescript
|
|
138
|
-
const company = await client.getCompany('comp-123');
|
|
139
|
-
console.log('Company:', company.name);
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
#### `createCompany(data: Partial<Company>): Promise<Company>`
|
|
143
|
-
|
|
144
|
-
Creates a new company.
|
|
145
|
-
|
|
146
|
-
**Parameters:**
|
|
147
|
-
- `data` (Partial<Company>) – Company data including:
|
|
148
|
-
- `name` (string, required) – Company name
|
|
149
|
-
- `tin` (string, required) – Tax Identification Number (9 digits)
|
|
150
|
-
- `address` (string, optional) – Company address
|
|
151
|
-
|
|
152
|
-
**Returns:** Promise resolving to the created `Company` object.
|
|
153
|
-
|
|
154
|
-
**Example:**
|
|
155
|
-
```typescript
|
|
156
|
-
const newCompany = await client.createCompany({
|
|
157
|
-
name: 'Acme Corporation',
|
|
158
|
-
tin: '123456789',
|
|
159
|
-
address: 'Kigali, Rwanda'
|
|
160
|
-
});
|
|
161
|
-
console.log('Created company:', newCompany.id);
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
#### `updateCompany(id: string, data: Partial<Company>): Promise<Company>`
|
|
165
|
-
|
|
166
|
-
Updates an existing company.
|
|
167
|
-
|
|
168
|
-
**Parameters:**
|
|
169
|
-
- `id` (string) – Company ID
|
|
170
|
-
- `data` (Partial<Company>) – Updated company data
|
|
171
|
-
|
|
172
|
-
**Returns:** Promise resolving to the updated `Company` object.
|
|
173
|
-
|
|
174
|
-
**Example:**
|
|
175
|
-
```typescript
|
|
176
|
-
const updated = await client.updateCompany('comp-123', {
|
|
177
|
-
address: 'New Address, Kigali'
|
|
178
|
-
});
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
#### `deleteCompany(id: string): Promise<{ success: boolean; message?: string }>`
|
|
182
|
-
|
|
183
|
-
Deletes a company by ID.
|
|
184
|
-
|
|
185
|
-
**Parameters:**
|
|
186
|
-
- `id` (string) – Company ID
|
|
187
|
-
|
|
188
|
-
**Returns:** Promise resolving to a deletion confirmation object.
|
|
189
|
-
|
|
190
|
-
**Example:**
|
|
191
|
-
```typescript
|
|
192
|
-
const result = await client.deleteCompany('comp-123');
|
|
193
|
-
if (result.success) {
|
|
194
|
-
console.log('Company deleted successfully');
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
---
|
|
199
|
-
|
|
200
|
-
### Branches
|
|
201
|
-
|
|
202
|
-
Manage branch locations for your company.
|
|
26
|
+
`apiKey` is still accepted as an alias for `token`.
|
|
203
27
|
|
|
204
|
-
|
|
28
|
+
## Quick Start
|
|
205
29
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
```typescript
|
|
212
|
-
const branches = await client.getBranches();
|
|
213
|
-
branches.forEach(branch => {
|
|
214
|
-
console.log(`${branch.name} (${branch.id})`);
|
|
30
|
+
```ts
|
|
31
|
+
// 1) Login (if you do not have a token yet)
|
|
32
|
+
const auth = await client.login({
|
|
33
|
+
email: "user@example.com",
|
|
34
|
+
password: "your-password",
|
|
215
35
|
});
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
#### `getBranch(id: string): Promise<Branch>`
|
|
219
|
-
|
|
220
|
-
Retrieves a specific branch by ID.
|
|
221
|
-
|
|
222
|
-
**Parameters:**
|
|
223
|
-
- `id` (string) – Branch ID
|
|
224
|
-
|
|
225
|
-
**Returns:** Promise resolving to a `Branch` object.
|
|
226
|
-
|
|
227
|
-
**Example:**
|
|
228
|
-
```typescript
|
|
229
|
-
const branch = await client.getBranch('branch-123');
|
|
230
|
-
```
|
|
231
36
|
|
|
232
|
-
|
|
37
|
+
// 2) Reference data
|
|
38
|
+
const paymentModes = await client.getPaymentModes();
|
|
39
|
+
const productTaxes = await client.getProductTaxes();
|
|
233
40
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
**Example:**
|
|
244
|
-
```typescript
|
|
245
|
-
const newBranch = await client.createBranch({
|
|
246
|
-
name: 'Kicukiro Branch',
|
|
247
|
-
companyId: 'comp-123'
|
|
41
|
+
// 3) Create parties/products
|
|
42
|
+
await client.createCustomer({
|
|
43
|
+
name: "John Doe",
|
|
44
|
+
phone: "0780000000",
|
|
45
|
+
email: "john@example.com",
|
|
46
|
+
tin: "123456789",
|
|
47
|
+
address: "Kigali",
|
|
48
|
+
hasInsurance: "no",
|
|
248
49
|
});
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
#### `updateBranch(id: string, data: Partial<Branch>): Promise<Branch>`
|
|
252
|
-
|
|
253
|
-
Updates an existing branch.
|
|
254
|
-
|
|
255
|
-
**Parameters:**
|
|
256
|
-
- `id` (string) – Branch ID
|
|
257
|
-
- `data` (Partial<Branch>) – Updated branch data
|
|
258
|
-
|
|
259
|
-
**Returns:** Promise resolving to the updated `Branch` object.
|
|
260
50
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
|
-
### Products
|
|
273
|
-
|
|
274
|
-
Manage your product catalog.
|
|
275
|
-
|
|
276
|
-
#### `getProducts(): Promise<Product[]>`
|
|
277
|
-
|
|
278
|
-
Retrieves a list of all products.
|
|
279
|
-
|
|
280
|
-
**Returns:** Promise resolving to an array of `Product` objects.
|
|
281
|
-
|
|
282
|
-
**Example:**
|
|
283
|
-
```typescript
|
|
284
|
-
const products = await client.getProducts();
|
|
285
|
-
console.log(`Total products: ${products.length}`);
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
#### `getProduct(id: string): Promise<Product>`
|
|
289
|
-
|
|
290
|
-
Retrieves a specific product by ID.
|
|
291
|
-
|
|
292
|
-
**Parameters:**
|
|
293
|
-
- `id` (string) – Product ID
|
|
294
|
-
|
|
295
|
-
**Returns:** Promise resolving to a `Product` object.
|
|
296
|
-
|
|
297
|
-
**Example:**
|
|
298
|
-
```typescript
|
|
299
|
-
const product = await client.getProduct('prod-123');
|
|
300
|
-
console.log(`${product.name} - ${product.price} RWF`);
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
#### `createProduct(data: Partial<Product>): Promise<Product>`
|
|
304
|
-
|
|
305
|
-
Creates a new product.
|
|
306
|
-
|
|
307
|
-
**Parameters:**
|
|
308
|
-
- `data` (Partial<Product>) – Product data including:
|
|
309
|
-
- `name` (string, required) – Product name
|
|
310
|
-
- `code` (string, optional) – Product code/SKU
|
|
311
|
-
- `price` (number, optional) – Product price
|
|
312
|
-
- `unit` (string, optional) – Unit of measurement
|
|
313
|
-
|
|
314
|
-
**Returns:** Promise resolving to the created `Product` object.
|
|
315
|
-
|
|
316
|
-
**Example:**
|
|
317
|
-
```typescript
|
|
318
|
-
const newProduct = await client.createProduct({
|
|
319
|
-
name: 'Premium Coffee',
|
|
320
|
-
code: 'COFFEE-001',
|
|
321
|
-
price: 5000,
|
|
322
|
-
unit: 'kg'
|
|
51
|
+
await client.createProduct({
|
|
52
|
+
name: "Service Item",
|
|
53
|
+
packagingUnitID: 1,
|
|
54
|
+
quantityUnitID: 1,
|
|
55
|
+
countryID: 1,
|
|
56
|
+
taxID: 1,
|
|
57
|
+
branchProductCategoryID: 1,
|
|
58
|
+
hasStock: "yes",
|
|
323
59
|
});
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
#### `updateProduct(id: string, data: Partial<Product>): Promise<Product>`
|
|
327
|
-
|
|
328
|
-
Updates an existing product.
|
|
329
|
-
|
|
330
|
-
**Parameters:**
|
|
331
|
-
- `id` (string) – Product ID
|
|
332
|
-
- `data` (Partial<Product>) – Updated product data
|
|
333
60
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
price: 5500 // Update price
|
|
61
|
+
// 4) Create sale transaction
|
|
62
|
+
await client.createSaleTransaction({
|
|
63
|
+
paymentMethodID: 1,
|
|
64
|
+
transactionDate: "2026-01-01",
|
|
65
|
+
items: [{ productID: 1, units: 1, unitPrice: 1000, discountRate: 0 }],
|
|
340
66
|
});
|
|
341
67
|
```
|
|
342
68
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
Deletes a product by ID.
|
|
346
|
-
|
|
347
|
-
**Parameters:**
|
|
348
|
-
- `id` (string) – Product ID
|
|
349
|
-
|
|
350
|
-
**Returns:** Promise resolving to a deletion confirmation object.
|
|
69
|
+
## API Coverage
|
|
351
70
|
|
|
352
|
-
|
|
71
|
+
The SDK exposes methods for all paths in the current OpenAPI spec, including:
|
|
353
72
|
|
|
354
|
-
|
|
73
|
+
- Auth and account: `login`, `createAccount`
|
|
74
|
+
- Company and branches: `listCompanies`, `getCompany`, `createCompany`, `updateCompany`, `listCompanyBranches`, `createCompanyBranch`, `updateCompanyBranch`, `getCompanyFinance`, `getCompanyTaxInfo`
|
|
75
|
+
- Reference data: `getPaymentModes`, `getProductCategories`, `getProductClasses`, `getProductCountryOrigins`, `getProductPackagingUnits`, `getProductQuantityUnits`, `getProductTaxes`, `getProductTypes`
|
|
76
|
+
- Parties: `listParties`, `createCustomer`, `createSupplier`
|
|
77
|
+
- Product: `createProduct`, `listBranchProducts`, `getProduct`, `updateProduct`, `increaseProductQuantity`, `reduceProductQuantity`
|
|
78
|
+
- Expense: `listExpenses`, `createExpense`, `getExpenseCategories`
|
|
79
|
+
- Insurance: `listInsurances`, `createPresetInsurance`, `createCustomInsurance`, `updateCustomInsurance`, `updateBranchInsurance`
|
|
80
|
+
- Patient: `listPatients`, `createPatient`, `getPatient`, `updatePatient`, `getPatientByParty`
|
|
81
|
+
- Transactions: `listTransactions`, `calculateTransaction`, `createSaleTransaction`, `createPurchaseTransaction`, `createProformaTransaction`, `createRefundTransaction`, `getTransaction`, `getTransactionDownloadSignature`, `downloadTransaction`
|
|
355
82
|
|
|
356
|
-
|
|
83
|
+
## Context and Headers
|
|
357
84
|
|
|
358
|
-
|
|
85
|
+
The client automatically attaches:
|
|
359
86
|
|
|
360
|
-
|
|
87
|
+
- `Authorization: Bearer <token>` (when token/apiKey provided)
|
|
88
|
+
- `companyId` header (when set)
|
|
89
|
+
- `branchId` header (when set)
|
|
361
90
|
|
|
362
|
-
|
|
91
|
+
You can update context at runtime:
|
|
363
92
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const customers = parties.filter(p => p.type === 'customer');
|
|
93
|
+
```ts
|
|
94
|
+
client.setContext({ companyId: 2, branchId: 3 });
|
|
95
|
+
client.setToken("new-token-value");
|
|
368
96
|
```
|
|
369
97
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
Retrieves a specific party by ID.
|
|
373
|
-
|
|
374
|
-
**Parameters:**
|
|
375
|
-
- `id` (string) – Party ID
|
|
376
|
-
|
|
377
|
-
**Returns:** Promise resolving to a `Party` object.
|
|
378
|
-
|
|
379
|
-
**Example:**
|
|
380
|
-
```typescript
|
|
381
|
-
const customer = await client.getParty('party-123');
|
|
382
|
-
console.log(`Customer: ${customer.name} (TIN: ${customer.tin})`);
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
#### `createParty(data: Partial<Party>): Promise<Party>`
|
|
386
|
-
|
|
387
|
-
Creates a new party (customer or supplier).
|
|
388
|
-
|
|
389
|
-
**Parameters:**
|
|
390
|
-
- `data` (Partial<Party>) – Party data including:
|
|
391
|
-
- `name` (string, required) – Party name
|
|
392
|
-
- `tin` (string, optional) – Tax Identification Number (9 digits)
|
|
393
|
-
- `type` (string, optional) – Party type: `'customer'` or `'supplier'`
|
|
394
|
-
|
|
395
|
-
**Returns:** Promise resolving to the created `Party` object.
|
|
396
|
-
|
|
397
|
-
**Example:**
|
|
398
|
-
```typescript
|
|
399
|
-
const newCustomer = await client.createParty({
|
|
400
|
-
name: 'John Doe',
|
|
401
|
-
tin: '123456789',
|
|
402
|
-
type: 'customer'
|
|
403
|
-
});
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
#### `updateParty(id: string, data: Partial<Party>): Promise<Party>`
|
|
407
|
-
|
|
408
|
-
Updates an existing party.
|
|
409
|
-
|
|
410
|
-
**Parameters:**
|
|
411
|
-
- `id` (string) – Party ID
|
|
412
|
-
- `data` (Partial<Party>) – Updated party data
|
|
413
|
-
|
|
414
|
-
**Returns:** Promise resolving to the updated `Party` object.
|
|
415
|
-
|
|
416
|
-
#### `deleteParty(id: string): Promise<{ success: boolean }>`
|
|
417
|
-
|
|
418
|
-
Deletes a party by ID.
|
|
419
|
-
|
|
420
|
-
**Parameters:**
|
|
421
|
-
- `id` (string) – Party ID
|
|
422
|
-
|
|
423
|
-
**Returns:** Promise resolving to a deletion confirmation object.
|
|
424
|
-
|
|
425
|
-
---
|
|
426
|
-
|
|
427
|
-
### Expenses
|
|
428
|
-
|
|
429
|
-
Track business expenses.
|
|
430
|
-
|
|
431
|
-
#### `getExpenses(): Promise<Expense[]>`
|
|
432
|
-
|
|
433
|
-
Retrieves a list of all expenses.
|
|
434
|
-
|
|
435
|
-
**Returns:** Promise resolving to an array of `Expense` objects.
|
|
436
|
-
|
|
437
|
-
**Example:**
|
|
438
|
-
```typescript
|
|
439
|
-
const expenses = await client.getExpenses();
|
|
440
|
-
const total = expenses.reduce((sum, e) => sum + e.amount, 0);
|
|
441
|
-
console.log(`Total expenses: ${total} RWF`);
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
#### `getExpense(id: string): Promise<Expense>`
|
|
445
|
-
|
|
446
|
-
Retrieves a specific expense by ID.
|
|
447
|
-
|
|
448
|
-
**Parameters:**
|
|
449
|
-
- `id` (string) – Expense ID
|
|
450
|
-
|
|
451
|
-
**Returns:** Promise resolving to an `Expense` object.
|
|
452
|
-
|
|
453
|
-
**Example:**
|
|
454
|
-
```typescript
|
|
455
|
-
const expense = await client.getExpense('exp-123');
|
|
456
|
-
console.log(`${expense.description}: ${expense.amount} RWF`);
|
|
457
|
-
```
|
|
458
|
-
|
|
459
|
-
#### `createExpense(data: Partial<Expense>): Promise<Expense>`
|
|
460
|
-
|
|
461
|
-
Creates a new expense record.
|
|
462
|
-
|
|
463
|
-
**Parameters:**
|
|
464
|
-
- `data` (Partial<Expense>) – Expense data including:
|
|
465
|
-
- `amount` (number, required) – Expense amount
|
|
466
|
-
- `description` (string, required) – Expense description
|
|
467
|
-
- `date` (string, optional) – Expense date (YYYY-MM-DD format)
|
|
468
|
-
|
|
469
|
-
**Returns:** Promise resolving to the created `Expense` object.
|
|
470
|
-
|
|
471
|
-
**Example:**
|
|
472
|
-
```typescript
|
|
473
|
-
const newExpense = await client.createExpense({
|
|
474
|
-
amount: 50000,
|
|
475
|
-
description: 'Office Supplies',
|
|
476
|
-
date: '2024-01-15'
|
|
477
|
-
});
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
#### `updateExpense(id: string, data: Partial<Expense>): Promise<Expense>`
|
|
481
|
-
|
|
482
|
-
Updates an existing expense.
|
|
483
|
-
|
|
484
|
-
**Parameters:**
|
|
485
|
-
- `id` (string) – Expense ID
|
|
486
|
-
- `data` (Partial<Expense>) – Updated expense data
|
|
487
|
-
|
|
488
|
-
**Returns:** Promise resolving to the updated `Expense` object.
|
|
489
|
-
|
|
490
|
-
#### `deleteExpense(id: string): Promise<{ success: boolean }>`
|
|
491
|
-
|
|
492
|
-
Deletes an expense by ID.
|
|
493
|
-
|
|
494
|
-
**Parameters:**
|
|
495
|
-
- `id` (string) – Expense ID
|
|
496
|
-
|
|
497
|
-
**Returns:** Promise resolving to a deletion confirmation object.
|
|
498
|
-
|
|
499
|
-
---
|
|
500
|
-
|
|
501
|
-
### Transactions (Invoices, Receipts, etc.)
|
|
502
|
-
|
|
503
|
-
Create and manage transactions including invoices, receipts, credit notes, and more.
|
|
504
|
-
|
|
505
|
-
#### `getTransactions(): Promise<Transaction[]>`
|
|
506
|
-
|
|
507
|
-
Retrieves a list of all transactions.
|
|
508
|
-
|
|
509
|
-
**Returns:** Promise resolving to an array of `Transaction` objects.
|
|
510
|
-
|
|
511
|
-
**Example:**
|
|
512
|
-
```typescript
|
|
513
|
-
const transactions = await client.getTransactions();
|
|
514
|
-
const invoices = transactions.filter(t => t.type === 'invoice');
|
|
515
|
-
```
|
|
516
|
-
|
|
517
|
-
#### `getTransaction(id: string): Promise<Transaction>`
|
|
518
|
-
|
|
519
|
-
Retrieves a specific transaction by ID.
|
|
520
|
-
|
|
521
|
-
**Parameters:**
|
|
522
|
-
- `id` (string) – Transaction ID
|
|
523
|
-
|
|
524
|
-
**Returns:** Promise resolving to a `Transaction` object.
|
|
525
|
-
|
|
526
|
-
**Example:**
|
|
527
|
-
```typescript
|
|
528
|
-
const transaction = await client.getTransaction('txn-123');
|
|
529
|
-
console.log(`Invoice #${transaction.id}: ${transaction.totalAmount} RWF`);
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
#### `createTransaction(data: Partial<Transaction>): Promise<Transaction>`
|
|
533
|
-
|
|
534
|
-
Creates a new transaction (invoice, receipt, credit note, etc.).
|
|
535
|
-
|
|
536
|
-
**Parameters:**
|
|
537
|
-
- `data` (Partial<Transaction>) – Transaction data including:
|
|
538
|
-
- `type` (string, optional) – Transaction type: `'invoice'`, `'receipt'`, `'credit_note'`, etc.
|
|
539
|
-
- `partyId` (string, optional) – Customer/Supplier party ID
|
|
540
|
-
- `items` (array, optional) – Transaction line items:
|
|
541
|
-
- `productId` (string, optional) – Product ID
|
|
542
|
-
- `quantity` (number, required) – Item quantity
|
|
543
|
-
- `unitPrice` (number, required) – Unit price
|
|
544
|
-
- `totalAmount` (number, optional) – Total transaction amount
|
|
545
|
-
|
|
546
|
-
**Returns:** Promise resolving to the created `Transaction` object.
|
|
547
|
-
|
|
548
|
-
**Example:**
|
|
549
|
-
```typescript
|
|
550
|
-
const invoice = await client.createTransaction({
|
|
551
|
-
type: 'invoice',
|
|
552
|
-
partyId: 'party-123',
|
|
553
|
-
items: [
|
|
554
|
-
{
|
|
555
|
-
productId: 'prod-123',
|
|
556
|
-
quantity: 2,
|
|
557
|
-
unitPrice: 5000
|
|
558
|
-
}
|
|
559
|
-
]
|
|
560
|
-
});
|
|
561
|
-
console.log(`Created invoice: ${invoice.id}`);
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
#### `updateTransaction(id: string, data: Partial<Transaction>): Promise<Transaction>`
|
|
565
|
-
|
|
566
|
-
Updates an existing transaction.
|
|
567
|
-
|
|
568
|
-
**Parameters:**
|
|
569
|
-
- `id` (string) – Transaction ID
|
|
570
|
-
- `data` (Partial<Transaction>) – Updated transaction data
|
|
571
|
-
|
|
572
|
-
**Returns:** Promise resolving to the updated `Transaction` object.
|
|
573
|
-
|
|
574
|
-
#### `deleteTransaction(id: string): Promise<{ success: boolean }>`
|
|
575
|
-
|
|
576
|
-
Deletes a transaction by ID.
|
|
577
|
-
|
|
578
|
-
**Parameters:**
|
|
579
|
-
- `id` (string) – Transaction ID
|
|
580
|
-
|
|
581
|
-
**Returns:** Promise resolving to a deletion confirmation object.
|
|
582
|
-
|
|
583
|
-
#### `getSignedPdf(id: string): Promise<SignedPdfResponse>`
|
|
584
|
-
|
|
585
|
-
Retrieves a signed PDF document for a transaction.
|
|
586
|
-
|
|
587
|
-
**Parameters:**
|
|
588
|
-
- `id` (string) – Transaction ID
|
|
589
|
-
|
|
590
|
-
**Returns:** Promise resolving to a `SignedPdfResponse` object containing:
|
|
591
|
-
- `url` (string, optional) – URL to download the PDF
|
|
592
|
-
- `base64` (string, optional) – Base64-encoded PDF content
|
|
593
|
-
|
|
594
|
-
**Example:**
|
|
595
|
-
```typescript
|
|
596
|
-
const pdf = await client.getSignedPdf('txn-123');
|
|
597
|
-
if (pdf.url) {
|
|
598
|
-
console.log('PDF URL:', pdf.url);
|
|
599
|
-
// Download the PDF from the URL
|
|
600
|
-
} else if (pdf.base64) {
|
|
601
|
-
// Decode and save the base64 PDF
|
|
602
|
-
const buffer = Buffer.from(pdf.base64, 'base64');
|
|
603
|
-
fs.writeFileSync('invoice.pdf', buffer);
|
|
604
|
-
}
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
---
|
|
608
|
-
|
|
609
|
-
## 💡 Common Use Cases
|
|
610
|
-
|
|
611
|
-
### Creating a Complete Invoice Flow
|
|
612
|
-
|
|
613
|
-
```typescript
|
|
614
|
-
import { ZataClient } from 'zata-vsdc-sdk';
|
|
615
|
-
|
|
616
|
-
const client = new ZataClient({
|
|
617
|
-
apiKey: process.env.ZATA_API_KEY!
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
async function createInvoice() {
|
|
621
|
-
try {
|
|
622
|
-
// 1. Create or get a customer
|
|
623
|
-
const customer = await client.createParty({
|
|
624
|
-
name: 'Acme Customer Ltd',
|
|
625
|
-
tin: '123456789',
|
|
626
|
-
type: 'customer'
|
|
627
|
-
});
|
|
628
|
-
|
|
629
|
-
// 2. Create or get products
|
|
630
|
-
const product = await client.createProduct({
|
|
631
|
-
name: 'Premium Service',
|
|
632
|
-
price: 10000,
|
|
633
|
-
unit: 'hour'
|
|
634
|
-
});
|
|
635
|
-
|
|
636
|
-
// 3. Create the invoice
|
|
637
|
-
const invoice = await client.createTransaction({
|
|
638
|
-
type: 'invoice',
|
|
639
|
-
partyId: customer.id,
|
|
640
|
-
items: [
|
|
641
|
-
{
|
|
642
|
-
productId: product.id,
|
|
643
|
-
quantity: 5,
|
|
644
|
-
unitPrice: 10000
|
|
645
|
-
}
|
|
646
|
-
]
|
|
647
|
-
});
|
|
648
|
-
|
|
649
|
-
console.log(`Invoice created: ${invoice.id}`);
|
|
650
|
-
|
|
651
|
-
// 4. Get the signed PDF
|
|
652
|
-
const pdf = await client.getSignedPdf(invoice.id);
|
|
653
|
-
console.log('PDF available at:', pdf.url);
|
|
654
|
-
|
|
655
|
-
return invoice;
|
|
656
|
-
} catch (error) {
|
|
657
|
-
console.error('Error creating invoice:', error);
|
|
658
|
-
throw error;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
### Batch Processing
|
|
664
|
-
|
|
665
|
-
```typescript
|
|
666
|
-
async function createMultipleInvoices(invoices: Array<{ customerId: string; items: any[] }>) {
|
|
667
|
-
const results = await Promise.allSettled(
|
|
668
|
-
invoices.map(data =>
|
|
669
|
-
client.createTransaction({
|
|
670
|
-
type: 'invoice',
|
|
671
|
-
partyId: data.customerId,
|
|
672
|
-
items: data.items
|
|
673
|
-
})
|
|
674
|
-
)
|
|
675
|
-
);
|
|
676
|
-
|
|
677
|
-
const successful = results
|
|
678
|
-
.filter((r): r is PromiseFulfilledResult<any> => r.status === 'fulfilled')
|
|
679
|
-
.map(r => r.value);
|
|
680
|
-
|
|
681
|
-
const failed = results
|
|
682
|
-
.filter((r): r is PromiseRejectedResult => r.status === 'rejected')
|
|
683
|
-
.map(r => r.reason);
|
|
684
|
-
|
|
685
|
-
console.log(`Created ${successful.length} invoices, ${failed.length} failed`);
|
|
686
|
-
return { successful, failed };
|
|
687
|
-
}
|
|
688
|
-
```
|
|
689
|
-
|
|
690
|
-
### Error Handling
|
|
691
|
-
|
|
692
|
-
```typescript
|
|
693
|
-
async function safeCreateProduct(productData: Partial<Product>) {
|
|
694
|
-
try {
|
|
695
|
-
const product = await client.createProduct(productData);
|
|
696
|
-
return { success: true, data: product };
|
|
697
|
-
} catch (error: any) {
|
|
698
|
-
// Parse error message
|
|
699
|
-
if (error.message.includes('400')) {
|
|
700
|
-
return { success: false, error: 'Validation error', details: error.message };
|
|
701
|
-
} else if (error.message.includes('401')) {
|
|
702
|
-
return { success: false, error: 'Authentication failed' };
|
|
703
|
-
} else if (error.message.includes('404')) {
|
|
704
|
-
return { success: false, error: 'Resource not found' };
|
|
705
|
-
} else {
|
|
706
|
-
return { success: false, error: 'Unknown error', details: error.message };
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
```
|
|
711
|
-
|
|
712
|
-
---
|
|
713
|
-
|
|
714
|
-
## 🔧 TypeScript Types
|
|
715
|
-
|
|
716
|
-
The SDK exports TypeScript interfaces for all resources:
|
|
717
|
-
|
|
718
|
-
```typescript
|
|
719
|
-
import {
|
|
720
|
-
ZataClient,
|
|
721
|
-
Company,
|
|
722
|
-
Branch,
|
|
723
|
-
Product,
|
|
724
|
-
Party,
|
|
725
|
-
Expense,
|
|
726
|
-
Transaction,
|
|
727
|
-
SignedPdfResponse,
|
|
728
|
-
ZataClientOptions
|
|
729
|
-
} from 'zata-vsdc-sdk';
|
|
730
|
-
```
|
|
731
|
-
|
|
732
|
-
### Available Types
|
|
733
|
-
|
|
734
|
-
- `Company` – Company resource
|
|
735
|
-
- `Branch` – Branch resource
|
|
736
|
-
- `Product` – Product resource
|
|
737
|
-
- `Party` – Customer/Supplier resource
|
|
738
|
-
- `Expense` – Expense resource
|
|
739
|
-
- `Transaction` – Invoice/Receipt/Credit Note resource
|
|
740
|
-
- `SignedPdfResponse` – PDF response with URL or base64
|
|
741
|
-
- `ZataClientOptions` – Client initialization options
|
|
742
|
-
- `ZataResourceMeta` – Base metadata fields for resources
|
|
743
|
-
|
|
744
|
-
---
|
|
745
|
-
|
|
746
|
-
## ⚠️ Error Handling
|
|
747
|
-
|
|
748
|
-
The SDK includes built-in error handling that provides detailed error messages:
|
|
749
|
-
|
|
750
|
-
```typescript
|
|
751
|
-
try {
|
|
752
|
-
await client.getCompany('invalid-id');
|
|
753
|
-
} catch (error: any) {
|
|
754
|
-
// Error format: "Zata API Error 404: {...}"
|
|
755
|
-
console.error(error.message);
|
|
756
|
-
}
|
|
757
|
-
```
|
|
758
|
-
|
|
759
|
-
Common error scenarios:
|
|
760
|
-
|
|
761
|
-
- **400 Bad Request** – Validation errors (check request data)
|
|
762
|
-
- **401 Unauthorized** – Invalid or missing API key
|
|
763
|
-
- **404 Not Found** – Resource doesn't exist
|
|
764
|
-
- **500 Server Error** – Internal server error (retry with backoff)
|
|
765
|
-
- **Network Errors** – Connection issues (check network/API URL)
|
|
766
|
-
|
|
767
|
-
---
|
|
768
|
-
|
|
769
|
-
## 🌍 Environment Configuration
|
|
770
|
-
|
|
771
|
-
For different environments, you can configure the base URL:
|
|
772
|
-
|
|
773
|
-
```typescript
|
|
774
|
-
// Production (default)
|
|
775
|
-
const prodClient = new ZataClient({
|
|
776
|
-
apiKey: process.env.ZATA_API_KEY!
|
|
777
|
-
});
|
|
778
|
-
|
|
779
|
-
// Staging/Development
|
|
780
|
-
const devClient = new ZataClient({
|
|
781
|
-
apiKey: process.env.ZATA_API_KEY!,
|
|
782
|
-
baseUrl: 'https://staging-api.zata.rw/v1'
|
|
783
|
-
});
|
|
784
|
-
|
|
785
|
-
// Custom timeout for slow connections
|
|
786
|
-
const slowClient = new ZataClient({
|
|
787
|
-
apiKey: process.env.ZATA_API_KEY!,
|
|
788
|
-
timeout: 60000 // 60 seconds
|
|
789
|
-
});
|
|
790
|
-
```
|
|
791
|
-
|
|
792
|
-
---
|
|
793
|
-
|
|
794
|
-
## 🤝 Contributing
|
|
795
|
-
|
|
796
|
-
This is an open-source project, and we welcome contributions from the community! Here's how you can help:
|
|
797
|
-
|
|
798
|
-
1. **Report Issues** – Found a bug? [Open an issue](https://github.com/HiQ-Africa/zata-npm/issues)
|
|
799
|
-
2. **Suggest Features** – Have an idea? [Share it with us](https://github.com/HiQ-Africa/zata-npm/issues)
|
|
800
|
-
3. **Submit Pull Requests** – Fixed a bug or added a feature? [Submit a PR](https://github.com/HiQ-Africa/zata-npm/pulls)
|
|
801
|
-
4. **Improve Documentation** – Help make the docs better for everyone
|
|
802
|
-
|
|
803
|
-
### Development Setup
|
|
98
|
+
## Scripts
|
|
804
99
|
|
|
805
100
|
```bash
|
|
806
|
-
# Clone the repository
|
|
807
|
-
git clone https://github.com/HiQ-Africa/zata-npm.git
|
|
808
|
-
cd zata-npm
|
|
809
|
-
|
|
810
|
-
# Install dependencies
|
|
811
|
-
npm install
|
|
812
|
-
|
|
813
|
-
# Build the project
|
|
814
101
|
npm run build
|
|
815
|
-
|
|
816
|
-
# Run tests (if available)
|
|
817
102
|
npm test
|
|
818
103
|
```
|
|
819
104
|
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
- Use TypeScript for all new code
|
|
823
|
-
- Follow existing code style and patterns
|
|
824
|
-
- Add JSDoc comments for public methods
|
|
825
|
-
- Include examples in documentation
|
|
826
|
-
|
|
827
|
-
---
|
|
828
|
-
|
|
829
|
-
## 📝 License
|
|
830
|
-
|
|
831
|
-
This project is licensed under the MIT License – see the [LICENSE](LICENSE) file for details.
|
|
832
|
-
|
|
833
|
-
---
|
|
834
|
-
|
|
835
|
-
## 🙏 Acknowledgments
|
|
836
|
-
|
|
837
|
-
- Built for the Rwanda business community
|
|
838
|
-
- Powered by [Zata](https://zata.rw) – Rwanda's leading tax compliance platform
|
|
839
|
-
- Developed by [HiQ Africa](https://hiq.africa)
|
|
840
|
-
|
|
841
|
-
---
|
|
842
|
-
|
|
843
|
-
## 📞 Support
|
|
844
|
-
|
|
845
|
-
- **Documentation**: [https://docs.zata.rw](https://docs.zata.rw)
|
|
846
|
-
- **Support Email**: hirwa@hiq.africa
|
|
847
|
-
- **GitHub Issues**: [https://github.com/HiQ-Africa/zata-npm/issues](https://github.com/HiQ-Africa/zata-npm/issues)
|
|
848
|
-
|
|
849
|
-
---
|
|
850
|
-
|
|
851
|
-
## 🔗 Related Resources
|
|
852
|
-
|
|
853
|
-
- [Zata Official Website](https://zata.rw)
|
|
854
|
-
- [Zata API Documentation](https://docs.zata.rw)
|
|
855
|
-
- [Implementation Guide](./guide.md) – Detailed step-by-step guide for implementing the Zata API
|
|
856
|
-
|
|
857
|
-
---
|
|
105
|
+
## Resources
|
|
858
106
|
|
|
859
|
-
|
|
107
|
+
- API docs: [https://docs.zata.rw](https://docs.zata.rw)
|
|
108
|
+
- Website: [https://zata.rw](https://zata.rw)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
export type Primitive = string | number | boolean;
|
|
2
|
+
export type QueryParams = Record<string, Primitive | undefined>;
|
|
3
|
+
export type ApiRecord = Record<string, unknown>;
|
|
4
|
+
export interface ZataClientOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Bearer token for Zata API. `apiKey` remains as an alias
|
|
7
|
+
* for backwards compatibility with previous SDK versions.
|
|
8
|
+
*/
|
|
9
|
+
token?: string;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
timeout?: number;
|
|
13
|
+
companyId?: string | number;
|
|
14
|
+
branchId?: string | number;
|
|
15
|
+
defaultHeaders?: Record<string, string>;
|
|
16
|
+
}
|
|
17
|
+
export interface ZataClientContext {
|
|
18
|
+
companyId?: string | number;
|
|
19
|
+
branchId?: string | number;
|
|
20
|
+
}
|
|
21
|
+
export declare class ZataClient {
|
|
22
|
+
private readonly axios;
|
|
23
|
+
private readonly baseHeaders;
|
|
24
|
+
private context;
|
|
25
|
+
constructor(options?: ZataClientOptions);
|
|
26
|
+
setToken(token: string): void;
|
|
27
|
+
setContext(context: ZataClientContext): void;
|
|
28
|
+
private buildHeaders;
|
|
29
|
+
private request;
|
|
30
|
+
login(data: ApiRecord): Promise<ApiRecord>;
|
|
31
|
+
createAccount(data: ApiRecord): Promise<ApiRecord>;
|
|
32
|
+
getTestStatus(): Promise<ApiRecord>;
|
|
33
|
+
listCompanies(params?: {
|
|
34
|
+
perPage?: number;
|
|
35
|
+
page?: number;
|
|
36
|
+
}): Promise<ApiRecord>;
|
|
37
|
+
createCompany(data: ApiRecord): Promise<ApiRecord>;
|
|
38
|
+
updateCompany(data: ApiRecord): Promise<ApiRecord>;
|
|
39
|
+
getCompany(companyId: string | number): Promise<ApiRecord>;
|
|
40
|
+
listCompanyBranches(params?: {
|
|
41
|
+
perPage?: number;
|
|
42
|
+
page?: number;
|
|
43
|
+
}): Promise<ApiRecord>;
|
|
44
|
+
createCompanyBranch(data: ApiRecord): Promise<ApiRecord>;
|
|
45
|
+
updateCompanyBranch(data: ApiRecord): Promise<ApiRecord>;
|
|
46
|
+
getCompanyFinance(): Promise<ApiRecord>;
|
|
47
|
+
getCompanyTaxInfo(): Promise<ApiRecord>;
|
|
48
|
+
getPaymentModes(): Promise<ApiRecord>;
|
|
49
|
+
getProductCategories(): Promise<ApiRecord>;
|
|
50
|
+
getProductClasses(): Promise<ApiRecord>;
|
|
51
|
+
getProductCountryOrigins(): Promise<ApiRecord>;
|
|
52
|
+
getProductPackagingUnits(): Promise<ApiRecord>;
|
|
53
|
+
getProductQuantityUnits(): Promise<ApiRecord>;
|
|
54
|
+
getProductTaxes(): Promise<ApiRecord>;
|
|
55
|
+
getProductTypes(): Promise<ApiRecord>;
|
|
56
|
+
listParties(params?: {
|
|
57
|
+
partyType?: string;
|
|
58
|
+
perPage?: number;
|
|
59
|
+
page?: number;
|
|
60
|
+
}): Promise<ApiRecord>;
|
|
61
|
+
createCustomer(data: ApiRecord): Promise<ApiRecord>;
|
|
62
|
+
createSupplier(data: ApiRecord): Promise<ApiRecord>;
|
|
63
|
+
listExpenses(params?: {
|
|
64
|
+
perPage?: number;
|
|
65
|
+
page?: number;
|
|
66
|
+
searchQuery?: string;
|
|
67
|
+
}): Promise<ApiRecord>;
|
|
68
|
+
createExpense(data: ApiRecord): Promise<ApiRecord>;
|
|
69
|
+
getExpenseCategories(): Promise<ApiRecord>;
|
|
70
|
+
listInsurances(): Promise<ApiRecord>;
|
|
71
|
+
createPresetInsurance(data: ApiRecord): Promise<ApiRecord>;
|
|
72
|
+
createCustomInsurance(data: ApiRecord): Promise<ApiRecord>;
|
|
73
|
+
updateCustomInsurance(insuranceId: string | number, data: ApiRecord): Promise<ApiRecord>;
|
|
74
|
+
updateBranchInsurance(companyInsuranceId: string | number, data: ApiRecord): Promise<ApiRecord>;
|
|
75
|
+
listPatients(params?: {
|
|
76
|
+
perPage?: number;
|
|
77
|
+
page?: number;
|
|
78
|
+
searchQuery?: string;
|
|
79
|
+
}): Promise<ApiRecord>;
|
|
80
|
+
createPatient(data: ApiRecord): Promise<ApiRecord>;
|
|
81
|
+
getPatient(patientId: string | number): Promise<ApiRecord>;
|
|
82
|
+
updatePatient(patientId: string | number, data: ApiRecord): Promise<ApiRecord>;
|
|
83
|
+
getPatientByParty(partyId: string | number): Promise<ApiRecord>;
|
|
84
|
+
createProduct(data: ApiRecord): Promise<ApiRecord>;
|
|
85
|
+
listBranchProducts(params?: {
|
|
86
|
+
perPage?: number;
|
|
87
|
+
page?: number;
|
|
88
|
+
searchQuery?: string;
|
|
89
|
+
}): Promise<ApiRecord>;
|
|
90
|
+
getProduct(productId: string | number): Promise<ApiRecord>;
|
|
91
|
+
updateProduct(productId: string | number, data: ApiRecord): Promise<ApiRecord>;
|
|
92
|
+
increaseProductQuantity(productId: string | number, data: ApiRecord): Promise<ApiRecord>;
|
|
93
|
+
reduceProductQuantity(productId: string | number, data: ApiRecord): Promise<ApiRecord>;
|
|
94
|
+
listTransactions(params?: {
|
|
95
|
+
perPage?: number;
|
|
96
|
+
page?: number;
|
|
97
|
+
fromDate?: string;
|
|
98
|
+
toDate?: string;
|
|
99
|
+
invoiceType?: string;
|
|
100
|
+
}): Promise<ApiRecord>;
|
|
101
|
+
calculateTransaction(data: ApiRecord): Promise<ApiRecord>;
|
|
102
|
+
createSaleTransaction(data: ApiRecord): Promise<ApiRecord>;
|
|
103
|
+
createPurchaseTransaction(data: ApiRecord): Promise<ApiRecord>;
|
|
104
|
+
createProformaTransaction(data: ApiRecord): Promise<ApiRecord>;
|
|
105
|
+
createRefundTransaction(transactionId: string | number, data: ApiRecord): Promise<ApiRecord>;
|
|
106
|
+
getTransaction(transactionId: string | number, params?: {
|
|
107
|
+
withSignature?: boolean;
|
|
108
|
+
}): Promise<ApiRecord>;
|
|
109
|
+
getTransactionDownloadSignature(transactionId: string | number, params?: {
|
|
110
|
+
downloadSize?: 'A4' | 'm80' | 'm58';
|
|
111
|
+
}): Promise<ApiRecord>;
|
|
112
|
+
downloadTransaction(params: {
|
|
113
|
+
expires: string | number;
|
|
114
|
+
id: string | number;
|
|
115
|
+
signature: string;
|
|
116
|
+
}): Promise<ApiRecord>;
|
|
117
|
+
}
|
|
118
|
+
export default ZataClient;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ZataClient = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
class ZataClient {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
const { token, apiKey, baseUrl = 'https://api.zata.rw', timeout = 30000, companyId, branchId, defaultHeaders = {}, } = options;
|
|
11
|
+
const authToken = token ?? apiKey;
|
|
12
|
+
this.baseHeaders = {
|
|
13
|
+
Accept: 'application/json',
|
|
14
|
+
'Content-Type': 'application/json',
|
|
15
|
+
...defaultHeaders,
|
|
16
|
+
};
|
|
17
|
+
if (authToken) {
|
|
18
|
+
this.baseHeaders.Authorization = authToken.startsWith('Bearer ')
|
|
19
|
+
? authToken
|
|
20
|
+
: `Bearer ${authToken}`;
|
|
21
|
+
}
|
|
22
|
+
this.context = { companyId, branchId };
|
|
23
|
+
this.axios = axios_1.default.create({
|
|
24
|
+
baseURL: baseUrl,
|
|
25
|
+
timeout,
|
|
26
|
+
headers: this.baseHeaders,
|
|
27
|
+
});
|
|
28
|
+
this.axios.interceptors.response.use((response) => response, (error) => {
|
|
29
|
+
if (error.response) {
|
|
30
|
+
const { status, data } = error.response;
|
|
31
|
+
throw new Error(`Zata API Error ${status}: ${JSON.stringify(data)}`);
|
|
32
|
+
}
|
|
33
|
+
throw new Error(`Network/Request Error: ${error.message}`);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
setToken(token) {
|
|
37
|
+
this.baseHeaders.Authorization = token.startsWith('Bearer ')
|
|
38
|
+
? token
|
|
39
|
+
: `Bearer ${token}`;
|
|
40
|
+
}
|
|
41
|
+
setContext(context) {
|
|
42
|
+
this.context = {
|
|
43
|
+
...this.context,
|
|
44
|
+
...context,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
buildHeaders(extraHeaders) {
|
|
48
|
+
const headers = {
|
|
49
|
+
...this.baseHeaders,
|
|
50
|
+
...extraHeaders,
|
|
51
|
+
};
|
|
52
|
+
if (this.context.companyId !== undefined) {
|
|
53
|
+
headers.companyId = String(this.context.companyId);
|
|
54
|
+
}
|
|
55
|
+
if (this.context.branchId !== undefined) {
|
|
56
|
+
headers.branchId = String(this.context.branchId);
|
|
57
|
+
}
|
|
58
|
+
return headers;
|
|
59
|
+
}
|
|
60
|
+
async request(method, path, options = {}) {
|
|
61
|
+
const { data, params, headers, config } = options;
|
|
62
|
+
const response = await this.axios.request({
|
|
63
|
+
method,
|
|
64
|
+
url: path,
|
|
65
|
+
data,
|
|
66
|
+
params,
|
|
67
|
+
headers: this.buildHeaders(headers),
|
|
68
|
+
...config,
|
|
69
|
+
});
|
|
70
|
+
return response.data;
|
|
71
|
+
}
|
|
72
|
+
// Auth and utilities
|
|
73
|
+
login(data) {
|
|
74
|
+
return this.request('POST', '/api/v1/login', { data });
|
|
75
|
+
}
|
|
76
|
+
createAccount(data) {
|
|
77
|
+
return this.request('POST', '/api/v1/create-account', { data });
|
|
78
|
+
}
|
|
79
|
+
getTestStatus() {
|
|
80
|
+
return this.request('GET', '/api/v1/test');
|
|
81
|
+
}
|
|
82
|
+
// Company
|
|
83
|
+
listCompanies(params) {
|
|
84
|
+
return this.request('GET', '/api/v1/company', { params });
|
|
85
|
+
}
|
|
86
|
+
createCompany(data) {
|
|
87
|
+
return this.request('POST', '/api/v1/company', { data });
|
|
88
|
+
}
|
|
89
|
+
updateCompany(data) {
|
|
90
|
+
return this.request('PUT', '/api/v1/company', { data });
|
|
91
|
+
}
|
|
92
|
+
getCompany(companyId) {
|
|
93
|
+
return this.request('GET', `/api/v1/company/${companyId}`);
|
|
94
|
+
}
|
|
95
|
+
listCompanyBranches(params) {
|
|
96
|
+
return this.request('GET', '/api/v1/company/branch', { params });
|
|
97
|
+
}
|
|
98
|
+
createCompanyBranch(data) {
|
|
99
|
+
return this.request('POST', '/api/v1/company/branch', { data });
|
|
100
|
+
}
|
|
101
|
+
updateCompanyBranch(data) {
|
|
102
|
+
return this.request('PUT', '/api/v1/company/branch', { data });
|
|
103
|
+
}
|
|
104
|
+
getCompanyFinance() {
|
|
105
|
+
return this.request('GET', '/api/v1/company/finance');
|
|
106
|
+
}
|
|
107
|
+
getCompanyTaxInfo() {
|
|
108
|
+
return this.request('GET', '/api/v1/company/tax-info');
|
|
109
|
+
}
|
|
110
|
+
// Data/Reference
|
|
111
|
+
getPaymentModes() {
|
|
112
|
+
return this.request('GET', '/api/v1/data/payment-mode');
|
|
113
|
+
}
|
|
114
|
+
getProductCategories() {
|
|
115
|
+
return this.request('GET', '/api/v1/data/product-category');
|
|
116
|
+
}
|
|
117
|
+
getProductClasses() {
|
|
118
|
+
return this.request('GET', '/api/v1/data/product-class');
|
|
119
|
+
}
|
|
120
|
+
getProductCountryOrigins() {
|
|
121
|
+
return this.request('GET', '/api/v1/data/product-country-origin');
|
|
122
|
+
}
|
|
123
|
+
getProductPackagingUnits() {
|
|
124
|
+
return this.request('GET', '/api/v1/data/product-packaging-unit');
|
|
125
|
+
}
|
|
126
|
+
getProductQuantityUnits() {
|
|
127
|
+
return this.request('GET', '/api/v1/data/product-quantity-unit');
|
|
128
|
+
}
|
|
129
|
+
getProductTaxes() {
|
|
130
|
+
return this.request('GET', '/api/v1/data/product-tax');
|
|
131
|
+
}
|
|
132
|
+
getProductTypes() {
|
|
133
|
+
return this.request('GET', '/api/v1/data/product-type');
|
|
134
|
+
}
|
|
135
|
+
// Party
|
|
136
|
+
listParties(params) {
|
|
137
|
+
return this.request('GET', '/api/v1/party', { params });
|
|
138
|
+
}
|
|
139
|
+
createCustomer(data) {
|
|
140
|
+
return this.request('POST', '/api/v1/party/new-customer', { data });
|
|
141
|
+
}
|
|
142
|
+
createSupplier(data) {
|
|
143
|
+
return this.request('POST', '/api/v1/party/new-supplier', { data });
|
|
144
|
+
}
|
|
145
|
+
// Expense
|
|
146
|
+
listExpenses(params) {
|
|
147
|
+
return this.request('GET', '/api/v1/expense', { params });
|
|
148
|
+
}
|
|
149
|
+
createExpense(data) {
|
|
150
|
+
return this.request('POST', '/api/v1/expense', { data });
|
|
151
|
+
}
|
|
152
|
+
getExpenseCategories() {
|
|
153
|
+
return this.request('GET', '/api/v1/expense/categories');
|
|
154
|
+
}
|
|
155
|
+
// Insurance
|
|
156
|
+
listInsurances() {
|
|
157
|
+
return this.request('GET', '/api/v1/insurance');
|
|
158
|
+
}
|
|
159
|
+
createPresetInsurance(data) {
|
|
160
|
+
return this.request('POST', '/api/v1/insurance/preset', { data });
|
|
161
|
+
}
|
|
162
|
+
createCustomInsurance(data) {
|
|
163
|
+
return this.request('POST', '/api/v1/insurance/custom', { data });
|
|
164
|
+
}
|
|
165
|
+
updateCustomInsurance(insuranceId, data) {
|
|
166
|
+
return this.request('PUT', `/api/v1/insurance/custom/${insuranceId}`, { data });
|
|
167
|
+
}
|
|
168
|
+
updateBranchInsurance(companyInsuranceId, data) {
|
|
169
|
+
return this.request('PUT', `/api/v1/insurance/branch/${companyInsuranceId}`, {
|
|
170
|
+
data,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// Patient
|
|
174
|
+
listPatients(params) {
|
|
175
|
+
return this.request('GET', '/api/v1/patient', { params });
|
|
176
|
+
}
|
|
177
|
+
createPatient(data) {
|
|
178
|
+
return this.request('POST', '/api/v1/patient', { data });
|
|
179
|
+
}
|
|
180
|
+
getPatient(patientId) {
|
|
181
|
+
return this.request('GET', `/api/v1/patient/${patientId}`);
|
|
182
|
+
}
|
|
183
|
+
updatePatient(patientId, data) {
|
|
184
|
+
return this.request('PUT', `/api/v1/patient/${patientId}`, { data });
|
|
185
|
+
}
|
|
186
|
+
getPatientByParty(partyId) {
|
|
187
|
+
return this.request('GET', `/api/v1/patient/party/${partyId}`);
|
|
188
|
+
}
|
|
189
|
+
// Product
|
|
190
|
+
createProduct(data) {
|
|
191
|
+
return this.request('POST', '/api/v1/product', { data });
|
|
192
|
+
}
|
|
193
|
+
listBranchProducts(params) {
|
|
194
|
+
return this.request('GET', '/api/v1/product/branch', { params });
|
|
195
|
+
}
|
|
196
|
+
getProduct(productId) {
|
|
197
|
+
return this.request('GET', `/api/v1/product/${productId}`);
|
|
198
|
+
}
|
|
199
|
+
updateProduct(productId, data) {
|
|
200
|
+
return this.request('PUT', `/api/v1/product/${productId}`, { data });
|
|
201
|
+
}
|
|
202
|
+
increaseProductQuantity(productId, data) {
|
|
203
|
+
return this.request('PUT', `/api/v1/product/increase-quantity/${productId}`, { data });
|
|
204
|
+
}
|
|
205
|
+
reduceProductQuantity(productId, data) {
|
|
206
|
+
return this.request('PUT', `/api/v1/product/reduce-quantity/${productId}`, { data });
|
|
207
|
+
}
|
|
208
|
+
// Transaction
|
|
209
|
+
listTransactions(params) {
|
|
210
|
+
return this.request('GET', '/api/v1/transaction', { params });
|
|
211
|
+
}
|
|
212
|
+
calculateTransaction(data) {
|
|
213
|
+
return this.request('POST', '/api/v1/transaction/calculate', { data });
|
|
214
|
+
}
|
|
215
|
+
createSaleTransaction(data) {
|
|
216
|
+
return this.request('POST', '/api/v1/transaction/sale', { data });
|
|
217
|
+
}
|
|
218
|
+
createPurchaseTransaction(data) {
|
|
219
|
+
return this.request('POST', '/api/v1/transaction/purchase', { data });
|
|
220
|
+
}
|
|
221
|
+
createProformaTransaction(data) {
|
|
222
|
+
return this.request('POST', '/api/v1/transaction/proforma', { data });
|
|
223
|
+
}
|
|
224
|
+
createRefundTransaction(transactionId, data) {
|
|
225
|
+
return this.request('POST', `/api/v1/transaction/refund/${transactionId}`, { data });
|
|
226
|
+
}
|
|
227
|
+
getTransaction(transactionId, params) {
|
|
228
|
+
return this.request('GET', `/api/v1/transaction/${transactionId}`, { params });
|
|
229
|
+
}
|
|
230
|
+
getTransactionDownloadSignature(transactionId, params) {
|
|
231
|
+
return this.request('GET', `/api/v1/transaction/download-signature/${transactionId}`, {
|
|
232
|
+
params,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
downloadTransaction(params) {
|
|
236
|
+
return this.request('GET', '/api/v1/transaction/download', { params });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
exports.ZataClient = ZataClient;
|
|
240
|
+
exports.default = ZataClient;
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zata-vsdc-sdk",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "TypeScript SDK for Zata API – E-Invoicing & Tax Compliance (Rwanda)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"homepage": "https://zata.rw",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "tsc",
|
|
10
|
-
"
|
|
10
|
+
"test": "node --test test/*.test.js",
|
|
11
|
+
"prepublishOnly": "npm run build && npm test"
|
|
11
12
|
},
|
|
12
13
|
"keywords": [
|
|
13
14
|
"zata",
|
|
@@ -38,4 +39,4 @@
|
|
|
38
39
|
"access": "public"
|
|
39
40
|
},
|
|
40
41
|
"readme": "README.md"
|
|
41
|
-
}
|
|
42
|
+
}
|