Adrien Gras
Ateliers

Code métier

Calcul du solde total, balances entre utilisateurs (qui doit combien à qui) et affichage final.

Dans cet atelier, nous allons finaliser la partie fonctionnelle de notre application.

Gestion du compte total

Pour cette première partie, nous allons gérer la balance totale du portefeuille.

Astuce

Nous allons utiliser une méthode de gestion de la donnée efficace.

Pour obtenir le compte total de la balance, il y a deux méthodes :

  • Soit nous faisons la somme de toutes les dépenses à chaque fois que nous en avons besoin, à chaque affichage de la page par exemple.
  • Soit nous stockons la valeur du compte total dans la table Wallet et nous la mettons à jour à chaque ajout ou suppression de dépense.

La première méthode est simple à mettre en place, mais elle est très inefficace en termes de performance. En effet, si nous avons beaucoup de dépenses, faire la somme à chaque affichage peut ralentir considérablement l'application.

Nous allons donc utiliser la deuxième méthode, qui est plus performante. Nous allons stocker le compte total dans la table Wallet et le mettre à jour à chaque ajout ou suppression de dépense.

Consigne

  1. Dans le repository Wallet, ajoutez une méthode calculateTotalBalance(Wallet $wallet): int qui calcule la somme des montants de toutes les dépenses associées au portefeuille.
  2. Dans le service WalletService, ajoutez une méthode updateTotalBalance(Wallet $wallet): void qui utilise la méthode du repository pour calculer et mettre à jour le compte total du portefeuille.
    • Vous n'oublirez pas de persister les changements en base de données.
  3. Modifiez les méthodes d'ajout et de suppression de dépense dans le service ExpenseService pour appeler la méthode updateTotalBalance du WalletService après chaque opération.
  4. Ajoutez, dans le détail d'un portefeuille, l'affichage du compte total.
  5. Testez l'ajout et la suppression de dépenses pour vérifier que le compte total est correctement mis à jour.

Gestion des balances - Qui doit combien à qui

Dans cette partie, nous allons gérer les balances entre les différents utilisateurs d'un portefeuille partagé.

Nous allons faire ça en deux étapes :

  • Créer un bouton et son code pour marquer un portefeuille comme "réglé".
  • Afficher les balances entre les utilisateurs.

Consigne

Régler un portefeuille partagé

  1. Ajoutez un bouton "Marquer comme réglé" dans le détail d'un portefeuille partagé.
  2. Créez une méthode dans le WalletService markAsSettled(Wallet $wallet): void qui marque le portefeuille comme réglé. (mets la date de dernier règlement à maintenant)
  3. Créez le contrôleur et la route pour gérer cette action.
  4. Testez l'action en marquant un portefeuille comme réglé.

Afficher les balances entre utilisateurs

  1. Dans le repository Expense, créez une méthode findExpensesSinceLastSettlement(Wallet $wallet): array qui récupère toutes les dépenses d'un portefeuille depuis la dernière date de règlement.
  2. Dans le ExpenseService, ajoutez une méthode findExpensesSinceLastSettlement(Wallet $wallet): array qui utilise la méthode du repository pour récupérer les dépenses.
  3. Dans le WalletService, injectez le ExpenseService.
  4. Dans le WalletService, ajoutez une méthode getUserBalances(Wallet $wallet): array qui calcule les balances entre les utilisateurs du portefeuille.
    • La méthode doit retourner un tableau associatif de la forme ['user1' => ['user2' => amount, ...], ...] indiquant combien chaque utilisateur doit aux autres.
  5. Appelez cette méthode pour rafraichir les balances à chaque ajout ou suppression de dépense.
  6. Affichez les balances dans le détail du portefeuille partagé.
  7. Testez l'affichage des balances en ajoutant et supprimant des dépenses.

Astuce

Pour calculer les balances entre utilisateurs, vous pouvez vous inspirer de l'algorithme suivant :

FONCTION calculerBalances(portefeuille: Wallet) RETOURNE tableau
DEBUT
    // 1. Calculer le total des dépenses
    total = calculerTotal(portefeuille) // vous avez déjà cette fonction
    transactions = liste des transactions dans portefeuille depuis la dernière date de règlement (utilisez la méthode créée précédemment)

    // 2. Calculer la part équitable par utilisateur
    utilisateurs = liste unique des utilisateurs dans transactions
    nbUtilisateurs = taille(utilisateurs)
    partEquitable = total / nbUtilisateurs

    // 3. Calculer le solde de chaque utilisateur
    soldes = TABLEAU VIDE

    // 3.1 Initialiser les soldes à 0
    POUR CHAQUE utilisateur DANS utilisateurs
        soldes[utilisateur] = 0
    FIN POUR

    // 3.2 Calculer les soldes pour chaque utilisateur
    POUR CHAQUE transaction DANS transactions
        soldes[transaction.user] = soldes[transaction.user] + transaction.amount
    FIN POUR

    // 3.3 Ajuster les soldes par la part équitable
    POUR CHAQUE utilisateur DANS soldes
        soldes[utilisateur] = arrondir(soldes[utilisateur] - partEquitable, 2)
    FIN POUR

    // 4. Séparer créanciers et débiteurs
    créanciers = TABLEAU VIDE // ceux à qui on doit de l'argent
    débiteurs = TABLEAU VIDE   // ceux qui doivent de l'argent

    POUR CHAQUE utilisateur, solde DANS soldes
        SI solde > 0
            créanciers[utilisateur] = solde
        SINON SI solde < 0
            débiteurs[utilisateur] = valeur_absolue(solde) // utilisez abs()
        FIN SI
    FIN POUR

    // 5. Calculer les transferts
    transferts = TABLEAU VIDE

    TANT QUE créanciers n'est pas vide ET débiteurs n'est pas vide
        crediteur = premier élément de créanciers
        debiteur = premier élément de débiteurs
        montant = minimum(créanciers[crediteur], débiteurs[debiteur]) // utilisez min()

        // 5.1 Enregistrer le transfert
        transferts[debiteur][] = (crediteur, montant)

        // 5.2 Mettre à jour les montants restants
        créanciers[crediteur] = créanciers[crediteur] - montant
        débiteurs[debiteur] = débiteurs[debiteur] - montant

        // 5.3Retirer les utilisateurs dont le solde est réglé
        SI créanciers[crediteur] == 0
            supprimer crediteur de créanciers
        FIN SI
        SI débiteurs[debiteur] == 0
            supprimer debiteur de débiteurs
        FIN SI
    FIN TANT QUE

    RETOURNER transferts
FIN

Chemins métier

Ici pas de consigne, vous devez juste vous assurer que la navigation entre les différentes pages de l'application est fluide et intuitive.

Sur cette page