package dev.lions.roi; import jakarta.enterprise.context.ApplicationScoped; import java.util.Map; import java.util.HashMap; /** * Calculateur de ROI pour démontrer la valeur de la digitalisation */ @ApplicationScoped public class ROICalculator { /** * Calcule le ROI basé sur les gains de productivité */ public ROIResult calculateROI(ROIInput input) { ROIResult result = new ROIResult(); // Calculs des gains annuels double productivityGains = calculateProductivityGains(input); double errorReduction = calculateErrorReduction(input); double timesSavings = calculateTimeSavings(input); double complianceGains = calculateComplianceGains(input); double totalAnnualGains = productivityGains + errorReduction + timesSavings + complianceGains; // Coûts double implementationCost = input.getInvestmentAmount(); double annualMaintenanceCost = implementationCost * 0.15; // 15% par an // ROI sur 3 ans double totalGains3Years = totalAnnualGains * 3; double totalCosts3Years = implementationCost + (annualMaintenanceCost * 3); double roi3Years = ((totalGains3Years - totalCosts3Years) / totalCosts3Years) * 100; // Période de retour sur investissement double paybackPeriod = implementationCost / totalAnnualGains; // Remplissage du résultat result.setAnnualProductivityGains(productivityGains); result.setAnnualErrorReduction(errorReduction); result.setAnnualTimeSavings(timesSavings); result.setAnnualComplianceGains(complianceGains); result.setTotalAnnualGains(totalAnnualGains); result.setImplementationCost(implementationCost); result.setAnnualMaintenanceCost(annualMaintenanceCost); result.setRoi3Years(roi3Years); result.setPaybackPeriodMonths(paybackPeriod * 12); result.setNetPresentValue3Years(totalGains3Years - totalCosts3Years); // Détails par catégorie result.setGainsByCategory(Map.of( "Productivité", productivityGains, "Réduction erreurs", errorReduction, "Gain de temps", timesSavings, "Conformité", complianceGains )); return result; } private double calculateProductivityGains(ROIInput input) { // Gain de productivité basé sur l'automatisation double baseProductivity = input.getEmployeeCount() * input.getAverageSalary() * 0.12; // 12% de gain // Ajustement selon les modules double multiplier = 1.0; if (input.getSelectedModules().contains("CRM")) multiplier += 0.15; if (input.getSelectedModules().contains("STOCK")) multiplier += 0.10; if (input.getSelectedModules().contains("COMPTA")) multiplier += 0.08; if (input.getSelectedModules().contains("RH")) multiplier += 0.05; return baseProductivity * multiplier; } private double calculateErrorReduction(ROIInput input) { // Réduction des erreurs et reprises double currentErrorCost = input.getTurnover() * 0.02; // 2% du CA en erreurs double reductionRate = 0.70; // 70% de réduction des erreurs return currentErrorCost * reductionRate; } private double calculateTimeSavings(ROIInput input) { // Gain de temps sur les tâches administratives double adminTimeHours = input.getEmployeeCount() * 2 * 250; // 2h/jour/employé, 250 jours/an double hourlyRate = input.getAverageSalary() / (8 * 250); // Taux horaire double timeSavingRate = 0.40; // 40% de gain de temps return adminTimeHours * hourlyRate * timeSavingRate; } private double calculateComplianceGains(ROIInput input) { // Évitement des pénalités et amendes double potentialFines = 500000; // 500K FCFA de pénalités potentielles par an double complianceImprovement = 0.80; // 80% d'amélioration de la conformité return potentialFines * complianceImprovement; } /** * Génère des recommandations basées sur le ROI */ public String generateRecommendations(ROIResult result) { StringBuilder recommendations = new StringBuilder(); if (result.getRoi3Years() > 200) { recommendations.append("🚀 ROI EXCELLENT (>200%) : Investissement hautement recommandé !\n\n"); } else if (result.getRoi3Years() > 100) { recommendations.append("✅ ROI TRÈS BON (>100%) : Investissement très rentable.\n\n"); } else if (result.getRoi3Years() > 50) { recommendations.append("👍 ROI CORRECT (>50%) : Investissement rentable à moyen terme.\n\n"); } else { recommendations.append("⚠️ ROI FAIBLE (<50%) : Revoir la configuration ou étaler l'investissement.\n\n"); } recommendations.append("POINTS CLÉS :\n"); recommendations.append(String.format("• Retour sur investissement en %.1f mois\n", result.getPaybackPeriodMonths())); recommendations.append(String.format("• Gains annuels : %,.0f FCFA\n", result.getTotalAnnualGains())); recommendations.append(String.format("• Bénéfice net sur 3 ans : %,.0f FCFA\n", result.getNetPresentValue3Years())); recommendations.append("\nPRIORITÉS D'IMPLÉMENTATION :\n"); // Recommandations par gain le plus élevé result.getGainsByCategory().entrySet().stream() .sorted(Map.Entry.comparingByValue().reversed()) .forEach(entry -> { recommendations.append(String.format("• %s : %,.0f FCFA/an\n", entry.getKey(), entry.getValue())); }); return recommendations.toString(); } /** * Calcule le ROI pour différents scénarios */ public Map calculateScenarios(ROIInput baseInput) { Map scenarios = new HashMap<>(); // Scénario conservateur (gains -30%) ROIInput conservative = baseInput.copy(); conservative.setAverageSalary(baseInput.getAverageSalary() * 0.7); scenarios.put("Conservateur", calculateROI(conservative)); // Scénario réaliste (base) scenarios.put("Réaliste", calculateROI(baseInput)); // Scénario optimiste (gains +50%) ROIInput optimistic = baseInput.copy(); optimistic.setAverageSalary(baseInput.getAverageSalary() * 1.5); scenarios.put("Optimiste", calculateROI(optimistic)); return scenarios; } } /** * Données d'entrée pour le calcul ROI */ class ROIInput { private int employeeCount; private double averageSalary; // Salaire moyen annuel private double turnover; // CA annuel private double investmentAmount; // Montant investissement private java.util.List selectedModules; private String sector; // Constructeurs public ROIInput() {} public ROIInput copy() { ROIInput copy = new ROIInput(); copy.employeeCount = this.employeeCount; copy.averageSalary = this.averageSalary; copy.turnover = this.turnover; copy.investmentAmount = this.investmentAmount; copy.selectedModules = new java.util.ArrayList<>(this.selectedModules); copy.sector = this.sector; return copy; } // Getters et Setters public int getEmployeeCount() { return employeeCount; } public void setEmployeeCount(int employeeCount) { this.employeeCount = employeeCount; } public double getAverageSalary() { return averageSalary; } public void setAverageSalary(double averageSalary) { this.averageSalary = averageSalary; } public double getTurnover() { return turnover; } public void setTurnover(double turnover) { this.turnover = turnover; } public double getInvestmentAmount() { return investmentAmount; } public void setInvestmentAmount(double investmentAmount) { this.investmentAmount = investmentAmount; } public java.util.List getSelectedModules() { return selectedModules; } public void setSelectedModules(java.util.List selectedModules) { this.selectedModules = selectedModules; } public String getSector() { return sector; } public void setSector(String sector) { this.sector = sector; } } /** * Résultat du calcul ROI */ class ROIResult { private double annualProductivityGains; private double annualErrorReduction; private double annualTimeSavings; private double annualComplianceGains; private double totalAnnualGains; private double implementationCost; private double annualMaintenanceCost; private double roi3Years; private double paybackPeriodMonths; private double netPresentValue3Years; private Map gainsByCategory; // Constructeurs public ROIResult() {} // Getters et Setters public double getAnnualProductivityGains() { return annualProductivityGains; } public void setAnnualProductivityGains(double annualProductivityGains) { this.annualProductivityGains = annualProductivityGains; } public double getAnnualErrorReduction() { return annualErrorReduction; } public void setAnnualErrorReduction(double annualErrorReduction) { this.annualErrorReduction = annualErrorReduction; } public double getAnnualTimeSavings() { return annualTimeSavings; } public void setAnnualTimeSavings(double annualTimeSavings) { this.annualTimeSavings = annualTimeSavings; } public double getAnnualComplianceGains() { return annualComplianceGains; } public void setAnnualComplianceGains(double annualComplianceGains) { this.annualComplianceGains = annualComplianceGains; } public double getTotalAnnualGains() { return totalAnnualGains; } public void setTotalAnnualGains(double totalAnnualGains) { this.totalAnnualGains = totalAnnualGains; } public double getImplementationCost() { return implementationCost; } public void setImplementationCost(double implementationCost) { this.implementationCost = implementationCost; } public double getAnnualMaintenanceCost() { return annualMaintenanceCost; } public void setAnnualMaintenanceCost(double annualMaintenanceCost) { this.annualMaintenanceCost = annualMaintenanceCost; } public double getRoi3Years() { return roi3Years; } public void setRoi3Years(double roi3Years) { this.roi3Years = roi3Years; } public double getPaybackPeriodMonths() { return paybackPeriodMonths; } public void setPaybackPeriodMonths(double paybackPeriodMonths) { this.paybackPeriodMonths = paybackPeriodMonths; } public double getNetPresentValue3Years() { return netPresentValue3Years; } public void setNetPresentValue3Years(double netPresentValue3Years) { this.netPresentValue3Years = netPresentValue3Years; } public Map getGainsByCategory() { return gainsByCategory; } public void setGainsByCategory(Map gainsByCategory) { this.gainsByCategory = gainsByCategory; } }