Many times when we extend the use of Bricknode Financial Systems (BFS) by building applications on top of it using the API we end up with the need for more property fields. BFS has a lot of dedicated fields but when we need more we can use Custom Fields! Every object in BFS has Custom Fields, it is part of the Entity Base class.

Custom Fields store data in simple string format and in the old days we might have worked with for example semicolon separated values. During the last couple of years we have changed this behaviour and began working with JSON data in Custom Fields instead. This way the data in Custom Fields both become more easy to read and edit in the regular GUIs and for developers the data is more structured.

We have a plan to integrate a GUI editor for fields that contain JSON which will make the life easier for non-developers but for now GUI users can work with tools like Excel that can be converted to JSON format with tools like this one for example: http://beautifytools.com/excel-to-json-converter.php

Now onto an example. I am building a new application that will take care of recurring fees based on assets under management in BFS.

I do not want to set up a separate database for this application but instead use BFS for all my data needs. There are a few things that I need to take care of.

I am calling this application RecurringAumFees and thus it is good practice to name the Custom Fields with this prefix.

To communicate with BFS I am using our NuGet package.

Let’s have a look at the class that I call RecurringAumFee_HouseSettings.

/// <summary>
///     This model is used to collect data from the House in the BFS instance from the custom field called
///     RecurringAumFees_HouseSettings
/// </summary>
public class RecurringAumFees_HouseSettings
{
    /// <summary>
    /// This is the interval of how often the fee should be applied
    /// </summary>
    public FeeInterval FeeInterval { get; set; }
    /// <summary>
    /// This is the date when fees were last executed
    /// </summary>
    public DateTime LastFeeExecutionDate { get; set; }
    /// <summary>
    /// This is the first date that fees should be executed
    /// </summary>
    public DateTime FirstFeeExecutionDate { get; set; }
}

The FeeInterval property is an enum looking like this:

public enum FeeInterval
{
    Monthly,
    Quarterly,
    SemiAnnually,
    Annually
}

As a GUI user I can put this data into an Excel sheet according to the template below.

RecurringAumFees_HouseSettings

I can then visit the conversion tool and import the Excel file and then extract the following data.

{
 "FeeInterval": "1",
 "FirstFeeExecutionDate": "3/31/20"
}

I navigate to the House View in Bricknode Broker.

On to the details section.

And create a new Custom Field where I paste the JSON formatted data.

The result:

Now in my application I can just collect the house data and deserialize the Custom Field values into a C# object to work with it like this.

public async Task GetRecurringAumFeesHouseSettings()
{
    var houseData = await _bfsLegalEntitiesService.GetHouseInformationAsync("[yourinstancename]");

    var recurringAumFeesHouseSettings = houseData.Result.First().CustomFields
        .First(t => t.FieldName == "RecurringAumFees_HouseSettings").Value;

    var recurringAumFeesHouseSettingsObject =
        JsonConvert.DeserializeObject<RecurringAumFees_HouseSettings>(recurringAumFeesHouseSettings);
}

The data that I got back looked like this.

In my humble opinion this is the absolute best way to work with complex Custom Fields in BFS and not have to create one Custom Field per value or use generic separators.

At its core, Bricknode Financial Systems is like a database application for building financial applications where you don’t have to host and maintain the database. With its API you can basically develop any financial service that you would like and not have to invent the wheel again. Custom fields are a way for anyone to make BFS their own and use it for storing any type of data related to the different objects. Some examples can be found here and here.

We wrote a previous article here with some examples of how to use custom fields.

On our API site we have an article about custom fields too.

We think that this is probably the most usable function that we have in BFS to date since you can expand our core application to handle a lot more things than what we have come to think of.

Please let us know of any interesting applications that you have built using our custom fields so we can share this with the community!

Check out the full guide on how we used BFS to work with fund holdings to understand the power of this.

A neat new cost efficient way to build smaller functions that can be consumed through simple HttpRequests are Azure Functions. Instead of building and hosting a whole web application it is now possible to build a function that can be triggered through a HttpRequest and then perform a number of things.

Ideally when building some financial functions we don’t want to set up new databases to keep our data and thanks to the Custom Fields within Bricknode Financial Systems (“BFS”) we can just create new fields ad-hoc and keep our data in BFS.

In this example we wanted to build a function that took care of closing a share offering in BFS once a certain level of subscriptions for the offer had been reached.

To start with we used the UpdateInstruments function to create a custom field to hold the number of shares that would be the limit of the offer.

First we have a function to update the instrument with custom fields and the status of the instrument.

private static async Task<UpdateInstrumentResponse> UpdateInstrument(UpdateInstrument[] entities)
{
    return await Client.UpdateInstrumentsAsync(new UpdateInstrumentsRequest
    {
        Credentials = Credentials,
        identify = BfsIdentifier,
        Fields = new UpdateInstrumentFields
        {
            CustomFields = true,
            InstrumentStatus = true
        },
        Entities = entities
    });
}

Next, we will set the custom field to 1000 shares and we name the custom field “ShareLimit”.

private static async Task CreateAndSetCustomField(Guid instrumentId)
{
    var response = await UpdateInstrument(new UpdateInstrument[]
    {
        new UpdateInstrument
        {
            BrickId = instrumentId,
            CustomFields = new CustomField[]
            {
                new CustomField
                {
                    FieldName = "ShareLimit",
                    Value = "1000"
                }
            }
        }
    });
}

Creating, updating and deleting custom fields can also be done fully in the GUI of BFS where each object supports a collection of custom fields.

In the Azure Function we can now calculate how many shares are subscribed for each time a new subscription is posted on our onboarding form which we can collect with the following function that use GetSubscriptionOrders.

private static async Task<GetSubscriptionOrderResponse> GetSubscriptionOrders(Guid instrumentId)
{
    return await Client.GetSubscriptionOrdersAsync(new GetSubscriptionOrderRequest
    {
        Credentials = Credentials,
        identify = BfsIdentifier,
        Args = new GetSubscriptionOrderArgs
        {
            BrickIds = new []{instrumentId},
            States = new[] {"Created"}
        },
        Fields = new GetSubscriptionOrderFields
        {
            BrickId = true,
            InstrumentAmount = true
        }
    });
}

private static async Task<decimal> CalculateSubscriptionVolume(Guid instrumentId)
{
    var response = await GetSubscriptionOrders(instrumentId);

    return response.Result.Sum(sum => sum.InstrumentAmount);
}

Now we need to compare the subscribed volume to the limit amount that we entered in the custom field.

First we need a function to get the instrument details.

private static async Task<GetInstrumentsResponse> GetInstrumentsById(Guid instrumentId)
{
    return await Client.GetInstrumentsAsync(new GetInstrumentsRequest()
    {
        Credentials = Credentials,
        identify = BfsIdentifier,
        Args = new GetInstrumentsArgs()
        {
            BrickIds = new Guid[] {instrumentId}
        },
        Fields = new GetInstrumentsFields()
        {
            BrickId = true,
            InstrumentType = true,
            Name = true,
            CustomFields = true
        }
    });
}
private static async Task EvaluateSubscriptionStatus(Guid instrumentId)
{
    var instrument = await GetInstrumentsById(instrumentId);

    var subscriptionVolumeLimit = Decimal.Parse(instrument.Result.First().CustomFields
        .First(t => t.FieldName == "ShareLimit").Value);

    var subscribedVolume = await CalculateSubscriptionVolume(instrumentId);

    if (subscribedVolume >= subscriptionVolumeLimit)
    {
        await CloseInstrument(instrumentId);
    }

}

Finally we can change the status of the instrument so that it is not open for further subscriptions by updating the status to Closed.

private static async Task CloseInstrument(Guid instrumentId)
{
    var response = await UpdateInstrument(new UpdateInstrument[]
    {
        new UpdateInstrument
        {
            BrickId = instrumentId,
            InstrumentStatus = 3
        }
    });
}