
# Doc demandes de logement

## 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 **Applicant**

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
    	    }




**Attention, après sa création, le code est valable pendant 15 jours**
## housing_request form_status

Afin que le frontend puisse informer le back de l'avancement et de la complétude du formulaire, un champs "form_status" est ajouté a la housing request.
il peut prendre les valeurs suivantes :

 - "empty" => valeur initiale
 - "invalid" => le formulaire ne satisfait pas les regles de validations
 - "in progress" => le formulaire satisfait les regles de validations mais n'a pas été validé par l'utilisateur
 - "complete" =>le formulaire satisfait les regles de validations et à été validé par l'utilisateur (seul status pris en compte par le back)
 - "cancelled" => demande annulée
l'envoi de flux 3O vers le SNE via sopra (en création comme en édition) est conditionné au fait que le form_status soit à "complete"

### modifications du request_status par rapport au form_status

voici les régression entrainées par l'evolution du form_status sur le request_status renvoyé enjson lors de la requete : 
        
| request_status de base \ form_status | empty | invalid | in progress | complete |
|--|--|--|--|--|
|"INCOMPLETE" | INCOMPLETE| INCOMPLETE| INCOMPLETE|**EN ATTENTE DE LA CNI**|
|"EN ATTENTE DE NUD" | INCOMPLETE| INCOMPLETE| INCOMPLETE|EN ATTENTE DE NUD|
|"EN ATTENTE DE PIECES" | INCOMPLETE| INCOMPLETE| INCOMPLETE|EN ATTENTE DE PIECES|
|"ELIGIBLE" | INCOMPLETE| INCOMPLETE| INCOMPLETE|ELIGIBLE|
|"COMPLETE" | INCOMPLETE| INCOMPLETE| INCOMPLETE|COMPLETE|

 
### Upload des document pour renseigner une piece à fournir (en ajout initial ou update)

    POST api/dmo/required_documents/${id}/send_files
    
    
Retour 200 avec le required document en body

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

retours erreurs possibles : 
 - 404 required document non trouvé
 - 422 "not_writers" => vous n'avez pas les droits d'écriture sur l'objet
 - 422 "no_file_in_the_request" => il n'y a pas de fichiers envoyés ac la requete

### Supression des fichiers liés a une piece 

    DELETE api/dmo/required_documents/${id}/files


Retour 200 avec le required document en body

retours erreurs possibles : 
 - 404 required document non trouvé
 - 422 "not_writers" => vous n'avez pas les droits d'écriture sur l'objet


### Récupérer Historisations des statuts 

    GET api/dmo/required_documents/:id/historical_status 

    params: :id 
    
    {status: "success", code: 200, message: {'statuses' => statuses}} 

    5 statuts sont renvoyé de bases pour avoir la totalité il faut ajouter

    params: :id, more: true 
    

### 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

(a pour résultat temporaire de faire passer les pieces a "en attente de traitement" au status "piece validée")


### Forcer la validation/invalidation des pièces

    POST /api/dmo/housing_requests/:id/housing_request_folder/change_confirmed
        {
            required_documents:{
                Id_1 : false,
                Id_2 : true,
                Id_3 : true
            }
        }
        ou 
        {
            required_documents:{
                all: true|false
            }
        }


## 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}





## 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 »,
        },
        ...
      ]




## 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}

Avec en body : 

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

  ou 

    DELETE api/dmo/housing_requests/{id}




## Points managing on housing requests 

    Add points to entity  User must be collaborateur offre logement
    POST /api/dmo/entities/:entity_id/add_points

        params: entity_id: , points_to_add:
        {status: "success", code: 200, message: {"message" => "successfullly modified", "value" => entity.available_points}}

    Add points from an entity to an housing request user must be entreprise

    POST api/dmo/housing_requests/{id}/add_points_to_housing_request

        params: id: , points: , entity_id:

        {status: "success", code: 200, message: {'message' => 'points successfully added', 'points_added' => points}}


    List the points that are waiting 
    GET api/dmo/housing_requests/{id}/waiting_points

        params: id: 

        {status: "success", code: 200, message: {'waiting_points' => waiting_points}}

    List the points that have been spent
    GET api/dmo/housing_requests/{id}/spent_points
        
        params: id: 

        {status: "success", code: 200, message: {'spent_points' => spent_points}}

    List all the entity account request

    GET api/dmo/housing_requests/{id}/entity_requests
        params: id: 
        {status: "success", code: 200, message: {'entity_requests_account' => entity_requests_account}}



## Gestion des entity note / internal note 

    lire entity note d'une request 

    GET  api/dmo/housing_requests/{id}/entity_note
        params:  id:
        {status: "success", code: 200, message: entity_note}

  lire internal note d'une request 

    GET  api/dmo/housing_requests/{id}/internal_note
        params:  id:
        {status: "success", code: 200, message: internal_note}
        
        

    Modifier entity note 

        PUT api/dmo/housing_requests/{id}/update_entity_note
        params: id:, entity_note:

        {status: "success", code: 200, message: {"message" => "successfullly modified", "value" => entity_note}}


    Modifier internal note 

        PUT api/dmo/housing_requests/{id}/update_internal_note
        params: id:, internal_note:

        {status: "success", code: 200, message: {"message" => "successfullly modified", "value" => internal}}



## Mise a jour de la demande avec les infos du SNE.

### Fonctionnement :
A chaque GET sur une housing_request, une routine qui ne se déclenche au maximum qu'un fois toutes les 24h vient verifier la dateFichier du retour XML de la demande récupérée par rapport au updated_at de la housing_request en bdd.

si la date de la demande sur le sne est plus récente que celle sur hermes, le booléen "is_sne_update_available" est passé à true et est visible dans le json de la housing_request.

### Chemin API :

Un champs `applicant_verified` dans la housing_request, par défault true pour toutes les nouvelles créations et qui est passe à true lors de la validation du code pour les demandes existantes.
Pour mettre à jour les informations de la housing_request et des applicants a partir des informations contenues dans le SNE, il faut appeller :

    POST /api/dmo/housing_requests/{id}/update_from_sne
    
Si la demande applicant_verified: true => alors elle peut être mise à jour par le sne.
Si la demande applicant_verified: false => On doit fournir le code comme pour l'appel /api/dmo/nuds/:nud/authentify_with_pin_code sinon on a une erreur.
Pour générer un email/code pour une demande on peut appeler la route /api/dmo/nuds/:nud/send_new_pin_code





## Consentement et délégation

### Définition des niveaux de constement pour une Entity : `HousingRequestEntityFormLevel`

Ce modèle permet de définir les niveaux de constement pour un `entity_id` donné.

Requête pour créer un nouveau niveau de constement : 

    POST api/dmo/entities/{ID de l'entity}/housing_request_entity_form_levels

Requête pour mettre à jour le niveau de consentement : 

    PUT api/dmo/entities/{ID de l'entity}/housing_request_entity_form_levels/{id de l'entity_form_level'}

Avec en body pour les 2 requêtes : 

    {
      "data": {
        "attributes": {
          "consent_fields": ['champ_1', 'champ_2'],  // tableau des champs consentis
          "description": 'string',
          "level": integer,                          // e.g. 1, 2, 3....
          "delegation": true/false
        }
      }
    }

Pour supprimer le consentement : 

    DELETE api/dmo/entities/{ID de l'entity}/housing_request_entity_form_levels/{id de l'entity_form_level}

Pour afficher la liste des niveaux de consentement (utilitaires de tri disponibles $in, $nin, $ne, $eq, $all) : 

    GET api/dmo/entities/{ID de l'entity}/housing_request_entity_form_levels

Pour afficher un niveau spécifique : 

    GET api/dmo/entities/{ID de l'entity}/housing_request_entity_form_levels/{id de l'entity_form_level}

### Choix du consentement pour un demandeur : `HousingRequestEntityForm`

Ce modèle permet pour un candidat de choisir son niveau de consentement.

Requête pour créer un nouveau niveau de constement : 

    POST api/dmo/housing_request_entity_forms

Requête pour mettre à jour le niveau de consentement : 

    PUT api/dmo/housing_request_entity_forms/{id de l'entity_form'}

Avec en body pour les 2 requêtes : 

    {
      "data": {
        "attributes": {
          "consent_fields": ['champ_1', 'champ_2'],  // tableau des champs consentis
          "delegation": true/false,
          "housing_request_id": 'string',
          "entity_form_level_id": 'string' // ID de l'entity_form_level créé par l'entreprise
        }
      }
    }

Pour supprimer le consentement : 

    DELETE api/dmo/housing_request_entity_forms/{id de l'entity_form}

Pour afficher la liste des niveaux de consentement (utilitaires de tri disponibles $in, $nin, $ne, $eq, $all) : 

    GET api/dmo/housing_request_entity_forms

Pour afficher la liste des niveaux de consentement actifs (utilitaires de tri disponibles $in, $nin, $ne, $eq, $all) : 

    GET api/dmo/housing_request_entity_forms/actives

Pour afficher un niveau spécifique : 

    GET api/dmo/housing_request_entity_forms/{id de l'entity_form}

Une entreprise a également accès en lecture à la liste des champs consentis pour un niveau spécifique :

    GET api/dmo/housing_request_entity_forms/{id de l'entity_form}/show_request

Retourne en réponse le tableau des champs consentis : 

    [
      "champ_1",
      "champ_2",
      ...
    ]

### Filtrer les demandes de logement par niveau de consentement

Ajouter le param `consent_level` dans l'url de la requête. Exemple : 

    GET api/dmo/housing_requests?consent_level=4

Cela va retourner toutes les demandes de logement pour lesquelles il existe un niveau de consentement (`HousingRequestEntityForm`) de level 4.

On peut également ajouter un `entity_id` dans l'url de la requête pour filtrer les demandes de logement selon le niveau de consentement **et** selon l'entity : 

    GET api/dmo/housing_requests?consent_level=4&entity_id={id de l'entity}




## Validation du salarié par l'entreprise

Au changement d'entreprise du salarié demandeur principal, le booléen `housing_request.entity_validated` passe à `true` ou `false` en fonction du champ `auto_request_validation` de la nouvelle entreprise.
Seuls les utilisateurs avec des droits en écriture sur l'objet `entity` du salarié peuvent modifier ce booleen.

        PATCH/PUT api/dmo/housing_requests/{:id}
         body : {
           "data": {
             "attributes": {
               "entity_validated": true
               }
             }

Seuls les utilisateurs avec des droits en écriture sur le `main_applicant` de la `housing_request` ou sur son `entity` (entreprise) peuvent venir repasser le main_employer_siret de l'applicant à nil et supprimer la relation entre un demandeur et une entreprise.  
Pour créer cette relation, il faut passer par un code.

## renvoi du flux 30
    
### par batch asynchrones 
pour renvoyer le flux 30 sur un ensemble de housing request données, utilisez la route en lui passant des ids OU des als_ids (si ya les deux ca prendra que les ids):

    POST api/dmo/housing_requests/send_flux_thirty
    avec en body :
      {
        ids : array, // tableau d'id (string) des housing_requests concernées 
        als_ids : array,  // OU tableau d'als_id (string, avec les 0000.. devant) des housing_requests concernées
      }

### unitairement de manière synchrone

    POST api/dmo/housing_requests/{id}/send_flux_thirty_sync
    
## notion de provider de nud

lors de la création d'un nud, l'api hermes recherche parmis la liste des providers dans les settings pour attribuer le provider du departement concerné a un nud donné.
cette information pourra ensuite se retrouver dans le json de la housing request :
    
    housing_request : {
                            ...
                            unique_numbers : ["0110418041931AL004", "0030418041931AL006"]
                            providers : ["SNE", "IHOWEB"],
                            unique_numbers_complete : [
                                                    {
                                                      unique_number: "0110418041931AL004", 
                                                      provider: "SNE"
                                                    },
                                                    {
                                                      unique_number: "0030418041931AL006", 
                                                      provider: "IHOWEB"
                                                    }
                                                ],
                                                ...
                                                }
## affectation de nud invalide
lors de la création d'un numéro unique pour une demande, ou de l'affectation d'un numéro unique existant a une demande ou de son passage à "is_active",     une vérification est effectuée afin d'exclure la possibilité d'affecter a une demande active un numéro unique déja affecté a une autre demande active                       
## rapatriement des demandes par collaborateurs

    POST api/dmo/nuds/{unique_number}/hydrate_housing_request_from_sne

params : 

       {
        user_id: "vivementLeWeekend"
       }

codes retours 

-> 200 ok (avec la housing request ds le json)
-> 401 l'utilisateur n'est pas collaborateur
-> 400 le numéro unique est déja pris
-> 422 l'utilisateur n'a pas pu etre trouvé a partir de l'user_id fourni

## Demande info sur l'utilisateur qui a fait derniere modification

  Voici les champs qui sont mis à jour quand un utilisateur modifie une demande. Ces champs peuvent être utilisé en paramètre sur la route /api/dmo/housing_requests pour filtrer/trier.

    last_update_user_id
    last_update_user_last_name
    last_update_user_first_name
    
## recherche d'offre par channel

il est possible de rechercher des offres par channel

    /api/dmo/housing_request?housing_channel_keys="votre channel key"

## Récupération du nombre de demande éligible et notre possible de nombre éligible

  Sur l'object `housing_offer`, il y a 2 attributs : 
  - `eligible_requests_nb` donne le total de demande actuelement éligible 
  - `possible_eligible_requests_nb` donne le total de demande qui pourrait être éligible si l'offre devenait publiée

## Vérifier si un utilisateur à un housing_request_initializer en attente de code

    GET /api/dmo/nuds/pending_for_current_user 

    Retourne soit une 404 ou alors l'housing_request_initializer avec les attributs unique_number, pin_code_created_at, email, done, expired 
    L'attribut expired vaut vrai quand on trouve une housing_request_initializer qui correspond mais qui est plus ancienne que 24h.


## changements du champs motivation

avec la version 4 du cerfa sne, les champs de type string "motivation1", "motivation2" et "motivation3" sont remplacés par un champs de type array "motivations"

    ex : 
    housing_request.motivations = ["valeur1", "valeur2", ...]

## nouveaux champs liés au cerfa V4

Le cerfa V4 introduit de nouvelles données, la correspondance aidera les fronts a communiquer avec hermes. l'anglais n'est pas parfait mais il aidera les francophones du projet a s'y retrouver facilement.

 | Balise xlm | Nom du champ sur hermes | Nom du champ front | type |
|--|--|--|--|
|10095|10095|10095|10095|
| ressourcesMensuelles | housing_request.have_monthly_income | Percevez-vous des ressources mensuelles ? | Booléen |
| periodeChomage | applicant.unemployment_period | Chômage de plus d’un an | Booleen|
| dateFinPeriodeChomage | applicant.unemployment_period_date_end | Date de fin de période de chômage| Date aaaa-mm-jj |
| compDateCommandement | applicant.command_to_leave_date | Date du commandement si commandement de quitter les lieux| Date aaaa-mm-jj |
| nombreHandicap | housing_request.disabled_person_number | Nombre de personnes en situation de handicap|  Numérique (1) |
| telDomicilePro | applicant.pro_or_home_tel_number | tel Domicile ou professionnel | String (la sec demande Numérique (10) mais nous preferons utiliser une string pour harmoniser avec les autres tels |
|10106|10106|10106|10106|
| infoProprietaire | housing_request.owner_info_needed | Je souhaite être informé sur la possibilité de devenir propriétaire | Booléen |

## cerfaV4

l'objet housing_request a désormais un champ String "cerfa_version"
si une demande à été extraite d'un cerfa V4 récupéré en xml sur le sne, alors :

    housing_request.cerfa_version = "4"
