Skip to main content
Glama
create-manual-entry.ts17 kB
import { createAction, Property, DynamicPropsValue, OAuth2PropertyValue } from '@activepieces/pieces-framework'; import { bexioAuth } from '../../index'; import { BexioClient } from '../common/client'; import { bexioCommonProps } from '../common/props'; import { BexioManualEntry, BexioManualEntryResponse } from '../common/types'; export const createManualEntryAction = createAction({ auth: bexioAuth, name: 'create_manual_entry', displayName: 'Create Manual Entry', description: 'Create a manual accounting entry (single, compound, or group)', props: { type: Property.StaticDropdown({ displayName: 'Entry Type', description: 'Choose the type of manual entry', required: true, defaultValue: 'manual_single_entry', options: { disabled: false, options: [ { label: 'Single Entry - Simple one-line booking', value: 'manual_single_entry', }, { label: 'Compound Entry - Total distributed across multiple accounts', value: 'manual_compound_entry', }, { label: 'Group Entry - Multiple separate bookings with same reference', value: 'manual_group_entry', }, ], }, }), date: Property.ShortText({ displayName: 'Booking Date', description: 'Date of the booking (YYYY-MM-DD)', required: true, }), reference_nr: Property.ShortText({ displayName: 'Reference Number', description: 'Reference number for the booking', required: false, }), entryFields: Property.DynamicProperties({ auth: bexioAuth, displayName: 'Entry Details', description: 'Configure the entry details based on selected type', required: true, refreshers: ['type', 'auth'], props: async ({ type, auth }, ctx) => { const entryType = (type as unknown as string) || 'manual_single_entry'; let accounts: Array<{ id: number; account_no: string; name: string }> = []; let taxes: Array<{ id: number; name: string; percentage: string }> = []; let currencies: Array<{ id: number; name: string }> = []; if (auth) { try { const client = new BexioClient(auth); accounts = await client.get<Array<{ id: number; account_no: string; name: string }>>('/accounts'); taxes = await client.get<Array<{ id: number; name: string; percentage: string }>>('/taxes'); currencies = await client.get<Array<{ id: number; name: string }>>('/3.0/currencies'); } catch (error) { console.warn('Failed to fetch accounts/taxes/currencies:', error); } } const accountOptions = accounts.map((acc) => ({ label: `${acc.account_no} - ${acc.name}`, value: acc.id, })); const taxOptions = taxes.map((tax) => ({ label: `${tax.name} (${tax.percentage}%)`, value: tax.id, })); const currencyOptions = currencies.map((curr) => ({ label: curr.name, value: curr.id, })); if (entryType === 'manual_single_entry') { return { debit_account: accountOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Debit Account', description: 'The account to debit', required: true, options: { disabled: false, options: accountOptions, }, }) : Property.Number({ displayName: 'Debit Account ID', description: 'The account ID to debit', required: true, }), credit_account: accountOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Credit Account', description: 'The account to credit', required: true, options: { disabled: false, options: accountOptions, }, }) : Property.Number({ displayName: 'Credit Account ID', description: 'The account ID to credit', required: true, }), amount: Property.Number({ displayName: 'Amount', description: 'The transaction amount', required: true, }), description: Property.ShortText({ displayName: 'Description', description: 'Description of the transaction', required: false, }), tax_id: taxOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Tax', description: 'Tax rate (optional)', required: false, options: { disabled: false, options: taxOptions, }, }) : Property.Number({ displayName: 'Tax ID', description: 'Tax ID (optional)', required: false, }), tax_account: accountOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Tax Account', description: 'Account for tax calculation', required: false, options: { disabled: false, options: accountOptions, }, }) : Property.Number({ displayName: 'Tax Account ID', description: 'Account ID for tax calculation', required: false, }), currency_id: currencyOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Currency', description: 'Currency (optional)', required: false, options: { disabled: false, options: currencyOptions, }, }) : Property.Number({ displayName: 'Currency ID', description: 'Currency ID (optional)', required: false, }), currency_factor: Property.Number({ displayName: 'Currency Factor', description: 'Exchange rate factor (defaults to 1)', required: false, }), helper_info: Property.MarkDown({ value: '', }), entries: Property.Array({ displayName: 'Entries', description: 'Not used for single entries', required: false, properties: {}, }), }; } else { const isCompound = entryType === 'manual_compound_entry'; return { debit_account: Property.Number({ displayName: 'Debit Account', description: 'Not used for compound/group entries', required: false, }), credit_account: Property.Number({ displayName: 'Credit Account', description: 'Not used for compound/group entries', required: false, }), amount: Property.Number({ displayName: 'Amount', description: 'Not used for compound/group entries', required: false, }), description: Property.ShortText({ displayName: 'Description', description: 'Not used for compound/group entries', required: false, }), tax_id: Property.Number({ displayName: 'Tax ID', description: 'Not used for compound/group entries', required: false, }), tax_account: Property.Number({ displayName: 'Tax Account', description: 'Not used for compound/group entries', required: false, }), currency_id: Property.Number({ displayName: 'Currency ID', description: 'Not used for compound/group entries', required: false, }), currency_factor: Property.Number({ displayName: 'Currency Factor', description: 'Not used for compound/group entries', required: false, }), helper_info: Property.MarkDown({ value: isCompound ? 'For compound entries, each entry should have EITHER debit_account_id OR credit_account_id (not both).' : 'For group entries, each entry must have BOTH debit_account_id and credit_account_id.', }), entries: Property.Array({ displayName: 'Entries', description: isCompound ? 'Multiple entries to distribute the total. Each entry should have either debit_account_id OR credit_account_id (not both).' : 'Multiple complete bookings. Each entry must have both debit_account_id and credit_account_id.', required: true, properties: { debit_account_id: accountOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Debit Account', description: isCompound ? 'Account to debit (leave empty if this is a credit entry)' : 'Account to debit', required: !isCompound, options: { disabled: false, options: accountOptions, }, }) : Property.Number({ displayName: 'Debit Account ID', description: isCompound ? 'Account ID to debit (leave 0 if this is a credit entry)' : 'Account ID to debit', required: !isCompound, }), credit_account_id: accountOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Credit Account', description: isCompound ? 'Account to credit (leave empty if this is a debit entry)' : 'Account to credit', required: !isCompound, options: { disabled: false, options: accountOptions, }, }) : Property.Number({ displayName: 'Credit Account ID', description: isCompound ? 'Account ID to credit (leave 0 if this is a debit entry)' : 'Account ID to credit', required: !isCompound, }), amount: Property.Number({ displayName: 'Amount', description: 'The transaction amount', required: true, }), description: Property.ShortText({ displayName: 'Description', description: 'Description for this entry', required: false, }), tax_id: taxOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Tax', description: 'Tax rate (optional)', required: false, options: { disabled: false, options: taxOptions, }, }) : Property.Number({ displayName: 'Tax ID', description: 'Tax ID (optional)', required: false, }), tax_account_id: accountOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Tax Account', description: 'Account for tax calculation (optional)', required: false, options: { disabled: false, options: accountOptions, }, }) : Property.Number({ displayName: 'Tax Account ID', description: 'Account ID for tax calculation (optional)', required: false, }), currency_id: currencyOptions.length > 0 ? Property.StaticDropdown({ displayName: 'Currency', description: 'Currency (optional)', required: false, options: { disabled: false, options: currencyOptions, }, }) : Property.Number({ displayName: 'Currency ID', description: 'Currency ID (optional)', required: false, }), currency_factor: Property.Number({ displayName: 'Currency Factor', description: 'Exchange rate factor (defaults to 1)', required: false, }), }, }), }; } }, }), }, async run(context) { const client = new BexioClient(context.auth); const entryType = context.propsValue.type as 'manual_single_entry' | 'manual_compound_entry' | 'manual_group_entry'; const entryFields = context.propsValue.entryFields as DynamicPropsValue; let entries: BexioManualEntry[] = []; if (entryType === 'manual_single_entry') { const entry: BexioManualEntry = { debit_account_id: entryFields['debit_account'] as number, credit_account_id: entryFields['credit_account'] as number, amount: entryFields['amount'] as number, }; if (entryFields['description']) { entry.description = entryFields['description'] as string; } if (entryFields['tax_id']) { entry.tax_id = entryFields['tax_id'] as number; } if (entryFields['tax_account']) { entry.tax_account_id = entryFields['tax_account'] as number; } if (entryFields['currency_id']) { entry.currency_id = entryFields['currency_id'] as number; } if (entryFields['currency_factor']) { entry.currency_factor = entryFields['currency_factor'] as number; } entries = [entry]; } else { const entriesArray = entryFields['entries'] as Array<Record<string, unknown>> | undefined; if (!entriesArray || entriesArray.length === 0) { throw new Error('At least one entry is required for compound or group entries'); } entries = entriesArray.map((entry) => { const bexioEntry: BexioManualEntry = { amount: entry['amount'] as number, }; const debitAccountId = entry['debit_account_id'] as number | undefined; if (debitAccountId && debitAccountId !== 0) { bexioEntry.debit_account_id = debitAccountId; } const creditAccountId = entry['credit_account_id'] as number | undefined; if (creditAccountId && creditAccountId !== 0) { bexioEntry.credit_account_id = creditAccountId; } if (entry['description']) { bexioEntry.description = entry['description'] as string; } const taxId = entry['tax_id'] as number | undefined; if (taxId && taxId !== 0) { bexioEntry.tax_id = taxId; } const taxAccountId = entry['tax_account_id'] as number | undefined; if (taxAccountId && taxAccountId !== 0) { bexioEntry.tax_account_id = taxAccountId; } const currencyId = entry['currency_id'] as number | undefined; if (currencyId && currencyId !== 0) { bexioEntry.currency_id = currencyId; } if (entry['currency_factor']) { bexioEntry.currency_factor = entry['currency_factor'] as number; } return bexioEntry; }); } const requestBody = { type: entryType, date: context.propsValue.date, reference_nr: context.propsValue.reference_nr, entries, }; const response = await client.post<BexioManualEntryResponse>( '/accounts/manual_entries', requestBody ); return response; }, });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server