Skip to content

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 :
    1. code et 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, champ amount), consommés par la chaîne de prix (useBCPricingcomputeBookingPricing, 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. ».
    2. id (le GiftCodeResponse.id) est stocké dans le même scope (rebateCode.giftId), exposé par useBCPricing via appliedGiftId, puis injecté dans finalBooking.booking.gifts (stores/bookingConstructor.ts) sous la forme [{ id } as Gift] avant l'appel à paymentApi.initialize. Seul id est envoyé — le backend re-fetch l'entité Gift par cet id et marque IsUsed = true (ou décompte le RemainingValue) à la création du booking ; le cast évite de fabriquer un Gift complet (createDefault) alors que le reste des champs est ignoré côté backend.
  • Type : GiftCodeResponse déclaré dans types/extensions.ts, étend Gift de @spektrum/horizon-types (dont il hérite remainingValue) en surchargeant validUntil (string sur le wire, Date sur Gift) et value (toujours présent ici), et en ajoutant status + isUsed (sur le wire GiftDto mais pas encore dans le package). Importé par services/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 sur value) ; IsUsed = bon entièrement consommé (le backend GetByCode filtre déjà ces bons → réponse nulle → code affiché « invalide » côté mobile, donc isUsed n'arrive jamais true sur une validation réussie). Le mobile déduit désormais remainingValue ?? value, plafonné au sous-total suppléments globaux inclus (rebateCodeDiscount), et affiche le solde restant du bon après réservation (rebateCodeLeftover). L'id reste seul transmis au backend — c'est lui qui décompte réellement le solde.
  • Pas de bon en pourcentage : GiftDto (Horizon GET /api/gifts/{code}) ne porte que value/remainingValue — un bon est toujours un montant CHF. Le type PERCENT de la chaîne de prix (ValueOrPercent) est un échafaudage pour de futurs codes promo (sémantique Discount Horizon : % sur la base hors suppléments et early booking) — aucun émetteur côté UI aujourd'hui (TBPaymentRebateCode.vue force VALUE).
  • Un seul bon à la fois : l'UI n'a qu'un seul champ de saisie ; finalBooking.booking.gifts ne 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 dans publicApi.gifts.validate).
  • Le status numérique de GiftCodeResponse n'est pas typé en enum — référer au backend pour la grille (GiftStatus côté Horizon).

Contributors

No contributors

Changelog

No recent changes