Example #1
0
    def obter_fluxo_inicial(self, documento):
        """
        Retorna o fluxo de acordo com a query para pegar o fluxo inicial de uma tramitacao:

        “SELECT F.* FROM FLUXOS F WHERE F.SITUACAO_ATUAL = 1 AND F.IND_ATIVO = ‘S’ AND F.ID_TIPO_DOC =
        :ID_TIPO_DOC”

        :param documento:
        :return:
        """
        params = {
            "ID_TIPO_DOC": documento["ID_TIPO_DOC"],
            "SITUACAO_ATUAL": 1,
            "IND_ATIVO": "S",
        }

        fluxos = self.api.get(self.fluxo_path, params, bypass_no_content_exception=True)

        if len(fluxos) == 0:
            raise SIEException("Nao foi possivel obter o fluxo inical para o tipo de documento especificado.")

        if len(fluxos) > 2:
            raise SIEException("Tipo de documento possui mais de um fluxo inicial definido. Escolha um manualmente.")

        return fluxos.first()
Example #2
0
    def _marcar_tramitacao_atual_entregue(self, documento, fluxo, resolvedor_destino=None):
        """
        Marca a tramitacao atual como entregue, atualiza os campos necessarios e define o fluxo especificado na tramitacao.

        :param documento: Um dicionario contendo uma entrada da tabela DOCUMENTOS
        :type documento: dict
        :param fluxo: Um dicionario referente a uma entrada na tabela FLUXOS
        :type fluxo: dict
        :param resolvedor_destino: eh um callable que resolve o destino dado um fluxo que tenha a flag IND_QUERY='S', ou seja, o tipo_destino e id_destino devem ser obtidos atraves de uma query adicional. O retorno deve ser uma tupla (tipo_destino, id_destino).
        :type resolvedor_destino: callable
        :raises: SIEException
        """

        try:
            # Pega a tramitacao atual
            tramitacao = self.obter_tramitacao_atual(documento)  # Espera uma linha de tramitação com status 'T'

            if self.__is_destino_fluxo_definido_externamente(fluxo):
                if not resolvedor_destino:
                    raise SIEException("Nao eh possivel tramitar um documento atraves de um fluxo que possui a flag IND_QUERY='S' sem ter especificado uma callable para resolver o destino (id/tipo)")

                tipo_destino, id_destino = resolvedor_destino(fluxo)
                fluxo.update({'TIPO_DESTINO': tipo_destino, 'ID_DESTINO': id_destino})

            # atualizando a tramitacao
            tramitacao.update({
                "TIPO_DESTINO": fluxo["TIPO_DESTINO"],
                "ID_DESTINO": fluxo["ID_DESTINO"],
                "DT_ENVIO": date.today(),
                "DT_VALIDADE": self.__calcular_data_validade(date.today(), fluxo["NUM_DIAS"]),
                "DESPACHO": fluxo["TEXTO_DESPACHO"],
                "DESPACHO_RTF": fluxo["TEXTO_DESPACHO"],
                "SITUACAO_TRAMIT": SIEDocumentoDAO.TRAMITACAO_SITUACAO_ENTREGUE,
                "IND_RETORNO_OBRIG": SIEDocumentoDAO.TRAMITACAO_IND_RETORNO_OBRIG_CONFORME_FLUXO,
                "ID_FLUXO": fluxo["ID_FLUXO"],
                "DT_ALTERACAO": date.today(),
                "HR_ALTERACAO": strftime("%H:%M:%S"),
                "CONCORRENCIA": tramitacao["CONCORRENCIA"] + 1,
                "ID_USUARIO_INFO": self.usuario["ID_USUARIO"],
                "DT_DESPACHO": date.today(),
                "HR_DESPACHO": strftime("%H:%M:%S"),
                "ID_APLIC_ACAO": fluxo["ID_APLIC_ACAO"]
            })

            self.api.put(self.tramite_path, tramitacao)

            try:
                self.atualizar_situacao_documento(documento, fluxo)
            except APIException as e:
                raise SIEException("Nao foi possivel atualizar o documento", e)

        except (APIException, SIEException) as e:
            raise SIEException("Nao foi possivel tramitar o documento", e)
Example #3
0
    def reverter_ultimo_numero_processo(self):
        """ Reverte a geracao do ultimo numero de processo. """
        params = {"ID_TIPO_DOC": self.id_tipo_doc, "ANO_TIPO_DOC": self.ano}
        fields = ["NUM_ULTIMO_DOC"]

        try:
            valor_anterior = self.api.get_single_result(self.path, params, fields)["NUM_ULTIMO_DOC"] - 1  # TODO resolver problema de concorrencia
            try:
                self.__atualizar_ultimo_numero_tipo_documento(valor_anterior)
            except Exception as e:
                raise SIEException("Erro ao reverter geracao de numero de processo.", e)
        except ValueError as e:
            raise SIEException("Nao existem registros de numeros de processo para o tipo de documento " + str(self.id_tipo_doc), e)
Example #4
0
    def __proximo_numero_tipo_documento(self):
        """
        O metodo retorna qual sera o proximo NUM_TIPO_DOC que sera utilizado. Caso ja exista
        uma entrada nesta tabela para o ANO_TIPO_DOC e ID_TIPO_DOC, retornara o ultimo numero,
        caso contrario, uma nova entrada sera criada.

        :rtype: int
        :raises: SIEException
        """
        params = {"ID_TIPO_DOC": self.id_tipo_doc, "ANO_TIPO_DOC": self.ano}
        fields = ["NUM_ULTIMO_DOC"]

        try:
            numero_novo = self.api.get_single_result(self.path, params, fields)["NUM_ULTIMO_DOC"] + 1  # TODO resolver problema de concorrencia

            try:
                self.__atualizar_ultimo_numero_tipo_documento(numero_novo)
            except Exception as e:
                raise SIEException("Erro ao atualizar contador numero de processo para o tipo de documento %d" % self.id_tipo_doc, e)
        except ValueError as e:
            # caso nao exista uma entrada na tabela, criar uma para comecar a gerir a sequencia de numeros de processo para esse tipo de documento/ano
            # SIEException("Não existe entrada na tabela de numeros de processo para o tipo de documento %d" % self.id_tipo_doc, e)
            self.atualizar_indicadores_default()
            numero_novo = self.criar_novo_numero_tipo_documento()

        return numero_novo
Example #5
0
    def registrar_projeto(self, id_projeto):
        """
        Cria o documento e tramita para DPQ. Muda status do projeto tb.
        :param id_projeto:
        :return:
        :rtype: bool
        """

        #verificar se tem classificações
        classificacoes_projeto = SIEClassifProjetos().get_classificacoes_cnpq(id_projeto)
        grupos_projeto = SIEClassifProjetos().get_grupos_cnpq(id_projeto)
        camara_pesquisa = SIEClassifProjetos().get_camara_pesquisa(id_projeto)

        if not camara_pesquisa or not classificacoes_projeto or not grupos_projeto:
            raise SIEException("Projeto não cadastrado. Favor informar as classificações na aba anterior.")


        documento_projeto = self.documento_inicial_padrao()
        documentoDAO = SIEDocumentoDAO()
        documento = documentoDAO.criar_documento(documento_projeto)  # PASSO 1

        # marcando a maneira de lidar com o fluxo caso o destino esteja em uma query (IND_QUERY='S')
        # resolvedor_destino = lambda fluxo: self.resolve_destino_tramitacao(fluxo, id_projeto) # Era usado anteriormente. Deixando aqui pois pode server para depois.

        # faz a primeira tramitação
        fluxo = documentoDAO.obter_fluxo_inicial(documento)
        documentoDAO.tramitar_documento(documento, fluxo)

        projeto = {
            "ID_PROJETO": id_projeto,
            "ID_DOCUMENTO": documento['ID_DOCUMENTO'],
            "NUM_PROCESSO": documento['NUM_PROCESSO']
        }

        return self.atualizar_projeto(projeto)
Example #6
0
    def deletar_candidatos(self, candidatos):
        try:
            for candidato in candidatos:
                params = {"ID_CANDIDATOS_BOLSISTA": candidato["ID_CANDIDATOS_BOLSISTA"]}

                # Deletar linha do candidato
                self.api.delete(self.path, params)
                # plano de estudo relacionado.
                SIEArquivosProj().deletar_arquivo(candidato["ID_PLANO_ESTUDO"])

        except APIException as e:
            raise SIEException("Não foi possível deletar candidato a bolsista", e)
        return True
Example #7
0
    def obter_tramitacao_atual(self, documento):
        """
        Retorna a tramitacao atual (mais recente) do documento.
        :param documento: Um dicionario contendo uma entrada da tabela DOCUMENTOS
        :type documento: dict
        :return: Uma dicionario correspondente a uma entrada da tabela TRAMITACOES
        :rtype : dict
        :raises: SIEException
        """
        try:
            params = {
                "ID_DOCUMENTO": documento['ID_DOCUMENTO'],
                "ORDERBY": "SEQUENCIA",
                "SORT": "DESC"
            }
            # Pega a tramitacao atual
            tramitacao = self.api.get_single_result(self.tramite_path, params)
        except APIException as e:
            raise SIEException("Nao foi possivel obter tramitacao", e)

        return tramitacao
Example #8
0
    def descricaoDeItem(self, ITEM_TABELA, COD_TABELA):
        """
        Método de conveniência para

        :type ITEM_TABELA: int
        :type COD_TABELA: int
        :param ITEM_TABELA:
        :param COD_TABELA:
        :return:
        """
        params = {
            "ITEM_TABELA": ITEM_TABELA,
            "COD_TABELA": COD_TABELA,
            "LMIN": 0,
            "LMAX": 1
        }
        fields = ["DESCRICAO"]
        try:
            return self.api.get(self.path, params, fields, cache_time=self.cacheTime).first()["DESCRICAO"]
        except NoContentException as e:
            raise SIEException("Descrição não encontrada.", e)
Example #9
0
    def _marcar_tramitacao_atual_recebida(self,documento):
        """
        Marca o documento como recebido na tramitacao atual do documento
        Esse metodo deve ser usado para emular a abertura da tramitacao atraves da caixa postal do SIE.

        :param documento: Um dicionario contendo uma entrada da tabela DOCUMENTOS
        :type documento: dict
        :raises: SIEException
        """
        try:
            # Pega a tramitacao atual
            tramitacao = self.obter_tramitacao_atual(documento)
            tramitacao.update({
                "SITUACAO_TRAMIT": SIEDocumentoDAO.TRAMITACAO_SITUACAO_RECEBIDO,
                "DT_ALTERACAO": date.today(),
                "HR_ALTERACAO": strftime("%H:%M:%S"),
            })

            self.api.put(self.tramite_path, tramitacao)

        except (APIException, SIEException) as e:
            raise SIEException("Nao foi possivel tramitar o documento", e)
Example #10
0
    def _criar_registro_tramitacao(self,documento):
        """
        Cria um registro novo na tabela de tramitacoes para esse documento.

        :param documento: Um dicionario contendo uma entrada da tabela DOCUMENTOS
        :type documento: dict
        :return: Retorna a linha de tramitacao recem criada
        :rtype: dict
        :raises: SIEException
        """

        # pegar a mais recente do documento
        tramitacao_anterior = self.obter_tramitacao_atual(documento)

        # so deveriamos criar um registro novo caso a tramitacao anterior estiver no estado SIEDocumentoDAO.TRAMITACAO_SITUACAO_RECEBIDO
        # essa restricao pode conflitar com dados antigos e incosistentes
        if tramitacao_anterior["SITUACAO_TRAMIT"] != SIEDocumentoDAO.TRAMITACAO_SITUACAO_RECEBIDO:
            raise SIEException("Tramitacao anterior ainda nao foi processada")

        tramitacao_params = {
            "SEQUENCIA": tramitacao_anterior["SEQUENCIA"] + 1,
            "ID_DOCUMENTO": documento["ID_DOCUMENTO"],
            "TIPO_ORIGEM": documento["TIPO_PROPRIETARIO"],
            "ID_ORIGEM": documento["ID_PROPRIETARIO"],
            "TIPO_DESTINO": documento["TIPO_PROPRIETARIO"],
            "ID_DESTINO": documento["ID_PROPRIETARIO"],
            "DT_ENVIO": date.today(),
            "SITUACAO_TRAMIT": SIEDocumentoDAO.TRAMITACAO_SITUACAO_AGUARDANDO,
            "IND_RETORNO_OBRIG": SIEDocumentoDAO.TRAMITACAO_IND_RETORNO_OBRIG_NAO,
            "DT_ALTERACAO": date.today(),
            "HR_ALTERACAO": strftime("%H:%M:%S"),
            "PRIORIDADE_TAB": 5101,
            "PRIORIDADE_ITEM": SIEDocumentoDAO.TRAMITACAO_PRIORIDADE_NORMAL
        }

        id_tramitacao = self.api.post(self.tramite_path, tramitacao_params).insertId
        tramitacao = self.api.get_single_result(self.tramite_path, {"ID_TRAMITACAO": id_tramitacao})  # pega uma instancia nova do banco (por seguranca)

        return tramitacao
Example #11
0
    def itemsDeCodigo(self, COD_TABELA):
        """
        Dado um COD_TABELA, a função retornará uma lista de dicionários de valores possíveis de ITEM_TABELA e sua
        DESCRICAO

        :param COD_TABELA: Identificador de único de um domínio de valores de uma tabela
        :raise AttributeError: Uma exception é disparada caso nenhum item seja encontrado para o COD_TABELA
        :rtype : list
        :return: Uma lista de dicionários contendo as chaves `ITEM_TABELA` e `COD_TABELA`
        """
        params = {
            "COD_TABELA": COD_TABELA,
            "LMIN": 0,
            "LMAX": 99999,
            "IND_ATIVO": self.COD_IND_ATIVO
        }
        fields = ["ITEM_TABELA", "DESCRICAO"]
        try:
            items = self.api.get(self.path, params, fields, cache_time=self.cacheTime).content
            # Primeiro item de uma de ITEMS de uma TABELA é sempre a descrição do conteúdo
            return items[1:]
        except NoContentException as e:
            raise SIEException("Nenhum item encontreado para este código.", e)
Example #12
0
    def gerar_numero_processo(self):
        """
        Gera o proximo numero de processo a ser usado, formado de acordo com a mascara do tipo de documento.

        :rtype: str
        :return: Retorna o NUM_PROCESSO gerado a partir da logica de negocio
        :raise: SIEException
        """
        try:
            try:
                mascara = SIETiposDocumentosDAO().obter_mascara(self.id_tipo_doc)
                prox_numero = self.__proximo_numero_tipo_documento()
            except APIException as e:
                raise SIEException("Erro obter mascara do tipo documento " + str(self.id_tipo_doc), e)

            if mascara == "pNNNN/AAAA":  # TODO usar o parser de mascara ao inves dessa gambi
                numero = self.__gera_numero_processo_projeto(prox_numero, "P")

            elif mascara == "eNNNN/AAAA":  # TODO usar o parser de mascara ao inves dessa gambi
                numero = self.__gera_numero_processo_projeto(prox_numero, "e")

            elif mascara == "xNNNN/AAAA":  # TODO usar o parser de mascara ao inves dessa gambi
                numero = self.__gera_numero_processo_projeto(prox_numero, "x")

            elif mascara == "dNNNN/AAAA":  # TODO usar o parser de mascara ao inves dessa gambi
                numero = self.__gera_numero_processo_projeto(prox_numero, "d")

            elif mascara == "NNNNNN/AAAA":  # TODO usar um parser de mascar em vez dessa gambi
                numero = self.__gera_numero_processo_avaliacao_projeto(prox_numero)
            else:  # interpretar a mascara
                # TODO Criar parser para mascara para entender como gerar o numero do processo de modo generico

                raise NotImplementedError
            return numero
        except Exception as e:
            raise e#raise SIEException("Erro ao gerar numero de processo.", e)
Example #13
0
    def enviar_relatorio_docente(self, relatorio, params_projeto):

        documento_dao = SIEDocumentoDAO()

        avaliacao = SIEAvaliacaoProjsPesquisaDAO().get_avaliacao(params_projeto['ANO_REF_AVAL'],relatorio.id_projeto,params_projeto["PERIODO_REF_TAB"],params_projeto["PERIODO_REF_ITEM"])
        if avaliacao:
            avaliacao_com_professor = SIEAvaliacaoProjsPesquisaDAO().is_avaliacao_com_professor(avaliacao)
            if not avaliacao_com_professor:
                raise SIEException("Já há avaliação cadastrada para este projeto neste período de avaliação. Caso queira enviar outra avaliação, entre em contato com a DPq.")
            else:
                #Salva relatorio
                arquivo_salvo = SIEArquivosProj().salvar_arquivo(nome_arquivo=relatorio.filename,
                                                             arquivo=relatorio.arquivo,
                                                             id_projeto=relatorio.id_projeto,
                                                             tipo_arquivo=SIEArquivosProj.ITEM_TIPO_ARQUIVO_RELATORIO_DOCENTE)

                # atualizar ref tabela de arquivos com id da avaliacao
                SIEArquivosProj().atualizar_arquivo(arquivo_salvo["ID_ARQUIVO_PROJ"],
                                                {"ID_AVALIACAO_PROJ": avaliacao["ID_AVALIACAO_PROJ"]})

                #obtem estado atual
                documento = documento_dao.obter_documento(avaliacao["ID_DOCUMENTO"])
                tramitacao_atual = documento_dao.obter_tramitacao_atual(documento)

                #recebe documento se necessario
                if tramitacao_atual["SITUACAO_TRAMIT"]==SIEDocumentoDAO.TRAMITACAO_SITUACAO_ENTREGUE:
                    documento_dao.receber_documento(documento)
                elif tramitacao_atual["SITUACAO_TRAMIT"]==SIEDocumentoDAO.TRAMITACAO_SITUACAO_AGUARDANDO:
                    #Só tramitar
                    pass
                else:
                    #Shouldn't fall here.
                    raise NotImplementedError

                # tramita para DPq de novo.
                fluxo = documento_dao.obter_fluxo_inicial(documento) #TODO É o fluxo inicial? Me parece ser! Senão seria o último.
                documento_dao.tramitar_documento(documento, fluxo)

        else:
            #Salva relatorio
            arquivo_salvo = SIEArquivosProj().salvar_arquivo(nome_arquivo=relatorio.filename,
                                                             arquivo=relatorio.arquivo,
                                                             id_projeto=relatorio.id_projeto,
                                                             tipo_arquivo=SIEArquivosProj.ITEM_TIPO_ARQUIVO_RELATORIO_DOCENTE)

            #cria documento avaliacao
            documento_avaliacao = SIEAvaliacaoProjsPesquisaDAO().documento_inicial_padrao()
            projeto =  self.get_projeto(relatorio.id_projeto)
            documento_avaliacao.update({
                "RESUMO_ASSUNTO": "Projeto n"+u"\u00BA " + projeto['NUM_PROCESSO'].strip() # Parece ser.
            })
            documento = documento_dao.criar_documento(documento_avaliacao)  # PASSO 1

            # cria avaliacao para o arquivo
            avaliacao = SIEAvaliacaoProjsPesquisaDAO().criar_avaliacao(projeto,documento,params_projeto,data_prorrogacao=relatorio.nova_data_conclusao,obs=relatorio.obs)

            # atualizar ref tabela de arquivos com id da avaliacao
            SIEArquivosProj().atualizar_arquivo(arquivo_salvo["ID_ARQUIVO_PROJ"],
                                                {"ID_AVALIACAO_PROJ": avaliacao["ID_AVALIACAO_PROJ"]})


            # tramita para a câmara
            fluxo = documento_dao.obter_fluxo_inicial(documento)
            documento_dao.tramitar_documento(documento, fluxo)

            #atualizar projeto com avaliacao_item pendente.
            self.atualizar_projeto({
                "ID_PROJETO":relatorio.id_projeto,
                "AVALIACAO_ITEM": SIEProjetosPesquisa.ITEM_AVALIACAO_PROJETOS_INSTITUICAO_PENDENTE_AVALIACAO
            })