Introduction

You Goal

There can be many reasons to submit timesheets through API requests. A common use case is to submit timesheets that were already automatically filled with TimeEntries through previous API requests. If there is no need to let the employee adjust it, then you can submit their timesheet for them directly.

What Is a Timesheet?

Timesheets are TimeEntries containers. A timesheet belongs to a single user owner and ranges over several days [startsOn - endsOn[ (endsOn excluded). Its range depends on the submission frequency set up in Timmi Timesheet (weekly / monthly).

A timesheet purpose is to ease the approval workflow: rather than approving each TimeEntry individually, they are approved in a weekly / monthly batch.

See the Timesheet API Reference for additional information on timesheets and approval workflow.

Prerequisites

You will need:

Guide

1. Identify Timesheets Due For Submission

You first need to get your hands on the unique identifiers ownerId of the timesheet owners you will want to submit timesheets.

Then, you can list all due timesheets with a GET request to /api/v3/timmitimesheets/remindable, filtering either on ownerIds, managerIds or legalEntityIds. See the API reference here.

While a timesheet is only created upon submitting it, you can still retrieve “calculated” timesheets that represent the ones that still have not been submitted. These timesheets all have an id equal to 0 (zero).

POST /api/v3/timmitimesheets/remindable?ownerids=45,16&fields=id,startsAt,endsAt,status,ownerid HTTP/1.1
Host: {yourDomain}
Authorization: lucca application={apiKey}
Content-Type: application/json

{
  "items": [
    {
      "id": 0,
      "startsAt": "2024-01-29T00:00:00",
      "endsAt": "2024-02-26T00:00:00",
      "status": 0,
      "ownerId": 16
    },
    {
      "id": 0,
      "startsAt": "2024-02-26T00:00:00",
      "endsAt": "2024-04-01T00:00:00",
      "status": 0,
      "ownerId": 16
    },
    {
      "id": 0,
      "startsAt": "2024-04-29T00:00:00",
      "endsAt": "2024-05-06T00:00:00",
      "status": 0,
      "ownerId": 45
    },
    {
      "id": 0,
      "startsAt": "2024-04-01T00:00:00",
      "endsAt": "2024-04-29T00:00:00",
      "status": 0,
      "ownerId": 16
    },
    {
      "id": 0,
      "startsAt": "2024-04-29T00:00:00",
      "endsAt": "2024-05-27T00:00:00",
      "status": 0,
      "ownerId": 16
    },
    ...
  ]
}

2. Submit Timesheets

Timesheets must be submitted in chronological order (from the oldest to the newest). On any request submitting a given N timesheet, if there is an older N-1, N-2, … timesheet pending submission for that user, the request will return an error.

Hence, you can either :

  1. Submit timesheets for each user precisely in chronological order from the oldest to the latest.
  2. Include all timesheets pending submission in a single request (easiest solution)

Transfer authorizations can be set up at Timesheets’ regulation level to link 2 Timesheet accounts, allowing upon timesheet submission and following approval workflow steps to transfer a certain duration amount from the to-be-debited account to the to-be-credited account.

See Timesheet API reference and Transfer API reference for additional information.

Continuing the example above, if you want to submit John (id=16) first 2 timesheets with a transfer for the first one, and Sarah (id=45) early may timesheet, the easiest solution is to send the following request :

POST /timmi-timesheet/api/timmi/services/workflow/submit HTTP/1.1
Host: {yourDomain}
Authorization: lucca application={apiKey}
Content-Type: application/json

{
  "timesheets": [
    {
      "startsAt": "2024-01-29T00:00:00",
      "endsAt": "2024-02-26T00:00:00",
      "ownerId": 16,
      "transfers": [
        {
          "transferAuthorizationId": 0,
          "amount": "02:00:00",
          "comment": "2h extra hours to be paid. Discussed with Tom."
        }
      ]
    },
    {
      "startsAt": "2024-02-26T00:00:00",
      "endsAt": "2024-04-01T00:00:00",
      "ownerId": 16,
    },
    {
      "startsAt": "2024-04-29T00:00:00",
      "endsAt": "2024-05-06T00:00:00",
      "ownerId": 45,
    }
  ]
}

As a result, the following timesheets would have been submitted:

{
  "id": 10539,
  "startsAt": "2024-01-29T00:00:00",
  "endsAt": "2024-02-26T00:00:00",
  "status": 1,
  "ownerId": 16
},
{
  "id": 10540,
  "startsAt": "2024-02-26T00:00:00",
  "endsAt": "2024-04-01T00:00:00",
  "status": 1,
  "ownerId": 16
},
{
  "id": 10542,
  "startsAt": "2024-04-01T00:00:00",
  "endsAt": "2024-04-29T00:00:00",
  "status": 1,
  "ownerId": 45
}

But those later timesheets would still be pending submission:

{
  "id": 0,
  "startsAt": "2024-04-01T00:00:00",
  "endsAt": "2024-04-29T00:00:00",
  "status": 0,
  "ownerId": 16
},
{
  "id": 0,
  "startsAt": "2024-04-29T00:00:00",
  "endsAt": "2024-05-27T00:00:00",
  "status": 0,
  "ownerId": 16
}