Annexes

Structure du fichier de configuration

Ce fichier est créé automatiquement par l'assistant d'installation, mais en cas de modification il est bon de savoir à quoi servent ses composantes.
Voici donc un exemple de contenu du fichier de configuration principal, expliqué ligne par ligne en dessous  :

{
    "apiUrl": "https://example-robert2.net",
    "basename": "Loxya",
    "enableCORS": false,
    "displayErrorDetails": false,
    "useRouterCache": true,
    "useHTTPS": true,
    "maxItemsPerPage": 100,
    "JWTSecret": "super_long_secret_string_to_never_commit",
    "httpAuthHeader": "Authorization",
    "sessionExpireHours": 12,
    "defaultLang": "fr",
    "currency": {
        "symbol": "€",
        "name": "Euro",
        "iso": "EUR",
        "symbol_intl": "€",
        "decimal_digits": 2,
        "rounding": 0
    },
    "billingMode": "partial",
    "defaultParkName": "Interne",
    "degressiveRateFunction": "((daysCount - 1) * 0.75) + 1",
    "db": {
        "host": "localhost",
        "username": "myuser",
        "password": "mypassword",
        "database": "robert2",
        "prefix": ""
    },
    "companyData": {
        "name": "Votre société",
        "logo": "votre_logo.jpg",
        "street": "32, rue du matoss",
        "zipCode": "75000",
        "locality": "Paris",
        "country": "France",
        "phone": "+33 (0)1 23 45 67 89",
        "email": "contact@your-company.com",
        "vatNumber": "FR78945612300",
        "vatRate": 20,
        "legalNumbers": [
            {
                "name": "SIRET",
                "value": "123 456 789 00001"
            },
            {
                "name": "APE",
                "value": "947A"
            }
        ]
    },
    "logger": {
        "timezone": "Europe/Paris",
        "level": 100,
        "max_files": 3
    },

    //////////////////////////////////////////////////
    // La suite est spécifique à la variante Premium :
    //////////////////////////////////////////////////

    "handScanner": {
        "scanTimeout": 100,
        "inputLayout": "azerty"
    },
    "colorSwatches": [
        "#f5006b",
        "#06b5a9",
        "#0004ff",
        "#f8ad14",
        "#ffe78e",
        "#9fde3f",
        "#ff0000",
        "#ff6e21",
        "#909090"
    ],
    "notifications": {
        "overdue": {
            "enabled": false,
            "days": [1, 15, 22, 27, 30],
            "lookBackMaxMonths": 2
        }
    },
    "email": {
        "from": {
            "email": "noreply@example.com",
            "name": "Notification Loxya"
        },
        "driver": "mail",
        "smtp": {
            "host": "localhost",
            "port": 1025,
            "username": null,
            "password": null,
            "security": ""
        },
        "mailjet": {
            "apiKey": "mailjet-api-key",
            "apiSecretKey": "mailjet-api-secret"
        }
    },
    "auth": {
        "cookie": "auth",
        "CAS": {
            "enabled": false,
            "host": "cas.robert2.local",
            "uri": "/cas",
            "port": 8080,
            "cert": false,
            "attributes": {
                "pseudo": "givenName",
                "email": ["mail", "email"],
                "firstName": "first_name",
                "lastName": "last_name",
                "group": "group"
            },
            "groupsMapping": {}
        }
    }
}
Clé Description Type de valeur Valeur par défaut
apiUrl Adresse web de l'application string [URL actuel]
basename Nom de l'application string "Loxya"
enableCORS Activer le "Cross Origin Resource Sharing" boolean false
displayErrorDetails Afficher le détail des erreurs (stack trace) boolean false
useRouterCache Utiliser le cache du router de Slim3 boolean true
useHTTPS Utiliser SSL boolean [Détection auto]
maxItemsPerPage Nombre d'enregistrements retournés par pages pour la pagination integer 100
JWTSecret Passphrase utilisée pour la création du JWT (Json Web Token) string [Valeur aléatoire]
httpAuthHeader Nom du header utilisé pour l'authentification des requêtes string "Authorization"
sessionExpireHours Nombre d'heures avant expiration d'une session utilisateur.
Attention, ne pas utiliser la valeur 0, car cela risque de faire planter le login !
integer 12
defaultLang Langue de l'interface par défaut (en étant non connecté) "fr" ou "en" "fr"
defaultParkName Nom du parc principal utilisé au départ pour le matériel string "Interne"
billingMode Le mode d'utilisation de la facturation. Trois valeurs possibles :
- all : facturation de tous les événements,
- partial : facturation des événements facturables uniquement,
- none : pas de facturation du tout (mode prêt)
string "partial"
degressiveRateFunction Fonction (javascript) permettant d'appliquer un tarif dégressif string ((daysCount - 1) * 0.75) + 1
currency Devise utilisée pour les montants : un objet décrivant la devise object
→ currency.symbol Symbole de la devise string "€"
→ currency.name Nom lisible de la devise string "Euro"
→ currency.iso Code ISO de la devise string "EUR"
db Informations de connection à la base de données MySQL object
→ db.host Le nom du serveur hôte à utiliser pour la connexion MySQL string "localhost"
→ db.username Le nom de l'utilisateur MySQL à utiliser pour la connexion à la base de données string "root"
→ db.password Le mot de passe de l'utilisateur MySQL string ""
→ db.database Le nom de la base de données string "robert2"
→ db.prefix Un préfixe éventuel à ajouter devant chaque nom de table de la base de données string ""
companyData Informations de la société pour la création des documents (devis, factures...) object
→ companyData.name Raison sociale (nom) de la société string ""
→ companyData.logo Nom du fichier (image JPG ou PNG) du logo la société, à placer dans le dossier src/public/img/ string (ou null) null
→ companyData.street Adresse postale (rue et numéro) de la société string ""
→ companyData.zipCode Code postal de la société string ""
→ companyData.locality Localité (ville ou village) de la société string ""
→ companyData.country Pays de la société string ""
→ companyData.phone Numéro de téléphone de la société string ""
→ companyData.email Adresse email de contact de la société string ""
→ companyData.vatNumber Numéro de TVA intracommunautaire de la société string ""
→ companyData.vatRate Taux de TVA applicable dans les factures number (float) 0.0
→ companyData.legalNumbers Numéros légaux supplémentaires pour affichage sur les documents (devis et factures) object
→ companyData.legalNumbers.0.name Type du premier numéro légal (nom ou acronyme) string "SIRET"
→ companyData.legalNumbers.0.value Valeur du premier numéro légal string ""
→ companyData.legalNumbers.1.name Type du second numéro légal (nom ou acronyme) string "APE"
→ companyData.legalNumbers.1.value Valeur du second numéro légal string ""
logger Paramétrage du logging (fichiers de logs du système, voir dans /src/var/logs) object
→ logger.timezone La timezone à utiliser pour l'horodatage dans les fichiers de log string "Europe/Paris"
→ logger.level Le niveau de log à utiliser (voir cette documentation.) number 250
→ logger.max_files Le nombre maximum de fichiers de log à conserver number 10

Les éléments suivants sont spécifiques à la variante Premium :

Clé Description Type de valeur Valeur par défaut
handScanner Paramétrage du scanner de code-barres object
→ handScanner.scanTimeout Le temps (en millisecondes) permettant de détecter un scan de code-barre number 100
→ handScanner.inputLayout Le type de clavier à émuler (doit être similaire à celui utilisé par les utilisateurs) string "qwerty"
colorSwatches Liste des couleurs proposées dans le color-picker de l'étape 1 de l'édition des événements array
notifications Paramétrage des notifications object
→ notifications.overdue Notifications en cas de non retour du matériel à temps par les bénéficiaires object
→ notifications.overdue.enabled Activation de ce type de notification boolean false
→ notifications.overdue.days Liste du nombre de jours après lesquels il faut envoyer une notification tant que le matériel n'est pas restitué. Après la dernière valeur, une notification est envoyée tous les jours. array [1,15,22,27,30]
→ notifications.overdue.lookBackMaxMonths Nombre maximum de mois pendant lesquels une notification est envoyée tous les jours après le dernier jour spécifié dans days (voir ci-dessus). number 2
email Paramétrage de l'envoi des e-mails object
→ email.from Nom et adresse e-mail de l'expéditeur.
Peut aussi être une simple chaîne de caractère (devant être une adresse e-mail valide).
object (ou string) ""
→ email.from.email Adresse e-mail de l'expéditeur string
→ email.from.name Nom de l'expéditeur string
→ email.driver Type de système à utiliser pour l'envoi des e-mails. Peut être soit mail, soit smtp, soit mailjet (voir ci-dessous) string "mail"
→ email.smtp Pour une utilisation du système d'envoi smtp (voir ci-dessus) object
→ email.smtp.host Nom d'hôte du serveur SMTP à utiliser string "localhost"
→ email.smtp.port Numéro du port SMTP à utiliser number 1025
→ email.smtp.username Nom d'utilisateur pour le compte SMTP à utiliser string (ou null) null
→ email.smtp.password Mot de passe pour le compte SMTP string (ou null) null
→ email.smtp.security Type de cryptage à utiliser pour SMTP. Peut être une chaîne vide, ou tls, ou ssl string ""
→ email.mailjet Pour une utilisation de l'API de Mailjet pour envoyer les e-mails object
→ email.mailjet.apiKey Votre clé d'API fournie par Mailjet string (ou null) null
→ email.mailjet.apiSecretKey Votre clé secrète fournie par Mailjet string (ou null) null
auth Paramétrage de l'authentification object
→ auth.cookie Nom du cookie à utiliser pour le stockage de session. string "auth"
→ auth.CAS Paramétrage de l'authentification CAS. object
→ auth.CAS.enabled Pour activer l'authentification via un serveur CAS. boolean false
→ auth.CAS.host Nom complet du serveur CAS hôte. string "cas.robert2.local"
→ auth.CAS.port Numéro du port pour accéder au serveur CAS. number 8443
→ auth.CAS.uri Chemin vers l'authentification sur le serveur CAS. string "/cas"
→ auth.CAS.cert Pour activer ou non la récupération du certificat SSL. boolean false
→ auth.CAS.attributes Paramétrage fin de la correspondance des attributs CAS pour la création des utilisateurs dans Loxya. Peuvent être soit une chaîne de caractère, soit un tableau. Si c'est un tableau, le premier attribut trouvé avec une valeur non nulle sera utilisé. object
→ auth.CAS.attributes.pseudo Les noms des attributs CAS à utiliser pour construire le pseudo de l'utilisateur. string (ou array) "givenName"
→ auth.CAS.attributes.email Les noms des attributs CAS à utiliser pour construire l'adresse email de l'utilisateur. string (ou array) ["mail", "email"]
→ auth.CAS.attributes.group Les noms des attributs CAS à utiliser pour choisir le groupe de l'utilisateur. string (ou array) "group"
→ auth.CAS.attributes.firstName Les noms des attributs CAS à utiliser pour construire le prénom de l'utilisateur. string (ou array) "first_name"
→ auth.CAS.attributes.lastName Les noms des attributs CAS à utiliser pour construire le nom de famille de l'utilisateur. string (ou array) "last_name"
→ auth.CAS.beneficiaryGroup Un groupe CAS dont la présence permettra de créer un bénéficiaire en même temps que l'utilisateur. string (ou null) null
→ auth.CAS.groupsMapping Un tableau de correspondance entre les groupes CAS et les groupes des utilisateurs de Loxya. object {}
→ auth.CAS.defaultGroup Le groupe utilisateur de Loxya à utiliser si aucun groupe CAS n'a été trouvé dans groupsMapping (voir ci-dessus). string (ou null) null

Important
Veillez bien à ne pas casser la structure du fichier de configuration, car cela pourrait rendre le logiciel complètement inutilisable.

Choisir un scanner de code-barre ( Premium)

Les codes-barres des unités de matériel sont générés par l'application (variante Premium uniquement).

Ce sont des codes-barres 2D, au format PDF417. Voici un exemple :

Dans un éditeur de texte, en scannant ce code-barre avec votre douchette, vous devriez voir apparaître la chaîne de caractères suivante :
^#[00000000001|00000000002]#$

Si c'est le cas, alors votre douchette est correctement paramétrée 👍.
Sinon, il faudrait la configurer pour le format PDF417 et la langue qui correspond à la disposition de votre clavier.

Ajouter un logo en en-tête des PDF

Pour ajouter le logo de votre structure en en-tête des fiches de sortie, des devis et des factures, il faut :

  1. Ajouter le fichier du logo dans le dossier src/public/img/. Ce fichier doit être une image du type JPEG ou PNG. Dans l'idéal, cette image ne devrait avoir une résolution d'au moins 400x250 pixels (notez aussi le rapport d'affichage, qui devrait rester plus large que haut).
  2. Assurez-vous que le fichier est bien accessible en lecture par l'utilisateur système du serveur web (par ex. www-data).
  3. Ensuite, dans le fichier de configuration (voir ci-dessus), insérer la clé companyData.logo avec comme valeur le nom de ce fichier.
    Pour exemple, voici un extrait du fichier de configuration modifié pour ajouter un logo votre_logo.jpg :
    },
    "companyData": {
        "name": "Votre société",
        "logo": "votre_logo.jpg",
        "street": "32, rue du matoss",
        (...)

Coefficient de tarif dégressif

Lors de l'étape 2 de l'assistant d'installation, une formule a été définie pour appliquer un tarif dégressif aux événements.

Par défaut, cette formule est la suivante : ((daysCount - 1) * 0.75) + 1. On peut traduire ceci par la phrase :

« Le premier jour est à plein tarif, et les jours supplémentaires sont à 3/4 du tarif »

Vous pouvez modifier cette formule en modifiant le fichier de configuration pour qu'elle corresponde à vos besoins.

Il s'agit du contenu d'une fonction javascript. Cette fonction n'accepte qu'une seule variable, daysCount qui correspond au nombre de jours d'un événement.

Vous êtes libre de composer votre formule comme vous le voulez. Si vous souhaitez ne pas appliquer de tarif dégressif, il suffit d'inscrire daysCount (ce qui veut dire que le tarif sera toujours exactement proportionnel au nombre de jours de l'événement).

Personnaliser les devis et factures

Il est possible de personnaliser la présentation des devis et factures, en modifiant les fichiers suivants :

  • Pour les devis : src/views/pdf/estimate-default.twig
  • Pour les factures : src/views/pdf/invoice-default.twig.

Il s'agit d'un fichier écrit en HTML, il faut donc maîtriser ce langage. Le système de template utilisé est Twig 3. Le système fourni des variables permettant d'afficher les diverses données de la facture. Pour utiliser une variable, il suffit d'écrire son nom entre double-accolades, comme ceci : {{ variable }}, ou {{ variable['name'] }}.

Voici la liste des variables disponibles :

Variable Description Type
number Numéro de la facture. string
date Date de la facture. DateTime*
currency Devise de la facture (code ISO, par ex. EUR). string
currencyName Nom de la devise de la facture (p. ex. Euro). string
dailyAmount Montant total par jour. float**
degressiveRate Coefficient du tarif dégressif (voir fichier de config). float**
daysCount Nombre de jours (durée) de l'événement. integer
discountableDailyAmount Montant remisable total par jour. float**
discountRate Taux de remise appliqué (voir fichier de config). float**
dailyTotalDiscount Montant total de la remise par jour H.T.. float**
hasVat Est-ce que la TVA est utilisée ? boolean
vatRate Taux de T.V.A. applicable float**
vatAmount Montant de la T.V.A. float**
dailyTotalWithoutDiscount Montant total par jour H.T. sans remise. float**
dailyTotalDiscountable Montant remisable total par jour H.T.. float**
dailyTotalWithoutTaxes Montant total par jour H.T. avec remise. float**
dailyTotalTaxes Montant des taxes par jour float**
dailyTotalWithTaxes Montant total par jour T.T.C. float**
totalWithoutTaxes Montant total de la facture H.T.. float**
totalWithTaxes Montant total de la facture T.T.C.. float**
totalReplacement Valeur de remplacement totale. float**
locale Langue utilisée pour les traductions (fr, ou en). string

company

Informations de votre société (voir ci-dessous).

Array
company[name] Nom de votre société. string
company[street] Adresse de votre société (rue et n°). string
company[zipCode] Code postal de votre société. string
company[locality] Ville de votre société. string
company[country] Pays de votre société. string
company[phone] Numéro de téléphone de votre société. string
company[email] Adresse e-mail de contact de votre société. string
company[vatNumber] Le numéro de T.V.A. de votre société. string
company[legalNumbers] Numéros spéciaux de votre société.
(Par exemple, n° SIRET ou code APE, voir fichier de config).
Pour chaque numéro, les clés name et value sont disponibles.
Array

booking

Informations de l'événement à facturer (voir ci-dessous).

Array
booking[title] Titre (nom) de l'événement. string
booking[start_date] Date de début de l'événement. DateTime*
booking[end_date] Date de fin de l'événement. DateTime*
booking[location] Localisation (lieu) de l'événement. string
booking[beneficiaries] La liste des bénéficiaires de l'événement.
Dans la vue par défaut, seul le 1er bénéficiaire de la liste (le 0) est utilisé.
Array
booking[beneficiaries][0][full_name] Nom complet du bénéficiaire. string
booking[beneficiaries][0][street] Adresse (rue et numéro) du bénéficiaire. string
booking[beneficiaries][0][postal_code] Code postal du bénéficiaire. string
booking[beneficiaries][0][locality] Ville du bénéficiaire. string

categoriesSubTotals

Sous-totaux par catégories (voir ci-dessous).

Array
categoriesSubTotals[x][name] Nom de la catégorie. string
categoriesSubTotals[x][quantity] Quantité de matériel dans la catégorie. integer
categoriesSubTotals[x][subTotal] Montant total pour la catégorie. float**

materials

Détail du matériel, trié par sous-catégories (voir ci-dessous).

Array
materials[x][subCategory] Nom de la sous-catégorie. string
materials[x][materialsList] Liste du matériel de la sous-catégorie (voir ci-dessous). Array
materials[x][materialsList][x][reference] Référence du matériel. string
materials[x][materialsList][x][name] Nom du matériel. string
materials[x][materialsList][x][quantity] Quantité du matériel alloué. integer
materials[x][materialsList][x][unit_price] Tarif de location (unité). float**
materials[x][materialsList][x][replacement_price] Prix de remplacement total du matériel. float**
materials[x][materialsList][x][total_price] Montant total pour le matériel. float**

Personnaliser les fiches de sortie

De même que pour les devis et factures, il est possible de modifier le fichier suivant pour personnaliser les fiches de sortie :

  • src/views/pdf/event-summary-default.twig

Voici la liste des variables disponibles :

Variable Description Type
date Date du jour DateTime*
currency Devise de la facture (code ISO, par ex. EUR). string
currencyName Nom de la devise de la facture (p. ex. Euro). string
materialDisplayMode Le classement utilisé pour la liste du matériel string
replacementAmount Valeur de remplacement totale. float**
locale Langue utilisée pour les traductions (fr, ou en). string

company

Informations de votre société.

Array
company[name] Nom de votre société. string
company[street] Adresse de votre société (rue et n°). string
company[zipCode] Code postal de votre société. string
company[locality] Ville de votre société. string
company[country] Pays de votre société. string
company[phone] Numéro de téléphone de votre société. string
company[email] Adresse e-mail de contact de votre société. string
company[vatNumber] Le numéro de T.V.A. de votre société. string
company[legalNumbers] Numéros spéciaux de votre société.
(Par exemple, n° SIRET ou code APE, voir fichier de config).
Pour chaque numéro, les clés name et value sont disponibles.
Array

event

Informations de l'événement à facturer.

Array
event[title] Titre (nom) de l'événement. string
event[start_date] Date de début de l'événement. DateTime*
event[end_date] Date de fin de l'événement. DateTime*
event[location] Localisation (lieu) de l'événement. string
event[beneficiaries] La liste des bénéficiaires de l'événement.
Dans la vue par défaut, seul le 1er bénéficiaire de la liste (le 0) est utilisé.
Array
event[beneficiaries][0][full_name] Nom complet du bénéficiaire. string
event[beneficiaries][0][street] Adresse (rue et numéro) du bénéficiaire. string
event[beneficiaries][0][postal_code] Code postal du bénéficiaire. string
event[beneficiaries][0][locality] Ville du bénéficiaire. string

materialList

Liste du matériel (le tri dépend de materialDisplayMode).

Array
materialList[x][name] Nom de la sous-catégorie, ou du parc. string
materialList[x][materials] Liste du matériel de la sous-catégorie ou du parc. Array
materialList[x][materials][x][reference] Référence du matériel. string
materialList[x][materials][x][name] Nom du matériel. string
materialList[x][materials][x][quantity] Quantité du matériel alloué. integer
materialList[x][materials][x][rentalPrice] Tarif de location (unité). float**
materialList[x][materials][x][replacementPrice] Prix de remplacement total du matériel. float**
materialList[x][materials][x][total] Montant total pour le matériel. float**

* Les variables du type DateTime peuvent être formatées avec le filtre format_date() de Twig.
** Les variables du type float peuvent être formatées avec le filtre format_currency() de Twig si on veut un montant en devise, ou bien le filtre format_percent_number() si on veut un nombre en %.