Concepts: Custom Fields Deep Dive
  • 17 Minutes to read
  • Dark
    Light
  • PDF

Concepts: Custom Fields Deep Dive

  • Dark
    Light
  • PDF

Article summary

Introduction

This article takes a deeper look at each custom field data type and provides examples, details, and tips for each one.

Available Data Types

As previously outlined in the system objects with custom fields intro article, there are currently 10 different data types available:

Data Type Id

Data Type Name

Stored As

1

Basic Text

ValueAsString

2

Rich Text*

ValueAsString

3

Whole Number

ValueAsNumber

4

Decimal Number

ValueAsDecimal

5

Yes or No Choice

ValueAsBoolean

6

Date Only

ValueAsDate

7

Date and Time

ValueAsDate

8

Single Choice

ValueAsString

9

Multiple Choice**

ValueAsString

10

Reference

ReferenceObject

Data Type: Basic Text

The following script example creates a new client that has a basic text custom field named “Billing Contact Name”

$billingContactNameFieldId  = 10

$clientToCreate = @{
  Name      = "SoundWave Studios"
  Reference = "SWS0001"
  Fields = @(
    @{
      FieldId = $billingContactNameFieldId
      Label   = "Billing Contact Name"
      Value = @{
        ValueAsString = "Seth Trapsitell"
      }
    }
  )
}

$createdClient = Add-Client -Entry $clientToCreate

Write-Output "Client $($createdClient.ClientId) ($($createdClient.Name)) was created"

The output of this script:

Client 85 (SoundWave Studios) was created

Points of Interest:

  • Note that we used the ValueAsString property to store the decimal value.

Data Type: Rich Text

The following script example creates a new client that has a rich text custom field named “Client Address”

$clientAddressFieldId  = 90

$clientToCreate = @{
  Name      = "SoundWave Studios"
  Reference = "SWS0001"
  Fields = @(
    @{
      FieldId = $clientAddressFieldId  
      Label   = "Client Address"
      Value = @{
        ValueAsString = "<p><strong>123 Main Street</strong><br />Suite 2400<br />Somewheresville, NW 55555</p>"
      }
    }
  )
}

$createdClient = Add-Client -Entry $clientToCreate

Write-Output "Client $($createdClient.ClientId) ($($createdClient.Name)) was created"

The output of this script:

Client 86 (SoundWave Studios) was created

Points of Interest:

  • Note that we used the ValueAsString property to store the decimal value.

  • Rich text fields allow you to add light-weight tag-based HTML formatting to your values. As seen in the example above, we wrapped the value in an HTML paragraph tag, made the street portion of the address bold, and added HTML line breaks to format the address so it displays nicely in the browser.

Head’s Up!

As mentioned, light-weight tag-based HTML formatting is allowed, but there are many HTML features that are sanitized for security reasons, specifically <script> tags and inline attributes such as the style attribute. Intended formatting includes creating paragraphs, line breaks, hyperlinks, tables, and lists. You can experiment with what works and what doesn’t directly within the application by entering information into a rich text field by using the HTML source code button on the righthand side of the UI editor widget’s toolbar.

Data Type: Whole Number

The following script example creates a new media log entry that has a whole number custom field named “Total Documents Destroyed”

# Media Type Id for Hard Drive
$mediaTypeId = 2

# Create the media log entry on a matter by associating the Matter Id
$matterId = 1

# The custom field Id for the total documents destroyed field on the media log entry object
$totalDocsDestroyedFieldId = 91

# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
    -DateTime (Get-Date) `
    -TimeZone "Central Standard Time" `
    -IncludeTime

# Define a media log entry entry object
$mediaLogEntry = @{
    MediaTypeId     = $mediaTypeId
    MatterId        = $matterId
    Date            = $currentDateTime
    Fields = @(
        @{
            FieldId         = $totalDocsDestroyedFieldId
            Label           = "Total Documents Destroyed"
            Value = @{
                ValueAsNumber = 1000
            }
        }
    )
}

# Pass the media log entry object to the Add-MediaLogEntry command to create the entry. 
# This example bypasses custom field validation by including the switch parameter
$createdMediaLogEntry = Add-MediaLogEntry -Entry $mediaLogEntry -BypassCustomFieldValidation

# Use Write-Output to log the execution results
Write-Output "Media log entry $($createdMediaLogEntry.MediaLogEntryId) created"

The output of this script:

Media log entry 58 created

Points of Interest:

  • Note that we used the ValueAsNumber property to store the value.

Data Type: Decimal Number

The following script example creates a new volume that has a decimal number custom field named “Uncompressed Data (GB)”

# Create the volume on a matter by associating the Matter Id
$matterId = 1

# The custom field Id for the uncompressed data (GB) field on the media log entry object
$uncompressedDataGBFieldId = 92

# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
    -DateTime (Get-Date) `
    -TimeZone "Central Standard Time" `
    -IncludeTime

# Define a volume object
$volume = @{
    Name            = "VOL001"
    MatterId        = $matterId
    VolumeDate      = $currentDateTime
    DocCount        = 100
    PageCount       = 0
    NativeCount     = 100
    Fields = @(
        @{
            FieldId         = $uncompressedDataGBFieldId
            Label           = "Uncompressed Data (GB)"
            Value = @{
                ValueAsDecimal = 32.24
            }
        }
    )
}

# Pass the volume object to the Add-Volume command to create the entry. 
# This example bypasses custom field validation by including the switch parameter
$createdVolume = Add-Volume -Entry $volume -BypassCustomFieldValidation

# Use Write-Output to log the execution results
Write-Output "Volume $($createdVolume.VolumeId) created"

The output of this script:

Volume 44 created

Points of Interest:

  • Note that we used the ValueAsDecimal property to store the value.

Decimal Precision

At the time of this writing, the decimal fields will only store up to 2 places. If you try to provide a number with more decimal places, the system will round it to the nearest 100th.

Data Type: Yes or No Choice

The following script example creates a new billing entry that has a yes or no custom field named “Billed?”

# Billing Type Id for Hourly Technical Work
$billingTypeId = 98 

# Create the billing entry on the matter by associating the Matter Id
$matterId = 3

# The custom field Id for the billed field on the billing entry object
$billedFieldId = 93

# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
    -DateTime (Get-Date) `
    -TimeZone "Central Standard Time" `
    -IncludeTime

# Defind a billing entry object
$billingEntry = @{
    BillingTypeId   = 98
    MatterId       = $matterId
    Narrative       = "Scripted Billing Entry."
    Quantity        = 0.50
    UnitPrice       = 100.00
    Date            = $currentDateTime
    Fields = @(
        @{
            FieldId         = $billedFieldId
            Label           = "Billed?"
            Value = @{
                ValueAsBoolean = $true
            }
        }
    )
}

# Pass the billing entry object to the Add-BillingEntry command to create the entry. 
# This example bypasses custom field validation by including the switch parameter
$createdBillingEntry = Add-BillingEntry -Entry $billingEntry -BypassCustomFieldValidation

# Use Write-Output to log the execution results
Write-Output "Billing entry $($createdBillingEntry.BillingEntryId) created"

The output of this script:

Billing entry 485 created

Points of Interest:

  • Note that we used the ValueAsBoolean property to store the value.

Data Type: Date Only

The following script example creates a new billing entry that has a date only custom field named “Invoiced On”

# Define our own function for retreiving the current date with a specificed time zone offset
# where the time component is set to noon. We do this because Agility Blue stores all dates
# as DateTimeOffset.
function Get-CurrentDateOnlyString([int]$offset) {
    # Get the current date and set it to noon
    $currentDateAtNoon = (Get-Date).Date.AddHours(12)
    
    # Ensure the kind is unspecified
    $currentDateAtNoon = [DateTime]::SpecifyKind($currentDateAtNoon, [DateTimeKind]::Unspecified)
    
    # Specify the offset (e.g., -05:00 for Central Time)
    $offsetTimeSpan = [TimeSpan]::FromHours($offset)
    
    # Create the DateTimeOffset object with the specified offset
    $currentDateAtNoonWithOffset = [System.DateTimeOffset]::new($currentDateAtNoon, $offsetTimeSpan)
    
    # Return the format that Agility Blue needs to store the date
    return ConvertTo-DateString `
        -DateTimeOffset $currentDateAtNoonWithOffset `
        -IncludeTime
}

# Billing Type Id for Processing
$billingTypeId = 224

# Create the billing entry on the matter by associating the Matter Id
$matterId = 1

# The custom field Id for the billed field on the billing entry object
$invoicedOnFieldId = 93

# Call our custom function to retrieve a date-only string with a time zone offset of -5
# to indicate that we want it in central standard time
$currentDate = Get-CurrentDateOnlyString -offset -5

# Defind a billing entry object
$billingEntry = @{
    BillingTypeId   = $billingTypeId
    MatterId        = $matterId
    Narrative       = "Scripted Billing Entry."
    Quantity        = 0.50
    UnitPrice       = 100.00
    Date            = $currentDate
    Fields = @(
        @{
            FieldId         = $invoicedOnFieldId
            Label           = "Invoiced On"
            Value = @{
                ValueAsDate = $currentDate
            }
        }
    )
}

# Pass the billing entry object to the Add-BillingEntry command to create the entry. 
# This example bypasses custom field validation by including the switch parameter
$createdBillingEntry = Add-BillingEntry -Entry $billingEntry -BypassCustomFieldValidation

# Use Write-Output to log the execution results
Write-Output "Billing entry $($createdBillingEntry.BillingEntryId) created"

The output of this script:

Billing entry 489 created

Points of Interest:

  • Note that we used the ValueAsDate property to store the value.

  • All dates in Agility Blue are stored with a date, time, and time zone component in the following format: yyyy-MM-ddTHH:mm:ssK. You can use the utility command ConvertTo-DateString to format a date object into this format with a specified time zone. Not specifying a time zone for a DateTime object will result in dates being stored in UTC time.

Date Only Fields

In Agility Blue, you can pick between a date only field and a date and time field. When choosing these types of fields, the time being omitted or not refers to the formatting as they are displayed to end users in the browser, however, they are both stored with a time and time zone offset component regardless of which one is selected. If a date is provided without a time or time zone offset, they will default to UTC 00:00:00+00:00. Because of this, you should be mindful of how the time component can affect users that may exist in other time zones. Agility Blue will always display times local to the user’s time zone. If you don’t want to have to worry about the time component for a date-only field and you have users that access Agility Blue that span within 12 hours of each other, consider setting the time to 12:00 noon like in the example above instead of 00:00 midnight so the dates don’t appear to shift around for users in the other time zones. For users outside of a 12-hour time difference, they will need to be made aware of this behavior.

Data Type: Date and Time

The following script example creates a new media log entry that has a media log entry date and time custom field named “Checked Out At”

# Media Type Id for Hard Drive
$mediaTypeId = 2

# Create the media log entry on a matter by associating the Matter Id
$matterId = 1

# The custom field Id for the total documents destroyed field on the media log entry object
$checkedOutAtFieldId = 94

# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
    -DateTime (Get-Date) `
    -TimeZone "Eastern Standard Time" `
    -IncludeTime

# Define a media log entry entry object
$mediaLogEntry = @{
    MediaTypeId     = $mediaTypeId
    MatterId        = $matterId
    Date            = $checkedOutAtFieldId
    Fields = @(
        @{
            FieldId         = $checkedOutAtFieldId
            Label           = "Checked Out At"
            Value = @{
                ValueAsDate = $currentDateTime
            }
        }
    )
}

# Pass the media log entry object to the Add-MediaLogEntry command to create the entry. 
# This example bypasses custom field validation by including the switch parameter
$createdMediaLogEntry = Add-MediaLogEntry -Entry $mediaLogEntry -BypassCustomFieldValidation

# Use Write-Output to log the execution results
Write-Output "Media log entry $($createdMediaLogEntry.MediaLogEntryId) created"

The output of this script:

Media log entry 59 created

Points of Interest:

  • Note that we used the ValueAsDate property to store the value.

  • All dates in Agility Blue are stored with a date, time, and time zone component in the following format: yyyy-MM-ddTHH:mm:ssK. You can use the utility command ConvertTo-DateString to format a date into this format with a specified time zone. Not specifying a time zone for a DateTime object will result in dates being stored in UTC time.

Data Type: Single Choice

The following script example creates a contact that has a single choice custom field named “Office Location”

# The custom field Id for the office location field on the contact object
$officeLocationFieldId = 95

# Define a contact object
$contact = @{
    FirstName       = "Donna"
    LastName        = "Taylor"
    EmailAddress    = "dtayler@agilitybluedemo.com"
    Fields = @(
        @{
            FieldId         = $officeLocationFieldId
            Label           = "Office Location Field"
            Value = @{
                ValueAsString = "Minneapolis"
            }
        }
    )
}

# Pass the contact object to the Add-Contact command to create the entry. 
# This example bypasses custom field validation by including the switch parameter
$createdContact = Add-Contact -Entry $contact -BypassCustomFieldValidation

# Use Write-Output to log the execution results
Write-Output "Contact $($createdContact.ContactId) created"

The output of this script:

Media log entry 60 created

Points of Interest:

  • Note that we used the ValueAsString property to store the value.

  • Single choice values are simply stored as strings. You can technically store values that aren’t listed in the choices defined on the object!

Data Type: Multiple Choice

The following script example creates a new media log entry that has a multiple choice custom field named “Properties”

# Media Type Id for Hard Drive
$mediaTypeId = 2

# Create the media log entry on a matter by associating the Matter Id
$matterId = 1

# The custom field Id for the properties field on the media log entry object
$propertiesFieldId = 96

# Use the ConvertTo-DateString command to convert the date to a specific time zone:
$currentDateTime = ConvertTo-DateString `
    -DateTime (Get-Date) `
    -TimeZone "Central Standard Time" `
    -IncludeTime

# Define a media log entry entry object
$mediaLogEntry = @{
    MediaTypeId     = $mediaTypeId
    MatterId        = $matterId
    Date            = $currentDateTime
    Fields = @(
        @{
            FieldId         = $propertiesFieldId
            Label           = "Properties"
            Value = @{
                ValueAsString = "Forensics`nChain of Custody`nFast-Track"
            }
        }
    )
}

# Pass the media log entry object to the Add-MediaLogEntry command to create the entry. 
# This example bypasses custom field validation by including the switch parameter
$createdMediaLogEntry = Add-MediaLogEntry -Entry $mediaLogEntry -BypassCustomFieldValidation

# Use Write-Output to log the execution results
Write-Output "Media log entry $($createdMediaLogEntry.MediaLogEntryId) created"

The output of this script:

Media log entry 65 created

Points of Interest:

  • Note that we used the ValueAsString property to store the value.

  • Separate selected choices by using the newline character `n within the string value.

Data Type: Reference

Reference fields are fields that can store zero, one, or many values in a collection of records that contain a small amount of metadata about the source object instance they point to. Here is an example of a custom field that references the “User” object:

{
  "FieldId": 55,
  "ObjectId": 1,
  "DataTypeId": 10,
  "DataTypeName": "Reference",
  "Label": "Project Manager",
  "IsRequired": false,
  "Position": 5,
  "Guid": 2907893454017,
  "IsSystemField": false,
  "IsReferenceValue": false,
  "DefaultValue": null,
  "CopyPreviousValueOnSaveAndNew": false,
  "Value": {
    "ObjectFieldValueId": 2140,
    "ObjectFieldId": 55,
    "ObjectId": 1,
    "PrimaryKeyId": 71,
    "ValueAsString": null,
    "ValueAsBoolean": null,
    "ValueAsNumber": null,
    "ValueAsDecimal": null,
    "ValueAsDate": null,
    "ReferenceObject": {
      "ObjectFieldReferenceObjectInstanceId": 320,
      "ObjectFieldValueId": 2140,
      "ObjectId": 8,
      "Object": null,
      "PrimaryObjectId": 1,
      "PrimaryKeyId": 71,
      "KeyType": "String",
      "DisplayFormat": "%Val%",
      "IsSystemObject": true,
      "Name": null,
      "NumberOfValues": 1,
      "Values": [
        {
          "ObjectFieldReferenceObjectInstanceValueId": 239,
          "ObjectFieldReferenceObjectInstanceId": 320,
          "KeyAsString": "2c35e3b4-2e17-4ee6-b192-e92e4db5cf3c",
          "KeyAsInteger": null,
          "KeyAsLong": null,
          "Value": "Roger Schlachter"
        }
      ]
    }
  }
}

The root of the object contains the standard metadata information about the field, where the DataTypeName property indicates that this is a reference type field. When a field is a reference type, the value will be stored in the ReferenceObject object property that contains information about what kind of reference is being used (for example, users, clients, media log entries, etc.), and a collection property named Values that stores the actual reference values. Reference values contain two pieces of information: the KeyAs* property and the Value. The type of key (ID) that’s stored depends on the reference object because some objects, like User, use a string for their key, where most other objects use an integer for their key.

The following table provides the system objects that can be referenced and information about their keys:

Object Id

Object Name

Key Name

Key Data Type

KeyAs* Property

Value Format

1

Client

ClientId

Int32

KeyAsInteger

Client Name + Reference in parenthesis. Ex: “ABC Client (0001)”

2

Matter

MatterId

Int32

KeyAsInteger

Matter Name + Reference in parenthesis. Ex: “ABC vs XYZ (0001)”

3

Media Log Entry

MediaLogEntryId

Int32

KeyAsInteger

Id + Media Type. Ex: “#1 - Hard Drive”

4

Volume

VolumeId

Int32

KeyAsInteger

Id + Volume Name. Ex: “#2 - VOL001”

5

Project

ProjectId

Int64

KeyAsLong

Id + Project Description. Ex: “#2024060000001 - Production”

6

Task

TaskId

Int32

KeyAsInteger

Id + Task Name. Ex: “#1026 - Process Documents”

7

Contact

ContactId

Int32

KeyAsInteger

Full Name + Email in brackets. Ex: Adele Butler <abutler@abdemo.com>“

8

User

Id

String

KeyAsString

Full Name. Ex: “Roger Schlachter”

9

Billing Entry

BillingEntryId

Int32

KeyAsInteger

Id + Billing Type + Quantity in parenthesis. Ex: “#1 - Hourly Technical Work (Quantity: 3.5)”

10+

Custom Object

Id

Int32

KeyAsInteger

The reference link field. Ex: “Analyst”

When creating or updating a reference field with values, there are only a few fields that need to be provided. The following example is a script that creates a new client that contains a custom user reference field named “Project Manager”:

$clientToCreate = @{
  Name      = "SoundWave Studios"
  Reference = "SWS0001"
  Fields = @(
    @{
      FieldId = 55
      Label   = "Project Manager"
      Value   = @{
        ReferenceObject = @{
          Values = @(
            @{
              KeyAsString = "2c35e3b4-2e17-4ee6-b192-e92e4db5cf3c"
              Value       = "Roger Schlachter"
            }
          )
        }
      }
    }
  )
}

$createdClient = Add-Client -Entry $clientToCreate

Write-Output "Client $($createdClient.ClientId) ($($createdClient.Name)) was created"

Points of Interest:

  • As usual, the custom field requires that we provide the FieldId property. The Label property is only used here to help us understand which field this is in the field collection and is ignored by the system because it is read-only.

  • The Value object property only needs to contain the ReferenceObject property that contains the values collection for the record we’re referencing.

  • In this example, the “Project Manager” field is setup to reference users. To reference a user, we need to know their Id and their full name. The user’s Id will need to be placed in the KeyAsString property because the key data type for users is “String”. The user’s full name can then be placed into the Value property. The value is what the end user sees when they are viewing this record within the application.

Head’s Up!

You can technically put anything you want into the Value property for the custom field and the application will reflect what you put in there. However, if you ever end up updating the source instance of the referenced field, the system will automatically propagate the update anywhere it’s referenced and the value will change to the system-defined format as described in the table above. Additionally, the system may update the cached values from time to time during maintenance cycles.