chore(quarkus-327): bump to Quarkus 3.27.3 LTS, rename quarkus-resteasy-reactive → quarkus-rest, fix testGetAuditQuestions map vs list, rename deprecated config keys
This commit is contained in:
256
src/main/java/dev/lions/roi/ROICalculator.java
Normal file
256
src/main/java/dev/lions/roi/ROICalculator.java
Normal file
@@ -0,0 +1,256 @@
|
||||
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; }
|
||||
}
|
||||
Reference in New Issue
Block a user