//------------------------------------------------------------------------------------------------------------------------------ private static void AffecteValeurCalcSansSourcesToElement(IElementACout element, bool bCoutReel) { if (element == null) { return; } double fCout = element.CalculeTonCoutPuisqueTuNeCalculePasAPartirDesSourcesDeCout(bCoutReel); element.SetCoutSansCalculDesParents(fCout, bCoutReel); CValeursImputées valeurs = GetValeursImputéesDeSources(element); valeurs.Reset(bCoutReel); valeurs.SetImputation(element, fCout, bCoutReel); SetValeurImputéeSurUtilisateur(element, element, fCout, bCoutReel); }
//------------------------------------------------------------------------------------------------------------------------------ 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); }