- Installation simple
- Installation avancée
- Assistant d'installation
-
Utiliser Loxya (Robert2)
- Terminologie
- Rôles des utilisateurs
- Menus et navigation
- Listings
- Création / modification
- Catégories et étiquettes
- Le matériel
- Caractéristiques spéciales
- Documents du matériel
- Unités de matériel
- Indispo. du matériel
- Le Calendrier
- Fenêtre d'un événement
- Gérer un événement
- Réservations en ligne
- Dupliquer un événement
- Devis et factures
- Retour du matériel
- Modèles de liste
- Parcs de matériel
- Inventaires des parcs
- Techniciens
- Bénéficiaires
- Gérer les utilisateurs
- Paramètres de l'application
- Mise à jour
- Participer
- Annexes
- Licence
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 |
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 :
- 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). - Assurez-vous que le fichier est bien accessible en lecture par l'utilisateur système du serveur web (par ex.
www-data
). - 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 logovotre_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 %.