# Enregistrement des activités

Nous allons détailler ici les différentes opérations qui permettent de réaliser ces enregistrements.

## Prérequis

Toutes les opérations explicitées ci-après nécessitent l'authentification d'un compte "activé" :&#x20;

* à la suite de l'inscription, l'utilisateur doit confirmer son adresse email pour activer son compte
* tant que son compte n'est pas actif, les opérations ci-dessous ne seront pas disponibles

{% hint style="info" %}
Pour en savoir plus sur le parcours utilisateur, vous pouvez consulter les notices d'utilisation des [travailleurs mobiles](https://mobilic.beta.gouv.fr/resources/driver) et des [gestionnaires](https://mobilic.beta.gouv.fr/resources/admin)
{% endhint %}

Pour savoir si un compte utilisateur est actif, l'opération suivante permet de récupérer les paramètres `hasActivatedEmail` et `hasConfirmedEmail` :&#x20;

```graphql
query user {
  user(id: XXXXX) {
    hasConfirmedEmail
    hasActivatedEmail
  }
}
```

Ceux-ci doivent correspondre à `true`.

## Opérations <a href="#operations" id="operations"></a>

### Récupérer les entreprises sur lesquelles un salarié peut créer une mission <a href="#creation-dune-nouvelle-mission" id="creation-dune-nouvelle-mission"></a>

Pour pouvoir récupérer les id des entreprises sur lesquelles un salarié peut renseigner du temps de travail, l'opération suivante peut être utilisée :

```graphql
query user {
  user(id: XXXXX) {
    currentEmployments {
      company {
        name
        id
      }
    }
  }
}
```

### Création d'une nouvelle mission <a href="#creation-dune-nouvelle-mission" id="creation-dune-nouvelle-mission"></a>

Avant d'enregistrer les activités il est indispensable de créer une mission à laquelle seront rattachées les activités.

L'opération de création de la mission est la suivante :

```graphql
mutation {
    activities {
        createMission(name: "XXX", "companyId: YYY) {
            id
            name
        }
    }
}
```

Il y a deux variables, optionnelles toutes les deux :

* `name`
* `companyId`, qui permet de préciser l'entreprise associée à la mission dans le cas où l'auteur est rattaché à plusieurs entreprises.

{% hint style="info" %}
Si une entreprise est donnée via `companyId` il faut que l'auteur y soit rattaché, soit en tant que gestionnaire soit en tant que travailleur. Dans le cas où aucune entreprise n'est précisée la mission est associée à l'entreprise de rattachement principale de l'auteur.
{% endhint %}

La création de la mission ne déclenche pas le démarrage du chrono de temps de travail : les deux moments sont séparés. Cela permet par exemple à l'exploitant de planifier et de créer à l'avance les missions dans son logiciel métier, qui pourrait ensuite les enregistrer dans l'interface dédiée aux travailleurs mobiles pour leur permettre de renseigner le temps de travail de chaque mission le moment venu.

### Enregistrement d'une activité <a href="#enregistrement-dune-activite" id="enregistrement-dune-activite"></a>

L'enegistrement d'une activité se fait au moyen de l'opération `logActivity`.

C'est l'opération principale.

```graphql
mutation(
  $type: ActivityTypeEnum!
  $startTime: TimeStamp!
  $endTime: TimeStamp
  $switch: Boolean
  $userId: Int
  $context: GenericScalar
  $missionId: Int!
) {
  activities {
    logActivity(
      type: $type
      startTime: $startTime
      missionId: $missionId
      endTime: $endTime
      switch: $switch
      context: $context
      userId: $userId
    ) {
      id
      type
      startTime
    }
  }
}
```

Elle prend en arguments :

* `type`, la nature de la nouvelle activité (déplacement, travail, accompagnement)
* `startTime`, l'heure de début d'activité
* `missionId`, la mission pour laquelle est effectuée l'activité
* `endTime`, l'heure de fin d'activité (optionnelle)
* `switch`, indique si le mode d'enregistrement tachygraphe est activé (optionnel, par défaut oui)
* `userId`, le travailleur mobile pour lequel enregistrer l'activité (optionnel, par défaut c'est l'utilisateur authentifié)
* `context`, des données libres qui seront rattachées à l'activité

{% hint style="info" %}
Par défaut l'activité est enregistrée pour l'utilisateur qui effectue l'opération (l'utilisateur authentifié avec le jeton). Afin de faciliter l'usage de l'API il est possible d'enregistrer des activités pour un autre utilisateur, en utilisant le champ `userId`.
{% endhint %}

#### **Mode d'enregistrement tachygraphe**

L'API Mobilic privilègie une saisie en temps réel des activités, dans laquelle les évènements de changement d'activité sont transmis à l'API. L'heure de fin d'une activité n'est déterminée qu'au moment du changement d'activité suivant.

En conséquence l'opération `logActivity` a deux modes de fonctionnement :

* le mode "tachygraphe", correspondant au principe ci-dessus (`switch: true`). L'API enregistre les **changements d'activité**.
* un mode plus classique où les activités sont saisies a posteriori avec leur heure de fin éventuelle (`switch: false`). L'API enregistre directement **les activités**.

Plus précisément le mode "tachygraphe" fonctionne de la manière suivante :

* la variable `startTime` correspond à l'heure de changement d'activité. Au moment de l'opération l'utilisateur ne peut pas avoir d'activité enregistrée après cette heure. En d'autres termes le changement d'activité n'est possible que **pendant ou après la dernière activité**.
* l'opération **n'accepte pas d'heure de fin** (`endTime`)
* si la dernière activité de l'utilisateur n'est pas terminée **l'opération met fin à la dernière activité à l'heure** `startTime`.
* l'opération crée une **nouvelle activité démarrant à** `startTime` **et sans date de fin**.

Par opposition le mode d'enregistrement classique se contente de créer une nouvelle période d'activité pour l'utilisateur, en vérifiant simplement qu'il n'y a pas de chevauchement avec son historique. Il peut notamment être utilisé pour intercaler une nouvelle activité parmi les activités passées (ce que le mode tachygraphe ne permet pas de faire).

### Mise à jour d'une activité <a href="#mise-a-jour-dune-activite" id="mise-a-jour-dune-activite"></a>

L'opération de correction ou de modification d'une activité est `editActivity`. Seule la période d'une activité est modifiable (pas le type de travail, ni la mission ni le travailleur concernés)

```graphql
mutation(
  $activityId: Int!
  $startTime: TimeStamp
  $endTime: TimeStamp
  $removeEndTime: Boolean
  $context
) {
  activities {
    editActivity(
      activityId: $activityId
      startTime: $startTime
      endTime: $endTime
      removeEndTime: $removeEndTime
      context: $context
    ) {
      id
      type
      startTime
    }
  }
}
```

Elle prend en arguments :

* `activityId`, l'identifiant de l'activité à modifier
* `startTime`, la nouvelle heure de début (optionnelle, si elle a été modifiée)
* `endTime`, la nouvelle heure de fin (optionnelle, si elle a été modifiée)
* `removeEndTime`, indique si la fin de l'activité doit être annulée (optionnel et incompatible avec `endTime`). Utile si l'activité a été terminée par erreur.
* `context`, des données libres qui seront rattachées à l'évènement de modification.

### Annulation d'une activité <a href="#annulation-dune-activite" id="annulation-dune-activite"></a>

L'opération d'annulation d'une activité est `cancelActivity`. Elle permet de supprimer l'activité de l'historique de l'utilisateur.

```graphql
mutation(
  $activityId: Int!
  $context
) {
  activities {
    cancelActivity(
      activityId: $activityId
      context: $context
    ) {
       success
    }
  }
}
```

### Fin de mission <a href="#fin-de-mission" id="fin-de-mission"></a>

L'opération signale la fin de la mission pour le travailleur mobile.

```graphql
mutation(
  $missionId: Int!
  $endTime: TimeStamp!
  $userId: Int
  $context: GenericScalar
) {
  activities {
    endMission(
      missionId: $missionId
      endTime: $endTime
      userId: $userId
      context: $context
    ) {
      id
      name
    }
  }
}
```

Les arguments de l'opération ont la même fonction que pour l'enregistrement d'une activité. Dans le cas où la dernière activité de l'utilisateur n'est pas terminée l'opération y met fin à l'heure `endTime`.

### Création d'une absence

La création d'une absence est plus simple grace à l'opération `logHoliday`. Elle permet de créer une mission avec une activité de type `OFF` et de la valider en un seul appel.

```graphql
mutation (
    $companyId: Int!
    $userId: Int
    $startTime: TimeStamp!
    $endTime: TimeStamp!
    $title: String!
) {
    activities{
        logHoliday(
            companyId: $companyId
            userId: $userId
            startTime: $startTime
            endTime: $endTime
            title: $title
        ) {
            id
        }
    }
}
```

Elle prend en arguments :&#x20;

* `comment`, le motif de l'absence (optionel)
* `companyId`, l'identifiant de l'entreprise pour laquelle l'absence est enregistrée
* `endTime`, l'heure de fin de l'absence
* `startTime`, l'heure de début de l'absence
* `title`, l'intitulé de l'absence
* `userId`, l'identifiant du salarié concerné par l'absence (optionnel, par défaut c'est l'auteur de l'opération)

## Exemples <a href="#exemples" id="exemples"></a>

Nous allons illustrer l'utilisation et le rôle des opérations précédentes à travers l'exemple d'une journée de travail classique.

### Début de journée <a href="#debut-de-journee" id="debut-de-journee"></a>

La première action à effectuer consiste à créer une mission.

```graphql
mutation {
  activities {
    createMission(name: "Journée test", companyId: 1) {
      id
      name
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "createMission": {
        "id": 18,
        "name": "Journée test"
      }
    }
  }
}
```

#### **Lieu de début de mission**

Une fois la mission créée, on peut renseigner le lieu de début de mission, et le kilométrage du véhicule.

Ces informations sont obligatoires.

```graphql
mutation {
  activities {
    logLocation(missionId: 18, type: "mission_start_location", manualAddress: "10 avenue de la République 75011", kilometerReading: 5500) {
      id
      name
    }
  }
}
```

Pour plus d'information sur le renseignement des lieux d'une mission, se référer à la page suivante :

{% content-ref url="/pages/4SLtn48D8QhvBeWD7Xw1" %}
[Enregistrement des lieux de début et de fin de mission](/guides/enregistrement-des-lieux-de-debut-et-de-fin-de-mission.md)
{% endcontent-ref %}

#### **Première activité**

On peut ensuite enregistrer le démarrage de la première activité de la mission.

```graphql
mutation {
  activities {
    # 9h00
    logActivity(missionId: 18, type: "drive", startTime: 1577869200) {
      id
      type
      startTime
      endTime
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "logActivity": {
        "id": 193,
        "type": "drive",
        "startTime": 1577869200,
        "endTime": null
      }
    }
  }
}
```

En mode tachygraphe l'activité n'a pas d'heure de fin au moment de son enregistrement. Tant que l'API ne reçoit pas un nouvel évènement de changement ou de fin d'activité le chronomètre continue de tourner.

#### **Deuxième activité**

L'enregistrement du changement d'activité se fait de manière identique à l'enregistrement précédent, c'est-à-dire en mode tachygraphe.

```graphql
mutation {
  activities {
    # 11h00
    logActivity(missionId: 18, type: "work", startTime: 1577876400) {
      id
      type
      startTime
      endTime
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "logActivity": {
        "id": 194,
        "type": "work",
        "startTime": 1577876400,
        "endTime": null
      }
    }
  }
}
```

Le changement d'activité a créé une nouvelle activité débutant à 11h (et sans heure de fin) et a mis fin à l'activité précédente à cette même heure.

### Pause <a href="#pause" id="pause"></a>

Pour indiquer la fin d'une activité sans démarrage immédiat d'une autre activité, il suffit d'éditer la date de fin de l'activité.

```graphql
mutation {
  activities {
    # 12h30
    editActivity(activityId: 194, endTime: 1577881800) {
      id
      type
      startTime
      endTime
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "editActivity": {
        "id": 194,
        "type": "work",
        "startTime": 1577876400,
        "endTime": 1577881800
      }
    }
  }
}
```

### Fin de journée <a href="#fin-de-journee" id="fin-de-journee"></a>

**Troisième activité**

Une fois la pause terminée l'enregistrement des activités peut reprendre, toujours en mode tachygraphe.

```graphql
mutation {
  activities {
    # 14h00
    logActivity(missionId: 18, type: "work", startTime: 1577887200) {
      id
      type
      startTime
      endTime
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "logActivity": {
        "id": 195,
        "type": "work",
        "startTime": 1577887200,
        "endTime": null
      }
    }
  }
}
```

Lors du décompte du temps de travail sur la journée, les périodes de creux entre deux activités seront automatiquement décomptées comme du temps de pause.

#### **Quatrième activité**

```graphql
mutation {
  activities {
    # 15h30
    logActivity(missionId: 18, type: "drive", startTime: 1577892600) {
      id
      type
      startTime
      endTime
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "logActivity": {
        "id": 196,
        "type": "drive",
        "startTime": 1577892600,
        "endTime": null
      }
    }
  }
}
```

#### **Lieu de fin de mission**

On termine la journée en renseignant le lieu de fin de mission, et le nouveau kilométrage du véhicule.

Ces informations sont obligatoires.

```graphql
mutation {
  activities {
    logLocation(missionId: 18, type: "mission_end_location", manualAddress: "25 avenue de la République 75011", kilometerReading: 5550) {
      id
      name
    }
  }
}
```

Pour plus d'information sur le renseignement des lieux d'une mission, se référer à la page suivante :

{% content-ref url="/pages/4SLtn48D8QhvBeWD7Xw1" %}
[Enregistrement des lieux de début et de fin de mission](/guides/enregistrement-des-lieux-de-debut-et-de-fin-de-mission.md)
{% endcontent-ref %}

#### **Fin de mission**

Pour terminer la mission il suffit d'effectuer l'opération `endMission` en passant la date de fin de l'activité en cours.

```graphql
mutation {
  activities {
    # 17h
    endMission(missionId: 18, endTime: 1577898000) {
      id
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "endMission": {
        "id": 18
      }
    }
  }
}
```

### Corrections éventuelles <a href="#corrections-eventuelles" id="corrections-eventuelles"></a>

Le travailleur mobile s'aperçoit de quelques erreurs et oublis dans sa saisie intiale.

#### **Oubli de redémarrer après la pause**

La vraie heure de reprise d'activité après la pause du midi est 13h30 mais l'utilisateur n'a enregistré la reprise qu'à 14h. Pour corriger cela il lui suffit d'indiquer que l'activité de reprise a en fait démarré une demi-heure plus tôt.

```graphql
mutation {
  activities {
    # 13h30
    editActivity(activityId: 195, startTime: 1577885400) {
      id
      type
      startTime
      endTime
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "editActivity": {
        "id": 195,
        "type": "work",
        "startTime": 1577885400,
        "endTime": 1577892600
      }
    }
  }
}
```

**Correction de la fin d'une activité**

Le travailleur mobile a signalé trop tôt la fin de mission. Il souhaite décaler la date de fin de 17h à 17h30.

```graphql
mutation {
  activities {
    # 17h30
    editActivity(activityId: 196, endTime: 1577899800) {
      id
      type
      startTime
      endTime
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "editActivity": {
        "id": 196,
        "type": "work",
        "startTime": 1577892600,
        "endTime": 1577899800
      }
    }
  }
}
```

**Rajout d'une activité a posteriori**

Le travailleur mobile souhaite ajouter une activité qui s'est déroulée de 8h à 9h. Il lui suffit d'enregistrer une activité en mode classique.

```graphql
mutation {
  activities {
    # 8h - 9h
    logActivity(
      missionId: 18
      type: "work"
      startTime: 1577865600
      endTime: 1577869200
      switch: false
    ) {
      id
      type
      startTime
      endTime
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "logActivity": {
        "id": 197,
        "type": "work",
        "startTime": 1577865600,
        "endTime": 1577869200
      }
    }
  }
}
```

#### **Validation de la mission**

Pour valider la mission il suffit d'effectuer l'opération `validateMission`.

```graphql
mutation {
  activities {
    validateMission(missionId: 18, usersIds: [1577898000]) {
      id
    }
  }
}
```

Réponse

```json
{
  "data": {
    "activities": {
      "validateMission": {
        "id": 18
      }
    }
  }
}
```

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developers.mobilic.beta.gouv.fr/guides/enregistrement-des-activites.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
