private void ShowUFDialog(bool CreateNew)
		{
			GISADataset.TipoNivelRelacionadoRow tnrRow = (GISADataset.TipoNivelRelacionadoRow)(GisaDataSetHelper.GetInstance().TipoNivelRelacionado. Select(string.Format("ID={0}", TipoNivelRelacionado.UF))[0]);

			GISADataset.NivelRow nufRow = null;
			GISADataset.NivelDesignadoRow ndufRow = null;
			GISADataset.NivelDesignadoRow ndedRow = null;
			GISADataset.RelacaoHierarquicaRow rhufRow = null;
			GISADataset.NivelUnidadeFisicaRow nufufRow = null;
			GISADataset.FRDBaseRow frdufRow = null;
            GISADataset.SFRDUFCotaRow cota = null;
            GISADataset.SFRDUFDescricaoFisicaRow df = null;
            GISADataset.SFRDDatasProducaoRow dp = null;
            GISADataset.SFRDConteudoEEstruturaRow ce = null;
            List<GISADataset.NivelDesignadoRow> edsNdRRows = null;

            if (CreateNew && ((frmMain)TopLevelControl).isSuportPanel && !PersistencyHelper.hasCurrentDatasetChanges())
            {
                try
                {
                    Trace.WriteLine("Saving before creating new UF in suport panel...");
                    PersistencyHelper.save();
                    PersistencyHelper.cleanDeletedData();
                }
                catch (Exception)
                {
                    MessageBox.Show("Ocorreu um erro ao tentar abrir o formulário de criação." + System.Environment.NewLine + "Por favor contacte o administrador de sistema.", "Criação de unidade física", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }

                
                using (GisaDataSetHelper.HoldOpen ho = new GisaDataSetHelper.HoldOpen(GisaDataSetHelper.GetConnection()))
                {
                    if (CurrentContext.NivelEstrututalDocumental == null)
                    {
                        MessageBox.Show("Ocorreu um erro ao tentar abrir o formulário de criação." + System.Environment.NewLine + "Por favor contacte o administrador de sistema.", "Criação de unidade física", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        Trace.WriteLine("Pincipal context not found!!");
                        return;
                    }
                    DBAbstractDataLayer.DataAccessRules.NivelRule.Current.LoadEntidadesDetentoras(GisaDataSetHelper.GetInstance(), ho.Connection);
                    var edsIds = UFRule.Current.GetEntidadeDetentoraForNivel(CurrentContext.NivelEstrututalDocumental.ID, ho.Connection);

                    var ndRows=GisaDataSetHelper.GetInstance().NivelDesignado.Cast<GISADataset.NivelDesignadoRow>().Where(r=>r.RowState != DataRowState.Deleted);
                    edsNdRRows = edsIds.Cast<long>().Select(id => ndRows.Single(r=>r.ID==id)).ToList();
                }
            }

			using (GisaDataSetHelper.HoldOpen ho = new GisaDataSetHelper.HoldOpen(GisaDataSetHelper.GetConnection()))
            {
				GisaDataSetHelper.ManageDatasetConstraints(false);
				DBAbstractDataLayer.DataAccessRules.NivelRule.Current.LoadUFsRelatedData(GisaDataSetHelper.GetInstance(), ho.Connection);
				GisaDataSetHelper.ManageDatasetConstraints(true);
			}

			PersistencyHelper.AddEditUFPreConcArguments argsPC = new PersistencyHelper.AddEditUFPreConcArguments();
			PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments argsPS = new PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments();

			FormCreateUF frm = new FormCreateUF();
            if (CreateNew)
            {
                argsPC.Operation = PersistencyHelper.AddEditUFPreConcArguments.Operations.Create;
                // nivel
                nufRow = GisaDataSetHelper.GetInstance().Nivel.NewNivelRow();
                // nivelDesignado
                ndufRow = GisaDataSetHelper.GetInstance().NivelDesignado.NewNivelDesignadoRow();
                // RelacaoHierarquica
                rhufRow = GisaDataSetHelper.GetInstance().RelacaoHierarquica.NewRelacaoHierarquicaRow();
                // NivelUnidadeFisicaRow
                nufufRow = GisaDataSetHelper.GetInstance().NivelUnidadeFisica.NewNivelUnidadeFisicaRow();
                // FRDBaseRow
                frdufRow = GisaDataSetHelper.GetInstance().FRDBase.NewFRDBaseRow();
                // nivel da entidade detentora 
                ndedRow = null;

                cota = GisaDataSetHelper.GetInstance().SFRDUFCota.NewSFRDUFCotaRow();
                df = GisaDataSetHelper.GetInstance().SFRDUFDescricaoFisica.NewSFRDUFDescricaoFisicaRow();
                dp = GisaDataSetHelper.GetInstance().SFRDDatasProducao.NewSFRDDatasProducaoRow();
                ce = GisaDataSetHelper.GetInstance().SFRDConteudoEEstrutura.NewSFRDConteudoEEstruturaRow();

                frm.Text = "Criar " + tnrRow.Designacao;
                if (CreateNew && ((frmMain)TopLevelControl).isSuportPanel && !PersistencyHelper.hasCurrentDatasetChanges())
                    frm.EntidadeDetentoraList = edsNdRRows;

                frm.ReloadData();
                foreach (GISADataset.NivelDesignadoRow row in frm.cbEntidadeDetentora.Items)
                {
                    if (row.ID == ShowUFDialog_edID)
                    {
                        frm.cbEntidadeDetentora.SelectedItem = row;
                        break;
                    }
                }

                frm.txtDesignacao.Text = ShowUFDialog_designacao;
                frm.txtDesignacao.SelectAll();
            }
            else
            {
                if (ufList.SelectedItems.Count == 0)
                {
                    return;
                }
                if (((GISADataset.NivelRow)(ufList.SelectedItems[0].Tag)).RowState == DataRowState.Detached)
                {
                    MessageBox.Show("Não é possível editar a unidade física selecionada " + System.Environment.NewLine + "uma vez que foi apagada por outro utilizador.", "Edição de unidades físicas", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                argsPC.Operation = PersistencyHelper.AddEditUFPreConcArguments.Operations.Edit;
                // nivel
                nufRow = (GISADataset.NivelRow)(ufList.SelectedItems[0].Tag);
                argsPC.nivelUFRowID = nufRow.ID;
                // nivelDesignado
                ndufRow = nufRow.GetNivelDesignadoRows()[0];
                argsPC.ndufRowID = ndufRow.ID;
                // RelacaoHierarquica
                rhufRow = nufRow.GetRelacaoHierarquicaRowsByNivelRelacaoHierarquica()[0];
                argsPC.rhufRowID = rhufRow.ID;
                argsPC.rhufRowIDUpper = rhufRow.IDUpper;
                // NivelUnidadeFisicaRow
                if (ndufRow.GetNivelUnidadeFisicaRows().Length > 0)
                    nufufRow = ndufRow.GetNivelUnidadeFisicaRows()[0];
                else
                {
                    // via conversão de dados esta linha pode não ser criada, mas pela aplicação é garantido que a row é criada
                    nufufRow = GisaDataSetHelper.GetInstance().NivelUnidadeFisica.NewNivelUnidadeFisicaRow();
                    nufufRow.GuiaIncorporacao = "";
                    nufufRow.NivelDesignadoRow = ndufRow;
                    nufufRow.isDeleted = 0;
                    GisaDataSetHelper.GetInstance().NivelUnidadeFisica.AddNivelUnidadeFisicaRow(nufufRow);
                }
                argsPC.nufufRowID = nufufRow.ID;

                // nivel da entidade detentora
                ndedRow = rhufRow.NivelRowByNivelRelacaoHierarquicaUpper.GetNivelDesignadoRows()[0];

                frm.Text = "Editar " + tnrRow.Designacao;
                frm.ReloadData();
                frm.EntidadeDetentora = ndedRow;

                frm.NivelDesignado = ndufRow;

                frm.Codigo = nufRow.Codigo;

                frdufRow = nufRow.GetFRDBaseRows().First();
            }

			switch (frm.ShowDialog())
			{
				case DialogResult.OK:
					ndufRow.Designacao = frm.Designacao;

                    List<string> uaAssociadas = new List<string>();

					if (CreateNew)
					{
						Trace.WriteLine("A criar unidade física...");
						nufRow.TipoNivelRow = tnrRow.TipoNivelRow;
						nufRow.Codigo = frm.Codigo;
						nufRow.CatCode = "NVL";

						ndufRow.NivelRow = nufRow;
						ndufRow.Designacao = frm.Designacao;
						ShowUFDialog_edID = frm.EntidadeDetentora.ID;
						ShowUFDialog_designacao = frm.Designacao;

						rhufRow.NivelRowByNivelRelacaoHierarquica = nufRow;
                        rhufRow.TipoNivelRelacionadoRow = tnrRow;
						rhufRow["InicioAno"] = DBNull.Value;
						rhufRow["InicioMes"] = DBNull.Value;
						rhufRow["InicioDia"] = DBNull.Value;
						rhufRow["FimAno"] = DBNull.Value;
						rhufRow["FimMes"] = DBNull.Value;
						rhufRow["FimDia"] = DBNull.Value;
						rhufRow.NivelRowByNivelRelacaoHierarquicaUpper = frm.EntidadeDetentora.NivelRow;

						nufufRow.NivelDesignadoRow = ndufRow;

						frdufRow.NivelRow = nufRow;
						frdufRow.NotaDoArquivista = string.Empty;
						frdufRow.TipoFRDBaseRow = (GISADataset.TipoFRDBaseRow)(GisaDataSetHelper.GetInstance().TipoFRDBase.Select(string.Format("ID={0}", System.Enum.Format(typeof(TipoFRDBase), TipoFRDBase.FRDUnidadeFisica, "D")))[0]);
						frdufRow.RegrasOuConvencoes = string.Empty;

                        cota.FRDBaseRow = frdufRow;
                        cota.Cota = string.Empty;

                        df.FRDBaseRow = frdufRow;
                        df.IDTipoMedida = 1;
                        df.TipoAcondicionamentoRow = (GISADataset.TipoAcondicionamentoRow)(GisaDataSetHelper.GetInstance().TipoAcondicionamento.Select(string.Format("ID={0:d}", TipoAcondicionamento.Pasta))[0]);
                        
                        dp.FRDBaseRow = frdufRow;
                        dp.FimAno = string.Empty;
                        dp.FimMes = string.Empty;
                        dp.FimDia = string.Empty;
                        dp.FimAtribuida = false;
                        dp.InicioAno = string.Empty;
                        dp.InicioMes = string.Empty;
                        dp.InicioDia = string.Empty;
                        dp.InicioAtribuida = false;

                        ce.FRDBaseRow = frdufRow;
                        ce.ConteudoInformacional = string.Empty;
                        ce.Incorporacao = string.Empty;

						GisaDataSetHelper.GetInstance().Nivel.AddNivelRow(nufRow);
						GisaDataSetHelper.GetInstance().NivelDesignado.AddNivelDesignadoRow(ndufRow);
						GisaDataSetHelper.GetInstance().RelacaoHierarquica.AddRelacaoHierarquicaRow(rhufRow);
						GisaDataSetHelper.GetInstance().NivelUnidadeFisica.AddNivelUnidadeFisicaRow(nufufRow);
						GisaDataSetHelper.GetInstance().FRDBase.AddFRDBaseRow(frdufRow);
                        GisaDataSetHelper.GetInstance().SFRDUFCota.AddSFRDUFCotaRow(cota);
                        GisaDataSetHelper.GetInstance().SFRDUFDescricaoFisica.AddSFRDUFDescricaoFisicaRow(df);
                        GisaDataSetHelper.GetInstance().SFRDDatasProducao.AddSFRDDatasProducaoRow(dp);
                        GisaDataSetHelper.GetInstance().SFRDConteudoEEstrutura.AddSFRDConteudoEEstruturaRow(ce);

						argsPC.nivelUFRowID = nufRow.ID;
						argsPC.ndufRowID = ndufRow.ID;
						argsPC.rhufRowID = rhufRow.ID;
						argsPC.rhufRowIDUpper = rhufRow.IDUpper;
						argsPC.nufufRowID = nufufRow.ID;
						argsPC.frdufRowID = frdufRow.ID;
					}
					else
					{
							// se a entidade detentora da unidade fisica for alterada
							// é necessário actualizar o Codigo
						if (frm.EntidadeDetentora.ID != ndedRow.ID)
						{
                            var uasInfo = new List<UnidadesFisicasHelper.UaInfo>();
                            var res = MessageBox.Show("A entidade detentora foi alterada. Por essa razão será " + "atribuído um novo código a esta unidade física. Deseja prosseguir?", "Edição da unidade física", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                            // switch (ConfirmCascadeDeletion("A entidade detentora foi alterada. Por essa razão será " + "atribuído um novo código a esta unidade física. Deseja prosseguir?", "A entidade detentora foi alterada. Por essa razão será " + "atribuído um novo código a esta unidade física " + "e as referências existentes serão perdidas." + "Deseja prosseguir?", nufRow, ref uaAssociadas, ref uasInfo))
                            switch (res)
							{
								case DialogResult.OK:
								case DialogResult.Yes:
									Trace.WriteLine("A editar unidade física...");
									nufRow.Codigo = frm.Codigo;

								        //nova RelacaoHierarquicaRow
									GISADataset.RelacaoHierarquicaRow newRhufRow = null;
									newRhufRow = GisaDataSetHelper.GetInstance().RelacaoHierarquica.NewRelacaoHierarquicaRow();
									newRhufRow.ID = rhufRow.ID;
									newRhufRow.NivelRowByNivelRelacaoHierarquicaUpper = frm.EntidadeDetentora.NivelRow;
									newRhufRow.IDTipoNivelRelacionado = rhufRow.IDTipoNivelRelacionado;
									GisaDataSetHelper.GetInstance().RelacaoHierarquica.AddRelacaoHierarquicaRow(newRhufRow);
									argsPC.newRhufRowID = newRhufRow.ID;
									argsPC.newRhufRowIDUpper = newRhufRow.IDUpper;
									argsPC.nufufRowID = nufufRow.ID;

									    //apagar a relacao antiga
									rhufRow.Delete();
									break;
								case DialogResult.Cancel:
								case DialogResult.No:
										// cancelar toda a operação de edição
                                    MessageBox.Show("A unidade física não foi alterada.", "Edição da unidade física");
										// FIXME: exit sub?
									return;
							}
						}
					}

					argsPS.nivelUFRowID = nufufRow.ID;
					argsPC.psa = argsPS;

                    var postSaveAction = new PostSaveAction();
                    var argsPostSave = new PersistencyHelper.UpdatePermissionsPostSaveArguments();
                    postSaveAction.args = argsPostSave;

                    postSaveAction.postSaveDelegate = delegate(PersistencyHelper.PostSaveArguments postSaveArgs)
                    {
                        if (!postSaveArgs.cancelAction && argsPC.OperationError == PersistencyHelper.AddEditUFPreConcArguments.OperationErrors.NoError)
                        {
                            if (CreateNew && ((frmMain)TopLevelControl).isSuportPanel)
                            {
                                GISADataset.TrusteeUserRow tuAuthorRow = null;
                                if (SessionHelper.GetGisaPrincipal().TrusteeUserAuthor != null && !(SessionHelper.GetGisaPrincipal().TrusteeUserAuthor.RowState == DataRowState.Detached))
                                    tuAuthorRow = SessionHelper.GetGisaPrincipal().TrusteeUserAuthor;
                                var r = GISA.Model.RecordRegisterHelper.CreateFRDBaseDataDeDescricaoRow(frdufRow, SessionHelper.GetGisaPrincipal().TrusteeUserOperator, tuAuthorRow, DateTime.Now);
                                GisaDataSetHelper.GetInstance().FRDBaseDataDeDescricao.AddFRDBaseDataDeDescricaoRow(r);
                            }
                            else
                                CurrentContext.RaiseRegisterModificationEvent(frdufRow);
                            PersistencyHelperRule.Current.saveRows(GisaDataSetHelper.GetInstance().FRDBaseDataDeDescricao,
                                    GisaDataSetHelper.GetInstance().FRDBaseDataDeDescricao.Cast<GISADataset.FRDBaseDataDeDescricaoRow>().Where(frd => frd.RowState == DataRowState.Added).ToArray(), postSaveArgs.tran);
                        }
                    };

                    PersistencyHelper.SaveResult successfulSave = PersistencyHelper.save(DelegatesHelper.HandleUF, argsPC, DelegatesHelper.SetCodigo, argsPS, postSaveAction);
                    PersistencyHelper.cleanDeletedData(PersistencyHelper.determinaNuvem("NivelUnidadeFisica"));

					try
					{
						if (CreateNew)
						{
							if (argsPC.OperationError == PersistencyHelper.AddEditUFPreConcArguments.OperationErrors.NewUF)
							{
								MessageBox.Show(argsPC.message, "Criar unidade física", MessageBoxButtons.OK, MessageBoxIcon.Warning);
							}
							else
							{
                                // adicionar unidade física à lista
								ufList.AddNivel(nufRow);

                                if (successfulSave == PersistencyHelper.SaveResult.successful)
                                {
                                    GISA.Search.Updater.updateNivelDocumental(uaAssociadas);
                                    GISA.Search.Updater.updateUnidadeFisica(frdufRow.NivelRow.ID);
                                }
							}
						}
						else
						{
							if (argsPC.OperationError == PersistencyHelper.AddEditUFPreConcArguments.OperationErrors.EditEDAndDesignacao)
							{
								MessageBox.Show(argsPC.message, "Editar unidade física", MessageBoxButtons.OK, MessageBoxIcon.Warning);
								ufList.ClearItemSelection(ufList.SelectedItems[0]);
							}
							else if (argsPC.OperationError == PersistencyHelper.AddEditUFPreConcArguments.OperationErrors.EditNewEd)
							{
								MessageBox.Show(argsPC.message, "Editar unidade física", MessageBoxButtons.OK, MessageBoxIcon.Warning);
							}
							else if (argsPC.OperationError == PersistencyHelper.AddEditUFPreConcArguments.OperationErrors.EditOriginalEd)
							{
								MessageBox.Show(argsPC.message, "Editar unidade física", MessageBoxButtons.OK, MessageBoxIcon.Warning);
									// recarregar a UF de forma a actualizar a sua informação
								ListViewItem lvItem = ufList.SelectedItems[0];
								ufList.ClearItemSelection(lvItem);
								ufList.SelectItem(lvItem);
								ufList.UpdateNivel(ufList.SelectedItems[0]);
							}
							else
							{
								ufList.UpdateNivel(ufList.SelectedItems[0]);

                                frdufRow = ((GISADataset.NivelRow)ufList.SelectedItems[0].Tag).GetFRDBaseRows()[0];

                                if (successfulSave == PersistencyHelper.SaveResult.successful)
                                {
                                    GISA.Search.Updater.updateNivelDocumental(uaAssociadas);
                                    GISA.Search.Updater.updateUnidadeFisica(frdufRow.NivelRow.ID);
                                }

								// force a context update so that lower panel gets updated
								CurrentContext.SetNivelUnidadeFisica(null);
								UpdateContext();
							}
						}
					}
					catch (Exception ex)
					{
						Trace.WriteLine("Exception while refreshing data: " + ex.ToString());
						throw;
					}
					break;
			}
		}
Beispiel #2
0
		// Trata a criação de novos níveis e respectivas relações. Caso se trate 
		// de um nível orgânico (estrutural e que esteja associado a uma EP) o 
		// nível correspondente deverá já existir e não será por isso criado, 
		// será criada apenas a relação.
		private bool handleNewNivel(Form frm, GISADataset.NivelRow parentNivelRow, GISADataset.TipoNivelRelacionadoRow tnrRow)
		{
			frm.Text = "Criar " + tnrRow.Designacao;

			// se se tratar de uma série ou subsérie
			if (tnrRow.ID == TipoNivelRelacionado.SR || tnrRow.ID == TipoNivelRelacionado.SSR)
			{
				FormNivelDocumental frmDoc = (FormNivelDocumental)frm;
				frmDoc.grpCodigo.Text += " previsto";
				frmDoc.txtCodigo.Enabled = false;

				GisaDataSetHelper.HoldOpen ho = new GisaDataSetHelper.HoldOpen(GisaDataSetHelper.GetConnection());
				try
				{
					NivelRule.Current.FillTipoNivelRelacionadoCodigo(GisaDataSetHelper.GetInstance(), ho.Connection);
				}
				catch (Exception ex)
				{
					Trace.WriteLine(ex);
					throw;
				}
				finally
				{
					ho.Dispose();
				}
                frmDoc.txtCodigo.Text = NiveisHelper.getNextSeriesCodigo(false);
			}

			bool successfulSave = true;
			switch (frm.ShowDialog())
			{
				case DialogResult.OK:
				{
					Trace.WriteLine("A criar nível...");
                    long click = DateTime.Now.Ticks;
					GISADataset.NivelRow nRow = null;
					GISADataset.NivelDesignadoRow ndRow = null;
					GISADataset.NivelControloAutRow ncaRow = null;
					GISADataset.FRDBaseRow frdRow = null;

					string designacaoUFAssociada = string.Empty;
					bool addNewUF = false;

                    PostSaveAction postSaveAction = null;

					// Create a new Nivel with or without a Notícia autoridade
					if (frm is FormNivelEstrutural && ((FormNivelEstrutural)frm).chkControloAut)
					{
						GISADataset.ControloAutRow caRow = null;
						caRow = ((GISADataset.ControloAutDicionarioRow)(((FormNivelEstrutural)frm). caList.SelectedItems[0].Tag)).ControloAutRow;

						GisaDataSetHelper.HoldOpen ho = new GisaDataSetHelper.HoldOpen(GisaDataSetHelper.GetConnection());
						try
						{
							DBAbstractDataLayer.DataAccessRules.NivelRule.Current.LoadNivelByControloAut(caRow.ID, GisaDataSetHelper.GetInstance(), ho.Connection);
						}
						finally
						{
							ho.Dispose();
						}

						ncaRow = caRow.GetNivelControloAutRows()[0];
						nRow = ncaRow.NivelRow;

						// Impedir criação de relações repetidas entre niveis 
						// estruturais e níveis "logicos"
						if (GisaDataSetHelper.GetInstance().RelacaoHierarquica.Select(string.Format("ID={0} AND IDUpper={1} OR ID={1} AND IDUpper={0}", parentNivelRow.ID, nRow.ID)).Length > 0)
						{
							MessageBox.Show("A relação pretendida já existe e não pode ser duplicada.", "Adição de relação", MessageBoxButtons.OK, MessageBoxIcon.Warning);
							return false;
						}
					}
					else
					{
						nRow = GisaDataSetHelper.GetInstance().Nivel. AddNivelRow(tnrRow.TipoNivelRow, ((FormAddNivel)frm).txtCodigo.Text.Trim(), "NVL", new byte[]{}, 0);
						ndRow = GisaDataSetHelper.GetInstance().NivelDesignado. AddNivelDesignadoRow(nRow, ((FormAddNivel)frm).txtDesignacao.Text.Trim(), new byte[]{}, 0);

                        if (nRow.IDTipoNivel != TipoNivel.LOGICO)
						    frdRow = GisaDataSetHelper.GetInstance().FRDBase.AddFRDBaseRow(nRow, (GISADataset.TipoFRDBaseRow)(GisaDataSetHelper.GetInstance().TipoFRDBase. Select("ID=" + DomainValuesHelper.stringifyEnumValue(TipoFRDBase.FRDOIRecolha))[0]), "", "", new byte[]{}, 0);

						if (nRow.IDTipoNivel == TipoNivel.DOCUMENTAL && ((FormNivelDocumental)frm).CreateUFAssociada)
						{
							designacaoUFAssociada = ((FormNivelDocumental)frm).DesignacaoUF;
							addNewUF = true;
						}
					}

                    // valores por omissão
                    var globalConfig = GisaDataSetHelper.GetInstance().GlobalConfig.Cast<GISADataset.GlobalConfigRow>().Single();
                    if (globalConfig.ApplyDefaultValues && nRow.IDTipoNivel == TipoNivel.DOCUMENTAL)
                    {
                        var sfrdcaRow = GisaDataSetHelper.GetInstance().SFRDCondicaoDeAcesso
                            .AddSFRDCondicaoDeAcessoRow(frdRow, "", globalConfig.IsCondicaoDeAcessoNull() ? "" : globalConfig.CondicaoDeAcesso,
                            globalConfig.IsCondicaoDeReproducaoNull() ? "" : globalConfig.CondicaoDeReproducao, "", new byte[] { }, 0);

                        foreach (GISADataset.ConfigLinguaRow r in globalConfig.GetConfigLinguaRows())
                            GisaDataSetHelper.GetInstance().SFRDLingua.AddSFRDLinguaRow(sfrdcaRow, r.Iso639Row, new byte[] { }, 0);

                        foreach (GISADataset.ConfigAlfabetoRow r in globalConfig.GetConfigAlfabetoRows())
                            GisaDataSetHelper.GetInstance().SFRDAlfabeto.AddSFRDAlfabetoRow(sfrdcaRow, r.Iso15924Row, new byte[] { }, 0);
                    }

					GISADataset.RelacaoHierarquicaRow rhRow = null;
					// garantir que os nós raiz não são criados com pais
					if (tnrRow.ID != TipoNivelRelacionado.ED)
						rhRow = GisaDataSetHelper.GetInstance().RelacaoHierarquica. AddRelacaoHierarquicaRow(nRow, parentNivelRow, tnrRow, null, null, null, null, null, null, null, new byte[]{}, 0);

					// Só adicionar permissões ao grupo TODOS dos níveis lógicos e a níveis documentais imediatamente
					// abaixo de níveis orgânicos (Documentos soltos e séries); caso se se trate de um nível estrutural 
					// controlado, as permissões já foram atribuidas aquando da criação do controlo de autoridade 
					if (nRow.IDTipoNivel == TipoNivel.LOGICO || (nRow.IDTipoNivel == TipoNivel.DOCUMENTAL && parentNivelRow.IDTipoNivel == TipoNivel.ESTRUTURAL))
					{
                        var nUpperRow = rhRow == null ? default(GISADataset.NivelRow) : rhRow.NivelRowByNivelRelacaoHierarquicaUpper;
                        PermissoesHelper.AddNewNivelGrantPermissions(nRow, nUpperRow);
					}

                    // actualizar permissões implícitas
                    postSaveAction = new PostSaveAction();
                    PersistencyHelper.UpdatePermissionsPostSaveArguments args = new PersistencyHelper.UpdatePermissionsPostSaveArguments();
                    postSaveAction.args = args;

                    postSaveAction.postSaveDelegate = delegate(PersistencyHelper.PostSaveArguments postSaveArgs)
                    {
                        if (!postSaveArgs.cancelAction && nRow != null && nRow.RowState != DataRowState.Detached && nRow.RowState != DataRowState.Deleted)
                        {
                            if (addNewUF)
                            {
                                // registar a criação da unidade física
                                GISADataset.FRDBaseRow frdUFRow =
                                    nRow.GetFRDBaseRows()[0].GetSFRDUnidadeFisicaRows()[0].NivelRow.GetFRDBaseRows()[0];
                                CurrentContext.RaiseRegisterModificationEvent(frdUFRow);
                            }

                            // registar a criação do nivel documental
                            GISADataset.FRDBaseRow frdDocRow = null;
                            GISADataset.FRDBaseRow[] frdDocRows = nRow.GetFRDBaseRows();
                            if (frdDocRows.Length > 0)
                                frdDocRow = frdDocRows[0];
                            CurrentContext.RaiseRegisterModificationEvent(frdDocRow);

                            PersistencyHelperRule.Current.saveRows(GisaDataSetHelper.GetInstance().FRDBaseDataDeDescricao,
                                GisaDataSetHelper.GetInstance().FRDBaseDataDeDescricao.Cast<GISADataset.FRDBaseDataDeDescricaoRow>().Where(frd => frd.RowState == DataRowState.Added).ToArray(), postSaveArgs.tran);
                        }
                    };

					// se se tratar de uma série ou subsérie
					if (tnrRow.ID == TipoNivelRelacionado.SR || tnrRow.ID == TipoNivelRelacionado.SSR)
					{
						// é necessário garantir que o código gerado ainda não está 
						// em uso, por isso geramo-lo dentro da própria transacção                        
                        
						PersistencyHelper.ValidateNivelAddAndAssocNewUFPreConcArguments pcArgs = new PersistencyHelper.ValidateNivelAddAndAssocNewUFPreConcArguments();                                                
						PersistencyHelper.SetNewCodigosPreSaveArguments psArgs = new PersistencyHelper.SetNewCodigosPreSaveArguments();                        
						PersistencyHelper.VerifyIfRHNivelUpperExistsPreConcArguments pcArgsNivel = new PersistencyHelper.VerifyIfRHNivelUpperExistsPreConcArguments();
						PersistencyHelper.FetchLastCodigoSeriePreSaveArguments psArgsNivel = new PersistencyHelper.FetchLastCodigoSeriePreSaveArguments();
						PersistencyHelper.AddEditUFPreConcArguments pcArgsUF = new PersistencyHelper.AddEditUFPreConcArguments();
						PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments psArgsUF = new PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments();
                        

						pcArgs.argsNivel = pcArgsNivel;
						pcArgs.argsUF = pcArgsUF;

						psArgs.argsNivel = psArgsNivel;
						psArgs.argsUF = psArgsUF;

						// dados que serão usados no delegate responsável pela criação do nível documental
						pcArgsNivel.nRowID = nRow.ID;
						pcArgsNivel.ndRowID = ndRow.ID;
						pcArgsNivel.rhRowID = rhRow.ID;
						pcArgsNivel.rhRowIDUpper = rhRow.IDUpper;
						pcArgsNivel.frdBaseID = frdRow.ID;

						// dados para a atribuição de um código ao nível documental
						psArgsNivel.nRowID = nRow.ID;
						psArgsNivel.pcArgs = pcArgsNivel;

						if (addNewUF)
						{
							// dados que serão usados no delegate responsável pela criação da unidade física
							pcArgsUF.Operation = PersistencyHelper.AddEditUFPreConcArguments.Operations.Create;
							pcArgsUF.psa = psArgsUF;

							// dados que serão usados no delegate que fará a associação entre o nível documental e unidade física
							pcArgs.addNewUF = true;
							pcArgs.IDFRDBaseNivelDoc = frdRow.ID;
                            pcArgs.produtor = this.nivelNavigator1.SelectedNode;
							pcArgs.designacaoUFAssociada = designacaoUFAssociada;
						}

						// permitir ao delegate selecionar o delegate correspondente ao tipo de nível que se está a criar
						pcArgs.IDTipoNivelRelacionado = tnrRow.ID;

						psArgs.createNewNivelCodigo = true;
						psArgs.createNewUFCodigo = addNewUF;

                        PersistencyHelper.save(DelegatesHelper.ValidateNivelAddAndAssocNewUF, pcArgs, DelegatesHelper.SetNewCodigos, psArgs, postSaveAction);
                        
						if (! pcArgsNivel.RHNivelUpperExists)
						{
							successfulSave = false;
							MessageBox.Show(pcArgsNivel.message, "Criação de unidade de descrição", MessageBoxButtons.OK, MessageBoxIcon.Warning);
						}
                        else if (addNewUF && pcArgsUF.OperationError == PersistencyHelper.AddEditUFPreConcArguments.OperationErrors.NewUF)
                            MessageBox.Show(pcArgsUF.message, "Criar unidade física", MessageBoxButtons.OK, MessageBoxIcon.Warning);
					}
					else if (tnrRow.ID == TipoNivelRelacionado.D || tnrRow.ID == TipoNivelRelacionado.SD)
					{                     
						// se se tratar de um (sub)documento é necessário garantir que se trata de um código 
						// único dentro da sua série (se constituir série) ou nivel estrutural superior
						PersistencyHelper.ValidateNivelAddAndAssocNewUFPreConcArguments pcArgs = new PersistencyHelper.ValidateNivelAddAndAssocNewUFPreConcArguments();                                               
						PersistencyHelper.SetNewCodigosPreSaveArguments psArgs = new PersistencyHelper.SetNewCodigosPreSaveArguments();
						PersistencyHelper.EnsureUniqueCodigoNivelPreConcArguments pcArgsNivel = new PersistencyHelper.EnsureUniqueCodigoNivelPreConcArguments();
						PersistencyHelper.AddEditUFPreConcArguments pcArgsUF = new PersistencyHelper.AddEditUFPreConcArguments();
						PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments psArgsUF = new PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments();

						pcArgs.argsNivel = pcArgsNivel;
						pcArgs.argsUF = pcArgsUF;

						// dados que serão usados no delegate responsável pela criação do nível documental
						pcArgsNivel.nRowID = nRow.ID;
						pcArgsNivel.ndRowID = ndRow.ID;
						pcArgsNivel.rhRowID = rhRow.ID;
						pcArgsNivel.rhRowIDUpper = rhRow.IDUpper;
						pcArgsNivel.frdBaseID = frdRow.ID;
						pcArgsNivel.testOnlyWithinNivel = true;

						if (addNewUF)
						{
							// dados que serão usados no delegate responsável pela criação da unidade física
							pcArgsUF.Operation = PersistencyHelper.AddEditUFPreConcArguments.Operations.Create;
							pcArgsUF.psa = psArgsUF;

							// dados que serão usados no delegate que fará a associação entre o nível documental e unidade física
							pcArgs.addNewUF = true;
							pcArgs.IDFRDBaseNivelDoc = frdRow.ID;
                            pcArgs.produtor = this.nivelNavigator1.SelectedNode;
							pcArgs.designacaoUFAssociada = designacaoUFAssociada;
						}

						// permitir ao delegate selecionar o delegate correspondente ao tipo de nível que se está a criar
						pcArgs.IDTipoNivelRelacionado = tnrRow.ID;

						psArgs.createNewNivelCodigo = false;
						psArgs.createNewUFCodigo = addNewUF;
                        psArgs.setNewCodigo = rhRow.IDTipoNivelRelacionado == TipoNivelRelacionado.SD;
                        psArgs.argsUF = psArgsUF;
                        psArgs.argsNivelDocSimples = NiveisHelper.AddNivelDocumentoSimplesWithDelegateArgs(nRow.GetNivelDesignadoRows().Single(), rhRow.IDUpper, rhRow.IDTipoNivelRelacionado);

                        PersistencyHelper.save(DelegatesHelper.ValidateNivelAddAndAssocNewUF, pcArgs, DelegatesHelper.SetNewCodigos, psArgs, postSaveAction);
						if (! pcArgsNivel.successful)
						{
							successfulSave = false;
							MessageBox.Show(pcArgsNivel.message, "Criação de unidade de descrição", MessageBoxButtons.OK, MessageBoxIcon.Warning);
						}
						else if (parentNivelRow.GetRelacaoHierarquicaRowsByNivelRelacaoHierarquica()[0].TipoNivelRelacionadoRow.ID == TipoNivelRelacionado.SR)
						{
							GisaDataSetHelper.HoldOpen ho = new GisaDataSetHelper.HoldOpen(GisaDataSetHelper.GetConnection());
							try
							{
								DBAbstractDataLayer.DataAccessRules.FRDRule.Current.LoadSFRDAvaliacaoData(GisaDataSetHelper.GetInstance(), parentNivelRow.ID, ho.Connection);
							}
							finally
							{
								ho.Dispose();
							}
						}
					}
					else if (nRow.IDTipoNivel == TipoNivel.ESTRUTURAL && ! (nRow.CatCode.Trim().Equals("CA")))
					{                     
						// se se tratar de um nivel estrutural temático-funcional
						// é necessário garantir que se trata de um código único no sistema
						PersistencyHelper.EnsureUniqueCodigoNivelPreConcArguments pcArgs = new PersistencyHelper.EnsureUniqueCodigoNivelPreConcArguments();
						pcArgs.nRowID = nRow.ID;
						pcArgs.ndRowID = ndRow.ID;
						pcArgs.rhRowID = rhRow.ID;
						pcArgs.rhRowIDUpper = rhRow.IDUpper;
                        PersistencyHelper.save(DelegatesHelper.ensureUniqueCodigo, pcArgs, postSaveAction);
						if (! pcArgs.successful)
						{
							successfulSave = false;
							MessageBox.Show(pcArgs.message, "Criação de unidade de descrição", MessageBoxButtons.OK, MessageBoxIcon.Warning);
						}
					}
					else if (nRow.IDTipoNivel == TipoNivel.LOGICO && nRow.GetRelacaoHierarquicaRowsByNivelRelacaoHierarquica().Length == 0)
					{
                     	// se se tratar de uma entidade detentora
						// é necessário garantir que se trata de um código único no sistema
						PersistencyHelper.EnsureUniqueCodigoNivelPreConcArguments pcArgs = new PersistencyHelper.EnsureUniqueCodigoNivelPreConcArguments();
						pcArgs.nRowID = nRow.ID;
						pcArgs.ndRowID = ndRow.ID;
						pcArgs.testOnlyWithinNivel = true;
                        PersistencyHelper.save(DelegatesHelper.ensureUniqueCodigo, pcArgs, postSaveAction);
                        if (!pcArgs.successful)
                        {
                            successfulSave = false;
                            MessageBox.Show(pcArgs.message, "Criação de unidade de descrição", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            // forçar o refresh das entidades produtoras (qualquer outro que esteja expandido
                            // vai ser colapsado)
                            resetEstrutura();
                        }

					}
                    else if (nRow.IDTipoNivel == TipoNivel.ESTRUTURAL && nRow.CatCode.Trim().Equals("CA"))
                    {
                        GISADataset.TipoFRDBaseRow tipoFRD = 
                            (GISADataset.TipoFRDBaseRow)(GisaDataSetHelper.GetInstance().TipoFRDBase.Select("ID=" + DomainValuesHelper.stringifyEnumValue(TipoFRDBase.FRDOIRecolha))[0]);

                        if (GisaDataSetHelper.GetInstance().FRDBase.Select(string.Format("IDNivel={0} AND IDTipoFRDBase={1}", nRow.ID.ToString(), tipoFRD.ID.ToString())).Length == 0)
                        {
                            GISADataset.FRDBaseRow frdNivelDocRow = GisaDataSetHelper.GetInstance().FRDBase.AddFRDBaseRow(nRow, tipoFRD, "", "", new byte[] { }, 0);
                            GisaDataSetHelper.GetInstance().SFRDDatasProducao.AddSFRDDatasProducaoRow(frdNivelDocRow, "", "", "", "", false, "", "", "", "", false, new byte[] { }, 0);
                            GisaDataSetHelper.GetInstance().SFRDConteudoEEstrutura.AddSFRDConteudoEEstruturaRow(frdNivelDocRow, "", "", new byte[] { }, 0);
                            GisaDataSetHelper.GetInstance().SFRDContexto.AddSFRDContextoRow(frdNivelDocRow, "", "", "", false, new byte[] { }, 0);
                            GisaDataSetHelper.GetInstance().SFRDDocumentacaoAssociada.AddSFRDDocumentacaoAssociadaRow(frdNivelDocRow, "", "", "", "", new byte[] { }, 0);
                            GisaDataSetHelper.GetInstance().SFRDDimensaoSuporte.AddSFRDDimensaoSuporteRow(frdNivelDocRow, "", new byte[] { }, 0);
                            GisaDataSetHelper.GetInstance().SFRDNotaGeral.AddSFRDNotaGeralRow(frdNivelDocRow, "", new byte[] { }, 0);
                            var CurrentSFRDAvaliacao = GisaDataSetHelper.GetInstance().SFRDAvaliacao.NewSFRDAvaliacaoRow();
                            CurrentSFRDAvaliacao.FRDBaseRow = frdNivelDocRow;
                            CurrentSFRDAvaliacao.IDPertinencia = 1;
                            CurrentSFRDAvaliacao.IDDensidade = 1;
                            CurrentSFRDAvaliacao.IDSubdensidade = 1;
                            CurrentSFRDAvaliacao.Publicar = false;
                            CurrentSFRDAvaliacao.Observacoes = "";
                            CurrentSFRDAvaliacao.AvaliacaoTabela = false;
                            GisaDataSetHelper.GetInstance().SFRDAvaliacao.AddSFRDAvaliacaoRow(CurrentSFRDAvaliacao);
                            var sfrdcda = GisaDataSetHelper.GetInstance().SFRDCondicaoDeAcesso.AddSFRDCondicaoDeAcessoRow(frdNivelDocRow, "", "", "", "", new byte[] { }, 0);

                            var caRow = nRow.GetNivelControloAutRows().Single().ControloAutRow;
                            if (!caRow.IsIDIso639p2Null())
                                GisaDataSetHelper.GetInstance().SFRDLingua.AddSFRDLinguaRow(sfrdcda, caRow.Iso639Row, new byte[] { }, 0);
                            else if (globalConfig.ApplyDefaultValues)
                            {
                                foreach (GISADataset.ConfigLinguaRow r in globalConfig.GetConfigLinguaRows())
                                    GisaDataSetHelper.GetInstance().SFRDLingua.AddSFRDLinguaRow(sfrdcda, r.Iso639Row, new byte[] { }, 0);
                            }
                            
                            if (!caRow.IsIDIso15924Null())
                                GisaDataSetHelper.GetInstance().SFRDAlfabeto.AddSFRDAlfabetoRow(sfrdcda, caRow.Iso15924Row, new byte[] { }, 0);
                            else if (globalConfig.ApplyDefaultValues)
                            {
                                foreach (GISADataset.ConfigAlfabetoRow r in globalConfig.GetConfigAlfabetoRows())
                                    GisaDataSetHelper.GetInstance().SFRDAlfabeto.AddSFRDAlfabetoRow(sfrdcda, r.Iso15924Row, new byte[] { }, 0);
                            }
                        }

                        var sucessfulSave = PersistencyHelper.save(postSaveAction);
                        if(sucessfulSave == PersistencyHelper.SaveResult.successful)
                            GISA.Search.Updater.updateProdutor(nRow.GetNivelControloAutRows()[0].IDControloAut);

                    }
                    else
                        PersistencyHelper.save(postSaveAction);

                    PersistencyHelper.cleanDeletedData(new List<TableDepthOrdered.TableCloudType>(new TableDepthOrdered.TableCloudType[] { PersistencyHelper.determinaNuvem("RelacaoHierarquica"), PersistencyHelper.determinaNuvem("FRDBase") }));

					if (! successfulSave)
						return successfulSave;

					// Para as EDs
					if (rhRow == null)
					{
						//update data
						resetEstrutura();
					}
					else
					{
                        if (addNewUF)
                        {
                            // registar a criação da unidade física
                            GISADataset.FRDBaseRow frdUFRow =
                                nRow.GetFRDBaseRows()[0].GetSFRDUnidadeFisicaRows()[0].NivelRow.GetFRDBaseRows()[0];
                            GISA.Search.Updater.updateUnidadeFisica(frdUFRow.IDNivel);
                        }

                        if (nRow.IDTipoNivel == TipoNivel.DOCUMENTAL)
                        {
                            GISA.Search.Updater.updateNivelDocumentalComProdutores(nRow.ID);
                            GISA.Search.Updater.updateNivelDocumental(nRow.ID);
                        }

                        if (this.nivelNavigator1.PanelToggleState == NivelNavigator.ToggleState.Estrutural)
                            this.nivelNavigator1.RefreshTreeViewControlSelectedBranch();
						else
                            this.nivelNavigator1.AddNivel(nRow);
					}
                    Debug.WriteLine("<<A criar nível...>> " + new TimeSpan(DateTime.Now.Ticks - click).ToString());
					break;
				}
				case DialogResult.Cancel:
				{
					successfulSave = false;
					break;
				}
			}

			return successfulSave;
		}       
		private void DuplicateUF()
		{
            if (!ValidateSelection())
                return;

			GISADataset.NivelRow nufRow = (GISADataset.NivelRow)(ufList.SelectedItems[0].Tag);

            //forçar uma mudança de contexto para que a unidade física seleccionada seja gravada
            ufList.ClearItemSelection(ufList.SelectedItems[0]);

            //testar se a unidade física não foi apagada por outro utilizador entretanto
            if (nufRow == null || nufRow.RowState == DataRowState.Detached)
            {
                MessageBox.Show("A unidade física a ser duplicada foi eliminada por outro utilizador " + System.Environment.NewLine + 
                    "pelo que a operação não pode ser concluída.",
                    "Duplicação da unidade física", 
                    MessageBoxButtons.OK, 
                    MessageBoxIcon.Warning);

                return;
            }

            Trace.WriteLine("A duplicar unidade física id: " + nufRow.ID);

            PersistencyHelper.AddEditUFPreConcArguments argsPC = new PersistencyHelper.AddEditUFPreConcArguments();
            PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments argsPS = new PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments();

			//carregar toda a informação da unidade física a ser duplicada
			GisaDataSetHelper.HoldOpen ho = new GisaDataSetHelper.HoldOpen(GisaDataSetHelper.GetConnection());
			try
			{
                GisaDataSetHelper.ManageDatasetConstraints(false);
				DBAbstractDataLayer.DataAccessRules.UFRule.Current.LoadUF(GisaDataSetHelper.GetInstance(), nufRow.ID, ho.Connection);
			}
			catch (Exception ex)
			{
				Trace.WriteLine(ex.ToString());
				throw;
			}
			finally
			{
				ho.Dispose();
                GisaDataSetHelper.ManageDatasetConstraints(true);
			}

			//duplicar uf seleccionada
			GISADataset.TipoNivelRelacionadoRow tnrRow = (GISADataset.TipoNivelRelacionadoRow)(GisaDataSetHelper.GetInstance().TipoNivelRelacionado. Select(string.Format("ID={0}", TipoNivelRelacionado.UF))[0]);

			GISADataset.NivelDesignadoRow ndufRow = nufRow.GetNivelDesignadoRows()[0];
			GISADataset.NivelUnidadeFisicaRow nivelUFRow = ndufRow.GetNivelUnidadeFisicaRows()[0];
			GISADataset.RelacaoHierarquicaRow rhufRow = nufRow.GetRelacaoHierarquicaRowsByNivelRelacaoHierarquica()[0];
			GISADataset.NivelRow nedRow = rhufRow.NivelRowByNivelRelacaoHierarquicaUpper;
			GISADataset.FRDBaseRow[] frdufRows = nufRow.GetFRDBaseRows();
			GISADataset.FRDBaseRow newfrdufRow = null;
            GISADataset.LocalConsultaRow newLocalConsultaRow = nivelUFRow.IsIDLocalConsultaNull() ? null : nivelUFRow.LocalConsultaRow;

			GISADataset.NivelRow newNufRow = GisaDataSetHelper.GetInstance().Nivel.AddNivelRow(nufRow.TipoNivelRow, nufRow.Codigo, nufRow.CatCode, new byte[]{}, 0);
			ndufRow = GisaDataSetHelper.GetInstance().NivelDesignado.AddNivelDesignadoRow(newNufRow, ndufRow.Designacao, new byte[]{}, 0);
            GISADataset.TipoEntregaRow teRow = null;
            if (!nivelUFRow.IsIDTipoEntregaNull())
                teRow = (GISADataset.TipoEntregaRow)
                    (GisaDataSetHelper.GetInstance().TipoEntrega.Select("ID=" + nivelUFRow.IDTipoEntrega)[0]);
            nivelUFRow = GisaDataSetHelper.GetInstance().NivelUnidadeFisica.AddNivelUnidadeFisicaRow(ndufRow, GisaDataSetHelper.GetDBNullableText(nivelUFRow, "GuiaIncorporacao"), GisaDataSetHelper.GetDBNullableText(nivelUFRow, "CodigoBarras"), new byte[] { }, 0, false, teRow, newLocalConsultaRow);
			rhufRow = GisaDataSetHelper.GetInstance().RelacaoHierarquica.AddRelacaoHierarquicaRow(newNufRow, nedRow, tnrRow, GisaDataSetHelper.GetDBNullableText(rhufRow, "Descricao"), GisaDataSetHelper.GetDBNullableText(rhufRow, "InicioAno"), GisaDataSetHelper.GetDBNullableText(rhufRow, "InicioMes"), GisaDataSetHelper.GetDBNullableText(rhufRow, "InicioDia"), GisaDataSetHelper.GetDBNullableText(rhufRow, "FimAno"), GisaDataSetHelper.GetDBNullableText(rhufRow, "FimMes"), GisaDataSetHelper.GetDBNullableText(rhufRow, "FimDia"), new byte[]{}, 0);

			GISADataset.SFRDDatasProducaoRow dpufRow = null;
			GISADataset.SFRDUFCotaRow cufRow = null;
			GISADataset.SFRDConteudoEEstruturaRow conteudoufRow = null;
            GISADataset.SFRDDatasProducaoRow[] dpufRows;
            GISADataset.SFRDUFCotaRow[] cufRows;
            GISADataset.SFRDConteudoEEstruturaRow[] conteudoufRows;
            GISADataset.SFRDUFDescricaoFisicaRow[] descricaoFisicaRows;
			GISADataset.SFRDUFDescricaoFisicaRow newDescricaoFisicaRow = null;
			if (frdufRows.Length > 0)
			{
				newfrdufRow = GisaDataSetHelper.GetInstance().FRDBase.AddFRDBaseRow(newNufRow, frdufRows[0].TipoFRDBaseRow, GisaDataSetHelper.GetDBNullableText(frdufRows[0], "NotaDoArquivista"), GisaDataSetHelper.GetDBNullableText(frdufRows[0], "RegrasOuConvencoes"), new byte[]{}, 0);
				argsPC.frdufRowID = newfrdufRow.ID;
				dpufRows = frdufRows[0].GetSFRDDatasProducaoRows();
				cufRows = frdufRows[0].GetSFRDUFCotaRows();
				conteudoufRows = frdufRows[0].GetSFRDConteudoEEstruturaRows();
				descricaoFisicaRows = frdufRows[0].GetSFRDUFDescricaoFisicaRows();

                if (dpufRows.Length > 0)
                    dpufRow = GisaDataSetHelper.GetInstance().SFRDDatasProducao.AddSFRDDatasProducaoRow(
                        newfrdufRow, 
                        GisaDataSetHelper.GetDBNullableText(dpufRows[0], "InicioTexto"),
                        GisaDataSetHelper.GetDBNullableText(dpufRows[0], "InicioAno"), 
                        GisaDataSetHelper.GetDBNullableText(dpufRows[0], "InicioMes"), 
                        GisaDataSetHelper.GetDBNullableText(dpufRows[0], "InicioDia"), 
                        dpufRows[0].InicioAtribuida, 
                        GisaDataSetHelper.GetDBNullableText(dpufRows[0], "FimTexto"), 
                        GisaDataSetHelper.GetDBNullableText(dpufRows[0], "FimAno"), 
                        GisaDataSetHelper.GetDBNullableText(dpufRows[0], "FimMes"), 
                        GisaDataSetHelper.GetDBNullableText(dpufRows[0], "FimDia"), 
                        dpufRows[0].FimAtribuida, 
                        new byte[] { }, 0);

                if (cufRows.Length > 0)
                    cufRow = GisaDataSetHelper.GetInstance().SFRDUFCota.AddSFRDUFCotaRow(
                        newfrdufRow, 
                        GisaDataSetHelper.GetDBNullableText(cufRows[0], "Cota"), 
                        new byte[]{}, 0);

                if (conteudoufRows.Length > 0)
                    conteudoufRow = GisaDataSetHelper.GetInstance().SFRDConteudoEEstrutura.AddSFRDConteudoEEstruturaRow(
                        newfrdufRow, 
                        GisaDataSetHelper.GetDBNullableText(conteudoufRows[0], "ConteudoInformacional"), 
                        GisaDataSetHelper.GetDBNullableText(conteudoufRows[0], "Incorporacao"), 
                        new byte[]{}, 0);

				newDescricaoFisicaRow = GisaDataSetHelper.GetInstance().SFRDUFDescricaoFisica.NewSFRDUFDescricaoFisicaRow();
				newDescricaoFisicaRow.FRDBaseRow = newfrdufRow;

                if (descricaoFisicaRows.Length > 0)
                {
                    newDescricaoFisicaRow.TipoAcondicionamentoRow = descricaoFisicaRows[0].TipoAcondicionamentoRow;
                    newDescricaoFisicaRow.TipoMedidaRow = descricaoFisicaRows[0].TipoMedidaRow;
                    newDescricaoFisicaRow.Versao = new byte[] { };
                    newDescricaoFisicaRow.isDeleted = 0;
                    if (!(descricaoFisicaRows[0]["MedidaLargura"] == DBNull.Value))
                        newDescricaoFisicaRow.MedidaLargura = descricaoFisicaRows[0].MedidaLargura;

                    if (!(descricaoFisicaRows[0]["MedidaAltura"] == DBNull.Value))
                        newDescricaoFisicaRow.MedidaAltura = descricaoFisicaRows[0].MedidaAltura;

                    if (!(descricaoFisicaRows[0]["MedidaProfundidade"] == DBNull.Value))
                        newDescricaoFisicaRow.MedidaProfundidade = descricaoFisicaRows[0].MedidaProfundidade;
                }

				GisaDataSetHelper.GetInstance().SFRDUFDescricaoFisica.AddSFRDUFDescricaoFisicaRow(newDescricaoFisicaRow);
			}

			List<long> uaAssociadas = new List<long>();
			foreach (GISADataset.SFRDUnidadeFisicaRow sfrdUA in nufRow.GetSFRDUnidadeFisicaRows())
			{
				GisaDataSetHelper.GetInstance().SFRDUnidadeFisica.AddSFRDUnidadeFisicaRow(sfrdUA.FRDBaseRow, newNufRow, null, new byte[]{}, 0);
				uaAssociadas.Add(sfrdUA.FRDBaseRow.ID);
			}

			argsPC.Operation = PersistencyHelper.AddEditUFPreConcArguments.Operations.CreateLike;
			argsPC.nivelUFRowID = newNufRow.ID;
			argsPC.ndufRowID = ndufRow.ID;
			argsPC.rhufRowID = rhufRow.ID;
			argsPC.rhufRowIDUpper = rhufRow.IDUpper;
			argsPC.nufufRowID = nivelUFRow.ID;
			argsPC.uaAssociadas = uaAssociadas;

			argsPS.nivelUFRowID = nivelUFRow.ID;
			argsPC.psa = argsPS;

            var postSaveAction = new PostSaveAction();
            PersistencyHelper.UpdatePermissionsPostSaveArguments args = new PersistencyHelper.UpdatePermissionsPostSaveArguments();
            postSaveAction.args = args;

            postSaveAction.postSaveDelegate = delegate(PersistencyHelper.PostSaveArguments postSaveArgs)
            {
                if (!postSaveArgs.cancelAction && argsPC.OperationError == PersistencyHelper.AddEditUFPreConcArguments.OperationErrors.NoError)
                {
                    CurrentContext.RaiseRegisterModificationEvent(newfrdufRow);
                    PersistencyHelperRule.Current.saveRows(GisaDataSetHelper.GetInstance().FRDBaseDataDeDescricao,
                        GisaDataSetHelper.GetInstance().FRDBaseDataDeDescricao.Cast<GISADataset.FRDBaseDataDeDescricaoRow>().Where(frd => frd.RowState == DataRowState.Added).ToArray(), postSaveArgs.tran);
                }
            };

            PersistencyHelper.SaveResult successfulSave = PersistencyHelper.save(DelegatesHelper.HandleUF, argsPC, DelegatesHelper.SetCodigo, argsPS, postSaveAction);
            PersistencyHelper.cleanDeletedData(PersistencyHelper.determinaNuvem("NivelUnidadeFisica"));

			try
			{
				if (argsPC.OperationError == PersistencyHelper.AddEditUFPreConcArguments.OperationErrors.NewUF)
				{
					MessageBox.Show(argsPC.message, "Criar unidade física", MessageBoxButtons.OK, MessageBoxIcon.Warning);
				}
				else
				{
                    // adicionar a unidade física à lista
					ufList.AddNivel(newNufRow);

                    // actualizar o índice
                    if (successfulSave == PersistencyHelper.SaveResult.successful)
                    {
                        ho = new GisaDataSetHelper.HoldOpen(GisaDataSetHelper.GetConnection());
                        try
                        {
                            List<string> IDNiveis = DBAbstractDataLayer.DataAccessRules.UFRule.Current.GetNiveisDocAssociados(newNufRow.ID, ho.Connection);
                            GISA.Search.Updater.updateNivelDocumental(IDNiveis);
                            GISA.Search.Updater.updateUnidadeFisica(newfrdufRow.NivelRow.ID);
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine(ex.ToString());
                            throw;
                        }
                        finally
                        {
                            ho.Dispose();
                        }
                    }
				}
			}
			catch (Exception ex)
			{
				Trace.WriteLine("Exception while refreshing data: " + ex.ToString());
				throw;
			}
		}
        public static void ImportFromExcel(string fileLocation)
        {   
            ImportExcel imp = null;
            string fileExtension = fileLocation.Split('.').Last();

            if (fileExtension.Equals("xls")) 
                imp = new ImportExcel97to2003(fileLocation);
            else if (fileExtension.Equals("xlsx"))
                imp = new ImportExcel2007Up(fileLocation);
            else
            {
                MessageBox.Show("O formato '" + fileExtension + "' não é reconhecido.", TAG, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            
            try
            {
                imp.Import();

                var uiList = imp.GetUnidadesInformacionais;
                var ufList = imp.GetUnidadesFisicas;

                // validar campos obrigatorios
                uiList.ToList().ForEach(ui => ValidaCamposObrigatorios(ui));
                ufList.ToList().ForEach(uf => ValidaCamposObrigatorios(uf));

                // validar se não há identificadores repetidos
                var rep = ValidaIdentificadores(uiList.Select(ui => ui.identificador));
                if (rep != null)
                    ExceptionHelper.ThrowException(ExceptionHelper.TAB_DOCUMENTOS, string.Empty, ImportExcel.UI_IDENTIFICADOR, rep.First(), ExceptionHelper.ERR_VALOR_REPETIDO);

                rep = ValidaIdentificadores(ufList.Select(uf => uf.identificador));
                if (rep != null)
                    ExceptionHelper.ThrowException(ExceptionHelper.TAB_UNIDADES_FISICAS, string.Empty, ImportExcel.UI_IDENTIFICADOR, rep.First(), ExceptionHelper.ERR_VALOR_REPETIDO);

                // validar se não há códigos de referência repetidos por nível superior
                ValidaCodigosReferencia(uiList);

                unidadesInformacionais = uiList.ToDictionary(ui => ui.identificador, ui => ui);
                unidadesFisicas = ufList.ToDictionary(uf => uf.identificador, uf => uf);

                var niveisDoc = unidadesInformacionais.Values.Where(ui => ui.idNivelSuperior != null && ui.idNivelSuperior.Length > 0 && ui.idNivelSuperior.StartsWith("gisa:")).Select(ui => ui.idNivelSuperior.Replace("gisa:", "")).Distinct();
                var niveisUfAssoc = unidadesInformacionais.Values.SelectMany(ui => ui.unidadesFisicas).Where(uf => uf.StartsWith("gisa_uf:")).Select(uf => uf.Replace("gisa_uf:", "").Split('/')[1]).Distinct();
                var entidadesProdutoras = unidadesInformacionais.Values.SelectMany(ui => ui.entidadesProdutoras).Distinct();
                var autores = unidadesInformacionais.Values.SelectMany(ui => ui.autores).Distinct();
                var modelos = unidadesInformacionais.Values.SelectMany(ui => ui.modelo).Distinct();
                var diplomas = unidadesInformacionais.Values.SelectMany(ui => ui.diplomaLegal).Distinct();
                var onomasticos = unidadesInformacionais.Values.SelectMany(ui => ui.onomasticos).Distinct();
                var ideograficos = unidadesInformacionais.Values.SelectMany(ui => ui.ideograficos).Distinct();
                var geograficos = unidadesInformacionais.Values.SelectMany(ui => ui.geograficos).Distinct();
                var tipologias = unidadesInformacionais.Values.Where(ui => ui.tipoInformacional != null && ui.tipoInformacional.Length > 0).Select(val => val.tipoInformacional).Distinct();

                var cas = new List<string>();
                cas.AddRange(entidadesProdutoras);
                cas.AddRange(autores);
                cas.AddRange(modelos);
                cas.AddRange(diplomas);
                cas.AddRange(onomasticos);
                cas.AddRange(ideograficos);
                cas.AddRange(geograficos);
                cas.AddRange(tipologias);

                // load data
                LoadEDsInfo();
                LoadNiveisDoc(niveisDoc.ToList());
                LoadNiveisUfAssoc(niveisUfAssoc.ToList());
                LoadControlosAutoridade(cas.Distinct().ToList());
                LoadTrustees();
                LoadLocalConsulta();

                // importação para o data set
                GisaDataSetHelper.ManageDatasetConstraints(false);

                uiRows = new Dictionary<string, GISADataset.NivelRow>();
                ufRows = new Dictionary<string, GISADataset.NivelRow>();
                registos = new Dictionary<GISADataset.FRDBaseRow, Registo>();

                unidadesInformacionais.Keys.ToList().ForEach(key =>
                {
                    if (!uiRows.ContainsKey(key))
                        UIsToGISADatasetRow(unidadesInformacionais[key]);
                });

                unidadesFisicas.Keys.ToList().ForEach(key =>
                {
                    if (!ufRows.ContainsKey(key))
                        UFsToGISADatasetRows(unidadesFisicas[key]);
                });
                

                GisaDataSetHelper.ManageDatasetConstraints(true);

                var pcArgs = new PersistencyHelper.ValidaImportPreConcArguments();
                var psArgs = new PersistencyHelper.ValidaImportPreSaveArguments();

                var pcArgsLstUI = new List<PersistencyHelper.ValidateNivelAddAndAssocNewUFPreConcArguments>();
                var psArgsNivelLstUI = new List<PersistencyHelper.SetNewCodigosPreSaveArguments>();
                foreach (var nRow in uiRows.Values)
                {
                    var pcArgsNewNivel = new PersistencyHelper.ValidateNivelAddAndAssocNewUFPreConcArguments();
                    var psArgsNivel = new PersistencyHelper.SetNewCodigosPreSaveArguments();
                    var pcArgsNivelUniqueCode = new PersistencyHelper.EnsureUniqueCodigoNivelPreConcArguments();

                    // dados que serão usados no delegate responsável pela criação do nível documental
                    var rhRow = nRow.GetRelacaoHierarquicaRowsByNivelRelacaoHierarquica().Single();
                    pcArgsNivelUniqueCode.nRowID = nRow.ID;
                    pcArgsNivelUniqueCode.ndRowID = nRow.GetNivelDesignadoRows().Single().ID;
                    pcArgsNivelUniqueCode.rhRowID = nRow.ID;
                    pcArgsNivelUniqueCode.rhRowIDUpper = rhRow.IDUpper;
                    pcArgsNivelUniqueCode.frdBaseID = nRow.GetFRDBaseRows().Single().ID;
                    pcArgsNivelUniqueCode.testOnlyWithinNivel = true;

                    pcArgsNewNivel.IDTipoNivelRelacionado = rhRow.IDTipoNivelRelacionado;
                    pcArgsNewNivel.argsNivel = pcArgsNivelUniqueCode;

                    psArgsNivel.createNewNivelCodigo = false;
                    psArgsNivel.createNewUFCodigo = false;
                    psArgsNivel.setNewCodigo = rhRow.IDTipoNivelRelacionado == TipoNivelRelacionado.SD;
                    psArgsNivel.argsNivelDocSimples = NiveisHelper.AddNivelDocumentoSimplesWithDelegateArgs(nRow.GetNivelDesignadoRows().Single(), rhRow.IDUpper, rhRow.IDTipoNivelRelacionado);

                    pcArgsLstUI.Add(pcArgsNewNivel);
                    psArgsNivelLstUI.Add(psArgsNivel);
                }

                pcArgs.newDocsList = pcArgsLstUI;
                psArgs.newDocArgs = psArgsNivelLstUI;

                var pcArgsLstUF = new List<PersistencyHelper.AddEditUFPreConcArguments>();
                var psArgsLstUF = new List<PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments>();
                foreach (var nRow in ufRows.Values)
                {
                    var argsPC = new PersistencyHelper.AddEditUFPreConcArguments();
                    var argsPS = new PersistencyHelper.IsCodigoUFBeingUsedPreSaveArguments();

                    argsPC.Operation = PersistencyHelper.AddEditUFPreConcArguments.Operations.Create;

                    argsPC.nivelUFRowID = nRow.ID;
                    argsPC.ndufRowID = nRow.GetNivelDesignadoRows().First().ID;
                    argsPC.rhufRowID = nRow.GetRelacaoHierarquicaRowsByNivelRelacaoHierarquica().First().ID;
                    argsPC.rhufRowIDUpper = nRow.GetRelacaoHierarquicaRowsByNivelRelacaoHierarquica().First().IDUpper;
                    argsPC.nufufRowID = nRow.GetNivelDesignadoRows().First().GetNivelUnidadeFisicaRows().First().ID;
                    argsPC.frdufRowID = nRow.GetFRDBaseRows().First().ID;

                    argsPS.nivelUFRowID = nRow.ID;
                    argsPC.psa = argsPS;

                    pcArgsLstUF.Add(argsPC);
                    psArgsLstUF.Add(argsPS);
                }

                pcArgs.newUfsList = pcArgsLstUF;
                psArgs.newUfArgs = psArgsLstUF;

                // actualizar permissões implícitas
                var postSaveAction = new PostSaveAction();
                PersistencyHelper.UpdatePermissionsPostSaveArguments args = new PersistencyHelper.UpdatePermissionsPostSaveArguments();
                postSaveAction.args = args;

                postSaveAction.postSaveDelegate = delegate(PersistencyHelper.PostSaveArguments postSaveArgs)
                {
                    var regs = registos.Keys
                        .Select(key => RecordRegisterHelper.CreateFRDBaseDataDeDescricaoRow(registos[key].CurrentFRDBase, registos[key].tuOperator, registos[key].tuAuthor, registos[key].data, true))
                        .ToArray();

                    regs.ToList().ForEach(reg => GisaDataSetHelper.GetInstance().FRDBaseDataDeDescricao.AddFRDBaseDataDeDescricaoRow(reg));

                    PersistencyHelperRule.Current.saveRows(GisaDataSetHelper.GetInstance().FRDBaseDataDeDescricao, regs, postSaveArgs.tran);
                };

                var saveResult = PersistencyHelper.save(ValidateImport, pcArgs, ValidateImport, psArgs, postSaveAction, true);

                if (saveResult == PersistencyHelper.SaveResult.cancel || saveResult == PersistencyHelper.SaveResult.unsuccessful)
                {
                    string errorMessage = "";
                    string abortMessage = "A importação vai ser abortada.";
                    if (pcArgs.errorMessage.Length > 0)
                        errorMessage = pcArgs.errorMessage + System.Environment.NewLine + System.Environment.NewLine + abortMessage;
                    else if (psArgs.errorMessage.Length > 0)
                        errorMessage = psArgs.errorMessage + System.Environment.NewLine + System.Environment.NewLine + abortMessage;
                    else
                        errorMessage = "Ocorreu um problema inesperado." + System.Environment.NewLine + abortMessage;

                    MessageBox.Show(errorMessage, TAG, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    GisaDataSetHelper.GetInstance().RejectChanges();
                    return;
                }

                var nUiIds = uiRows.Values.Select(r => r.ID.ToString()).ToList();
                var nUfIds = ufRows.Values.Select(r => r.ID.ToString()).ToList();
                GISA.Search.Updater.updateNivelDocumental(nUiIds);
                GISA.Search.Updater.updateNivelDocumentalComProdutores(nUiIds);
                GISA.Search.Updater.updateUnidadeFisica(nUfIds);

                PersistencyHelper.cleanDeletedData();

                MessageBox.Show("Importação concluída com sucesso.", TAG, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex);
                MessageBox.Show("Ocorreu um erro durante a importação." + System.Environment.NewLine + "A operação foi cancelada.", TAG, MessageBoxButtons.OK, MessageBoxIcon.Error);
                GisaDataSetHelper.GetInstance().RejectChanges();
            }
        }