From de52162131547a7ccde4a64d91e203ee82c0136b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Wed, 17 Jun 2020 11:34:35 -0300 Subject: [PATCH 01/25] =?UTF-8?q?Corrige=20classifica=C3=A7=C3=A3o=20dos?= =?UTF-8?q?=20logs=20de=20erros=20para=20logs=20de=20avisos=20(#3197)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/materia/forms.py | 31 +++++++++++-------------------- sapl/parlamentares/views.py | 3 +-- sapl/protocoloadm/views.py | 6 +++--- sapl/sessao/views.py | 8 ++++---- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index c0a3b3777..65d227894 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -211,10 +211,8 @@ class MateriaLegislativaForm(FileFieldCheckMixin, ModelForm): if protocolo: if not Protocolo.objects.filter(numero=protocolo, ano=ano).exists(): - self.logger.error("Protocolo %s/%s não" - " existe" % (protocolo, ano)) - raise ValidationError(_('Protocolo %s/%s não' - ' existe' % (protocolo, ano))) + self.logger.warning("Protocolo %s/%s não existe" % (protocolo, ano)) + raise ValidationError(_('Protocolo %s/%s não existe' % (protocolo, ano))) if protocolo_antigo != protocolo: exist_materia = MateriaLegislativa.objects.filter( @@ -517,11 +515,9 @@ class TramitacaoForm(ModelForm): raise ValidationError(msg) if cleaned_data['data_tramitacao'] > timezone.now().date(): - self.logger.error('A data de tramitação informada ({}) não é ' + - 'menor ou igual a data de hoje!'.format(cleaned_data['data_tramitacao'])) - msg = _( - 'A data de tramitação deve ser ' + - 'menor ou igual a data de hoje!') + self.logger.warning('A data de tramitação informada ({}) não é menor ou igual a data de hoje!' + .format(cleaned_data['data_tramitacao'])) + msg = _('A data de tramitação deve ser menor ou igual a data de hoje!') raise ValidationError(msg) if (ultima_tramitacao and @@ -535,10 +531,8 @@ class TramitacaoForm(ModelForm): if data_enc_form: if data_enc_form < data_tram_form: - msg = _('A data de encaminhamento deve ser ' + - 'maior que a data de tramitação!') - self.logger.error("A data de encaminhamento ({}) deve ser " - "maior que a data de tramitação! ({})" + msg = _('A data de encaminhamento deve ser maior que a data de tramitação!') + self.logger.warning("A data de encaminhamento ({}) deve ser maior que a data de tramitação! ({})" .format(data_enc_form, data_tram_form)) raise ValidationError(msg) @@ -904,8 +898,7 @@ class AnexadaForm(ModelForm): except ObjectDoesNotExist: msg = _('A {} {}/{} não existe no cadastro de matérias legislativas.' .format(cleaned_data['tipo'], cleaned_data['numero'], cleaned_data['ano'])) - self.logger.error("A matéria a ser anexada não existe no cadastro" - " de matérias legislativas.") + self.logger.warning("A matéria a ser anexada não existe no cadastro de matérias legislativas.") raise ValidationError(msg) materia_principal = self.instance.materia_principal @@ -1742,11 +1735,9 @@ class TramitacaoEmLoteForm(ModelForm): if data_enc_form: if data_enc_form < data_tram_form: - self.logger.error('A data de encaminhamento ({}) deve ser ' - 'maior que a data de tramitação ({})!' - .format(data_enc_form, data_tram_form)) - msg = _('A data de encaminhamento deve ser ' + - 'maior que a data de tramitação!') + self.logger.warning('A data de encaminhamento ({}) deve ser maior que a data de tramitação ({})!' + .format(data_enc_form, data_tram_form)) + msg = _('A data de encaminhamento deve ser maior que a data de tramitação!') raise ValidationError(msg) if data_prazo_form: diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 7e1c63025..50f042dec 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -585,8 +585,7 @@ class ParlamentarCrud(Crud): ". Tentando obter id da legislatura.") return int(self.request.GET['pk']) except: - self.logger.error( - "user=" + username + ". Legislatura não possui ID. Buscando em todas as entradas.") + self.logger.warning("User=" + username + ". Legislatura não possui ID. Buscando em todas as entradas.") legislaturas = Legislatura.objects.all() for l in legislaturas: if l.atual(): diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index b61b91ff8..83091c6b9 100755 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -1368,9 +1368,9 @@ class TramitacaoAdmCrud(MasterDetailCrud): if tramitacao.pk != ultima_tramitacao.pk: username = request.user.username - self.logger.error("user=" + username + ". Não é possível deletar a tramitação de pk={}. " - "Somente a última tramitação (pk={}) pode ser deletada!." - .format(tramitacao.pk, ultima_tramitacao.pk)) + self.logger.warning("User={}. Não é possível deletar a tramitação de pk={}. " + "Somente a última tramitação (pk={}) pode ser deletada!." + .format(username, tramitacao.pk, ultima_tramitacao.pk)) msg = _('Somente a última tramitação pode ser deletada!') messages.add_message(request, messages.ERROR, msg) return HttpResponseRedirect(url) diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 25cde87d1..26da9d23a 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -2801,8 +2801,8 @@ class VotacaoNominalAbstract(SessaoPermissionMixin): parlamentar=parlamentar) except ObjectDoesNotExist: username = self.request.user.username - self.logger.error('user=' + username + '. Objeto voto_parlamentar do ' + - 'parlamentar de id={} não existe.'.format(parlamentar.pk)) + self.logger.warning('User={}. Objeto voto_parlamentar do parlamentar de id={} não existe.' + .format(username, parlamentar.pk)) yield [parlamentar, None] else: yield [parlamentar, voto.voto] @@ -4398,8 +4398,8 @@ class VotacaoEmBlocoNominalView(PermissionRequiredForAppCrudMixin, TemplateView) parlamentar=parlamentar) except ObjectDoesNotExist: username = self.request.user.username - self.logger.error('user=' + username + '. Objeto voto_parlamentar do ' + - 'parlamentar de id={} não existe.'.format(parlamentar.pk)) + self.logger.warning('User={}. Objeto voto_parlamentar do parlamentar de id={} não existe.' + .format(username, parlamentar.pk)) yield [parlamentar, None] else: yield [parlamentar, voto.voto] From 99cf064c3494b59ac04eed6b1147eca3a0959028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?= Date: Tue, 23 Jun 2020 10:11:09 -0300 Subject: [PATCH 02/25] =?UTF-8?q?Refatora=C3=A7=C3=A3o=20das=20classifica?= =?UTF-8?q?=C3=A7=C3=B5es=20de=20logs=20(#3204)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/audiencia/forms.py | 16 +++-- sapl/base/forms.py | 151 ++++++++++++++++++++++++---------------- sapl/comissoes/forms.py | 108 +++++++++++++++++++--------- sapl/crud/base.py | 10 +-- 4 files changed, 184 insertions(+), 101 deletions(-) diff --git a/sapl/audiencia/forms.py b/sapl/audiencia/forms.py index 9009b1bd5..a765ca34e 100755 --- a/sapl/audiencia/forms.py +++ b/sapl/audiencia/forms.py @@ -95,8 +95,10 @@ class AudienciaForm(FileFieldCheckMixin, forms.ModelForm): except ObjectDoesNotExist: msg = _('A matéria %s nº %s/%s não existe no cadastro' ' de matérias legislativas.' % (tipo_materia, materia, ano_materia)) - self.logger.error('A MateriaLegislativa %s nº %s/%s não existe no cadastro' - ' de matérias legislativas.' % (tipo_materia, materia, ano_materia)) + self.logger.warn( + 'A MateriaLegislativa %s nº %s/%s não existe no cadastro' + ' de matérias legislativas.' % (tipo_materia, materia, ano_materia) + ) raise ValidationError(msg) else: self.logger.info("MateriaLegislativa %s nº %s/%s obtida com sucesso." % (tipo_materia, materia, ano_materia)) @@ -106,8 +108,10 @@ class AudienciaForm(FileFieldCheckMixin, forms.ModelForm): campos = [materia, tipo_materia, ano_materia] if campos.count(None) + campos.count('') < len(campos): msg = _('Preencha todos os campos relacionados à Matéria Legislativa') - self.logger.error('Algum campo relacionado à MatériaLegislativa %s nº %s/%s \ - não foi preenchido.' % (tipo_materia, materia, ano_materia)) + self.logger.warn( + 'Algum campo relacionado à MatériaLegislativa %s nº %s/%s \ + não foi preenchido.' % (tipo_materia, materia, ano_materia) + ) raise ValidationError(msg) if not cleaned_data['numero']: @@ -122,7 +126,9 @@ class AudienciaForm(FileFieldCheckMixin, forms.ModelForm): if self.cleaned_data['hora_fim'] < self.cleaned_data['hora_inicio']: msg = _('A hora de fim ({}) não pode ser anterior a hora de início({})' .format(self.cleaned_data['hora_fim'], self.cleaned_data['hora_inicio'])) - self.logger.error('Hora de fim anterior à hora de início.') + self.logger.warn( + 'Hora de fim anterior à hora de início.' + ) raise ValidationError(msg) if parlamentar_autor.autor.first() not in requerimento.autores.all(): diff --git a/sapl/base/forms.py b/sapl/base/forms.py index efd7322ec..b1ce0f9e8 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -117,8 +117,7 @@ class UsuarioCreateForm(ModelForm): data = self.cleaned_data if data['password1'] != data['password2']: - self.logger.error('Erro de validação. Senhas informadas ({}, {}) são diferentes.'.format( - data['password1'], data['password2'])) + self.logger.warn('Erro de validação. Senhas informadas são diferentes.') raise ValidationError('Senhas informadas são diferentes') return data @@ -252,8 +251,7 @@ class UsuarioEditForm(ModelForm): data = self.cleaned_data if data['password1'] and data['password1'] != data['password2']: - self.logger.error("Erro de validação. Senhas informadas ({}, {}) são diferentes." - .format(data['password1'], data['password2'])) + self.logger.warn("Erro de validação. Senhas informadas são diferentes.") raise ValidationError('Senhas informadas são diferentes') return data @@ -316,30 +314,37 @@ class SessaoLegislativaForm(FileFieldCheckMixin, ModelForm): ult = 0 if numero <= ult and flag_edit: - self.logger.error('O número da SessaoLegislativa ({}) é menor ou igual ' - 'que o de Sessões Legislativas passadas ({})'.format(numero, ult)) + self.logger.warn( + 'O número da SessaoLegislativa ({}) é menor ou igual ' + 'que o de Sessões Legislativas passadas ({})'.format(numero, ult) + ) raise ValidationError('O número da Sessão Legislativa não pode ser menor ou igual ' 'que o de Sessões Legislativas passadas') if data_inicio < data_inicio_leg or \ data_inicio > data_fim_leg: - self.logger.error('A data de início ({}) da SessaoLegislativa está compreendida ' - 'fora da data início ({}) e fim ({}) da Legislatura ' - 'selecionada'.format(data_inicio, data_inicio_leg, data_fim_leg)) + self.logger.warn( + 'A data de início ({}) da SessaoLegislativa está compreendida ' + 'fora da data início ({}) e fim ({}) da Legislatura ' + 'selecionada'.format(data_inicio, data_inicio_leg, data_fim_leg) + ) raise ValidationError('A data de início da Sessão Legislativa deve estar compreendida ' 'entre a data início e fim da Legislatura selecionada') if data_fim > data_fim_leg or \ data_fim < data_inicio_leg: - self.logger.error('A data de fim ({}) da SessaoLegislativa está compreendida ' - 'fora da data início ({}) e fim ({}) da Legislatura ' - 'selecionada.'.format(data_fim, data_inicio_leg, data_fim_leg)) + self.logger.warn( + 'A data de fim ({}) da SessaoLegislativa está compreendida ' + 'fora da data início ({}) e fim ({}) da Legislatura ' + 'selecionada.'.format(data_fim, data_inicio_leg, data_fim_leg) + ) raise ValidationError('A data de fim da Sessão Legislativa deve estar compreendida ' 'entre a data início e fim da Legislatura selecionada') if data_inicio > data_fim: - self.logger.error( - 'Data início ({}) superior à data fim ({}).'.format(data_inicio, data_fim)) + self.logger.warn( + 'Data início ({}) superior à data fim ({}).'.format(data_inicio, data_fim) + ) raise ValidationError( 'Data início não pode ser superior à data fim') @@ -348,8 +353,10 @@ class SessaoLegislativaForm(FileFieldCheckMixin, ModelForm): if data_inicio_intervalo and data_fim_intervalo and \ data_inicio_intervalo > data_fim_intervalo: - self.logger.error('Data início de intervalo ({}) superior à ' - 'data fim de intervalo ({}).'.format(data_inicio_intervalo, data_fim_intervalo)) + self.logger.warn( + 'Data início de intervalo ({}) superior à ' + 'data fim de intervalo ({}).'.format(data_inicio_intervalo, data_fim_intervalo) + ) raise ValidationError('Data início de intervalo não pode ser ' 'superior à data fim de intervalo') @@ -358,10 +365,13 @@ class SessaoLegislativaForm(FileFieldCheckMixin, ModelForm): data_inicio_intervalo < data_inicio_leg or \ data_inicio_intervalo > data_fim or \ data_inicio_intervalo > data_fim_leg: - self.logger.error('A data de início do intervalo ({}) não está compreendida entre ' - 'as datas de início ({}) e fim ({}) tanto da Legislatura quanto da ' - 'própria Sessão Legislativa ({} e {}).' - .format(data_inicio_intervalo, data_inicio_leg, data_fim_leg, data_inicio, data_fim)) + self.logger.warn( + 'A data de início do intervalo ({}) não está compreendida entre ' + 'as datas de início ({}) e fim ({}) tanto da Legislatura quanto da ' + 'própria Sessão Legislativa ({} e {}).'.format( + data_inicio_intervalo, data_inicio_leg, data_fim_leg, data_inicio, data_fim + ) + ) raise ValidationError('A data de início do intervalo deve estar compreendida entre ' 'as datas de início e fim tanto da Legislatura quanto da ' 'própria Sessão Legislativa') @@ -370,10 +380,13 @@ class SessaoLegislativaForm(FileFieldCheckMixin, ModelForm): data_fim_intervalo > data_fim_leg or \ data_fim_intervalo < data_inicio or \ data_fim_intervalo < data_inicio_leg: - self.logger.error('A data de fim do intervalo ({}) não está compreendida entre ' - 'as datas de início ({}) e fim ({}) tanto da Legislatura quanto da ' - 'própria Sessão Legislativa ({} e {}).' - .format(data_fim_intervalo, data_inicio_leg, data_fim_leg, data_inicio, data_fim)) + self.logger.warn( + 'A data de fim do intervalo ({}) não está compreendida entre ' + 'as datas de início ({}) e fim ({}) tanto da Legislatura quanto da ' + 'própria Sessão Legislativa ({} e {}).'.format( + data_fim_intervalo, data_inicio_leg, data_fim_leg, data_inicio, data_fim + ) + ) raise ValidationError('A data de fim do intervalo deve estar compreendida entre ' 'as datas de início e fim tanto da Legislatura quanto da ' 'própria Sessão Legislativa') @@ -567,8 +580,9 @@ class AutorForm(ModelForm): def valida_igualdade(self, texto1, texto2, msg): if texto1 != texto2: - self.logger.error( - 'Textos diferentes. ("{}" e "{}")'.format(texto1, texto2)) + self.logger.warn( + 'Textos diferentes. ("{}" e "{}")'.format(texto1, texto2) + ) raise ValidationError(msg) return True @@ -582,8 +596,10 @@ class AutorForm(ModelForm): cd = self.cleaned_data if 'action_user' not in cd or not cd['action_user']: - self.logger.error('Não Informado se o Autor terá usuário ' - 'vinculado para acesso ao Sistema.') + self.logger.warn( + 'Não Informado se o Autor terá usuário ' + 'vinculado para acesso ao Sistema.' + ) raise ValidationError(_('Informe se o Autor terá usuário ' 'vinculado para acesso ao Sistema.')) @@ -593,10 +609,13 @@ class AutorForm(ModelForm): self.instance.user, get_user_model().USERNAME_FIELD) != cd['username']: if 'status_user' not in cd or not cd['status_user']: - self.logger.error('Foi trocado ou removido o usuário deste Autor ({}), ' - 'mas não foi informado como se deve proceder ' - 'com o usuário que está sendo desvinculado? ({})' - .format(cd['username'], get_user_model().USERNAME_FIELD)) + self.logger.warn( + 'Foi trocado ou removido o usuário deste Autor ({}), ' + 'mas não foi informado como se deve proceder ' + 'com o usuário que está sendo desvinculado? ({})'.format( + cd['username'], get_user_model().USERNAME_FIELD + ) + ) raise ValidationError( _('Foi trocado ou removido o usuário deste Autor, ' 'mas não foi informado como se deve proceder ' @@ -613,8 +632,9 @@ class AutorForm(ModelForm): if cd['action_user'] == 'A': param_username = {get_user_model().USERNAME_FIELD: cd['username']} if not User.objects.filter(**param_username).exists(): - self.logger.error( - 'Não existe usuário com username "%s". ' % cd['username']) + self.logger.warn( + 'Não existe usuário com username "%s". ' % cd['username'] + ) raise ValidationError( _('Não existe usuário com username "%s". ' 'Para utilizar esse username você deve selecionar ' @@ -623,7 +643,7 @@ class AutorForm(ModelForm): if cd['action_user'] != 'N': if 'username' not in cd or not cd['username']: - self.logger.error('Username não informado.') + self.logger.warn('Username não informado.') raise ValidationError(_('O username deve ser informado.')) param_username = { @@ -634,7 +654,7 @@ class AutorForm(ModelForm): nome = autor_vinculado[0].nome error_msg = 'Já existe um autor para este ' \ 'usuário ({}): {}'.format(cd['username'], nome) - self.logger.error(error_msg) + self.logger.warn(error_msg) raise ValidationError(_(error_msg)) """ @@ -643,7 +663,7 @@ class AutorForm(ModelForm): ainda assim para renderizar um message.danger no topo do form. """ if 'tipo' not in cd or not cd['tipo']: - self.logger.error('Tipo do Autor não selecionado.') + self.logger.warn('Tipo do Autor não selecionado.') raise ValidationError( _('O Tipo do Autor deve ser selecionado.')) @@ -655,21 +675,25 @@ class AutorForm(ModelForm): if not tipo.content_type: if 'nome' not in cd or not cd['nome']: - self.logger.error('Nome do Autor não informado.') + self.logger.warn('Nome do Autor não informado.') raise ValidationError( _('O Nome do Autor deve ser informado.')) else: if 'autor_related' not in cd or not cd['autor_related']: - self.logger.error('Registro de %s não escolhido para ser ' - 'vinculado ao cadastro de Autor' % tipo.descricao) + self.logger.warn( + 'Registro de %s não escolhido para ser ' + 'vinculado ao cadastro de Autor' % tipo.descricao + ) raise ValidationError( _('Um registro de %s deve ser escolhido para ser ' 'vinculado ao cadastro de Autor') % tipo.descricao) if not tipo.content_type.model_class().objects.filter( pk=cd['autor_related']).exists(): - self.logger.error('O Registro definido (%s-%s) não está na base ' - 'de %s.' % (cd['autor_related'], cd['q'], tipo.descricao)) + self.logger.warn( + 'O Registro definido (%s-%s) não está na base ' + 'de %s.' % (cd['autor_related'], cd['q'], tipo.descricao) + ) raise ValidationError( _('O Registro definido (%s-%s) não está na base de %s.' ) % (cd['autor_related'], cd['q'], tipo.descricao)) @@ -679,8 +703,10 @@ class AutorForm(ModelForm): content_type_id=cd['tipo'].content_type_id) if qs_autor_selected.exists(): autor = qs_autor_selected.first() - self.logger.error('Já existe um autor Cadastrado para ' - '%s' % autor.autor_related) + self.logger.warn( + 'Já existe um autor Cadastrado para ' + '%s' % autor.autor_related + ) raise ValidationError( _('Já existe um autor Cadastrado para %s' ) % autor.autor_related) @@ -1548,12 +1574,14 @@ class ConfiguracoesAppForm(ModelForm): casa = CasaLegislativa.objects.first() if not casa: - self.logger.error('Não há casa legislativa relacionada.') + self.logger.warn('Não há casa legislativa relacionada.') raise ValidationError("Não há casa legislativa relacionada.") if not casa.logotipo and mostrar_brasao_painel: - self.logger.error('Não há logitipo configurado para esta ' - 'CasaLegislativa ({}).'.format(casa)) + self.logger.warn( + 'Não há logitipo configurado para esta ' + 'CasaLegislativa ({}).'.format(casa) + ) raise ValidationError("Não há logitipo configurado para esta " "Casa legislativa.") @@ -1587,8 +1615,9 @@ class RecuperarSenhaForm(PasswordResetForm): if not email_existente: msg = 'Não existe nenhum usuário cadastrado com este e-mail.' - self.logger.error('Não existe nenhum usuário cadastrado com este e-mail ({}).' - .format(self.data['email'])) + self.logger.warn( + 'Não existe nenhum usuário cadastrado com este e-mail ({}).'.format(self.data['email']) + ) raise ValidationError(msg) return self.cleaned_data @@ -1655,8 +1684,7 @@ class AlterarSenhaForm(Form): new_password2 = data['new_password2'] if new_password1 != new_password2: - self.logger.error("'Nova Senha' ({}) diferente de 'Confirmar Senha' ({})".format( - new_password1, new_password2)) + self.logger.warn("'Nova Senha' diferente de 'Confirmar Senha'") raise ValidationError( "'Nova Senha' diferente de 'Confirmar Senha'") @@ -1665,8 +1693,9 @@ class AlterarSenhaForm(Form): # TODO: senha atual igual a senha anterior, etc if len(new_password1) < 6: - self.logger.error( - 'A senha informada ({}) não tem o mínimo de 6 caracteres.'.format(new_password1)) + self.logger.warn( + 'A senha informada não tem o mínimo de 6 caracteres.' + ) raise ValidationError( "A senha informada deve ter no mínimo 6 caracteres") @@ -1675,20 +1704,24 @@ class AlterarSenhaForm(Form): user = User.objects.get(username=username) if user.is_anonymous(): - self.logger.error( - 'Não é possível alterar senha de usuário anônimo ({}).'.format(username)) + self.logger.warn( + 'Não é possível alterar senha de usuário anônimo ({}).'.format(username) + ) raise ValidationError( "Não é possível alterar senha de usuário anônimo") if not user.check_password(old_password): - self.logger.error('Senha atual informada ({}) não confere ' - 'com a senha armazenada.'.format(old_password)) + self.logger.warn( + 'Senha atual informada não confere ' + 'com a senha armazenada.' + ) raise ValidationError("Senha atual informada não confere " "com a senha armazenada") if user.check_password(new_password1): - self.logger.error( - 'Nova senha ({}) igual à senha anterior.'.format(new_password1)) + self.logger.warn( + 'Nova senha igual à senha anterior.' + ) raise ValidationError( "Nova senha não pode ser igual à senha anterior") diff --git a/sapl/comissoes/forms.py b/sapl/comissoes/forms.py index 77523d26b..2b2081432 100644 --- a/sapl/comissoes/forms.py +++ b/sapl/comissoes/forms.py @@ -61,11 +61,17 @@ class ComposicaoForm(forms.ModelForm): if intersecao_periodo: if periodo.data_fim: - self.logger.error('O período informado ({} a {}) choca com períodos já cadastrados para esta comissão' - .format(periodo.data_inicio, periodo.data_fim)) + self.logger.warn( + 'O período informado ({} a {}) choca com períodos já cadastrados para esta comissão'.format( + periodo.data_inicio, periodo.data_fim + ) + ) else: - self.logger.error('O período informado ({} - ) choca com períodos já cadastrados para esta comissão' - .format(periodo.data_inicio)) + self.logger.warn( + 'O período informado ({} - ) choca com períodos já cadastrados para esta comissão'.format( + periodo.data_inicio + ) + ) raise ValidationError('O período informado choca com períodos já cadastrados para esta comissão') return data @@ -89,8 +95,10 @@ class PeriodoForm(forms.ModelForm): data_fim = cleaned_data['data_fim'] if data_fim and data_fim < data_inicio: - self.logger.error('A Data Final ({}) é menor que ' - 'a Data Inicial({}).'.format(data_fim, data_inicio)) + self.logger.warn( + 'A Data Final ({}) é menor que ' + 'a Data Inicial({}).'.format(data_fim, data_inicio) + ) raise ValidationError('A Data Final não pode ser menor que ' 'a Data Inicial') @@ -103,9 +111,11 @@ class PeriodoForm(forms.ModelForm): ) if not legislatura: - self.logger.error('O período informado ({} a {})' - 'não está contido em uma única ' - 'legislatura existente'.format(data_inicio, data_fim)) + self.logger.warn( + 'O período informado ({} a {})' + 'não está contido em uma única ' + 'legislatura existente'.format(data_inicio, data_fim) + ) raise ValidationError('O período informado ' 'deve estar contido em uma única ' 'legislatura existente') @@ -165,8 +175,10 @@ class ParticipacaoCreateForm(forms.ModelForm): if data_desligamento and \ data_designacao > data_desligamento: - self.logger.error('Data de designação ({}) superior ' - 'à data de desligamento ({})'.format(data_designacao, data_desligamento)) + self.logger.warn( + 'Data de designação ({}) superior ' + 'à data de desligamento ({})'.format(data_designacao, data_desligamento) + ) raise ValidationError(_('Data de designação não pode ser superior ' 'à data de desligamento')) @@ -176,8 +188,11 @@ class ParticipacaoCreateForm(forms.ModelForm): if cleaned_data['cargo'].nome in cargos_unicos: msg = _('Este cargo é único para esta Comissão.') - self.logger.error('Este cargo ({}) é único para esta Comissão.'.format( - cleaned_data['cargo'].nome)) + self.logger.warn( + 'Este cargo ({}) é único para esta Comissão.'.format( + cleaned_data['cargo'].nome + ) + ) raise ValidationError(msg) return cleaned_data @@ -253,8 +268,10 @@ class ParticipacaoEditForm(forms.ModelForm): if data_desligamento and \ data_designacao > data_desligamento: - self.logger.error('Data de designação ({}) superior ' - 'à data de desligamento ({})'.format(data_designacao, data_desligamento)) + self.logger.warn( + 'Data de designação ({}) superior ' + 'à data de desligamento ({})'.format(data_designacao, data_desligamento) + ) raise ValidationError(_('Data de designação não pode ser superior ' 'à data de desligamento')) @@ -266,8 +283,11 @@ class ParticipacaoEditForm(forms.ModelForm): if cleaned_data['cargo'].nome in cargos_unicos: msg = _('Este cargo é único para esta Comissão.') - self.logger.error('Este cargo ({}) é único para esta Comissão (id={}).' - .format(cleaned_data['cargo'].nome, composicao_id)) + self.logger.warn( + 'Este cargo ({}) é único para esta Comissão (id={}).'.format( + cleaned_data['cargo'].nome, composicao_id + ) + ) raise ValidationError(msg) return cleaned_data @@ -301,51 +321,70 @@ class ComissaoForm(forms.ModelForm): if len(self.cleaned_data['nome']) > 100: msg = _('Nome da Comissão informado ({}) tem mais de 50 caracteres.'.format( self.cleaned_data['nome'])) - self.logger.error( - 'Nome da Comissão deve ter no máximo 50 caracteres.') + self.logger.warn( + 'Nome da Comissão deve ter no máximo 50 caracteres.' + ) raise ValidationError(msg) if (self.cleaned_data['data_extincao'] and self.cleaned_data['data_extincao'] < self.cleaned_data['data_criacao']): msg = _('Data de extinção não pode ser menor que a de criação') - self.logger.error('Data de extinção ({}) não pode ser menor que a de criação ({}).' - .format(self.cleaned_data['data_extincao'], self.cleaned_data['data_criacao'])) + self.logger.warn( + 'Data de extinção ({}) não pode ser menor que a de criação ({}).'.format( + self.cleaned_data['data_extincao'], self.cleaned_data['data_criacao'] + ) + ) raise ValidationError(msg) if (self.cleaned_data['data_final_prevista_temp'] and self.cleaned_data['data_final_prevista_temp'] < self.cleaned_data['data_criacao']): msg = _('Data Prevista para Término não pode ser menor que a de criação') - self.logger.error('Data Prevista para Término ({}) não pode ser menor que a de criação ({}).' - .format(self.cleaned_data['data_final_prevista_temp'], self.cleaned_data['data_criacao'])) + self.logger.warn( + 'Data Prevista para Término ({}) não pode ser menor que a de criação ({}).'.format( + self.cleaned_data['data_final_prevista_temp'], self.cleaned_data['data_criacao'] + ) + ) raise ValidationError(msg) if (self.cleaned_data['data_prorrogada_temp'] and self.cleaned_data['data_prorrogada_temp'] < self.cleaned_data['data_criacao']): msg = _('Data Novo Prazo não pode ser menor que a de criação') - self.logger.error('Data Novo Prazo ({}) não pode ser menor que a de criação ({}).' - .format(self.cleaned_data['data_prorrogada_temp'], self.cleaned_data['data_criacao'])) + self.logger.warn( + 'Data Novo Prazo ({}) não pode ser menor que a de criação ({}).'.format( + self.cleaned_data['data_prorrogada_temp'], self.cleaned_data['data_criacao'] + ) + ) raise ValidationError(msg) if (self.cleaned_data['data_instalacao_temp'] and self.cleaned_data['data_instalacao_temp'] < self.cleaned_data['data_criacao']): msg = _('Data de Instalação não pode ser menor que a de criação') - self.logger.error('Data de Instalação ({}) não pode ser menor que a de criação ({}).' - .format(self.cleaned_data['data_instalacao_temp'], self.cleaned_data['data_criacao'])) + self.logger.warn( + 'Data de Instalação ({}) não pode ser menor que a de criação ({}).'.format( + self.cleaned_data['data_instalacao_temp'], self.cleaned_data['data_criacao'] + ) + ) raise ValidationError(msg) if (self.cleaned_data['data_final_prevista_temp'] and self.cleaned_data['data_instalacao_temp'] and self.cleaned_data['data_final_prevista_temp'] < self.cleaned_data['data_instalacao_temp']): msg = _( 'Data Prevista para Término não pode ser menor que a de Instalação.') - self.logger.error('Data Prevista para Término ({}) não pode ser menor que a de Instalação ({}).' - .format(self.cleaned_data['data_final_prevista_temp'], self.cleaned_data['data_instalacao_temp'])) + self.logger.warn( + 'Data Prevista para Término ({}) não pode ser menor que a de Instalação ({}).'.format( + self.cleaned_data['data_final_prevista_temp'], self.cleaned_data['data_instalacao_temp'] + ) + ) raise ValidationError(msg) if (self.cleaned_data['data_prorrogada_temp'] and self.cleaned_data['data_instalacao_temp'] and self.cleaned_data['data_prorrogada_temp'] < self.cleaned_data['data_instalacao_temp']): msg = _('Data Novo Prazo não pode ser menor que a de Instalação.') - self.logger.error('Data Novo Prazo ({}) não pode ser menor que a de Instalação ({}).' - .format(self.cleaned_data['data_prorrogada_temp'], self.cleaned_data['data_instalacao_temp'])) + self.logger.warn( + 'Data Novo Prazo ({}) não pode ser menor que a de Instalação ({}).'.format( + self.cleaned_data['data_prorrogada_temp'], self.cleaned_data['data_instalacao_temp'] + ) + ) raise ValidationError(msg) return self.cleaned_data @@ -391,8 +430,11 @@ class ReuniaoForm(ModelForm): self.cleaned_data['hora_inicio']): msg = _( 'A hora de término da reunião não pode ser menor que a de início') - self.logger.error("A hora de término da reunião ({}) não pode ser menor que a de início ({})." - .format(self.cleaned_data['hora_fim'], self.cleaned_data['hora_inicio'])) + self.logger.warn( + "A hora de término da reunião ({}) não pode ser menor que a de início ({}).".format( + self.cleaned_data['hora_fim'], self.cleaned_data['hora_inicio'] + ) + ) raise ValidationError(msg) upload_pauta = self.cleaned_data.get('upload_pauta', False) diff --git a/sapl/crud/base.py b/sapl/crud/base.py index f4f86a36f..4a9ab196c 100644 --- a/sapl/crud/base.py +++ b/sapl/crud/base.py @@ -577,8 +577,9 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): fm = model._meta.get_field(fo) except Exception as e: username = self.request.user.username - self.logger.error( - "user=" + username + ". " + str(e)) + self.logger.info( + "user=" + username + ". " + str(e) + ) pass if fm and hasattr(fm, 'related_model')\ @@ -607,8 +608,9 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): # print(ordering) except Exception as e: - logger.error(string_concat(_( - 'ERRO: construção da tupla de ordenação.'), str(e))) + logger.warn( + string_concat(_('ERRO: construção da tupla de ordenação.'), str(e)) + ) # print(queryset.query) if not self.request.user.is_authenticated(): From 4dc1c3498777eac445643e68e12a70afb1092709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Wed, 24 Jun 2020 12:57:37 -0300 Subject: [PATCH 03/25] Update docker-compose-dev.yml --- docker-compose-dev.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 5265bcf4f..72f7b8fb5 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -4,7 +4,6 @@ services: sapldb-dev: container_name: sapldb-dev image: postgres:10.5-alpine - restart: always environment: POSTGRES_PASSWORD: sapl POSTGRES_USER: sapl @@ -16,7 +15,6 @@ services: sapl-dev: container_name: sapl-dev - restart: always image: sapl:dev build: context: . From 21f8872e9b736f0875694864d377b96277605764 Mon Sep 17 00:00:00 2001 From: Ulysses Lara Date: Mon, 29 Jun 2020 10:48:56 -0300 Subject: [PATCH 04/25] Fix #3209 Apresentando ValidationError para usuario (#3210) * Fix #3209 Apresentando ValidationError para usuario * Update sapl/base/views.py * Melhorando mensagem de erro * Update sapl/base/views.py * Adequando aos comentarios do PR Co-authored-by: Edward <9326037+edwardoliveira@users.noreply.github.com> --- sapl/base/views.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index b5d2f6e24..260253527 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -2020,9 +2020,15 @@ class AppConfigCrud(CrudAux): recibo_prop_atual = AppConfig.objects.last().receber_recibo_proposicao recibo_prop_novo = self.request.POST['receber_recibo_proposicao'] if recibo_prop_novo == 'False' and recibo_prop_atual: - props = Proposicao.objects.filter(hash_code='') + props = Proposicao.objects.filter(hash_code='').exclude(data_envio__isnull=True) for prop in props: - self.gerar_hash(prop) + try: + self.gerar_hash(prop) + except ValidationError as e: + form.add_error('receber_recibo_proposicao',e) + msg = _("Não foi possível mudar a configuração porque a Proposição {} não possui texto original vinculado!".format(prop)) + messages.error(self.request, msg) + return super().form_invalid(form) return super().form_valid(form) def gerar_hash(self, inst): From 289d04ba85b8e7d311978fb9f05c09e40a837de8 Mon Sep 17 00:00:00 2001 From: "Denis E. Sanches" Date: Mon, 29 Jun 2020 10:50:13 -0300 Subject: [PATCH 05/25] =?UTF-8?q?HOTFIX:=20Corre=C3=A7=C3=B5es=20de=20port?= =?UTF-8?q?ugu=C3=AAs=20em=20howtogit.rst=20(#3208)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * HOTFIX: Correções de português em howtogit.rst * Update docs/howtogit.rst Co-authored-by: Edward <9326037+edwardoliveira@users.noreply.github.com> --- docs/howtogit.rst | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/docs/howtogit.rst b/docs/howtogit.rst index 69d6d474a..e1faa6008 100644 --- a/docs/howtogit.rst +++ b/docs/howtogit.rst @@ -1,15 +1,17 @@ -De forma muito simples e em linhas gerais o básico sobre GIT +==== +De forma muito simples e em linhas gerais o básico sobre Git +==== Glosário --------- Git - Sistema de controle de versão de aquivos - GitHub - É um serviço web que oferece diversas funcionalidades extras aplicadas ao git + GitHub - É um serviço web que oferece diversas funcionalidades extras aplicadas ao Git - Branch - Significa ramificar seu projeto, criar um snapshot. + Branch - Significa ramificar seu projeto, criar um snapshot - Merge - Significa incorporar seu branch no master + Merge - Significa incorporar seu branch ao master Pode ser útil @@ -23,58 +25,52 @@ Exibir informações: git status - -Ver repositorio +Ver repositório: git remote -v - -Para definir repositorio +Definir repositório: git remote set-url origin https://github.com/interlegis/sapl.git - -Para criar um branch +Criar um branch: git checkout -b nome_branch git add arquivos -Para remover um branch +Remover um branch: git branch -d nome-branch - -Para comitar +Commitar: git commit -m "Comentário" -Para enviar o branch +Enviar o branch: git push origin nome_branch - -Na base local descartar alguma alteração feita nos arquivos: +Na base local, descartar alguma alteração feita nos arquivos: git checkout -- - -Ao invés dissoremover todas as alterações e commits locais, recuperar o histórico mais recente do servidor e apontar para seu branch master local +Ao invés disso, remover todas as alterações e commits locais, recuperar o histórico mais recente do servidor e apontar para seu branch master local: git fetch origin git reset --hard origin/master -Atualizar para alguma brach especifica (ex:785-atualizar-migracao): +Atualizar para algum branch específico (ex:785-atualizar-migracao): git checkout 785-atualizar-migracao -Voltar para a branch master +Voltar para a branch master: git checkout master -Verificar 5 ultimos comits: +Verificar os últimos 5 commits: git log --oneline -n 5 - + Referência: From 6edbedecae47f338b886823cf2efa0866b5ec4e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Mon, 29 Jun 2020 12:52:03 -0300 Subject: [PATCH 06/25] 3177 - Adiciona Pesquisa de Autor (#3196) * Adiciona pesquisa de autor * Corrige nome do campo para pesquisa --- sapl/base/forms.py | 20 ++++++++ sapl/base/urls.py | 4 +- sapl/base/views.py | 54 ++++++++++++++++++++- sapl/templates/base/autor_detail.html | 14 ++++++ sapl/templates/base/autor_filter.html | 51 +++++++++++++++++++ sapl/templates/menu_tabelas_auxiliares.yaml | 7 ++- 6 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 sapl/templates/base/autor_detail.html create mode 100644 sapl/templates/base/autor_filter.html diff --git a/sapl/base/forms.py b/sapl/base/forms.py index b1ce0f9e8..c6f4a3ce8 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -770,6 +770,26 @@ class AutorForm(ModelForm): return autor +class AutorFilterSet(django_filters.FilterSet): + nome = django_filters.CharFilter(label=_('Nome do Autor'), lookup_expr='icontains') + + class Meta: + model = Autor + fields = ['nome'] + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + row0 = to_row([('nome', 12)]) + + self.form.helper = SaplFormHelper() + self.form.helper.form_method = 'GET' + self.form.helper.layout = Layout( + Fieldset(_('Pesquisa de Autor'), + row0, + form_actions(label='Pesquisar'))) + + class AutorFormForAdmin(AutorForm): status_user = forms.ChoiceField( label=_('Bloqueio do Usuário Existente'), diff --git a/sapl/base/urls.py b/sapl/base/urls.py index e8bcc587b..2630f5114 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -8,7 +8,8 @@ from django.contrib.auth.views import (password_reset, password_reset_complete, password_reset_done) from django.views.generic.base import RedirectView, TemplateView -from sapl.base.views import AutorCrud, ConfirmarEmailView, TipoAutorCrud, get_estatistica, DetailUsuarioView +from sapl.base.views import AutorCrud, ConfirmarEmailView, TipoAutorCrud, get_estatistica, DetailUsuarioView, \ + PesquisarAutorView from sapl.settings import EMAIL_SEND_USER, MEDIA_URL from .apps import AppConfig @@ -90,6 +91,7 @@ recuperar_senha = [ urlpatterns = [ url(r'^sistema/autor/tipo/', include(TipoAutorCrud.get_urls())), url(r'^sistema/autor/', include(AutorCrud.get_urls())), + url(r'^sistema/autor/pesquisar-autor/', PesquisarAutorView.as_view(), name='pesquisar_autor'), url(r'^sistema/ajuda/(?P\w+)$', HelpTopicView.as_view(), name='help_topic'), diff --git a/sapl/base/views.py b/sapl/base/views.py index 260253527..56e8879e1 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -41,7 +41,7 @@ from sapl.relatorios.views import (relatorio_materia_em_tramitacao, relatorio_ma from sapl import settings from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica from sapl.base.models import Autor, TipoAutor -from sapl.base.forms import AutorForm, AutorFormForAdmin, TipoAutorForm +from sapl.base.forms import AutorForm, AutorFormForAdmin, TipoAutorForm, AutorFilterSet from sapl.comissoes.models import Comissao, Reuniao from sapl.crud.base import CrudAux, make_pagination from sapl.materia.models import (Anexada, Autoria, DocumentoAcessorio, @@ -295,6 +295,58 @@ class AutorCrud(CrudAux): return url_reverse +class PesquisarAutorView(FilterView): + model = Autor + filterset_class = AutorFilterSet + paginate_by = 10 + + def get_filterset_kwargs(self, filterset_class): + super().get_filterset_kwargs(filterset_class) + + kwargs = {'data': self.request.GET or None} + + qs = self.get_queryset().order_by('nome').distinct() + + kwargs.update({ + 'queryset': qs, + }) + return kwargs + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + paginator = context['paginator'] + page_obj = context['page_obj'] + + context['page_range'] = make_pagination(page_obj.number, paginator.num_pages) + + context['NO_ENTRIES_MSG'] = 'Nenhum Autor encontrado!' + + context['title'] = _('Autores') + + return context + + def get(self, request, *args, **kwargs): + super().get(request) + + data = self.filterset.data + url = '' + if data: + url = "&" + str(self.request.META['QUERY_STRING']) + if url.startswith("&page"): + ponto_comeco = url.find('nome=') - 1 + url = url[ponto_comeco:] + + context = self.get_context_data(filter=self.filterset, + object_list=self.object_list, + filter_url=url, + numero_res=len(self.object_list)) + + context['show_results'] = show_results_filter_set(self.request.GET.copy()) + + return self.render_to_response(context) + + class RelatoriosListView(TemplateView): template_name='base/relatorios_list.html' diff --git a/sapl/templates/base/autor_detail.html b/sapl/templates/base/autor_detail.html new file mode 100644 index 000000000..c9938e372 --- /dev/null +++ b/sapl/templates/base/autor_detail.html @@ -0,0 +1,14 @@ +{% extends "crud/detail.html" %} +{% load i18n %} +{% load crispy_forms_tags staticfiles %} + +{% block sub_actions %} + +{% endblock sub_actions %} diff --git a/sapl/templates/base/autor_filter.html b/sapl/templates/base/autor_filter.html new file mode 100644 index 000000000..5e1a05542 --- /dev/null +++ b/sapl/templates/base/autor_filter.html @@ -0,0 +1,51 @@ +{% extends "crud/list.html" %} +{% load i18n %} +{% load crispy_forms_tags staticfiles %} + +{% block base_content %} + {% if not show_results %} + {% crispy filter.form %} + {% else %} +
+ {% trans 'Fazer nova pesquisa' %} + {% if not request.user.is_anonymous %} + Cadastrar Autor + {% endif %} +
+
+ {% if numero_res > 0 %} + {% if numero_res == 1 %} +

Foi encontrado {{ numero_res }} resultado

+ {% else %} +

Foram encontrados {{ numero_res }} resultados

+ {% endif %} + + + + + + + + + + {% for autor in page_obj %} + + + + + + {% endfor %} + +
Tipo do AutorNome do AutorUsuário
{{ autor.tipo }} + + {% if autor.nome %} {{ autor.nome }} {% else %} - {% endif %} + + {% if autor.user %} {{ autor.user }} {% else %} - {% endif %}
+ {% else %} +

{{ NO_ENTRIES_MSG }}

+ {% endif %} + {% endif %} +
+ {% include 'paginacao.html'%} +


+{% endblock base_content %} diff --git a/sapl/templates/menu_tabelas_auxiliares.yaml b/sapl/templates/menu_tabelas_auxiliares.yaml index 84dbde48a..8a83ac44f 100644 --- a/sapl/templates/menu_tabelas_auxiliares.yaml +++ b/sapl/templates/menu_tabelas_auxiliares.yaml @@ -8,8 +8,11 @@ - title: {% trans 'Configurações da Aplicação' %} url: sapl.base:appconfig_list css_class: btn btn-link - - title: {% trans 'Autor' %} - url: sapl.base:autor_list + - title: {% trans 'Pesquisar Autor' %} + url: sapl.base:pesquisar_autor + css_class: btn btn-link + - title: {% trans 'Adicionar Autor' %} + url: sapl.base:autor_create css_class: btn btn-link - title: {% trans 'Tipo de Autor' %} url: sapl.base:tipoautor_list From d3cab7a3a50cac3e016d11ce8c739d25e2557a6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?= Date: Tue, 30 Jun 2020 10:53:01 -0300 Subject: [PATCH 07/25] =?UTF-8?q?Fix=20#3211=20-=20Valida=C3=A7=C3=A3o=20d?= =?UTF-8?q?e=20Cria=C3=A7=C3=A3o=20e=20Edi=C3=A7=C3=A3o=20de=20Autores=20(?= =?UTF-8?q?#3212)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Altera posição de validação * Adiciona correção --- sapl/base/forms.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sapl/base/forms.py b/sapl/base/forms.py index c6f4a3ce8..388007bf2 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -668,16 +668,13 @@ class AutorForm(ModelForm): _('O Tipo do Autor deve ser selecionado.')) tipo = cd['tipo'] - - if 'nome' in cd and \ - qs_autor.filter(nome=cd['nome']).exists(): - raise ValidationError("Autor '%s' já existente!" % cd['nome']) - if not tipo.content_type: if 'nome' not in cd or not cd['nome']: self.logger.warn('Nome do Autor não informado.') raise ValidationError( _('O Nome do Autor deve ser informado.')) + elif qs_autor.filter(nome=cd['nome']).exists(): + raise ValidationError("Autor '%s' já existente!" % cd['nome']) else: if 'autor_related' not in cd or not cd['autor_related']: self.logger.warn( From ad6d369a7541ccb29b6913856f1e64c19bd221dd Mon Sep 17 00:00:00 2001 From: Ulysses Lara Date: Tue, 30 Jun 2020 11:01:55 -0300 Subject: [PATCH 08/25] Corrigindo logs (#3199) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Corrigindo logs * Corrige log e formatação em ProposicaoCrud * Update views.py * Corrigindo erros relatados no PR Co-authored-by: Vinícius Cantuária --- sapl/api/serializers.py | 2 +- sapl/materia/views.py | 229 ++++++++++++++++++---------------------- sapl/norma/forms.py | 2 +- sapl/norma/views.py | 2 +- 4 files changed, 103 insertions(+), 132 deletions(-) diff --git a/sapl/api/serializers.py b/sapl/api/serializers.py index b3ff9213e..ebd40add9 100644 --- a/sapl/api/serializers.py +++ b/sapl/api/serializers.py @@ -139,7 +139,7 @@ class ParlamentarResumeSerializer(serializers.ModelSerializer): # Caso não exista filiação com essas condições except ObjectDoesNotExist: - self.logger.error("user=" + username + ". Parlamentar com (data<={} e data_desfiliacao>={}) " + self.logger.warning("user=" + username + ". Parlamentar com (data<={} e data_desfiliacao>={}) " "ou (data<={} e data_desfiliacao=Null)) não possui filiação." .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim)) filiacao = 'Não possui filiação' diff --git a/sapl/materia/views.py b/sapl/materia/views.py index db28dd2c3..773ca0eaf 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -736,8 +736,14 @@ class ProposicaoCrud(Crud): container_field = 'autor__user' class BaseMixin(Crud.BaseMixin): - list_field_names = ['data_envio', 'data_recebimento', 'descricao', - 'tipo', 'conteudo_gerado_related', 'cancelado', ] + list_field_names = [ + 'data_envio', + 'data_recebimento', + 'descricao', + 'tipo', + 'conteudo_gerado_related', + 'cancelado' + ] class BaseLocalMixin: form_class = ProposicaoForm @@ -751,22 +757,23 @@ class ProposicaoCrud(Crud): def get(self, request, *args, **kwargs): if not self._action_is_valid(request, *args, **kwargs): - return redirect(reverse('sapl.materia:proposicao_detail', - kwargs={'pk': kwargs['pk']})) + return redirect(reverse('sapl.materia:proposicao_detail', kwargs={'pk': kwargs['pk']})) return super().get(self, request, *args, **kwargs) def post(self, request, *args, **kwargs): if not self._action_is_valid(request, *args, **kwargs): - return redirect(reverse('sapl.materia:proposicao_detail', - kwargs={'pk': kwargs['pk']})) + return redirect(reverse('sapl.materia:proposicao_detail', kwargs={'pk': kwargs['pk']})) return super().post(self, request, *args, **kwargs) class DetailView(Crud.DetailView): layout_key = 'Proposicao' - permission_required = (RP_DETAIL, 'materia.detail_proposicao_enviada', - 'materia.detail_proposicao_devolvida', - 'materia.detail_proposicao_incorporada') + permission_required = ( + RP_DETAIL, + 'materia.detail_proposicao_enviada', + 'materia.detail_proposicao_devolvida', + 'materia.detail_proposicao_incorporada' + ) logger = logging.getLogger(__name__) @@ -785,7 +792,6 @@ class ProposicaoCrud(Crud): return context def get(self, request, *args, **kwargs): - action = request.GET.get('action', '') user = request.user username = user.username @@ -802,10 +808,8 @@ class ProposicaoCrud(Crud): msg_error = _('Proposição já foi enviada e recebida.') elif p.data_envio: msg_error = _('Proposição já foi enviada.') - elif not p.texto_original and\ - not p.texto_articulado.exists(): - msg_error = _('Proposição não possui nenhum tipo de ' - 'Texto associado.') + elif not p.texto_original and not p.texto_articulado.exists(): + msg_error = _('Proposição não possui nenhum tipo de Texto associado.') else: if p.texto_articulado.exists(): ta = p.texto_articulado.first() @@ -813,8 +817,7 @@ class ProposicaoCrud(Crud): ta.editing_locked = True ta.save() - receber_recibo = BaseAppConfig.attr( - 'receber_recibo_proposicao') + receber_recibo = BaseAppConfig.attr('receber_recibo_proposicao') if not receber_recibo: ta = p.texto_articulado.first() @@ -824,45 +827,39 @@ class ProposicaoCrud(Crud): p.data_envio = timezone.now() p.save() - messages.success(request, _( - 'Proposição enviada com sucesso.')) + messages.success(request, _('Proposição enviada com sucesso.')) try: - self.logger.debug("user=" + username + ". Tentando obter número do objeto MateriaLegislativa com " - "atributos tipo={} e ano={}." - .format(p.tipo.tipo_conteudo_related, p.ano)) + self.logger.debug("User={}. Tentando obter número do objeto MateriaLegislativa " + "com atributos tipo={} e ano={}." + .format(username, p.tipo.tipo_conteudo_related, p.ano)) if p.numero_materia_futuro: numero = p.numero_materia_futuro else: numero = MateriaLegislativa.objects.filter(tipo=p.tipo.tipo_conteudo_related, ano=p.ano).last().numero + 1 - messages.success(request, _( - '%s : nº %s de %s
Atenção! Este número é apenas um provável ' - 'número que pode não corresponder com a realidade' - % (p.tipo, numero, p.ano))) + messages.success(request, _("{}: nº {} de {}
Atenção! Este número é apenas um provável " + "número que pode não corresponder com a realidade" + .format(p.tipo, numero, p.ano))) except ValueError as e: - self.logger.error( - "user=" + username + "." + str(e)) + self.logger.warning("User=" + username + ". " + str(e)) pass except AttributeError as e: - self.logger.error( - "user=" + username + "." + str(e)) + self.logger.warning("User=" + username + ". " + str(e)) pass except TypeError as e: - self.logger.error( - "user=" + username + "." + str(e)) + self.logger.warning("User=" + username + ". " + str(e)) pass elif action == 'return': if not p.data_envio: - self.logger.error( - "user=" + username + ". Proposição (numero={}) ainda não foi enviada.".format(p.numero_proposicao)) + self.logger.warning("User={}. Proposição (numero={}) ainda não foi enviada." + .format(username, p.numero_proposicao)) msg_error = _('Proposição ainda não foi enviada.') elif p.data_recebimento: - self.logger.error("user=" + username + ". Proposição (numero={}) já foi recebida, não é " - "possível retorná-la.".format(p.numero_proposicao)) - msg_error = _('Proposição já foi recebida, não é ' - 'possível retorná-la.') + self.logger.warning("User={}. Proposição (numero={}) já foi recebida, " + "não é possível retorná-la.".format(username, p.numero_proposicao)) + msg_error = _('Proposição já foi recebida, não é possível retorná-la.') else: p.data_envio = None p.save() @@ -871,27 +868,24 @@ class ProposicaoCrud(Crud): ta.privacidade = STATUS_TA_PRIVATE ta.editing_locked = False ta.save() - self.logger.info( - "user=" + username + ". Proposição (numero={}) Retornada com sucesso.".format(p.numero_proposicao)) - messages.success(request, _( - 'Proposição Retornada com sucesso.')) + self.logger.info("User={}. Proposição (numero={}) Retornada com sucesso." + .format(username, p.numero_proposicao)) + messages.success(request, _('Proposição Retornada com sucesso.')) if msg_error: messages.error(request, msg_error) # retornar redirecionando para limpar a variavel action - return redirect(reverse('sapl.materia:proposicao_detail', - kwargs={'pk': kwargs['pk']})) + return redirect(reverse('sapl.materia:proposicao_detail', kwargs={'pk': kwargs['pk']})) def dispatch(self, request, *args, **kwargs): username = request.user.username try: - self.logger.debug( - "user=" + username + ". Tentando obter objeto Proposicao com pk={}".format(kwargs['pk'])) + self.logger.debug("User={}. Tentando obter objeto Proposicao com pk={}".format(username, kwargs['pk'])) p = Proposicao.objects.get(id=kwargs['pk']) except Exception as e: - self.logger.error( - "user=" + username + ". Erro ao obter proposicao com pk={}. Retornando 404. ".format(kwargs['pk']) + str(e)) + self.logger.warning("User={}. Erro ao obter proposicao com pk={}. Retornando 404. {}" + .format(username, kwargs['pk'], str(e))) raise Http404() if not self.has_permission(): @@ -901,47 +895,38 @@ class ProposicaoCrud(Crud): if not p.data_envio and not p.data_devolucao: raise Http404() - if p.data_devolucao and not request.user.has_perm( - 'materia.detail_proposicao_devolvida'): + if p.data_devolucao and not request.user.has_perm('materia.detail_proposicao_devolvida'): raise Http404() - if p.data_envio and not p.data_recebimento\ - and not request.user.has_perm( - 'materia.detail_proposicao_enviada'): + if p.data_envio and not p.data_recebimento \ + and not request.user.has_perm('materia.detail_proposicao_enviada'): raise Http404() - if p.data_envio and p.data_recebimento\ - and not request.user.has_perm( - 'materia.detail_proposicao_incorporada'): + if p.data_envio and p.data_recebimento \ + and not request.user.has_perm('materia.detail_proposicao_incorporada'): raise Http404() - return super(PermissionRequiredMixin, self).dispatch( - request, *args, **kwargs) + return super(PermissionRequiredMixin, self).dispatch(request, *args, **kwargs) class DeleteView(BaseLocalMixin, Crud.DeleteView): - logger = logging.getLogger(__name__) def _action_is_valid(self, request, *args, **kwargs): - proposicao = Proposicao.objects.filter( - id=kwargs['pk']).values_list( - 'data_envio', 'data_recebimento') + proposicao = Proposicao.objects.filter(id=kwargs['pk']).values_list('data_envio', 'data_recebimento') username = request.user.username if proposicao: if proposicao[0][0] and proposicao[0][1]: - self.logger.error("user=" + username + ". Proposição (id={}) já foi enviada e recebida." - "Não pode mais ser excluida.".format(kwargs['pk'])) - msg = _('Proposição já foi enviada e recebida.' - 'Não pode mais ser excluida.') + self.logger.warning("User={}. Proposição (id={}) já foi enviada e recebida." + "Não pode mais ser excluida.".format(username, kwargs['pk'])) + msg = _('Proposição já foi enviada e recebida. Não pode mais ser excluida.') elif proposicao[0][0] and not proposicao[0][1]: - self.logger.error("user=" + username + ". Proposição (id={}) já foi enviada mas ainda não recebida " - "pelo protocolo. Use a opção Recuperar Proposição " - "para depois excluí-la.".format(kwargs['pk'])) - msg = _('Proposição já foi enviada mas ainda não recebida ' - 'pelo protocolo. Use a opção Recuperar Proposição ' - 'para depois excluí-la.') + self.logger.warning("""\ + User={}. Proposição (id={}) já foi enviada, mas ainda não recebida pelo protocolo. \ + Use a opção Recuperar Proposição para depois excluí-la.""".format(username, kwargs['pk'])) + msg = _("Proposição já foi enviada mas ainda não recebida pelo protocolo. " + "Use a opção Recuperar Proposição para depois excluí-la.") if proposicao[0][0] or proposicao[0][1]: messages.error(request, msg) @@ -949,20 +934,18 @@ class ProposicaoCrud(Crud): return True class UpdateView(BaseLocalMixin, Crud.UpdateView): - logger = logging.getLogger(__name__) form_class = ProposicaoForm def form_valid(self, form): tz = timezone.get_current_timezone() - objeto_antigo = Proposicao.objects.get( - pk=self.kwargs['pk'] - ) + objeto_antigo = Proposicao.objects.get(pk=self.kwargs['pk']) dict_objeto_antigo = objeto_antigo.__dict__ tipo_texto = self.request.POST.get('tipo_texto', '') - if tipo_texto=='D' and objeto_antigo.texto_articulado.exists() or tipo_texto=='T' and not objeto_antigo.texto_articulado.exists(): + if tipo_texto == 'D' and objeto_antigo.texto_articulado.exists()\ + or tipo_texto == 'T' and not objeto_antigo.texto_articulado.exists(): self.object.user = self.request.user self.object.ip = get_client_ip(self.request) self.object.ultima_edicao = tz.localize(datetime.now()) @@ -972,7 +955,10 @@ class ProposicaoCrud(Crud): dict_objeto_novo = self.object.__dict__ atributos = [ - 'tipo_id', 'descricao', 'observacao', 'texto_original', + 'tipo_id', + 'descricao', + 'observacao', + 'texto_original', 'materia_de_vinculo_id' ] @@ -987,27 +973,22 @@ class ProposicaoCrud(Crud): return super().form_valid(form) def _action_is_valid(self, request, *args, **kwargs): - - proposicao = Proposicao.objects.filter( - id=kwargs['pk']).values_list( - 'data_envio', 'data_recebimento') + proposicao = Proposicao.objects.filter(id=kwargs['pk']).values_list('data_envio', 'data_recebimento') username = request.user.username if proposicao: msg = '' if proposicao[0][0] and proposicao[0][1]: - self.logger.error('user=' + username + '. Proposição (id={}) já foi enviada e recebida.' - 'Não pode mais ser editada'.format(kwargs['pk'])) - msg = _('Proposição já foi enviada e recebida.' - 'Não pode mais ser editada') + self.logger.warning('User={}. Proposição (id={}) já foi enviada e recebida. ' + 'Não pode mais ser editada'.format(username, kwargs['pk'])) + msg = _('Proposição já foi enviada e recebida. Não pode mais ser editada') elif proposicao[0][0] and not proposicao[0][1]: - self.logger.error('user=' + username + '. Proposição (id={}) já foi enviada mas ainda não recebida ' - 'pelo protocolo. Use a opção Recuperar Proposição ' - 'para voltar para edição.'.format(kwargs['pk'])) - msg = _('Proposição já foi enviada mas ainda não recebida ' - 'pelo protocolo. Use a opção Recuperar Proposição ' - 'para voltar para edição.') + self.logger.warning("""\ + User={}. Proposição (id={}) já foi enviada, mas ainda não recebida pelo protocolo. \ + Use a opção Recuperar Proposição para voltar para edição.""".format(username, kwargs['pk'])) + msg = _("Proposição já foi enviada, mas ainda não recebida pelo protocolo. " + "Use a opção Recuperar Proposição para voltar para edição.") if proposicao[0][0] or proposicao[0][1]: messages.error(request, msg) @@ -1015,22 +996,17 @@ class ProposicaoCrud(Crud): return True def get_success_url(self): - tipo_texto = self.request.POST.get('tipo_texto', '') username = self.request.user.username if tipo_texto == 'T': - messages.info(self.request, - _('Sempre que uma Proposição é inclusa ou ' - 'alterada e a opção "Texto Articulado " for ' - 'marcada, você será redirecionado para a ' - 'edição do Texto Eletrônico.')) - self.logger.debug('user=' + username + '. Sempre que uma Proposição é inclusa ou ' - 'alterada e a opção "Texto Articulado " for ' - 'marcada, você será redirecionado para a ' - 'edição do Texto Eletrônico.') - return reverse('sapl.materia:proposicao_ta', - kwargs={'pk': self.object.pk}) + messages.info(self.request, _("""\ + Sempre que uma Proposição é inclusa ou alterada e a opção "Texto Articulado " for marcada, \ + você será redirecionado para a edição do Texto Eletrônico.""")) + self.logger.debug("""\ + User={}. Sempre que uma Proposição é inclusa ou alterada e a opção "Texto Articulado" for marcada, \ + você será redirecionado para a edição do Texto Eletrônico.""".format(username)) + return reverse('sapl.materia:proposicao_ta', kwargs={'pk': self.object.pk}) else: return Crud.UpdateView.get_success_url(self) @@ -1061,43 +1037,38 @@ class ProposicaoCrud(Crud): username = self.request.user.username if tipo_texto == 'T': - messages.info(self.request, - _('Sempre que uma Proposição é inclusa ou ' - 'alterada e a opção "Texto Articulado " for ' - 'marcada, você será redirecionado para o ' - 'Texto Eletrônico. Use a opção "Editar Texto" ' - 'para construir seu texto.')) - self.logger.debug('user=' + username + '. Sempre que uma Proposição é inclusa ou ' - 'alterada e a opção "Texto Articulado " for ' - 'marcada, você será redirecionado para o ' - 'Texto Eletrônico. Use a opção "Editar Texto" ' - 'para construir seu texto.') - return reverse('sapl.materia:proposicao_ta', - kwargs={'pk': self.object.pk}) + messages.info(self.request, _("""\ + Sempre que uma Proposição é inclusa ou alterada e a opção "Texto Articulado" for marcada, \ + você será redirecionado para o Texto Eletrônico. \ + Use a opção "Editar Texto" para construir seu texto.""")) + self.logger.debug("""\ + User={}. Sempre que uma Proposição é inclusa ou alterada e a opção "Texto Articulado" for marcada, \ + você será redirecionado para o Texto Eletrônico. \ + Use a opção "Editar Texto" para construir seu texto.""".format(username)) + return reverse('sapl.materia:proposicao_ta', kwargs={'pk': self.object.pk}) else: return Crud.CreateView.get_success_url(self) class ListView(Crud.ListView): - ordering = ['-data_envio', 'descricao'] + ordering = [ + '-data_envio', + 'descricao' + ] def get_rows(self, object_list): for obj in object_list: if obj.data_recebimento is None: - obj.data_recebimento = 'Não recebida'\ - if obj.data_envio else 'Não enviada' + obj.data_recebimento = 'Não recebida' if obj.data_envio else 'Não enviada' else: - obj.data_recebimento = timezone.localtime( - obj.data_recebimento) - obj.data_recebimento = formats.date_format( - obj.data_recebimento, "DATETIME_FORMAT") + obj.data_recebimento = timezone.localtime(obj.data_recebimento) + obj.data_recebimento = formats.date_format(obj.data_recebimento, "DATETIME_FORMAT") if obj.data_envio is None: obj.data_envio = 'Em elaboração...' else: obj.data_envio = timezone.localtime(obj.data_envio) - obj.data_envio = formats.date_format( - obj.data_envio, "DATETIME_FORMAT") + obj.data_envio = formats.date_format(obj.data_envio, "DATETIME_FORMAT") return [self._as_row(obj) for obj in object_list] @@ -2757,11 +2728,11 @@ def create_zip_docacessorios(materia): def get_zip_docacessorios(request, pk): logger = logging.getLogger(__name__) - username = request.user.username + username = 'Usuário anônimo' if request.user.is_anonymous else request.user.username materia = get_object_or_404(MateriaLegislativa, pk=pk) try: external_name, zipfilename = create_zip_docacessorios(materia) - logger.info("user= {}. Gerou o zip compilado de documento acessorios") + logger.info("user= {}. Gerou o zip compilado de documento acessorios".format(username)) except FileNotFoundError: logger.error("user= {}.Não há arquivos cadastrados".format(username)) msg=_('Não há arquivos cadastrados nesses documentos acessórios.') @@ -2822,10 +2793,10 @@ def create_pdf_docacessorios(materia): def get_pdf_docacessorios(request, pk): materia = get_object_or_404(MateriaLegislativa, pk=pk) logger = logging.getLogger(__name__) - username = request.user.username + username = 'Usuário anônimo' if request.user.is_anonymous else request.user.username try: external_name, pdffilename = create_pdf_docacessorios(materia) - logger.info("user= {}. Gerou o pdf compilado de documento acessorios") + logger.info("user= {}. Gerou o pdf compilado de documento acessorios".format(username)) except FileNotFoundError: logger.error("user= {}.Não há arquivos cadastrados".format(username)) msg=_('Não há arquivos cadastrados nesses documentos acessórios.') diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index 2be8315a7..7feb3b3c3 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -163,7 +163,7 @@ class NormaJuridicaForm(FileFieldCheckMixin, ModelForm): numero=cleaned_data['numero'], tipo=cleaned_data['tipo']).exists() if norma: - self.logger.error("Já existe uma norma de mesmo Tipo ({}), Ano ({}) " + self.logger.warning("Já existe uma norma de mesmo Tipo ({}), Ano ({}) " "e Número ({}) no sistema." .format(cleaned_data['tipo'], cleaned_data['ano'], cleaned_data['numero'])) raise ValidationError("Já existe uma norma de mesmo Tipo, Ano " diff --git a/sapl/norma/views.py b/sapl/norma/views.py index 44c2cfeac..98825f4cf 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -329,7 +329,7 @@ def recuperar_norma(request): response = JsonResponse({'ementa': norma.ementa, 'id': norma.id}) except ObjectDoesNotExist: - logger.error('user=' + username + '. NormaJuridica buscada (tipo={}, ano={}, numero={}) não existe. ' + logger.warning('user=' + username + '. NormaJuridica buscada (tipo={}, ano={}, numero={}) não existe. ' 'Definida com ementa vazia e id 0.'.format(tipo, ano, numero)) response = JsonResponse({'ementa': '', 'id': 0}) From cd04b29777984e8db1f7c066ac5ca81cdbf9cade Mon Sep 17 00:00:00 2001 From: ulyssesBML Date: Wed, 1 Jul 2020 10:47:38 -0300 Subject: [PATCH 09/25] =?UTF-8?q?HOT-FIX=20-=20atualizando=20vers=C3=A3o?= =?UTF-8?q?=20do=20jquery=20para=20corrigir=20erro=20mobile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/js/chunk-vendors.f89f6c45.js | 3 --- .../chunk-vendors.f89f6c45.js.LICENSE.txt.gz | Bin 2035 -> 0 bytes .../frontend/js/chunk-vendors.f89f6c45.js.gz | Bin 464314 -> 0 bytes .../frontend/js/chunk-vendors.f89f6c45.js.map | 1 - .../js/chunk-vendors.f89f6c45.js.map.gz | Bin 1649229 -> 0 bytes .../frontend/js/chunk-vendors.f8cff174.js | 3 +++ ... => chunk-vendors.f8cff174.js.LICENSE.txt} | 4 ++-- .../chunk-vendors.f8cff174.js.LICENSE.txt.gz | Bin 0 -> 2033 bytes .../frontend/js/chunk-vendors.f8cff174.js.gz | Bin 0 -> 464314 bytes .../frontend/js/chunk-vendors.f8cff174.js.map | 1 + .../js/chunk-vendors.f8cff174.js.map.gz | Bin 0 -> 1649222 bytes sapl/webpack-stats.json | 2 +- 12 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f89f6c45.js delete mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f89f6c45.js.LICENSE.txt.gz delete mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f89f6c45.js.gz delete mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f89f6c45.js.map delete mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f89f6c45.js.map.gz create mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f8cff174.js rename sapl/static/sapl/frontend/js/{chunk-vendors.f89f6c45.js.LICENSE.txt => chunk-vendors.f8cff174.js.LICENSE.txt} (99%) create mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f8cff174.js.LICENSE.txt.gz create mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f8cff174.js.gz create mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f8cff174.js.map create mode 100644 sapl/static/sapl/frontend/js/chunk-vendors.f8cff174.js.map.gz diff --git a/sapl/static/sapl/frontend/js/chunk-vendors.f89f6c45.js b/sapl/static/sapl/frontend/js/chunk-vendors.f89f6c45.js deleted file mode 100644 index f52502e6f..000000000 --- a/sapl/static/sapl/frontend/js/chunk-vendors.f89f6c45.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! For license information please see chunk-vendors.f89f6c45.js.LICENSE.txt */ -(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-vendors"],{"00ee":function(e,t,n){var r=n("b622"),i=r("toStringTag"),o={};o[i]="z",e.exports="[object z]"===String(o)},"0366":function(e,t,n){var r=n("1c0b");e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 0:return function(){return e.call(t)};case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},"057f":function(e,t,n){var r=n("fc6a"),i=n("241c").f,o={}.toString,a="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(e){try{return i(e)}catch(t){return a.slice()}};e.exports.f=function(e){return a&&"[object Window]"==o.call(e)?s(e):i(r(e))}},"06cf":function(e,t,n){var r=n("83ab"),i=n("d1e7"),o=n("5c6c"),a=n("fc6a"),s=n("c04e"),u=n("5135"),c=n("0cfb"),l=Object.getOwnPropertyDescriptor;t.f=r?l:function(e,t){if(e=a(e),t=s(t,!0),c)try{return l(e,t)}catch(n){}if(u(e,t))return o(!i.f.call(e,t),e[t])}},"0773":function(e,t,n){},"07d1":function(e,t,n){n("94ce")},"0a06":function(e,t,n){"use strict";var r=n("c532"),i=n("30b5"),o=n("f6b4"),a=n("5270"),s=n("4a7b");function u(e){this.defaults=e,this.interceptors={request:new o,response:new o}}u.prototype.request=function(e){"string"===typeof e?(e=arguments[1]||{},e.url=arguments[0]):e=e||{},e=s(this.defaults,e),e.method?e.method=e.method.toLowerCase():this.defaults.method?e.method=this.defaults.method.toLowerCase():e.method="get";var t=[a,void 0],n=Promise.resolve(e);this.interceptors.request.forEach((function(e){t.unshift(e.fulfilled,e.rejected)})),this.interceptors.response.forEach((function(e){t.push(e.fulfilled,e.rejected)}));while(t.length)n=n.then(t.shift(),t.shift());return n},u.prototype.getUri=function(e){return e=s(this.defaults,e),i(e.url,e.params,e.paramsSerializer).replace(/^\?/,"")},r.forEach(["delete","get","head","options"],(function(e){u.prototype[e]=function(t,n){return this.request(r.merge(n||{},{method:e,url:t}))}})),r.forEach(["post","put","patch"],(function(e){u.prototype[e]=function(t,n,i){return this.request(r.merge(i||{},{method:e,url:t,data:n}))}})),e.exports=u},"0ae9":function(e,t,n){var r,i,o;(function(a){i=[n("1157"),n("4309")],r=a,o="function"===typeof r?r.apply(t,i):r,void 0===o||(e.exports=o)})((function(e){return e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo((function(t){return function(n){return!!e.data(n,t)}})):function(t,n,r){return!!e.data(t,r[3])}})}))},"0c9b":function(e,t,n){},"0cfb":function(e,t,n){var r=n("83ab"),i=n("d039"),o=n("cc12");e.exports=!r&&!i((function(){return 7!=Object.defineProperty(o("div"),"a",{get:function(){return 7}}).a}))},"0df6":function(e,t,n){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}},1157:function(e,t,n){var r,i;(function(t,n){"use strict";"object"===typeof e.exports?e.exports=t.document?n(t,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return n(e)}:n(t)})("undefined"!==typeof window?window:this,(function(n,o){"use strict";var a=[],s=Object.getPrototypeOf,u=a.slice,c=a.flat?function(e){return a.flat.call(e)}:function(e){return a.concat.apply([],e)},l=a.push,f=a.indexOf,d={},h=d.toString,p=d.hasOwnProperty,m=p.toString,g=m.call(Object),v={},A=function(e){return"function"===typeof e&&"number"!==typeof e.nodeType},y=function(e){return null!=e&&e===e.window},b=n.document,w={type:!0,src:!0,nonce:!0,noModule:!0};function _(e,t,n){n=n||b;var r,i,o=n.createElement("script");if(o.text=e,t)for(r in w)i=t[r]||t.getAttribute&&t.getAttribute(r),i&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"===typeof e||"function"===typeof e?d[h.call(e)]||"object":typeof e}var C="3.5.0",E=function(e,t){return new E.fn.init(e,t)};function S(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!A(e)&&!y(e)&&("array"===n||0===t||"number"===typeof t&&t>0&&t-1 in e)}E.fn=E.prototype={jquery:C,constructor:E,length:0,toArray:function(){return u.call(this)},get:function(e){return null==e?u.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=E.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return E.each(this,e)},map:function(e){return this.pushStack(E.map(this,(function(t,n){return e.call(t,n,t)})))},slice:function(){return this.pushStack(u.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(E.grep(this,(function(e,t){return(t+1)%2})))},odd:function(){return this.pushStack(E.grep(this,(function(e,t){return t%2})))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|"+L+")"+L+"*"),Y=new RegExp(L+"|>"),V=new RegExp(H),G=new RegExp("^"+F+"$"),q={ID:new RegExp("^#("+F+")"),CLASS:new RegExp("^\\.("+F+")"),TAG:new RegExp("^("+F+"|[*])"),ATTR:new RegExp("^"+U),PSEUDO:new RegExp("^"+H),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},J=/HTML$/i,$=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,X=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+L+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){d()},ae=be((function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()}),{dir:"parentNode",next:"legend"});try{M.apply(I=R.call(w.childNodes),w.childNodes),I[w.childNodes.length].nodeType}catch(De){M={apply:I.length?function(e,t){N.apply(e,R.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(e,t,r,i){var o,s,c,l,f,p,v,A=t&&t.ownerDocument,w=t?t.nodeType:9;if(r=r||[],"string"!==typeof e||!e||1!==w&&9!==w&&11!==w)return r;if(!i&&(d(t),t=t||h,m)){if(11!==w&&(f=Z.exec(e)))if(o=f[1]){if(9===w){if(!(c=t.getElementById(o)))return r;if(c.id===o)return r.push(c),r}else if(A&&(c=A.getElementById(o))&&y(t,c)&&c.id===o)return r.push(c),r}else{if(f[2])return M.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return M.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!D[e+" "]&&(!g||!g.test(e))&&(1!==w||"object"!==t.nodeName.toLowerCase())){if(v=e,A=t,1===w&&(Y.test(e)||W.test(e))){A=ee.test(e)&&ve(t.parentNode)||t,A===t&&n.scope||((l=t.getAttribute("id"))?l=l.replace(re,ie):t.setAttribute("id",l=b)),p=a(e),s=p.length;while(s--)p[s]=(l?"#"+l:":scope")+" "+ye(p[s]);v=p.join(",")}try{return M.apply(r,A.querySelectorAll(v)),r}catch(_){D(e,!0)}finally{l===b&&t.removeAttribute("id")}}}return u(e.replace(Q,"$1"),t,r,i)}function ue(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function ce(e){return e[b]=!0,e}function le(e){var t=h.createElement("fieldset");try{return!!e(t)}catch(De){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function he(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function me(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ae(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function ge(e){return ce((function(t){return t=+t,ce((function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))}))}))}function ve(e){return e&&"undefined"!==typeof e.getElementsByTagName&&e}for(t in n=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!J.test(t||n&&n.nodeName||"HTML")},d=se.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!=h&&9===a.nodeType&&a.documentElement?(h=a,p=h.documentElement,m=!o(h),w!=h&&(i=h.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",oe,!1):i.attachEvent&&i.attachEvent("onunload",oe)),n.scope=le((function(e){return p.appendChild(e).appendChild(h.createElement("div")),"undefined"!==typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length})),n.attributes=le((function(e){return e.className="i",!e.getAttribute("className")})),n.getElementsByTagName=le((function(e){return e.appendChild(h.createComment("")),!e.getElementsByTagName("*").length})),n.getElementsByClassName=X.test(h.getElementsByClassName),n.getById=le((function(e){return p.appendChild(e).id=b,!h.getElementsByName||!h.getElementsByName(b).length})),n.getById?(r.filter["ID"]=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},r.find["ID"]=function(e,t){if("undefined"!==typeof t.getElementById&&m){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter["ID"]=function(e){var t=e.replace(te,ne);return function(e){var n="undefined"!==typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find["ID"]=function(e,t){if("undefined"!==typeof t.getElementById&&m){var n,r,i,o=t.getElementById(e);if(o){if(n=o.getAttributeNode("id"),n&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if(n=o.getAttributeNode("id"),n&&n.value===e)return[o]}return[]}}),r.find["TAG"]=n.getElementsByTagName?function(e,t){return"undefined"!==typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find["CLASS"]=n.getElementsByClassName&&function(e,t){if("undefined"!==typeof t.getElementsByClassName&&m)return t.getElementsByClassName(e)},v=[],g=[],(n.qsa=X.test(h.querySelectorAll))&&(le((function(e){var t;p.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&g.push("[*^$]="+L+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||g.push("\\["+L+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||g.push("~="),t=h.createElement("input"),t.setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||g.push("\\["+L+"*name"+L+"*="+L+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||g.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||g.push(".#.+[+~]"),e.querySelectorAll("\\\f"),g.push("[\\r\\n\\f]")})),le((function(e){e.innerHTML="";var t=h.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&g.push("name"+L+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&g.push(":enabled",":disabled"),p.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")}))),(n.matchesSelector=X.test(A=p.matches||p.webkitMatchesSelector||p.mozMatchesSelector||p.oMatchesSelector||p.msMatchesSelector))&&le((function(e){n.disconnectedMatch=A.call(e,"*"),A.call(e,"[s!='']:x"),v.push("!=",H)})),g=g.length&&new RegExp(g.join("|")),v=v.length&&new RegExp(v.join("|")),t=X.test(p.compareDocumentPosition),y=t||X.test(p.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},k=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(r=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&r||!n.sortDetached&&t.compareDocumentPosition(e)===r?e==h||e.ownerDocument==w&&y(w,e)?-1:t==h||t.ownerDocument==w&&y(w,t)?1:l?O(l,e)-O(l,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==h?-1:t==h?1:i?-1:o?1:l?O(l,e)-O(l,t):0;if(i===o)return de(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?de(a[r],s[r]):a[r]==w?-1:s[r]==w?1:0},h):h},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(d(e),n.matchesSelector&&m&&!D[t+" "]&&(!v||!v.test(t))&&(!g||!g.test(t)))try{var r=A.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(De){D(t,!0)}return se(t,h,null,[e]).length>0},se.contains=function(e,t){return(e.ownerDocument||e)!=h&&d(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=h&&d(e);var i=r.attrHandle[t.toLowerCase()],o=i&&T.call(r.attrHandle,t.toLowerCase())?i(e,t,!m):void 0;return void 0!==o?o:n.attributes||!m?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,l=!n.sortStable&&e.slice(0),e.sort(k),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return l=null,e},i=se.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"===typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},r=se.selectors={cacheLength:50,createPseudo:ce,match:q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return q["CHILD"].test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=C[e+" "];return t||(t=new RegExp("(^|"+L+")"+e+"("+L+"|$)"))&&C(e,(function(e){return t.test("string"===typeof e.className&&e.className||"undefined"!==typeof e.getAttribute&&e.getAttribute("class")||"")}))},ATTR:function(e,t,n){return function(r){var i=se.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace(j," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var c,l,f,d,h,p,m=o!==a?"nextSibling":"previousSibling",g=t.parentNode,v=s&&t.nodeName.toLowerCase(),A=!u&&!s,y=!1;if(g){if(o){while(m){d=t;while(d=d[m])if(s?d.nodeName.toLowerCase()===v:1===d.nodeType)return!1;p=m="only"===e&&!p&&"nextSibling"}return!0}if(p=[a?g.firstChild:g.lastChild],a&&A){d=g,f=d[b]||(d[b]={}),l=f[d.uniqueID]||(f[d.uniqueID]={}),c=l[e]||[],h=c[0]===_&&c[1],y=h&&c[2],d=h&&g.childNodes[h];while(d=++h&&d&&d[m]||(y=h=0)||p.pop())if(1===d.nodeType&&++y&&d===t){l[e]=[_,h,y];break}}else if(A&&(d=t,f=d[b]||(d[b]={}),l=f[d.uniqueID]||(f[d.uniqueID]={}),c=l[e]||[],h=c[0]===_&&c[1],y=h),!1===y)while(d=++h&&d&&d[m]||(y=h=0)||p.pop())if((s?d.nodeName.toLowerCase()===v:1===d.nodeType)&&++y&&(A&&(f=d[b]||(d[b]={}),l=f[d.uniqueID]||(f[d.uniqueID]={}),l[e]=[_,y]),d===t))break;return y-=i,y===r||y%r===0&&y/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?ce((function(e,n){var r,o=i(e,t),a=o.length;while(a--)r=O(e,o[a]),e[r]=!(n[r]=o[a])})):function(e){return i(e,0,n)}):i}},pseudos:{not:ce((function(e){var t=[],n=[],r=s(e.replace(Q,"$1"));return r[b]?ce((function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))})):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}})),has:ce((function(e){return function(t){return se(e,t).length>0}})),contains:ce((function(e){return e=e.replace(te,ne),function(t){return(t.textContent||i(t)).indexOf(e)>-1}})),lang:ce((function(e){return G.test(e||"")||se.error("unsupported lang: "+e),e=e.replace(te,ne).toLowerCase(),function(t){var n;do{if(n=m?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}})),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===p},focus:function(e){return e===h.activeElement&&(!h.hasFocus||h.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:me(!1),disabled:me(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos["empty"](e)},header:function(e){return K.test(e.nodeName)},input:function(e){return $.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ge((function(){return[0]})),last:ge((function(e,t){return[t-1]})),eq:ge((function(e,t,n){return[n<0?n+t:n]})),even:ge((function(e,t){for(var n=0;nt?t:n;--r>=0;)e.push(r);return e})),gt:ge((function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function _e(e,t,n){for(var r=0,i=t.length;r-1&&(o[c]=!(a[c]=f))}}else v=xe(v===a?v.splice(p,v.length):v),i?i(null,a,v,u):M.apply(a,v)}))}function Ee(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,l=be((function(e){return e===t}),s,!0),f=be((function(e){return O(t,e)>-1}),s,!0),d=[function(e,n,r){var i=!a&&(r||n!==c)||((t=n).nodeType?l(e,n,r):f(e,n,r));return t=null,i}];u1&&we(d),u>1&&ye(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(Q,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,l){var f,p,g,v=0,A="0",y=o&&[],b=[],w=c,x=o||i&&r.find["TAG"]("*",l),C=_+=null==w?1:Math.random()||.1,E=x.length;for(l&&(c=a==h||a||l);A!==E&&null!=(f=x[A]);A++){if(i&&f){p=0,a||f.ownerDocument==h||(d(f),s=!m);while(g=e[p++])if(g(f,a||h,s)){u.push(f);break}l&&(_=C)}n&&((f=!g&&f)&&v--,o&&y.push(f))}if(v+=A,n&&A!==v){p=0;while(g=t[p++])g(y,b,a,s);if(o){if(v>0)while(A--)y[A]||b[A]||(b[A]=B.call(u));b=xe(b)}M.apply(u,b),l&&!o&&b.length>0&&v+t.length>1&&se.uniqueSort(u)}return l&&(_=C,c=w),y};return n?ce(o):o}return Ae.prototype=r.filters=r.pseudos,r.setFilters=new Ae,a=se.tokenize=function(e,t){var n,i,o,a,s,u,c,l=E[e+" "];if(l)return t?0:l.slice(0);s=e,u=[],c=r.preFilter;while(s){for(a in n&&!(i=z.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),n=!1,(i=W.exec(s))&&(n=i.shift(),o.push({value:n,type:i[0].replace(Q," ")}),s=s.slice(n.length)),r.filter)!(i=q[a].exec(s))||c[a]&&!(i=c[a](i))||(n=i.shift(),o.push({value:n,type:a,matches:i}),s=s.slice(n.length));if(!n)break}return t?s.length:s?se.error(e):E(e,u).slice(0)},s=se.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)o=Ee(t[n]),o[b]?r.push(o):i.push(o);o=S(e,Se(i,r)),o.selector=e}return o},u=se.select=function(e,t,n,i){var o,u,c,l,f,d="function"===typeof e&&e,h=!i&&a(e=d.selector||e);if(n=n||[],1===h.length){if(u=h[0]=h[0].slice(0),u.length>2&&"ID"===(c=u[0]).type&&9===t.nodeType&&m&&r.relative[u[1].type]){if(t=(r.find["ID"](c.matches[0].replace(te,ne),t)||[])[0],!t)return n;d&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=q["needsContext"].test(e)?0:u.length;while(o--){if(c=u[o],r.relative[l=c.type])break;if((f=r.find[l])&&(i=f(c.matches[0].replace(te,ne),ee.test(u[0].type)&&ve(t.parentNode)||t))){if(u.splice(o,1),e=i.length&&ye(u),!e)return M.apply(n,i),n;break}}}return(d||s(e,h))(i,t,!m,n,!t||ee.test(e)&&ve(t.parentNode)||t),n},n.sortStable=b.split("").sort(k).join("")===b,n.detectDuplicates=!!f,d(),n.sortDetached=le((function(e){return 1&e.compareDocumentPosition(h.createElement("fieldset"))})),le((function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")}))||fe("type|href|height|width",(function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)})),n.attributes&&le((function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")}))||fe("value",(function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue})),le((function(e){return null==e.getAttribute("disabled")}))||fe(P,(function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null})),se}(n);E.find=D,E.expr=D.selectors,E.expr[":"]=E.expr.pseudos,E.uniqueSort=E.unique=D.uniqueSort,E.text=D.getText,E.isXMLDoc=D.isXML,E.contains=D.contains,E.escapeSelector=D.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&E(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},I=E.expr.match.needsContext;function B(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function M(e,t,n){return A(t)?E.grep(e,(function(e,r){return!!t.call(e,r,e)!==n})):t.nodeType?E.grep(e,(function(e){return e===t!==n})):"string"!==typeof t?E.grep(e,(function(e){return f.call(t,e)>-1!==n})):E.filter(t,e,n)}E.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?E.find.matchesSelector(r,e)?[r]:[]:E.find.matches(e,E.grep(t,(function(e){return 1===e.nodeType})))},E.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!==typeof e)return this.pushStack(E(e).filter((function(){for(t=0;t1?E.uniqueSort(n):n},filter:function(e){return this.pushStack(M(this,e||[],!1))},not:function(e){return this.pushStack(M(this,e||[],!0))},is:function(e){return!!M(this,"string"===typeof e&&I.test(e)?E(e):e||[],!1).length}});var R,O=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,P=E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||R,"string"===typeof e){if(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:O.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:b,!0)),N.test(r[1])&&E.isPlainObject(t))for(r in t)A(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return i=b.getElementById(r[2]),i&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):A(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)};P.prototype=E.fn,R=E(b);var L=/^(?:parents|prev(?:Until|All))/,F={children:!0,contents:!0,next:!0,prev:!0};function U(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter((function(){for(var e=0;e-1:1===n.nodeType&&E.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?E.uniqueSort(o):o)},index:function(e){return e?"string"===typeof e?f.call(E(e),this[0]):f.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(E.uniqueSort(E.merge(this.get(),E(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),E.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return U(e,"nextSibling")},prev:function(e){return U(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&s(e.contentDocument)?e.contentDocument:(B(e,"template")&&(e=e.content||e),E.merge([],e.childNodes))}},(function(e,t){E.fn[e]=function(n,r){var i=E.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"===typeof r&&(i=E.filter(r,i)),this.length>1&&(F[e]||E.uniqueSort(i),L.test(e)&&i.reverse()),this.pushStack(i)}}));var H=/[^\x20\t\r\n\f]+/g;function j(e){var t={};return E.each(e.match(H)||[],(function(e,n){t[n]=!0})),t}function Q(e){return e}function z(e){throw e}function W(e,t,n,r){var i;try{e&&A(i=e.promise)?i.call(e).done(t).fail(n):e&&A(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}E.Callbacks=function(e){e="string"===typeof e?j(e):E.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--})),this},has:function(e){return e?E.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},E.extend({Deferred:function(e){var t=[["notify","progress",E.Callbacks("memory"),E.Callbacks("memory"),2],["resolve","done",E.Callbacks("once memory"),E.Callbacks("once memory"),0,"resolved"],["reject","fail",E.Callbacks("once memory"),E.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return E.Deferred((function(n){E.each(t,(function(t,r){var i=A(e[r[4]])&&e[r[4]];o[r[1]]((function(){var e=i&&i.apply(this,arguments);e&&A(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[r[0]+"With"](this,i?[e]:arguments)}))})),e=null})).promise()},then:function(e,r,i){var o=0;function a(e,t,r,i){return function(){var s=this,u=arguments,c=function(){var n,c;if(!(e=o&&(r!==z&&(s=void 0,u=[n]),t.rejectWith(s,u))}};e?l():(E.Deferred.getStackHook&&(l.stackTrace=E.Deferred.getStackHook()),n.setTimeout(l))}}return E.Deferred((function(n){t[0][3].add(a(0,n,A(i)?i:Q,n.notifyWith)),t[1][3].add(a(0,n,A(e)?e:Q)),t[2][3].add(a(0,n,A(r)?r:z))})).promise()},promise:function(e){return null!=e?E.extend(e,i):i}},o={};return E.each(t,(function(e,n){var a=n[2],s=n[5];i[n[1]]=a.add,s&&a.add((function(){r=s}),t[3-e][2].disable,t[3-e][3].disable,t[0][2].lock,t[0][3].lock),a.add(n[3].fire),o[n[0]]=function(){return o[n[0]+"With"](this===o?void 0:this,arguments),this},o[n[0]+"With"]=a.fireWith})),i.promise(o),e&&e.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=u.call(arguments),o=E.Deferred(),a=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?u.call(arguments):n,--t||o.resolveWith(r,i)}};if(t<=1&&(W(e,o.done(a(n)).resolve,o.reject,!t),"pending"===o.state()||A(i[n]&&i[n].then)))return o.then();while(n--)W(i[n],a(n),o.reject);return o.promise()}});var Y=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;E.Deferred.exceptionHook=function(e,t){n.console&&n.console.warn&&e&&Y.test(e.name)&&n.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},E.readyException=function(e){n.setTimeout((function(){throw e}))};var V=E.Deferred();function G(){b.removeEventListener("DOMContentLoaded",G),n.removeEventListener("load",G),E.ready()}E.fn.ready=function(e){return V.then(e).catch((function(e){E.readyException(e)})),this},E.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--E.readyWait:E.isReady)||(E.isReady=!0,!0!==e&&--E.readyWait>0||V.resolveWith(b,[E]))}}),E.ready.then=V.then,"complete"===b.readyState||"loading"!==b.readyState&&!b.documentElement.doScroll?n.setTimeout(E.ready):(b.addEventListener("DOMContentLoaded",G),n.addEventListener("load",G));var q=function(e,t,n,r,i,o,a){var s=0,u=e.length,c=null==n;if("object"===x(n))for(s in i=!0,n)q(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,A(r)||(a=!0),c&&(a?(t.call(e,r),t=null):(c=t,t=function(e,t,n){return c.call(E(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each((function(){ne.remove(this,e)}))}}),E.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=te.get(e,t),n&&(!r||Array.isArray(n)?r=te.access(e,t,E.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=E.queue(e,t),r=n.length,i=n.shift(),o=E._queueHooks(e,t),a=function(){E.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return te.get(e,n)||te.access(e,n,{empty:E.Callbacks("once memory").add((function(){te.remove(e,[t+"queue",n])}))})}}),E.fn.extend({queue:function(e,t){var n=2;return"string"!==typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]*)/i,be=/^$|^module$|\/(?:java|ecma)script/i;(function(){var e=b.createDocumentFragment(),t=e.appendChild(b.createElement("div")),n=b.createElement("input");n.setAttribute("type","radio"),n.setAttribute("checked","checked"),n.setAttribute("name","t"),t.appendChild(n),v.checkClone=t.cloneNode(!0).cloneNode(!0).lastChild.checked,t.innerHTML="",v.noCloneChecked=!!t.cloneNode(!0).lastChild.defaultValue,t.innerHTML="",v.option=!!t.lastChild})();var we={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function _e(e,t){var n;return n="undefined"!==typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!==typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&B(e,t)?E.merge([e],n):n}function xe(e,t){for(var n=0,r=e.length;n",""]);var Ce=/<|&#?\w+;/;function Ee(e,t,n,r,i){for(var o,a,s,u,c,l,f=t.createDocumentFragment(),d=[],h=0,p=e.length;h-1)i&&i.push(o);else if(c=fe(o),a=_e(f.appendChild(o),"script"),c&&xe(a),n){l=0;while(o=a[l++])be.test(o.type||"")&&n.push(o)}return f}var Se=/^key/,De=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ke=/^([^.]*)(?:\.(.+)|)/;function Te(){return!0}function Ie(){return!1}function Be(e,t){return e===Ne()===("focus"===t)}function Ne(){try{return b.activeElement}catch(e){}}function Me(e,t,n,r,i,o){var a,s;if("object"===typeof t){for(s in"string"!==typeof n&&(r=r||n,n=void 0),t)Me(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"===typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ie;else if(!i)return e;return 1===o&&(a=i,i=function(e){return E().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=E.guid++)),e.each((function(){E.event.add(this,t,i,r,n)}))}function Re(e,t,n){n?(te.set(e,t,!1),E.event.add(e,t,{namespace:!1,handler:function(e){var r,i,o=te.get(this,t);if(1&e.isTrigger&&this[t]){if(o.length)(E.event.special[t]||{}).delegateType&&e.stopPropagation();else if(o=u.call(arguments),te.set(this,t,o),r=n(this,t),this[t](),i=te.get(this,t),o!==i||r?te.set(this,t,!1):i={},o!==i)return e.stopImmediatePropagation(),e.preventDefault(),i.value}else o.length&&(te.set(this,t,{value:E.event.trigger(E.extend(o[0],E.Event.prototype),o.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===te.get(e,t)&&E.event.add(e,t,Te)}E.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,c,l,f,d,h,p,m,g=te.get(e);if(Z(e)){n.handler&&(o=n,n=o.handler,i=o.selector),i&&E.find.matchesSelector(le,i),n.guid||(n.guid=E.guid++),(u=g.events)||(u=g.events=Object.create(null)),(a=g.handle)||(a=g.handle=function(t){return"undefined"!==typeof E&&E.event.triggered!==t.type?E.event.dispatch.apply(e,arguments):void 0}),t=(t||"").match(H)||[""],c=t.length;while(c--)s=ke.exec(t[c])||[],h=m=s[1],p=(s[2]||"").split(".").sort(),h&&(f=E.event.special[h]||{},h=(i?f.delegateType:f.bindType)||h,f=E.event.special[h]||{},l=E.extend({type:h,origType:m,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&E.expr.match.needsContext.test(i),namespace:p.join(".")},o),(d=u[h])||(d=u[h]=[],d.delegateCount=0,f.setup&&!1!==f.setup.call(e,r,p,a)||e.addEventListener&&e.addEventListener(h,a)),f.add&&(f.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,l):d.push(l),E.event.global[h]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,c,l,f,d,h,p,m,g=te.hasData(e)&&te.get(e);if(g&&(u=g.events)){t=(t||"").match(H)||[""],c=t.length;while(c--)if(s=ke.exec(t[c])||[],h=m=s[1],p=(s[2]||"").split(".").sort(),h){f=E.event.special[h]||{},h=(r?f.delegateType:f.bindType)||h,d=u[h]||[],s=s[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=d.length;while(o--)l=d[o],!i&&m!==l.origType||n&&n.guid!==l.guid||s&&!s.test(l.namespace)||r&&r!==l.selector&&("**"!==r||!l.selector)||(d.splice(o,1),l.selector&&d.delegateCount--,f.remove&&f.remove.call(e,l));a&&!d.length&&(f.teardown&&!1!==f.teardown.call(e,p,g.handle)||E.removeEvent(e,h,g.handle),delete u[h])}else for(h in u)E.event.remove(e,h+t[c],n,r,!0);E.isEmptyObject(u)&&te.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=E.event.fix(e),c=(te.get(this,"events")||Object.create(null))[u.type]||[],l=E.event.special[u.type]||{};for(s[0]=u,t=1;t=1))for(;c!==this;c=c.parentNode||this)if(1===c.nodeType&&("click"!==e.type||!0!==c.disabled)){for(o=[],a={},n=0;n-1:E.find(i,this,null,[c]).length),a[i]&&o.push(r);o.length&&s.push({elem:c,handlers:o})}return c=this,u\s*$/g;function Fe(e,t){return B(e,"table")&&B(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function Ue(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function je(e,t){var n,r,i,o,a,s,u;if(1===t.nodeType){if(te.hasData(e)&&(o=te.get(e),u=o.events,u))for(i in te.remove(t,"handle events"),u)for(n=0,r=u[i].length;n1&&"string"===typeof p&&!v.checkClone&&Pe.test(p))return e.each((function(i){var o=e.eq(i);m&&(t[0]=p.call(this,i,o.html())),ze(o,t,n,r)}));if(d&&(i=Ee(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(a=E.map(_e(i,"script"),Ue),s=a.length;f0&&xe(a,!u&&_e(e,"script")),s},cleanData:function(e){for(var t,n,r,i=E.event.special,o=0;void 0!==(n=e[o]);o++)if(Z(n)){if(t=n[te.expando]){if(t.events)for(r in t.events)i[r]?E.event.remove(n,r):E.removeEvent(n,r,t.handle);n[te.expando]=void 0}n[ne.expando]&&(n[ne.expando]=void 0)}}}),E.fn.extend({detach:function(e){return We(this,e,!0)},remove:function(e){return We(this,e)},text:function(e){return q(this,(function(e){return void 0===e?E.text(this):this.empty().each((function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)}))}),null,e,arguments.length)},append:function(){return ze(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Fe(this,e);t.appendChild(e)}}))},prepend:function(){return ze(this,arguments,(function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Fe(this,e);t.insertBefore(e,t.firstChild)}}))},before:function(){return ze(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this)}))},after:function(){return ze(this,arguments,(function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)}))},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(E.cleanData(_e(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map((function(){return E.clone(this,e,t)}))},html:function(e){return q(this,(function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"===typeof e&&!Oe.test(e)&&!we[(ye.exec(e)||["",""])[1].toLowerCase()]){e=E.htmlPrefilter(e);try{for(;n3,le.removeChild(e)),s}}))})();var Ke=["Webkit","Moz","ms"],Xe=b.createElement("div").style,Ze={};function et(e){var t=e[0].toUpperCase()+e.slice(1),n=Ke.length;while(n--)if(e=Ke[n]+t,e in Xe)return e}function tt(e){var t=E.cssProps[e]||Ze[e];return t||(e in Xe?e:Ze[e]=et(e)||e)}var nt=/^(none|table(?!-c[ea]).+)/,rt=/^--/,it={position:"absolute",visibility:"hidden",display:"block"},ot={letterSpacing:"0",fontWeight:"400"};function at(e,t,n){var r=ue.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function st(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=E.css(e,n+ce[a],!0,i)),r?("content"===n&&(u-=E.css(e,"padding"+ce[a],!0,i)),"margin"!==n&&(u-=E.css(e,"border"+ce[a]+"Width",!0,i))):(u+=E.css(e,"padding"+ce[a],!0,i),"padding"!==n?u+=E.css(e,"border"+ce[a]+"Width",!0,i):s+=E.css(e,"border"+ce[a]+"Width",!0,i));return!r&&o>=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function ut(e,t,n){var r=Ve(e),i=!v.boxSizingReliable()||n,o=i&&"border-box"===E.css(e,"boxSizing",!1,r),a=o,s=Je(e,t,r),u="offset"+t[0].toUpperCase()+t.slice(1);if(Ye.test(s)){if(!n)return s;s="auto"}return(!v.boxSizingReliable()&&o||!v.reliableTrDimensions()&&B(e,"tr")||"auto"===s||!parseFloat(s)&&"inline"===E.css(e,"display",!1,r))&&e.getClientRects().length&&(o="border-box"===E.css(e,"boxSizing",!1,r),a=u in e,a&&(s=e[u])),s=parseFloat(s)||0,s+st(e,t,n||(o?"border":"content"),a,r,s)+"px"}function ct(e,t,n,r,i){return new ct.prototype.init(e,t,n,r,i)}E.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Je(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=rt.test(t),c=e.style;if(u||(t=tt(s)),a=E.cssHooks[t]||E.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:c[t];o=typeof n,"string"===o&&(i=ue.exec(n))&&i[1]&&(n=pe(e,t,i),o="number"),null!=n&&n===n&&("number"!==o||u||(n+=i&&i[3]||(E.cssNumber[s]?"":"px")),v.clearCloneStyle||""!==n||0!==t.indexOf("background")||(c[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?c.setProperty(t,n):c[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t),u=rt.test(t);return u||(t=tt(s)),a=E.cssHooks[t]||E.cssHooks[s],a&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Je(e,t,r)),"normal"===i&&t in ot&&(i=ot[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),E.each(["height","width"],(function(e,t){E.cssHooks[t]={get:function(e,n,r){if(n)return!nt.test(E.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?ut(e,t,r):Ge(e,it,(function(){return ut(e,t,r)}))},set:function(e,n,r){var i,o=Ve(e),a=!v.scrollboxSize()&&"absolute"===o.position,s=a||r,u=s&&"border-box"===E.css(e,"boxSizing",!1,o),c=r?st(e,t,r,u,o):0;return u&&a&&(c-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-st(e,t,"border",!1,o)-.5)),c&&(i=ue.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=E.css(e,t)),at(e,n,c)}}})),E.cssHooks.marginLeft=$e(v.reliableMarginLeft,(function(e,t){if(t)return(parseFloat(Je(e,"marginLeft"))||e.getBoundingClientRect().left-Ge(e,{marginLeft:0},(function(){return e.getBoundingClientRect().left})))+"px"})),E.each({margin:"",padding:"",border:"Width"},(function(e,t){E.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"===typeof n?n.split(" "):[n];r<4;r++)i[e+ce[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(E.cssHooks[e+t].set=at)})),E.fn.extend({css:function(e,t){return q(this,(function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ve(e),i=t.length;a1)}}),E.Tween=ct,ct.prototype={constructor:ct,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||E.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(E.cssNumber[n]?"":"px")},cur:function(){var e=ct.propHooks[this.prop];return e&&e.get?e.get(this):ct.propHooks._default.get(this)},run:function(e){var t,n=ct.propHooks[this.prop];return this.options.duration?this.pos=t=E.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):ct.propHooks._default.set(this),this}},ct.prototype.init.prototype=ct.prototype,ct.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=E.css(e.elem,e.prop,""),t&&"auto"!==t?t:0)},set:function(e){E.fx.step[e.prop]?E.fx.step[e.prop](e):1!==e.elem.nodeType||!E.cssHooks[e.prop]&&null==e.elem.style[tt(e.prop)]?e.elem[e.prop]=e.now:E.style(e.elem,e.prop,e.now+e.unit)}}},ct.propHooks.scrollTop=ct.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},E.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},E.fx=ct.prototype.init,E.fx.step={};var lt,ft,dt=/^(?:toggle|show|hide)$/,ht=/queueHooks$/;function pt(){ft&&(!1===b.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(pt):n.setTimeout(pt,E.fx.interval),E.fx.tick())}function mt(){return n.setTimeout((function(){lt=void 0})),lt=Date.now()}function gt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)n=ce[r],i["margin"+n]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function vt(e,t,n){for(var r,i=(bt.tweeners[t]||[]).concat(bt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each((function(){E.removeAttr(this,e)}))}}),E.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"===typeof e.getAttribute?E.prop(e,t,n):(1===o&&E.isXMLDoc(e)||(i=E.attrHooks[t.toLowerCase()]||(E.expr.match.bool.test(t)?wt:void 0)),void 0!==n?null===n?void E.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:(r=E.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!v.radioValue&&"radio"===t&&B(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(H);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),wt={set:function(e,t,n){return!1===t?E.removeAttr(e,n):e.setAttribute(n,n),n}},E.each(E.expr.match.bool.source.match(/\w+/g),(function(e,t){var n=_t[t]||E.find.attr;_t[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=_t[a],_t[a]=i,i=null!=n(e,t,r)?a:null,_t[a]=o),i}}));var xt=/^(?:input|select|textarea|button)$/i,Ct=/^(?:a|area)$/i;function Et(e){var t=e.match(H)||[];return t.join(" ")}function St(e){return e.getAttribute&&e.getAttribute("class")||""}function Dt(e){return Array.isArray(e)?e:"string"===typeof e&&e.match(H)||[]}E.fn.extend({prop:function(e,t){return q(this,E.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each((function(){delete this[E.propFix[e]||e]}))}}),E.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&E.isXMLDoc(e)||(t=E.propFix[t]||t,i=E.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=E.find.attr(e,"tabindex");return t?parseInt(t,10):xt.test(e.nodeName)||Ct.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),v.optSelected||(E.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),E.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],(function(){E.propFix[this.toLowerCase()]=this})),E.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(A(e))return this.each((function(t){E(this).addClass(e.call(this,t,St(this)))}));if(t=Dt(e),t.length)while(n=this[u++])if(i=St(n),r=1===n.nodeType&&" "+Et(i)+" ",r){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");s=Et(r),i!==s&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(A(e))return this.each((function(t){E(this).removeClass(e.call(this,t,St(this)))}));if(!arguments.length)return this.attr("class","");if(t=Dt(e),t.length)while(n=this[u++])if(i=St(n),r=1===n.nodeType&&" "+Et(i)+" ",r){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");s=Et(r),i!==s&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"===typeof t&&r?t?this.addClass(e):this.removeClass(e):A(e)?this.each((function(n){E(this).toggleClass(e.call(this,n,St(this),t),t)})):this.each((function(){var t,i,o,a;if(r){i=0,o=E(this),a=Dt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||(t=St(this),t&&te.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":te.get(this,"__className__")||""))}))},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+Et(St(n))+" ").indexOf(t)>-1)return!0;return!1}});var kt=/\r/g;E.fn.extend({val:function(e){var t,n,r,i=this[0];return arguments.length?(r=A(e),this.each((function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,E(this).val()):e,null==i?i="":"number"===typeof i?i+="":Array.isArray(i)&&(i=E.map(i,(function(e){return null==e?"":e+""}))),t=E.valHooks[this.type]||E.valHooks[this.nodeName.toLowerCase()],t&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))}))):i?(t=E.valHooks[i.type]||E.valHooks[i.nodeName.toLowerCase()],t&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:(n=i.value,"string"===typeof n?n.replace(kt,""):null==n?"":n)):void 0}}),E.extend({valHooks:{option:{get:function(e){var t=E.find.attr(e,"value");return null!=t?t:Et(E.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),E.each(["radio","checkbox"],(function(){E.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=E.inArray(E(e).val(),t)>-1}},v.checkOn||(E.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})})),v.focusin="onfocusin"in n;var Tt=/^(?:focusinfocus|focusoutblur)$/,It=function(e){e.stopPropagation()};E.extend(E.event,{trigger:function(e,t,r,i){var o,a,s,u,c,l,f,d,h=[r||b],m=p.call(e,"type")?e.type:e,g=p.call(e,"namespace")?e.namespace.split("."):[];if(a=d=s=r=r||b,3!==r.nodeType&&8!==r.nodeType&&!Tt.test(m+E.event.triggered)&&(m.indexOf(".")>-1&&(g=m.split("."),m=g.shift(),g.sort()),c=m.indexOf(":")<0&&"on"+m,e=e[E.expando]?e:new E.Event(m,"object"===typeof e&&e),e.isTrigger=i?2:3,e.namespace=g.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+g.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=r),t=null==t?[e]:E.makeArray(t,[e]),f=E.event.special[m]||{},i||!f.trigger||!1!==f.trigger.apply(r,t))){if(!i&&!f.noBubble&&!y(r)){for(u=f.delegateType||m,Tt.test(u+m)||(a=a.parentNode);a;a=a.parentNode)h.push(a),s=a;s===(r.ownerDocument||b)&&h.push(s.defaultView||s.parentWindow||n)}o=0;while((a=h[o++])&&!e.isPropagationStopped())d=a,e.type=o>1?u:f.bindType||m,l=(te.get(a,"events")||Object.create(null))[e.type]&&te.get(a,"handle"),l&&l.apply(a,t),l=c&&a[c],l&&l.apply&&Z(a)&&(e.result=l.apply(a,t),!1===e.result&&e.preventDefault());return e.type=m,i||e.isDefaultPrevented()||f._default&&!1!==f._default.apply(h.pop(),t)||!Z(r)||c&&A(r[m])&&!y(r)&&(s=r[c],s&&(r[c]=null),E.event.triggered=m,e.isPropagationStopped()&&d.addEventListener(m,It),r[m](),e.isPropagationStopped()&&d.removeEventListener(m,It),E.event.triggered=void 0,s&&(r[c]=s)),e.result}},simulate:function(e,t,n){var r=E.extend(new E.Event,n,{type:e,isSimulated:!0});E.event.trigger(r,null,t)}}),E.fn.extend({trigger:function(e,t){return this.each((function(){E.event.trigger(e,t,this)}))},triggerHandler:function(e,t){var n=this[0];if(n)return E.event.trigger(e,t,n,!0)}}),v.focusin||E.each({focus:"focusin",blur:"focusout"},(function(e,t){var n=function(e){E.event.simulate(t,e.target,E.event.fix(e))};E.event.special[t]={setup:function(){var r=this.ownerDocument||this.document||this,i=te.access(r,t);i||r.addEventListener(e,n,!0),te.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this.document||this,i=te.access(r,t)-1;i?te.access(r,t,i):(r.removeEventListener(e,n,!0),te.remove(r,t))}}}));var Bt=n.location,Nt={guid:Date.now()},Mt=/\?/;E.parseXML=function(e){var t;if(!e||"string"!==typeof e)return null;try{t=(new n.DOMParser).parseFromString(e,"text/xml")}catch(r){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||E.error("Invalid XML: "+e),t};var Rt=/\[\]$/,Ot=/\r?\n/g,Pt=/^(?:submit|button|image|reset|file)$/i,Lt=/^(?:input|select|textarea|keygen)/i;function Ft(e,t,n,r){var i;if(Array.isArray(t))E.each(t,(function(t,i){n||Rt.test(e)?r(e,i):Ft(e+"["+("object"===typeof i&&null!=i?t:"")+"]",i,n,r)}));else if(n||"object"!==x(t))r(e,t);else for(i in t)Ft(e+"["+i+"]",t[i],n,r)}E.param=function(e,t){var n,r=[],i=function(e,t){var n=A(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!E.isPlainObject(e))E.each(e,(function(){i(this.name,this.value)}));else for(n in e)Ft(n,e[n],t,i);return r.join("&")},E.fn.extend({serialize:function(){return E.param(this.serializeArray())},serializeArray:function(){return this.map((function(){var e=E.prop(this,"elements");return e?E.makeArray(e):this})).filter((function(){var e=this.type;return this.name&&!E(this).is(":disabled")&&Lt.test(this.nodeName)&&!Pt.test(e)&&(this.checked||!Ae.test(e))})).map((function(e,t){var n=E(this).val();return null==n?null:Array.isArray(n)?E.map(n,(function(e){return{name:t.name,value:e.replace(Ot,"\r\n")}})):{name:t.name,value:n.replace(Ot,"\r\n")}})).get()}});var Ut=/%20/g,Ht=/#.*$/,jt=/([?&])_=[^&]*/,Qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,zt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Wt=/^(?:GET|HEAD)$/,Yt=/^\/\//,Vt={},Gt={},qt="*/".concat("*"),Jt=b.createElement("a");function $t(e){return function(t,n){"string"!==typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(H)||[];if(A(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function Kt(e,t,n,r){var i={},o=e===Gt;function a(s){var u;return i[s]=!0,E.each(e[s]||[],(function(e,s){var c=s(t,n,r);return"string"!==typeof c||o||i[c]?o?!(u=c):void 0:(t.dataTypes.unshift(c),a(c),!1)})),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function Xt(e,t){var n,r,i=E.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&E.extend(!0,e,r),e}function Zt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function en(e,t,n,r){var i,o,a,s,u,c={},l=e.dataTypes.slice();if(l[1])for(a in e.converters)c[a.toLowerCase()]=e.converters[a];o=l.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=l.shift(),o)if("*"===o)o=u;else if("*"!==u&&u!==o){if(a=c[u+" "+o]||c["* "+o],!a)for(i in c)if(s=i.split(" "),s[1]===o&&(a=c[u+" "+s[0]]||c["* "+s[0]],a)){!0===a?a=c[i]:!0!==c[i]&&(o=s[0],l.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(f){return{state:"parsererror",error:a?f:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}Jt.href=Bt.href,E.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Bt.href,type:"GET",isLocal:zt.test(Bt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":qt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":E.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Xt(Xt(e,E.ajaxSettings),t):Xt(E.ajaxSettings,e)},ajaxPrefilter:$t(Vt),ajaxTransport:$t(Gt),ajax:function(e,t){"object"===typeof e&&(t=e,e=void 0),t=t||{};var r,i,o,a,s,u,c,l,f,d,h=E.ajaxSetup({},t),p=h.context||h,m=h.context&&(p.nodeType||p.jquery)?E(p):E.event,g=E.Deferred(),v=E.Callbacks("once memory"),A=h.statusCode||{},y={},w={},_="canceled",x={readyState:0,getResponseHeader:function(e){var t;if(c){if(!a){a={};while(t=Qt.exec(o))a[t[1].toLowerCase()+" "]=(a[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=a[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return c?o:null},setRequestHeader:function(e,t){return null==c&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,y[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)x.always(e[x.status]);else for(t in e)A[t]=[A[t],e[t]];return this},abort:function(e){var t=e||_;return r&&r.abort(t),C(0,t),this}};if(g.promise(x),h.url=((e||h.url||Bt.href)+"").replace(Yt,Bt.protocol+"//"),h.type=t.method||t.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(H)||[""],null==h.crossDomain){u=b.createElement("a");try{u.href=h.url,u.href=u.href,h.crossDomain=Jt.protocol+"//"+Jt.host!==u.protocol+"//"+u.host}catch(S){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!==typeof h.data&&(h.data=E.param(h.data,h.traditional)),Kt(Vt,h,t,x),c)return x;for(f in l=E.event&&h.global,l&&0===E.active++&&E.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Wt.test(h.type),i=h.url.replace(Ht,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(Ut,"+")):(d=h.url.slice(i.length),h.data&&(h.processData||"string"===typeof h.data)&&(i+=(Mt.test(i)?"&":"?")+h.data,delete h.data),!1===h.cache&&(i=i.replace(jt,"$1"),d=(Mt.test(i)?"&":"?")+"_="+Nt.guid+++d),h.url=i+d),h.ifModified&&(E.lastModified[i]&&x.setRequestHeader("If-Modified-Since",E.lastModified[i]),E.etag[i]&&x.setRequestHeader("If-None-Match",E.etag[i])),(h.data&&h.hasContent&&!1!==h.contentType||t.contentType)&&x.setRequestHeader("Content-Type",h.contentType),x.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+qt+"; q=0.01":""):h.accepts["*"]),h.headers)x.setRequestHeader(f,h.headers[f]);if(h.beforeSend&&(!1===h.beforeSend.call(p,x,h)||c))return x.abort();if(_="abort",v.add(h.complete),x.done(h.success),x.fail(h.error),r=Kt(Gt,h,t,x),r){if(x.readyState=1,l&&m.trigger("ajaxSend",[x,h]),c)return x;h.async&&h.timeout>0&&(s=n.setTimeout((function(){x.abort("timeout")}),h.timeout));try{c=!1,r.send(y,C)}catch(S){if(c)throw S;C(-1,S)}}else C(-1,"No Transport");function C(e,t,a,u){var f,d,y,b,w,_=t;c||(c=!0,s&&n.clearTimeout(s),r=void 0,o=u||"",x.readyState=e>0?4:0,f=e>=200&&e<300||304===e,a&&(b=Zt(h,x,a)),!f&&E.inArray("script",h.dataTypes)>-1&&(h.converters["text script"]=function(){}),b=en(h,b,x,f),f?(h.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(E.lastModified[i]=w),w=x.getResponseHeader("etag"),w&&(E.etag[i]=w)),204===e||"HEAD"===h.type?_="nocontent":304===e?_="notmodified":(_=b.state,d=b.data,y=b.error,f=!y)):(y=_,!e&&_||(_="error",e<0&&(e=0))),x.status=e,x.statusText=(t||_)+"",f?g.resolveWith(p,[d,_,x]):g.rejectWith(p,[x,_,y]),x.statusCode(A),A=void 0,l&&m.trigger(f?"ajaxSuccess":"ajaxError",[x,h,f?d:y]),v.fireWith(p,[x,_]),l&&(m.trigger("ajaxComplete",[x,h]),--E.active||E.event.trigger("ajaxStop")))}return x},getJSON:function(e,t,n){return E.get(e,t,n,"json")},getScript:function(e,t){return E.get(e,void 0,t,"script")}}),E.each(["get","post"],(function(e,t){E[t]=function(e,n,r,i){return A(n)&&(i=i||r,r=n,n=void 0),E.ajax(E.extend({url:e,type:t,dataType:i,data:n,success:r},E.isPlainObject(e)&&e))}})),E.ajaxPrefilter((function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")})),E._evalUrl=function(e,t,n){return E.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){E.globalEval(e,t,n)}})},E.fn.extend({wrapAll:function(e){var t;return this[0]&&(A(e)&&(e=e.call(this[0])),t=E(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map((function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e})).append(this)),this},wrapInner:function(e){return A(e)?this.each((function(t){E(this).wrapInner(e.call(this,t))})):this.each((function(){var t=E(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)}))},wrap:function(e){var t=A(e);return this.each((function(n){E(this).wrapAll(t?e.call(this,n):e)}))},unwrap:function(e){return this.parent(e).not("body").each((function(){E(this).replaceWith(this.childNodes)})),this}}),E.expr.pseudos.hidden=function(e){return!E.expr.pseudos.visible(e)},E.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},E.ajaxSettings.xhr=function(){try{return new n.XMLHttpRequest}catch(e){}};var tn={0:200,1223:204},nn=E.ajaxSettings.xhr();v.cors=!!nn&&"withCredentials"in nn,v.ajax=nn=!!nn,E.ajaxTransport((function(e){var t,r;if(v.cors||nn&&!e.crossDomain)return{send:function(i,o){var a,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(a in e.xhrFields)s[a]=e.xhrFields[a];for(a in e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest"),i)s.setRequestHeader(a,i[a]);t=function(e){return function(){t&&(t=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!==typeof s.status?o(0,"error"):o(s.status,s.statusText):o(tn[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!==typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=t(),r=s.onerror=s.ontimeout=t("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&n.setTimeout((function(){t&&r()}))},t=t("abort");try{s.send(e.hasContent&&e.data||null)}catch(u){if(t)throw u}},abort:function(){t&&t()}}})),E.ajaxPrefilter((function(e){e.crossDomain&&(e.contents.script=!1)})),E.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return E.globalEval(e),e}}}),E.ajaxPrefilter("script",(function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")})),E.ajaxTransport("script",(function(e){var t,n;if(e.crossDomain||e.scriptAttrs)return{send:function(r,i){t=E(" - + {% endblock %} From 2663edf32a9f43c7a26fa604f0c3e04a59ff1883 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Fri, 3 Jul 2020 12:19:33 -0300 Subject: [PATCH 13/25] =?UTF-8?q?Adiciona=20status=20da=20tramita=C3=A7?= =?UTF-8?q?=C3=A3o=20das=20mat=C3=A9rias=20na=20sess=C3=A3o=20plen=C3=A1ri?= =?UTF-8?q?a=20e=20seus=20relat=C3=B3rios=20(#3214)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/relatorios/views.py | 4 +- sapl/sessao/views.py | 165 ++++++------------ .../materias_expediente.html | 3 + .../materias_ordemdia.html | 3 + .../blocos_ata/materias_expediente.html | 3 + .../sessao/blocos_ata/materias_ordem_dia.html | 3 + .../blocos_resumo/materias_expediente.html | 5 + .../blocos_resumo/materias_ordem_dia.html | 5 + 8 files changed, 83 insertions(+), 108 deletions(-) diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 200ce04af..35a6f6ddf 100755 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -601,6 +601,7 @@ def get_sessao_plenaria(sessao, casa): str(materia.ano)), "des_numeracao": ' ', "des_turno": get_turno(materia)[0], + "situacao": materia.materiaemtramitacao_set.first().tramitacao.status, "txt_ementa": str(materia.ementa), "ordem_observacao": expediente_materia.observacao, "nom_resultado": '', @@ -703,7 +704,8 @@ def get_sessao_plenaria(sessao, casa): # https://github.com/interlegis/sapl/issues/1009 "txt_ementa": html.unescape(materia.ementa), "ordem_observacao": html.unescape(votacao.observacao), - "nom_autor": '' + "nom_autor": '', + "situacao": materia.materiaemtramitacao_set.first().tramitacao.status }) autoria = materia.autoria_set.all() diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index 26da9d23a..e650fb5e1 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -29,7 +29,7 @@ from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, PermissionRequiredForAppCrudMixin, make_pagination) from sapl.materia.forms import filtra_tramitacao_status from sapl.materia.models import (Autoria, TipoMateriaLegislativa, - Tramitacao) + Tramitacao, MateriaEmTramitacao) from sapl.materia.views import MateriaLegislativaPesquisaView from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato, Parlamentar, SessaoLegislativa) @@ -228,19 +228,23 @@ def customize_link_materia(context, pk, has_permission, is_expediente): if t[0] == tramitacao.turno: turno = t[1] break + situacao = MateriaEmTramitacao.objects.select_related("materia", "tramitacao")\ + .filter(materia=materia).first().tramitacao.status title_materia = """%s
Processo: %s
Autor: %s
Protocolo: %s
Turno: %s
+ Situação: %s
""" % (obj.materia.id, url_materia, row[1][0], numeracao if numeracao else '', autor if autor else '', num_protocolo if num_protocolo else '', - turno) + turno, + situacao if situacao else '') # Na linha abaixo, o segundo argumento é None para não colocar # url em toda a string de title_materia @@ -1689,28 +1693,14 @@ def get_expedientes(sessao_plenaria): def get_materias_expediente(sessao_plenaria): - materias = ExpedienteMateria.objects.filter( - sessao_plenaria_id=sessao_plenaria.id) - materias_expediente = [] - for m in materias: - - ementa = m.materia.ementa - titulo = m.materia - numero = m.numero_ordem - + for m in ExpedienteMateria.objects.select_related("materia").filter(sessao_plenaria_id=sessao_plenaria.id): tramitacao = '' - tramitacoes = Tramitacao.objects.filter( - materia=m.materia).order_by('-pk') - for aux_tramitacao in tramitacoes: + for aux_tramitacao in Tramitacao.objects.filter(materia=m.materia).order_by('-pk'): if aux_tramitacao.turno: tramitacao = aux_tramitacao break - turno = None - if tramitacao: - turno = get_turno(tramitacao.turno) - rv = m.registrovotacao_set.first() rp = m.retiradapauta_set.filter(materia=m.materia).first() if rv: @@ -1720,30 +1710,24 @@ def get_materias_expediente(sessao_plenaria): resultado = rp.tipo_de_retirada.descricao resultado_observacao = rp.observacao else: - if m.tipo_votacao == 4: - resultado = _('Matéria lida') - else: - resultado = _('Matéria não votada') + resultado = _('Matéria lida') if m.tipo_votacao == 4 else _('Matéria não votada') resultado_observacao = _(' ') - autoria = Autoria.objects.filter(materia_id=m.materia_id) - autor = [str(x.autor) for x in autoria] - - mat = {'ementa': ementa, - 'titulo': titulo, - 'numero': numero, - 'turno': turno, - 'resultado': resultado, - 'resultado_observacao': resultado_observacao, - 'autor': autor, - 'numero_protocolo': m.materia.numero_protocolo, - 'numero_processo': m.materia.numeracao_set.last(), - 'observacao': m.observacao - } - materias_expediente.append(mat) + materias_expediente.append({ + 'ementa': m.materia.ementa, + 'titulo': m.materia, + 'numero': m.numero_ordem, + 'turno': get_turno(tramitacao.turno) if tramitacao else None, + 'situacao': m.materia.materiaemtramitacao_set.first().tramitacao.status, + 'resultado': resultado, + 'resultado_observacao': resultado_observacao, + 'autor': [str(x.autor) for x in Autoria.objects.select_related("autor").filter(materia_id=m.materia_id)], + 'numero_protocolo': m.materia.numero_protocolo, + 'numero_processo': m.materia.numeracao_set.last(), + 'observacao': m.observacao + }) - context = {'materia_expediente': materias_expediente} - return context + return {'materia_expediente': materias_expediente} def get_oradores_expediente(sessao_plenaria): @@ -1811,26 +1795,14 @@ def get_assinaturas(sessao_plenaria): def get_materias_ordem_do_dia(sessao_plenaria): - ordem = OrdemDia.objects.filter(sessao_plenaria_id=sessao_plenaria.id) materias_ordem = [] - for o in ordem: - ementa = o.materia.ementa - ementa_observacao = o.observacao - titulo = o.materia - numero = o.numero_ordem - + for o in OrdemDia.objects.filter(sessao_plenaria_id=sessao_plenaria.id): tramitacao = '' - tramitacoes = Tramitacao.objects.filter( - materia=o.materia).order_by('-pk') - for aux_tramitacao in tramitacoes: + for aux_tramitacao in Tramitacao.objects.filter(materia=o.materia).order_by('-pk'): if aux_tramitacao.turno: tramitacao = aux_tramitacao break - turno = None - if tramitacao: - turno = get_turno(tramitacao.turno) - # Verificar resultado rv = o.registrovotacao_set.filter(materia=o.materia).first() rp = o.retiradapauta_set.filter(materia=o.materia).first() @@ -1841,55 +1813,44 @@ def get_materias_ordem_do_dia(sessao_plenaria): resultado = rp.tipo_de_retirada.descricao resultado_observacao = rp.observacao else: - if o.tipo_votacao == 4: - resultado = _('Matéria lida') - else: - resultado = _('Matéria não votada') + resultado = _('Matéria lida') if o.tipo_votacao == 4 else _('Matéria não votada') resultado_observacao = _(' ') - voto_sim = "" - voto_nao = "" - voto_abstencoes = "" voto_nominal = [] - if o.tipo_votacao == 2: - votos = VotoParlamentar.objects.filter(ordem=o.id) - for voto in votos: - aux_voto = (voto.parlamentar.nome_completo, voto.voto) - voto_nominal.append(aux_voto) - try: - voto = RegistroVotacao.objects.filter(ordem=o.id).last() + for voto in VotoParlamentar.objects.filter(ordem=o.id): + voto_nominal.append((voto.parlamentar.nome_completo, voto.voto)) + + voto = RegistroVotacao.objects.filter(ordem=o.id).last() + if voto: voto_sim = voto.numero_votos_sim voto_nao = voto.numero_votos_nao voto_abstencoes = voto.numero_abstencoes - except AttributeError: + else: voto_sim = " Não Informado" voto_nao = " Não Informado" voto_abstencoes = " Não Informado" - autoria = Autoria.objects.filter( - materia_id=o.materia_id) - autor = [str(x.autor) for x in autoria] - mat = {'ementa': ementa, - 'ementa_observacao': ementa_observacao, - 'titulo': titulo, - 'numero': numero, - 'turno': turno, - 'resultado': resultado, - 'resultado_observacao': resultado_observacao, - 'autor': autor, - 'numero_protocolo': o.materia.numero_protocolo, - 'numero_processo': o.materia.numeracao_set.last(), - 'tipo_votacao': o.TIPO_VOTACAO_CHOICES[o.tipo_votacao], - 'voto_sim': voto_sim, - 'voto_nao': voto_nao, - 'voto_abstencoes': voto_abstencoes, - 'voto_nominal': voto_nominal, - } - materias_ordem.append(mat) + materias_ordem.append({ + 'ementa': o.materia.ementa, + 'ementa_observacao': o.observacao, + 'titulo': o.materia, + 'numero': o.numero_ordem, + 'turno': get_turno(tramitacao.turno) if tramitacao else None, + 'situacao': o.materia.materiaemtramitacao_set.first().tramitacao.status, + 'resultado': resultado, + 'resultado_observacao': resultado_observacao, + 'autor': [str(x.autor) for x in Autoria.objects.select_related("autor").filter(materia_id=o.materia_id)], + 'numero_protocolo': o.materia.numero_protocolo, + 'numero_processo': o.materia.numeracao_set.last(), + 'tipo_votacao': o.TIPO_VOTACAO_CHOICES[o.tipo_votacao], + 'voto_sim': voto_sim, + 'voto_nao': voto_nao, + 'voto_abstencoes': voto_abstencoes, + 'voto_nominal': voto_nominal, + }) - context = {'materias_ordem': materias_ordem} - return context + return {'materias_ordem': materias_ordem} def get_oradores_ordemdia(sessao_plenaria): @@ -1957,13 +1918,9 @@ class ResumoView(DetailView): context = self.get_context_data(object=self.object) # Votos de Votação Nominal de Matérias Expediente - materias_expediente_votacao_nominal = ExpedienteMateria.objects.filter( - sessao_plenaria_id=self.object.id, - tipo_votacao=2).order_by('-materia') - votacoes = [] - for mevn in materias_expediente_votacao_nominal: - + for mevn in ExpedienteMateria.objects.filter(sessao_plenaria_id=self.object.id, tipo_votacao=2)\ + .order_by('-materia'): votos_materia = [] titulo_materia = mevn.materia registro = RegistroVotacao.objects.filter(expediente=mevn) @@ -1971,11 +1928,10 @@ class ResumoView(DetailView): for vp in VotoParlamentar.objects.filter(votacao=registro).order_by('parlamentar'): votos_materia.append(vp) - dados_votacao = { + votacoes.append({ 'titulo': titulo_materia, 'votos': votos_materia - } - votacoes.append(dados_votacao) + }) context.update({'votos_nominais_materia_expediente': votacoes}) @@ -2009,12 +1965,8 @@ class ResumoView(DetailView): # ===================================================================== # Matérias Ordem do Dia # Votos de Votação Nominal de Matérias Ordem do Dia - materias_ordem_dia_votacao_nominal = OrdemDia.objects.filter( - sessao_plenaria_id=self.object.id, - tipo_votacao=2).order_by('-materia') - votacoes_od = [] - for modvn in materias_ordem_dia_votacao_nominal: + for modvn in OrdemDia.objects.filter(sessao_plenaria_id=self.object.id, tipo_votacao=2).order_by('-materia'): votos_materia_od = [] t_materia = modvn.materia registro_od = RegistroVotacao.objects.filter(ordem=modvn) @@ -2022,11 +1974,10 @@ class ResumoView(DetailView): for vp_od in VotoParlamentar.objects.filter(votacao=registro_od).order_by('parlamentar'): votos_materia_od.append(vp_od) - dados_votacao_od = { + votacoes_od.append({ 'titulo': t_materia, 'votos': votos_materia_od - } - votacoes_od.append(dados_votacao_od) + }) context.update({'votos_nominais_materia_ordem_dia': votacoes_od}) diff --git a/sapl/templates/relatorios/blocos_sessao_plenaria/materias_expediente.html b/sapl/templates/relatorios/blocos_sessao_plenaria/materias_expediente.html index bb5178b59..265184e58 100644 --- a/sapl/templates/relatorios/blocos_sessao_plenaria/materias_expediente.html +++ b/sapl/templates/relatorios/blocos_sessao_plenaria/materias_expediente.html @@ -16,6 +16,9 @@
{{materia.num_ordem}} - {{materia.id_materia}}
Turno: {{materia.des_turno}}
{{materia.num_autores}}: {{materia.nom_autor}}
+ {% if materia.situacao %} +
Situação: {{materia.situacao}}
+ {% endif %}
{{materia.txt_ementa}}
diff --git a/sapl/templates/relatorios/blocos_sessao_plenaria/materias_ordemdia.html b/sapl/templates/relatorios/blocos_sessao_plenaria/materias_ordemdia.html index a44b4d3ca..ec2356126 100644 --- a/sapl/templates/relatorios/blocos_sessao_plenaria/materias_ordemdia.html +++ b/sapl/templates/relatorios/blocos_sessao_plenaria/materias_ordemdia.html @@ -16,6 +16,9 @@
{{materia.num_ordem}} - {{materia.id_materia}}
Turno: {{materia.des_turno}}
{{materia.num_autores}}: {{materia.nom_autor}}
+ {% if materia.situacao %} +
Situação: {{materia.situacao}}
+ {% endif %} {{materia.txt_ementa}} diff --git a/sapl/templates/sessao/blocos_ata/materias_expediente.html b/sapl/templates/sessao/blocos_ata/materias_expediente.html index 4a3964993..5b21e200b 100644 --- a/sapl/templates/sessao/blocos_ata/materias_expediente.html +++ b/sapl/templates/sessao/blocos_ata/materias_expediente.html @@ -15,6 +15,9 @@ {% if m.turno %} Turno: {{m.turno}}, {% endif %} + {% if m.situacao %} + Situação: {{m.situacao}}, + {% endif %} {% if m.tipo_votacao %} Tipo: {{m.tipo_votacao}}, Sim: {{ m.voto_sim }}, diff --git a/sapl/templates/sessao/blocos_ata/materias_ordem_dia.html b/sapl/templates/sessao/blocos_ata/materias_ordem_dia.html index 6b38be5e4..c25ce9683 100644 --- a/sapl/templates/sessao/blocos_ata/materias_ordem_dia.html +++ b/sapl/templates/sessao/blocos_ata/materias_ordem_dia.html @@ -15,6 +15,9 @@ {% if m.turno %} Turno: {{m.turno}}, {% endif %} + {% if m.situacao %} + Situação: {{m.situacao}}, + {% endif %} {% if m.tipo_votacao %} Tipo: {{m.tipo_votacao}}, Sim: {{ m.voto_sim }}, diff --git a/sapl/templates/sessao/blocos_resumo/materias_expediente.html b/sapl/templates/sessao/blocos_resumo/materias_expediente.html index 046c15cee..4a8be7c55 100644 --- a/sapl/templates/sessao/blocos_resumo/materias_expediente.html +++ b/sapl/templates/sessao/blocos_resumo/materias_expediente.html @@ -34,6 +34,11 @@
Processo: {{ m.numero_processo }} {% endif %} + + {% if m.situacao %} +
+ Situação: {{ m.situacao }} + {% endif %} {{m.ementa|dont_break_out}}
diff --git a/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html b/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html index 909adf1b2..a463f7492 100644 --- a/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html +++ b/sapl/templates/sessao/blocos_resumo/materias_ordem_dia.html @@ -35,6 +35,11 @@
Processo: {{ m.numero_processo }} {% endif %} + + {% if m.situacao %} +
+ Situação: {{ m.situacao }} + {% endif %} {{m.ementa|dont_break_out}}
{{m.observacao|dont_break_out}} {{m.resultado}}
{{m.resultado_observacao}} From e1bb6d3652e7f16255ee82ecfba436529c8c6c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Fri, 3 Jul 2020 12:57:19 -0300 Subject: [PATCH 14/25] =?UTF-8?q?3195=20-=20Troca=20de=20Mat=C3=A9ria=20em?= =?UTF-8?q?=20Norma=20Existente=20(#3206)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Diminui a quantidade de queries * Adiciona modal para saber se atualiza ementa e indexação na troca de matéria * Verifica se intancia já existe para mostrar modal * Corrige mensagem na modal Co-authored-by: Edward <9326037+edwardoliveira@users.noreply.github.com> * Remove verificação de form através do path Co-authored-by: Edward <9326037+edwardoliveira@users.noreply.github.com> --- sapl/norma/views.py | 6 +- sapl/templates/norma/normajuridica_form.html | 116 ++++++++++++------- 2 files changed, 75 insertions(+), 47 deletions(-) diff --git a/sapl/norma/views.py b/sapl/norma/views.py index 98825f4cf..21975f77a 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -258,7 +258,7 @@ class NormaCrud(Crud): def get_initial(self): initial = super().get_initial() - norma = NormaJuridica.objects.get(id=self.kwargs['pk']) + norma = NormaJuridica.objects.select_related("materia").get(id=self.kwargs['pk']) if norma.materia: initial['tipo_materia'] = norma.materia.tipo initial['ano_materia'] = norma.materia.ano @@ -267,9 +267,7 @@ class NormaCrud(Crud): return initial def form_valid(self, form): - norma_antiga = NormaJuridica.objects.get( - pk=self.kwargs['pk'] - ) + norma_antiga = NormaJuridica.objects.get(pk=self.kwargs['pk']) # Feito desta forma para que sejam materializados os assuntos # antigos diff --git a/sapl/templates/norma/normajuridica_form.html b/sapl/templates/norma/normajuridica_form.html index 91531c4d1..0355faee8 100644 --- a/sapl/templates/norma/normajuridica_form.html +++ b/sapl/templates/norma/normajuridica_form.html @@ -10,20 +10,23 @@ var tipo_materia = $("#id_tipo_materia").val(); var numero_materia = $("#id_numero_materia").val(); var ano_materia = $("#id_ano_materia").val(); - var tipo = $('#id_tipo').val(); - var ano = $('#id_ano').val(); - var numero = $('#id_numero').val(); - var ementa = $('#id_ementa').val(); + if (tipo_materia && numero_materia && ano_materia) { - $.get("/sessao/recuperar-materia", - {tipo_materia: tipo_materia, - numero_materia: numero_materia, - ano_materia: ano_materia}, - function(data, status) { - $("#id_ementa").val(data.ementa); - $("#id_indexacao").val(data.indexacao); - } - ); + $.get("/sessao/recuperar-materia", { + tipo_materia: tipo_materia, + numero_materia: numero_materia, + ano_materia: ano_materia + }, (data, status) => { + $("#id_fundo_confirmacao_mudanca_ementa_indexacao").fadeIn(); + $("#id_sim_mudanca_ementa_indexacao").click(() => { + $("#id_ementa").val(data.ementa); + $("#id_indexacao").val(data.indexacao); + $("#id_fundo_confirmacao_mudanca_ementa_indexacao").hide(); + }); + $("#id_nao_mudanca_ementa_indexacao").click(() => { + $("#id_fundo_confirmacao_mudanca_ementa_indexacao").hide(); + }); + }); } } var fields = ["#id_tipo_materia", "#id_numero_materia", "#id_ano_materia"] @@ -36,12 +39,11 @@ var ano = $("#id_ano").val(); if (tipo) { - $.get("/norma/recuperar-numero-norma",{tipo: tipo, - ano: ano}, - function(data, status) { - $("#id_numero").val(data.numero); - $("#id_ano").val(data.ano); - }); + $.get("/norma/recuperar-numero-norma", { tipo: tipo, ano: ano }, + (data, status) => { + $("#id_numero").val(data.numero); + $("#id_ano").val(data.ano); + }); } } var fields = ["#id_tipo", "#id_ano"]; @@ -58,29 +60,57 @@ } }); - var modal_estilos = 'display: block;' - +'width: 85%; max-width: 600px;' - +'background: #fff; padding: 15px;' - +'border-radius: 5px;' - +'-webkit-box-shadow: 0px 6px 14px -2px rgba(0,0,0,0.75);' - +'-moz-box-shadow: 0px 6px 14px -2px rgba(0,0,0,0.75);' - +'box-shadow: 0px 6px 14px -2px rgba(0,0,0,0.75);' - +'position: fixed;' - +'top: 50%; left: 50%;' - +'transform: translate(-50%,-50%);' - +'z-index: 99999999; text-align: center'; - - var fundo_modal_estilos = 'top: 0; right: 0;' - +'bottom: 0; left: 0; position: fixed;' - +'background-color: rgba(0, 0, 0, 0.6); z-index: 99999999;' - +'display: none;'; - - var meu_modal = '
' - +'
' - +'

Atenção! Ano de apresentação e ano da norma são diferentes.


' - +'' - +'
'; + var modal_estilos = ` + display: block; + width: 85%; + max-width: 600px; + background: #fff; + padding: 15px; + border-radius: 5px; + -webkit-box-shadow: 0px 6px 14px -2px rgba(0,0,0,0.75); + -moz-box-shadow: 0px 6px 14px -2px rgba(0,0,0,0.75); + box-shadow: 0px 6px 14px -2px rgba(0,0,0,0.75); + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%,-50%); + z-index: 99999999; + text-align: center; + `; + + var fundo_modal_estilos = ` + top: 0; + right: 0; + bottom: 0; + left: 0; + position: fixed; + background-color: rgba(0, 0, 0, 0.6); + z-index: 99999999; + display: none; + `; + + var meu_modal = ` +
+
+

Atenção! Ano de apresentação e ano da norma são diferentes.


+ +
+
+ `; + + const confirmacao_mudanca_ementa_indexacao = ` +
+
+

Houve à mudança de Matéria vinculada a norma.

+

Deseja atualizar a Ementa e a Indexação com a nova Matéria?


+ + +
+
+ `; + function verifica_ano(){ let ano = $("select#id_ano.select").val(); @@ -93,7 +123,7 @@ } $(document).ready(function() { - $("body").append(meu_modal); + $("body").append(meu_modal, confirmacao_mudanca_ementa_indexacao); $("#fundo_modal, #close_model_btn").click(function(){ $("#fundo_modal").hide(); }); $("#meu_modal").click(function(e){ e.stopPropagation(); }); From 52859676986d7b7a3fa46461ee66666ce3f1a127 Mon Sep 17 00:00:00 2001 From: Ulysses Lara Date: Fri, 3 Jul 2020 15:53:24 -0300 Subject: [PATCH 15/25] =?UTF-8?q?3138=20gerar=20etiqueta=20com=20informa?= =?UTF-8?q?=C3=A7=C3=B5es=20da=20materia=20(#3162)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix#3138 - Iniciando etiqueta de materia legislativa * Gerando pdf com codigo de barra e opção largura/altura * Anexando etiqueta em Texto Articulado * Adaptando pra ficar parecido com protocolo Fix #3138 * Colocando classe de configuração de etiqueta da materia no map rules * Ajustando importações * Melhorando a disposição dos elementos da etiqueta * Mudando fontes da etiqueta * Melhorando formato da etiqueta * Limitando campo ementa para no maximo 200 caracteres em ementa de materia legislativa * Aumenta um pouco mais o tam máx Co-authored-by: eribeiro --- requirements/requirements.txt | 1 + sapl/materia/forms.py | 9 ++- .../0068_configetiquetamaterialegislativa.py | 23 ++++++++ .../migrations/0069_auto_20200518_1519.py | 20 +++++++ sapl/materia/models.py | 8 +++ sapl/materia/urls.py | 4 +- sapl/materia/views.py | 18 +++++- sapl/relatorios/urls.py | 4 +- sapl/relatorios/views.py | 55 ++++++++++++++++++- sapl/rules/map_rules.py | 3 +- .../materia/config_etiqueta_materia.html | 19 +++++++ sapl/templates/materia/layouts.yaml | 6 ++ .../materia/materialegislativa_detail.html | 6 ++ .../materia/materialegislativa_filter.html | 2 + sapl/templates/menu_tabelas_auxiliares.yaml | 3 + .../etiqueta_materia_legislativa.html | 40 ++++++++++++++ 16 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 sapl/materia/migrations/0068_configetiquetamaterialegislativa.py create mode 100644 sapl/materia/migrations/0069_auto_20200518_1519.py create mode 100644 sapl/templates/materia/config_etiqueta_materia.html create mode 100644 sapl/templates/relatorios/etiqueta_materia_legislativa.html diff --git a/requirements/requirements.txt b/requirements/requirements.txt index c5a1f6fd9..65d3e3f87 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -31,6 +31,7 @@ more-itertools==8.2.0 pysolr==3.6.0 PyPDF4==1.27.0 pyoai==2.5.0 +Unidecode==1.1.1 git+https://github.com/interlegis/trml2pdf git+https://github.com/interlegis/django-admin-bootstrapped diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 65d227894..b8a1ed246 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -34,7 +34,7 @@ from sapl.materia.models import (AssuntoMateria, Autoria, MateriaAssunto, MateriaLegislativa, Orgao, RegimeTramitacao, StatusTramitacao, TipoDocumento, TipoProposicao, - UnidadeTramitacao) + UnidadeTramitacao,ConfigEtiquetaMateriaLegislativa) from sapl.norma.models import (LegislacaoCitada, NormaJuridica, TipoNormaJuridica) from sapl.parlamentares.models import Legislatura, Partido, Parlamentar @@ -2913,3 +2913,10 @@ class MateriaPesquisaSimplesForm(forms.Form): _('A Data Final não pode ser menor que a Data Inicial')) return cleaned_data + +class ConfigEtiquetaMateriaLegislativaForms(ModelForm): + class Meta: + model = ConfigEtiquetaMateriaLegislativa + fields = '__all__' + + \ No newline at end of file diff --git a/sapl/materia/migrations/0068_configetiquetamaterialegislativa.py b/sapl/materia/migrations/0068_configetiquetamaterialegislativa.py new file mode 100644 index 000000000..3dce8a3f3 --- /dev/null +++ b/sapl/materia/migrations/0068_configetiquetamaterialegislativa.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.29 on 2020-05-18 18:14 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0067_auto_20200416_1538'), + ] + + operations = [ + migrations.CreateModel( + name='ConfigEtiquetaMateriaLegislativa', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('largura', models.FloatField(default=5)), + ('altura', models.FloatField(default=3)), + ], + ), + ] diff --git a/sapl/materia/migrations/0069_auto_20200518_1519.py b/sapl/materia/migrations/0069_auto_20200518_1519.py new file mode 100644 index 000000000..4251cb6e9 --- /dev/null +++ b/sapl/materia/migrations/0069_auto_20200518_1519.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.29 on 2020-05-18 18:19 +from __future__ import unicode_literals + +from django.db import migrations + + +def create_first(apps, schema_editor): + db_alias = schema_editor.connection.alias + Type = apps.get_model("materia", "ConfigEtiquetaMateriaLegislativa") + Type.objects.using(db_alias).create() + +class Migration(migrations.Migration): + dependencies = [ + ('materia', '0068_configetiquetamaterialegislativa'), + ] + + operations = [ + migrations.RunPython(create_first), + ] \ No newline at end of file diff --git a/sapl/materia/models.py b/sapl/materia/models.py index b94ea78ff..fe0c45c39 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -1116,3 +1116,11 @@ class MateriaEmTramitacao(models.Model): def __str__(self): return '{}/{}'.format(self.materia, self.tramitacao) + +class ConfigEtiquetaMateriaLegislativa(models.Model): + largura = models.FloatField(default=5) + altura = models.FloatField(default=3) + + def save(self, *args, **kwargs): + self.id = 1 + return super().save(*args, **kwargs) \ No newline at end of file diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index 05733599c..4c6c5166b 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -27,7 +27,8 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, proposicao_texto, recuperar_materia, ExcluirTramitacaoEmLoteView, RetornarProposicao, MateriaPesquisaSimplesView, - DespachoInicialMultiCreateView, get_zip_docacessorios, get_pdf_docacessorios) + DespachoInicialMultiCreateView, get_zip_docacessorios, + get_pdf_docacessorios, configEtiquetaMateriaLegislativaCrud) from sapl.norma.views import NormaPesquisaSimplesView from sapl.protocoloadm.views import ( FichaPesquisaAdmView, FichaSelecionaAdmView) @@ -172,6 +173,7 @@ urlpatterns_sistema = [ url(r'^sistema/materia/status-tramitacao/', include(StatusTramitacaoCrud.get_urls())), url(r'^sistema/materia/orgao/', include(OrgaoCrud.get_urls())), + url(r'^sistema/materia/config-etiqueta-materia-legislativas/',configEtiquetaMateriaLegislativaCrud, name="configEtiquetaMateriaLegislativaCrud"), ] urlpatterns = urlpatterns_impressos + urlpatterns_materia + \ diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 773ca0eaf..ded3dc6ea 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -32,6 +32,8 @@ from django.utils.translation import ugettext_lazy as _ from django.views.generic import CreateView, ListView, TemplateView, UpdateView from django.views.generic.base import RedirectView from django.views.generic.edit import FormView +from django.shortcuts import render + from django_filters.views import FilterView @@ -48,7 +50,7 @@ from sapl.materia.forms import (AnexadaForm, AutoriaForm, AutoriaMultiCreateForm ConfirmarProposicaoForm, DevolverProposicaoForm, DespachoInicialCreateForm, LegislacaoCitadaForm, MateriaPesquisaSimplesForm, OrgaoForm, ProposicaoForm, - TipoProposicaoForm, TramitacaoForm, TramitacaoUpdateForm) + TipoProposicaoForm, TramitacaoForm, TramitacaoUpdateForm,ConfigEtiquetaMateriaLegislativaForms) from sapl.norma.models import LegislacaoCitada from sapl.parlamentares.models import Legislatura from sapl.protocoloadm.models import Protocolo @@ -72,7 +74,7 @@ from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, De DocumentoAcessorio, MateriaAssunto, MateriaLegislativa, Numeracao, Orgao, Origem, Proposicao, RegimeTramitacao, Relatoria, StatusTramitacao, TipoDocumento, TipoFimRelatoria, TipoMateriaLegislativa, TipoProposicao, - Tramitacao, UnidadeTramitacao) + Tramitacao, UnidadeTramitacao,ConfigEtiquetaMateriaLegislativa) AssuntoMateriaCrud = CrudAux.build(AssuntoMateria, 'assunto_materia') @@ -2824,3 +2826,15 @@ def get_pdf_docacessorios(request, pk): % external_name) return response +def configEtiquetaMateriaLegislativaCrud(request): + config = ConfigEtiquetaMateriaLegislativa.objects.last() + if request.method == "POST": + form = ConfigEtiquetaMateriaLegislativaForms(request.POST, instance=config) + if form.is_valid(): + config = form.save(commit=False) + config.published_date = timezone.now() + config.save() + return redirect('materia/config_etiqueta_materia.html', {'form': form}) + else: + form = ConfigEtiquetaMateriaLegislativaForms(instance=config) + return render(request, 'materia/config_etiqueta_materia.html', {'form': form}) \ No newline at end of file diff --git a/sapl/relatorios/urls.py b/sapl/relatorios/urls.py index 05ad22671..e60a1e03e 100644 --- a/sapl/relatorios/urls.py +++ b/sapl/relatorios/urls.py @@ -6,7 +6,7 @@ from .views import (relatorio_capa_processo, relatorio_etiqueta_protocolo, relatorio_materia, relatorio_ordem_dia, relatorio_pauta_sessao, relatorio_protocolo, relatorio_sessao_plenaria, - resumo_ata_pdf, relatorio_sessao_plenaria_pdf) + resumo_ata_pdf, relatorio_sessao_plenaria_pdf, etiqueta_materia_legislativa) app_name = AppConfig.name @@ -33,4 +33,6 @@ urlpatterns = [ resumo_ata_pdf, name='resumo_ata_pdf'), url(r'^relatorios/(?P\d+)/sessao-plenaria-pdf$', relatorio_sessao_plenaria_pdf, name='relatorio_sessao_plenaria_pdf'), + url(r'^relatorios/(?P\d+)/etiqueta-materia-legislativa$', + etiqueta_materia_legislativa, name='etiqueta_materia_legislativa'), ] diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 35a6f6ddf..beb523bb1 100755 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -3,6 +3,7 @@ import html import logging import re import tempfile +import unidecode from django.core.exceptions import ObjectDoesNotExist from django.http import Http404, HttpResponse @@ -15,7 +16,7 @@ from sapl.settings import MEDIA_URL from sapl.base.models import Autor, CasaLegislativa from sapl.comissoes.models import Comissao from sapl.materia.models import (Autoria, MateriaLegislativa, Numeracao, - Tramitacao, UnidadeTramitacao) + Tramitacao, UnidadeTramitacao, ConfigEtiquetaMateriaLegislativa) from sapl.parlamentares.models import CargoMesa, Filiacao, Parlamentar from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, TramitacaoAdministrativo) @@ -26,7 +27,7 @@ from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao, SessaoPlenariaPresenca, OcorrenciaSessao, RegistroVotacao, VotoParlamentar, OradorOrdemDia, TipoExpediente, ResumoOrdenacao) from sapl.settings import STATIC_ROOT -from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data +from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data, create_barcode from sapl.sessao.views import (get_identificacao_basica, get_mesa_diretora, get_presenca_sessao, get_expedientes, @@ -1005,6 +1006,8 @@ def relatorio_etiqueta_protocolo(request, nro, ano): protocolo = Protocolo.objects.filter(numero=nro, ano=ano) + m = MateriaLegislativa.objects.filter(numero_protocolo=nro,ano=ano) + protocolo_data = get_etiqueta_protocolos(protocolo) pdf = pdf_etiqueta_protocolo_gerar.principal(imagem, @@ -1500,3 +1503,51 @@ def relatorio_sessao_plenaria_pdf(request, pk): response.write(pdf_file) return response + + +def gera_etiqueta_ml(materia_legislativa, base_url): + confg = ConfigEtiquetaMateriaLegislativa.objects.first() + + ml_info = unidecode.unidecode("{}/{}-{}".format(materia_legislativa.numero, + materia_legislativa.ano, + materia_legislativa.tipo.sigla)) + base64_data = create_barcode(ml_info, 100, 500) + barcode = 'data:image/png;base64,{0}'.format(base64_data) + + max_ementa_size = 240 + ementa = materia_legislativa.ementa + ementa = ementa if len(ementa) < max_ementa_size else ementa[:max_ementa_size]+"..." + + context = { + 'numero': materia_legislativa.numero, + 'ano': materia_legislativa.ano, + 'tipo': materia_legislativa.tipo, + 'data_apresentacao':materia_legislativa.data_apresentacao, + 'autores': materia_legislativa.autores.all(), + 'ementa':ementa, + 'largura': confg.largura, + 'altura':confg.largura, + 'barcode': barcode + } + + main_template = render_to_string('relatorios/etiqueta_materia_legislativa.html', context) + + html = HTML(base_url=base_url, string=main_template) + main_doc = html.render(stylesheets=[CSS(string="@page {{size: {}cm {}cm;}}".format(confg.largura,confg.altura))]) + + pdf_file = main_doc.write_pdf() + return pdf_file + + +def etiqueta_materia_legislativa(request, pk): + base_url = request.build_absolute_uri() + materia_legislativa = MateriaLegislativa.objects.get(pk=pk) + + pdf_file = gera_etiqueta_ml(materia_legislativa, base_url) + + response = HttpResponse(content_type='application/pdf;') + response['Content-Disposition'] = 'inline; filename=etiqueta.pdf' + response['Content-Transfer-Encoding'] = 'binary' + response.write(pdf_file) + + return response \ No newline at end of file diff --git a/sapl/rules/map_rules.py b/sapl/rules/map_rules.py index e47ebe5dc..316ce8ce3 100644 --- a/sapl/rules/map_rules.py +++ b/sapl/rules/map_rules.py @@ -258,7 +258,8 @@ rules_group_geral = { (materia.Parecer, __base__, __perms_publicas__), (materia.StatusTramitacao, __base__, __perms_publicas__), (materia.UnidadeTramitacao, __base__, __perms_publicas__), - + (materia.ConfigEtiquetaMateriaLegislativa, __base__, set()), + (norma.AssuntoNorma, __base__, __perms_publicas__), (norma.TipoNormaJuridica, __base__, __perms_publicas__), diff --git a/sapl/templates/materia/config_etiqueta_materia.html b/sapl/templates/materia/config_etiqueta_materia.html new file mode 100644 index 000000000..cea6716c6 --- /dev/null +++ b/sapl/templates/materia/config_etiqueta_materia.html @@ -0,0 +1,19 @@ +{% extends "crud/form.html" %} +{% load i18n %} +{% load crispy_forms_tags %} + +{% block base_content %} +

Configuração Etiqueta Materia Legislativa

+
+ {% csrf_token %} + {{ form|crispy }} +
+
+
+ Cancelar + +
+
+
+
+{% endblock base_content %} diff --git a/sapl/templates/materia/layouts.yaml b/sapl/templates/materia/layouts.yaml index a885a418d..142dcdf91 100644 --- a/sapl/templates/materia/layouts.yaml +++ b/sapl/templates/materia/layouts.yaml @@ -157,3 +157,9 @@ MateriaLegislativaDetail: - ementa - indexacao - observacao + +ConfigEtiquetaMateriaLegislativa: + {% trans 'Configurações de Etiqueta' %}: + - largura + - altura + - mostrar_em_arquivo \ No newline at end of file diff --git a/sapl/templates/materia/materialegislativa_detail.html b/sapl/templates/materia/materialegislativa_detail.html index 10749b765..2d46b3312 100644 --- a/sapl/templates/materia/materialegislativa_detail.html +++ b/sapl/templates/materia/materialegislativa_detail.html @@ -10,6 +10,12 @@ {% endif %} {% endblock sub_actions %} +{% block editions %} + {{ block.super }} + {% trans 'Etiqueta' %} +{% endblock editions %} + + {% block detail_content %} {{ block.super }} {% if object.registrovotacao_set.exists %} diff --git a/sapl/templates/materia/materialegislativa_filter.html b/sapl/templates/materia/materialegislativa_filter.html index 5cf56d17d..9e91c29b8 100644 --- a/sapl/templates/materia/materialegislativa_filter.html +++ b/sapl/templates/materia/materialegislativa_filter.html @@ -1,6 +1,7 @@ {% extends "crud/detail.html" %} {% load i18n %} {% load crispy_forms_tags common_tags%} +{% load webpack_static from webpack_loader %} {% block actions %} @@ -47,6 +48,7 @@ {{m.tipo.sigla}} {{m.numero}}/{{m.ano}} - {{m.tipo}} + Etiqueta Individual
Ementa: {{ m.ementa|dont_break_out }}
diff --git a/sapl/templates/menu_tabelas_auxiliares.yaml b/sapl/templates/menu_tabelas_auxiliares.yaml index 8a83ac44f..864b8e5a6 100644 --- a/sapl/templates/menu_tabelas_auxiliares.yaml +++ b/sapl/templates/menu_tabelas_auxiliares.yaml @@ -119,6 +119,9 @@ - title: {% trans 'Assunto Matéria' %} url: sapl.materia:assuntomateria_list css_class: btn btn-link + - title: {% trans 'Configuração Etiqueta Materia Legislativa' %} + url: sapl.materia:configEtiquetaMateriaLegislativaCrud + css_class: btn btn-link - title: {% trans 'Módulo Normas Jurídicas' %} css_class: head_title children: diff --git a/sapl/templates/relatorios/etiqueta_materia_legislativa.html b/sapl/templates/relatorios/etiqueta_materia_legislativa.html new file mode 100644 index 000000000..365d02bfb --- /dev/null +++ b/sapl/templates/relatorios/etiqueta_materia_legislativa.html @@ -0,0 +1,40 @@ + +{% load i18n %} +{% load crispy_forms_tags %} +{% load common_tags %} +{% load static %} + + + + + + + +
+

Materia Legislativa - {{numero}}/{{ano}}

+

Tipo: {{tipo.sigla}} - {{tipo.descricao}}

+

Data: {{data_apresentacao}}

+

Ementa: {{ementa}}

+ +
+ From 4d36d526dbf388a65615991b834d36f0cb122ba6 Mon Sep 17 00:00:00 2001 From: Ulysses Lara Date: Fri, 3 Jul 2020 15:56:27 -0300 Subject: [PATCH 16/25] =?UTF-8?q?Fix=20#3200=20#3201=20#3203=20adicionando?= =?UTF-8?q?=20numera=C3=A7=C3=A3o=20autom=C3=A1tica=20em=20oradores=20sess?= =?UTF-8?q?=C3=A3o=20(#3207)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/sessao/views.py | 15 ++++++++++++++- sapl/templates/sessao/oradores_create.html | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 sapl/templates/sessao/oradores_create.html diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py index e650fb5e1..019b33dd0 100755 --- a/sapl/sessao/views.py +++ b/sapl/sessao/views.py @@ -710,6 +710,8 @@ class OradorCrud(MasterDetailCrud): class CreateView(MasterDetailCrud.CreateView): form_class = OradorForm + template_name = 'sessao/oradores_create.html' + def get_initial(self): return {'id_sessao': self.kwargs['pk']} @@ -722,6 +724,8 @@ class OradorCrud(MasterDetailCrud): if tipo_sessao.nome == "Solene": context.update( {'subnav_template_name': 'sessao/subnav-solene.yaml'}) + ultimo_orador = Orador.objects.filter(sessao_plenaria=kwargs['root_pk']).order_by("-numero_ordem").first() + context["ultima_ordem"] = ultimo_orador.numero_ordem if ultimo_orador else 0 return context def get_success_url(self): @@ -779,6 +783,7 @@ class OradorExpedienteCrud(OradorCrud): class CreateView(MasterDetailCrud.CreateView): form_class = OradorExpedienteForm + template_name = 'sessao/oradores_create.html' def get_initial(self): return {'id_sessao': self.kwargs['pk']} @@ -791,6 +796,8 @@ class OradorExpedienteCrud(OradorCrud): if tipo_sessao.nome == "Solene": context.update( {'subnav_template_name': 'sessao/subnav-solene.yaml'}) + ultimo_orador = OradorExpediente.objects.filter(sessao_plenaria=kwargs['root_pk']).order_by("-numero_ordem").first() + context["ultima_ordem"] = ultimo_orador.numero_ordem if ultimo_orador else 0 return context def get_success_url(self): @@ -854,9 +861,9 @@ class OradorExpedienteCrud(OradorCrud): class OradorOrdemDiaCrud(OradorCrud): model = OradorOrdemDia - class CreateView(MasterDetailCrud.CreateView): form_class = OradorOrdemDiaForm + template_name = 'sessao/oradores_create.html' def get_initial(self): return {'id_sessao': self.kwargs['pk']} @@ -865,6 +872,12 @@ class OradorOrdemDiaCrud(OradorCrud): return reverse('sapl.sessao:oradorordemdia_list', kwargs={'pk': self.kwargs['pk']}) + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + ultimo_orador = OradorOrdemDia.objects.filter(sessao_plenaria=kwargs['root_pk']).order_by("-numero_ordem").first() + context["ultima_ordem"] = ultimo_orador.numero_ordem if ultimo_orador else 0 + return context + class UpdateView(MasterDetailCrud.UpdateView): form_class = OradorOrdemDiaForm diff --git a/sapl/templates/sessao/oradores_create.html b/sapl/templates/sessao/oradores_create.html new file mode 100644 index 000000000..26e9ee6b1 --- /dev/null +++ b/sapl/templates/sessao/oradores_create.html @@ -0,0 +1,17 @@ +{% extends "crud/form.html" %} +{% load i18n %} +{% load crispy_forms_tags %} +{% load common_tags %} + +{% block extra_js %} + +{% endblock extra_js %} From c34f2aca7d90790bee697f4fa8ea2c4700264588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Fri, 3 Jul 2020 16:00:31 -0300 Subject: [PATCH 17/25] =?UTF-8?q?3178=20-=20Atualiza=20status=20de=20ativa?= =?UTF-8?q?=C3=A7=C3=A3o=20do=20usu=C3=A1rio=20com=20o=20do=20parlamentar?= =?UTF-8?q?=20vinculado=20(#3186)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Atualiza status de ativação do usuário com o do parlamentar vinculado * Realiza mudanças solicitadas --- sapl/parlamentares/forms.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py index 448535d40..2f2cd49c3 100755 --- a/sapl/parlamentares/forms.py +++ b/sapl/parlamentares/forms.py @@ -216,6 +216,17 @@ class ParlamentarForm(FileFieldCheckMixin, ModelForm): 'biografia': forms.Textarea( attrs={'id': 'texto-rico'})} + def save(self, commit=True): + parlamentar = super().save() + autor = parlamentar.autor.first() + usuario = autor.user if autor else None + + if autor and usuario: + usuario.is_active = parlamentar.ativo + usuario.save() + + return parlamentar + class ParlamentarFilterSet(django_filters.FilterSet): nome_parlamentar = django_filters.CharFilter( From 56f43a6965f0cdd4b4275542dec651e586115968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?= Date: Fri, 3 Jul 2020 16:05:22 -0300 Subject: [PATCH 18/25] =?UTF-8?q?Fix=20#3174=20-=20Visualiza=C3=A7=C3=A3o?= =?UTF-8?q?=20dos=20dados=20de=20altera=C3=A7=C3=A3o=20de=20uma=20tramita?= =?UTF-8?q?=C3=A7=C3=A3o=20de=20Mat=C3=A9ria=20Legislativa=20(#3215)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #3174 - Altera perm. visualização autor tram. * Atualização sapl/templates/materia/tramitacao_detail.html Co-authored-by: Edward <9326037+edwardoliveira@users.noreply.github.com> * Retira cód. inutilizado * Update sapl/materia/views.py Co-authored-by: Edward <9326037+edwardoliveira@users.noreply.github.com> --- sapl/materia/views.py | 4 ++-- sapl/templates/materia/tramitacao_detail.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index ded3dc6ea..dedab0ed0 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -1388,7 +1388,6 @@ class TramitacaoCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['user'] = self.request.user return context @@ -2826,6 +2825,7 @@ def get_pdf_docacessorios(request, pk): % external_name) return response + def configEtiquetaMateriaLegislativaCrud(request): config = ConfigEtiquetaMateriaLegislativa.objects.last() if request.method == "POST": @@ -2837,4 +2837,4 @@ def configEtiquetaMateriaLegislativaCrud(request): return redirect('materia/config_etiqueta_materia.html', {'form': form}) else: form = ConfigEtiquetaMateriaLegislativaForms(instance=config) - return render(request, 'materia/config_etiqueta_materia.html', {'form': form}) \ No newline at end of file + return render(request, 'materia/config_etiqueta_materia.html', {'form': form}) diff --git a/sapl/templates/materia/tramitacao_detail.html b/sapl/templates/materia/tramitacao_detail.html index df108ad13..8b2458720 100644 --- a/sapl/templates/materia/tramitacao_detail.html +++ b/sapl/templates/materia/tramitacao_detail.html @@ -3,7 +3,7 @@ {% block detail_content %} {{ block.super }} - {% if user.is_superuser %} + {% if 'materia.detail_tramitacao' in request.user.get_all_permissions %}
{% if tramitacao.user %}
From cf2f461b3fbf1bf060022b7594875e4fae8e72b1 Mon Sep 17 00:00:00 2001 From: ulyssesBML Date: Tue, 7 Jul 2020 13:07:08 -0300 Subject: [PATCH 19/25] =?UTF-8?q?HOT-FIX=20-=20Subindo=20script=20para=20c?= =?UTF-8?q?riar=20hash=20de=20recebimento=20de=20proposi=C3=A7=C3=A3o=20se?= =?UTF-8?q?m=20recibo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/views.py | 4 ++-- scripts/gerar_hash_proposicoes.py | 35 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 scripts/gerar_hash_proposicoes.py diff --git a/sapl/base/views.py b/sapl/base/views.py index 56e8879e1..6a29eb5d1 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -2084,17 +2084,17 @@ class AppConfigCrud(CrudAux): return super().form_valid(form) def gerar_hash(self, inst): - inst.save() if inst.texto_original: try: inst.hash_code = gerar_hash_arquivo( inst.texto_original.path, str(inst.pk)) + inst.save() except IOError: raise ValidationError("Existem proposicoes com arquivos inexistentes.") elif inst.texto_articulado.exists(): ta = inst.texto_articulado.first() inst.hash_code = 'P' + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(inst.pk) - inst.save() + inst.save() class CreateView(CrudAux.CreateView): diff --git a/scripts/gerar_hash_proposicoes.py b/scripts/gerar_hash_proposicoes.py new file mode 100644 index 000000000..0591ec60f --- /dev/null +++ b/scripts/gerar_hash_proposicoes.py @@ -0,0 +1,35 @@ +# Gerar hash de proposições para recebimento sem recibo +from sapl.materia.models import Proposicao +from sapl.utils import gerar_hash_arquivo, SEPARADOR_HASH_PROPOSICAO +from datetime import datetime + +def gerar_hash(proposicao): + if proposicao.texto_original: + try: + proposicao.hash_code = gerar_hash_arquivo( + proposicao.texto_original.path, str(proposicao.pk)) + except IOError: + raise Exception("Existem proposicoes com arquivos inexistentes.") + elif proposicao.texto_articulado.exists(): + ta = proposicao.texto_articulado.first() + proposicao.hash_code = 'P' + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(proposicao.pk) + print(proposicao.hash_code) + proposicao.save() + + +def gerar_hash_proposicoes(): + di = datetime.now() + print(di) + props = Proposicao.objects.filter(hash_code='').exclude(data_envio__isnull=True) + print("Total de proposicoes: %s" % props.count()) + for prop in props: + try: + print(".",end="") + gerar_hash(prop) + except Exception as e: + print('Erro para proposicao', prop) + print(e) + + elapsed = datetime.now() - di + print("\n {}s".format(elapsed.seconds)) + From dc3b1fd6165d7657a952df18f053507cda2a7925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Wed, 8 Jul 2020 12:04:44 -0300 Subject: [PATCH 20/25] =?UTF-8?q?HOT-FIX:=20Corrige=20data=5Fultima=5Fatua?= =?UTF-8?q?lizacao=20para=20estat=C3=ADsticas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/views.py | 41 +++++++++++++++++------------------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index 6a29eb5d1..960e7827c 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -1631,32 +1631,25 @@ def mandato_sem_data_inicio(): def get_estatistica(request): + materias = MateriaLegislativa.objects.all() + normas = NormaJuridica.objects.all() + + datas = [ + materias.order_by('-data_ultima_atualizacao').values_list('data_ultima_atualizacao', flat=True) + .exclude(data_ultima_atualizacao__isnull=True).first(), + normas.order_by('-data_ultima_atualizacao').values_list('data_ultima_atualizacao', flat=True) + .exclude(data_ultima_atualizacao__isnull=True).first() + ] - json_dict = {} - - datas = [MateriaLegislativa.objects.all(). - order_by('-data_ultima_atualizacao'). - values_list('data_ultima_atualizacao', flat=True). - first(), - NormaJuridica.objects.all(). - order_by('-data_ultima_atualizacao'). - values_list('data_ultima_atualizacao', flat=True). - first()] # Retorna [None, None] se inexistem registros - - max_data = '' - - if datas[0] and datas[1]: - max_data = max(datas) - else: - max_data = next(iter([i for i in datas if i is not None]), '') - - json_dict["data_ultima_atualizacao"] = max_data - json_dict["num_materias_legislativas"] = MateriaLegislativa.objects.all().count() - json_dict["num_normas_juridicas "] = NormaJuridica.objects.all().count() - json_dict["num_parlamentares"] = Parlamentar.objects.all().count() - json_dict["num_sessoes_plenarias"] = SessaoPlenaria.objects.all().count() + max_data = max(datas) if datas[0] and datas[1] else next(iter([i for i in datas if i is not None]), '') - return JsonResponse(json_dict) + return JsonResponse({ + "data_ultima_atualizacao": max_data, + "num_materias_legislativas": materias.count(), + "num_normas_juridicas ": normas.count(), + "num_parlamentares": Parlamentar.objects.all().count(), + "num_sessoes_plenarias": SessaoPlenaria.objects.all().count() + }) class ListarMandatoSemDataInicioView(PermissionRequiredMixin, ListView): From f8be7fb90ffc3c9f58418c21a40bc725ff12be0a Mon Sep 17 00:00:00 2001 From: Ulysses Lara Date: Thu, 9 Jul 2020 10:36:46 -0300 Subject: [PATCH 21/25] =?UTF-8?q?Filtrando=20proposi=C3=A7=C3=A3o=20por=20?= =?UTF-8?q?data=20de=20recebimento=20(#3219)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/views.py | 2 +- scripts/gerar_hash_proposicoes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/base/views.py b/sapl/base/views.py index 960e7827c..67222cd6c 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -2065,7 +2065,7 @@ class AppConfigCrud(CrudAux): recibo_prop_atual = AppConfig.objects.last().receber_recibo_proposicao recibo_prop_novo = self.request.POST['receber_recibo_proposicao'] if recibo_prop_novo == 'False' and recibo_prop_atual: - props = Proposicao.objects.filter(hash_code='').exclude(data_envio__isnull=True) + props = Proposicao.objects.filter(hash_code='', data_recebimento__isnull=True).exclude(data_envio__isnull=True) for prop in props: try: self.gerar_hash(prop) diff --git a/scripts/gerar_hash_proposicoes.py b/scripts/gerar_hash_proposicoes.py index 0591ec60f..f7a3af3a6 100644 --- a/scripts/gerar_hash_proposicoes.py +++ b/scripts/gerar_hash_proposicoes.py @@ -20,7 +20,7 @@ def gerar_hash(proposicao): def gerar_hash_proposicoes(): di = datetime.now() print(di) - props = Proposicao.objects.filter(hash_code='').exclude(data_envio__isnull=True) + props = Proposicao.objects.filter(hash_code='', data_recebimento__isnull=True).exclude(data_envio__isnull=True) print("Total de proposicoes: %s" % props.count()) for prop in props: try: From ddc3ed9d2a874d8c2a8646b79f33bc3b1467fe34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Thu, 9 Jul 2020 10:39:20 -0300 Subject: [PATCH 22/25] =?UTF-8?q?Troca=20restri=C3=A7=C3=A3o=20de=20Autor?= =?UTF-8?q?=20em=20Protocolo=20(#3218)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/base/models.py | 30 ++++--- .../migrations/0033_auto_20200708_1312.py | 21 +++++ sapl/protocoloadm/models.py | 79 +++++++++++-------- 3 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 sapl/protocoloadm/migrations/0033_auto_20200708_1312.py diff --git a/sapl/base/models.py b/sapl/base/models.py index 07f028984..3c8f2753c 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -231,24 +231,28 @@ class TipoAutor(models.Model): @reversion.register() class Autor(models.Model): - - user = models.OneToOneField(get_settings_auth_user_model(), - on_delete=models.SET_NULL, - null=True) - - tipo = models.ForeignKey(TipoAutor, verbose_name=_('Tipo do Autor'), - on_delete=models.PROTECT) - + user = models.OneToOneField( + get_settings_auth_user_model(), + on_delete=models.SET_NULL, + null=True) + tipo = models.ForeignKey( + TipoAutor, + verbose_name=_('Tipo do Autor'), + on_delete=models.PROTECT) content_type = models.ForeignKey( ContentType, - blank=True, null=True, default=None) + blank=True, + null=True, + default=None) object_id = models.PositiveIntegerField( - blank=True, null=True, default=None) + blank=True, + null=True, + default=None) autor_related = GenericForeignKey('content_type', 'object_id') - nome = models.CharField( - max_length=120, blank=True, verbose_name=_('Nome do Autor')) - + max_length=120, + blank=True, + verbose_name=_('Nome do Autor')) cargo = models.CharField(max_length=50, blank=True) class Meta: diff --git a/sapl/protocoloadm/migrations/0033_auto_20200708_1312.py b/sapl/protocoloadm/migrations/0033_auto_20200708_1312.py new file mode 100644 index 000000000..1edf18073 --- /dev/null +++ b/sapl/protocoloadm/migrations/0033_auto_20200708_1312.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.29 on 2020-07-08 16:12 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0032_auto_20200416_1538'), + ] + + operations = [ + migrations.AlterField( + model_name='protocolo', + name='autor', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='base.Autor'), + ), + ] diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py index e1a6077dd..72d5cae30 100644 --- a/sapl/protocoloadm/models.py +++ b/sapl/protocoloadm/models.py @@ -53,43 +53,55 @@ def texto_upload_path(instance, filename): @reversion.register() class Protocolo(models.Model): numero = models.PositiveIntegerField( - blank=False, null=False, verbose_name=_('Número de Protocolo')) - ano = models.PositiveSmallIntegerField(blank=False, - null=False, - choices=RANGE_ANOS, - verbose_name=_('Ano do Protocolo')) - data = models.DateField(null=True, blank=True, - verbose_name=_('Data do Protocolo'), - help_text=_('Informado manualmente')) - hora = models.TimeField(null=True, blank=True, - verbose_name=_('Hora do Protocolo'), - help_text=_('Informado manualmente')) + blank=False, + null=False, + verbose_name=_('Número de Protocolo')) + ano = models.PositiveSmallIntegerField( + blank=False, + null=False, + choices=RANGE_ANOS, + verbose_name=_('Ano do Protocolo')) + data = models.DateField( + null=True, + blank=True, + verbose_name=_('Data do Protocolo'), + help_text=_('Informado manualmente')) + hora = models.TimeField( + null=True, + blank=True, + verbose_name=_('Hora do Protocolo'), + help_text=_('Informado manualmente')) timestamp_data_hora_manual = models.DateTimeField(default=timezone.now) user_data_hora_manual = models.CharField( - max_length=256, blank=True, + max_length=256, + blank=True, verbose_name=_('IP'), - help_text=_('Usuário que está realizando Protocolo e informando ' - 'data e hora manualmente.')) + help_text=_('Usuário que está realizando Protocolo e informando data e hora manualmente.')) ip_data_hora_manual = models.CharField( - max_length=256, blank=True, + max_length=256, + blank=True, verbose_name=_('IP'), - help_text=_('Endereço IP da estação de trabalho ' - 'do usuário que está realizando Protocolo e informando ' - 'data e hora manualmente.')) - - # Não foi utilizado auto_now_add=True em timestamp porque - # ele usa datetime.now que não é timezone aware. + help_text=_('Endereço IP da estação de trabalho do usuário que está realizando Protocolo e ' + 'informando data e hora manualmente.')) + # Não foi utilizado auto_now_add=True em timestamp porque ele usa datetime.now que não é timezone aware. timestamp = models.DateTimeField( - default=timezone.now, null=True, blank=True) + null=True, + blank=True, + default=timezone.now) tipo_protocolo = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Tipo de Protocolo')) + blank=True, + null=True, + verbose_name=_('Tipo de Protocolo')) tipo_processo = models.PositiveIntegerField() interessado = models.CharField( - max_length=200, blank=True, verbose_name=_('Interessado')) - autor = models.ForeignKey(Autor, - blank=True, - null=True, - on_delete=models.PROTECT) + max_length=200, + blank=True, + verbose_name=_('Interessado')) + autor = models.ForeignKey( + Autor, + blank=True, + null=True, + on_delete=models.SET_NULL) assunto_ementa = models.TextField(blank=True) tipo_documento = models.ForeignKey( TipoDocumentoAdministrativo, @@ -104,14 +116,17 @@ class Protocolo(models.Model): on_delete=models.PROTECT, verbose_name=_('Tipo de Matéria')) numero_paginas = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Número de Páginas')) - observacao = models.TextField( - blank=True, verbose_name=_('Observação')) + blank=True, + null=True, + verbose_name=_('Número de Páginas')) + observacao = models.TextField(blank=True, verbose_name=_('Observação')) anulado = models.BooleanField(default=False) user_anulacao = models.CharField(max_length=20, blank=True) ip_anulacao = models.CharField(max_length=15, blank=True) justificativa_anulacao = models.CharField( - max_length=260, blank=True, verbose_name=_('Motivo')) + max_length=260, + blank=True, + verbose_name=_('Motivo')) timestamp_anulacao = models.DateTimeField(blank=True, null=True) class Meta: From b34c06bbc9bb5a50052fc4a956b7d015b4ab08bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Rodrigues?= Date: Fri, 10 Jul 2020 14:16:15 -0300 Subject: [PATCH 23/25] Fix #3221 - Aumenta tam fonte (#3222) --- sapl/templates/relatorios/relatorio_pauta_sessao.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/templates/relatorios/relatorio_pauta_sessao.html b/sapl/templates/relatorios/relatorio_pauta_sessao.html index ccf41ace4..8cc6f9fd9 100644 --- a/sapl/templates/relatorios/relatorio_pauta_sessao.html +++ b/sapl/templates/relatorios/relatorio_pauta_sessao.html @@ -19,7 +19,7 @@ MatériaEmenta {% for m in materia_expediente %} - + {{ m.numero }} - {{ m.titulo }}
Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} @@ -38,7 +38,7 @@ MatériaEmenta {% for m in materias_ordem %} - + {{m.numero}} - {{m.titulo}}
Autor{{ m.autor|length|pluralize:"es" }}: {{ m.autor|join:', ' }} From 16149d4e5bec503db821a0c6f5128410082529c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Cantu=C3=A1ria?= Date: Mon, 13 Jul 2020 14:18:15 -0300 Subject: [PATCH 24/25] =?UTF-8?q?HOT-FIX:=20Atualiza=20vers=C3=A3o=20do=20?= =?UTF-8?q?python?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 80532c789..ac8e19b06 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python python: - - 3.5 + - 3.6 services: - postgresql From 44d2a2d734fadfbd10edc2ccea85b3016d5a9058 Mon Sep 17 00:00:00 2001 From: Ulysses Lara Date: Tue, 14 Jul 2020 11:05:38 -0300 Subject: [PATCH 25/25] Comentando link do antigo relatorio de resumo da sessao (#3223) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * HOT-FIX: Atualiza versão do python * Comentando link do antido relatorio de resumo da sessao Co-authored-by: Vinícius Cantuária --- sapl/relatorios/urls.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapl/relatorios/urls.py b/sapl/relatorios/urls.py index e60a1e03e..d24c67aaf 100644 --- a/sapl/relatorios/urls.py +++ b/sapl/relatorios/urls.py @@ -21,8 +21,8 @@ urlpatterns = [ name='relatorio_documento_administrativo'), url(r'^relatorios/espelho$', relatorio_espelho, name='relatorio_espelho'), - url(r'^relatorios/(?P\d+)/sessao-plenaria$', - relatorio_sessao_plenaria, name='relatorio_sessao_plenaria'), + #url(r'^relatorios/(?P\d+)/sessao-plenaria$', + # relatorio_sessao_plenaria, name='relatorio_sessao_plenaria'), url(r'^relatorios/protocolo$', relatorio_protocolo, name='relatorio_protocolo'), url(r'^relatorios/(?P\d+)/(?P\d+)/etiqueta-protocolo$',