Skip to main content

Custom Fields (Attributes)

Warning: legacy API

This page is about the legacy SOAP-based jxAPI that is no longer updated or recommended for use in new projects. The documentation in this section may be outdated or inaccurate, and is provided for reference purposes only.

Journyx recommends using the REST-based API for new projects in most cases. However, at the current time, there are certain object types that are not available through the REST API.

Journyx supports custom fields for users, projects, and several other core data types. Some custom fields are predefined or used for internal purposes, while others may be defined by the site administrator. In the jxAPI, custom fields are referred to as Attributes.

In this interface, an Attribute Type is the definition of a field -- its name, type, and what core table it is associated with -- and an Attribute associates an individual custom field value with both the corresponding Attribute Type and a specific record in the associated core table.

An Attribute Type record contains the following fields:

FieldDescription
id_attr_typeThe ID of this attribute type.
table_nameThe name of the table this attribute type applies to.
pnameThe printable name of this attribute type.
descriptionA description of this attribute type.
attr_typeThe type of this attribute.
visibilityThe visibility of this attribute in the GUI: 0 if it does not appear, 1 if it is visible and editable, and 2 if it is visible but not editable.
id_domainThe domain this attribute type applies to.
string_defaultThe default value of this attribute, if it is a string.
numeric_defaultThe default value of this attribute, if it is a number.

The table_name field contains the name of the core table this attribute is associated with. This field uses the internal table names, for example "users" or "projects", not jxAPI record type names. You can use the getAttributeObjectTypes jxAPI method to list the names of all tables that support custom fields.

The attr_type field describes the data type of the attribute; a full description of attribute data types is provided below.

Note that the visibility field only affects the web interface, not the jxAPI.

Basic Operations

To query the list of attribute types, use the queryAttributeTypes method. This method returns a list of AttributeTypeRecord objects matching one that you pass in. Therefore, passing an empty pattern record returns all Attribute Types that currently exist, while filling in only the table_name field will allow you to fetch Attribute Type definitions for a particular table. For example:

rec = AttributeTypeRecord()
rec.table_name = "projects"

attribute_types = proxy.queryAttributeTypes(skey, rec)

In Journyx 9.1 and later, certain tables have a helper method to fetch Attribute Types for that table, for example getUserAttributeTypes or getProjectAttributeTypes.

Once you know the ID of an attribute, you can get the value of it for a particular record with getAttribute and set it with setAttribute:

old_value = proxy.getAttribute(skey, 'projects', project_id, attrtype_id)
proxy.setAttribute(skey, 'projects', project_id, attrtype_id, new_value)

Note that in typed endpoints the getAttribute and setAttribute method assume all values are strings. To directly use numeric values without string conversion, use getAttributeNumber, getAttributeInteger, setAttributeNumber, or setAttributeInteger as appropriate.

While the server will throw an exception if you try to set an attribute to an invalid value, you can also use the checkAttributeValue (and checkAttributeValueInteger or checkAttributeValueNumber, in typed endpoints) method to perform explicit validation of a potential attribute value.

Since retrieving attribute values one at a time is cumbersome, the queryAttributes method is provided to retrieve many or all attribute values at once. The queryAttributes method takes three parameters (plus session key): a table name, a list of IDs of records in that table, and a list of Attribute Type IDs. Empty lists are treated as wildcards -- if the record ID list is empty the query will match every record in the table, and if the Attribute Type ID list is empty, it will return all attributes on the requested records.

In Journyx 9.1 and above, certain record types have a helper method to query all attributes from a single record. See getUserAttributes or getProjectAttributes, for example.

The queryAttributes method and the table helper methods mentioned above return a list of AttributeQueryResult records, which contain the following fields:

FieldDescription
object_idThe ID of the record this value is attached to
attrtype_idThe ID of the Attribute Type
attr_pnameThe printable name of the Attribute Type
valueThe value of the attribute

Note that in typed endpoints, the value field is always a string, even if the attribute actually contains a numeric value.

To create an Attribute Type, use the AddFullAttributeType method. This works similarly to adding any other kind of record through the jxAPI, in that you pass it a filled-out AttributeTypeRecord and get back an ID. See below for a discussion of what you can put in the attr_type field to declare the type of the attribute's values.

If an Attribute Type has a default value, it is stored in the Attribute Type record, or you can inspect it with getAttributeTypeDefaultValue (or getAttributeTypeDefaultValueNumber or getAttributeTypeDefaultValueInteger in typed endpoints). You can set the default value with setAttributeTypeDefaultValue (or setAttributeTypeDefaultValueInteger or setAttributeTypeDefaultValueNumber in typed endpoints.)

Historic Value Tracking

In addition to the object classes listed above, these classes can have "Historic" custom field tracking.

  • time_recs (regular Time Entry record)
  • expense_recs (Expense Entry record)
  • travel_recs (Mileage / Travel Entry records)

Every Attribute Type can be designated as "historic" for time, expense, or mileage, which means that when a new time/expense/mileage record is created, the value of the Attribute at the time when the record was created is saved for future reference. Historic attributes for Time, Expense, and Mileage only track the values of the "regular" Attribute Types at the time they were created, and are unaffected by changing the original values later. This is why they are called "Historic." You cannot attach independent custom fields to Time, Expense, or Mileage; you can only track historical values of the other custom fields, such as for Projects and Users.

For example, let's say that the user Jane is entering some Time Records, and Jane's userid is janesmith. The user object janesmith has an Pay Rate custom field value of 25, because this is Jane's hourly pay rate. If the Journyx administrator designates the User Pay Rate custom field "historical" for Time entries, then every time Jane creates a time record, the Pay Rate of 25 is recorded with each time record, independently from the actual Pay Rate entry for janesmith.

Now, let's suppose that Jane gets a promotion, and a subsequent pay rate of 30 per hour. (The Pay Rate custom field for the user object janesmith is changed from 25 to 30.) Jane goes and enters some new time records after her promotion, and these new records will have the new Pay Rate of 30. However, all the time records she entered before her promotion will still have the old Pay Rate of 25, even if those time records are modified in some way, such as if the comment was changed. This is useful for reporting and other analytical purposes.

While there is currently no way to retrieve historical attribute values using the jxAPI, you can declare an attribute type as historical with makeAttributeTypeAsHistorical and check what Attribute Types are historical with getHistoricalAttributeTypes. You can also stop recording historical values for an Attribute Type with dropAttributeTypeAsHistorical, which does not delete previously recorded values but will cause changes not to be recorded in the future.

Attribute Type Selection Lists

An Attribute Type can have a list of acceptable values associated with it, appearing as a popup list selector in the web interface. An Attribute Type is has a selection list if its data type begins with ENUM_, and the jxAPI includes several methods for manipulating the allowed values.

Although there is no externally visible record type associated with selection values, each of them has its own ID that is used to refer to it in some methods.

To add a selection value, use addAttributeTypeSelectionValue (or addAttributeTypeSelectionValueInteger or addAttributeTypeSelecionValueNumber as appropriate in typed endpoints). This method returns the ID of the just added value.

To set the default selection value, use setAttributeTypeSelectionDefault. Note that the usual means of setting a default value for attributes does not apply if the attribute has a selection list; you must use this method to flag an already existing selection value as the default instead.

To get the existing selection values for an attribute type, use getAttributeTypeSelectionValues for a list of just the values (always as strings), or getAttributeTypeSelectionValueRecords to get both the IDs and values.

Finally, to delete a selection value, use deleteAttributeTypeSelectionValue.

Note that you do not need to know a selection value ID, or even whether an attribute has selection values at all, to set its value -- simply pass the actual value to setAttribute, and it will be validated on the server side.

Attribute Data Types

Each Attribute Type has an associated attribute data type that determines what values are acceptable for the attribute. An attribute data type is a string, naming one of the following base types, plus an optional prefix and suffix:

  • NUMBER -- A floating point number, stored in the database as a double precision column. Consult your database documentation for the numeric limits of this type.
  • INTEGER -- A whole number, stored in the database as an integer column which typically has a range of -2147483648 to +2147483647.
  • STRING -- A variable length string with a maximum length of 252 characters unless otherwise specified. Note that only 7-bit ASCII characters are guaranteed to work; Unicode or other character sets may not be stored in the database or passed through the jxAPI properly.
  • CHAR -- A fixed length string. You must specify a maximum length, and values will be padded with spaces to that length.
  • DATE -- A string containing a date in YYYYMMDD format. Note that this is only a date, not a time; if you want to put times in a custom field, you must define your own format that you store in a different field type (STRING, or perhaps NUMBER for a Unix style timestamp).

In addition to the base type, you may add a suffix to either the STRING or CHAR types to specify the length of the field, for example "STRING_100" or "CHAR_30". For STRING fields this is the maximum size of the field, while CHAR fields are fixed-width.

You may also add the "ENUM_" prefix to a field to define it as a selection list, for example "ENUM_STRING" or "ENUM_STRING_50".

The checkAttributeDataType method can be used to verify whether a string is a valid attribute data type.