246 lines
7.1 KiB
TypeScript
246 lines
7.1 KiB
TypeScript
import * as plugins from './bunq.plugins.js';
|
|
import { BunqAccount } from './bunq.classes.account.js';
|
|
import { BunqTransaction } from './bunq.classes.transaction.js';
|
|
import { BunqPayment } from './bunq.classes.payment.js';
|
|
import type { IBunqPaginationOptions, IBunqMonetaryAccountBank } from './bunq.interfaces.js';
|
|
|
|
export type TAccountType = 'bank' | 'joint' | 'savings' | 'external' | 'light' | 'card' | 'external_savings' | 'savings_external';
|
|
|
|
/**
|
|
* a monetary account
|
|
*/
|
|
export class BunqMonetaryAccount {
|
|
public static fromAPIObject(bunqAccountRef: BunqAccount, apiObject: any) {
|
|
const newMonetaryAccount = new this(bunqAccountRef);
|
|
|
|
let type: TAccountType;
|
|
let accessor: string;
|
|
|
|
switch (true) {
|
|
case !!apiObject.MonetaryAccountBank:
|
|
type = 'bank';
|
|
accessor = 'MonetaryAccountBank';
|
|
break;
|
|
case !!apiObject.MonetaryAccountJoint:
|
|
type = 'joint';
|
|
accessor = 'MonetaryAccountJoint';
|
|
break;
|
|
case !!apiObject.MonetaryAccountSavings:
|
|
type = 'savings';
|
|
accessor = 'MonetaryAccountSavings';
|
|
break;
|
|
case !!apiObject.MonetaryAccountExternal:
|
|
type = 'external';
|
|
accessor = 'MonetaryAccountExternal';
|
|
break;
|
|
case !!apiObject.MonetaryAccountLight:
|
|
type = 'light';
|
|
accessor = 'MonetaryAccountLight';
|
|
break;
|
|
case !!apiObject.MonetaryAccountCard:
|
|
type = 'card';
|
|
accessor = 'MonetaryAccountCard';
|
|
break;
|
|
case !!apiObject.MonetaryAccountExternalSavings:
|
|
type = 'external_savings';
|
|
accessor = 'MonetaryAccountExternalSavings';
|
|
break;
|
|
case !!apiObject.MonetaryAccountSavingsExternal:
|
|
type = 'savings_external';
|
|
accessor = 'MonetaryAccountSavingsExternal';
|
|
break;
|
|
default:
|
|
console.log('Unknown account type:', apiObject);
|
|
throw new Error('Unknown account type');
|
|
}
|
|
|
|
Object.assign(newMonetaryAccount, apiObject[accessor], { type });
|
|
return newMonetaryAccount;
|
|
}
|
|
|
|
// computed
|
|
public type: TAccountType;
|
|
|
|
// from API
|
|
public id: number;
|
|
public created: string;
|
|
public updated: string;
|
|
public alias: any[];
|
|
public avatar: {
|
|
uuid: string;
|
|
image: any[];
|
|
anchor_uuid: string;
|
|
};
|
|
public balance: {
|
|
currency: string;
|
|
value: string;
|
|
};
|
|
public country: string;
|
|
public currency: string;
|
|
public daily_limit: {
|
|
currency: string;
|
|
value: string;
|
|
};
|
|
public daily_spent: {
|
|
currency: string;
|
|
value: string;
|
|
};
|
|
public description: string;
|
|
public public_uuid: string;
|
|
public status: string;
|
|
public sub_status: string;
|
|
public timezone: string;
|
|
public user_id: number;
|
|
public monetary_account_profile: null;
|
|
public notification_filters: any[];
|
|
public setting: any[];
|
|
public connected_cards: any[];
|
|
public overdraft_limit: {
|
|
currency: string;
|
|
value: string;
|
|
};
|
|
public reason: string;
|
|
public reason_description: string;
|
|
public auto_save_id: null;
|
|
public all_auto_save_id: any[];
|
|
|
|
public bunqAccountRef: BunqAccount;
|
|
constructor(bunqAccountRefArg: BunqAccount) {
|
|
this.bunqAccountRef = bunqAccountRefArg;
|
|
}
|
|
|
|
/**
|
|
* gets all transactions on this account
|
|
* @param options - Pagination options or a number for backward compatibility (treated as newer_id)
|
|
*/
|
|
public async getTransactions(options?: IBunqPaginationOptions | number | false): Promise<BunqTransaction[]> {
|
|
let paginationOptions: IBunqPaginationOptions = {};
|
|
|
|
// Backward compatibility: if a number or false is passed, treat it as newer_id
|
|
if (typeof options === 'number' || options === false) {
|
|
paginationOptions.newer_id = options;
|
|
} else if (options) {
|
|
paginationOptions = { ...options };
|
|
}
|
|
|
|
// Set default count if not specified
|
|
if (!paginationOptions.count) {
|
|
paginationOptions.count = 200;
|
|
}
|
|
|
|
// Build clean pagination object - only include properties that are not false/undefined
|
|
const cleanPaginationOptions: IBunqPaginationOptions = {
|
|
count: paginationOptions.count,
|
|
};
|
|
|
|
if (paginationOptions.newer_id !== undefined && paginationOptions.newer_id !== false) {
|
|
cleanPaginationOptions.newer_id = paginationOptions.newer_id;
|
|
}
|
|
|
|
if (paginationOptions.older_id !== undefined && paginationOptions.older_id !== false) {
|
|
cleanPaginationOptions.older_id = paginationOptions.older_id;
|
|
}
|
|
|
|
await this.bunqAccountRef.apiContext.ensureValidSession();
|
|
|
|
const response = await this.bunqAccountRef.getHttpClient().list(
|
|
`/v1/user/${this.bunqAccountRef.userId}/monetary-account/${this.id}/payment`,
|
|
cleanPaginationOptions
|
|
);
|
|
|
|
const transactionsArray: BunqTransaction[] = [];
|
|
|
|
if (response.Response) {
|
|
for (const apiTransaction of response.Response) {
|
|
transactionsArray.push(BunqTransaction.fromApiObject(this, apiTransaction));
|
|
}
|
|
}
|
|
|
|
return transactionsArray;
|
|
}
|
|
|
|
/**
|
|
* Create a payment from this account
|
|
*/
|
|
public async createPayment(payment: BunqPayment): Promise<number> {
|
|
return payment.create();
|
|
}
|
|
|
|
/**
|
|
* Update account settings
|
|
*/
|
|
public async update(updates: any): Promise<void> {
|
|
await this.bunqAccountRef.apiContext.ensureValidSession();
|
|
|
|
const endpoint = `/v1/user/${this.bunqAccountRef.userId}/monetary-account/${this.id}`;
|
|
|
|
// Determine the correct update key based on account type
|
|
let updateKey: string;
|
|
switch (this.type) {
|
|
case 'bank':
|
|
updateKey = 'MonetaryAccountBank';
|
|
break;
|
|
case 'joint':
|
|
updateKey = 'MonetaryAccountJoint';
|
|
break;
|
|
case 'savings':
|
|
updateKey = 'MonetaryAccountSavings';
|
|
break;
|
|
case 'external':
|
|
updateKey = 'MonetaryAccountExternal';
|
|
break;
|
|
case 'light':
|
|
updateKey = 'MonetaryAccountLight';
|
|
break;
|
|
case 'card':
|
|
updateKey = 'MonetaryAccountCard';
|
|
break;
|
|
case 'external_savings':
|
|
updateKey = 'MonetaryAccountExternalSavings';
|
|
break;
|
|
case 'savings_external':
|
|
updateKey = 'MonetaryAccountSavingsExternal';
|
|
break;
|
|
default:
|
|
throw new Error(`Unknown account type: ${this.type}`);
|
|
}
|
|
|
|
await this.bunqAccountRef.getHttpClient().put(endpoint, {
|
|
[updateKey]: updates
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get account details
|
|
*/
|
|
public async refresh(): Promise<void> {
|
|
await this.bunqAccountRef.apiContext.ensureValidSession();
|
|
|
|
const response = await this.bunqAccountRef.getHttpClient().get(
|
|
`/v1/user/${this.bunqAccountRef.userId}/monetary-account/${this.id}`
|
|
);
|
|
|
|
if (response.Response && response.Response[0]) {
|
|
const refreshedAccount = BunqMonetaryAccount.fromAPIObject(
|
|
this.bunqAccountRef,
|
|
response.Response[0]
|
|
);
|
|
|
|
// Update this instance with refreshed data
|
|
Object.assign(this, refreshedAccount);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close this monetary account
|
|
*/
|
|
public async close(reason: string): Promise<void> {
|
|
await this.update({
|
|
status: 'CANCELLED',
|
|
sub_status: 'REDEMPTION_VOLUNTARY',
|
|
reason: 'OTHER',
|
|
reason_description: reason
|
|
});
|
|
}
|
|
}
|