Esempio n. 1
0
        //-------------------------------------------------------------------------
        protected override CResultAErreur MAJ_Champs()
        {
            CResultAErreur result = base.MAJ_Champs();

            result = m_panelSaisie.Maj_Champs();

            EvenementAttribute.StockeDeclenchement(Acteur, CActeur.c_evenementValidationFicheActivite);

            return(result);
        }
        /// <summary>
        /// /////////////////////////////////////////////////////////////////////////////////
        /// </summary>
        /// <param name="table"></param>
        /// <param name="result"></param>
        ///
        private static CResultAErreur TraitementAvantSauvegardeExterne(CContexteDonnee contexte, Hashtable tableData)
        {
            CResultAErreur result = CResultAErreur.True;

            ///Stef 22/07/08 : l'appel à shouldDeclenche peut
            ///nécessiter GetValeurChamp (si conditions sur des champs). Or, si un élément n'a pas
            ///de valeur pour un champ, l'appli va aller chercher la valeur par défaut de ce
            ///champ, si le champ n'est pas chargé, l'appli va le lire. Comme on est souvent
            ///dans un contexte sans gestion par tables complètes, on est mal, parce que
            ///ça va génerer une requête par champ.
            ///Donc, on lit tous les champs custom avant de commencer
            CListeObjetsDonnees listeChamps = new CListeObjetsDonnees(contexte, typeof(CChampCustom));

            listeChamps.PreserveChanges = true;            //Pour ne pas modifier les champs modifiés
            listeChamps.AssureLectureFaite();

            DateTime dt = DateTime.Now;
            CTraitementApresSauvegarde traitement = new CTraitementApresSauvegarde( );

            ArrayList lstTables = CContexteDonnee.GetTablesOrderInsert(contexte);

            //Pour empêcher de regarder deux fois les évenements d'un même objet
            //Type->Dictionnaire des ids vus
            Dictionary <Type, Dictionary <int, bool> > elementsVus = new Dictionary <Type, Dictionary <int, bool> >();

            DataRowChangeEventHandler handlerRedo = new DataRowChangeEventHandler(table_RowChanged);

            Dictionary <string, Dictionary <int, bool> > listeElementsARepasser = null;

            if (!m_listeElementsARepasser.TryGetValue(contexte, out listeElementsARepasser))
            {
                listeElementsARepasser             = new Dictionary <string, Dictionary <int, bool> >();
                m_listeElementsARepasser[contexte] = listeElementsARepasser;
            }

            bool bFirstPasse     = true;
            int  nLimiteurPasses = 0;

            while ((bFirstPasse | listeElementsARepasser.Count > 0) && nLimiteurPasses < 5)
            {
                nLimiteurPasses++;

                foreach (DataTable table in lstTables)
                {
                    if (table.Rows.Count > 0 && table.PrimaryKey.Length == 1)
                    {
                        string strChampCle = table.PrimaryKey[0].ColumnName;

                        Type tpObjets = CContexteDonnee.GetTypeForTable(table.TableName);
                        if (!typeof(CObjetDonneeAIdNumerique).IsAssignableFrom(tpObjets))
                        {
                            continue;
                        }

                        Type typeOriginal = tpObjets;

                        //Lors de la modif de champs custom, l'élement parent n'est pas forcement modifié
                        //Mais le champ peut l'être
                        if (tpObjets.IsSubclassOf(typeof(CRelationElementAChamp_ChampCustom)))
                        {
                            int  nLigne = 0;
                            bool bGoOut = false;
                            while (table.Rows.Count > nLigne && !bGoOut)
                            {
                                if (table.Rows[nLigne].RowState != DataRowState.Deleted)
                                {
                                    CRelationElementAChamp_ChampCustom rel = (CRelationElementAChamp_ChampCustom)contexte.GetNewObjetForRow(table.Rows[nLigne]);
                                    tpObjets    = rel.ElementAChamps.GetType();
                                    strChampCle = ((CObjetDonnee)rel.ElementAChamps).GetChampsId()[0];
                                    bGoOut      = true;
                                }
                                nLigne++;
                            }
                        }

                        //Les objets qui n'ont pas de relationTypeId ne peuvent pas avoir d'évenements
                        if (tpObjets.GetCustomAttributes(typeof(NoRelationTypeIdAttribute), true).Length > 0)
                        {
                            continue;
                        }

                        ArrayList lstEvenements = GetListeEvenementsAutoSur(tpObjets, contexte.IdVersionDeTravail);

                        //Id des éléments modifiés
                        List <int> listeIdsElementsAVerifierHandlers = new List <int>();
                        string     strPrimaryKey = "";
                        if (table.PrimaryKey.Length == 1 &&
                            table.PrimaryKey[0].DataType == typeof(int))
                        {
                            strPrimaryKey = table.PrimaryKey[0].ColumnName;
                        }

                        Dictionary <int, bool> tableIdsVues = null;
                        if (!elementsVus.TryGetValue(tpObjets, out tableIdsVues))
                        {
                            tableIdsVues          = new Dictionary <int, bool>();
                            elementsVus[tpObjets] = tableIdsVues;
                        }

                        Dictionary <int, bool> listeARepasserPourTable = null;
                        if (!listeElementsARepasser.TryGetValue(table.TableName, out listeARepasserPourTable))
                        {
                            listeARepasserPourTable = null;
                        }

                        List <CObjetDonnee> lstObjetsAvecEvenementsSpecifiques = new List <CObjetDonnee>();

                        //Stef 16/11/2012 :
                        //Si c'est un élément à champs, il est consideré comme modifié
                        //si un de ses champs custom est modifiés
                        //Ca a été fait parce que les handlers d'évenement n'étaient
                        //Pas pris en compte sur modif de champ custom
                        //On n'enlève pas pour autant l'ancienne méthode qui consiste
                        //à considérer l'élément modifié losrqu'on passe sur la table des
                        //valeurs de champs custom
                        if (typeof(IObjetDonneeAChamps).IsAssignableFrom(typeOriginal) && table.Rows.Count > 0)
                        {
                            //Regarde s'il y a des relations
                            IObjetDonneeAChamps objAChamp = contexte.GetNewObjetForRow(table.Rows[0]) as IObjetDonneeAChamps;
                            string strTableChamps         = objAChamp.GetNomTableRelationToChamps();
                            //Trouve la relation à la table
                            DataTable tableChamps = contexte.Tables[strTableChamps];
                            if (tableChamps != null)//Si la table champs n'est pas là, c'est
                            //qu'elle n'a pas été modifiée !! c'est logique çà
                            {
                                DataRelation rel = null;
                                foreach (DataRelation relTest in tableChamps.ParentRelations)
                                {
                                    if (relTest.ParentTable.TableName == table.TableName)
                                    {
                                        rel = relTest;
                                        break;
                                    }
                                }
                                if (rel != null)//On peut vérifier !
                                {
                                    foreach (DataRow row in new ArrayList(table.Rows))
                                    {
                                        if (row.RowState == DataRowState.Unchanged)//sinon, ce n'est pas la peine
                                        {
                                            DataRow[] rowsChamps = row.GetChildRows(rel);
                                            foreach (DataRow rowChamp in rowsChamps)
                                            {
                                                if (rowChamp.RowState != DataRowState.Unchanged)
                                                {
                                                    //Aloue l'objet pour s'assurer que la ligne est bien pleine
                                                    CObjetDonnee objTmp = contexte.GetNewObjetForRow(row);
                                                    objTmp.AssureData();
                                                    row.SetModified();
                                                    string strOldContexte = (string)row[CObjetDonnee.c_champContexteModification];
                                                    if (strOldContexte.Length == 0)
                                                    {
                                                        row[CObjetDonnee.c_champContexteModification] = rowChamp[CObjetDonnee.c_champContexteModification,
                                                                                                                 rowChamp.RowState == DataRowState.Deleted ? DataRowVersion.Original : DataRowVersion.Current] as string;
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        foreach (DataRow row in new ArrayList(table.Rows))
                        {
                            CObjetDonneeAIdNumerique objet = null;
                            if (lstEvenements.Count > 0)
                            {
                                if (row.RowState == DataRowState.Added ||
                                    row.RowState == DataRowState.Modified ||
                                    row.RowState == DataRowState.Deleted)
                                {
                                    objet = (CObjetDonneeAIdNumerique)((CContexteDonnee)table.DataSet).GetNewObjetForRow(row);
                                    if (objet.Row.RowState == DataRowState.Deleted)
                                    {
                                        objet.VersionToReturn = DataRowVersion.Original;
                                    }
                                    if (objet.Row.RowState != DataRowState.Deleted && EvenementAttribute.HasEventsSpecifiques(objet))
                                    {
                                        lstObjetsAvecEvenementsSpecifiques.Add(objet);
                                    }

                                    if (typeof(CRelationElementAChamp_ChampCustom).IsAssignableFrom(typeOriginal))
                                    {
                                        CRelationElementAChamp_ChampCustom rel = objet as CRelationElementAChamp_ChampCustom;
                                        objet = (CObjetDonneeAIdNumerique)((CRelationElementAChamp_ChampCustom)objet).ElementAChamps;
                                        if (objet.Row.RowState == DataRowState.Unchanged)
                                        {
                                            objet.Row.Row.SetModified();
                                        }
                                        if (objet.Row.RowState == DataRowState.Deleted)
                                        {
                                            objet.VersionToReturn = DataRowVersion.Original;
                                        }
                                        if (rel.ContexteDeModification.Length != 0 &&
                                            objet.ContexteDeModification.Length == 0)
                                        {
                                            objet.ContexteDeModification = rel.ContexteDeModification;
                                        }
                                    }
                                    if (!tableIdsVues.ContainsKey(objet.Id) || (
                                            listeARepasserPourTable != null && listeARepasserPourTable.ContainsKey(objet.Id)))
                                    {
                                        tableIdsVues[objet.Id] = true;
                                        foreach (CEvenement evt in lstEvenements)
                                        {
                                            if (!traitement.ContainsCouple(evt, (CObjetDonneeAIdNumerique)objet))
                                            {
                                                //Attention, si c'est une valeur de champ custom, envoie la valeur,
                                                //c'est elle qui sera testée.
                                                CInfoDeclencheurProcess infoDeclencheur = null;
                                                if (evt.ShouldDeclenche((CObjetDonneeAIdNumerique)objet, ref infoDeclencheur))
                                                {
                                                    infoDeclencheur.DbKeyEvenementDeclencheur = evt.DbKey;
                                                    infoDeclencheur.Info = evt.Libelle;
                                                    traitement.AddCoupleEvenementObjet(evt, (CObjetDonneeAIdNumerique)objet, infoDeclencheur);
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            //Regarde les handle d'évenement sur l'objet
                            if (strPrimaryKey != "" && (row.RowState == DataRowState.Modified))
                            {
                                listeIdsElementsAVerifierHandlers.Add((int)row[strPrimaryKey]);
                            }
                        }
                        if (listeARepasserPourTable != null)
                        {
                            listeARepasserPourTable.Clear();
                        }

                        if (listeIdsElementsAVerifierHandlers.Count > 0 && bFirstPasse)
                        {
                            //traitement par paquet de 500
                            for (int nIndexLot = 0; nIndexLot < listeIdsElementsAVerifierHandlers.Count; nIndexLot += 500)
                            {
                                int           nMin = Math.Min(nIndexLot + 500, listeIdsElementsAVerifierHandlers.Count);
                                StringBuilder bl   = new StringBuilder();
                                for (int nIndex = nIndexLot; nIndex < nMin; nIndex++)
                                {
                                    bl.Append(listeIdsElementsAVerifierHandlers[nIndex].ToString());
                                    bl.Append(",");
                                }
                                string strIdsElementsAVerifierHandlers = bl.ToString().Substring(0, bl.ToString().Length - 1);
                                //Recherche tous les handlers d'évenement pour les objets concernés
                                CListeObjetsDonnees listeHandler = new CListeObjetsDonnees(contexte, typeof(CHandlerEvenement));
                                listeHandler.Filtre = new CFiltreData(
                                    CHandlerEvenement.c_champIdCible + " in (" + strIdsElementsAVerifierHandlers + ") and " +
                                    CHandlerEvenement.c_champTypeCible + "=@1 and " +
                                    CHandlerEvenement.c_champTypeEvenement + "=@2",
                                    tpObjets.ToString(),
                                    (int)TypeEvenement.Modification);
                                listeHandler.PreserveChanges = true;
                                foreach (CHandlerEvenement handler in listeHandler)
                                {
                                    if (handler.Row.RowState != DataRowState.Deleted)
                                    {
                                        CObjetDonneeAIdNumerique objetTmp = (CObjetDonneeAIdNumerique)Activator.CreateInstance(tpObjets, new object[] { contexte });
                                        if (objetTmp.ReadIfExists(handler.IdElementCible))
                                        {
                                            CInfoDeclencheurProcess infoDeclencheur = null;
                                            if (handler.ShoulDeclenche(objetTmp, ref infoDeclencheur))
                                            {
                                                if (infoDeclencheur != null && handler.EvenementLie != null)
                                                {
                                                    infoDeclencheur.Info = handler.EvenementLie.Libelle;
                                                }
                                                traitement.AddCoupleHandlerObjet(handler, (CObjetDonneeAIdNumerique)objetTmp, infoDeclencheur);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        //Annule les évenements spécifiques, ils ont été traités !
                        foreach (CObjetDonnee objet in lstObjetsAvecEvenementsSpecifiques)
                        {
                            EvenementAttribute.ClearEvenements(objet);
                        }
                    }
                }

                //Execute ce qui peut être executé tout de suite
                foreach (DataTable table in contexte.Tables)
                {
                    table.RowChanged += handlerRedo;
                }
                listeElementsARepasser.Clear();
                foreach (CTraitementApresSauvegarde.CCoupleDeclencheurObjet couple in traitement.CouplesEvenementOuHandlerObjet)
                {
                    if (couple.Objet is CObjetDonneeAIdNumerique &&
                        couple.PeutEtreExecuteSurLePosteClient)
                    {
                        result = couple.OnDeclencheSurClient();
                        if (!result)
                        {
                            return(result);
                        }
                    }
                }
                foreach (DataTable table in contexte.Tables)
                {
                    table.RowChanged -= handlerRedo;
                }
                bFirstPasse = false;
            }

            if (traitement.CouplesEvenementOuHandlerObjet.Count != 0)
            {
                tableData[c_cleDonneeListeTraitements] = traitement;
            }
            m_listeElementsARepasser.Remove(contexte);
            return(result);
        }
Esempio n. 3
0
        /// <summary>
        /// Indique si l'évenement doit se déclencher
        /// </summary>
        /// <param name="objet"></param>
        /// <param name="bModeAvecInterface">
        /// si vrai, les évenements de type Manuel ou Ouverture retournent vrai,
        /// sinon, ils retournent systématiquement faux
        /// </param>
        /// <param name="bModeStatique">
        /// Si vrai, les évenements de création sont vrai et les évenements
        /// de modif sans valeur initiale retournent vrai si la valeur de fin est verifiée
        /// </param>
        /// <returns></returns>
        public bool ShouldDeclenche(CObjetDonneeAIdNumerique objet, bool bModeAvecInterface, bool bModeStatique, ref CInfoDeclencheurProcess infoDeclencheur)
        {
            CResultAErreur result = CResultAErreur.True;

            if (ContextesException.Contains(objet.ContexteDeModification))
            {
                return(false);
            }
            //CObjetDonneeAIdNumeriqueAuto objetToEval = objet;
            CDefinitionProprieteDynamique defPropriete = ProprieteASurveiller;

            if (objet is CRelationElementAChamp_ChampCustom)
            {
                if (!(defPropriete is CDefinitionProprieteDynamiqueChampCustom))
                {
                    return(false);
                }
                CRelationElementAChamp_ChampCustom rel = (CRelationElementAChamp_ChampCustom)objet;
                if (rel.ChampCustom.DbKey != ((CDefinitionProprieteDynamiqueChampCustom)defPropriete).DbKeyChamp)
                {
                    return(false);
                }
            }
            CObjetDonneeAIdNumerique objetToTest = GetObjetToRun(objet);

            if (objetToTest == null)
            {
                return(false);
            }
            DataRowVersion versionToReturnOriginal = objetToTest.VersionToReturn;

            try
            {
                if (objetToTest.Row.RowState == DataRowState.Deleted)
                {
                    objetToTest.VersionToReturn = DataRowVersion.Original;
                }
                CContexteEvaluationExpression contexteEval = new CContexteEvaluationExpression(objetToTest);
                object valeurAvant;
                object valeurApres;
                infoDeclencheur = new CInfoDeclencheurProcess();
                infoDeclencheur.TypeDeclencheur = TypeEvenement;
                switch (TypeEvenement)
                {
                case TypeEvenement.Manuel:
                    if (!bModeAvecInterface)
                    {
                        return(false);
                    }
                    break;

                case TypeEvenement.Creation:
                    if (objet.Row.RowState != DataRowState.Added && !bModeStatique)
                    {
                        return(false);
                    }
                    break;

                case TypeEvenement.Date:
                    //Vérifie si la date a changé
                    if (defPropriete != null)
                    {
                        if (!bModeStatique)
                        {
                            valeurAvant = GetValeur(objet, defPropriete, DataRowVersion.Original);
                            valeurApres = GetValeur(objet, defPropriete, DataRowVersion.Current);
                            if (TestEgalite(valeurApres, valeurAvant))
                            {
                                return(false);
                            }
                        }
                    }
                    break;

                case TypeEvenement.Modification:
                    if (objet.Row.RowState == DataRowState.Modified || objet.Row.RowState == DataRowState.Added || bModeStatique)
                    {
                        if (defPropriete != null)
                        {
                            try
                            {
                                valeurAvant = null;
                                if (objet.Row.RowState == DataRowState.Modified)
                                {
                                    valeurAvant = GetValeur(objet, defPropriete, DataRowVersion.Original);
                                }
                                valeurApres = GetValeur(objet, defPropriete, DataRowVersion.Current);
                                if (objet.Row.RowState == DataRowState.Modified && TestEgalite(valeurApres, valeurAvant))
                                {
                                    return(false);
                                }
                                if (FormuleValeurAvant != null)
                                {
                                    if (bModeStatique)
                                    {
                                        return(false);
                                    }
                                    result = FormuleValeurAvant.Eval(contexteEval);
                                    if (!result)
                                    {
                                        return(false);
                                    }
                                    if (!TestEgalite(result.Data, valeurAvant))
                                    {
                                        return(false);
                                    }
                                }
                                if (FormuleValeurApres != null)
                                {
                                    result = FormuleValeurApres.Eval(contexteEval);
                                    if (!result)
                                    {
                                        return(false);
                                    }
                                    if (!TestEgalite(result.Data, valeurApres))
                                    {
                                        return(false);
                                    }
                                }
                                infoDeclencheur.ValeurOrigine = valeurAvant;
                            }
                            catch
                            {
                                return(false);
                            }
                        }
                    }
                    else
                    {
                        return(false);
                    }
                    break;

                case TypeEvenement.Specifique:
                    if (objet.Table.Columns.Contains(EvenementAttribute.c_champEvenements))
                    {
                        if (!EvenementAttribute.HasEvent(objet, IdEvenementSpecifique))
                        {
                            return(false);
                        }
                    }
                    //Stef 110309 : Si on annule l'évenement là, et qu'il y a d'autres
                    //Hanlder sur cet évenement, les autres handler ne se déclencheront pas
                    //il faut donc annuler l'evenement quand on a parcouru tous les évenements
                    //Donc, dans le CGestionnaireEvenements
                    //EvenementAttribute.AnnuleEvenement(objet, IdEvenementSpecifique);
                    break;

                case TypeEvenement.Suppression:
                    if (objet.Row.RowState != DataRowState.Deleted)
                    {
                        return(false);
                    }
                    break;
                }
                //Evalue la condition
                if (FormuleConditionDeclenchement != null)
                {
                    result = FormuleConditionDeclenchement.Eval(contexteEval);
                    if (!result)
                    {
                        return(result);
                    }
                    if (result.Data is bool)
                    {
                        if (!(bool)result.Data)
                        {
                            return(false);
                        }
                    }
                    else if (result.Data.ToString() == "" || result.Data.ToString() == "0")
                    {
                        return(false);
                    }
                }
            }
            catch
            {
            }
            finally
            {
                objetToTest.VersionToReturn = versionToReturnOriginal;
            }
            return(true);
        }