Intégrations de la caisse v2

Intégration avec le backend

API REST

PointOfSaleApiService

Endpoints utilisés :

  • getPosData(hostname: string, date: DateTime)

    • Récupère les données complètes du point de vente
    • Retourne : PosData (territoire, entreprise, cinéma, POS, produits, séances)
    • Utilisé lors du démarrage de la caisse
  • open(args: PosOpenAction)

    • Ouvre une session de caisse
    • Paramètres : { posId, cashDrawerAmount }
    • Retourne : { isSync: boolean, basket: PosBasket }
    • Mode synchrone uniquement (mode asynchrone déprécié)
  • close(args: PosCloseAction)

    • Ferme une session de caisse
    • Paramètres : { posId, cashCounts, telecollecteData }
    • Retourne : Réponse de fermeture

PosBasketApiService

Endpoints utilisés :

  • persist(params: PosBasketPersistParams)
    • Sauvegarde un panier
    • Paramètres : { pointOfSaleId, posSessionId, posBasketId, item, finalize }
    • Retourne : OperationResponseWithBasket
    • Mode synchrone ou asynchrone selon finalize
    • Si finalize: true, envoie également un message Kafka cineges.posbasket.finalize.action

PosSessionApiService

Endpoints utilisés :

  • getById(id: string)

    • Récupère une session par son ID
    • Retourne : PosSession
  • getById(id: string) (avec stats)

    • Récupère une session avec statistiques
    • Retourne : PosSessionWithStats
  • getBankDepositSlip(sessionId: string)

    • Génère le bordereau de remise en banque
    • Retourne : { pdfBase64: string }
  • printBankDepositSlip(params: { sessionId: string })

    • Imprime le bordereau de remise
    • Utilise le hardware proxy pour l’impression

Communication synchrone vs asynchrone

Mode synchrone

Utilisé pour :

  • Ouverture de session (PointOfSaleApiService.open())
  • Persistance du panier pendant la composition (PosBasketApiService.persist() avec finalize: false)
  • Fermeture de session (PointOfSaleApiService.close())

Avantages :

  • Retour immédiat
  • Gestion d’erreur simple
  • Pas de complexité de synchronisation

Mode asynchrone

Utilisé pour :

  • Finalisation du panier côté Odoo (via Kafka)

Flux :

  1. Frontend appelle persist() avec finalize: true
  2. Backend valide et enregistre le panier
  3. Backend envoie un message Kafka cineges.posbasket.finalize.action
  4. Backend retourne immédiatement au frontend
  5. Un job Kafka traite la finalisation Odoo en arrière-plan

Avantages :

  • Pas d’attente pour l’utilisateur
  • Traitement Odoo peut prendre du temps sans bloquer l’interface

Intégration avec Kafka

Notifications en temps réel

KafkaNotifService

Service utilisé pour s’abonner aux notifications Kafka.

Abonnements :

  • Territoire : { type: "territory", id: territoryId }

    • Mise à jour automatique des données du territoire
    • Utilisé pour les changements de configuration (arrondis, devise, etc.)
  • Entreprise : { type: "company", id: companyId }

    • Mise à jour automatique des données de l’entreprise
  • Cinéma : { type: "cinema", id: cinemaId }

    • Mise à jour automatique des données du cinéma
  • Point de vente : { type: "pos", id: posId }

    • Mise à jour automatique des données du POS
    • Utilisé pour les changements d’état (ouvert/fermé)

Gestion des mises à jour :

  private knotUpdateTerritory(notif: ItemTypeIdNotif<Territory>) {
    if (this.posData?.territory?.id !== notif.id) {
      return;
    }

    const oldItem = JSON.parse(JSON.stringify(this.posData.territory)) as Territory;
    const patch = compare(oldItem, notif.item);
    this.logger.debug(`caisseService: territory changed: ${patch}`);

    this.posData.territory = notif.item;
    this.posDataChange.emit(this.posData);
  }

Les mises à jour utilisent fast-json-patch pour détecter les changements et appliquer uniquement les modifications nécessaires.

Messages Kafka émis

cineges.posbasket.finalize.action

Message envoyé lors de la finalisation d’un panier.

Contenu :

  • ID du panier
  • Données complètes du panier
  • Métadonnées de finalisation

Traitement :

  • Un job Kafka consomme ce message
  • Création du panier dans Odoo
  • Mise à jour du statut de finalisation

Intégration avec le hardware

HwProxyService

Service proxy pour l’accès au matériel via @hardware/hwproxy.

Imprimante ESC/POS

Fonctionnalités :

  • Impression des tickets de caisse
  • Impression des billets
  • Impression des bordereaux de remise

Utilisation :

const printImages = await this.convertPrintablesToImages(printables);
await modalComponent.print(printImages);

Conversion en images : Les tickets HTML sont convertis en images PNG via html2canvas avant l’impression.

Tiroir caisse

Fonctionnalités :

  • Ouverture automatique lors des paiements en espèce
  • Ouverture lors de l’ouverture de session
  • Ouverture lors de la fermeture de session

Utilisation :

const firstDevice = this.hwproxy.escpos.status().devices[0];
await this.hwproxy.escpos.openCashDrawer(firstDevice.path);

Terminal de paiement (TPE)

Fonctionnalités :

  • Initiation de transactions
  • Gestion des différents types de cartes
  • Récupération des réponses du terminal

Utilisation :

const payTpeResult = await PayTpeModalComponent.show(
  this.modalService,
  totalRemaining,
  posData,
  methodRequested,
  methodAvailable
);

Gestion de la connexion

Vérification de la connexion :

if (this.hwproxy.isConnected) {
  // Hardware disponible
} else {
  // Attendre la connexion
  this.hwproxy.isConnectedChange.subscribe((connected) => {
    if (connected) {
      // Continuer le démarrage
    }
  });
}

Intégration avec ElasticSearch

Stockage des paniers

Les paniers sont stockés dans ElasticSearch pour :

  • Persistance des paniers en cours
  • Historique des ventes
  • Recherche et analyse

Index : posbasket

Opérations :

  • persist() : Sauvegarde/ mise à jour d’un panier
  • Recherche par session, date, utilisateur, etc.

Intégration avec Odoo

Finalisation asynchrone

La finalisation du panier dans Odoo se fait de manière asynchrone :

  1. Frontend finalise le panier via persist() avec finalize: true
  2. Backend enregistre le panier dans ElasticSearch
  3. Backend envoie un message Kafka cineges.posbasket.finalize.action
  4. Un job Kafka consomme le message
  5. Le job crée le panier dans Odoo
  6. Le job met à jour le statut de finalisation

Avantages :

  • Pas de blocage de l’interface utilisateur
  • Possibilité de retry en cas d’échec
  • Traçabilité via Kafka

Données synchronisées

  • Produits et prix
  • Taxes
  • Sessions de caisse
  • Paniers finalisés

Gestion des erreurs

Erreurs réseau

Gestion :

  • Retry automatique pour les erreurs temporaires
  • Affichage d’un message d’erreur à l’utilisateur
  • Logging des erreurs pour le debugging

Erreurs de validation

Gestion :

  • Validation côté backend avant persistance
  • Retour des erreurs de validation dans OperationResponseWithBasket.validationError
  • Affichage des erreurs dans le modal de finalisation

Erreurs matériel

Gestion :

  • Vérification de la disponibilité du matériel avant utilisation
  • Messages d’erreur explicites
  • Possibilité de forcer certains paiements en cas d’erreur matérielle