Files
lionsdev-client-impl-quarkus/src/main/java/dev/lions/roi/ROICalculator.java

257 lines
11 KiB
Java

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.<String, Double>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<String, ROIResult> calculateScenarios(ROIInput baseInput) {
Map<String, ROIResult> 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<String> 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<String> getSelectedModules() { return selectedModules; }
public void setSelectedModules(java.util.List<String> 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<String, Double> 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<String, Double> getGainsByCategory() { return gainsByCategory; }
public void setGainsByCategory(Map<String, Double> gainsByCategory) { this.gainsByCategory = gainsByCategory; }
}