diff --git a/requirements/requirements.txt b/requirements/requirements.txt index c6e9f2266..36ed3844b 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -28,3 +28,4 @@ rtyaml==0.0.3 unipath==1.1 python-magic==0.4.12 gunicorn==19.6.0 +django-reversion==2.0.8 diff --git a/sapl/base/admin.py b/sapl/base/admin.py index 02ccd3c60..941faf8d1 100644 --- a/sapl/base/admin.py +++ b/sapl/base/admin.py @@ -1,5 +1,8 @@ from django.contrib import admin from django.core.urlresolvers import reverse +from django.shortcuts import redirect +from django.utils.translation import ugettext_lazy as _ +from reversion.models import Revision from sapl.base.models import ProblemaMigracao from sapl.utils import register_all_models_in_admin @@ -27,3 +30,15 @@ class ProblemaMigracaoAdmin(admin.ModelAdmin): get_url.short_description = "Endereço" get_url.allow_tags = True + + +class RevisionAdmin(admin.ModelAdmin): + list_display = ('user', 'comment', 'date_created') + search_fields = ('=user__username', '=user__email') + date_hierarchy = ('date_created') + + def change_view(self, request, obj=None): + self.message_user(request, _('You cannot change history.')) + return redirect('admin:reversion_revision_changelist') + +admin.site.register(Revision, RevisionAdmin) diff --git a/sapl/base/models.py b/sapl/base/models.py index 8d87b14cd..e481e4d1d 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -2,6 +2,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models from django.utils.translation import ugettext_lazy as _ +import reversion from sapl.utils import UF, YES_NO_CHOICES, get_settings_auth_user_model @@ -20,6 +21,7 @@ def get_casa_media_path(instance, filename): return get_sessao_media_path(instance, 'Logotipo', filename) +@reversion.register() class CasaLegislativa(models.Model): # TODO ajustar todos os max_length !!!! # cod_casa => id (pk) @@ -59,6 +61,7 @@ class CasaLegislativa(models.Model): 'municipio': self.municipio} +@reversion.register() class ProblemaMigracao(models.Model): content_type = models.ForeignKey(ContentType, verbose_name=_('Tipo de Content')) @@ -76,6 +79,7 @@ class ProblemaMigracao(models.Model): verbose_name_plural = _('Problemas na Migração') +@reversion.register() class AppConfig(models.Model): POLITICA_PROTOCOLO_CHOICES = ( @@ -151,6 +155,7 @@ class AppConfig(models.Model): 'id': self.id} +@reversion.register() class TipoAutor(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -168,6 +173,7 @@ class TipoAutor(models.Model): return self.descricao +@reversion.register() class Autor(models.Model): user = models.OneToOneField(get_settings_auth_user_model(), diff --git a/sapl/comissoes/models.py b/sapl/comissoes/models.py index 441eacba6..3f0a37144 100644 --- a/sapl/comissoes/models.py +++ b/sapl/comissoes/models.py @@ -2,12 +2,14 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.parlamentares.models import Parlamentar from sapl.utils import YES_NO_CHOICES, SaplGenericRelation +@reversion.register() class TipoComissao(models.Model): NATUREZA_CHOICES = Choices(('T', 'temporaria', _('Temporária')), ('P', 'permanente', _('Permanente'))) @@ -28,6 +30,7 @@ class TipoComissao(models.Model): return self.nome +@reversion.register() class Comissao(models.Model): tipo = models.ForeignKey(TipoComissao, verbose_name=_('Tipo')) nome = models.CharField(max_length=60, verbose_name=_('Nome')) @@ -95,6 +98,7 @@ class Comissao(models.Model): return self.sigla + ' - ' + self.nome +@reversion.register() class Periodo(models.Model): # PeriodoCompComissao data_inicio = models.DateField(verbose_name=_('Data Início')) data_fim = models.DateField( @@ -112,6 +116,7 @@ class Periodo(models.Model): # PeriodoCompComissao return '-' +@reversion.register() class CargoComissao(models.Model): nome = models.CharField(max_length=50, verbose_name=_('Cargo')) unico = models.BooleanField( @@ -125,6 +130,7 @@ class CargoComissao(models.Model): return self.nome +@reversion.register() class Composicao(models.Model): # IGNORE comissao = models.ForeignKey(Comissao, verbose_name=_('Comissão')) periodo = models.ForeignKey(Periodo, verbose_name=_('Período')) @@ -137,6 +143,7 @@ class Composicao(models.Model): # IGNORE return '%s: %s' % (self.comissao.sigla, self.periodo) +@reversion.register() class Participacao(models.Model): # ComposicaoComissao composicao = models.ForeignKey(Composicao, related_name='participacao_set') parlamentar = models.ForeignKey(Parlamentar) diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py index 5b022fffa..a633303ee 100644 --- a/sapl/compilacao/models.py +++ b/sapl/compilacao/models.py @@ -11,12 +11,14 @@ from django.http.response import Http404 from django.template import defaultfilters from django.utils.decorators import classonlymethod from django.utils.translation import ugettext_lazy as _ +import reversion from sapl.compilacao.utils import (get_integrations_view_names, int_to_letter, int_to_roman) from sapl.utils import YES_NO_CHOICES, get_settings_auth_user_model +@reversion.register() class TimestampedMixin(models.Model): created = models.DateTimeField( verbose_name=_('created'), @@ -28,6 +30,7 @@ class TimestampedMixin(models.Model): abstract = True +@reversion.register() class BaseModel(models.Model): class Meta: @@ -75,6 +78,7 @@ class BaseModel(models.Model): update_fields=update_fields) +@reversion.register() class PerfilEstruturalTextoArticulado(BaseModel): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -100,6 +104,7 @@ class PerfilEstruturalTextoArticulado(BaseModel): return self.nome +@reversion.register() class TipoTextoArticulado(models.Model): sigla = models.CharField(max_length=3, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -161,6 +166,7 @@ PRIVACIDADE_STATUS = ( ) +@reversion.register() class TextoArticulado(TimestampedMixin): data = models.DateField(blank=True, null=True, verbose_name=_('Data')) ementa = models.TextField(verbose_name=_('Ementa')) @@ -492,6 +498,7 @@ class TextoArticulado(TimestampedMixin): update(dpk) +@reversion.register() class TipoNota(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -507,6 +514,7 @@ class TipoNota(models.Model): return '%s: %s' % (self.sigla, self.nome) +@reversion.register() class TipoVide(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -520,6 +528,7 @@ class TipoVide(models.Model): return '%s: %s' % (self.sigla, self.nome) +@reversion.register() class TipoDispositivo(BaseModel): """ - no attributo rotulo_prefixo_texto, caso haja um ';' (ponto e vírgula), e @@ -729,6 +738,7 @@ class TipoDispositivo(BaseModel): return False +@reversion.register() class TipoDispositivoRelationship(BaseModel): pai = models.ForeignKey(TipoDispositivo, related_name='filhos_permitidos') filho_permitido = models.ForeignKey( @@ -761,6 +771,7 @@ class TipoDispositivoRelationship(BaseModel): self.filho_permitido.nome if self.filho_permitido else '') +@reversion.register() class TipoPublicacao(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -774,6 +785,7 @@ class TipoPublicacao(models.Model): return self.nome +@reversion.register() class VeiculoPublicacao(models.Model): sigla = models.CharField( max_length=10, unique=True, verbose_name=_('Sigla')) @@ -787,6 +799,7 @@ class VeiculoPublicacao(models.Model): return '%s: %s' % (self.sigla, self.nome) +@reversion.register() class Publicacao(TimestampedMixin): ta = models.ForeignKey( TextoArticulado, verbose_name=_('Texto Articulado')) @@ -828,6 +841,7 @@ class Publicacao(TimestampedMixin): self.ta) +@reversion.register() class Dispositivo(BaseModel, TimestampedMixin): TEXTO_PADRAO_DISPOSITIVO_REVOGADO = _('(Revogado)') INTERVALO_ORDEM = 1000 @@ -1603,6 +1617,7 @@ class Dispositivo(BaseModel, TimestampedMixin): ordem_bloco_atualizador=count) +@reversion.register() class Vide(TimestampedMixin): texto = models.TextField(verbose_name=_('Texto do Vide')) @@ -1639,6 +1654,7 @@ NOTAS_PUBLICIDADE_CHOICES = ( ) +@reversion.register() class Nota(TimestampedMixin): NPRIV = 1 diff --git a/sapl/context_processors.py b/sapl/context_processors.py index cc7daca57..2386c0338 100644 --- a/sapl/context_processors.py +++ b/sapl/context_processors.py @@ -1,5 +1,3 @@ - - from sapl.base.views import get_casalegislativa diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 7fece5489..626aed4ee 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -1,17 +1,21 @@ import re from datetime import date +from subprocess import call, PIPE import pkg_resources import yaml from django.apps import apps from django.apps.config import AppConfig from django.contrib.auth import get_user_model +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist -from django.db import OperationalError, ProgrammingError, connections, models -from django.db.models import CharField, Max, ProtectedError, TextField +from django.db import connections, models, OperationalError, ProgrammingError +from django.db.models import CharField, TextField, ProtectedError, Max, signals from django.db.models.base import ModelBase from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make +import reversion +from reversion.models import Revision, Version from sapl.base.models import Autor, ProblemaMigracao from sapl.comissoes.models import Comissao, Composicao, Participacao @@ -19,7 +23,9 @@ from sapl.legacy.models import Protocolo as ProtocoloLegado from sapl.materia.models import (Proposicao, StatusTramitacao, TipoDocumento, TipoMateriaLegislativa, TipoProposicao, Tramitacao) -from sapl.norma.models import AssuntoNorma, NormaJuridica +from sapl.legacy.models import Protocolo as ProtocoloLegado +from sapl.norma.models import (AssuntoNorma, NormaJuridica, + TipoVinculoNormaJuridica) from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo from sapl.sessao.models import ExpedienteMateria, OrdemDia, SessaoPlenaria @@ -122,24 +128,42 @@ def get_fk_related(field, value, label=None): pk = 1 if hasattr(field.related_model.objects.last(), 'pk'): pk = field.related_model.objects.last().pk - value = mommy.make( - field.related_model, **fields_dict, - pk=(pk + 1 or 1)) - descricao = 'stub criado para campos não nuláveis!' - save_relation(value, [field.name], msg, descricao, - eh_stub=True) - warn(msg + ' => ' + descricao) + with reversion.create_revision(): + reversion.set_comment('Stub criado pela migração') + value = mommy.make( + field.related_model, **fields_dict, + pk=(pk + 1 or 1)) + descricao = 'stub criado para campos não nuláveis!' + save_relation(value, [field.name], msg, descricao, + eh_stub=True) + warn(msg + ' => ' + descricao) else: value = None else: if field.model._meta.label == 'sessao.RegistroVotacao' and \ field.name == 'ordem': return value - value = make_stub(field.related_model, value) - descricao = 'stub criado para entrada orfã!' - warn(msg + ' => ' + descricao) - save_relation(value, [field.name], msg, descricao, - eh_stub=True) + # Caso TipoProposicao não exista, um objeto será criado então + # com content_type=13 (ProblemaMigracao) + if field.related_model.__name__ == 'TipoProposicao': + tipo = TipoProposicao.objects.filter(descricao='Erro') + if not tipo: + with reversion.create_revision(): + reversion.set_comment( + 'TipoProposicao "Erro" criado') + ct = ContentType.objects.get(pk=13) + value = TipoProposicao.objects.create( + id=value, descricao='Erro', content_type=ct) + else: + value = tipo[0] + else: + with reversion.create_revision(): + reversion.set_comment('Stub criado pela migração') + value = make_stub(field.related_model, value) + descricao = 'stub criado para entrada orfã!' + warn(msg + ' => ' + descricao) + save_relation(value, [field.name], msg, descricao, + eh_stub=True) else: assert value return value @@ -279,6 +303,25 @@ def get_fields_dict(model): return fields_dict +def fill_vinculo_norma_juridica(): + lista = [('A', 'Altera a norma'), + ('R', 'Revoga integralmente a norma'), + ('P', 'Revoga parcialmente a norma'), + ('T', 'Revoga integralmente por consolidação'), + ('C', 'Norma Correlata'), + ('S', 'Ressalva a Norma'), + ('E', 'Reedita a Norma'), + ('I', 'Reedita a Norma com Alteração'), + ('G', 'Regulamenta a Norma'), + ('K', 'Suspende parcialmente a norma'), + ('L', 'Suspende integralmente a norma'), + ('N', 'Julgada integralmente inconstitucional'), + ('O', 'Julgada parcialmente inconstitucional')] + lista_objs = [VinculoNormaJuridica(sigla=item[0], descricao=item[1]) + for item in lista] + VinculoNormaJuridica.objects.bulk_create(lista_objs) + + class DataMigrator: def __init__(self): @@ -308,11 +351,11 @@ class DataMigrator: value = getattr(old, old_field_name) if field_type == 'DateField' and \ not field.null and value is None: - descricao = 'A data 0001-01-01 foi colocada no lugar' + descricao = 'A data 1111-11-11 foi colocada no lugar' problema = 'O valor da data era nulo ou inválido' warn(msg + ' => ' + descricao) - value = '0001-01-01' + value = date(1111, 11, 11) self.data_mudada['obj'] = new self.data_mudada['descricao'] = descricao self.data_mudada['problema'] = problema @@ -334,11 +377,13 @@ class DataMigrator: '(em %s %s)' % ( field.name, value, field.model.__name__, label or '---') - value = make_stub(field.related_model, value) - descricao = 'stub criado para entrada orfã!' - warn(msg + ' => ' + descricao) - save_relation(value, [field.name], msg, descricao, - eh_stub=True) + with reversion.create_revision(): + value = make_stub(field.related_model, value) + descricao = 'stub criado para entrada orfã!' + warn(msg + ' => ' + descricao) + save_relation(value, [field.name], msg, descricao, + eh_stub=True) + reversion.set_comment('Stub criado pela migração') setattr(new, field.name, value) elif field.model.__name__ == 'TipoAutor' and \ field.name == 'content_type': @@ -352,10 +397,22 @@ class DataMigrator: def migrate(self, obj=appconfs): # warning: model/app migration order is of utmost importance - self.to_delete = [] - ProblemaMigracao.objects.all().delete() exec_sql_file('sapl/legacy/scripts/fix_tables.sql', 'legacy') - get_user_model().objects.exclude(is_superuser=True).delete() + self.to_delete = [] + + # excluindo database antigo. + info('Todos os dados do banco serão excluidos. ' + 'Recomendamos que faça backup do banco sapl antes de continuar.') + info('Deseja continuar? [s/n]') + resposta = input() + if resposta.lower() in ['s', 'sim', 'y', 'yes']: + pass + else: + info('Migração cancelada.') + return 0 + info('Excluindo entradas antigas do banco.') + call(['./manage.py', 'flush', '--settings=sapl.settings', + '--database=default', '--no-input'], stdout=PIPE) info('Começando migração: %s...' % obj) self._do_migrate(obj) @@ -420,13 +477,16 @@ class DataMigrator: if legacy_pk_name == 'id': # There is no pk in the legacy table def save(new, old): - new.save() - + with reversion.create_revision(): + new.save() + reversion.set_comment('Objeto criado pela migração') old_records = iter_sql_records( 'select * from ' + legacy_model._meta.db_table, 'legacy') else: def save(new, old): - save_with_id(new, getattr(old, legacy_pk_name)) + with reversion.create_revision(): + save_with_id(new, getattr(old, legacy_pk_name)) + reversion.set_comment('Objeto criado pela migração') old_records = legacy_model.objects.all().order_by(legacy_pk_name) @@ -443,8 +503,10 @@ class DataMigrator: if ajuste_depois_salvar: ajuste_depois_salvar(new, old) if self.data_mudada: - save_relation(**self.data_mudada) - self.data_mudada.clear() + with reversion.create_revision(): + save_relation(**self.data_mudada) + self.data_mudada.clear() + reversion.set_comment('Ajuste de data pela migração') if getattr(old, 'ind_excluido', False): self.to_delete.append(new) @@ -504,7 +566,9 @@ def adjust_participacao(new, old): assert len(already_created) == 1 # we must never have made 2 copies [composicao] = already_created else: - composicao.save() + with reversion.create_revision(): + composicao.save() + reversion.set_comment('Objeto criado pela migração') new.composicao = composicao @@ -570,11 +634,13 @@ def adjust_normajuridica_depois_salvar(new, old): def adjust_protocolo_depois_salvar(new, old): if old.num_protocolo is None: - problema = 'Número do protocolo de PK %s é nulo' % new.pk - descricao = 'Número do protocolo alterado para %s!' % new.numero - warn(problema + ' => ' + descricao) - save_relation(obj=new, problema=problema, - descricao=descricao, eh_stub=False) + with reversion.create_revision(): + problema = 'Número do protocolo de PK %s é nulo' % new.pk + descricao = 'Número do protocolo alterado para %s!' % new.numero + warn(problema + ' => ' + descricao) + save_relation(obj=new, problema=problema, + descricao=descricao, eh_stub=False) + reversion.set_comment('Numero de protocolo teve que ser alterado') def adjust_autor(new, old): @@ -589,7 +655,9 @@ def adjust_autor(new, old): username=old.col_username).exists(): user = get_user_model()( username=old.col_username, password=12345) - user.save() + with reversion.create_revision(): + user.save() + reversion.set_comment('Objeto criado pela migração') new.user = user else: new.user = get_user_model().objects.filter( diff --git a/sapl/lexml/models.py b/sapl/lexml/models.py index b931a5d17..8c30d9ee1 100644 --- a/sapl/lexml/models.py +++ b/sapl/lexml/models.py @@ -1,7 +1,9 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ +import reversion +@reversion.register() class LexmlProvedor(models.Model): # LexmlRegistroProvedor id_provedor = models.PositiveIntegerField(verbose_name=_('Id do provedor')) nome = models.CharField(max_length=255, verbose_name=_('Nome do provedor')) @@ -29,6 +31,7 @@ class LexmlProvedor(models.Model): # LexmlRegistroProvedor return self.nome +@reversion.register() class LexmlPublicador(models.Model): id_publicador = models.PositiveIntegerField( verbose_name=_('Id do publicador')) diff --git a/sapl/materia/migrations/0075_auto_20170123_1548.py b/sapl/materia/migrations/0075_auto_20170123_1548.py new file mode 100644 index 000000000..7a1ca66ea --- /dev/null +++ b/sapl/materia/migrations/0075_auto_20170123_1548.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-01-23 15:48 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0074_auto_20170102_0951'), + ] + + operations = [ + migrations.AlterField( + model_name='materialegislativa', + name='ano', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano'), + ), + migrations.AlterField( + model_name='materialegislativa', + name='ano_origem_externa', + field=models.PositiveSmallIntegerField(blank=True, choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], null=True, verbose_name='Ano'), + ), + migrations.AlterField( + model_name='numeracao', + name='ano_materia', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano'), + ), + migrations.AlterField( + model_name='proposicao', + name='ano', + field=models.PositiveSmallIntegerField(blank=True, choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], default=None, null=True, verbose_name='Ano'), + ), + ] diff --git a/sapl/materia/migrations/0076_merge.py b/sapl/materia/migrations/0076_merge.py new file mode 100644 index 000000000..49ae8f130 --- /dev/null +++ b/sapl/materia/migrations/0076_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-03-03 16:34 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('materia', '0075_auto_20170203_1019'), + ('materia', '0075_auto_20170123_1548'), + ] + + operations = [ + ] diff --git a/sapl/materia/models.py b/sapl/materia/models.py index e18f662d6..c0d5f3383 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -8,6 +8,7 @@ from django.db.models.deletion import PROTECT from django.utils import formats from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.comissoes.models import Comissao @@ -30,6 +31,7 @@ def grupo_autor(): return grupo.id +@reversion.register() class TipoProposicao(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -63,6 +65,7 @@ class TipoProposicao(models.Model): return self.descricao +@reversion.register() class TipoMateriaLegislativa(models.Model): sigla = models.CharField(max_length=5, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição ')) @@ -88,6 +91,7 @@ class TipoMateriaLegislativa(models.Model): return self.descricao +@reversion.register() class RegimeTramitacao(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -99,6 +103,7 @@ class RegimeTramitacao(models.Model): return self.descricao +@reversion.register() class Origem(models.Model): sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) nome = models.CharField(max_length=50, verbose_name=_('Nome')) @@ -115,6 +120,7 @@ TIPO_APRESENTACAO_CHOICES = Choices(('O', 'oral', _('Oral')), ('E', 'escrita', _('Escrita'))) +@reversion.register() class MateriaLegislativa(models.Model): tipo = models.ForeignKey(TipoMateriaLegislativa, verbose_name=_('Tipo')) @@ -228,6 +234,7 @@ class MateriaLegislativa(models.Model): update_fields=update_fields) +@reversion.register() class Autoria(models.Model): autor = models.ForeignKey(Autor, verbose_name=_('Autor')) materia = models.ForeignKey( @@ -245,6 +252,7 @@ class Autoria(models.Model): 'autor': self.autor, 'materia': self.materia} +@reversion.register() class AcompanhamentoMateria(models.Model): usuario = models.CharField(max_length=50) materia = models.ForeignKey(MateriaLegislativa) @@ -264,6 +272,7 @@ class AcompanhamentoMateria(models.Model): 'materia': self.materia, 'hash': self.hash} +@reversion.register() class Anexada(models.Model): materia_principal = models.ForeignKey( MateriaLegislativa, related_name='materia_principal_set') @@ -284,6 +293,7 @@ class Anexada(models.Model): 'materia_anexada': self.materia_anexada} +@reversion.register() class AssuntoMateria(models.Model): assunto = models.CharField(max_length=200) dispositivo = models.CharField(max_length=50) @@ -296,6 +306,7 @@ class AssuntoMateria(models.Model): return self.assunto +@reversion.register() class DespachoInicial(models.Model): # TODO M2M? # TODO Despachos não são necessáriamente comissoes, podem ser outros @@ -313,6 +324,7 @@ class DespachoInicial(models.Model): 'comissao': self.comissao} +@reversion.register() class TipoDocumento(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Tipo Documento')) @@ -332,6 +344,7 @@ class TipoDocumento(models.Model): return self.descricao +@reversion.register() class DocumentoAcessorio(models.Model): materia = models.ForeignKey(MateriaLegislativa) tipo = models.ForeignKey(TipoDocumento, verbose_name=_('Tipo')) @@ -384,6 +397,7 @@ class DocumentoAcessorio(models.Model): update_fields=update_fields) +@reversion.register() class MateriaAssunto(models.Model): # TODO M2M ?? assunto = models.ForeignKey(AssuntoMateria) @@ -398,6 +412,7 @@ class MateriaAssunto(models.Model): 'materia': self.materia, 'assunto': self.assunto} +@reversion.register() class Numeracao(models.Model): materia = models.ForeignKey(MateriaLegislativa) tipo_materia = models.ForeignKey( @@ -423,6 +438,7 @@ class Numeracao(models.Model): 'ano': self.data_materia.year} +@reversion.register() class Orgao(models.Model): nome = models.CharField(max_length=60, verbose_name=_('Nome')) sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) @@ -450,6 +466,7 @@ class Orgao(models.Model): '%(nome)s - %(sigla)s') % {'nome': self.nome, 'sigla': self.sigla} +@reversion.register() class TipoFimRelatoria(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Tipo Fim Relatoria')) @@ -462,6 +479,7 @@ class TipoFimRelatoria(models.Model): return self.descricao +@reversion.register() class Relatoria(models.Model): materia = models.ForeignKey(MateriaLegislativa) parlamentar = models.ForeignKey(Parlamentar, verbose_name=_('Parlamentar')) @@ -488,6 +506,7 @@ class Relatoria(models.Model): 'data': self.data_designacao_relator} +@reversion.register() class Parecer(models.Model): relatoria = models.ForeignKey(Relatoria) materia = models.ForeignKey(MateriaLegislativa) @@ -506,6 +525,7 @@ class Parecer(models.Model): } +@reversion.register() class Proposicao(models.Model): autor = models.ForeignKey(Autor, null=True, blank=True, on_delete=PROTECT) tipo = models.ForeignKey(TipoProposicao, verbose_name=_('Tipo')) @@ -642,6 +662,7 @@ class Proposicao(models.Model): update_fields=update_fields) +@reversion.register() class StatusTramitacao(models.Model): INDICADOR_CHOICES = Choices(('F', 'fim', _('Fim')), ('R', 'retorno', _('Retorno'))) @@ -663,6 +684,7 @@ class StatusTramitacao(models.Model): 'descricao': self.descricao} +@reversion.register() class UnidadeTramitacao(models.Model): comissao = models.ForeignKey( Comissao, blank=True, null=True, verbose_name=_('Comissão')) @@ -701,6 +723,7 @@ class UnidadeTramitacao(models.Model): return _('%(parlamentar)s') % {'parlamentar': self.parlamentar} +@reversion.register() class Tramitacao(models.Model): TURNO_CHOICES = Choices( ('P', 'primeiro', _('Primeiro')), diff --git a/sapl/norma/legacy.yaml b/sapl/norma/legacy.yaml index 89038ef69..17a7f083d 100644 --- a/sapl/norma/legacy.yaml +++ b/sapl/norma/legacy.yaml @@ -42,7 +42,8 @@ LegislacaoCitada: subsecao: des_subsecao titulo: des_titulo -VinculoNormaJuridica: - norma_referente: cod_norma_referente - norma_referida: cod_norma_referida - tipo_vinculo: tip_vinculo +# TODO Descomentar quando a issue #832 for concluida +# TipoVinculoNormaJuridica (VinculoNormaJuridica): +# norma_referente: cod_norma_referente +# norma_referida: cod_norma_referida +# tipo_vinculo: tip_vinculo diff --git a/sapl/norma/migrations/0033_auto_20170123_1548.py b/sapl/norma/migrations/0033_auto_20170123_1548.py new file mode 100644 index 000000000..918c476c9 --- /dev/null +++ b/sapl/norma/migrations/0033_auto_20170123_1548.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-01-23 15:48 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0032_merge'), + ] + + operations = [ + migrations.AlterField( + model_name='normajuridica', + name='ano', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano'), + ), + ] diff --git a/sapl/norma/migrations/0036_merge.py b/sapl/norma/migrations/0036_merge.py new file mode 100644 index 000000000..207c3b3c0 --- /dev/null +++ b/sapl/norma/migrations/0036_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-03-03 16:34 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('norma', '0035_auto_20170222_1438'), + ('norma', '0033_auto_20170123_1548'), + ] + + operations = [ + ] diff --git a/sapl/norma/models.py b/sapl/norma/models.py index 8d5dbce82..86745c8b1 100644 --- a/sapl/norma/models.py +++ b/sapl/norma/models.py @@ -3,12 +3,14 @@ from django.db import models from django.template import defaultfilters from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.compilacao.models import TextoArticulado from sapl.materia.models import MateriaLegislativa from sapl.utils import RANGE_ANOS, YES_NO_CHOICES, texto_upload_path +@reversion.register() class AssuntoNorma(models.Model): assunto = models.CharField(max_length=50, verbose_name=_('Assunto')) descricao = models.CharField( @@ -22,6 +24,7 @@ class AssuntoNorma(models.Model): return self.assunto +@reversion.register() class TipoNormaJuridica(models.Model): # TODO transform into Domain Model and use an FK for the field EQUIVALENTE_LEXML_CHOICES = ((name, name) for name in @@ -56,6 +59,7 @@ class TipoNormaJuridica(models.Model): return self.descricao +@reversion.register() class NormaJuridica(models.Model): ESFERA_FEDERACAO_CHOICES = Choices( ('E', 'estadual', _('Estadual')), @@ -152,6 +156,7 @@ class NormaJuridica(models.Model): update_fields=update_fields) +@reversion.register() class LegislacaoCitada(models.Model): materia = models.ForeignKey(MateriaLegislativa) norma = models.ForeignKey(NormaJuridica) @@ -188,6 +193,7 @@ class LegislacaoCitada(models.Model): return str(self.norma) +@reversion.register() class TipoVinculoNormaJuridica(models.Model): sigla = models.CharField( max_length=1, blank=True, verbose_name=_('Sigla')) @@ -204,6 +210,7 @@ class TipoVinculoNormaJuridica(models.Model): return self.descricao_ativa +@reversion.register() class NormaRelacionada(models.Model): norma_principal = models.ForeignKey( NormaJuridica, diff --git a/sapl/painel/models.py b/sapl/painel/models.py index 222dd3bae..0f3427f3a 100644 --- a/sapl/painel/models.py +++ b/sapl/painel/models.py @@ -1,7 +1,9 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ +import reversion +@reversion.register() class Painel(models.Model): PAINEL_TYPES = ( ('C', 'Completo'), @@ -19,6 +21,7 @@ class Painel(models.Model): return str(self.aberto) + ":" + self.data_painel.strftime("%d/%m/%Y") +@reversion.register() class Cronometro(models.Model): CRONOMETRO_TYPES = ( ('A', _('Aparte')), diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index 67f87673f..28a2e5677 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -4,6 +4,7 @@ from django.contrib.auth.models import User from django.db import models from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.utils import (INDICADOR_AFASTAMENTO, UF, YES_NO_CHOICES, @@ -12,6 +13,7 @@ from sapl.utils import (INDICADOR_AFASTAMENTO, UF, YES_NO_CHOICES, restringe_tipos_de_arquivo_img, texto_upload_path) +@reversion.register() class Legislatura(models.Model): numero = models.PositiveIntegerField(verbose_name=_('Número')) data_inicio = models.DateField(verbose_name=_('Data Início')) @@ -44,6 +46,7 @@ class Legislatura(models.Model): 'current': current} +@reversion.register() class SessaoLegislativa(models.Model): TIPO_SESSAO_CHOICES = Choices( ('O', 'ordinaria', _('Ordinária')), @@ -75,6 +78,7 @@ class SessaoLegislativa(models.Model): 'fim': self.data_fim.year} +@reversion.register() class Coligacao(models.Model): legislatura = models.ForeignKey(Legislatura, verbose_name=_('Legislatura')) nome = models.CharField(max_length=50, verbose_name=_('Nome')) @@ -97,6 +101,7 @@ def logo_upload_path(instance, filename): return get_logo_media_path(instance, 'logo', filename) +@reversion.register() class Partido(models.Model): sigla = models.CharField(max_length=9, verbose_name=_('Sigla')) nome = models.CharField(max_length=50, verbose_name=_('Nome')) @@ -121,6 +126,7 @@ class Partido(models.Model): } +@reversion.register() class ComposicaoColigacao(models.Model): # TODO M2M partido = models.ForeignKey(Partido, @@ -137,6 +143,7 @@ class ComposicaoColigacao(models.Model): } +@reversion.register() class Municipio(models.Model): # Localidade # TODO filter on migration leaving only cities @@ -165,6 +172,7 @@ class Municipio(models.Model): # Localidade } +@reversion.register() class NivelInstrucao(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Nível de Instrução')) @@ -177,6 +185,7 @@ class NivelInstrucao(models.Model): return self.descricao +@reversion.register() class SituacaoMilitar(models.Model): descricao = models.CharField( max_length=50, verbose_name=_('Situação Militar')) @@ -193,6 +202,7 @@ def foto_upload_path(instance, filename): return texto_upload_path(instance, filename, subpath='') +@reversion.register() class Parlamentar(models.Model): FEMININO = 'F' MASCULINO = 'M' @@ -334,6 +344,7 @@ class Parlamentar(models.Model): update_fields=update_fields) +@reversion.register() class TipoDependente(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -345,6 +356,7 @@ class TipoDependente(models.Model): return self.descricao +@reversion.register() class Dependente(models.Model): FEMININO = 'F' MASCULINO = 'M' @@ -375,6 +387,7 @@ class Dependente(models.Model): return self.nome +@reversion.register() class Filiacao(models.Model): data = models.DateField(verbose_name=_('Data Filiação')) parlamentar = models.ForeignKey(Parlamentar) @@ -395,6 +408,7 @@ class Filiacao(models.Model): } +@reversion.register() class TipoAfastamento(models.Model): descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) indicador = models.CharField( @@ -411,6 +425,7 @@ class TipoAfastamento(models.Model): return self.descricao +@reversion.register() class Mandato(models.Model): parlamentar = models.ForeignKey(Parlamentar) tipo_afastamento = models.ForeignKey( @@ -449,6 +464,7 @@ class Mandato(models.Model): f.data_desfiliacao or datetime.max.date())] +@reversion.register() class CargoMesa(models.Model): # TODO M2M ???? descricao = models.CharField( @@ -464,6 +480,7 @@ class CargoMesa(models.Model): return self.descricao +@reversion.register() class ComposicaoMesa(models.Model): # TODO M2M ???? Ternary????? parlamentar = models.ForeignKey(Parlamentar) @@ -480,6 +497,7 @@ class ComposicaoMesa(models.Model): } +@reversion.register() class Frente(models.Model): ''' * Uma frente agrupa vários parlamentares diff --git a/sapl/protocoloadm/migrations/0010_auto_20170123_1548.py b/sapl/protocoloadm/migrations/0010_auto_20170123_1548.py new file mode 100644 index 000000000..05dafb21c --- /dev/null +++ b/sapl/protocoloadm/migrations/0010_auto_20170123_1548.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-01-23 15:48 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0009_auto_20170102_0951'), + ] + + operations = [ + migrations.AlterField( + model_name='documentoadministrativo', + name='ano', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano'), + ), + migrations.AlterField( + model_name='protocolo', + name='ano', + field=models.PositiveSmallIntegerField(choices=[(2017, 2017), (2016, 2016), (2015, 2015), (2014, 2014), (2013, 2013), (2012, 2012), (2011, 2011), (2010, 2010), (2009, 2009), (2008, 2008), (2007, 2007), (2006, 2006), (2005, 2005), (2004, 2004), (2003, 2003), (2002, 2002), (2001, 2001), (2000, 2000), (1999, 1999), (1998, 1998), (1997, 1997), (1996, 1996), (1995, 1995), (1994, 1994), (1993, 1993), (1992, 1992), (1991, 1991), (1990, 1990), (1989, 1989), (1988, 1988), (1987, 1987), (1986, 1986), (1985, 1985), (1984, 1984), (1983, 1983), (1982, 1982), (1981, 1981), (1980, 1980), (1979, 1979), (1978, 1978), (1977, 1977), (1976, 1976), (1975, 1975), (1974, 1974), (1973, 1973), (1972, 1972), (1971, 1971), (1970, 1970), (1969, 1969), (1968, 1968), (1967, 1967), (1966, 1966), (1965, 1965), (1964, 1964), (1963, 1963), (1962, 1962), (1961, 1961), (1960, 1960), (1959, 1959), (1958, 1958), (1957, 1957), (1956, 1956), (1955, 1955), (1954, 1954), (1953, 1953), (1952, 1952), (1951, 1951), (1950, 1950), (1949, 1949), (1948, 1948), (1947, 1947), (1946, 1946), (1945, 1945), (1944, 1944), (1943, 1943), (1942, 1942), (1941, 1941), (1940, 1940), (1939, 1939), (1938, 1938), (1937, 1937), (1936, 1936), (1935, 1935), (1934, 1934), (1933, 1933), (1932, 1932), (1931, 1931), (1930, 1930), (1929, 1929), (1928, 1928), (1927, 1927), (1926, 1926), (1925, 1925), (1924, 1924), (1923, 1923), (1922, 1922), (1921, 1921), (1920, 1920), (1919, 1919), (1918, 1918), (1917, 1917), (1916, 1916), (1915, 1915), (1914, 1914), (1913, 1913), (1912, 1912), (1911, 1911), (1910, 1910), (1909, 1909), (1908, 1908), (1907, 1907), (1906, 1906), (1905, 1905), (1904, 1904), (1903, 1903), (1902, 1902), (1901, 1901), (1900, 1900), (1899, 1899), (1898, 1898), (1897, 1897), (1896, 1896), (1895, 1895), (1894, 1894), (1893, 1893), (1892, 1892), (1891, 1891), (1890, 1890)], verbose_name='Ano do Protocolo'), + ), + ] diff --git a/sapl/protocoloadm/migrations/0011_merge.py b/sapl/protocoloadm/migrations/0011_merge.py new file mode 100644 index 000000000..10ea183c3 --- /dev/null +++ b/sapl/protocoloadm/migrations/0011_merge.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-03-03 16:34 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('protocoloadm', '0010_auto_20170203_1019'), + ('protocoloadm', '0010_auto_20170123_1548'), + ] + + operations = [ + ] diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py index 5ae92f498..25bee0665 100644 --- a/sapl/protocoloadm/models.py +++ b/sapl/protocoloadm/models.py @@ -1,12 +1,14 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.materia.models import TipoMateriaLegislativa, UnidadeTramitacao from sapl.utils import RANGE_ANOS, YES_NO_CHOICES, texto_upload_path +@reversion.register() class TipoDocumentoAdministrativo(models.Model): sigla = models.CharField(max_length=5, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -45,6 +47,7 @@ def texto_upload_path(instance, filename): """ +@reversion.register() class DocumentoAdministrativo(models.Model): tipo = models.ForeignKey( TipoDocumentoAdministrativo, verbose_name=_('Tipo Documento')) @@ -107,6 +110,7 @@ class DocumentoAdministrativo(models.Model): update_fields=update_fields) +@reversion.register() class DocumentoAcessorioAdministrativo(models.Model): documento = models.ForeignKey(DocumentoAdministrativo) tipo = models.ForeignKey( @@ -156,6 +160,7 @@ class DocumentoAcessorioAdministrativo(models.Model): update_fields=update_fields) +@reversion.register() class Protocolo(models.Model): numero = models.PositiveIntegerField( blank=False, null=False, verbose_name=_('Número de Protocolo')) @@ -203,6 +208,7 @@ class Protocolo(models.Model): ) +@reversion.register() class StatusTramitacaoAdministrativo(models.Model): INDICADOR_CHOICES = Choices( ('F', 'fim', _('Fim')), @@ -225,6 +231,7 @@ class StatusTramitacaoAdministrativo(models.Model): return self.descricao +@reversion.register() class TramitacaoAdministrativo(models.Model): status = models.ForeignKey( StatusTramitacaoAdministrativo, diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py index b6982b587..e9bf2c50e 100644 --- a/sapl/rules/apps.py +++ b/sapl/rules/apps.py @@ -10,6 +10,8 @@ from django.db import models, router from django.db.utils import DEFAULT_DB_ALIAS from django.utils.translation import ugettext_lazy as _ from django.utils.translation import string_concat +import django +import reversion from sapl.rules import (SAPL_GROUP_ADMINISTRATIVO, SAPL_GROUP_COMISSOES, SAPL_GROUP_GERAL, SAPL_GROUP_MATERIA, SAPL_GROUP_NORMA, @@ -226,6 +228,12 @@ def update_groups(app_config, verbosity=2, interactive=True, rules.update_groups() +def revision_pre_delete_signal(sender, **kwargs): + with reversion.create_revision(): + kwargs['instance'].save() + reversion.set_comment("Deletado pelo sinal.") + + models.signals.post_migrate.connect( receiver=update_groups) @@ -233,3 +241,7 @@ models.signals.post_migrate.connect( models.signals.post_migrate.connect( receiver=create_proxy_permissions, dispatch_uid="django.contrib.auth.management.create_permissions") + +models.signals.pre_delete.connect( + receiver=revision_pre_delete_signal, + dispatch_uid="pre_delete_signal") diff --git a/sapl/sessao/models.py b/sapl/sessao/models.py index 0a414a1cc..572a1cad2 100644 --- a/sapl/sessao/models.py +++ b/sapl/sessao/models.py @@ -2,6 +2,7 @@ from django.contrib.auth.models import User from django.db import models from django.utils.translation import ugettext_lazy as _ from model_utils import Choices +import reversion from sapl.base.models import Autor from sapl.materia.models import MateriaLegislativa @@ -12,6 +13,7 @@ from sapl.utils import (YES_NO_CHOICES, SaplGenericRelation, restringe_tipos_de_arquivo_txt, texto_upload_path) +@reversion.register() class CargoBancada(models.Model): nome_cargo = models.CharField(max_length=80, verbose_name=_('Cargo de Bancada')) @@ -28,6 +30,7 @@ class CargoBancada(models.Model): return self.nome_cargo +@reversion.register() class Bancada(models.Model): legislatura = models.ForeignKey(Legislatura, verbose_name=_('Legislatura')) nome = models.CharField( @@ -60,6 +63,7 @@ class Bancada(models.Model): return self.nome +@reversion.register() class TipoSessaoPlenaria(models.Model): nome = models.CharField(max_length=30, verbose_name=_('Tipo')) quorum_minimo = models.PositiveIntegerField( @@ -92,6 +96,7 @@ def anexo_upload_path(instance, filename): # return get_sessao_media_path(instance, 'anexo', filename) +@reversion.register() class SessaoPlenaria(models.Model): # TODO trash??? Seems to have been a FK in the past. Would be: # andamento_sessao = models.ForeignKey( @@ -173,8 +178,8 @@ class SessaoPlenaria(models.Model): def save(self, force_insert=False, force_update=False, using=None, update_fields=None): - if not self.pk and (self.upload_pauta or - self.upload_ata or self.upload_anexo): + if not self.pk and (self.upload_pauta or self.upload_ata or + self.upload_anexo): upload_pauta = self.upload_pauta upload_ata = self.upload_ata upload_anexo = self.upload_anexo @@ -196,6 +201,7 @@ class SessaoPlenaria(models.Model): update_fields=update_fields) +@reversion.register() class AbstractOrdemDia(models.Model): TIPO_VOTACAO_CHOICES = Choices( (1, 'simbolica', (('Simbólica'))), @@ -225,6 +231,7 @@ class AbstractOrdemDia(models.Model): return '%s - %s' % (self.numero_ordem, self.sessao_plenaria) +@reversion.register() class ExpedienteMateria(AbstractOrdemDia): class Meta: @@ -233,6 +240,7 @@ class ExpedienteMateria(AbstractOrdemDia): ordering = ['numero_ordem'] +@reversion.register() class TipoExpediente(models.Model): nome = models.CharField(max_length=100, verbose_name=_('Tipo')) @@ -244,6 +252,7 @@ class TipoExpediente(models.Model): return self.nome +@reversion.register() class ExpedienteSessao(models.Model): # ExpedienteSessaoPlenaria sessao_plenaria = models.ForeignKey(SessaoPlenaria) tipo = models.ForeignKey(TipoExpediente) @@ -258,6 +267,7 @@ class ExpedienteSessao(models.Model): # ExpedienteSessaoPlenaria return '%s - %s' % (self.tipo, self.sessao_plenaria) +@reversion.register() class IntegranteMesa(models.Model): # MesaSessaoPlenaria sessao_plenaria = models.ForeignKey(SessaoPlenaria) cargo = models.ForeignKey(CargoMesa) @@ -271,6 +281,7 @@ class IntegranteMesa(models.Model): # MesaSessaoPlenaria return '%s - %s' % (self.cargo, self.parlamentar) +@reversion.register() class AbstractOrador(models.Model): # Oradores sessao_plenaria = models.ForeignKey(SessaoPlenaria) parlamentar = models.ForeignKey(Parlamentar, verbose_name=_('Parlamentar')) @@ -290,6 +301,7 @@ class AbstractOrador(models.Model): # Oradores 'numero': self.numero_ordem} +@reversion.register() class Orador(AbstractOrador): # Oradores class Meta: @@ -297,6 +309,7 @@ class Orador(AbstractOrador): # Oradores verbose_name_plural = _('Oradores das Explicações Pessoais') +@reversion.register() class OradorExpediente(AbstractOrador): # OradoresExpediente class Meta: @@ -304,6 +317,7 @@ class OradorExpediente(AbstractOrador): # OradoresExpediente verbose_name_plural = _('Oradores do Expediente') +@reversion.register() class OrdemDia(AbstractOrdemDia): class Meta: @@ -312,6 +326,7 @@ class OrdemDia(AbstractOrdemDia): ordering = ['numero_ordem'] +@reversion.register() class PresencaOrdemDia(models.Model): # OrdemDiaPresenca sessao_plenaria = models.ForeignKey(SessaoPlenaria) parlamentar = models.ForeignKey(Parlamentar) @@ -328,6 +343,7 @@ class PresencaOrdemDia(models.Model): # OrdemDiaPresenca 'parlamentar': self.parlamentar} +@reversion.register() class TipoResultadoVotacao(models.Model): nome = models.CharField(max_length=100, verbose_name=_('Tipo')) @@ -339,6 +355,7 @@ class TipoResultadoVotacao(models.Model): return self.nome +@reversion.register() class RegistroVotacao(models.Model): tipo_resultado_votacao = models.ForeignKey( TipoResultadoVotacao, verbose_name=_('Resultado da Votação')) @@ -364,6 +381,7 @@ class RegistroVotacao(models.Model): 'materia': self.materia} +@reversion.register() class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar votacao = models.ForeignKey(RegistroVotacao) parlamentar = models.ForeignKey(Parlamentar) @@ -379,6 +397,7 @@ class VotoParlamentar(models.Model): # RegistroVotacaoParlamentar 'votacao': self.votacao, 'parlamentar': self.parlamentar} +@reversion.register() class VotoNominal(models.Model): parlamentar = models.ForeignKey(Parlamentar) voto = models.CharField(verbose_name=_('Voto'), max_length=10) @@ -399,6 +418,7 @@ class VotoNominal(models.Model): return '%s - %s' % (self.parlamentar.nome_parlamentar, self.voto) +@reversion.register() class SessaoPlenariaPresenca(models.Model): sessao_plenaria = models.ForeignKey(SessaoPlenaria) parlamentar = models.ForeignKey(Parlamentar) @@ -410,6 +430,7 @@ class SessaoPlenariaPresenca(models.Model): ordering = ['parlamentar__nome_parlamentar'] +@reversion.register() class Bloco(models.Model): ''' * blocos podem existir por mais de uma legislatura diff --git a/sapl/settings.py b/sapl/settings.py index 918b4d2b2..37646e675 100644 --- a/sapl/settings.py +++ b/sapl/settings.py @@ -78,7 +78,7 @@ INSTALLED_APPS = ( 'floppyforms', 'sass_processor', 'rest_framework', - + 'reversion', ) + SAPL_APPS @@ -86,6 +86,7 @@ if DEBUG: INSTALLED_APPS += ('debug_toolbar', 'rest_framework_docs',) MIDDLEWARE_CLASSES = ( + 'reversion.middleware.RevisionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', diff --git a/sapl/utils.py b/sapl/utils.py index 1ff86f0fd..9afe021a8 100644 --- a/sapl/utils.py +++ b/sapl/utils.py @@ -19,6 +19,9 @@ from django.core.exceptions import ValidationError from django.utils.text import slugify from django.utils.translation import ugettext_lazy as _ from floppyforms import ClearableFileInput +from reversion.admin import VersionAdmin +import django_filters +import magic from sapl.crispy_layout_mixin import SaplFormLayout, form_actions, to_row from sapl.settings import BASE_DIR @@ -196,7 +199,7 @@ def register_all_models_in_admin(module_name): appname = appname[1] if appname[0] == 'sapl' else appname[0] app = apps.get_app_config(appname) for model in app.get_models(): - class CustomModelAdmin(admin.ModelAdmin): + class CustomModelAdmin(VersionAdmin): list_display = [f.name for f in model._meta.fields if f.name != 'id']