@rantalainen/fuusor-api-client
v3.1.0
Published
Fuusor API client library
Downloads
4
Maintainers
Keywords
Readme
Fuusor API Client
Third party Fuusor API client. Fuusor website: https://www.fuusor.fi/
:warning: This tool is in early stages and is subject to change.
Installation
Install from npm:
npm install @rantalainen/fuusor-api-client
Setup
Import to NodeJS project
const { FuusorApiClient } = require('@rantalainen/fuusor-api-client');
Import to TypeScript project
import { FuusorApiClient } from '@rantalainen/fuusor-api-client';
Setup client with options
Please consult Fuusor Oy to get your clientId
, clientSecret
, username
and password
for API usage.
const fuusorApiClient = new FuusorApiClient({
clientId: 'api-client-id-from-fuusor',
clientSecret: 'api-client-secret-from-fuusor',
username: 'environment-username-from-fuusor',
password: 'environment-password-from-fuusor',
// Optional: change timeout
timeout: 60000,
// Optional: keep alive agent
keepAliveAgent: true,
// Optional: DNS cache
dnsCache: true,
})
Changing timeout on the fly
Default timeout implemented in 1.0.0 is 120 seconds for Fuusor API requests. You can change it in initialization or before saving dataset:
// Change timeout on the fly:
fuusorApiClient.options.timeout = 60000;
Datasets
fuusorApiClient.createDataSet: Create dataset instance
const dataSet = fuusorApiClient.createDataSet(dataSetOptions);
Used to create new dataset instance for updating data in Fuusor database.
required:
groupId
Company specific identifier from Company ManagementdatasetName
Dataset name shown in Company ManagementdatasetId
Dataset identifier shown in Company Management (use same id to update old dataset)datasetType
Short type identifier, for example: invoices or offers
optional:
begin
andend
With large datasets you can only update data on certain timeframe between begin and endprimarydate
When updating dataset based on date, use primarydate to define which property contains primary date in dataperiods
Array of periods (financial year term selections, defaults to calendar year)updateById
If only certain rows should be updated, define the field name that contains unique id
const dataSet = await fuusorApiClient.createDataSet({
groupId: 'abc1234-1234-abcd-abcd-abcdabcdabcd',
datasetName: 'Invoices',
datasetId: 'invoices',
datasetType: 'invoices',
begin: '2020-01-01',
end: '2020-12-31',
primarydate: 'invoice_date',
periods: [
{
begin: '2019-01-01',
end: '2019-12-31'
},
{
begin: '2020-01-01',
end: '2020-12-31'
}
],
updateById: 'customer'
});
dataSet.defineField: Define dataset fields
dataSet.defineField(type, id, name, items?);
Shorthands:
dataSet.defineDimensionField(id, name, items);
dataSet.defineDateField(id, name);
dataSet.defineValueField(id, name);
dataSet.defineDescriptionField(id, name);
Each dataset is dynamically constructed, so you have to define data type for each field (property in object).
At the moment of writing, Fuusor has 4 different data types that are listed below:
dimension
Dataset dimensions used to filter datadate
Dataset date fieldsvalue
Numeric value fields (for example hours, euros etc.)description
Textual description fields for data row
Definition properties are as listed below:
id
Field property name in row objectsname
Field display name in Fuusor
For dimension field you will also define items
(that are shown in filtering). Please see example.
Examples
// Define dimension field
dataSet.defineDimensionField('costcenter', 'Cost center', [
{ id: 'SK123', name: 'Production' },
{ id: 'SK124', name: 'Sales' }
]);
// Define date field
dataSet.defineDateField('project_date', 'Project date');
// Define value field
dataSet.defineValueField('hours', 'Project hours');
// Define description field
dataSet.defineDescriptionField('work_description', 'Project work description');
dataSet.pushDimensionFieldDimension: Add dimension item to dimension field
dataSet.pushDimensionFieldDimension(dimensionId, item, options?);
Add dimension items to earlier defined dimension field by dimension id.
Examples
dataSet.pushDimensionFieldDimension('costcenter', {
id: 'SK125',
name: 'Accounting'
});
// Option to allow empty dimensions when programmatically adding new dimensions to dataset
dataSet.pushDimensionFieldDimension(
'customer',
{
id: null, // unknown in dataset row
name: null // unknown in dataset row
},
{ allowEmptyDimension: true }
);
dataSet.defineDimensionHierarchy: Define dataset dimension hierarchies
dataSet.defineDimensionHierarchy(id, name, dimensionId, items?);
This method is used to define dataset dimension hierarchies. When defining dimension hierarchy, the referenced dimension id must exist in dataset.
Definition properties are as listed below:
id
Dimension hierarchy idname
Dimension hierarchy namedimensionId
Referenced dimension id
Examples
// Define dimension hierarchy, 'customer' must be defined as dimension
dataSet.defineDimensionHierarchy('customer_category', 'Customer category', 'customer');
dataSet.pushDimensionHierarchyItem: Add items to defined hierarchy
dataSet.pushDimensionHierarchyItem(hierarchyId, hierarchyItem);
This method is used to define dataset dimension hierarchy items. When defining hierarchy items, the referenced dimension hierarchy id must exist in dataset.
Definition properties are as listed below:
hierarchyId
Hierarchy item idhierarchyItem
Hierarchy item (see examples)
Examples
// Defined customer_category hierarchy in previous example
dataSet.defineDimensionHierarchy('customer_category', 'Customer category', 'customer');
// Add items to hierarchy
dataSet.pushDimensionHierarchyItem('customer_category', {
id: 333, // actual category id
name: 'Production customers', // actual category name
items: [111, 222, 333] // actual customer ids in this category
});
dataSet.pushDimensionHierarchyItem('customer_category', {
id: 444,
name: 'Prospects',
items: [777, 888]
});
dataSet.addRow(s): Add data rows to dataset
// Add one row
dataSet.addRow(data);
// Add multiple rows
dataSet.addRows(data[]);
Add rows to dataset. Each row property field must be defined with dataSet.defineField
Examples
dataSet.addRow({
project_date: '2020-12-01',
work_description: 'My great project',
hours: 10,
costcenter: 'SK123'
});
dataSet.save: Save dataset to Fuusor via API
await dataSet.save();
Saves dataset to Fuusor. Returns promise.
Full dataset example (JS)
import { FuusorApiClient } from 'fuusor-api-client';
const fuusorApiClient = new FuusorApiClient({
clientId: 'api-client-id-from-fuusor',
clientSecret: 'api-client-secret-from-fuusor',
username: 'environment-username-from-fuusor',
password: 'environment-password-from-fuusor',
}
const dataSet = fuusorApiClient.createDataSet({
groupId: 'abc1234-1234-abcd-abcd-abcdabcdabcd',
datasetName: 'Invoices',
datasetId: 'invoices',
datasetType: 'invoices',
// define begin, end and primarydate or updatebyid field
begin: '2020-01-01',
end: '2020-01-31',
primarydate: 'invoice_date',
// if we want to update only certain rows, we must define updateById field
updateById: 'customer'
});
dataSet.defineDateField('invoice_date', 'Invoice date');
dataSet.defineValueField('total', 'Invoice total');
dataSet.defineDimensionField('customer', 'Customer name');
dataSet.pushDimensionFieldDimension('customer', { id: 1, name: 'Customer 1 Oy' });
dataSet.pushDimensionFieldDimension('customer', { id: 2, name: 'Customer 2 Oy' });
dataSet.defineDimensionField('costcenter', 'Branch', [
{ id: 'branch1', name: 'Branch 1' },
{ id: 'branch2', name: 'Branch 2' }
]);
dataSet.defineDimensionHierarchy('customer_category', 'Customer category', 'customer');
dataSet.pushDimensionHierarchyItem('customer_category', {
id: 5,
name: 'Category 5',
items: [1]
});
dataSet.pushDimensionHierarchyItem('customer_category', {
id: 6,
name: 'Category 6',
items: [2]
});
dataSet.pushDimensionFieldDimension('costcenter', {
id: 'branch3', name: 'Branch 3'
});
dataSet.addRows([
{ invoice_date: '2020-01-05', total: 150.00, customer: 1, costcenter: 'branch1', category_id: 5 },
{ invoice_date: '2020-01-06', total: 120.24, customer: 2, costcenter: 'branch2', category_id: 6 }
]);
await dataSet.save();
Users
fuusorApiClient.users.getAll()
Gets all user accounts.
const users = await fuusorApiClient.users.getAll();
Example response
[
{
userName: '[email protected]',
authenticationType: null,
language: 'fi-FI',
validUntil: '2022-02-28'
}
]
fuusorApiClient.users.create(user)
Creates a new user account.
required:
user.userName
Email used for login
optional:
user.authenticationType
Authentication type. Valid values:microsoft
,google
,activationlink
. Default ismicrosoft
.user.language
Default UI language for user. Valid values:fi-FI
,en-US
. Default isfi-FI
.user.validUntil
Optional expiration date for account.
await fuusorApiClient.users.create({
userName: '[email protected]',
authenticationType: 'microsoft',
language: 'fi-FI',
validUntil: '2022-02-28'
});
If activationlink
is used as an authentication type, the request will respond with the activation code (as a string) that is used to activate the account.
const activationCode = await fuusorApiClient.users.create({
userName: '[email protected]',
authenticationType: 'activationlink',
language: 'fi-FI'
});
fuusorApiClient.users.delete(userName)
Deletes user account.
required:
userName
Email used for login
await fuusorApiClient.users.delete('[email protected]');
User groups
fuusorApiClient.userGroups.getAll()
Gets all user groups.
const groups = await fuusorApiClient.userGroups.getAll();
Example response
[
{
id: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
name: 'Example group',
description: 'Example description',
users: ['[email protected]']
}
]
fuusorApiClient.userGroups.addUsers(id, users)
Adds users to the user group.
required:
id
User group idusers
Array of user emails
await fuusorApiClient.userGroups.addUsers('3fa85f64-5717-4562-b3fc-2c963f66afa6', ['[email protected]']);
fuusorApiClient.userGroups.removeUsers(id, users)
Removes users from the user group.
required:
id
User group idusers
Array of user emails
await fuusorApiClient.userGroups.removeUsers('3fa85f64-5717-4562-b3fc-2c963f66afa6', ['[email protected]']);
Changelog
- 0.1.0 Add support for dimension hierarchies
- 0.1.1 Add backwards compatible support for dataset endpoint (instead of fileupload)
- 1.0.0 Add timeout option
- 1.0.1 Scope @rantalainen/fuusor-api-client
- 1.1.0 Add support for User and User Group API endpoints
- 1.1.1 Add support for new authentication type when creating new users
- 1.1.2 Add support for user expiration date
- 1.1.3 Better logging in case of invalid hierarchy items or dimension items
- 1.2.0 pushDimensionFieldDimension option to allow empty dimensions
- 2.0.0 Add internal httpsAgent (from agentkeepalive package) by default
- 3.0.0 Added DNS cahcing support and updated httpsAgent to support options