Fix/transaction inconsitensies (#190)
* fix: request explicit page size from Enable Banking API to fetch all transactions The API defaults to ~10 transactions per page when no limit is specified, causing incomplete syncs for users with more transactions. * fix: enhance DELETE operations and add missing RLS policies for multi-tenant support
This commit is contained in:
@@ -3,6 +3,8 @@ import type { BokioResourceConfig, RateLimitConfig } from '../types';
|
||||
import {
|
||||
mapBokioToSalesInvoice,
|
||||
mapBokioToCustomer,
|
||||
mapBokioToSupplier,
|
||||
mapBokioToSupplierInvoice,
|
||||
mapBokioToJournal,
|
||||
mapBokioToAccountingAccount,
|
||||
mapBokioToCompanyInformation,
|
||||
@@ -26,6 +28,20 @@ export const BOKIO_RESOURCE_CONFIGS: Partial<Record<ResourceType, BokioResourceC
|
||||
mapper: mapBokioToCustomer,
|
||||
paginated: true,
|
||||
},
|
||||
[ResourceType.Suppliers]: {
|
||||
listEndpoint: '/suppliers',
|
||||
detailEndpoint: '/suppliers/{id}',
|
||||
idField: 'id',
|
||||
mapper: mapBokioToSupplier,
|
||||
paginated: true,
|
||||
},
|
||||
[ResourceType.SupplierInvoices]: {
|
||||
listEndpoint: '/supplier-invoices',
|
||||
detailEndpoint: '/supplier-invoices/{id}',
|
||||
idField: 'id',
|
||||
mapper: mapBokioToSupplierInvoice,
|
||||
paginated: true,
|
||||
},
|
||||
[ResourceType.Journals]: {
|
||||
listEndpoint: '/journal-entries',
|
||||
detailEndpoint: '/journal-entries/{id}',
|
||||
|
||||
@@ -2,6 +2,8 @@ import type {
|
||||
SalesInvoiceDto, SalesInvoiceLineDto, InvoiceStatusCode,
|
||||
LegalMonetaryTotalDto, PaymentStatusDto,
|
||||
CustomerDto,
|
||||
SupplierDto,
|
||||
SupplierInvoiceDto, SupplierInvoiceLineDto,
|
||||
JournalDto, AccountingEntryDto,
|
||||
AccountingAccountDto, AccountType,
|
||||
CompanyInformationDto,
|
||||
@@ -195,6 +197,110 @@ export function mapBokioToAccountingAccount(raw: Record<string, unknown>): Accou
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Map Bokio Supplier to SupplierDto.
|
||||
*
|
||||
* Bokio Supplier fields:
|
||||
* - id, name, orgNumber, vatNumber, paymentTerms
|
||||
* - address: { line1, line2, city, postalCode, country }
|
||||
* - contactsDetails: [{ email, phone, name }]
|
||||
* - bankAccount, bankgiro, plusgiro
|
||||
*/
|
||||
export function mapBokioToSupplier(raw: Record<string, unknown>): SupplierDto {
|
||||
const name = (raw['name'] as string) ?? '';
|
||||
const orgNumber = raw['orgNumber'] as string | undefined;
|
||||
const address = raw['address'] as Record<string, unknown> | undefined;
|
||||
const contacts = (raw['contactsDetails'] as Record<string, unknown>[] | undefined) ?? [];
|
||||
const firstContact = contacts[0];
|
||||
|
||||
const party = buildParty(name, orgNumber, address);
|
||||
if (firstContact) {
|
||||
party.contact = {
|
||||
email: firstContact['email'] as string | undefined,
|
||||
telephone: firstContact['phone'] as string | undefined,
|
||||
name: firstContact['name'] as string | undefined,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
id: String(raw['id'] ?? ''),
|
||||
supplierNumber: String(raw['id'] ?? ''),
|
||||
party,
|
||||
active: true,
|
||||
vatNumber: raw['vatNumber'] as string | undefined,
|
||||
bankAccount: raw['bankAccount'] as string | undefined,
|
||||
bankGiro: raw['bankgiro'] as string | undefined,
|
||||
plusGiro: raw['plusgiro'] as string | undefined,
|
||||
defaultPaymentTermsDays: raw['paymentTerms'] != null ? Number(raw['paymentTerms']) : undefined,
|
||||
_raw: raw,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Map Bokio Supplier Invoice to SupplierInvoiceDto.
|
||||
*
|
||||
* Bokio Supplier Invoice fields:
|
||||
* - id, invoiceNumber, status (draft|published|paid|overdue|cancelled)
|
||||
* - invoiceDate, dueDate, currency, totalAmount, totalTax, paidAmount
|
||||
* - supplierRef: { id, name }, lineItems: [{ id, description, quantity, unitPrice, taxRate, unitType }]
|
||||
* - ocrNumber
|
||||
*/
|
||||
export function mapBokioToSupplierInvoice(raw: Record<string, unknown>): SupplierInvoiceDto {
|
||||
const currency = (raw['currency'] as string) ?? 'SEK';
|
||||
const totalAmount = (raw['totalAmount'] as number) ?? 0;
|
||||
const totalTax = (raw['totalTax'] as number) ?? 0;
|
||||
const paidAmount = (raw['paidAmount'] as number) ?? 0;
|
||||
const balance = totalAmount - paidAmount;
|
||||
|
||||
const supplierRef = raw['supplierRef'] as Record<string, unknown> | undefined;
|
||||
const rawLines = (raw['lineItems'] as Record<string, unknown>[] | undefined) ?? [];
|
||||
|
||||
const lines: SupplierInvoiceLineDto[] = rawLines.map((line, idx) => {
|
||||
const unitPrice = line['unitPrice'] as number | undefined;
|
||||
const quantity = line['quantity'] as number | undefined;
|
||||
const lineTotal = unitPrice != null && quantity != null ? unitPrice * quantity : 0;
|
||||
|
||||
return {
|
||||
id: String(line['id'] ?? idx + 1),
|
||||
description: line['description'] as string | undefined,
|
||||
quantity,
|
||||
unitCode: line['unitType'] as string | undefined,
|
||||
unitPrice: unitPrice != null ? amount(unitPrice, currency) : undefined,
|
||||
lineExtensionAmount: amount(lineTotal, currency),
|
||||
taxPercent: line['taxRate'] as number | undefined,
|
||||
};
|
||||
});
|
||||
|
||||
const legalMonetaryTotal: LegalMonetaryTotalDto = {
|
||||
lineExtensionAmount: amount(totalAmount - totalTax, currency),
|
||||
taxInclusiveAmount: amount(totalAmount, currency),
|
||||
payableAmount: amount(totalAmount, currency),
|
||||
};
|
||||
|
||||
const paymentStatus: PaymentStatusDto = {
|
||||
paid: paidAmount >= totalAmount && totalAmount > 0,
|
||||
balance: amount(balance, currency),
|
||||
};
|
||||
|
||||
return {
|
||||
id: String(raw['id'] ?? ''),
|
||||
invoiceNumber: String(raw['invoiceNumber'] ?? raw['id'] ?? ''),
|
||||
issueDate: (raw['invoiceDate'] as string) ?? '',
|
||||
dueDate: raw['dueDate'] as string | undefined,
|
||||
currencyCode: currency,
|
||||
status: deriveInvoiceStatus(raw),
|
||||
supplier: buildParty(
|
||||
(supplierRef?.['name'] as string) ?? '',
|
||||
),
|
||||
buyer: buildParty(''),
|
||||
lines,
|
||||
legalMonetaryTotal,
|
||||
paymentStatus,
|
||||
ocrNumber: raw['ocrNumber'] as string | undefined,
|
||||
_raw: raw,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Map Bokio Company to CompanyInformationDto.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user