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
- Dans le repository Wallet, ajoutez une méthode
calculateTotalBalance(Wallet $wallet): intqui calcule la somme des montants de toutes les dépenses associées au portefeuille. - Dans le service WalletService, ajoutez une méthode
updateTotalBalance(Wallet $wallet): voidqui 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.
- Modifiez les méthodes d'ajout et de suppression de dépense dans le service ExpenseService pour appeler la méthode
updateTotalBalancedu WalletService après chaque opération. - Ajoutez, dans le détail d'un portefeuille, l'affichage du compte total.
- 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é
- Ajoutez un bouton "Marquer comme réglé" dans le détail d'un portefeuille partagé.
- Créez une méthode dans le WalletService
markAsSettled(Wallet $wallet): voidqui marque le portefeuille comme réglé. (mets la date de dernier règlement à maintenant) - Créez le contrôleur et la route pour gérer cette action.
- Testez l'action en marquant un portefeuille comme réglé.
Afficher les balances entre utilisateurs
- Dans le repository Expense, créez une méthode
findExpensesSinceLastSettlement(Wallet $wallet): arrayqui récupère toutes les dépenses d'un portefeuille depuis la dernière date de règlement. - Dans le ExpenseService, ajoutez une méthode
findExpensesSinceLastSettlement(Wallet $wallet): arrayqui utilise la méthode du repository pour récupérer les dépenses. - Dans le WalletService, injectez le ExpenseService.
- Dans le WalletService, ajoutez une méthode
getUserBalances(Wallet $wallet): arrayqui 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.
- La méthode doit retourner un tableau associatif de la forme
- Appelez cette méthode pour rafraichir les balances à chaque ajout ou suppression de dépense.
- Affichez les balances dans le détail du portefeuille partagé.
- 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
FINChemins 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.