@taxora/sdk 1.5.0 → 1.7.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/CHANGELOG.md +34 -0
- package/README.md +50 -0
- package/dist/index.cjs +242 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +154 -2
- package/dist/index.d.ts +154 -2
- package/dist/index.js +240 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@taxora/sdk` are documented here. Versions follow [SemVer](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## [1.7.0] — 2026-10-24
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Smart Enrichment: `taxNumberType`, `taxNumberLabel`, `taxNumberSource`** next to `taxNumber`. `taxNumber` is now
|
|
10
|
+
the company's local tax / business number: on `found` it is read off the confirmed VAT ID where that country's
|
|
11
|
+
VAT ID contains it (`taxNumberSource` = `'vat_id'`: FR SIREN, IT Partita IVA, ES NIF, PL NIP, BE enterprise
|
|
12
|
+
number, DK CVR, PT, RO, CZ IČO, SK DIČ, SE/NO orgnr, FI Y-tunnus, SI, HR OIB, BG EIK, GR AFM), otherwise a
|
|
13
|
+
domestic number the company published (`'company_website'`, e.g. a DE/AT Steuernummer — not a VAT ID).
|
|
14
|
+
`taxNumberType` is the code (`pl_nip`, `fr_siren`, `de_steuernummer` …), `taxNumberLabel` its national name.
|
|
15
|
+
New type `SmartEnrichmentTaxNumberSource`.
|
|
16
|
+
- **Local tax numbers report** on `client.vat`: `localTaxNumbersCsv()` (raw CSV, UTF-8 with BOM),
|
|
17
|
+
`localTaxNumbers()` (parsed `LocalTaxNumberRow[]` — BOM dropped, the Excel TAB guard before digit-only tax numbers
|
|
18
|
+
trimmed, empty cells `null`) and `localTaxNumbersSummary()` (`{ companies, withTaxNumber }`). Filters: `dateFrom`,
|
|
19
|
+
`dateTo`, `countries`, `onlyWithTaxNumber`. `parseLocalTaxNumbersCsv()` parses a saved file.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Bundled OpenAPI specs (`resources/`) refreshed from the current API.
|
|
24
|
+
|
|
25
|
+
## [1.6.0] — 2026-10-22
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- **Smart Enrichment: `taxNumber`** — a domestic tax number (e.g. a German Steuernummer) a company's page shows
|
|
30
|
+
instead of a VAT ID. It is not a VAT ID; the lookup stays `not_found`.
|
|
31
|
+
- **Smart Enrichment: the official VAT check behind a found number** — `vatValid`, `aiScore`, `nameMatch`
|
|
32
|
+
(`'ok' | 'mismatch'`, plus `nameMismatch()`), `officialName` and `officialAddress`
|
|
33
|
+
(`SmartEnrichmentOfficialAddress`). Lets you write the register's name and address back into your records.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Bundled OpenAPI specs (`resources/`) refreshed from the current API.
|
|
38
|
+
|
|
5
39
|
## [1.5.0] — 2026-10-22
|
|
6
40
|
|
|
7
41
|
### Added
|
package/README.md
CHANGED
|
@@ -307,6 +307,39 @@ const results = await client.vat.search('Alpha Handels', 25 /* perPage */);
|
|
|
307
307
|
|
|
308
308
|
---
|
|
309
309
|
|
|
310
|
+
## 🧾 Local tax numbers report
|
|
311
|
+
|
|
312
|
+
Every company you checked — single and bulk VAT checks and Smart Enrichment lookups — once, with its **local tax
|
|
313
|
+
number** (NIP, SIREN, Partita IVA, Steuernummer …), the number's national name and where it comes from (`vat_id` =
|
|
314
|
+
read off the confirmed VAT ID, `company_website` = published by the company). All filters are optional.
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
import { parseLocalTaxNumbersCsv } from '@taxora/sdk';
|
|
318
|
+
import { writeFileSync } from 'node:fs';
|
|
319
|
+
|
|
320
|
+
// Parsed rows (BOM dropped, cells trimmed, empty cells null)
|
|
321
|
+
const rows = await client.vat.localTaxNumbers({
|
|
322
|
+
dateFrom: '2026-10-01', // optional (YYYY-MM-DD or Date)
|
|
323
|
+
dateTo: '2026-10-31', // optional
|
|
324
|
+
countries: ['PL', 'IT'], // optional (ISO-2)
|
|
325
|
+
onlyWithTaxNumber: true, // optional: skip companies without one
|
|
326
|
+
});
|
|
327
|
+
for (const row of rows) {
|
|
328
|
+
// e.g. Orlen S.A. PL 5260250995 (NIP, vat_id)
|
|
329
|
+
console.log(`${row.companyName} ${row.country} ${row.taxNumber} (${row.taxNumberName}, ${row.taxNumberSource})`);
|
|
330
|
+
}
|
|
331
|
+
// row.vatStatus: valid | invalid | unconfirmed | wrong_company | no_vat_id | not_found
|
|
332
|
+
// row.source: vat_check | smart_enrichment; row.checkId: the VAT check uuid or the lookup job id
|
|
333
|
+
|
|
334
|
+
// The raw CSV (UTF-8 with BOM) for a spreadsheet. Digit-only tax numbers carry a leading TAB so
|
|
335
|
+
// Excel keeps leading zeros; parseLocalTaxNumbersCsv() turns a saved file into rows.
|
|
336
|
+
writeFileSync('local-tax-numbers.csv', await client.vat.localTaxNumbersCsv({ countries: ['PL'] }));
|
|
337
|
+
|
|
338
|
+
// Counts for the same filters
|
|
339
|
+
const summary = await client.vat.localTaxNumbersSummary({ dateFrom: '2026-10-01' });
|
|
340
|
+
console.log(`${summary.withTaxNumber} of ${summary.companies} companies have a local tax number`);
|
|
341
|
+
```
|
|
342
|
+
|
|
310
343
|
## 🔎 Smart Enrichment (reverse VAT lookup)
|
|
311
344
|
|
|
312
345
|
Resolve a company **name + address + country → VAT number + confidence**. A confident match
|
|
@@ -370,6 +403,23 @@ console.log(result?.sourceUrl ?? '—'); // e.g. 'https://example.de/impressum'
|
|
|
370
403
|
console.log(result?.sourceUrls.join(', ')); // every page it was found on, main one first
|
|
371
404
|
console.log(result?.registeredOwner ?? '—'); // e.g. 'Kevin Seibel'
|
|
372
405
|
|
|
406
|
+
// The official VAT check behind a found number. nameMatch 'mismatch' means the register has the
|
|
407
|
+
// number under a different name — another company, unless `registeredOwner` is set (an e.K. filed
|
|
408
|
+
// under its owner): then write officialName / officialAddress into your own records.
|
|
409
|
+
if (result?.nameMismatch()) {
|
|
410
|
+
console.log(result.officialName, result.officialAddress);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// `taxNumber` is the company's LOCAL tax / business number — what domestic e-invoicing asks for.
|
|
414
|
+
// On 'found' it is read off the confirmed VAT ID where that country's VAT ID contains it
|
|
415
|
+
// (taxNumberSource 'vat_id': FR SIREN, IT Partita IVA, ES NIF, PL NIP, BE, DK CVR, CZ IČO, …).
|
|
416
|
+
// Otherwise it is a number the company published itself ('company_website', e.g. a German
|
|
417
|
+
// Steuernummer shown under the VAT ID heading) — that one is not a VAT ID.
|
|
418
|
+
console.log(result?.taxNumber ?? '—'); // e.g. '5260250995'
|
|
419
|
+
console.log(result?.taxNumberType ?? '—'); // e.g. 'pl_nip', 'fr_siren', 'de_steuernummer'
|
|
420
|
+
console.log(result?.taxNumberLabel ?? '—'); // e.g. 'NIP'
|
|
421
|
+
console.log(result?.taxNumberSource ?? '—'); // 'vat_id' | 'company_website'
|
|
422
|
+
|
|
373
423
|
// 'not_found' doesn't always mean nothing turned up. When the research found a VAT number but
|
|
374
424
|
// the official check threw it out (e.g. the tax authority reports it as invalid), the number
|
|
375
425
|
// and the reason are in `rejectedCandidates` — no need to re-check it yourself.
|
package/dist/index.cjs
CHANGED
|
@@ -46,6 +46,7 @@ __export(index_exports, {
|
|
|
46
46
|
ImportResult: () => ImportResult,
|
|
47
47
|
InMemoryTokenStorage: () => InMemoryTokenStorage,
|
|
48
48
|
Language: () => Language,
|
|
49
|
+
LocalTaxNumberRow: () => LocalTaxNumberRow,
|
|
49
50
|
LoginIdentifier: () => LoginIdentifier,
|
|
50
51
|
NorwegianOrgNumber: () => NorwegianOrgNumber,
|
|
51
52
|
PeppolLookupResult: () => PeppolLookupResult,
|
|
@@ -98,6 +99,7 @@ __export(index_exports, {
|
|
|
98
99
|
generateWebhookSignatureHeader: () => generateWebhookSignatureHeader,
|
|
99
100
|
getBaseUrl: () => getBaseUrl,
|
|
100
101
|
getFailedVatStates: () => getFailedVatStates,
|
|
102
|
+
parseLocalTaxNumbersCsv: () => parseLocalTaxNumbersCsv,
|
|
101
103
|
parseWebhookSignatureHeader: () => parseWebhookSignatureHeader,
|
|
102
104
|
toComplianceDocumentType: () => toComplianceDocumentType,
|
|
103
105
|
toComplianceEnrollmentStatus: () => toComplianceEnrollmentStatus,
|
|
@@ -2430,8 +2432,22 @@ function toRejectedCandidates(value) {
|
|
|
2430
2432
|
}
|
|
2431
2433
|
return candidates;
|
|
2432
2434
|
}
|
|
2435
|
+
function toOfficialAddress(value) {
|
|
2436
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2437
|
+
return void 0;
|
|
2438
|
+
}
|
|
2439
|
+
const record = value;
|
|
2440
|
+
const address = {};
|
|
2441
|
+
for (const key of ["street", "postal_code", "city", "country"]) {
|
|
2442
|
+
const part = typeof record[key] === "string" ? record[key].trim() : "";
|
|
2443
|
+
if (part !== "") {
|
|
2444
|
+
address[key] = part;
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
return Object.keys(address).length > 0 ? address : void 0;
|
|
2448
|
+
}
|
|
2433
2449
|
var SmartEnrichmentResource = class _SmartEnrichmentResource {
|
|
2434
|
-
constructor(status, vatNumber, vatType, confidence, matchedCompanyName, matchedAddress, country, source, mode = void 0, providerVerdicts = [], addressQuality = void 0, rejectedCandidates = [], sourceUrl = void 0, registeredOwner = void 0, sourceUrls = []) {
|
|
2450
|
+
constructor(status, vatNumber, vatType, confidence, matchedCompanyName, matchedAddress, country, source, mode = void 0, providerVerdicts = [], addressQuality = void 0, rejectedCandidates = [], sourceUrl = void 0, registeredOwner = void 0, sourceUrls = [], taxNumber = void 0, vatValid = void 0, aiScore = void 0, nameMatch = void 0, officialName = void 0, officialAddress = void 0, taxNumberType = void 0, taxNumberLabel = void 0, taxNumberSource = void 0) {
|
|
2435
2451
|
this.status = status;
|
|
2436
2452
|
this.vatNumber = vatNumber;
|
|
2437
2453
|
this.vatType = vatType;
|
|
@@ -2447,6 +2463,15 @@ var SmartEnrichmentResource = class _SmartEnrichmentResource {
|
|
|
2447
2463
|
this.sourceUrl = sourceUrl;
|
|
2448
2464
|
this.registeredOwner = registeredOwner;
|
|
2449
2465
|
this.sourceUrls = sourceUrls;
|
|
2466
|
+
this.taxNumber = taxNumber;
|
|
2467
|
+
this.vatValid = vatValid;
|
|
2468
|
+
this.aiScore = aiScore;
|
|
2469
|
+
this.nameMatch = nameMatch;
|
|
2470
|
+
this.officialName = officialName;
|
|
2471
|
+
this.officialAddress = officialAddress;
|
|
2472
|
+
this.taxNumberType = taxNumberType;
|
|
2473
|
+
this.taxNumberLabel = taxNumberLabel;
|
|
2474
|
+
this.taxNumberSource = taxNumberSource;
|
|
2450
2475
|
}
|
|
2451
2476
|
status;
|
|
2452
2477
|
vatNumber;
|
|
@@ -2463,6 +2488,19 @@ var SmartEnrichmentResource = class _SmartEnrichmentResource {
|
|
|
2463
2488
|
sourceUrl;
|
|
2464
2489
|
registeredOwner;
|
|
2465
2490
|
sourceUrls;
|
|
2491
|
+
taxNumber;
|
|
2492
|
+
vatValid;
|
|
2493
|
+
aiScore;
|
|
2494
|
+
nameMatch;
|
|
2495
|
+
officialName;
|
|
2496
|
+
officialAddress;
|
|
2497
|
+
taxNumberType;
|
|
2498
|
+
taxNumberLabel;
|
|
2499
|
+
taxNumberSource;
|
|
2500
|
+
/** True when the register knows the number under a different name than the one requested. */
|
|
2501
|
+
nameMismatch() {
|
|
2502
|
+
return this.nameMatch === "mismatch";
|
|
2503
|
+
}
|
|
2466
2504
|
/** True when a VAT number was found but rejected by the official check. */
|
|
2467
2505
|
hasRejectedCandidates() {
|
|
2468
2506
|
return this.rejectedCandidates.length > 0;
|
|
@@ -2500,7 +2538,16 @@ var SmartEnrichmentResource = class _SmartEnrichmentResource {
|
|
|
2500
2538
|
toRejectedCandidates(data["rejectedCandidates"]),
|
|
2501
2539
|
url && isWebUrl(url) ? url : void 0,
|
|
2502
2540
|
text("registeredOwner"),
|
|
2503
|
-
Array.isArray(urls) ? [...new Set(urls.filter(isWebUrl).map((u) => u.trim()))] : []
|
|
2541
|
+
Array.isArray(urls) ? [...new Set(urls.filter(isWebUrl).map((u) => u.trim()))] : [],
|
|
2542
|
+
text("taxNumber"),
|
|
2543
|
+
typeof data["vatValid"] === "boolean" ? data["vatValid"] : void 0,
|
|
2544
|
+
num("aiScore"),
|
|
2545
|
+
data["nameMatch"] === "ok" || data["nameMatch"] === "mismatch" ? data["nameMatch"] : void 0,
|
|
2546
|
+
text("officialName"),
|
|
2547
|
+
toOfficialAddress(data["officialAddress"]),
|
|
2548
|
+
text("taxNumberType"),
|
|
2549
|
+
text("taxNumberLabel"),
|
|
2550
|
+
data["taxNumberSource"] === "vat_id" || data["taxNumberSource"] === "company_website" ? data["taxNumberSource"] : void 0
|
|
2504
2551
|
);
|
|
2505
2552
|
}
|
|
2506
2553
|
toArray() {
|
|
@@ -2519,7 +2566,16 @@ var SmartEnrichmentResource = class _SmartEnrichmentResource {
|
|
|
2519
2566
|
rejectedCandidates: this.rejectedCandidates.map((c) => ({ vatNumber: c.vatNumber, reason: c.reason })),
|
|
2520
2567
|
sourceUrl: this.sourceUrl ?? null,
|
|
2521
2568
|
registeredOwner: this.registeredOwner ?? null,
|
|
2522
|
-
sourceUrls: this.sourceUrls
|
|
2569
|
+
sourceUrls: this.sourceUrls,
|
|
2570
|
+
taxNumber: this.taxNumber ?? null,
|
|
2571
|
+
vatValid: this.vatValid ?? null,
|
|
2572
|
+
aiScore: this.aiScore ?? null,
|
|
2573
|
+
nameMatch: this.nameMatch ?? null,
|
|
2574
|
+
officialName: this.officialName ?? null,
|
|
2575
|
+
officialAddress: this.officialAddress ?? null,
|
|
2576
|
+
taxNumberType: this.taxNumberType ?? null,
|
|
2577
|
+
taxNumberLabel: this.taxNumberLabel ?? null,
|
|
2578
|
+
taxNumberSource: this.taxNumberSource ?? null
|
|
2523
2579
|
};
|
|
2524
2580
|
}
|
|
2525
2581
|
};
|
|
@@ -3527,6 +3583,123 @@ var VatValidationAddressInput = class _VatValidationAddressInput {
|
|
|
3527
3583
|
}
|
|
3528
3584
|
};
|
|
3529
3585
|
|
|
3586
|
+
// src/dto/LocalTaxNumberReport.ts
|
|
3587
|
+
var LocalTaxNumberRow = class _LocalTaxNumberRow {
|
|
3588
|
+
constructor(companyName, requestedName, country, vatNumber, vatStatus, taxNumber, taxNumberName, taxNumberSource, source, checkedAt, checkId) {
|
|
3589
|
+
this.companyName = companyName;
|
|
3590
|
+
this.requestedName = requestedName;
|
|
3591
|
+
this.country = country;
|
|
3592
|
+
this.vatNumber = vatNumber;
|
|
3593
|
+
this.vatStatus = vatStatus;
|
|
3594
|
+
this.taxNumber = taxNumber;
|
|
3595
|
+
this.taxNumberName = taxNumberName;
|
|
3596
|
+
this.taxNumberSource = taxNumberSource;
|
|
3597
|
+
this.source = source;
|
|
3598
|
+
this.checkedAt = checkedAt;
|
|
3599
|
+
this.checkId = checkId;
|
|
3600
|
+
}
|
|
3601
|
+
companyName;
|
|
3602
|
+
requestedName;
|
|
3603
|
+
country;
|
|
3604
|
+
vatNumber;
|
|
3605
|
+
vatStatus;
|
|
3606
|
+
taxNumber;
|
|
3607
|
+
taxNumberName;
|
|
3608
|
+
taxNumberSource;
|
|
3609
|
+
source;
|
|
3610
|
+
checkedAt;
|
|
3611
|
+
checkId;
|
|
3612
|
+
/** One CSV row keyed by column name. */
|
|
3613
|
+
static fromArray(data) {
|
|
3614
|
+
const cell = (key) => {
|
|
3615
|
+
const value = data[key];
|
|
3616
|
+
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
3617
|
+
return trimmed === "" ? null : trimmed;
|
|
3618
|
+
};
|
|
3619
|
+
return new _LocalTaxNumberRow(
|
|
3620
|
+
cell("companyName"),
|
|
3621
|
+
cell("requestedName"),
|
|
3622
|
+
cell("country"),
|
|
3623
|
+
cell("vatNumber"),
|
|
3624
|
+
cell("vatStatus"),
|
|
3625
|
+
cell("taxNumber"),
|
|
3626
|
+
cell("taxNumberName"),
|
|
3627
|
+
cell("taxNumberSource"),
|
|
3628
|
+
cell("source"),
|
|
3629
|
+
cell("checkedAt"),
|
|
3630
|
+
cell("checkId")
|
|
3631
|
+
);
|
|
3632
|
+
}
|
|
3633
|
+
toArray() {
|
|
3634
|
+
return {
|
|
3635
|
+
companyName: this.companyName,
|
|
3636
|
+
requestedName: this.requestedName,
|
|
3637
|
+
country: this.country,
|
|
3638
|
+
vatNumber: this.vatNumber,
|
|
3639
|
+
vatStatus: this.vatStatus,
|
|
3640
|
+
taxNumber: this.taxNumber,
|
|
3641
|
+
taxNumberName: this.taxNumberName,
|
|
3642
|
+
taxNumberSource: this.taxNumberSource,
|
|
3643
|
+
source: this.source,
|
|
3644
|
+
checkedAt: this.checkedAt,
|
|
3645
|
+
checkId: this.checkId
|
|
3646
|
+
};
|
|
3647
|
+
}
|
|
3648
|
+
};
|
|
3649
|
+
function parseCsvRecords(csv) {
|
|
3650
|
+
const records = [];
|
|
3651
|
+
let record = [];
|
|
3652
|
+
let cell = "";
|
|
3653
|
+
let quoted = false;
|
|
3654
|
+
for (let i = 0; i < csv.length; i++) {
|
|
3655
|
+
const ch = csv[i];
|
|
3656
|
+
if (quoted) {
|
|
3657
|
+
if (ch === '"') {
|
|
3658
|
+
if (csv[i + 1] === '"') {
|
|
3659
|
+
cell += '"';
|
|
3660
|
+
i++;
|
|
3661
|
+
} else {
|
|
3662
|
+
quoted = false;
|
|
3663
|
+
}
|
|
3664
|
+
} else {
|
|
3665
|
+
cell += ch;
|
|
3666
|
+
}
|
|
3667
|
+
} else if (ch === '"') {
|
|
3668
|
+
quoted = true;
|
|
3669
|
+
} else if (ch === ",") {
|
|
3670
|
+
record.push(cell);
|
|
3671
|
+
cell = "";
|
|
3672
|
+
} else if (ch === "\n" || ch === "\r") {
|
|
3673
|
+
if (ch === "\r" && csv[i + 1] === "\n") i++;
|
|
3674
|
+
record.push(cell);
|
|
3675
|
+
records.push(record);
|
|
3676
|
+
record = [];
|
|
3677
|
+
cell = "";
|
|
3678
|
+
} else {
|
|
3679
|
+
cell += ch;
|
|
3680
|
+
}
|
|
3681
|
+
}
|
|
3682
|
+
if (cell !== "" || record.length > 0) {
|
|
3683
|
+
record.push(cell);
|
|
3684
|
+
records.push(record);
|
|
3685
|
+
}
|
|
3686
|
+
return records.filter((r) => !(r.length === 1 && r[0] === ""));
|
|
3687
|
+
}
|
|
3688
|
+
function parseLocalTaxNumbersCsv(csv) {
|
|
3689
|
+
const [header, ...records] = parseCsvRecords(csv.replace(/^\uFEFF/, ""));
|
|
3690
|
+
if (!header) {
|
|
3691
|
+
return [];
|
|
3692
|
+
}
|
|
3693
|
+
const names = header.map((name) => name.trim());
|
|
3694
|
+
return records.map((cells) => {
|
|
3695
|
+
const row = {};
|
|
3696
|
+
names.forEach((name, i) => {
|
|
3697
|
+
row[name] = cells[i];
|
|
3698
|
+
});
|
|
3699
|
+
return LocalTaxNumberRow.fromArray(row);
|
|
3700
|
+
});
|
|
3701
|
+
}
|
|
3702
|
+
|
|
3530
3703
|
// src/endpoints/VatEndpoint.ts
|
|
3531
3704
|
var DATE_REGEX2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
3532
3705
|
var VatEndpoint = class {
|
|
@@ -3637,6 +3810,69 @@ var VatEndpoint = class {
|
|
|
3637
3810
|
return new Uint8Array(buffer);
|
|
3638
3811
|
});
|
|
3639
3812
|
}
|
|
3813
|
+
/**
|
|
3814
|
+
* Local tax numbers report as raw CSV (UTF-8 with BOM, comma-separated): every company checked —
|
|
3815
|
+
* single and bulk VAT checks and Smart Enrichment lookups — once, with its local tax number
|
|
3816
|
+
* (taxNumber, taxNumberName, taxNumberSource). Digit-only taxNumber cells carry a leading TAB so
|
|
3817
|
+
* Excel keeps them as text; `localTaxNumbers()` strips it for you.
|
|
3818
|
+
*/
|
|
3819
|
+
async localTaxNumbersCsv(options = {}) {
|
|
3820
|
+
const params = this.localTaxNumbersParams(options);
|
|
3821
|
+
if (options.onlyWithTaxNumber !== void 0) {
|
|
3822
|
+
params.set("only_with_tax_number", options.onlyWithTaxNumber ? "1" : "0");
|
|
3823
|
+
}
|
|
3824
|
+
const url = this.withQuery(`${this.baseUrl}/reports/local-tax-numbers`, params);
|
|
3825
|
+
return withRetries(this.retryPolicy, "Local tax numbers report", async () => {
|
|
3826
|
+
const headers = this.buildHeaders();
|
|
3827
|
+
delete headers["Content-Type"];
|
|
3828
|
+
headers["Accept"] = "text/csv, application/json";
|
|
3829
|
+
const response = await this.httpClient.request("GET", url, { headers });
|
|
3830
|
+
if (response.status === 422) {
|
|
3831
|
+
await this.parseJsonResponse(response);
|
|
3832
|
+
}
|
|
3833
|
+
const text = new TextDecoder("utf-8", { ignoreBOM: true }).decode(await response.arrayBuffer());
|
|
3834
|
+
if (!response.ok) {
|
|
3835
|
+
throw new HttpException(
|
|
3836
|
+
describeApiError(text, response.status),
|
|
3837
|
+
response.status,
|
|
3838
|
+
text,
|
|
3839
|
+
{},
|
|
3840
|
+
response.headers.get("retry-after")
|
|
3841
|
+
);
|
|
3842
|
+
}
|
|
3843
|
+
return text;
|
|
3844
|
+
});
|
|
3845
|
+
}
|
|
3846
|
+
/** The local tax numbers report, parsed: one row per company (same filters as `localTaxNumbersCsv()`). */
|
|
3847
|
+
async localTaxNumbers(options = {}) {
|
|
3848
|
+
return parseLocalTaxNumbersCsv(await this.localTaxNumbersCsv(options));
|
|
3849
|
+
}
|
|
3850
|
+
/** How many companies the report would list for the filters, and how many have a tax number. */
|
|
3851
|
+
async localTaxNumbersSummary(options = {}) {
|
|
3852
|
+
const url = this.withQuery(
|
|
3853
|
+
`${this.baseUrl}/reports/local-tax-numbers/summary`,
|
|
3854
|
+
this.localTaxNumbersParams(options)
|
|
3855
|
+
);
|
|
3856
|
+
return withRetries(this.retryPolicy, "Local tax numbers summary", async () => {
|
|
3857
|
+
const response = await this.sendRequest("GET", url);
|
|
3858
|
+
const data = await this.parseJsonResponse(response);
|
|
3859
|
+
const count = (key) => typeof data[key] === "number" ? data[key] : 0;
|
|
3860
|
+
return { companies: count("companies"), withTaxNumber: count("withTaxNumber") };
|
|
3861
|
+
});
|
|
3862
|
+
}
|
|
3863
|
+
localTaxNumbersParams(options) {
|
|
3864
|
+
const params = new URLSearchParams();
|
|
3865
|
+
if (options.dateFrom !== void 0) params.set("date_from", this.formatDate(options.dateFrom));
|
|
3866
|
+
if (options.dateTo !== void 0) params.set("date_to", this.formatDate(options.dateTo));
|
|
3867
|
+
for (const country of options.countries ?? []) {
|
|
3868
|
+
params.append("countries[]", country.trim().toUpperCase());
|
|
3869
|
+
}
|
|
3870
|
+
return params;
|
|
3871
|
+
}
|
|
3872
|
+
withQuery(url, params) {
|
|
3873
|
+
const queryString = params.toString();
|
|
3874
|
+
return queryString ? `${url}?${queryString}` : url;
|
|
3875
|
+
}
|
|
3640
3876
|
buildHeaders() {
|
|
3641
3877
|
const headers = {
|
|
3642
3878
|
"Content-Type": "application/json",
|
|
@@ -3797,7 +4033,7 @@ var AuthRetryHttpClient = class {
|
|
|
3797
4033
|
};
|
|
3798
4034
|
|
|
3799
4035
|
// src/version.ts
|
|
3800
|
-
var SDK_VERSION = "1.
|
|
4036
|
+
var SDK_VERSION = "1.7.0";
|
|
3801
4037
|
|
|
3802
4038
|
// src/http/SdkVersionHttpClient.ts
|
|
3803
4039
|
var SDK_VERSION_HEADER = "X-Taxora-SDK-Version";
|
|
@@ -4011,6 +4247,7 @@ function toBytes(rawBody) {
|
|
|
4011
4247
|
ImportResult,
|
|
4012
4248
|
InMemoryTokenStorage,
|
|
4013
4249
|
Language,
|
|
4250
|
+
LocalTaxNumberRow,
|
|
4014
4251
|
LoginIdentifier,
|
|
4015
4252
|
NorwegianOrgNumber,
|
|
4016
4253
|
PeppolLookupResult,
|
|
@@ -4063,6 +4300,7 @@ function toBytes(rawBody) {
|
|
|
4063
4300
|
generateWebhookSignatureHeader,
|
|
4064
4301
|
getBaseUrl,
|
|
4065
4302
|
getFailedVatStates,
|
|
4303
|
+
parseLocalTaxNumbersCsv,
|
|
4066
4304
|
parseWebhookSignatureHeader,
|
|
4067
4305
|
toComplianceDocumentType,
|
|
4068
4306
|
toComplianceEnrollmentStatus,
|