# Aide — faire une demande

Cette page explique le formulaire de demande de Granuloshop, distributeur
officiel de Topas GmbH. Elle est écrite pour deux lecteurs : la personne qui
remplit le formulaire, et l'agent logiciel qui le remplit pour elle. Les deux
parties disent la même chose, dans deux langages.

- Le formulaire : <https://www.granuloshop.com/common/contact/request_fr.html>
- Description destinée aux agents : <https://www.granuloshop.com/llms.txt>

---

## Pour un visiteur

### Une seule page pour toutes les demandes

Devis, question technique, documentation, calibration, SAV, pièces de
rechange, suivi de commande : la même page les reçoit toutes. Le choix de
l'objet, au début de la seconde étape, met le formulaire au format de la
demande — il ouvre les champs utiles et laisse de côté les autres.

Un lien peut déjà porter l'objet : `?a=quotation` ouvre la page sur un devis.
La liste complète figure plus bas, dans la partie destinée aux agents.

### Étape 1 — domaine, pays, langue

Trois choix, et chacun sert à quelque chose :

- **le domaine** oriente la demande vers l'équipe qui connaît les appareils
  concernés ;
- **le pays** décide des mentions de TVA, des régions proposées, et de
  l'interlocuteur qui répondra ;
- **la langue** est celle dans laquelle la réponse vous parviendra.

Le bouton **Continuer** dit lui-même ce qui lui manque encore.

### Étape 2 — la demande

Les champs marqués d'une étoile rouge sont attendus. Trois suffisent pour que
la demande parte : **votre e-mail**, **votre message**, et le **consentement**
au traitement de la demande. Le reste précise, et une demande précise reçoit
une réponse précise.

Selon l'objet choisi, la page ouvre d'elle-même :

- un menu de **produits**, pour nommer l'appareil ;
- un **numéro de série**, de commande ou de devis ;
- une **description du problème**, distincte du message ;
- une **préférence de réponse** : par e-mail, ou par un échange de vive voix
  dont vous choisissez le moyen, le jour et le créneau horaire.

### Ce que vous pouvez joindre

- **Des fichiers** : jusqu'à 3, 5 Mo chacun, 12 Mo en tout, aux formats pdf,
  doc, docx, xls, xlsx, odt, ods, jpg et png.
- **Un message vocal**, enregistré depuis la page, quand décrire à l'oral est
  plus simple que d'écrire.
- **Des collègues en copie** : jusqu'à 5 adresses, pour que votre équipe suive
  la demande avec vous.

### Après l'envoi

Une page de confirmation s'affiche et porte la **référence** de votre demande,
de la forme `GS-RQ-AAAAMMJJ-<identifiant>`. Conservez-la : elle désigne votre
demande dans tous les échanges qui suivront.

---

## Pour un agent

Cette partie donne de quoi composer une requête valide du premier coup.

### Envoi

    Method        POST
    Endpoint      https://www.granuloshop.com/ASP/contact.asp
    Content-Type  application/x-www-form-urlencoded
                  multipart/form-data lorsque des fichiers accompagnent
                  la demande

### Le parcours de la page, et ce qu'un agent en fait

La page se remplit en deux temps : une première étape demande le domaine, le
pays et la langue, puis le formulaire s'ouvre. Il s'ouvre **progressivement** :
le choix de l'objet décide des champs qui apparaissent, et les options du bloc
Message — pièces jointes, message vocal, collègues en copie — n'apparaissent
qu'une fois la demande complète et l'adresse professionnelle.

**Un agent n'a pas à suivre ce parcours.** Le POST est reçu tel quel : les
champs attendus sont ceux de la liste plus bas, quel que soit le chemin par
lequel ils ont été composés. Suivre la page sert quand on veut qu'elle
compose à votre place — c'est le cas d'un lien `?a=` ou d'un lien court `/Q/`.

### Le minimum qui aboutit

Quatre champs. Le serveur accepte la demande dès qu'ils sont présents et
valides :

    h_lg       langue de la demande : fr, en, nl, es, it, de, pl, pt, ja,
               ko, zh, ru. REQUIS, et sans valeur par défaut : une demande
               dont le h_lg manque ou sort de cette liste est tenue pour
               forgée.
    email      adresse de réponse, syntaxe vérifiée
    message    15 caractères au moins, 4000 au plus
    consent    toute valeur non vide, par exemple consent=1

Exemple complet :

    curl -i https://www.granuloshop.com/ASP/contact.asp \
      --data-urlencode "h_lg=en" \
      --data-urlencode "email=someone@example.com" \
      --data-urlencode "message=Please send a quotation for an aerosol generator." \
      --data-urlencode "consent=1" \
      --data-urlencode "objet=1" \
      --data-urlencode "h_country=DE"

### Ce qu'il faut ajouter pour être utile

`objet` oriente la demande : il désigne la nature de la requête et décide de
l'équipe qui la traite. Les deux colonnes ci-dessous nomment la même chose à
deux endroits différents — `?a=` dans l'URL de la page, `objet=` dans le POST.

Le catalogue ci-dessous est **engendré depuis le référentiel du site** à
chaque fabrication des pages : il décrit le formulaire tel qu'il est, et non
tel qu'il était. Chaque entrée donne le code à poster dans `objet`, les
valeurs de `?a=` qui le désignent, et **les champs que ce choix ouvre en
plus** — un agent sait ainsi d'avance ce qu'on attendra de lui.

Le code numérique vaut aussi comme `?a=` : `?a=1` et `?a=quotation` ouvrent
la même page. Sans `?a=`, la liste complète est proposée, sans présélection.

<!-- OBJETS : bloc engendre par gen_contact.py -->

    objet=0    ?a=contact
        Contact
        Aucun champ supplémentaire.

    objet=1    ?a=quotation
        Demande de devis
        Ouvre un menu de produits, une précision à choisir
        (precision_objet).

    objet=5    ?a=calibration, ?a=service
        Demande de maintenance / réparation (SAV)
        Ouvre un menu de produits, une précision à choisir
        (precision_objet), un numéro de série (serial), une description du
        problème (probleme).

    objet=2    ?a=product-info
        Demande d'information produit
        Ouvre un menu de produits, une précision à choisir
        (precision_objet).

    objet=3    ?a=technical
        Question technique
        Ouvre un menu de produits, une précision à choisir
        (precision_objet), une description du problème (probleme).

    objet=4    ?a=documentation
        Demande de manuel / documentation
        Ouvre un menu de produits, une précision à choisir
        (precision_objet), un numéro de série (serial).

    objet=6    ?a=spare-parts
        Pièces de rechange / consommables
        Ouvre un menu de produits, une précision à choisir
        (precision_objet), un numéro de série (serial).

    objet=8    ?a=offer
        Discussion sur une offre
        Ouvre un menu de produits. L'échange de vive voix est proposé
        d'emblée (pref=echange). L'étape 1 ne demande que le pays et la
        langue.

    objet=10   ?a=order-tracking
        Suivi de commande
        Ouvre un numéro de commande ou de devis, une précision à choisir
        (precision_objet). La réponse se fait par e-mail (pref=email).
        L'étape 1 ne demande que le pays et la langue.

    objet=9    ?a=other, ?a=refurbished, ?a=rental
        Autre demande
        Aucun champ supplémentaire.

<!-- OBJETS : fin du bloc engendre -->

`h_country` porte le pays de livraison, en code ISO 3166-1 alpha-2 : il
détermine le traitement de la TVA et l'interlocuteur qui répond. Le renseigner
fait gagner un aller-retour.

### Tous les champs, un par ligne

    h_lg             langue de la demande (REQUIS, voir ci-dessus)
    email            adresse de réponse (REQUIS)
    message          la demande elle-même (REQUIS, 15 à 4000 caractères)
    consent          consentement au traitement (REQUIS, valeur non vide)
    objet            code de l'objet, colonne objet= du tableau
    h_country        pays, code ISO 3166-1 alpha-2 : FR, BE, DE, CH...
    langpref         langue demandee, si elle differe de h_lg
    precision_objet  produit ou précision, selon l'objet
    serial           numéro de série, de commande ou de devis
    probleme         description du problème, pour un SAV
    nom              nom du contact
    societe          société
    tel              téléphone
    rue              rue
    cp               code postal
    ville            ville
    region           département (FR) ou province (BE)
    vat              numéro de TVA, SIREN ou SIRET
    pref             email (défaut) ou echange
    moyen            avec pref=echange : telephone, teams, whatsapp,
                     telegram ou zoom
    coord            avec pref=echange : numéro ou identifiant du moyen
    jour             avec pref=echange : jour proposé
    creneau          avec pref=echange : créneau, heure de Paris
    cc_nom_1..5      collègues en copie, nom
    cc_email_1..5    collègues en copie, adresse
    attachments      fichiers joints, en multipart/form-data
    h_source         origine de la demande, repris tel quel
    id_contact       identifiant proposé ; le serveur arbitre

### Les menus de l'étape 1 et les champs postés

Les trois menus de l'étape 1 — domaine, pays, langue — sont **hors du
formulaire** : ils gouvernent la suite de la page avant qu'il n'existe. Leurs
valeurs rejoignent la demande par des champs cachés, posés à la validation :
le pays dans `h_country`, la langue dans `h_lg`, le domaine dans
`h_perimetre`, que la page porte déjà dans son HTML. Le menu de langue, lui,
navigue : en changer recharge la page dans l'autre langue. Sa valeur part
tout de même, dans `langpref`, à côté de `h_lg` qui dit la langue servie —
les deux coïncident presque toujours.

### Ce que le balisage déclare

Chaque champ porte ses propres règles, lisibles sans exécuter le script :
`required` et `aria-required` sur ce qui est attendu, `minlength` sur le
message, `maxlength` partout où le serveur tronque, `type`, `inputmode`,
`pattern` et `autocomplete` sur ce qui a un format. Les champs dont
l'obligation dépend de l'état du formulaire — la région, les coordonnées
postales, la coordonnée d'échange — gagnent et perdent leur `required` au fil
des choix : lire le balisage à un instant donné, c'est lire la règle qui
s'applique à cet instant.

Le formulaire porte `novalidate` : le navigateur ne bloque rien de lui-même,
ces attributs décrivent.

### Champ réservé

    do_not_fill      MUST remain empty. Anti-spam honeypot field.
                     Legitimate users and automated agents MUST NOT
                     populate it. La page le signale elle-même, par le
                     libellé « Do not fill this field ».

### La réponse

- **Demande acceptée** : redirection **303** vers
  `/common/thank-you/thank-you_<lg>.html`, avec la référence de la demande
  dans le paramètre `ref`, de la forme `GS-RQ-AAAAMMJJ-<identifiant>`.
  Transmettez cette référence à la personne pour qui vous agissez : elle
  désigne la demande dans tous les échanges qui suivront.
- **Demande refusée** : une page d'erreur, au même emplacement, lorsque
  `email`, `message` ou `consent` ne satisfait pas les règles ci-dessus.

**La preuve d'enregistrement est le couple 303 + référence, et lui seul.**
Le code 303 dit que la demande est écrite ; la référence `ref` dit laquelle.
Une réponse 200 qui affiche une page de remerciement sans référence signale
que la demande a été reçue mais pas enregistrée : la relancer est alors la
bonne conduite, et la référence absente le signe à surveiller.

### Liens de préremplissage

Un lien de la forme `https://www.granuloshop.com/Q/<code>` porte une demande
déjà composée : objet, produit, pays et langue. Il ouvre la page de demande
avec ces valeurs en place. Suivez le lien et lisez la page qui en résulte
plutôt que de reconstruire la requête : le code porte des informations que
l'URL ne montre pas.

### Bonnes pratiques

- Une demande par sujet : deux questions distinctes reçoivent deux réponses
  mieux ciblées.
- Nommez l'appareil dans `message` ou `precision_objet` quand vous le
  connaissez, avec son numéro de série s'il s'agit d'un appareil en service.
- Servez-vous de la langue de l'URL : `request_en.html` répond en anglais,
  `request_fr.html` en français.
- Conservez la référence rendue par la redirection.

---

Granuloshop — distributeur officiel de Topas GmbH.
Mentions légales : <https://www.granuloshop.com/common/legal/legal_fr.html>
