389 lines
10 KiB
TypeScript
389 lines
10 KiB
TypeScript
import type { SimpleAccountResponse } from './account'
|
|
import type { Attachment } from './attachment'
|
|
import { ApiClient } from './base'
|
|
import type { Currency } from './data'
|
|
import { type Page, type PageRequest } from './pagination'
|
|
|
|
export interface SimpleVendorResponse {
|
|
id: number
|
|
name: string
|
|
}
|
|
|
|
export interface SimpleCategoryResponse {
|
|
id: number
|
|
name: string
|
|
color: string
|
|
}
|
|
|
|
export interface TransactionLineItemResponse {
|
|
idx: number
|
|
valuePerItem: number
|
|
quantity: number
|
|
description: string
|
|
category: TransactionCategory | null
|
|
}
|
|
|
|
export interface TransactionVendor {
|
|
id: number
|
|
name: string
|
|
description: string | null
|
|
}
|
|
|
|
export interface TransactionVendorPayload {
|
|
name: string
|
|
description: string | null
|
|
}
|
|
|
|
export interface TransactionCategory {
|
|
id: number
|
|
parentId: number | null
|
|
name: string
|
|
description: string | null
|
|
color: string
|
|
}
|
|
|
|
export interface TransactionCategoryTree {
|
|
id: number
|
|
parentId: number | null
|
|
name: string
|
|
description: string
|
|
color: string
|
|
children: TransactionCategoryTree[]
|
|
depth: number
|
|
}
|
|
|
|
export interface TransactionCategoryBalance {
|
|
credits: number
|
|
debits: number
|
|
balance: number
|
|
currency: Currency
|
|
}
|
|
|
|
export interface TransactionsListItem {
|
|
id: number
|
|
timestamp: string
|
|
addedAt: string
|
|
amount: number
|
|
currency: Currency
|
|
description: string
|
|
internalTransfer: boolean
|
|
vendor: SimpleVendorResponse | null
|
|
category: SimpleCategoryResponse | null
|
|
creditedAccount: SimpleAccountResponse | null
|
|
debitedAccount: SimpleAccountResponse | null
|
|
tags: string[]
|
|
}
|
|
|
|
export interface TransactionsListItemVendor {
|
|
id: number
|
|
name: string
|
|
}
|
|
|
|
export interface TransactionsListItemCategory {
|
|
id: number
|
|
name: string
|
|
color: string
|
|
}
|
|
|
|
export interface TransactionsListItemAccount {
|
|
id: number
|
|
name: string
|
|
type: string
|
|
numberSuffix: string
|
|
}
|
|
|
|
export interface TransactionDetail {
|
|
id: number
|
|
timestamp: string
|
|
addedAt: string
|
|
amount: number
|
|
currency: Currency
|
|
description: string
|
|
internalTransfer: boolean
|
|
vendor: TransactionVendor | null
|
|
category: TransactionCategory | null
|
|
creditedAccount: SimpleAccountResponse | null
|
|
debitedAccount: SimpleAccountResponse | null
|
|
tags: string[]
|
|
lineItems: TransactionLineItemResponse[]
|
|
attachments: Attachment[]
|
|
}
|
|
|
|
export interface AddTransactionPayload {
|
|
timestamp: string
|
|
amount: number
|
|
currencyCode: string
|
|
description: string
|
|
internalTransfer: boolean
|
|
vendorId: number | null
|
|
categoryId: number | null
|
|
creditedAccountId: number | null
|
|
debitedAccountId: number | null
|
|
tags: string[]
|
|
lineItems: AddTransactionPayloadLineItem[]
|
|
attachmentIdsToRemove: number[]
|
|
}
|
|
|
|
export interface AddTransactionPayloadLineItem {
|
|
valuePerItem: number
|
|
quantity: number
|
|
description: string
|
|
categoryId: number | null
|
|
}
|
|
|
|
export interface CreateCategoryPayload {
|
|
name: string
|
|
description: string | null
|
|
color: string
|
|
parentId: number | null
|
|
}
|
|
|
|
export interface AggregateTransactionCurrencyData {
|
|
credits: number
|
|
debits: number
|
|
balance: number
|
|
currency: Currency
|
|
}
|
|
|
|
export interface AggregateTransactionData {
|
|
currencies: AggregateTransactionCurrencyData[]
|
|
}
|
|
|
|
export interface TransactionDraftListItem {
|
|
id: number
|
|
addedAt: string
|
|
templateName: string | null
|
|
timestamp: string | null
|
|
amount: number | null
|
|
currency: Currency | null
|
|
description: string | null
|
|
internalTransfer: boolean | null
|
|
vendor: SimpleVendorResponse | null
|
|
category: SimpleCategoryResponse | null
|
|
creditedAccount: SimpleAccountResponse | null
|
|
debitedAccount: SimpleAccountResponse | null
|
|
tags: string[]
|
|
}
|
|
|
|
export interface TransactionDraftResponse {
|
|
id: number
|
|
addedAt: string
|
|
templateName: string | null
|
|
timestamp: string | null
|
|
amount: number | null
|
|
currency: Currency | null
|
|
description: string | null
|
|
internalTransfer: boolean | null
|
|
vendor: SimpleVendorResponse | null
|
|
category: SimpleCategoryResponse | null
|
|
creditedAccount: SimpleAccountResponse | null
|
|
debitedAccount: SimpleAccountResponse | null
|
|
tags: string[]
|
|
lineItems: TransactionLineItemResponse[]
|
|
attachments: Attachment[]
|
|
}
|
|
|
|
export interface TransactionDraftPayload {
|
|
templateName: string | null
|
|
timestamp: string | null
|
|
amount: number | null
|
|
currencyCode: string | null
|
|
description: string | null
|
|
internalTransfer: boolean | null
|
|
vendorId: number | null
|
|
categoryId: number | null
|
|
creditedAccountId: number | null
|
|
debitedAccountId: number | null
|
|
tags: string[]
|
|
lineItems: AddTransactionPayloadLineItem[]
|
|
attachmentIdsToRemove: number[]
|
|
}
|
|
|
|
export class TransactionApiClient extends ApiClient {
|
|
readonly path: string
|
|
|
|
constructor(profileName: string) {
|
|
super()
|
|
this.path = `/profiles/${profileName}`
|
|
}
|
|
|
|
getVendors(): Promise<TransactionVendor[]> {
|
|
return super.getJson(this.path + '/vendors')
|
|
}
|
|
|
|
getVendor(id: number): Promise<TransactionVendor> {
|
|
return super.getJson(this.path + '/vendors/' + id)
|
|
}
|
|
|
|
createVendor(data: TransactionVendorPayload): Promise<TransactionVendor> {
|
|
return super.postJson(this.path + '/vendors', data)
|
|
}
|
|
|
|
updateVendor(id: number, data: TransactionVendorPayload): Promise<TransactionVendor> {
|
|
return super.putJson(this.path + '/vendors/' + id, data)
|
|
}
|
|
|
|
deleteVendor(id: number): Promise<void> {
|
|
return super.delete(this.path + '/vendors/' + id)
|
|
}
|
|
|
|
getCategories(): Promise<TransactionCategoryTree[]> {
|
|
return super.getJson(this.path + '/categories')
|
|
}
|
|
|
|
async getCategoriesFlattened(): Promise<TransactionCategoryTree[]> {
|
|
const categories = await this.getCategories()
|
|
const flat: TransactionCategoryTree[] = []
|
|
await this.flattenCategories(flat, categories)
|
|
return flat
|
|
}
|
|
|
|
private flattenCategories(arr: TransactionCategoryTree[], tree: TransactionCategoryTree[]) {
|
|
for (const category of tree) {
|
|
arr.push(category)
|
|
this.flattenCategories(arr, category.children)
|
|
}
|
|
}
|
|
|
|
getCategory(id: number): Promise<TransactionCategory> {
|
|
return super.getJson(this.path + '/categories/' + id)
|
|
}
|
|
|
|
getChildCategories(parentId: number): Promise<TransactionCategory[]> {
|
|
return super.getJson(this.path + '/categories/' + parentId + '/children')
|
|
}
|
|
|
|
getCategoryBalances(id: number, includeChildren: boolean): Promise<TransactionCategoryBalance[]> {
|
|
return super.getJson(
|
|
this.path + '/categories/' + id + '/balances?includeChildren=' + includeChildren,
|
|
)
|
|
}
|
|
|
|
createCategory(data: CreateCategoryPayload): Promise<TransactionCategory> {
|
|
return super.postJson(this.path + '/categories', data)
|
|
}
|
|
|
|
updateCategory(id: number, data: CreateCategoryPayload): Promise<TransactionCategory> {
|
|
return super.putJson(this.path + '/categories/' + id, data)
|
|
}
|
|
|
|
deleteCategory(id: number): Promise<void> {
|
|
return super.delete(this.path + '/categories/' + id)
|
|
}
|
|
|
|
getTransactions(
|
|
paginationOptions: PageRequest | undefined = undefined,
|
|
): Promise<Page<TransactionsListItem>> {
|
|
return super.getJsonPage(this.path + '/transactions', paginationOptions)
|
|
}
|
|
|
|
searchTransactions(
|
|
params: URLSearchParams,
|
|
paginationOptions: PageRequest | undefined = undefined,
|
|
): Promise<Page<TransactionsListItem>> {
|
|
if (paginationOptions !== undefined) {
|
|
params.append('page', paginationOptions.page + '')
|
|
params.append('size', paginationOptions.size + '')
|
|
for (const sort of paginationOptions.sorts) {
|
|
params.append('sort', sort.attribute + ',' + sort.dir)
|
|
}
|
|
}
|
|
return super.getJson(this.path + '/transactions/search?' + params.toString())
|
|
}
|
|
|
|
getAggregateTransactionData(params: URLSearchParams): Promise<AggregateTransactionData> {
|
|
return super.getJson(this.path + '/transactions/aggregate-data?' + params.toString())
|
|
}
|
|
|
|
exportTransactions(params: URLSearchParams): Promise<void> {
|
|
return super.getFile(this.path + '/transactions/export?' + params.toString())
|
|
}
|
|
|
|
getTransaction(id: number): Promise<TransactionDetail> {
|
|
return super.getJson(this.path + '/transactions/' + id)
|
|
}
|
|
|
|
addTransaction(data: AddTransactionPayload, files: File[] = []): Promise<TransactionDetail> {
|
|
const formData = new FormData()
|
|
formData.append('payload', JSON.stringify(data))
|
|
for (const file of files) {
|
|
formData.append('file', file)
|
|
}
|
|
return super.postFormData(this.path + '/transactions', formData)
|
|
}
|
|
|
|
updateTransaction(
|
|
id: number,
|
|
data: AddTransactionPayload,
|
|
files: File[] = [],
|
|
): Promise<TransactionDetail> {
|
|
const formData = new FormData()
|
|
formData.append('payload', JSON.stringify(data))
|
|
for (const file of files) {
|
|
formData.append('file', file)
|
|
}
|
|
return super.putFormData(this.path + '/transactions/' + id, formData)
|
|
}
|
|
|
|
deleteTransaction(id: number): Promise<void> {
|
|
return super.delete(this.path + '/transactions/' + id)
|
|
}
|
|
|
|
getAllTags(): Promise<string[]> {
|
|
return super.getJson(this.path + '/transaction-tags')
|
|
}
|
|
|
|
// Drafts:
|
|
|
|
getDrafts(
|
|
paginationOptions: PageRequest | undefined = undefined,
|
|
): Promise<Page<TransactionDraftListItem>> {
|
|
return super.getJsonPage(this.path + '/transaction-drafts', paginationOptions)
|
|
}
|
|
|
|
getTemplateDrafts(
|
|
paginationOptions: PageRequest | undefined = undefined,
|
|
): Promise<Page<TransactionDraftListItem>> {
|
|
const params = new URLSearchParams()
|
|
params.append('template', 'true')
|
|
if (paginationOptions !== undefined) {
|
|
params.append('page', paginationOptions.page + '')
|
|
params.append('size', paginationOptions.size + '')
|
|
for (const sort of paginationOptions.sorts) {
|
|
params.append('sort', sort.attribute + ',' + sort.dir)
|
|
}
|
|
}
|
|
return super.getJson(this.path + '/transaction-drafts?' + params.toString())
|
|
}
|
|
|
|
getDraft(id: number): Promise<TransactionDraftResponse> {
|
|
return super.getJson(this.path + '/transaction-drafts/' + id)
|
|
}
|
|
|
|
addDraft(data: TransactionDraftPayload, files: File[] = []): Promise<TransactionDraftResponse> {
|
|
const formData = new FormData()
|
|
formData.append('payload', JSON.stringify(data))
|
|
for (const file of files) {
|
|
formData.append('file', file)
|
|
}
|
|
return super.postFormData(this.path + '/transaction-drafts', formData)
|
|
}
|
|
|
|
updateDraft(
|
|
id: number,
|
|
data: TransactionDraftPayload,
|
|
files: File[] = [],
|
|
): Promise<TransactionDraftResponse> {
|
|
const formData = new FormData()
|
|
formData.append('payload', JSON.stringify(data))
|
|
for (const file of files) {
|
|
formData.append('file', file)
|
|
}
|
|
return super.putFormData(this.path + '/transaction-drafts/' + id, formData)
|
|
}
|
|
|
|
deleteDraft(id: number): Promise<void> {
|
|
return super.delete(this.path + '/transaction-drafts/' + id)
|
|
}
|
|
}
|