//------------------------------------------------------------------------------------------------------------------------------ public static void SetPourcentageFor(CBesoin besoin, ISatisfactionBesoin satisfaction, double fPourcentageSouhaité) { CImputationsCouts imputations = satisfaction.GetImputationsAFaireSurUtilisateursDeCout(); CImputationCout imputation = imputations.GetImputation(besoin); if (fPourcentageSouhaité < 100 && fPourcentageSouhaité >= 0) { if (imputations != null) { double fPoids = imputations.PoidsTotal - imputation.Poids; if (fPoids == 0) { return; } CListeObjetsDonnees lst = satisfaction.RelationsSatisfaits; lst.Filtre = new CFiltreData(CBesoin.c_champId + "=@1", besoin.Id); if (lst.Count != 0) { double fCalc = fPourcentageSouhaité / 100.0 * fPoids / (1 - fPourcentageSouhaité / 100.0); CRelationBesoin_Satisfaction rel = lst[0] as CRelationBesoin_Satisfaction; rel.RatioCoutReel = fCalc; } } } }
//------------------------------------------------------------------------------------------------------------------------------ public static double CalcImputationAFaireSur(IElementACout source, IElementACout utilisateur, bool bCoutReel) { if (source == null || source.Row.RowState == DataRowState.Detached || source.Row.RowState == DataRowState.Deleted || utilisateur == null || utilisateur.Row.RowState == DataRowState.Deleted || utilisateur.Row.RowState == DataRowState.Detached) { return(0); } CImputationsCouts imputations = source.GetImputationsAFaireSurUtilisateursDeCout(); return(imputations.GetCoutImputéeA(utilisateur, bCoutReel)); }
//-------------------------------------------------------------------------- public double GetCoutResume(bool bCoutReel) { Dictionary <IElementACout, bool> setElementToAPrendreEnCompte = new Dictionary <IElementACout, bool>(); FillSetElementsACoutPourResumeCout(bCoutReel, setElementToAPrendreEnCompte); Dictionary <IElementACout, CImputationsCouts> cacheImputations = new Dictionary <IElementACout, CImputationsCouts>(); //On a tous les besoins dans un hashet, maintenant, il faut sommer les couts double fCout = 0; foreach (KeyValuePair <IElementACout, bool> kv in setElementToAPrendreEnCompte) { if (kv.Value) { IElementACout element = kv.Key; if (element is CBesoin) { bool bSourceInSet = false; foreach (IElementACout elt in element.GetSourcesDeCout(bCoutReel)) { if (setElementToAPrendreEnCompte.ContainsKey(elt)) { bSourceInSet = true; break; } } if (!bSourceInSet) { fCout += bCoutReel ? element.CoutReel : element.CoutPrevisionnel; } else { foreach (IElementACout source in element.GetSourcesDeCout(bCoutReel)) { if (!setElementToAPrendreEnCompte.ContainsKey(source)) //Si la source est dans le set, elle sera ajoutée, donc on ne la prend pas { CImputationsCouts imputations = null; if (!cacheImputations.TryGetValue(source, out imputations)) { imputations = source.GetImputationsAFaireSurUtilisateursDeCout(); cacheImputations[source] = imputations; } fCout += imputations.GetCoutImputéeA(element, bCoutReel); } } } } } } return(fCout); }
//--------------------------------------------- public CImputationsCouts GetImputationsAFaireSurUtilisateursDeCout() { CImputationsCouts imputations = new CImputationsCouts(this); foreach (CRelationBesoin_Satisfaction rel in RelationsSatisfaits) { imputations.AddImputation(rel.Besoin, rel.RatioCoutReelApplique, rel); } if (Projet != null && Projet.Row.RowState != DataRowState.Deleted) { imputations.AddImputation(Projet, imputations.PoidsTotal == 0 ? 1 : 0, null); } return(imputations); }
//------------------------------------------------------------------------------------------------------------------------------ public static double GetPourcentageFor(CBesoin besoin, ISatisfactionBesoin satisfaction) { CImputationsCouts imputations = satisfaction.GetImputationsAFaireSurUtilisateursDeCout(); CImputationCout imputation = imputations.GetImputation(besoin); if (imputations == null) { return(0); } if (imputations.PoidsTotal > 0) { return(imputation.Poids / imputations.PoidsTotal * 100); } return(0); }
//------------------------------------------------------------------------------------------------------------------------------ public static void FillSetUtilisateurs(IElementACout elementACout, HashSet <IElementACout> set, params IElementACout[] stopOn) { if (set.Contains(elementACout)) { return; } set.Add(elementACout); if (stopOn.Length > 0 && stopOn.Contains(elementACout)) { return; } CImputationsCouts imputations = elementACout.GetImputationsAFaireSurUtilisateursDeCout(); foreach (CImputationCout imput in imputations.Imputations) { IElementACout elt = imput.UtilisateurDeCout; if (elt != null && elt.Row.RowState != DataRowState.Deleted && elt.Row.RowState != DataRowState.Detached) { FillSetUtilisateurs(elt, set, stopOn); } } }
//------------------------------------------------------------------------------------------------------------------------------ private static void RecalcCoutMontant(IElementACout source, bool bCoutReel, HashSet <DataRow> setDejaRecalcules) { if (source == null) { return; } if (setDejaRecalcules.Contains(source.Row.Row)) { return; } setDejaRecalcules.Add(source.Row.Row); if (source.Row.RowState == DataRowState.Deleted || source.Row.RowState == DataRowState.Detached) { source.VersionToReturn = DataRowVersion.Original; } CImputationsCouts imputations = source.GetImputationsAFaireSurUtilisateursDeCout(); HashSet <IElementACout> elementsModifies = new HashSet <IElementACout>(); CValeursImputées newValeurs = GetValeursImputéesSurUtilisateurs(source); newValeurs.Reset(bCoutReel); CValeursImputées oldValeurs = GetValeursImputéesSurUtilisateurs(source); HashSet <string> newElementsImputes = new HashSet <string>(); if (source.Row.RowState != DataRowState.Deleted && source.Row.RowState != DataRowState.Deleted) { if (!source.IsCoutFromSources(bCoutReel)) { double fCout = source.CalculeTonCoutPuisqueTuNeCalculePasAPartirDesSourcesDeCout(bCoutReel); source.SetCoutSansCalculDesParents(fCout, bCoutReel); SetValeurImputéeDeSource(source, source, bCoutReel ? source.CoutReel : source.CoutPrevisionnel, bCoutReel); newValeurs.SetImputation(source, bCoutReel ? source.CoutReel : source.CoutPrevisionnel, bCoutReel); newElementsImputes.Add(source.IdUniversel); } } foreach (CImputationCout imputation in imputations.Imputations) { newElementsImputes.Add(imputation.UtilisateurDeCout.IdUniversel); IElementACout utilisateur = imputation.UtilisateurDeCout; if (utilisateur.Row.RowState == DataRowState.Deleted || utilisateur.Row.RowState == DataRowState.Deleted) { newValeurs.SetImputation(utilisateur, 0, bCoutReel); } else { double fOld = oldValeurs.GetImputation(utilisateur, bCoutReel); double fNew = 0; if (source.Row.RowState != DataRowState.Deleted && source.Row.RowState != DataRowState.Detached) { fNew = source.CalcImputationAFaireSur(utilisateur, bCoutReel); } if (Math.Abs(fOld - fNew) > 0.01) { elementsModifies.Add(utilisateur); setDejaRecalcules.Remove(utilisateur.Row.Row); double fVal = bCoutReel ? utilisateur.CoutReel : utilisateur.CoutPrevisionnel; fVal -= fOld; fVal += fNew; utilisateur.SetCoutSansCalculDesParents(fVal, bCoutReel); SetValeurImputéeDeSource(utilisateur, source, fNew, bCoutReel); } newValeurs.SetImputation(utilisateur, fNew, bCoutReel); } CUtilElementACout.SetValeursImputéesSurUtilisateurs(source, newValeurs); } //Enlève les valeurs qui ont été imputées sur des éléments qui ne sont plus imputés foreach (IElementACout utilisateur in oldValeurs.GetObjetsImputés(source.ContexteDonnee)) { if (!newElementsImputes.Contains(utilisateur.IdUniversel)) { //On avait imputé ce type, mais il ne faut plus //Vérifie que le coût de cet utilisateur intègre bien mon cout CValeursImputées valeurs = GetValeursImputéesDeSources(utilisateur); if (valeurs.ContainsElement(source, bCoutReel)) { double fImput = oldValeurs.GetImputation(utilisateur, bCoutReel); if (fImput > 0.001) { elementsModifies.Add(utilisateur); setDejaRecalcules.Remove(utilisateur.Row.Row); double fVal = bCoutReel ? utilisateur.CoutReel : utilisateur.CoutPrevisionnel; fVal -= fImput; utilisateur.SetCoutSansCalculDesParents(fVal, bCoutReel); SetValeurImputéeDeSource(utilisateur, source, 0, bCoutReel); } } } } if (source.Row.RowState != DataRowState.Deleted && source.Row.RowState != DataRowState.Detached) { source.TypesCoutsParentsARecalculer &= bCoutReel ? ~ETypeCout.réel : ~ETypeCout.Prévisionnel; } foreach (IElementACout eltModif in elementsModifies) { RecalcCoutMontant(eltModif, bCoutReel, setDejaRecalcules); } }
//------------------------------------------------------------------------------------------------------------------------------ public static CResultAErreur RecalculeCoutsDescendants(IEnumerable <IElementACout> elements, bool bCoutReel, bool bRecursif, IIndicateurProgression indicateurDeProgression) { CConteneurIndicateurProgression indicateur = CConteneurIndicateurProgression.GetConteneur(indicateurDeProgression); indicateur.CanCancel = true; CResultAErreur result = CResultAErreur.True; Dictionary <IElementACout, IElementACout[]> elementsToSources = new Dictionary <IElementACout, IElementACout[]>(); Dictionary <IElementACout, CImputationsCouts> dicImputations = new Dictionary <IElementACout, CImputationsCouts>(); foreach (IElementACout elt in elements) { FillDicSources(bCoutReel, elt, bRecursif, elementsToSources); } HashSet <IElementACout> setRecalcules = new HashSet <IElementACout>(); List <IElementACout> elementsACalculer = new List <IElementACout>(); if (bRecursif) { foreach (IElementACout elt in elementsToSources.Keys) { elementsACalculer.Add(elt); } } else { elementsACalculer.AddRange(elements); } indicateur.SetBornesSegment(0, elementsACalculer.Count()); int nNbFaits = 0; try { while (elementsACalculer.Count > 0) { if (indicateur.CancelRequest) { result.EmpileErreur(I.T("Operation cancelled|20184")); return(result); } List <IElementACout> prochaineGeneration = new List <IElementACout>(); foreach (IElementACout elt in elementsACalculer) { //Vérifie qu'il est possible de calculer cet élément IElementACout[] sources = elementsToSources[elt]; bool bCanCalcul = !elt.IsCoutFromSources(bCoutReel); if (!bCanCalcul) { bCanCalcul = true; foreach (IElementACout source in sources) { if (!setRecalcules.Contains(source) && elementsToSources.ContainsKey(source)) { bCanCalcul = false; break; } } } if (bCanCalcul) { nNbFaits++; indicateur.SetValue(nNbFaits); indicateur.SetInfo(elt.Libelle); setRecalcules.Add(elt); double fCout = 0; if (elt.ShouldAjouterCoutPropreAuCoutDesSource(bCoutReel) && elt.IsCoutFromSources(bCoutReel)) { AffecteValeurCalcSansSourcesToElement(elt, bCoutReel); fCout = bCoutReel ? elt.CoutReel : elt.CoutPrevisionnel; } CValeursImputées valeursDeSources = GetValeursImputéesDeSources(elt); valeursDeSources.Reset(bCoutReel); if (elt.IsCoutFromSources(bCoutReel)) { foreach (IElementACout source in sources) { CImputationsCouts imputations = null; if (!dicImputations.TryGetValue(source, out imputations)) { imputations = source.GetImputationsAFaireSurUtilisateursDeCout(); dicImputations[source] = imputations; } if (imputations != null) { double fImput = imputations.GetCoutImputéeA(elt, bCoutReel); fCout += fImput; SetValeurImputéeSurUtilisateur(source, elt, fImput, bCoutReel); valeursDeSources.SetImputation(source, fImput, bCoutReel); } } elt.SetCoutSansCalculDesParents(fCout, bCoutReel); OnChangeCoutSansCalculCoutDescendant(elt, bCoutReel, false); SetValeursImputéesDeSources(elt, valeursDeSources); } else { AffecteValeurCalcSansSourcesToElement(elt, bCoutReel); } } else { prochaineGeneration.Add(elt); } } if (prochaineGeneration.Count == elementsACalculer.Count)//On n'a rien fait, c'est la cata { result.EmpileErreur(I.T("Can not calculate cost. Cyclic redundancy error|20182")); return(result); } elementsACalculer = prochaineGeneration; if (!bRecursif) { break; } } } finally { } return(result); }