
# Documentation paw-HERMES
Cette documentation ajoute des précisions sur les différents appels de Flux réalisés, elle vient en complément de la documentation swagger disponible sur 
## liens utiles
[swagger du projet](/api/swagger/index.html)

[changelog](/api/dmo/changelog)

### Liste des hosts accessibles pour la solution :

intitulé|host par vpn|host externe
--------|------------|------------
environnement de développement|[https//dev.hermes.openstack.local](https://dev.hermes.openstack.local)|[https://doc-alshermes-int.be-idys.com](https://doc-alshermes-int.be-idys.com)
environnement de recette|[https://test.hermes.openstack.local](https://test.hermes.openstack.local)|[https://als-hermes-scoring-rec.be-idys.com](https://als-hermes-scoring-rec.be-idys.com)
environnement de démo|[https://demo.hermes.openstack.local](https://demo.hermes.openstack.local)|[https://als-hermes-demo-api.be-idys.com](https://als-hermes-demo-api.be-idys.com)

### url des clients frontends ALS:
intitulé|url
--------|------------
environnement de développement|[https://als-hermes-int.be-idys.com/](https://als-hermes-int.be-idys.com/)
environnement de recette|[http://als-hermes-entreprise-rec.be-idys.com/](http://als-hermes-entreprise-rec.be-idys.com/)

## url GED

[https://ged-test.dev.hermes.openstack.local](https://ged-test.dev.hermes.openstack.local)

als-hermes-int.be-idys.com
## Utilitaires de recherche

### Utilitaire de tri

Pour trier un retour dans notre application, utilisez le paramètre de recherche « sort » :

	?sort[champ1]=-1&sort[champ2]=1 …

La valeur « -1 » demande un tri décroissant, la valeur « 1 » demande un tri croissant.

Par exemple, pour trier sur la date de création de manière décroissante (du plus récent au plus ancien) :

	?sort[creation_date]=-1

###  Utilitaires de restriction logique

À votre disposition - pour tous les champs qui peuvent être recherchés sur tous les modèles, les opérateurs logiques suivants :

####  De grandeur

 - $gt : strictement plus grand que
 - $gte : plus grand ou égal à
 - $lt : strictement plus petit que
 - $lte : plus petit ou égal à

#### D’équité / d’iniquité

 - $ne : n'est pas 
 - $nin : n’est pas contenu dans 
 - $eq : est exactement 
 - $in : est contenu dans

#### D’expression régulière

 - $regex : avec une expression régulière sans les « / » de début et de
   fin

#### D'opération logique

 - **$or** et **$and** : une liste de listes associatives, chacune étant un nouveau filtre acceptant toutes les options précédement citées

    ex : ?$or[][field1]=value1&$or[][field2]=value2

équivaut à :

    {
      "$or": [
        {
          "field1": "value1",
          "field2": "value2
        }
      ]
    }

Il est aussi possible d'utiliser des index pour scinder les éléments de liste :

    ex: ?$or[0][field1]=value1&$or[1][field2]=value2

équivaut à :

    {
      "$or": [
        { "field1": "value1" },
        { "field2": "value2" }
      ]
    }

#### Complément d'info :
Ces opérateurs sont cumulables.

Ils s’utilisent de la façon suivante dans une requête :			  

    ?champ1[operateur1]=value&champ2[operateur2]=value&champ1[operateur2]=value …

L’exemple : 

    ?created_at[$lt]=2018-03-12T22:30&is_active[$ne]=true

Veut dire : _qui a été créé avant le 12 mars 2018 à 22h30 non inclue (strictement plus petit que) et qui n’est pas actif._

Exception faite sur les paramètres $in et $nin qui n’acceptent que des liste donc :

    ?title[$in][]=titre1&title[$in][]=titre2&status[$nin][]=PRET&status[$nin][]=PARTEZ

Veut dire : _qui a un titre contenue dans **[titre1, tritre2]** et un statut non contenu dans **[PRET, PARTEZ]**_

**ATTENTION:** *Si deux critères envoyés sont contradictoires il n’y aura aucun résultat.*

## Flux 3 accès aux candidatures transmises aux bailleurs

Pour répondre à ce besoin deux routes accessiblent via l'API :
* GET api/dmo/housing_offers/with_validated_applications
* GET api/dmo/housing_offers/with_validated_applications/{id}

### Paramètre obligatoire : "from"

Pour ces deux appels est nécessaire le paramètre **"from"**.

    {uri}?for={yyyy}-{mm}-{dd}T{hh}:{mm}:{ss}

Paramètre de filtrage pour limiter la date minimale de passage au statut "TRANSMIS BAILLEUR".

### Paramètres de recherche accessibles

Il est possible d'employer tous les champs et utilitaires de recherche accessibles pour les offres.

### Autre paramètre optionnel : "to"

Pour ces deux appels, est possible l'utilisation du paramètre **"to"**.

    {uri}?to={yyyy}-{mm}-{dd}T{hh}:{mm}:{ss}

Paramètre de filtrage pour limiter la date maximale de passage au statut "TRANSMIS BAILLEUR".

### Liste des offres ayant des candidatures au statut "TRANSMIS BAILLEUR"

uri :

    GET api/dmo/housing_offers/with_validated_applications?from={yyyy}-{mm}-{dd}T{hh}:{mm}:{ss}

Affiche la liste des offres ayant une ou plusieurs candidatures au statut **"TRANSMIS BAILLEUR"**, et qui ont pris ce statut depuis **"from"**.

### Liste des candidatures ayant l'état "TRANSMIS BAILLEUR" pour une offre donnée

uri :

    GET api/dmo/housing_offers/with_validated_applications/{id}?from={yyyy}-{mm}-{dd}T{hh}:{mm}:{ss}:{msms}

Le paramètre de chemin **"id"** étant l'id de l'offre souhaitée.
Affiche la liste des candidatures au statut **"TRANSMIS BAILLEUR"** pour une offre donnée, et qui est passée à ce statut depuis **"from"**.

## FLux 4 Gestion des statuts d'une offre

### route spécifique bailleurs

    POST     /api/dmo/housing_applications/update_status/
    
    {  
    "data":{     
      "attributes":{
                 "unique_number":"0690412654321G3U05",
                 "external_ref":"CVL-000014",
                 "status":"Visite proposée",
                 "last_status_update_date":"01/01/0001",
                 "lessor_event_informations ":"0"
        }
      }
    }
     

### Explication rapide du concept de "status"

Pour gérer au niveau du moteur le cycle de vie d'un objet, nous employons le concept de **"status"**.
Ceux-ci permettent de discriminer des objets entre eux en fonction de l'état "métier" dans lequel ils se trouvent.

Pour gérer ces statuts il y a deux méthodes accessibles :
- 1. Modifier un champ "status" sur une offre
- 2. Produire un "status" détaillé par la route : **POST api/dmo/statuses**

### Changement de "status" simple

Dans le cas des offres, les champs accessibles pour gérer ces changements non-détaillés de "status" sont les suivants :
- **lessor_status:** status fournit par le bailleur
- **offer_status:** status fournit par SOPRA ou produit par effet de bord
Changer la valeur d'un de ces champs vers la valeur adéquate, permet au moteur de produire les effets souhaités.

### Changement de "status" détaillé

uri :

     POST api/dmo/statuses

Il s'agit ensuite de fournir un corps de requête adéquat.
Pour le détail fonctionnel des champs présents dans notre swagger [https://als-hermes-scoring-rec.be-idys.com/api/swagger/index.html](https://als-hermes-scoring-rec.be-idys.com/api/swagger/index.html):
- **status_label:** complément de status indiquant à quel concept ce status est associé (ex: *lessor*, *offer*, *request*, *entity*, ...)
- **motive:** description du motif de passage à ce status
- **title:** intitulé du status. IMPORTANT : La validité parfaite de sa valeur est essentielle => ce champs détermine - pour le moteur, l'état métier actuel de l'objet associé.
- **object_id:** id de l'objet associé
- **performer_id:** dans le cas d'une possibilité de "status" concurrents, il est essentiel d'indiquer ici l'id du déclencheur de ce status. *(non utile dans le cas du bailleur)*

### Correspondance des évènements aux status

**NOUS AVONS BESOIN DE FAIRE UN POINT SUR CETTE CORRESPONDANCE.**

évènement|label de status|valeur PAW
---------|---------------|----------
||

## Flux 5 Mise à jour des bien MAD

Ce flux se déclenche lors d'une mise à disposition d'un bien, ou lors de la modification d'une offre en état MAD.
Son déclenchement implique la mise à jour de l'objet SOPRA associé.

## Flux 6A, 6B, 6C et 39 infos générales

uri globale : 

    GET api/dmo/housing_offers/${id}/eligible_request

Avec pour ${id} l’id de l’offre choisie.

Mapping des valeurs :

 - Numéro interne demande ALS => **als_id** 
 - Scoring intial =>  **profile_epci_score** 
 - Scoring actuel (si positionné) => **score_with_position** 
 - Rang initial => **eligible_position** 
 - Rang actuel (estimation ou réél si positionné) => **applicated_position**
 - Taux d’effort => **effort_rate**
 - Nombre de candidatures du demandeur => **applications_nb**

###  Flux 6A Instruction d'une offre - Onglets candidatures Affichage de la liste des propositions en cours d'instruction

Utilisez le paramètre de recherche « ids » contenant la liste des demandes éligibles à étudier :

    ids[]=${id1}&ids[]=${id2}&ids[]=${id3} …

Pour obtenir les demandes éligibles à une offre portant les ids saisis.

Ou

    ?als_id[$in][]=${id1}& als_id[$in][]=${id2}& als_id[$in][]=${id3} …

Pour Obtenir les demandes éligibles à une offre portant les als_id saisis.

### Flux 6B et 6C infos générales

Trier par scoring, exemple : 

    ?sort[profile_epci_score]=(-1 || 1)

Disponible aussi - comme pré-décrit, sur tous les autres champs des demandes.

#### Flux 6B Instruction d'une offre - Affichage de la liste des candidatures et de leurs scoring respectifs

Ajouter le paramètre 

    housing_offer_ids=${id} 

${id} étant l’id de l’offre en question, pour obtenir toutes les demandes positionnées sur l’offres.

#### Flux 6C Instruction d'une offre - Demandes éligibles Affichage de la liste des demandeurs éligibles (non positionnés sur l'offre) et de leurs scoring respectifs

Ajouter le paramètre 

    housing_offer_ids[$ne]=${id}

${id} étant l’id de l’offre en question, pour obtenir toutes les demandes non positionnées sur l’offres.

#### récuperer l'ensemble des candidatures liées a une offre donnée :
la demande liée à la candidature sera dépliée dans la réponses (champs housing_reqquest + main_applicant)

    GET /api/dmo/housing_offers/{id}/all_applications
    
### Flux 39 Affichage de la demande et de la liste des offres éligibles pour cette demande

Utilisez ensuite les utilitaires de recherche (cf : Utilitaires de recherche) sur les champs souhaités pour filtrer les demandes éligibles selon les critères définis.

##  Flux 7 Liste des offres à traiter par les différents rôles (COL, ROL, CDL-C)

    GET api/dmo/housing_offers

Utilisez le paramètre **« ids[] »** ou **« als_id[$in] »** pour rechercher un lot spécifique d’offre.

Mapping des champs :

 - Nombre de demande éligibles par orientation => **eligible_requests_nb_detailed**
	 - Contient potentiellement (absent ou à 0 si aucune demande correspondante) :
		 - **priority_public** (dalo inclut)
		 - **single_parent** (monoparentale)
		 - **mutation**
		 - **entities** (objet de forme) :
			 - **id_paw1** : quantité
			 - **id_paw2** : quantité
			 -  ...
- Nombre de candidats positionnés sur l’offre => **applicated_nb**
- Nombre de photos => **pictures_nb**

## Flux 10 gestion des photos

[https://als-hermes-scoring-rec.be-idys.com/api/swagger/index.html#operations-API_DMO_HOUSING_OFFERS-post_api_dmo_housing_offers__housing_offer_id__pictures](https://als-hermes-scoring-rec.be-idys.com/api/swagger/index.html#operations-API_DMO_HOUSING_OFFERS-post_api_dmo_housing_offers__housing_offer_id__pictures)

Les photos sont systématiquement ratachées à une housing_offer.

Le nombre maximal de photos par housing offer est de 5. Au-dela la création est bloquée.
Dans ce cas, il faut alors soit :
- Éditer une photo
- En supprimer une, puis rajouter celle souhaitée

Formatage du json pour une picture :

    {
	    "id" :"5dc5975b88cb110b0543a829",
	    "type" : "pictures",
	    "attributes" : {
		    "responsible" : {
			    "id" : "5dc5975a88cb110b0543a822",
			    "first_name" : "Martin",
			    "last_name" : "Durand"
		    },
		    "readers" : [],
		    "writers" : [],
		    "read_level" : "write",
		    "created_at" : "2019-11-08T17:27:07.560+01:00",
		    "updated_at" : "2019-11-08T17:27:08.538+01:00",
		    "thumb240" : “urlDeLaMiniature240pixel.png”,
		    "thumb1000" : “urlDeLImageEn1000pixelDeLarge.png”,
		    "full_size" : “urlDeLImageEnTailleOriginale.png”,
		    "housing_offer_id" : "5dc5975b88cb110b0543a828"
	    }
    }

#### Création

    POST /api/dmo/housing_offers/{housing_offer_id}/pictures  

avec un file dans les formDatas  
  
renvoie les infos sur la picture créée

####  Recuperation des images liées à une offre

uri :

    GET /api/dmo/housing_offers/{housing_offer_id}

Renvoie 3 champs concernant les pictures

    {
        "ordered_picture_ids": ["id1","id2"] ,
        /*(éditable) liste ordonnée des ids de pictures liées a l’offre
        * (max 5) la première de l’array est la picture principale*/
	    

        "main_picture": {…} 	,
        /*objet contenant les infos de l’image principale
        * première picture de l'array "ordered_pictures"
        * (non éditable directement)*/

	    "pictures": [ 
		    {…},
		    {…}
	    ]
        /*liste d’objets du type picture
        * (non editable directement)*/
    }

### Edition

    PUT ou PATCH     /api/dmo/housing_offers/{housing_offer_id}/pictures/{picture_id}  

avec un champ "file" contenant le fichier image dans dans les formDatas

### Suppression

    DELETE     /api/dmo/housing_offers/{housing_offer_id}/pictures/{picture_id}   

### Changement d’ordre dans les pictures

pour changer l’ordre des photos, il faut éditer le champ « ordered_picture_ids » de l’housing offer, la premiere de l’array en deviendra la picture princiaple (main_picture).

    PUT ou PATCH sur /api/dmo/housing_offers/{housing_offer_id}

  avec en params : 

    "data":{
	    "attributes":{
		    "ordered_picture_ids":[
			    “picture3.id”,
			    “picture1.id”,
			    “picture2.id”
		    ]
	    }
    }

### changement de la main picture

pour changer la main picture il faut réordonner les pictures afin que la picture souhaitée se retrouve au début du tableau « ordered_picture_ids »

## Flux 11 Rendre l'offre au bailleur (entrant)

Modifier la valeur du "offer_status" dans la "housing_offer": 

    PATCH/PUT sur /api/dmo/housing_offers/{housing_offers_id}
    
avec en params du body: 
    
        "data":{
    	    "attributes":{
    		   "offer_status": "RETIRE PAR LE BAILLEUR" 
    	    }
        }

## Flux 12 Reprise offre par le bailleur (sortant sopra)
Transmission au back sopra via un appel de WS du status d'une offre donnée (housing_offer) lorsque celle ci à son status qui passe à reprise par le bailleur ('RBA')



## Flux 13 Confirmer la reprise de l'offre par le bailleur

https://code.plugandwork.net/plugandwork.app/hermes/commit/cbe458dd5376cd92d934fbb07319c9225e011f9a
c'est une édition d'une entité offre, elle s'appele sur la route : 

    PATCH/PUT sur /api/dmo/housing_offers/{housing_offer_id}
    
avec en params du body: 
    
        "data":{
    	    "attributes":{
    		   "lessor_status" : "RETIRE" ,
    		    "offer_status" : "RETIRE PAR LE BAILLEUR"
    	    }
        }


## Flux 14 Gérer l'orientation d'une offre

L'orientation d'une offre est composée par les champs suivants :

  - **priority_public**: Boléen statuant sur l'accessibilité à l'offre par les publiques prioritaires uniquement
  - **mutation**: Boléen statuant sur l'accessibilité à l'offre par les demandes en situation de mutation uniquement
  - **single_parent**: Boléen statuant sur l'accessibilité à l'offre par les familles monoparentales uniquement
  - **reserved**: Boléen statuant sur l'accessibilité à l'offre par les demandeurs des entreprises liées à l'offre
  - **entity_ids**: Liste des ids des entreprises liées à l'offre

Pour modifier l'orientation d'une offre il s'agit donc de mettre à jour les champs indiqués plus haut au niveau de l'offre souhaitée.

## Flux 15 Gérer la publication d'un offre

L'offre doit passer au statut : "LOGEMENT PUBLIE".
Pour ce faire :

    PATCH /api/dmo/housing_offers/{id}

body :

    {
      "data":{
        "attributes":{
          "details": "string", // description du bien
          "dpe_ges": "string", // étiquette GES
          "dpe_conso": "string" // étiquet DPE
        }
      }
    }

## Flux 16 Commercialiser l'offre sans publication

c'est une édition d'une entité offre, elle s'appele sur la route : 

    PATCH/PUT sur /api/dmo/housing_offers/{housing_offer_id}
    
avec en params du body: 
    
        {
          "data":{
            "attributes":{
                    "offer_status": "COMMERCIALISE SANS PUBLICATION",
                    "lessor_status": "PUBLIE",
                    "publication_end_date": Date
            }
          }
        }


## Flux 17 Commercialiser une offre avec publication


c'est une édition d'une entité offre, elle s'appele sur la route : 

    PATCH/PUT sur /api/dmo/housing_offers/{housing_offer_id}
    
avec en params du body: 
    
        "data":{
    	    "attributes":{
    	            "offer_status": "LOGEMENT PUBLIE",
                    "lessor_status": "PUBLIE",
                    "publication_end_date": Date
    	    }
        }

- les offres avec le champ is_public à true sont des offres qui resortirons pour les candidats quelque soit les critères d'eligibilité
- les offres avec le status offer_status=='LOGEMENT PUBLIE' seront visible en mode visiteur

## Flux 18 Dépublier une offre


c'est une édition d'une entité offre, elle s'appele sur la route : 

    PATCH/PUT sur /api/dmo/housing_offers/{housing_offer_id}
    
avec en params du body: 
    
        "data":{
    	    "attributes":{
    		   offer_status : "EN COURS DE DESIGNATION" 
    		    lessor_status : "EN DESIGNATION"
    	    }
        }

## Flux 19 Suite à l'action 'Transmettre au bailleur", envoi des candidats choisis pour une offre donnée

### Transmission au front als des demandes retenues

    POST sur /api/dmo/housing_offers/{housing_offer_id}/selected_applications

  avec en params du body: 

    "data":{
	    "attributes":{
		   "als_request_ids":[
			    “als_request_id1”, //id de demande tels que présent dans le back
			    “als_request_id2”,
			    “als_request_id3”,
			    ...
		    ]
	    }
    }
    
   Entraine une modification du statut de la candidature à "TRANSMIS BAILLEUR" et renvoie la liste des candidatures ainsi éditées avec en embed les demandes associées

### recupération des candidatures enregistrées sur le front avec un status à TRANSMIS BAILLEUR pour une offre donnée
pour une offre donnée, récupération des candidature dont le statut est à « TRANSMIS BAILLEUR » avec pour chacune la housing_request associée en embed dans le json

    GET api/dmo/housing_offers/${id}/selected_applications

Avec pour ${id} l’id de l’offre choisie.  
  
il est possible d’ajouter des options de recherche et une pagination à cette requete comme pour les autres requêtes ; documentation accesible sur notre [swagger](https://als-hermes-scoring-rec.be-idys.com/api/swagger).

## Flux 20 Annuler la commercialisation d’une offre 


c'est une édition d'une entité offre, elle s'appele sur la route : 

    PATCH/PUT sur /api/dmo/housing_offers/{housing_offer_id}
    
avec en params du body: 
    
        "data":{
    	    "attributes":{
    		   "offer_status" : "EN ATTENTE COMMERCIALISATION",
    		   "lessor_status" : "EN ATTENTE PUBLICATION"
    	    }
        }

## Flux 21 Envoi d'une candidature au back sopra (sortant sopra)
Ce flux se déclenche lors de la création d'une candidature pour une offre ( au create d'une
housing_application ). Il envoie une requête  vers Sopra indiquant l'offre concerné et la demande concernée ainsi que la date de positionnement.
      
      
## Flux 30 Envoi d'une demande (sortant sopra)
ce flux se déclanche a la création ou a l'update d'une housing_request et permet de renseigner le back sopra sur les modifications d'une demande de logement.

## Flux 32 Envoit d'un NUD au FRONT

Pour créer un Nud :

uri:

    POST /api/dmo/nuds

body :

    {
      "data": {
        "attributes": {
          "housing_request_id": ,// String, id PAW de la demande concernée (utilisez aussi l'als_id si vous preferez)
          "als_id":             ,// String, als_id de la demande concernée (connue sous le nom de ref_interne chez sopre
          "department":         ,// String, code du département rattaché au nud
          "creation_date":      ,// DateTime, date de création rattaché au nud
          "unique_number":      ,// String, numéro unique du nud
          "is_active":           // Boolean, true si toujours d'actualité, false pour désactiver la validité
        }
      }
    }

Cette méthode API gère aussi les doublons :
Si la paire **"unique_number"** <==> **"housing_request_id"**, est déjà réferencée, alors l'objet portant cette correspondance sera récupéré et mit à jour.

Vous pouvez vous référer au [swagger](https://als-hermes-scoring-rec.be-idys.com/api/swagger/index.html) pour connaitre le reste de ses fonctionnalités classiques.

## Flux 36 Validation d'une demande par une entreprise (sortant sopra)
ce flux se déclenche quand entity_validated est modifié

## Flux 37 Dès détection d'une modification de l'orientation sur une demande suite au traitement automatique de détermination

	GET api/dmo/housing_requests/clp_details?als_ids[]=${id1}&als_ids[]=${id2}…

Le paramètre **_« als_ids »_** est ici obligatoire. C’est l’équivalent du paramètre **_« ids »_** mais pour la correspondance avec le champ « als_id » porté par une demande.

Ce paramètre n’existe que pour cette action !!! Autrement il faut utiliser **« als_id[$in] »** pour reproduire son effet.

Mapping des champs :

 - Nombre de candidatures => **applicantions_nb** Date dernière
  - candidature => **last_application_date** Nombres d’offres éligibles
  - détaillé => **eligible_offers_nb_detailed** Objet qui contient les
  - clefs : Nombre non commercialisées => **non_commercialized** Nombre
	  - commercialisées et non publiées => **commercialized_non_pubicated**
		 -  Nombre commercialisées et publiées => **commercialized_publicated**

## Flux 38 Gérer l'orientation d'une demande

### rappel généraux
Dans notre solution une demande est un objet composite formé :

  - d'un demandeur principal **Applicant**
  - d'une demande de logement **HousingRequest**
  - d'aucun à plusieurs co-titulaire **Applciant**

Les informations présentes sur chacun de ces objet produit l'orientation d'une demande.

Champs concernés pour :

  - Le demandeur principal et les co-titulaire :
    - **entity_id**: entreprise du demandeur principal ou du co-titulaire
  
  - La demande de logement :
    - **entity_validated**: validation entreprise (pour l'instant ne prend en compte que la validation de l'entreprise du demandeur principal)
    - **single_parent** (automatique): Boléen calculé en fonction de la composition familiale de la demande et statuant sur l'état "monoparental" ou non du foyer de la demande
    - **mutation**: Boléen statuant sur l'état "mutation" de la demande
    - **priority_public**: Boléean statuant sur l'état "publique prioritaire" de la demande

Pour modifier l'orientation d'une demande il s'agit donc de mettre à jour les champs indiqués plus haut au niveau de la demande souhaitée, excepté pour **single_parent** qui est produit par plusieurs composantes :

  - situation familiale du demandeur principale
  - si le foyer inclut ou non des enfants à charge

### application au flux 38 

    PATCH/PUT sur /api/dmo/housing_requests/{housing_request_id}
    
avec en params du body: 
    
        "data":{
    	    "attributes":{
    		   "priority_public" : Boolean
    	    }


## Flux 40 Notification du changement de statut d'une candidature (entrant)

Modifier la valeur du "status" dans la "housing_application": 

    PATCH/PUT sur /api/dmo/housing_applications/{housing_application_id}
    
avec en params du body: 
    
        "data":{
    	    "attributes":{
    		   "status": "A L'ETUDE ALS" 
    	    }
        }

## Flux 50 à 56 Communiquation d'evenements candidature (sortant sopra)

Ces flux se déclenche lors de la modification du status d'une candidature ( champ "status" d'une
housing_application ). Il envoie une requête indiquant l'évènnement vers Sopra avec un code évènement tel que décrit ci dessous
      
      
### Status des candidatures
Cette liste est peut être amené à évoluer car certaines corrrespondances avec les précédents status n'est pas encore bien établie.

A présent il est indispensable de séparer les status de commissions des status de visite, il existe donc deux champs sur le modèle HousingApplication qui sont status et visit_status

Actuellement la correspondance avec le code évenement fonctionne avec les anciens et les nouveaux status. 

Si un anciens status est utilisé alors il sera convertit suivant ce tableau.

Le code evenement sera renvoyé avec les anciens et nouveaux status (si correspondance)

|status|visit_status|Ancienne correspondance|code evenement renvoyé|
|---|---|---|---|
|EN ATTENTE||Waiting||
|PLO||PLO||
|TRANSMIS BAILLEUR||Inscription CAL|INSCAL|
|ACCEPTEE EN CAL||Attribution lot avec rang|DESCAL|
|REFUSEE EN CAL||Refus attribution|DESCAL03|
|NON RETENUE||Refus lot demandeur|REFLOG|
|NON RETENUE EN CAL||Radiation attribution|RADATT|
|DESISTEMENT SALARIE AVANT CAL||||
|ANNULEE BAILLEUR||||
|DESISTEMENT||||
|ANNULEE||||
|A L’ETUDE ALS||||
|DESISTEMENT APRES CAL||||
|**ACCEPTEE EN CAL**|VISITE PROPOSEE|Visite proposée|VISPRO|
|**ACCEPTEE EN CAL**|VISITE EFFECTUEE|Visite effectuée|VISEFF|
||DESISTEMENT APRES VISITE|||
||ACCORD APRES VISITE|||
|**ACCEPTEE EN CAL**||Attribution lot|DESCAL01|
|**ACCEPTEE EN CAL**||Attribution sous condition|DESCAL02|

## Affichage des offres de logements publiques

Le front-end peut lancer des requêtes afin de récupérer l'ensemble des offres de logements publiques (housing_offer avec le champ "is_public" à true)

Il n'est pas nécessaire d'être identifié pour y avoir accès (pas besoin de token).

    GET /api/dmo/public_housing_offers

Les paramètres de tri et de pagination possibles sont décris dans le swagger : 

[https://als-hermes-scoring-rec.be-idys.com/api/swagger/index.html#operations-tag-API_DMO_PUBLIC_HOUSING_OFFERS](https://als-hermes-scoring-rec.be-idys.com/api/swagger/index.html#operations-tag-API_DMO_PUBLIC_HOUSING_OFFERS)

Une expliquation plus détaillée de l'utilisation des query params pour préciser la recherche se trouve au premier chapitre de cette documentation.

Il est aussi possible de réaliser une requête pour récupérer le détail d'une seule housing_offer dont le champ is_public est à true sans être identifié (pas besoin de token) :

    GET /api/dmo/public_housing_offers/{id}
    

## Envoi d'email

Pour demander à l'api  d'envoyer un email, on doit réaliser la requete 

    POST /api/d2/docs
    
avec dans le body json de la requête : 
 
    {
        "to": "String",
        "cc": "String",
        "bcc": "String",
        "from": "String"
        "data":{
            "attributes":{
                "type": "email",  //doit etre égal à "email" pour que l'envoi soit réalisé
                "title": "String", //objet du mail
                "body": "String"   //contenu du mail
            }
        }
    }
    
    
## Gestion Documents 

A la création d'une Demande (housing_request), ainsi qu'aux updates, un objet housing_request_folder representant le dossier demande est créé ou mis a jour.
Des objets de type "required_document" sont générés après un calcul sur les pieces a fournir pour un dossier donné.
le calcul est automatisé par notre API, et il n'y a plus qu'a afficher la liste des pieces a fournir.
Si les pieces existent déja pour un applicant donné, alors elles sont récupérés directement.
Si la demande évolue et entraine une modification des pieces à fournir, alors les required_documents sont mis a jours automatiquement

### Récupération de la liste des pieces à fournir pour une demande

    GET api/dmo/housing_requests/${id}/housing_request_folder
    
cette requete renvoie un JSON ressemlant à ceci :

    {
        "data" : {
                    "id" : "5de12f9b88cb11400c9dcdfe",
                  "type" : "housing_request_folders",
            "attributes" : {
                        "created_at" : "2019-11-29T15:47:55.045+01:00",
                        "updated_at" : "2019-11-29T15:47:55.045+01:00",
                            "nud_status" : "Dossier validé", //status du dossier de demande pour obtention d'un nud
                            "consultation_status" : "Dossier validé", //status du dossier de demande pour consulter les offre
                            "application_status" : "Dossier incomplet", //status du dossier de demande pour candidater aux offre
                        "completion" : 0, //pourcentage de completion du dossier
                    "validity_limit" : "2021-11-29T15:47:55.045+01:00",
                    "is_still_valid" : true,
     "file_upload_from_sne_complete" : true, //booléen, true si la recherche des pieces justificatives dans le sne à été executée
                "housing_request_id" : "5de12f9a88cb11400c9dcdf9",
                "required_documents" : [{
                                                "id" : "5de12f9b88cb11400c9dcdfa",
                                        "created_at" : "2019-11-29T15:47:55.048+01:00",
                                        "updated_at" : "2019-11-29T15:47:55.048+01:00",
                                              "type" : "Carte d'identité ou passeport du pays d'origine",  //type de la piece a fournir
                                    "validity_limit" : "2021-11-29T15:47:55.045+01:00", //limite de validité si la piece n'est valable qu'un certain temps
                                    "is_still_valid" : true,
                                            "status" : "pièce non fournie", //status de la piece à fournir
                                 "validation_errors" : nil, //tableaucontenant la liste des erreurs de validations constatées sur une piece
                                         "tagset_id" : nil, //reference de l'espace de travail contenant la piece
                                    "tagsetLocation" : nil, //url du serveur hebergeant les documents et les especes de travail
                                             "files" : [{
                                                            "filename" : "piece_identité_recto.jpg",
                                                            "url" : "https://www.serveur_document.com/send/f7bc02187c5ea3fcaff6e248526e1c94/piece_identité_recto.jpg"
                                                        }, 
                                                        {
                                                            "filename" : "piece_identité_verso.jpg",
                                                            "url" : "https://www.serveur_document.com/send/f7bc02187c5ea3fcaff6e248526e1c94/piece_identité_verso.jpg"
                                                        }],
                                          "category" : "SPI",  //code de catégorie du document
                      "is_required_for_nud" : false,  //true si requis pour obtenir un nud
                      "is_required_for_consultation" : false,  //true si requis pour consulter les offres
                       "is_required_for_application" : true,   //true si requis pour postuler aux offres
                             "is_for_main_applicant" : false,  //true si le document est requis pour le main applicant
                               "dependent_infos" : {           //n'est renseigné que si la piece doit etre au nom du dépendent
                                              "last_name" : "GOUBILLze",
                                             "first_name" : "CHRIS",
                                             "birth_date" : "2017-03-23T00:00:00.000Z",
                                               "rel_type" : "P",
                                                    "sex" : "M"
                                         },
                                          //le document justificatif doit concerner cet applicant (demandeur)
                                         "applicant" : {             
                                                       "id" : "5de12f9a88cb11400c9dcdf7",
                                               "created_at" : "2019-11-29T15:47:54.930+01:00",
                                               "updated_at" : "2019-11-29T15:47:55.071+01:00",
                                                      "nud" : nil,
                                             "temporary_id" : nil,
                                "sne_profile_creation_date" : nil,
                                                    "ss_id" : nil,
                                               "first_name" : "Océane",
                                                "last_name" : "Vincent",
                                                "full_name" : "Océane Vincent",
                                                ...
                                                        }            
                                        },
                                        {...},
                                        {...}
                                    ]
                                      
            }
        }
    }
#### Statuts des dossiers de demande

pour la conception de l'UX il sera important de prendre en considération les deux status des housing_request_folders
consultation_status et application_status

nud_status, consultation_status et application_status pourront prendre les valeurs suivantes : 
    
   - "Dossier incomplet"
   - "Erreurs de validation dans les pieces fournies"
   - "Dossier complet prêt pour traitement"
   - "Dossier complet en cours de traitement"
   - "Dossier validé"
   - "Date de validité dépassée"

#### Statuts des pièces à fournir

à ce jour les required_documents.status pourront prendre les valeurs suivantes : 
    
   - "Pièce manquante"
   - "Prêt pour traitement"
   - "Controle en cours"
   - "Pièce invalide"
   - "Pièce validée"
   - "Date de validité dépassée"
   

#### personne concernée par la piece a fournir

il faut pour cela aller regarder dans la partie "applicant" du json pour pouvoir recuperer cette information
   
### Upload des document pour renseigner une piece à fournir

    POST api/dmo/required_documents/${id}/send_files
    
cette requete peut etre executée pour mettre à jour une piece a fournir comme pour l'ajout initial. 
Le ou les fichiers nécessaires doivent etre envoyés en un seul et meme envoi sus la forme d'un formData contenant un ou plusieurs fichiers

### Lancer un traitement de vérification du dossier

pour lancer la kycisation du dossier (l'idéal est de lancer cela lorsque l'un des trois status est à "Dossier complet prêt pour traitement")

    POST api/dmo/housing_requests/${id}/housing_request_folder/start_treatment

## Securisation de la récupération des documents sur le SNE

### Demande d'envoi d'une clef d'authentification par mail :

    POST api/dmo/nuds/${numero_unique_departemental}/send_pin_code_on_mail
    
Lorsque une requete est envoyée sur ce point d'entré, une recherche d'existence du NUD est faite. si elle permet de remonter à un NUD existant, alors on evoie sur le mail qui lui est asscié un code à 6 caractères.

actuellement, les nuds possibles sont :

    "0110418041931AL004","0110818044073AL004","0111018045296AL004","0540118094804AL004","0540218097596AL004","0540418098300AL004","0540918102877AL004","0600118113776AL004","0600118113887AL004","0600118114000AL004","0600118114365AL004","0600118114637AL004","1110318909578GDPUB","1110318909811AL004","111061768845292B12","111061768907694R01","111061769227595B02","111061769265475B02","111061770131093R01","111061770662994R01","111061770794293R01","111061771720793R01","111061771892494B05","111061772445575B02","111061773032393R01","111061773215694B02","111061897550093B05","111061897721592B12","111061897830994B02","111061898139492B02","111061898515575B06","111061898524492B05","111061899100193B05","111061899409193R01","111071233846193R01","111071234661777B02","111071358640193R01","111071359815692B02","111071359987194B02","111071360074992B06","111071462564194R01","111071483958293R01","111071485003693R01","111071485174794B02","111071487825293R01","111071509835192B05","111071511027193R01","111071511147375B02","111071511361794B02","111071511978375B02","111071512177392B06","111071641583193R01","111071642051793B10","111071642294393R01","111071642736093R01","111071642742894R01","111071642814493R01","111071642908692B05","111071643418992B05","111071643421793R01","111071643510092B02","111071645561375B02","111071771895294R01","111071772133193B10","111071772221294B02","111071772618093R01","111071772683492B02","111071772849494R01","111071772955292B06","111071773102394R01","111071773654892B02","111071774970893B10","111071801203092B02","111071801612275B02","111071801896277B04","111081237605875B02","111081359894092B12","111081360005092B09","111081360145592B02","111081361238292B12","111081361347093R01","111081485041375B02","111081485667475B01","111081486061975B02","111081487091193R01","111081492172975B02","111081511552675B02","111081512121875B02","111081512280793B05","111081512482992B12","111081513124692B05","111081513162475B02","111081513509092B02","111081513515292B02","111081514550694B02","111081643853094B02","111081644140575B02","111081644385494R01","111081645460275B06","111081773521993R01","111081773543294R01","111081773611991R01","111081773660193R01","111081773788094R01","111081773953892B02","111081774111894R01","111081774175993R01","111081774338994R01","111081774640093R01","111081774738875B02","111081774798694B02","111081775049675B02","111081775116292B12","111081776027894B05","111081802103794R01","111081802414975B02","111081803388775B01","111091237545394B04","111091362307278B01","111091364253393R01","111091364472392B05","111091486981293B10","111091487479993R01","111091487525993B03","111091487562992B02","111091487845292B02","111091488374992B02","111091488590094B01","111091489927493R01","111091514303593B05","111091514514393B05","111091515462175B02","111091515496893B05","111091515704193B05","111091515919893B05","111091516379692B02","111091516553275B02","111091516554292B12","111091517980592B06","111091521933893B10","111091645662193R01","111091646368192B06","111091647316192B06","111091647870792B05","111091647936893R01","111091648534675B02","111091652004194B02","111091654404994B02","111091775666794R01","111091775850793R01","111091775918492B02","111091775938093R01","111091776079092B05","111091776312992B06","111091776472577B04","111091776499493R01","111091776500793R01","111091776939091R01","111091777964375B02","111091778388694B05","111091778474778B04","111091781952478B04","111091804470593R02","111091804786793B10","111091804790393R01","111091805554592B05","111101115934194B02","111101239608493R01","111101240650277B04","111101240847692B02","111101241605192B09","111101363548794B05","111101364563093B05","111101364795092B02","111101364812892B05","111101364907593R01","111101365572392B05","111101367600193B10","111101489281375B02","111101489397292B05","111101489448175B02","111101490012375B02","111101490075892B02","111101490521294B02","111101490633275B02","111101490838593R01","111101491073475B02","111101491385292B02","111101491421793B10","111101491509093B10","111101492613193R01","111101516169594B02","111101516202793B10","111101516210392B02","111101516212175B02","111101516264175B01","111101516293993R01","111101516770392B05","111101517498393R01","111101517977792B02","111101518044793R01","111101518199393R01","111101518323393B10","111101518343193R01","111101518437693B05","111101518830192B06","111101519719177B04","111101522142775B02","111101648833793R01","111101648837492B05","111101649146393R01","111101649192894R01","111101649280194B02","111101649825993R01","111101650446992B02","111101651045477B04","111101651732875B02","111101652434694B02","111101654639493B10","111101655691294B02","111101657788975B02","111101778190375B02","111101778353893R01","111101778739775B01","111101778795793R01","111101779336993R01","111101779369275B06","111101779425478E02","111101779523692B02","111101779588375B06","111101780165092B02","111101780641892B02","111101781178094B05","111101781741293B10","111101782085094B02","111101782439391R01","111101782555192B12","111101785510194B02","111101807082177B02","111101807471775B07","111101808342994R01","111110346963793B05","111110500789778B04","111111116161892B02","111111119350392B02","111111241540893R01","111111242875793R01","111111244892693B05","111111365964978E01","111111365997792B01","111111366974393B10","111111367535392B01","111111367571894B02","111111368453293R01","111111491088175B06","111111492278975B02","111111497984075B02","111111498111194B02","111111518487793R01","111111519135093B01","111111520247893B10","111111520733875B02","111111520825392B12","111111521278475B02","111111523263593B10","111111524148494B02","111111526045792B12","111111650959675B02","111111651166893R01","111111651185494B02","111111651933994R01","111111652222993R01","111111652287894R01","111111652311793R01","111111652679193R01","111111653615994B02","111111654753893B10","111111654776094B02","111111655138193B10","111111780900694B02","111111780971075B02","111111781168294B02","111111782152194R01","111111782380678B04","111111782982292B02","111111783083092B02","111111783557692B01","111111784047993B10","111121032288592B09","111121119044793R01","111121119959593R01","111121244495375B02","111121244771275B02","111121245098593R01","111121367898475B02","111121368536392B02","111121369234592B02","111121369959077B04","111121373591493B10","111121493774693B10","111121494344393B10","111121494797393R01","111121494853792B06","111121495628393R01","111121521391892B05","111121523089593R01","111121523227093R01","111121523313693B10","111121523487494B02","111121653723294R01","111121654135293R01","111121654287893R01","111121654429494R01","111121654590393R01","111121654613494B02","111121654615992B12","111121654659493R01","111121654672293R01","111121654857293R01","111121654882991R01","111121654949094R01","111121655014192B12","111121655054392B02","111121655801292B05","111121656219975B02","111121657009193B10","111121657273293B10","111121657626993B10","111121657744293B10","111121663142092B05","111121783168577B02","111121783548094B02","111121783554793R01","111121783790593R01","111121783932975B02","111121784098793R01","111121784120092B02","092110427644292044","092110534926510037","092110535028092044","093020896111193008","093020914398693066","093021139917893050","093021140219393063","093030208411993048","094050672037910033","094050778651310001","094051095077894058
  
Output :
-	200 – OK
-	400 – NUD non trouvé / incorrect
- 422 - voir le message d'erreur :

    - unique_number_not_covered_by_sne => le numéro unique n'est pas couvert dans la liste des départements
    - recuperation_of_housing_request_from_sne_already_done => le numéro unique a déja été utilisé pour créer une housing_request

note : provisoirement, l'email est 
- envoyé depuis l'adresse : securite@masolutionlogement.fr
- expédié sur l'adresse : recette.hermes@actionlogement.fr et comptetestals@gmail.com

### Envoi par l'utilisateur du code pin reçu sur son mail

    POST api/dmo/nuds/${numero_unique_departemental}/authentify_with_pin_code
    
    //avec en body de la requête : 
    {
      "pin_code": "A9i74M"
    }
    
Requete à envoyer lorsque l'utilisateur saisis le code qu'il vient de recevoir sur sa boite mail.
    
-	400 – aucune association trouvée ou association expirée
-	200 – OK, la réponse doit renvoyer une demande initialisée avec les infos issues du SNE si existantes sinon vide,
elle renvoie donc un objet du type "housing_request" dont le format est décrit plus haut dans cette documentation
- 422 - voir le message d'erreur :

    - unique_number_not_covered_by_sne => le numéro unique n'est pas couvert dans la liste des départements
    - recuperation_of_housing_request_from_sne_already_done => le numéro unique a déja été utilisé pour créer une housing_request
    - unable_to_send_mail_with_pin_code => un probleme est survenu lors de l'envoi
    
## gestion des codemandeurs

### Ajout d'un codemandeur

    PATCH api/dmo/housing_requests/{id}
    //avec en body de la requête : 
    {"data":
        {"attributes":
            {"coapplicants":[
                //laisser les autres codemandeurs si il y en a
                {
                    "rel_type":"P", //type de relation avec le demandeur principal
                    "id": applicant.id //id d'un objet applicant qu'on souhaite ajouter
                }
            ]}
        }
    }
    
### Supression d'un codemandeur

pour le retirer de la demande de logement :

    PATCH api/dmo/housing_requests/{id}
avec en body de la requête : 

    {"data":
        {"attributes":
            {"coapplicants":[
                //laisser les autres codemandeurs si il y en a
            ]}
        }
    }
 ou
 
    {"data":
        {"attributes":
            {"applicant_ids":[
                //laisser les autres applicant_ids si il y en a
            ]}
        }
    }
    
le fait de supprimer l'objet applicant entraine aussi la supression dans la liste des codemandeurs des demandes ou il est inscrit, mais cela peut avoir des conséquences facheuse si cet applicant est inscrit sur d'autres demandes.

    DELETE /api/dmo/applicants/{id}


## ajout d'un objectif bailleur

    POST /api/dmo/lessor_objectives
avec en attribut de la requete :

    {
        "data": {
            "attributes": {
                  "lessor_id": "string", //id du bailleur auquel est rataché l'objectif
                  "activation_date": "Date", //date d'activation
                  "district": "string", //ville sur laquelle s'applique l'objectif 
                                        // (attention, la facon dont est rempli ce champs doit correspondre directement au champs housing_offer.district 
                                        // pour que l'assignation se fasse - sensible a la casse )
                  "department": "string", //département sur lequel s'applique l'objectif 
                                          //(à renseigner si la ville est renseigné, 
                                          // attention, la facon dont est rempli ce champs doit correspondre directement au champs housing_offer.departement 
                                          // pour que l'assignation se fasse - sensible a la casse )
                  "threshold_type": "string", //norme
                  "priority_public": true, //public prioritaire
                  "new_offer": true, //Mise à l’habitation
                  "target_by_typologies": {  
                                            "T2": 30 //renseigner ici l'objectif attendu pour un type de logement donné
                                                     // valeurs possibles : "T1" ,"T2", "T3" etc...  utilisez "all" si l'objectif est pour tout les types de logements
                                            }
                   "agency_id": "string" //Entity_id de la filiale concernée
            }
      }
    }

format json de l'objet retourné :

                     {
                                 ...    
                            "department" : "String",
                              "district" : "String",
                        "threshold_type" : "String",
                       "priority_public" : "String",
                             "new_offer" : "String",
                    "present_typologies" : ["T1"],   //liste des Typologies présentes sur l'objectif
                             "lessor_id" : "String", //ID bailleur
                             "agency_id" : "String", //entity ID
                           "agency_name" : "String", //title de l'entity fournie 
                        "operation_name" : "String",  
                  "target_by_typologies" : {T1: 200}, //objectif initial
                "realized_by_typologies" : {T1:50}, //réalisé
    "objective_difference_by_typologies" : {T1:150} //reste à faire
         "targeted_offers_count" : 200 //nombre d'offre ayant la capacité de valider l'objectif si elles sont "LOUE"
         "lessor_objective_history_ids" : ["6DYZFHDUUS", ".....] id des objet lessor_objective_history concernés
                    }   
 
### detail des evenements d'objectif bailleurs

recuperer toute l'historique d'un objectif donné :

    GET /api/dmo/lessor_objective_histories?lessor_objective_id={:id}

recuperer un evenement particulier à partir de son id :

    GET /api/dmo/lessor_objective_histories/{:id}

rechercher toutes les offres qui ont validé un objectif donné

    GET /api/dmo/housing_offers?target_objective_ids={objective_id}&lessor_status="LOUE"

rechercher toutes les offres qui pouraient valider un objectif donné si elles passaient à LOUE 

    GET /api/dmo/housing_offers?target_objective_ids={objective_id}&lessor_status[$ne]="LOUE"

## récuperer toutes les opération_name des offres d'un bailleur

    GET /api/dmo/lessor/{:id}/current_operation_names
    
retour json

    [
        "Nom d'opération 1",
        "Nom d'opération 2",
        ...
    ]

## lier ou dé-lier un utilisateur à un bailleur
Permet de pouvoir identifier le Lessor d'un utilisateur courant (dans les cas ou le bailleur veut lier plusieurs utilisateurs à son compte bailleur, donc en plus du champ `:user_id` du modèle `Hermes::Lessor`)

    Put /api/dmo/lessor/{:id}/add_user
    Put /api/dmo/lessor/{:id}/remove_user

avec en attribut de requete :

    {
        "data": {
            "attributes": {
                "user_id": "string" // id de l'utilisateur à lier au compte bailleur
            }
        }
    }
    
retour json

    "user updated"

## Filtrer les demandes enregistrées par numéro siret

### Pour les entreprises

Utilisez le paramètre de recherche « main_employer_siret » contenant la liste des sirets (des employeurs des candidats) que l'on souhaite filtrer  :

    GET api/dmo/housing_requests?main_employer_siret[]=${siret1}&main_employer_siret[]=${siret2} 

### Pour les bailleurs

Utilisez le paramètre de recherche « siret » contenant la liste des sirets (des bailleurs) que l'on souhaite filtrer  :

    GET api/dmo/lessors?siret[$in][]=${siret1}&siret[$in][]=${siret2} 

## housing_request renseigner le champs seeked_localisation_list

    seeked_localisation_list' : [
        '{
            "nom": String,
            'code': String, //requis code insee de la commune (doit correspondre au code insée
            'codesPostaux' : [String], //requis liste des codes postaux de la commune (si elle a plusieurs code postaux
            "codeDepartement": "83", //requis
            'departement': String,
            ...  //l'api sauvegarde tout les couples clef valeurs voulus pour l'affichage front, le champs est libre.
        },
        {...},
        ...
    ]
    
## housing_request renseigner les dependants

    housing_request.dependents' : [
        '{
            'monthly_incomes': {pokemon_selling: 5, 'autre activité' : 33.45}, //nous ne nous occupons que de faire la somme des valeurs, le nom des clefs n'a pas d'importance coté back
            'monthly_charges': {unicorn_food: 10}, //nous ne nous occupons que de faire la somme des valeurs, le nom des clefs n'a pas d'importance coté back
            "last_name":"GALLET", 
            "first_name":"ANTONY", 
            "birth_date":"2017-03-23T00:00:00.000Z", 
            "rel_type":"E", 
            "sex":"M",
            "coparentality":"G", // G,D, ou null
            ...  //l'api sauvegarde tout les couples clef valeurs voulus pour l'affichage front, le champs est libre.
        },
        {...},
        ...
    ]
#### unborn_children
    
      housing_request.unborn_children : [
        {
          nb_child_birth: 1
          anticipated_birth : « DATE »,
        },
        ...
      ]

    
## récuperer la liste des départements valide pour le SNE

    GET /api/dmo/nuds/sne_department_list
    
retour :

    ["01", "02","04","05", ... ,  "971","972","973" ]

## Bailleur

### housing_offer

Création d'une nouvelle offre

    POST /api/dmo/housing_offers

Mise à jour d'une offre

    PUT /api/dmo/housing_offers/{housing_offer_id}

Champs interdits pour le role `'Bailleur'`

    :als_siren
    :dalo
    :status
    :status_updated_at

### housing_request

Retrouver toute les housing_requests relative au current_user (si celui-ci à le role `'Bailleur'`)

    GET /api/dmo/housing_requests?available=true
## Modèles geolocalisables
|field|type|info|
|---|---|---|
|`:address`|`string`||
|`:postal_code`|`string`||
|`:district`|`string`||
|`:country`|`string`||
|`:latitude`|`float`||
|`:longitude`|`float`||

Pour utiliser le géocodage dans un modèle, il faut inclure le concern `include ::Concerns::Geolocalizable`

Les modèles concernés sont `Hermes::Entity`, `Hermes::Applicant` et `Hermes::HousingOffer`, ils utilisent la [gem geocoder](https://github.com/alexreisner/geocoder)
et peuvent donc utiliser toute les méthodes de recherche qu'elle fournit.

- A chaque création de l'un de ces modèles, le geocode ou reverse_geocode est appelé
- A chaque mise à jour de l'un de ces modèles, si l'un des champs ci-dessus est modifié alors le geocode ou reverse_geocode est appelé

## Rôles utilisateurs

  Il existe 2 type de rôle : 
   - Administratif qui sont stocké sur le champs roles. Administrator, SuperAdmin, Manager
   - Métier qui sont stocké sur le champs auth_roles. Demandeur, Bailleur, Entreprise, Réservataire

## Réservataire

    Création d'un Porteur de reservation via POST /api/dmo/reservation_holder
    
    Ajout d'un attribut reservation_holder_id sur les offres et demandes pour donner les droits aux utilisateurs avec le auth_roles 'Réservataire' et le reservation_holder_id correspondant

## Filtrer les offres publiques par dates

    GET api/dmo/public_housing_offers

Ajouter les paramètres 

    date_publication_start[$gte]=${date limite inférieure} // au format YYYY-MM-DD
    date_publication_end[$lte]=${date limite supérieure} // au format YYYY-MM-DD

La requête va retourner toutes les offres publiques dont les dates de publication sont comprises entre les 2 paramètres.

## Récupération de l'historique des décomptes bailleurs par n° d'offre

    GET api/dmo/housing_offers/{id de l'offre}/history

La requête va retourner le tableau d'historique des décomptes bailleurs pour une offre, si l'utilisateur est le réservataire ou le bailleur de cette offre.

Le champ `created_at` est le timestamp du moment où un objectif a été réalisé.  
Les `target_by_typologies` et `realized_by_typologies` sont les copies des "attendus" et "réalisés" à ce moment.

```
  [  
    {
      "id": "5e4fdc8b3604e9cfbf4d055e",
      "type": "lessor_objective_history",
      "attributes": {
        ...
        "created_at": "2020-02-21T14:35:07.613+01:00",
        "lessor_objective_id": "5dc3c9bfa70bf25732aaa55b",
        "lessor_id": "5dc2d6b6a70bf24cc5b33594",
        "housing_offer_id": "5dc30a5ba70bf23b53a26475",
        "target_by_typologies": {
          "T3": 25,
        },
        "realized_by_typologies": {
          "T3": 3,
        }
      }
    }
  ]
```

## Récupération du score détaillé par n° d'offre pour un demandeur donné


Si l'utilisateur est demandeur sur l'offre, la requête va retourner son score détaillé.

    GET api/dmo/housing_offers/{id de l'offre}/detailed_score

Si l'utilisateur est au moins lecteur de l'offre, le paramètre `applicant_id` est **obligatoire**. La requête ne retourne le score pour ce demandeur que si l'utilisateur est également au moins lecteur du demandeur.

    GET api/dmo/housing_offers/{id de l'offre}/detailed_score?applicant_id={id de l'applicant}




## Renseigner la date de visite pour une candidature

    PATCH/PUT api/dmo/housing_applications/{housing_application_id}

avec en body de la requête : 

    {
      "data":
        {
          "attributes":
            "visit_conducted_date": 'DD/MM/YYYY' // date de la visite
        }
    }

  
## Fonctionnement de la création/update/auto_delete des offres 

Lorsqu'on crée un offre, un recherche est effectuée sur le champs lessor_id et external_ref.
Si une offre correspondante existe, elle est mise a jour avec les infos transmises lors de l'update.

A chaque modifications de l'offre via l'api, si l'offre a le champs housing_offer.auto_destroy_next_day à true, un compte à rebour de 36h se déclenche.
A l'issue de ce compte à rebours, si aucune requête de création ou d'update n'a été faite sur l'offre par le bailleur, le offer_status passe à "RETIRE PAR LE BAILLEUR"
et les actions suivantes sont exécutées :

 - envoi du flux 12 pour informer sopra de la reprise par le bailleur (status "RBA").
 - à spécifier
 - à spécifier
 


## Centre de Notifications
- [Swagger](https://app.swaggerhub.com/apis-docs/simukappu/activity-notification/2.1.0#/)
- Endpoint notifications: `/api/dmo/{targetable_type}/{targetable_id}/notifications`
- Endpoint subscriptions: `/api/dmo/{targetable_type}/{targetable_id}/subscriptions`
- [Collection postman](https://www.postman.com/collections/2d165c413a89f7df87f9)

### Utilisation
Lors de de certaines actions une notification peut être créé. Cette notification est un
enregistrement en base de donnée qui relie une entité **notifiable** et une entité **targetable**. Par exemple, lorsqu'un
nouveau logement est disponible et est éligible pour un salarié donné, **HousingOffer** est le **notifiable** et Applicant le **targetable**.

Par défaut un **Applicant** sera notifié par email lorsqu'une nouvelle notification lui sera destiné mais il est possible
de créer un abonnement à un type de notification et de spécifier si oui ou non les emails doivent être envoyés lors de
la création d'une nouvelle notification.
Si l'email est envoyé, celui-ci contient un message informant d'une nouvelle notification, et d'un lien permettant de
redirigé vers l'entité notifiable en question.

L'api fournit une série de routes permettants la gestion des notifications et abonnements.

### Clés d'abonnement aux notifications disponible
|Modèle|Clé|Création|
|---|---|---|
|Hermes::HousingRequest|housing_request.status.change|Si le status d'une HousingRequest est modifié, alors on notifie le candidat|
|Hermes::HousingOffer|housing_offer.new.eligible|Si un candiat est éligible à un nouveau logement lors de la création d'un score, celui-ci est notifé|

### Exemple pour la gestion des notifications d'un Applicant

**Objet Notification**

    {
        "id": "5e5d2534d195540cc306cec2", // ID de la notification
        "key": "housing_offer.new.eligible", // Clé de notification (parmis les clés disponibles)
        "target_id": "5dcd4a32a70bf24770e869b2", // ID de la cible (un Applicant)
        "title": "Nouvelle éligibilité pour 5dc2ed9da70bf27ad7e1cca3", // Titre de la notification
        "body": "Vous venez d'être éligible à une nouvelle offre de logement", // Body de la notification
        "opened_at": "2020-03-06T12:43:28.909+01:00", // Date et heure d'ouverture (null si jamais lue)
        "created_at": "2020-03-02T16:24:36.487+01:00" // Date de création de la notification
    }

**Récupération de la liste de ses notifications**

    GET /api/dmo/applicants/5dcd4a32a70bf24770e869b2/notifications

    status: 200

**Marquer une notification comme lue**

    PUT /api/dmo/applicants/5dcd4a32a70bf24770e869b2/notifications/5e5d2534d195540cc306cec2/open

    status: 200

**Ouvrir toute les notifications**

    PUT /api/dmo/applicants/5dcd4a32a70bf24770e869b2/notifications/open_all

    status: 200

**Supprimer une notification**

    DELETE /api/dmo/applicants/5dcd4a32a70bf24770e869b2/notifications/5e5d2534d195540cc306cec2

    status: 200
### Exemple pour la gestion des abonnements d'un Applicant

**Objet abonnement**

    {
        "id": "5e623a94d195544122932aad", // ID de l'abonnement
        "key": "housing_offer.new.eligible", // Clé d'abonnement
        "subscribed_at": "2020-03-06T12:57:08.658+01:00", // Date de souscription à l'abonnement
        "subscribed_to_email_at": "2020-03-06T12:57:08.658+01:00", // Date de souscription à l'abonnement par email
        "subscribing": true, // Abonné oui/non
        "subscribing_to_email": true, // Abonné par email oui/non
        "target_id": "5dcd4a32a70bf24770e869b2", // ID de la l'Applicant
        "unsubscribed_at": null, // Date d'annulation d'abonnement
        "unsubscribed_to_email_at": null, // Date d'annulation d'abonnement par email
        "created_at": "2020-03-06T12:57:08.663+01:00", // Date de création de l'abonnement
        "updated_at": "2020-03-06T12:57:08.663+01:00", // Date de mise à jour de l'abonnement
    }

**Récupération de la liste des abonnements**

    GET /api/dmo/applicants/5dcd4a32a70bf24770e869b2/subscriptions

    status: 200

**réponse**

    {
        "subscriptions": [],
        "notification_keys": [
            "housing_offer.new.eligible"
        ]
    }

**Création d'un nouvel abonnement**

    POST /api/dmo/applicants/5dcd4a32a70bf24770e869b2/subscriptions

body

    {
        "subscription": {
            "key": "housing_offer.new.eligible",
            "subscribing": true,
            "subscribing_to_email": true
        }
    }

    status: 200
    

**Mise à jour d'un abonnement existant**

    PUT api/dmo/applicants/5dcd4a32a70bf24770e869b2/subscriptions/5e623a94d195544122932aad/unsubscribe_to_email

    status: 200

    PUT api/dmo/applicants/5dcd4a32a70bf24770e869b2/subscriptions/5e623a94d195544122932aad/subscribe_to_email

    status: 200

## Désactiver ou supprimer une demande
  Impossibilité de désactiver/supprimer un demande si elle a des candidatures

    PATCH/PUT api/dmo/housing_requests/{id}

    {
      "data":
        {
          "attributes":
            "is_active": false
        }
    }

    ou 

    DELETE api/dmo/housing_requests/{id}

## Trier les offres par codes postaux souhaités en premiers

    GET api/dmo/housing_offers

Ajouter en paramètre un array de codes postaux dans l'ordre souhaité

    postal_codes[]={code postal souhaité 1} (e.g. 75100)
    postal_codes[]={code postal souhaité 2} (e.g. 34200)

La requête va retourner en premier les offres dont les codes postaux sont "75100" puis les offres dont les codes postaux sont "34200" puis toutes les autres offres.

**Pour afficher le positionnement d'un candidat par rapport à sa localisation**


    GET api/dmo/housing_offers/{id de l'offre}/score_position

Si le score est trouvé, la requête retourne : 

    {
      "position_by_department": 4,
      "total_by_department": 10,
      "position_by_postal_code": 4,
      "total_by_postal_code": 10
    }

Avec "total_by_department/postal_code", le nombre de scores de l'offre pour le departement/code postal de l'utilisateur courant.  
Et "position_by_department/postal_code", la position sur l'offre pour le departement/code postal de l'utilisateur courant.

## Fonctionnement du scoring
  Pour chaque offre un score est créé pour chaque demandeur éligible qui contient ses informations (accessible sur l'offre/candidature) :
    - eligible_position
    - applicated_position
    - eligible_requests_nb
    - applicated_nb

