Module gifts (mobile)
Ce fichier doit rester synchronisé avec le code du module. À mettre à jour à chaque changement structurel.
Rôle : valider un code de bon cadeau au checkout d'une réservation et le faire consommer par le backend. Aligné sur gifts backend Horizon.
Code
- API :
publicApi.gifts.validate(code)→GiftCodeResponse({ id, code, value, remainingValue, isUsed, validUntil, status, customerId }) - Consommation : intégré au wizard de paiement, composant
travel-booking/payment/TBPaymentRebateCode.vue(titré « Bon et promotion » — traite aujourd'hui uniquement les bons cadeaux, aucun endpoint de code promo distinct n'existe côté backend mobile). Le code saisi est validé, puis :codeet le montant à déduire (remainingValue ?? value— le solde restant d'un bon partiellement utilisé, sinon sa valeur pleine) sont stockés dans le scope Regle partagérebateCode(composables/regle-scoped-config.ts, champamount), consommés par la chaîne de prix (useBCPricing→computeBookingPricing,utils/booking-pricing.ts). Celle-ci plafonne la déduction au sous-total de la réservation, suppléments globaux inclus (rebateCodeDiscount = min(amount, subTotal)— comme Horizon, qui mesure l'excédent d'un bon sur le total complet à la facture) et expose le solde qui restera sur le bon (rebateCodeLeftover = max(0, amount − subTotal)). En acompte, le bon est déduit à pleine valeur après le taux (pas de prorata — cf.business-rules.md→ « Acompte »). La case du bon affiche le montant appliqué et, si le bon dépasse le prix, « Il vous restera n CHF sur ce bon cadeau. ».id(leGiftCodeResponse.id) est stocké dans le même scope (rebateCode.giftId), exposé paruseBCPricingviaappliedGiftId, puis injecté dansfinalBooking.booking.gifts(stores/bookingConstructor.ts) sous la forme[{ id } as Gift]avant l'appel àpaymentApi.initialize. Seulidest envoyé — le backend re-fetch l'entitéGiftpar cet id et marqueIsUsed = true(ou décompte leRemainingValue) à la création du booking ; le cast évite de fabriquer unGiftcomplet (createDefault) alors que le reste des champs est ignoré côté backend.
- Type :
GiftCodeResponsedéclaré danstypes/extensions.ts, étendGiftde@spektrum/horizon-types(dont il hériteremainingValue) en surchargeantvalidUntil(string sur le wire,DatesurGift) etvalue(toujours présent ici), et en ajoutantstatus+isUsed(sur le wireGiftDtomais pas encore dans le package). Importé parservices/api.ts.
Invariants & règles spécifiques
- Bons à montant libre uniquement côté Buchard — il n'existe pas de bon « pour un voyage X ». Tous les bons cadeaux sont des montants en CHF appliqués sur n'importe quelle facture.
RemainingValue/IsUsed: un bon partiellement utilisé garde un solde reportable (RemainingValue, null = bon intact → on retombe survalue) ;IsUsed= bon entièrement consommé (le backendGetByCodefiltre déjà ces bons → réponse nulle → code affiché « invalide » côté mobile, doncisUsedn'arrive jamaistruesur une validation réussie). Le mobile déduit désormaisremainingValue ?? value, plafonné au sous-total suppléments globaux inclus (rebateCodeDiscount), et affiche le solde restant du bon après réservation (rebateCodeLeftover). L'idreste seul transmis au backend — c'est lui qui décompte réellement le solde.- Pas de bon en pourcentage :
GiftDto(HorizonGET /api/gifts/{code}) ne porte quevalue/remainingValue— un bon est toujours un montant CHF. Le typePERCENTde la chaîne de prix (ValueOrPercent) est un échafaudage pour de futurs codes promo (sémantiqueDiscountHorizon : % sur la base hors suppléments et early booking) — aucun émetteur côté UI aujourd'hui (TBPaymentRebateCode.vueforceVALUE). - Un seul bon à la fois : l'UI n'a qu'un seul champ de saisie ;
finalBooking.booking.giftsne contient donc jamais plus d'un élément. - Envoi automatique par email : pour les bons créés via web/mobile, mail auto. Pour les bons créés en back-office, pas d'envoi auto (mais ça n'impacte pas le mobile en lecture/usage).
- Création d'un bon cadeau depuis l'app mobile : pas implémentée à ce jour (uniquement consommation).
Dépendances
- Pas de dépendance entrante
- Consommé par :
booking/billing-payment(déduction au checkout)
Points d'attention
- Bien encoder le code via
encodeURIComponent(déjà fait danspublicApi.gifts.validate). - Le
statusnumérique deGiftCodeResponsen'est pas typé en enum — référer au backend pour la grille (GiftStatuscôté Horizon).
Contributors
No contributors
Changelog
No recent changes

