Skip to main content

Full-Sheet Submission in Journyx 10.1m1 and Above

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.

Starting with Journyx 10.1m1, a new set of API methods focusing on full-sheet submission is available. These methods provide an API workflow that is similar to the way the Journyx web interface handles sheet editing and submission, rather than the low-level, record-based access required in previous versions of the jxAPI. If your usage of the jxAPI involves modifying, submitting, and approving sheets, this new API may be beneficial to you.

The advantages of using the sheet-based API include:

  • Data is structured in the familiar "rows of cells" arrangement used in the web UI
  • A single API transaction can add or modify entries for multiple rows at once
  • Corrections and correction notes are handled for audit levels that require them
  • In/out times are supported for users with allocation entry screens
  • DVT and many customer-specific customizations are supported including returning errors to the client and blocking submission
  • No need to understand the structure and semantics of the Journyx database

Workflow

The basic full-sheet workflow consists of retrieving column data (if needed) and storing it for later use, retrieving a period, modifying one of the sheets in that period, saving and submitting the sheet, displaying the results to the user, and repeating.

First, for clients that need to allow a user to enter time or expenses, call the getDisplaySettings, getAllColumnRecords, getAllProjectDependencies, and getAllColumnDependencies methods to get the data you will need to properly display an entry screen to the user, populate and filter column data, and the like. Since this data tends to change much less frequently than sheet entries, you can cache it on the client side with a fairly long refresh interval.

Then, fetch a particular day's sheets with the getPeriodForDate method. Use the dates field of the sheet to determine the exact dates covered by the user's current period, as well as when the previous period ended and when the next one starts. (The DisplaySettings structure obtained in the previous step has fields that determine whether you should allow an interactive user to navigate between periods.) Note that creating a sheet yourself isn't supported -- always fetch a period with getPeriodForDate or an existing sheet with getSheet and modify that, otherwise the results may be unpredictable.

Modify existing rows or add new ones as you like. Don't reorder existing rows, and make sure to preserve the column_data field of the sheet, otherwise the server may duplicate existing rows or add new ones that you didn't intend. If the audit level requires correction notes, make sure to add one to any cell you have modified if the sheet has been submitted before. (See the audit_settings field of the sheet for the flags governing this.)

Save the sheet with save_sheet. Issues raised by the Data Validation Tool and other business logic will be reflected in the SheetSaveResult structure returned from this method. Check the success flag, and the status and errors arrays for messages describing what happened. If you have a cached copy of the sheet, replace it with the one returned in the sheet field of the SheetSaveResult, in case business logic on the server modified it.

Sheet-Based jxAPI Methods

The primary interface to full sheet submission is the save_sheet method:

save_sheet

save_sheet(sheet: Sheet, submit: boolean) -> SheetSaveResult

This method saves, and optionally submits for approval, a sheet to the server. It is functionally similar to modifying some data in the web user interface then pressing the Save or Submit button.

It returns a SheetSaveResult structure:

FieldTypeDescription
sheetSheetThe current contents of the sheet after the save/submit operation has completed.
successbooleanTrue if the operation was successful.
statusstring[]A list of status messages from the operation, if any.
errorsstring[]A list of error messages from the operation, if any.

punch_sheet

punch_sheet(sheet_id: string, inout: boolean) -> SheetSaveResult

For use when the user's default time sheet user interface is punch-only, this method is equivalent to clicking the punch in/out button in the web browser. Like save_sheet, it returns a SheetSaveResult containing the updated contents of the sheet.

getPeriodForDate

getPeriodForDate(date: string, full_sheets: boolean) -> Period

This method returns all three of a user's sheets for a specified date. (Note that they may not cover the same date range if the period lengths and starting dates are different!) The return is a Period structure:

FieldTypeDescription
time_sheetSheetThe user's time sheet for the specified date
expense_sheetSheetThe user's expense sheet for the specified date
custom_sheetSheetThe user's custom sheet for the specified date

getSheet

getSheet(sheet_type: string, sheet_id: string) -> Sheet

This method returns a single sheet, given its ID. The sheet_type parameter should be one of "time", "expense", or "custom", and the sheet_id parameter is the sheet's ID.

The Sheet Structure

Sheet

The Sheet structure includes almost all of the information that is displayed in the user's web browser while using Journyx, as well as metadata useful to clients. The "Save?" column of the table below indicates whether that field is used when saving a sheet; fields marked with "no" cannot be modified by save_sheet but will be ignored if sent back to the server.

FieldTypeSave?Description
idstringnoThe sheet's ID.
userstringnoThe user's ID.
user_loginstringnoThe user's login.
user_namestringnoThe user's full name.
typestringnoThe sheet type ("time", "expense", or "mileage".)
datesstring[]noAll dates in the sheet, in YYYYMMDD format.
statestringnoOne of "open", "submitted", "approved", "rejected", or "other".
statusstringnoA message describing the sheet status.
approverstringnoThe user ID of the next approver.
levelintnoThe level of the next approver.
reasonstringnoA message describing the reason the sheet was rejected.
totaldoublenoThe total of the hours, expenses, etc. in the sheet.
modified_atstringnoAn ISO8601 date describing when certain parts of the sheet were last modified.
audit_settingsSheetAuditSettingsnoThe current audit level settings for this sheet.
rowsSheetRow[]yes*A SheetRow structure representing each row in the sheet.
punchlistsSheetPunchList[]yesA SheetPunchList structure for each date in the sheet (corresponding to the date's position in dates).
column_datastringyesA binary value which you must preserve and include when saving a modified sheet.
can_be_submittedbooleannoIndicates whether the sheet can be submitted. May be useful in deciding whether to show a submit button.

Note that you must preserve and send back the column_data field of the sheet, along with preserving the order of existing rows, for modifications to work properly. Failure to do this will likely result in rows being duplicated or added erroneously, especially if you have changed any of the combo (project/code/comment) data.

The modified_at date may be used to help determine when you should automatically refresh a sheet from the server, but because not all possible modifications are tracked by the server database it is possible for this date not to be updated for certain changes (punch times, for example). Watch out for false negatives and if you are building a user facing client, consider providing a manual refresh option for users who also use the web interface.

SheetRow

A SheetRow represents one row of the sheet. That is, it has a single project/code/comment combo and a cell for each date in the sheet. Note that which column corresponds to "code0", "code1", and "code2" is dependent on the order specified in the user's display settings.

FieldTypeSave?Description
projectstringyesThe project ID.
project_namestringnoThe project displayed name.
code0stringyesThe first code ID (in order of display settings).
code0_namestringnoThe first code displayed name.
code1stringyesThe second code ID.
code1_namestringnoThe second code displayed name.
code2stringyesThe third code ID.
code2_namestringnoThe third code displayed name.
commentstringyesThe comment.
cellsSheetCell[]yes*One SheetCell structure per date in the sheet.

SheetCell

A SheetCell represents one "box" on the sheet:

FieldTypeSave?Description
amountdoubleyesThe amount in the cell (hours, dollars, etc.).
reasonstringno(Currently unused.) An error message if there is a problem with this cell.
errorbooleanno(Currently unused.) True if there is a problem with this cell.
notesCellNote[]yes*A list of notes attached to this cell.
attachmentsstring[]noThe encoded IDs of all file attachments on this cell.

Attachments are not included in their entirety due to size. Use the attachment-related jxAPI methods to retrieve, add, or delete them.

CellNote

A cell can have zero or more notes, each of which is represented by a CellNote:

FieldTypeSave?Description
idstringyesThe note's ID (empty when creating a new note).
modifiedbooleanyes*Set to true on save if modifying an existing note.
correctionbooleanyes*True if this is a correction note required by audit level.
textstringyesThe note text.

When modifying an existing note, set the modified flag to true. For a new note, leave id empty and set modified to true. Set the correction flag to true if this note was entered as a requirement of the audit level; this flag triggers special correction behavior on the server that will not be performed if you add a regular note.

SheetPunchList

Allocation times are represented by one SheetPunchList structure per date in the sheet:

FieldTypeSave?Description
punchesSheetPunch[]yesA list of punch times.

SheetPunch

A SheetPunch holds a single pair of in/out times:

FieldTypeSave?Description
time_instringyesThe punch in time, in HHMMSS format.
time_outstringyesThe punch out time, in HHMMSS format.

Note that punch times do not have an associated time zone. In the manual allocation entry UI format this doesn't make much difference, but note that punching in or out (with the punch_sheet or punch jxAPI methods, or the punch button in the web interface), the time recorded will be in the server timezone. Likewise, the behavior for punches that cross into a new day will be based on the server's idea of midnight.

SheetAuditSettings

The audit level settings of the sheet are provided in a SheetAuditSettings structure:

FieldTypeSave?Description
requires_new_entriesbooleannoTrue if sheets with new entries must be resubmitted.
has_ever_been_submittedbooleannoTrue if the sheet has ever been submitted for approval.
requires_correction_recsbooleannoTrue if correction notes are required with any change to a cell.
audit_level_settingstringnoThe audit level.

Other Useful Methods

A few other jxAPI methods are useful for a full-sheet workflow:

getAllColumnRecords

getAllColumnRecords(loggableOnly: boolean) -> AllColumnRecords

Returns all column records usable by the current user. This is a single-call way to get a complete list of the projects and codes that can be used to populate popups or completion menus on a client. The return value is a structure:

FieldTypeDescription
projectsProjectRecord[]Projects.
projects_extraProjectExtra[]Project extra fields.
codes_tasksCodeRecord[]Tasks (time code 0).
codes_pay_typesSubcodeRecord[]Pay types (time code 1).
codes_bill_typesSubsubcodeRecord[]Bill types (time code 2).
codes_expensesExpenseCodeRecord[]Expense codes (expense code 0).
codes_expense_sourcesExpenseSourceRecord[]Sources (expense code 1).
codes_currenciesExpenseCurrencyRecord[]Currencies (expense code 2).
codes_mileage_reasonsMileageReasonRecord[]Reasons (mileage/custom code 0).
codes_mileage_vehiclesMileageVehicleRecord[]Vehicles (mileage/custom code 1).
codes_mileage_measurementsMileageMeasurementRecord[]Measurements (mileage/custom code 2).

The ProjectExtra structure has extra fields for each project:

FieldTypeDescription
project_idstringThe project ID.
allow_timeintIf non-zero, can report time on this project.
allow_expenseintIf non-zero, can report expenses on this project.
allow_customintIf non-zero, can report mileage/custom on this project.
allow_leaveintIf non-zero, can make leave requests on this project.
allow_holidayintIf non-zero, can report holiday time on this project.

getAllProjectDependencies

getAllProjectDependencies(loggableOnly: boolean) -> ProjectDependencies[]

Returns all project dependencies for the current user. This is a single-call way to get dependency information used for filtering column data as the user selects it in a client. The return value is a list of structures:

FieldTypeDescription
project_idstringThe project ID.
project_namestringThe project name.
project_descriptionstringThe project description.
codes_tasksstring[]IDs of dependent codes (time code 0).
codes_pay_typesstring[]... (time code 1)
codes_bill_typesstring[]... (time code 2)
codes_expensesstring[]... (expense code 0)
codes_expense_sourcesstring[]... (expense code 1)
codes_currenciesstring[]... (expense code 2)
codes_mileage_reasonsstring[]... (mileage/custom code 0)
codes_mileage_vehiclesstring[]... (mileage/custom code 1)
codes_mileage_measurementsstring[]... (mileage/custom code 2)

getAllColumnDependencies

getAllColumnDependencies() -> ColumnDependency[]

Returns all code column dependencies for the current user. This is a single-call way to get dependency information used for filtering column data as the user selects it in a client. The return value is a list of structures:

FieldTypeDescription
parent_tablestringThe parent table (eg. "codes_tasks").
parent_idstringThe parent code ID.
child_tablestringThe child table.
child_idstringThe child code ID.

getDisplaySettings

getDisplaySettings() -> DisplaySettings

Returns the user's display settings. Some parts of the sheet structure depend on information found here, in particular the order and visibility of combo columns. The return value is a structure:

FieldTypeDescription
time_labelstringThe label for time screens.
time_column_namesstring[]Names of time columns. (See below.)
time_column_priorityint[]Order of time columns. (See below.)
time_column_defaultsstring[]Default values for time columns. (See below.)
expense_labelstringThe label for expense screens.
expense_column_namesstring[](See below.)
expense_column_priorityint[](See below.)
custom_labelstringThe label for custom/mileage screens.
custom_column_namesstring[](See below.)
custom_column_priorityint[](See below.)
allow_blank_commentsbooleanAre blank comments allowed?
time_gridstringThe time entry type: "plain", "inout" (allocation), or "punch" (punch-based allocation).
time_view_futurebooleanCan the user view future time sheets?
time_view_pastbooleanCan the user view past time sheets?
expense_view_futurebooleanCan the user view future expense sheets?
expense_view_pastbooleanCan the user view past expense sheets?
custom_view_futurebooleanCan the user view future custom/mileage sheets?
custom_view_pastbooleanCan the user view past custom/mileage sheets?

The column names, priority, and defaults are always in the same order: project, code0, code1, code2, comment. The priority list determines what order they should be displayed in on a client; a priority of zero means the column is not displayed. The specific tables that correspond to codes 0, 1, and 2 are always the same:

TypeCode0Code1Code2
Timetaskspay_typesbill_types
Expenseexpensesexpense_sourcescurrencies
Custommileage_reasonsmileage_vehiclesmileage_measurements

timezone

timezone() -> int

This method does not require a session key.

Returns the offset from UTC of the Journyx server's timezone.