diff --git a/conftest.py b/conftest.py index 62064338e..efd1af9c1 100644 --- a/conftest.py +++ b/conftest.py @@ -3,18 +3,17 @@ from django_webtest import DjangoTestApp, WebTestMixin class OurTestApp(DjangoTestApp): - def __init__(self, *args, **kwargs): - self.default_user = kwargs.pop('default_user', None) + self.default_user = kwargs.pop("default_user", None) super(OurTestApp, self).__init__(*args, **kwargs) def get(self, *args, **kwargs): - kwargs.setdefault('user', self.default_user) - kwargs.setdefault('auto_follow', True) + kwargs.setdefault("user", self.default_user) + kwargs.setdefault("auto_follow", True) return super(OurTestApp, self).get(*args, **kwargs) -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def app(request, admin_user): """WebTest's TestApp. diff --git a/docker/startup_scripts/create_admin.py b/docker/startup_scripts/create_admin.py index cc0e75bd4..eccff073c 100755 --- a/docker/startup_scripts/create_admin.py +++ b/docker/startup_scripts/create_admin.py @@ -8,24 +8,27 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sapl.settings") def get_enviroment_admin_password(username): - password = os.environ.get('ADMIN_PASSWORD') + password = os.environ.get("ADMIN_PASSWORD") if not password: print( "[SUPERUSER] Environment variable $ADMIN_PASSWORD" - " for user %s was not set. Leaving..." % username) - sys.exit('MISSING_ADMIN_PASSWORD') + " for user %s was not set. Leaving..." % username + ) + sys.exit("MISSING_ADMIN_PASSWORD") return password def create_user_interlegis(): from django.contrib.auth.models import User - password = get_enviroment_admin_password('interlegis') + password = get_enviroment_admin_password("interlegis") print("[SUPERUSER INTERLEGIS] Creating interlegis superuser...") - user, created = User.objects.get_or_create(username='interlegis') + user, created = User.objects.get_or_create(username="interlegis") if not created: - print("[SUPERUSER INTERLEGIS] User interlegis already exists." - " Updating password.") + print( + "[SUPERUSER INTERLEGIS] User interlegis already exists." + " Updating password." + ) user.is_superuser = True user.is_staff = True user.set_password(password) @@ -37,19 +40,21 @@ def create_superuser(): from django.contrib.auth.models import User username = "admin" - email = os.environ.get('ADMIN_EMAIL', '') + email = os.environ.get("ADMIN_EMAIL", "") if User.objects.filter(username=username).exists(): - print("[SUPERUSER] User %s already exists." - " Exiting without change." % username) - sys.exit('ADMIN_USER_EXISTS') + print( + "[SUPERUSER] User %s already exists." " Exiting without change." % username + ) + sys.exit("ADMIN_USER_EXISTS") else: password = get_enviroment_admin_password(username) print("[SUPERUSER] Creating superuser...") u = User.objects.create_superuser( - username=username, password=password, email=email) + username=username, password=password, email=email + ) u.save() print("[SUPERUSER] Done.") @@ -57,7 +62,7 @@ def create_superuser(): sys.exit(0) -if __name__ == '__main__': +if __name__ == "__main__": django.setup() create_user_interlegis() # must come before create_superuser create_superuser() diff --git a/docker/startup_scripts/genkey.py b/docker/startup_scripts/genkey.py index 4bf92f1ac..4bf39ebca 100644 --- a/docker/startup_scripts/genkey.py +++ b/docker/startup_scripts/genkey.py @@ -2,10 +2,15 @@ import random def generate_secret(): - return (''.join([random.SystemRandom().choice( - 'abcdefghijklmnopqrst' - 'uvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)])) + return "".join( + [ + random.SystemRandom().choice( + "abcdefghijklmnopqrst" "uvwxyz0123456789!@#$%^&*(-_=+)" + ) + for i in range(50) + ] + ) -if __name__ == '__main__': +if __name__ == "__main__": print(generate_secret()) diff --git a/docker/startup_scripts/gunicorn.conf.py b/docker/startup_scripts/gunicorn.conf.py index 2272eb15e..589846521 100644 --- a/docker/startup_scripts/gunicorn.conf.py +++ b/docker/startup_scripts/gunicorn.conf.py @@ -35,9 +35,9 @@ wsgi_app = WSGI_APP # Logs loglevel = "debug" -errorlog = "-" # send to stderr (so you see it in docker logs or terminal) -accesslog = "-" # send to stdout -capture_output = True # capture print/tracebacks from app +errorlog = "-" # send to stderr (so you see it in docker logs or terminal) +accesslog = "-" # send to stdout +capture_output = True # capture print/tracebacks from app # accesslog = "/var/log/sapl/access.log" # errorlog = "/var/log/sapl/error.log" @@ -68,6 +68,7 @@ def on_starting(server): def post_fork(server, worker): try: from django import db + db.connections.close_all() except Exception: # Django not initialized yet or not available diff --git a/docker/startup_scripts/solr_cli.py b/docker/startup_scripts/solr_cli.py index e7600914a..b42704c42 100755 --- a/docker/startup_scripts/solr_cli.py +++ b/docker/startup_scripts/solr_cli.py @@ -40,16 +40,16 @@ SECURITY_FILE_TEMPLATE = """ } """ -URL_PATTERN = 'https?://(([a-zA-Z0-9]+):([a-zA-Z0-9]+)@)?([a-zA-Z0-9.-]+)(:[0-9]{4})?' +URL_PATTERN = "https?://(([a-zA-Z0-9]+):([a-zA-Z0-9]+)@)?([a-zA-Z0-9.-]+)(:[0-9]{4})?" def solr_hash_password(password: str, salt: str = None): """ - Generates a password and salt to be used in Basic Auth Solr + Generates a password and salt to be used in Basic Auth Solr - password: clean text password string - salt (optional): base64 salt string - returns: sha256 hash of password and salt (both base64 strings) + password: clean text password string + salt (optional): base64 salt string + returns: sha256 hash of password and salt (both base64 strings) """ logger.debug("Generating Solr password") m = sha256() @@ -57,15 +57,15 @@ def solr_hash_password(password: str, salt: str = None): salt = secrets.token_bytes(32) else: salt = b64decode(salt) - m.update(salt + password.encode('utf-8')) + m.update(salt + password.encode("utf-8")) digest = m.digest() m = sha256() m.update(digest) digest = m.digest() - cypher = b64encode(digest).decode('utf-8') - salt = b64encode(salt).decode('utf-8') + cypher = b64encode(digest).decode("utf-8") + salt = b64encode(salt).decode("utf-8") return cypher, salt @@ -81,18 +81,18 @@ def upload_security_file(zk_host): zk_port = 9983 # embedded ZK port logger.info(f"Uploading security file to Solr, ZK server={zk_host}:{zk_port}...") try: - with open('security.json', 'r') as f: + with open("security.json", "r") as f: data = f.read() zk = KazooClient(hosts=f"{zk_host}:{zk_port}") zk.start() logger.info("Uploading security.json file...") - if zk.exists('/security.json'): + if zk.exists("/security.json"): zk.set("/security.json", str.encode(data)) else: zk.create("/security.json", str.encode(data)) - data, stat = zk.get('/security.json') + data, stat = zk.get("/security.json") logger.info("file uploaded!") - logger.info(data.decode('utf-8')) + logger.info(data.decode("utf-8")) zk.stop() except Exception as e: logger.error(e) @@ -103,14 +103,17 @@ class SolrClient: LIST_CONFIGSETS = "{}/solr/admin/configs?action=LIST&omitHeader=true&wt=json" UPLOAD_CONFIGSET = "{}/solr/admin/configs?action=UPLOAD&name={}&wt=json" LIST_COLLECTIONS = "{}/solr/admin/collections?action=LIST&wt=json" - STATUS_COLLECTION = "{}/solr/admin/collections?action=CLUSTERSTATUS" \ - "&collection={}&wt=json" + STATUS_COLLECTION = ( + "{}/solr/admin/collections?action=CLUSTERSTATUS" "&collection={}&wt=json" + ) STATUS_CORE = "{}/admin/cores?action=STATUS&name={}" EXISTS_COLLECTION = "{}/solr/{}/admin/ping?wt=json" OPTIMIZE_COLLECTION = "{}/solr/{}/update?optimize=true&wt=json" - CREATE_COLLECTION = "{}/solr/admin/collections?action=CREATE&name={}" \ - "&collection.configName={}&numShards={}" \ - "&replicationFactor={}&maxShardsPerNode={}&wt=json" + CREATE_COLLECTION = ( + "{}/solr/admin/collections?action=CREATE&name={}" + "&collection.configName={}&numShards={}" + "&replicationFactor={}&maxShardsPerNode={}&wt=json" + ) DELETE_COLLECTION = "{}/solr/admin/collections?action=DELETE&name={}&wt=json" DELETE_DATA = "{}/solr/{}/update?commitWithin=1000&overwrite=true&wt=json" QUERY_DATA = "{}/solr/{}/select?q=*:*" @@ -130,7 +133,7 @@ class SolrClient: dic = res.json() return dic["response"]["numFound"] except Exception as e: - print(F"Erro no get_num_docs. Erro: {e}") + print(f"Erro no get_num_docs. Erro: {e}") print(res.content) return 0 @@ -140,9 +143,9 @@ class SolrClient: res = requests.get(req_url) try: dic = res.json() - return dic['collections'] + return dic["collections"] except Exception as e: - print(F"Erro no list_collections. Erro: {e}") + print(f"Erro no list_collections. Erro: {e}") print(res.content) return 0 @@ -156,8 +159,8 @@ class SolrClient: # zip files in memory _zipfile = BytesIO() - with zipfile.ZipFile(_zipfile, 'w', zipfile.ZIP_DEFLATED) as zipf: - for file in base_path.rglob('*'): + with zipfile.ZipFile(_zipfile, "w", zipfile.ZIP_DEFLATED) as zipf: + for file in base_path.rglob("*"): zipf.write(file, file.relative_to(base_path)) return _zipfile except Exception as e: @@ -169,23 +172,26 @@ class SolrClient: res = requests.get(req_url) try: dic = res.json() - configsets = dic['configSets'] + configsets = dic["configSets"] except Exception as e: - print(F"Erro ao configurar configsets. Erro: {e}") + print(f"Erro ao configurar configsets. Erro: {e}") print(res.content) # UPLOAD configset if not self.CONFIGSET_NAME in configsets or force: - # GENERATE in memory configset configset_zip = self.zip_configset() data = configset_zip.getvalue() configset_zip.close() - files = {'file': ('saplconfigset.zip', - data, - 'application/octet-stream', - {'Expires': '0'})} + files = { + "file": ( + "saplconfigset.zip", + data, + "application/octet-stream", + {"Expires": "0"}, + ) + } req_url = self.UPLOAD_CONFIGSET.format(self.url, self.CONFIGSET_NAME) @@ -193,16 +199,20 @@ class SolrClient: print(resp.content) else: - print('O %s já presente no servidor, NÃO enviando.' % self.CONFIGSET_NAME) + print("O %s já presente no servidor, NÃO enviando." % self.CONFIGSET_NAME) - def create_collection(self, collection_name, shards=1, replication_factor=1, max_shards_per_node=1): + def create_collection( + self, collection_name, shards=1, replication_factor=1, max_shards_per_node=1 + ): self.maybe_upload_configset() - req_url = self.CREATE_COLLECTION.format(self.url, - collection_name, - self.CONFIGSET_NAME, - shards, - replication_factor, - max_shards_per_node) + req_url = self.CREATE_COLLECTION.format( + self.url, + collection_name, + self.CONFIGSET_NAME, + shards, + replication_factor, + max_shards_per_node, + ) res = requests.post(req_url) if res.ok: print("Collection '%s' created succesfully" % collection_name) @@ -210,15 +220,15 @@ class SolrClient: print("Error creating collection '%s'" % collection_name) try: as_json = res.json() - print("Error %s: %s" % (res.status_code, as_json['error']['msg'])) + print("Error %s: %s" % (res.status_code, as_json["error"]["msg"])) except Exception as e: - print(F"Erro ao verificar erro na resposta. Erro: {e}") + print(f"Erro ao verificar erro na resposta. Erro: {e}") print(res.content) return False return True def delete_collection(self, collection_name): - if collection_name == '*': + if collection_name == "*": collections = self.list_collections() else: collections = [collection_name] @@ -234,9 +244,11 @@ class SolrClient: def delete_index_data(self, collection_name): req_url = self.DELETE_DATA.format(self.url, collection_name) - res = requests.post(req_url, - data='*:*', - headers={'Content-Type': 'application/xml'}) + res = requests.post( + req_url, + data="*:*", + headers={"Content-Type": "application/xml"}, + ) if not res.ok: print("Error deleting index for collection '%s'", collection_name) print("Code {}: {}".format(res.status_code, res.text)) @@ -257,33 +269,67 @@ def setup_embedded_zk(solr_url): create_security_file(solr_user, solr_pwd) upload_security_file(solr_host) else: - print(f"Missing Solr's username, password, and host: {solr_user}/{solr_pwd}/{solr_host}") + print( + f"Missing Solr's username, password, and host: {solr_user}/{solr_pwd}/{solr_host}" + ) sys.exit(-1) else: print(f"Solr URL path doesn't match the required format: {solr_url}") sys.exit(-1) -if __name__ == '__main__': - - parser = argparse.ArgumentParser(description='Cria uma collection no Solr') +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Cria uma collection no Solr") # required arguments - parser.add_argument('-u', type=str, metavar='URL', nargs=1, dest='url', - required=True, help='Endereço do servidor Solr na forma http(s)://
[:port]') - parser.add_argument('-c', type=str, metavar='COLLECTION', dest='collection', nargs=1, - required=True, help='Collection Solr a ser criada') + parser.add_argument( + "-u", + type=str, + metavar="URL", + nargs=1, + dest="url", + required=True, + help="Endereço do servidor Solr na forma http(s)://
[:port]", + ) + parser.add_argument( + "-c", + type=str, + metavar="COLLECTION", + dest="collection", + nargs=1, + required=True, + help="Collection Solr a ser criada", + ) # optional arguments - parser.add_argument('-s', type=int, dest='shards', nargs='?', - help='Number of shards (default=1)', default=1) - parser.add_argument('-rf', type=int, dest='replication_factor', nargs='?', - help='Replication factor (default=1)', default=1) - parser.add_argument('-ms', type=int, dest='max_shards_per_node', nargs='?', - help='Max shards per node (default=1)', default=1) - - parser.add_argument("--embedded_zk", default=False, action="store_true", - help="Embedded ZooKeeper") + parser.add_argument( + "-s", + type=int, + dest="shards", + nargs="?", + help="Number of shards (default=1)", + default=1, + ) + parser.add_argument( + "-rf", + type=int, + dest="replication_factor", + nargs="?", + help="Replication factor (default=1)", + default=1, + ) + parser.add_argument( + "-ms", + type=int, + dest="max_shards_per_node", + nargs="?", + help="Max shards per node (default=1)", + default=1, + ) + + parser.add_argument( + "--embedded_zk", default=False, action="store_true", help="Embedded ZooKeeper" + ) try: args = parser.parse_args() @@ -305,10 +351,12 @@ if __name__ == '__main__': ## Add --clean option to clean uploadconfig and collection if not client.exists_collection(collection): print("Collection '%s' doesn't exists. Creating a new one..." % collection) - created = client.create_collection(collection, - shards=args.shards, - replication_factor=args.replication_factor, - max_shards_per_node=args.max_shards_per_node) + created = client.create_collection( + collection, + shards=args.shards, + replication_factor=args.replication_factor, + max_shards_per_node=args.max_shards_per_node, + ) if not created: sys.exit(-1) else: diff --git a/drfautoapi/drfautoapi.py b/drfautoapi/drfautoapi.py index 9f3a3c502..56275d242 100644 --- a/drfautoapi/drfautoapi.py +++ b/drfautoapi/drfautoapi.py @@ -36,25 +36,22 @@ class SplitStringCharFilter(django_filters.CharFilter): return qs if self.distinct: qs = qs.distinct() - lookup = '%s__%s' % (self.field_name, self.lookup_expr) + lookup = "%s__%s" % (self.field_name, self.lookup_expr) values = [value] - if self.lookup_expr == 'icontains': + if self.lookup_expr == "icontains": if not '"' in value: - values = value.split(' ') + values = value.split(" ") else: values = list( filter( - lambda x: x and x != ' ' and x[0] != '"', - self._re.findall(value) + lambda x: x and x != " " and x[0] != '"', + self._re.findall(value), ) ) + list( map( lambda x: x[1:-1], - filter( - lambda x: x and x[0] == '"', - self._re.findall(value) - ) + filter(lambda x: x and x[0] == '"', self._re.findall(value)), ) ) @@ -66,36 +63,34 @@ class SplitStringCharFilter(django_filters.CharFilter): class ApiFilterSetMixin(FilterSet): - - o = CharFilter(method='filter_o') + o = CharFilter(method="filter_o") class Meta: - fields = '__all__' + fields = "__all__" filter_overrides = { FileField: { - 'filter_class': django_filters.CharFilter, - 'extra': lambda f: { - 'lookup_expr': 'exact', + "filter_class": django_filters.CharFilter, + "extra": lambda f: { + "lookup_expr": "exact", }, }, CharField: { - 'filter_class': SplitStringCharFilter, + "filter_class": SplitStringCharFilter, }, TextField: { - 'filter_class': SplitStringCharFilter, + "filter_class": SplitStringCharFilter, }, JSONField: { - 'filter_class': django_filters.CharFilter, - 'extra': lambda f: { - 'lookup_expr': 'exact', + "filter_class": django_filters.CharFilter, + "extra": lambda f: { + "lookup_expr": "exact", }, }, } def filter_o(self, queryset, name, value): try: - return queryset.order_by( - *map(str.strip, value.split(','))) + return queryset.order_by(*map(str.strip, value.split(","))) except: return queryset @@ -113,29 +108,34 @@ class ApiFilterSetMixin(FilterSet): for f_str in fields_model: if f_str not in fields: - f = model._meta.get_field(f_str) if f.many_to_many: - fields[f_str] = ['exact'] + fields[f_str] = ["exact"] continue - fields[f_str] = ['exact'] + fields[f_str] = ["exact"] def get_keys_lookups(cl, sub_f): r = [] for lk, lv in cl.items(): - - if lk in ('contained_by', 'trigram_similar', 'unaccent', 'search'): + if lk in ( + "contained_by", + "trigram_similar", + "unaccent", + "search", + ): continue sflk = f'{sub_f}{"__" if sub_f else ""}{lk}' r.append(sflk) - if hasattr(lv, 'get_lookups'): + if hasattr(lv, "get_lookups"): r += get_keys_lookups(lv.get_lookups(), sflk) - if hasattr(lv, 'output_field') and hasattr(lv, 'output_field.get_lookups'): + if hasattr(lv, "output_field") and hasattr( + lv, "output_field.get_lookups" + ): r.append(f'{sflk}{"__" if sflk else ""}range') r += get_keys_lookups(lv.output_field.class_lookups, sflk) @@ -143,31 +143,30 @@ class ApiFilterSetMixin(FilterSet): return r fields[f_str] = list( - set(fields[f_str] + get_keys_lookups(f.get_lookups(), ''))) + set(fields[f_str] + get_keys_lookups(f.get_lookups(), "")) + ) # Remove excluded fields exclude = exclude or [] - fields = [(f, lookups) - for f, lookups in fields.items() if f not in exclude] + fields = [(f, lookups) for f, lookups in fields.items() if f not in exclude] return OrderedDict(fields) @classmethod - def filter_for_field(cls, f, name, lookup_expr='exact'): + def filter_for_field(cls, f, name, lookup_expr="exact"): # Redefine método estático para ignorar filtro para # fields que não possuam lookup_expr informado f, lookup_type = resolve_field(f, lookup_expr) default = { - 'field_name': name, - 'label': capfirst(f.verbose_name), - 'lookup_expr': lookup_expr + "field_name": name, + "label": capfirst(f.verbose_name), + "lookup_expr": lookup_expr, } - filter_class, params = cls.filter_for_lookup( - f, lookup_type) + filter_class, params = cls.filter_for_lookup(f, lookup_type) default.update(params) if filter_class is not None: return filter_class(**default) @@ -175,7 +174,7 @@ class ApiFilterSetMixin(FilterSet): class BusinessRulesNotImplementedMixin: - http_method_names = ['get', 'head', 'options', 'trace'] + http_method_names = ["get", "head", "options", "trace"] def create(self, request, *args, **kwargs): raise Exception(_("POST Create não implementado")) @@ -187,8 +186,7 @@ class BusinessRulesNotImplementedMixin: raise Exception(_("DELETE Delete não implementado")) -class ApiViewSetConstrutor(): - +class ApiViewSetConstrutor: _built_sets = {} class ApiViewSet(ModelViewSet): @@ -214,13 +212,14 @@ class ApiViewSetConstrutor(): app_label = getattr(app, "label", app.name.split(".")[-1]) for model, viewset in built_sets.items(): router.register( - f'{app.label}/{model._meta.model_name}', viewset, - basename=f"{app_label}-{model._meta.model_name}") + f"{app.label}/{model._meta.model_name}", + viewset, + basename=f"{app_label}-{model._meta.model_name}", + ) return router @classmethod def build_class(cls, apps_or_models): - DRFAUTOAPI = settings.DRFAUTOAPI serializers_classes = {} @@ -231,35 +230,38 @@ class ApiViewSetConstrutor(): try: if DRFAUTOAPI: - if 'DEFAULT_SERIALIZER_MODULE' in DRFAUTOAPI: + if "DEFAULT_SERIALIZER_MODULE" in DRFAUTOAPI: serializers = importlib.import_module( - DRFAUTOAPI['DEFAULT_SERIALIZER_MODULE'] + DRFAUTOAPI["DEFAULT_SERIALIZER_MODULE"] ) serializers_classes = inspect.getmembers(serializers) - serializers_classes = {i[0]: i[1] for i in filter( - lambda x: x[0].endswith('Serializer'), - serializers_classes - )} + serializers_classes = { + i[0]: i[1] + for i in filter( + lambda x: x[0].endswith("Serializer"), serializers_classes + ) + } - if 'DEFAULT_FILTER_MODULE' in DRFAUTOAPI: + if "DEFAULT_FILTER_MODULE" in DRFAUTOAPI: filters = importlib.import_module( - DRFAUTOAPI['DEFAULT_FILTER_MODULE'] + DRFAUTOAPI["DEFAULT_FILTER_MODULE"] ) filters_classes = inspect.getmembers(filters) - filters_classes = {i[0]: i[1] for i in filter( - lambda x: x[0].endswith('FilterSet'), - filters_classes - )} - - if 'GLOBAL_SERIALIZER_MIXIN' in DRFAUTOAPI: - cs = DRFAUTOAPI['GLOBAL_SERIALIZER_MIXIN'].split('.') - module = importlib.import_module( - '.'.join(cs[0:-1])) + filters_classes = { + i[0]: i[1] + for i in filter( + lambda x: x[0].endswith("FilterSet"), filters_classes + ) + } + + if "GLOBAL_SERIALIZER_MIXIN" in DRFAUTOAPI: + cs = DRFAUTOAPI["GLOBAL_SERIALIZER_MIXIN"].split(".") + module = importlib.import_module(".".join(cs[0:-1])) global_serializer_mixin = getattr(module, cs[-1]) - if 'GLOBAL_FILTERSET_MIXIN' in DRFAUTOAPI: - cs = DRFAUTOAPI['GLOBAL_FILTERSET_MIXIN'].split('.') - m = importlib.import_module('.'.join(cs[0:-1])) + if "GLOBAL_FILTERSET_MIXIN" in DRFAUTOAPI: + cs = DRFAUTOAPI["GLOBAL_FILTERSET_MIXIN"].split(".") + m = importlib.import_module(".".join(cs[0:-1])) global_filter_class = getattr(m, cs[-1]) except Exception as e: @@ -270,45 +272,50 @@ class ApiViewSetConstrutor(): def build(_model): object_name = _model._meta.object_name - serializer_name = f'{object_name}Serializer' + serializer_name = f"{object_name}Serializer" _serializer_class = serializers_classes.get( - serializer_name, global_serializer_mixin) + serializer_name, global_serializer_mixin + ) - filter_name = f'{object_name}FilterSet' - _filterset_class = filters_classes.get( - filter_name, global_filter_class) + filter_name = f"{object_name}FilterSet" + _filterset_class = filters_classes.get(filter_name, global_filter_class) def create_class(): - - _meta_serializer = object if not hasattr( - _serializer_class, 'Meta') else _serializer_class.Meta + _meta_serializer = ( + object + if not hasattr(_serializer_class, "Meta") + else _serializer_class.Meta + ) class ApiSerializer(_serializer_class): - class Meta(_meta_serializer): - if not hasattr(_meta_serializer, 'ref_name'): - ref_name = f'{object_name}Serializer' + if not hasattr(_meta_serializer, "ref_name"): + ref_name = f"{object_name}Serializer" - if not hasattr(_meta_serializer, 'model'): + if not hasattr(_meta_serializer, "model"): model = _model - if hasattr(_meta_serializer, 'exclude'): + if hasattr(_meta_serializer, "exclude"): exclude = _meta_serializer.exclude else: - if not hasattr(_meta_serializer, 'fields'): - fields = '__all__' - elif _meta_serializer.fields != '__all__': + if not hasattr(_meta_serializer, "fields"): + fields = "__all__" + elif _meta_serializer.fields != "__all__": fields = list(_meta_serializer.fields) else: fields = _meta_serializer.fields - _meta_filterset = object if not hasattr( - _filterset_class, 'Meta') else _filterset_class.Meta + _meta_filterset = ( + object + if not hasattr(_filterset_class, "Meta") + else _filterset_class.Meta + ) class ApiFilterSet(_filterset_class): - - class Meta(_meta_filterset, ): - if not hasattr(_meta_filterset, 'model'): + class Meta( + _meta_filterset, + ): + if not hasattr(_meta_filterset, "model"): model = _model class ModelApiViewSet(ApiViewSetConstrutor.ApiViewSet): @@ -319,11 +326,10 @@ class ApiViewSetConstrutor(): return ModelApiViewSet viewset = create_class() - viewset.__name__ = '%sModelViewSet' % _model.__name__ + viewset.__name__ = "%sModelViewSet" % _model.__name__ return viewset for am in apps_or_models: - if isinstance(am, ModelBase): app = am._meta.app_config else: @@ -353,17 +359,16 @@ class ApiViewSetConstrutor(): class wrapper_queryset_response_for_drf_action(object): - def __init__(self, model): self.model = model def __call__(self, cls): - def wrapper(instance_view, *args, **kwargs): # recupera a viewset do model anotado iv = instance_view viewset_from_model = ApiViewSetConstrutor._built_sets[ - self.model._meta.app_config][self.model] + self.model._meta.app_config + ][self.model] # apossa da instancia da viewset mae do action # em uma viewset que processa dados do model passado no decorator @@ -371,41 +376,38 @@ class wrapper_queryset_response_for_drf_action(object): iv.serializer_class = viewset_from_model.serializer_class iv.filterset_class = viewset_from_model.filterset_class - iv.queryset = instance_view.filter_queryset( - iv.get_queryset()) + iv.queryset = instance_view.filter_queryset(iv.get_queryset()) # chama efetivamente o metodo anotado que deve devolver um queryset # com os filtros específicos definido pelo programador customizador qs = cls(instance_view, *args, **kwargs) page = iv.paginate_queryset(qs) - data = iv.get_serializer( - page if page is not None else qs, many=True).data + data = iv.get_serializer(page if page is not None else qs, many=True).data - return iv.get_paginated_response( - data) if page is not None else Response(data) + return ( + iv.get_paginated_response(data) if page is not None else Response(data) + ) return wrapper # decorator para recuperar e transformar o default class customize(object): - def __init__(self, model): self.model = model def __call__(self, cls): - class _ApiViewSet( cls, - ApiViewSetConstrutor._built_sets[ - self.model._meta.app_config][self.model] + ApiViewSetConstrutor._built_sets[self.model._meta.app_config][self.model], ): pass - if hasattr(_ApiViewSet, 'build'): + if hasattr(_ApiViewSet, "build"): _ApiViewSet = _ApiViewSet.build() - ApiViewSetConstrutor._built_sets[ - self.model._meta.app_config][self.model] = _ApiViewSet + ApiViewSetConstrutor._built_sets[self.model._meta.app_config][ + self.model + ] = _ApiViewSet return _ApiViewSet diff --git a/sapl/api/apps.py b/sapl/api/apps.py index eb66f400b..02023a245 100644 --- a/sapl/api/apps.py +++ b/sapl/api/apps.py @@ -3,9 +3,9 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.api' - label = 'api' - verbose_name = _('API Rest') + name = "sapl.api" + label = "api" + verbose_name = _("API Rest") def ready(self): from . import signals diff --git a/sapl/api/deprecated.py b/sapl/api/deprecated.py index d876f66e4..1a2b29f5e 100644 --- a/sapl/api/deprecated.py +++ b/sapl/api/deprecated.py @@ -7,13 +7,11 @@ from sapl.api.serializers import SessaoPlenariaECidadaniaSerializer from sapl.sessao.models import SessaoPlenaria -class SessaoPlenariaViewSet(ListModelMixin, - RetrieveModelMixin, - GenericViewSet): +class SessaoPlenariaViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet): """ Deprecated - Será eliminado na versão 3.2 - * TODO: + * TODO: * eliminar endpoint, transferido para SaplApiViewSetConstrutor * /api/sessao-planaria -> /api/sessao/sessaoplenaria/ecidadania * /api/sessao-planaria/{pk} -> /api/sessao/sessaoplenaria/{pk}/ecidadania @@ -24,4 +22,4 @@ class SessaoPlenariaViewSet(ListModelMixin, serializer_class = SessaoPlenariaECidadaniaSerializer queryset = SessaoPlenaria.objects.all() filter_backends = (DjangoFilterBackend,) - filter_fields = ('data_inicio', 'data_fim', 'interativa') + filter_fields = ("data_inicio", "data_fim", "interativa") diff --git a/sapl/api/forms.py b/sapl/api/forms.py index 995d9d962..3a563c9f5 100644 --- a/sapl/api/forms.py +++ b/sapl/api/forms.py @@ -8,7 +8,7 @@ from django_filters.filterset import FilterSet from rest_framework import serializers from drfautoapi.drfautoapi import ApiFilterSetMixin -from sapl.base.models import TipoAutor, Autor +from sapl.base.models import Autor, TipoAutor from sapl.parlamentares.models import Legislatura from sapl.utils import generic_relations_for_model @@ -20,19 +20,17 @@ class SaplFilterSetMixin(ApiFilterSetMixin): class AutorFilterSet(SaplFilterSetMixin): - q = CharFilter(method='filter_q') + q = CharFilter(method="filter_q") tipo = ModelChoiceFilter(queryset=TipoAutor.objects.all()) def filter_q(self, queryset, name, value): - - query = value.split(' ') + query = value.split(" ") if query: q = Q() for qtext in query: if not qtext: continue - q_fs = Q(nome__icontains=qtext) | Q( - tipo__descricao__icontains=qtext) + q_fs = Q(nome__icontains=qtext) | Q(tipo__descricao__icontains=qtext) order_by = [] @@ -45,17 +43,23 @@ class AutorFilterSet(SaplFilterSetMixin): for field in item.fields_search: if flag_order_by: flag_order_by = False - order_by.append('%s__%s' % ( - item.related_query_name(), - field[0]) + order_by.append( + "%s__%s" % (item.related_query_name(), field[0]) ) # if len(field) == 3 and field[2](qtext) is not # None: - q_fs = q_fs | Q(**{'%s__%s%s' % ( - item.related_query_name(), - field[0], - field[1]): qtext if len(field) == 2 - else field[2](qtext)}) + q_fs = q_fs | Q( + **{ + "%s__%s%s" + % ( + item.related_query_name(), + field[0], + field[1], + ): qtext + if len(field) == 2 + else field[2](qtext) + } + ) q = q & q_fs @@ -66,25 +70,28 @@ class AutorFilterSet(SaplFilterSetMixin): class AutoresPossiveisFilterSet(SaplFilterSetMixin): - data_relativa = DateFilter(method='filter_data_relativa') - tipo = CharFilter(method='filter_tipo') + data_relativa = DateFilter(method="filter_data_relativa") + tipo = CharFilter(method="filter_tipo") class Meta: model = Autor - fields = ['data_relativa', 'tipo', ] + fields = [ + "data_relativa", + "tipo", + ] def filter_data_relativa(self, queryset, name, value): return queryset def filter_tipo(self, queryset, name, value): - try: logger.debug( - "Tentando obter TipoAutor correspondente à pk {}.".format(value)) + "Tentando obter TipoAutor correspondente à pk {}.".format(value) + ) tipo = TipoAutor.objects.get(pk=value) except: logger.error("TipoAutor(pk={}) inexistente.".format(value)) - raise serializers.ValidationError(_('Tipo de Autor inexistente.')) + raise serializers.ValidationError(_("Tipo de Autor inexistente.")) qs = queryset.filter(tipo=tipo) @@ -94,11 +101,15 @@ class AutoresPossiveisFilterSet(SaplFilterSetMixin): def qs(self): qs = super().qs - data_relativa = self.form.cleaned_data['data_relativa'] \ - if 'data_relativa' in self.form.cleaned_data else None + data_relativa = ( + self.form.cleaned_data["data_relativa"] + if "data_relativa" in self.form.cleaned_data + else None + ) - tipo = self.form.cleaned_data['tipo'] \ - if 'tipo' in self.form.cleaned_data else None + tipo = ( + self.form.cleaned_data["tipo"] if "tipo" in self.form.cleaned_data else None + ) if not tipo: return qs @@ -107,7 +118,7 @@ class AutoresPossiveisFilterSet(SaplFilterSetMixin): if not tipo.content_type: return qs - filter_for_model = 'filter_%s' % tipo.content_type.model + filter_for_model = "filter_%s" % tipo.content_type.model if not hasattr(self, filter_for_model): return qs @@ -120,62 +131,79 @@ class AutoresPossiveisFilterSet(SaplFilterSetMixin): def filter_parlamentar(self, queryset, data_relativa): # não leva em conta afastamentos legislatura_relativa = Legislatura.objects.filter( - data_inicio__lte=data_relativa, - data_fim__gte=data_relativa).first() + data_inicio__lte=data_relativa, data_fim__gte=data_relativa + ).first() q = Q( parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, - parlamentar_set__mandato__data_fim_mandato__isnull=True) | Q( + parlamentar_set__mandato__data_fim_mandato__isnull=True, + ) | Q( parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, - parlamentar_set__mandato__data_fim_mandato__gte=data_relativa) + parlamentar_set__mandato__data_fim_mandato__gte=data_relativa, + ) if legislatura_relativa.atual(): q = q & Q(parlamentar_set__ativo=True) - legislatura_anterior = self.request.GET.get( - 'legislatura_anterior', 'False') - if legislatura_anterior.lower() == 'true': + legislatura_anterior = self.request.GET.get("legislatura_anterior", "False") + if legislatura_anterior.lower() == "true": legislaturas = Legislatura.objects.filter( - data_fim__lte=data_relativa).order_by('-data_fim')[:2] + data_fim__lte=data_relativa + ).order_by("-data_fim")[:2] if len(legislaturas) == 2: _, leg_anterior = legislaturas q = q | Q( - parlamentar_set__mandato__data_inicio_mandato__gte=leg_anterior.data_inicio) + parlamentar_set__mandato__data_inicio_mandato__gte=leg_anterior.data_inicio + ) qs = queryset.filter(q) return qs def filter_comissao(self, queryset, data_relativa): return queryset.filter( - Q(comissao_set__data_extincao__isnull=True, - comissao_set__data_fim_comissao__isnull=True) | - Q(comissao_set__data_extincao__gte=data_relativa, - comissao_set__data_fim_comissao__isnull=True) | - Q(comissao_set__data_extincao__gte=data_relativa, - comissao_set__data_fim_comissao__isnull=True) | - Q(comissao_set__data_extincao__isnull=True, - comissao_set__data_fim_comissao__gte=data_relativa) | - Q(comissao_set__data_extincao__gte=data_relativa, - comissao_set__data_fim_comissao__gte=data_relativa), - comissao_set__data_criacao__lte=data_relativa) + Q( + comissao_set__data_extincao__isnull=True, + comissao_set__data_fim_comissao__isnull=True, + ) + | Q( + comissao_set__data_extincao__gte=data_relativa, + comissao_set__data_fim_comissao__isnull=True, + ) + | Q( + comissao_set__data_extincao__gte=data_relativa, + comissao_set__data_fim_comissao__isnull=True, + ) + | Q( + comissao_set__data_extincao__isnull=True, + comissao_set__data_fim_comissao__gte=data_relativa, + ) + | Q( + comissao_set__data_extincao__gte=data_relativa, + comissao_set__data_fim_comissao__gte=data_relativa, + ), + comissao_set__data_criacao__lte=data_relativa, + ) def filter_frente(self, queryset, data_relativa): return queryset.filter( - Q(frente_set__data_extincao__isnull=True) | - Q(frente_set__data_extincao__gte=data_relativa), - frente_set__data_criacao__lte=data_relativa) + Q(frente_set__data_extincao__isnull=True) + | Q(frente_set__data_extincao__gte=data_relativa), + frente_set__data_criacao__lte=data_relativa, + ) def filter_bancada(self, queryset, data_relativa): return queryset.filter( - Q(bancada_set__data_extincao__isnull=True) | - Q(bancada_set__data_extincao__gte=data_relativa), - bancada_set__data_criacao__lte=data_relativa) + Q(bancada_set__data_extincao__isnull=True) + | Q(bancada_set__data_extincao__gte=data_relativa), + bancada_set__data_criacao__lte=data_relativa, + ) def filter_bloco(self, queryset, data_relativa): return queryset.filter( - Q(bloco_set__data_extincao__isnull=True) | - Q(bloco_set__data_extincao__gte=data_relativa), - bloco_set__data_criacao__lte=data_relativa) + Q(bloco_set__data_extincao__isnull=True) + | Q(bloco_set__data_extincao__gte=data_relativa), + bloco_set__data_criacao__lte=data_relativa, + ) def filter_orgao(self, queryset, data_relativa): # na implementação, não havia regras a implementar para orgao diff --git a/sapl/api/pagination.py b/sapl/api/pagination.py index 67aecd7f5..54d15925e 100644 --- a/sapl/api/pagination.py +++ b/sapl/api/pagination.py @@ -5,71 +5,73 @@ from rest_framework.response import Response class StandardPagination(pagination.PageNumberPagination): page_size = 10 - page_size_query_param = 'page_size' + page_size_query_param = "page_size" max_page_size = 100 def paginate_queryset(self, queryset, request, view=None): - if request.query_params.get('get_all', '').lower() == 'true': + if request.query_params.get("get_all", "").lower() == "true": return None return super().paginate_queryset(queryset, request, view=view) def get_paginated_response_schema(self, schema): r = { - 'type': 'object', - 'properties': { - 'pagination': { - 'type': 'object', - 'properties': { - 'links': { - 'type': 'object', - 'properties': { - 'next': { - 'type': 'string', - 'nullable': True, - 'format': 'uri', - 'example': 'http://api.example.org/accounts/?{page_query_param}=4'.format( - page_query_param=self.page_query_param) + "type": "object", + "properties": { + "pagination": { + "type": "object", + "properties": { + "links": { + "type": "object", + "properties": { + "next": { + "type": "string", + "nullable": True, + "format": "uri", + "example": "http://api.example.org/accounts/?{page_query_param}=4".format( + page_query_param=self.page_query_param + ), }, - 'previous': { - 'type': 'string', - 'nullable': True, - 'format': 'uri', - 'example': 'http://api.example.org/accounts/?{page_query_param}=2'.format( - page_query_param=self.page_query_param) + "previous": { + "type": "string", + "nullable": True, + "format": "uri", + "example": "http://api.example.org/accounts/?{page_query_param}=2".format( + page_query_param=self.page_query_param + ), }, - } + }, }, - 'previous_page': { - 'type': 'integer', - 'example': 123, + "previous_page": { + "type": "integer", + "example": 123, }, - 'next_page': { - 'type': 'integer', - 'example': 123, + "next_page": { + "type": "integer", + "example": 123, }, - 'start_index': { - 'type': 'integer', - 'example': 123, + "start_index": { + "type": "integer", + "example": 123, }, - 'end_index': { - 'type': 'integer', - 'example': 123, + "end_index": { + "type": "integer", + "example": 123, }, - 'total_entries': { - 'type': 'integer', - 'example': 123, + "total_entries": { + "type": "integer", + "example": 123, }, - 'total_pages': { - 'type': 'integer', - 'example': 123, + "total_pages": { + "type": "integer", + "example": 123, }, - 'page': { - 'type': 'integer', - 'example': 123, + "page": { + "type": "integer", + "example": 123, }, - } + }, }, - 'results': schema, + "results": schema, }, } return r @@ -85,20 +87,21 @@ class StandardPagination(pagination.PageNumberPagination): except EmptyPage: next_page_number = None - return Response({ - 'pagination': { - 'links': { - 'next': self.get_next_link(), - 'previous': self.get_previous_link(), + return Response( + { + "pagination": { + "links": { + "next": self.get_next_link(), + "previous": self.get_previous_link(), + }, + "previous_page": previous_page_number, + "next_page": next_page_number, + "start_index": self.page.start_index(), + "end_index": self.page.end_index(), + "total_entries": self.page.paginator.count, + "total_pages": self.page.paginator.num_pages, + "page": self.page.number, }, - 'previous_page': previous_page_number, - 'next_page': next_page_number, - 'start_index': self.page.start_index(), - 'end_index': self.page.end_index(), - 'total_entries': self.page.paginator.count, - 'total_pages': self.page.paginator.num_pages, - 'page': self.page.number, - }, - 'results': data, - - }) + "results": data, + } + ) diff --git a/sapl/api/permissions.py b/sapl/api/permissions.py index ae39f8ca9..ed43b3c2a 100644 --- a/sapl/api/permissions.py +++ b/sapl/api/permissions.py @@ -1,42 +1,47 @@ from rest_framework.permissions import DjangoModelPermissions + from sapl.rules.map_rules import rules_patterns_public class SaplModelPermissions(DjangoModelPermissions): - perms_map = { - 'GET': ['%(app_label)s.list_%(model_name)s', - '%(app_label)s.detail_%(model_name)s'], - 'OPTIONS': ['%(app_label)s.list_%(model_name)s', - '%(app_label)s.detail_%(model_name)s'], - 'HEAD': ['%(app_label)s.list_%(model_name)s', - '%(app_label)s.detail_%(model_name)s'], - 'POST': ['%(app_label)s.add_%(model_name)s'], - 'PUT': ['%(app_label)s.change_%(model_name)s'], - 'PATCH': ['%(app_label)s.change_%(model_name)s'], - 'DELETE': ['%(app_label)s.delete_%(model_name)s'], - + "GET": [ + "%(app_label)s.list_%(model_name)s", + "%(app_label)s.detail_%(model_name)s", + ], + "OPTIONS": [ + "%(app_label)s.list_%(model_name)s", + "%(app_label)s.detail_%(model_name)s", + ], + "HEAD": [ + "%(app_label)s.list_%(model_name)s", + "%(app_label)s.detail_%(model_name)s", + ], + "POST": ["%(app_label)s.add_%(model_name)s"], + "PUT": ["%(app_label)s.change_%(model_name)s"], + "PATCH": ["%(app_label)s.change_%(model_name)s"], + "DELETE": ["%(app_label)s.delete_%(model_name)s"], } def has_permission(self, request, view): - if getattr(view, '_ignore_model_permissions', False): + if getattr(view, "_ignore_model_permissions", False): return True - if hasattr(view, 'get_queryset'): + if hasattr(view, "get_queryset"): queryset = view.get_queryset() else: - queryset = getattr(view, 'queryset', None) + queryset = getattr(view, "queryset", None) assert queryset is not None, ( - 'Cannot apply DjangoModelPermissions on a view that ' - 'does not set `.queryset` or have a `.get_queryset()` method.' + "Cannot apply DjangoModelPermissions on a view that " + "does not set `.queryset` or have a `.get_queryset()` method." ) perms = self.get_required_permissions(request.method, queryset.model) - key = '{}:{}'.format( - queryset.model._meta.app_label, - queryset.model._meta.model_name) + key = "{}:{}".format( + queryset.model._meta.app_label, queryset.model._meta.model_name + ) if key in rules_patterns_public: perms = set(perms) @@ -47,7 +52,7 @@ class SaplModelPermissions(DjangoModelPermissions): return True return ( - request.user and - (request.user.is_authenticated or not self.authenticated_users_only) and - request.user.has_perms(perms) + request.user + and (request.user.is_authenticated or not self.authenticated_users_only) + and request.user.has_perms(perms) ) diff --git a/sapl/api/serializers.py b/sapl/api/serializers.py index 903051d10..6545eb293 100644 --- a/sapl/api/serializers.py +++ b/sapl/api/serializers.py @@ -9,7 +9,7 @@ from rest_framework import serializers from rest_framework.fields import SerializerMethodField from sapl.base.models import Autor, CasaLegislativa, Metadata -from sapl.parlamentares.models import Parlamentar, Mandato, Legislatura +from sapl.parlamentares.models import Legislatura, Mandato, Parlamentar from sapl.sessao.models import OrdemDia, SessaoPlenaria @@ -18,7 +18,7 @@ class SaplSerializerMixin(serializers.ModelSerializer): metadata = SerializerMethodField() class Meta: - fields = '__all__' + fields = "__all__" def get___str__(self, obj) -> str: return str(obj) @@ -26,9 +26,8 @@ class SaplSerializerMixin(serializers.ModelSerializer): def get_metadata(self, obj) -> dict: try: metadata = Metadata.objects.get( - content_type=ContentType.objects.get_for_model( - obj._meta.model), - object_id=obj.id + content_type=ContentType.objects.get_for_model(obj._meta.model), + object_id=obj.id, ).metadata except: metadata = {} @@ -48,7 +47,6 @@ class ChoiceSerializer(serializers.Serializer): class ModelChoiceSerializer(ChoiceSerializer): - def get_text(self, obj): return str(obj) @@ -57,18 +55,16 @@ class ModelChoiceSerializer(ChoiceSerializer): class ModelChoiceObjectRelatedField(serializers.RelatedField): - def to_representation(self, value): return ModelChoiceSerializer(value).data class AutorSerializer(SaplSerializerMixin): - autor_related = ModelChoiceObjectRelatedField(read_only=True) class Meta: model = Autor - fields = '__all__' + fields = "__all__" class CasaLegislativaSerializer(SaplSerializerMixin): @@ -79,46 +75,57 @@ class CasaLegislativaSerializer(SaplSerializerMixin): class Meta: model = CasaLegislativa - fields = '__all__' + fields = "__all__" class ParlamentarSerializerPublic(SaplSerializerMixin): - class Meta: model = Parlamentar - exclude = ["cpf", "rg", "fax", "data_nascimento", - "endereco_residencia", "municipio_residencia", - "uf_residencia", "cep_residencia", "situacao_militar", - "telefone_residencia", "titulo_eleitor", "fax_residencia"] + exclude = [ + "cpf", + "rg", + "fax", + "data_nascimento", + "endereco_residencia", + "municipio_residencia", + "uf_residencia", + "cep_residencia", + "situacao_militar", + "telefone_residencia", + "titulo_eleitor", + "fax_residencia", + ] class ParlamentarSerializerVerbose(SaplSerializerMixin): - titular = serializers.SerializerMethodField('check_titular') - partido = serializers.SerializerMethodField('check_partido') - fotografia_cropped = serializers.SerializerMethodField('crop_fotografia') + titular = serializers.SerializerMethodField("check_titular") + partido = serializers.SerializerMethodField("check_partido") + fotografia_cropped = serializers.SerializerMethodField("crop_fotografia") logger = logging.getLogger(__name__) def crop_fotografia(self, obj): thumbnail_url = "" try: import os + if not obj.fotografia or not os.path.exists(obj.fotografia.path): return thumbnail_url self.logger.warning(f"Iniciando cropping da imagem {obj.fotografia}") thumbnail_url = get_backend().get_thumbnail_url( obj.fotografia, { - 'size': (128, 128), - 'box': obj.cropping, - 'crop': True, - 'detail': True, - } + "size": (128, 128), + "box": obj.cropping, + "crop": True, + "detail": True, + }, + ) + self.logger.warning( + f"Cropping da imagem {obj.fotografia} realizado com sucesso" ) - self.logger.warning(f"Cropping da imagem {obj.fotografia} realizado com sucesso") except Exception as e: self.logger.error(e) - self.logger.error('erro processando arquivo: %s' % - obj.fotografia.path) + self.logger.error("erro processando arquivo: %s" % obj.fotografia.path) return thumbnail_url @@ -129,19 +136,22 @@ class ParlamentarSerializerVerbose(SaplSerializerMixin): return "" try: - legislatura = Legislatura.objects.get( - id=self.context.get('legislatura')) + legislatura = Legislatura.objects.get(id=self.context.get("legislatura")) except ObjectDoesNotExist: legislatura = Legislatura.objects.first() - mandato = Mandato.objects.filter( - parlamentar=obj, - data_inicio_mandato__gte=legislatura.data_inicio, - data_fim_mandato__lte=legislatura.data_fim - ).order_by('-data_inicio_mandato').first() + mandato = ( + Mandato.objects.filter( + parlamentar=obj, + data_inicio_mandato__gte=legislatura.data_inicio, + data_fim_mandato__lte=legislatura.data_fim, + ) + .order_by("-data_inicio_mandato") + .first() + ) if mandato: - is_titular = 'Sim' if mandato.titular else 'Não' + is_titular = "Sim" if mandato.titular else "Não" else: - is_titular = '-' + is_titular = "-" return is_titular def check_partido(self, obj): @@ -151,76 +161,95 @@ class ParlamentarSerializerVerbose(SaplSerializerMixin): # da legislatura e data de desfiliação deve nula, ou maior, # ou igual a data de fim da legislatura - username = self.context['request'].user.username + username = self.context["request"].user.username if not Legislatura.objects.exists(): self.logger.error("Não há legislaturas cadastradas.") return "" try: - legislatura = Legislatura.objects.get( - id=self.context.get('legislatura')) + legislatura = Legislatura.objects.get(id=self.context.get("legislatura")) except ObjectDoesNotExist: legislatura = Legislatura.objects.first() try: - self.logger.debug("user=" + username + ". Tentando obter filiação do parlamentar com (data<={} e data_desfiliacao>={}) " - "ou (data<={} e data_desfiliacao=Null))." - .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim)) - filiacao = obj.filiacao_set.get(Q( - data__lte=legislatura.data_fim, - data_desfiliacao__gte=legislatura.data_fim) | Q( - data__lte=legislatura.data_fim, - data_desfiliacao__isnull=True)) + self.logger.debug( + "user=" + + username + + ". Tentando obter filiação do parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null)).".format( + legislatura.data_fim, legislatura.data_fim, legislatura.data_fim + ) + ) + filiacao = obj.filiacao_set.get( + Q( + data__lte=legislatura.data_fim, + data_desfiliacao__gte=legislatura.data_fim, + ) + | Q(data__lte=legislatura.data_fim, data_desfiliacao__isnull=True) + ) # Caso não exista filiação com essas condições except ObjectDoesNotExist: - 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' + 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" # Caso exista mais de uma filiação nesse intervalo # Entretanto, NÃO DEVE OCORRER except MultipleObjectsReturned: - self.logger.error("user=" + username + ". O Parlamentar com (data<={} e data_desfiliacao>={}) " - "ou (data<={} e data_desfiliacao=Null)) possui duas filiações conflitantes" - .format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim)) - filiacao = 'O Parlamentar possui duas filiações conflitantes' + self.logger.error( + "user=" + + username + + ". O Parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null)) possui duas filiações conflitantes".format( + legislatura.data_fim, legislatura.data_fim, legislatura.data_fim + ) + ) + filiacao = "O Parlamentar possui duas filiações conflitantes" # Caso encontre UMA filiação nessas condições else: - self.logger.debug("user=" + username + - ". Filiação encontrada com sucesso.") + self.logger.debug("user=" + username + ". Filiação encontrada com sucesso.") filiacao = filiacao.partido.sigla return filiacao class Meta: model = Parlamentar - fields = ['id', 'nome_parlamentar', 'fotografia_cropped', - 'fotografia', 'ativo', 'partido', 'titular', ] + fields = [ + "id", + "nome_parlamentar", + "fotografia_cropped", + "fotografia", + "ativo", + "partido", + "titular", + ] class SessaoPlenariaECidadaniaSerializer(serializers.ModelSerializer): - - codReuniao = serializers.SerializerMethodField('get_pk_sessao') - codReuniaoPrincipal = serializers.SerializerMethodField('get_pk_sessao') - txtTituloReuniao = serializers.SerializerMethodField('get_name') - txtSiglaOrgao = serializers.SerializerMethodField('get_sigla_orgao') - txtApelido = serializers.SerializerMethodField('get_name') - txtNomeOrgao = serializers.SerializerMethodField('get_nome_orgao') - codEstadoReuniao = serializers.SerializerMethodField( - 'get_estadoSessaoPlenaria') - txtTipoReuniao = serializers.SerializerMethodField('get_tipo_sessao') - txtObjeto = serializers.SerializerMethodField('get_assunto_sessao') - txtLocal = serializers.SerializerMethodField('get_endereco_orgao') - bolReuniaoConjunta = serializers.SerializerMethodField( - 'get_reuniao_conjunta') - bolHabilitarEventoInterativo = serializers.SerializerMethodField( - 'get_iterativo') - idYoutube = serializers.SerializerMethodField('get_url') + codReuniao = serializers.SerializerMethodField("get_pk_sessao") + codReuniaoPrincipal = serializers.SerializerMethodField("get_pk_sessao") + txtTituloReuniao = serializers.SerializerMethodField("get_name") + txtSiglaOrgao = serializers.SerializerMethodField("get_sigla_orgao") + txtApelido = serializers.SerializerMethodField("get_name") + txtNomeOrgao = serializers.SerializerMethodField("get_nome_orgao") + codEstadoReuniao = serializers.SerializerMethodField("get_estadoSessaoPlenaria") + txtTipoReuniao = serializers.SerializerMethodField("get_tipo_sessao") + txtObjeto = serializers.SerializerMethodField("get_assunto_sessao") + txtLocal = serializers.SerializerMethodField("get_endereco_orgao") + bolReuniaoConjunta = serializers.SerializerMethodField("get_reuniao_conjunta") + bolHabilitarEventoInterativo = serializers.SerializerMethodField("get_iterativo") + idYoutube = serializers.SerializerMethodField("get_url") codEstadoTransmissaoYoutube = serializers.SerializerMethodField( - 'get_estadoTransmissaoYoutube') - datReuniaoString = serializers.SerializerMethodField('get_date') + "get_estadoTransmissaoYoutube" + ) + datReuniaoString = serializers.SerializerMethodField("get_date") # Constantes SessaoPlenaria (de 1-9) (apenas 3 serão usados) SESSAO_FINALIZADA = 4 @@ -235,21 +264,21 @@ class SessaoPlenariaECidadaniaSerializer(serializers.ModelSerializer): class Meta: model = SessaoPlenaria fields = ( - 'codReuniao', - 'codReuniaoPrincipal', - 'txtTituloReuniao', - 'txtSiglaOrgao', - 'txtApelido', - 'txtNomeOrgao', - 'codEstadoReuniao', - 'txtTipoReuniao', - 'txtObjeto', - 'txtLocal', - 'bolReuniaoConjunta', - 'bolHabilitarEventoInterativo', - 'idYoutube', - 'codEstadoTransmissaoYoutube', - 'datReuniaoString' + "codReuniao", + "codReuniaoPrincipal", + "txtTituloReuniao", + "txtSiglaOrgao", + "txtApelido", + "txtNomeOrgao", + "codEstadoReuniao", + "txtTipoReuniao", + "txtObjeto", + "txtLocal", + "bolReuniaoConjunta", + "bolHabilitarEventoInterativo", + "idYoutube", + "codEstadoTransmissaoYoutube", + "datReuniaoString", ) def get_pk_sessao(self, obj): @@ -277,9 +306,7 @@ class SessaoPlenariaECidadaniaSerializer(serializers.ModelSerializer): def get_date(self, obj): return "{} {}{}".format( - obj.data_inicio.strftime("%d/%m/%Y"), - obj.hora_inicio, - ":00" + obj.data_inicio.strftime("%d/%m/%Y"), obj.hora_inicio, ":00" ) def get_estadoTransmissaoYoutube(self, obj): @@ -292,9 +319,9 @@ class SessaoPlenariaECidadaniaSerializer(serializers.ModelSerializer): return self.SEM_TRANSMISSAO def get_assunto_sessao(self, obj): - pauta_sessao = '' + pauta_sessao = "" ordem_dia = OrdemDia.objects.filter(sessao_plenaria=obj.pk) - pauta_sessao = ', '.join([i.materia.__str__() for i in ordem_dia]) + pauta_sessao = ", ".join([i.materia.__str__() for i in ordem_dia]) return str(pauta_sessao) diff --git a/sapl/api/urls.py b/sapl/api/urls.py index 5c84121e3..7c99d94bc 100644 --- a/sapl/api/urls.py +++ b/sapl/api/urls.py @@ -1,16 +1,14 @@ - from django.urls import include, path, re_path -from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, \ - SpectacularRedocView +from drf_spectacular.views import (SpectacularAPIView, SpectacularRedocView, + SpectacularSwaggerView) from rest_framework.authtoken.views import obtain_auth_token from sapl.api.deprecated import SessaoPlenariaViewSet -from sapl.api.views import AppVersionView, recria_token,\ - SaplApiViewSetConstrutor +from sapl.api.views import (AppVersionView, SaplApiViewSetConstrutor, + recria_token) from .apps import AppConfig - app_name = AppConfig.name router = SaplApiViewSetConstrutor.router() @@ -19,26 +17,30 @@ router = SaplApiViewSetConstrutor.router() # verificar se ainda permanece necessidade desses endpoint's # /api/sessao-planaria -> /api/sessao/sessaoplenaria/ecidadania # /api/sessao-planaria/{pk} -> /api/sessao/sessaoplenaria/{pk}/ecidadania -router.register(r'sessao-plenaria', SessaoPlenariaViewSet, - basename='sessao_plenaria_old') +router.register( + r"sessao-plenaria", SessaoPlenariaViewSet, basename="sessao_plenaria_old" +) urlpatterns_router = router.urls urlpatterns_api_doc = [ - re_path('^schema/swagger-ui/', - SpectacularSwaggerView.as_view(url_name='sapl.api:schema_api'), - name='swagger_ui_schema_api'), - re_path('^schema/redoc/', - SpectacularRedocView.as_view(url_name='sapl.api:schema_api'), - name='redoc_schema_api'), - re_path('^schema/', SpectacularAPIView.as_view(), name='schema_api'), + re_path( + "^schema/swagger-ui/", + SpectacularSwaggerView.as_view(url_name="sapl.api:schema_api"), + name="swagger_ui_schema_api", + ), + re_path( + "^schema/redoc/", + SpectacularRedocView.as_view(url_name="sapl.api:schema_api"), + name="redoc_schema_api", + ), + re_path("^schema/", SpectacularAPIView.as_view(), name="schema_api"), ] urlpatterns = [ - path('api/', include(urlpatterns_api_doc)), - path('api/', include(urlpatterns_router)), - - re_path(r'^api/version', AppVersionView.as_view()), - path('api/auth/token', obtain_auth_token), - re_path(r'^api/recriar-token/(?P\d*)$', recria_token, name="recria_token"), + path("api/", include(urlpatterns_api_doc)), + path("api/", include(urlpatterns_router)), + re_path(r"^api/version", AppVersionView.as_view()), + path("api/auth/token", obtain_auth_token), + re_path(r"^api/recriar-token/(?P\d*)$", recria_token, name="recria_token"), ] diff --git a/sapl/api/views.py b/sapl/api/views.py index a9c0686e8..b3fde1ea1 100644 --- a/sapl/api/views.py +++ b/sapl/api/views.py @@ -3,7 +3,7 @@ import logging from django.conf import settings from rest_framework.authtoken.models import Token from rest_framework.decorators import api_view, permission_classes -from rest_framework.permissions import IsAuthenticated, IsAdminUser +from rest_framework.permissions import IsAdminUser, IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView @@ -12,7 +12,7 @@ from drfautoapi.drfautoapi import ApiViewSetConstrutor logger = logging.getLogger(__name__) -@api_view(['POST']) +@api_view(["POST"]) @permission_classes([IsAdminUser]) def recria_token(request, pk): Token.objects.filter(user_id=pk).delete() @@ -26,28 +26,30 @@ class AppVersionView(APIView): def get(self, request): content = { - 'name': 'SAPL', - 'description': 'Sistema de Apoio ao Processo Legislativo', - 'version': settings.SAPL_VERSION, - 'user': request.user.username, - 'is_authenticated': request.user.is_authenticated, + "name": "SAPL", + "description": "Sistema de Apoio ao Processo Legislativo", + "version": settings.SAPL_VERSION, + "user": request.user.username, + "is_authenticated": request.user.is_authenticated, } return Response(content) SaplApiViewSetConstrutor = ApiViewSetConstrutor -SaplApiViewSetConstrutor.import_modules([ - 'sapl.api.views_audiencia', - 'sapl.api.views_base', - 'sapl.api.views_comissoes', - 'sapl.api.views_compilacao', - 'sapl.api.views_materia', - 'sapl.api.views_norma', - 'sapl.api.views_painel', - 'sapl.api.views_parlamentares', - 'sapl.api.views_protocoloadm', - 'sapl.api.views_sessao', -]) +SaplApiViewSetConstrutor.import_modules( + [ + "sapl.api.views_audiencia", + "sapl.api.views_base", + "sapl.api.views_comissoes", + "sapl.api.views_compilacao", + "sapl.api.views_materia", + "sapl.api.views_norma", + "sapl.api.views_painel", + "sapl.api.views_parlamentares", + "sapl.api.views_protocoloadm", + "sapl.api.views_sessao", + ] +) """ diff --git a/sapl/api/views_audiencia.py b/sapl/api/views_audiencia.py index c636be92f..756ea0b19 100644 --- a/sapl/api/views_audiencia.py +++ b/sapl/api/views_audiencia.py @@ -1,11 +1,8 @@ - from django.apps.registry import apps -from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ - customize, wrapper_queryset_response_for_drf_action +from drfautoapi.drfautoapi import (ApiViewSetConstrutor, customize, + wrapper_queryset_response_for_drf_action) AudienciaApiViewSetConstrutor = ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('audiencia') - ] + [apps.get_app_config("audiencia")] ) diff --git a/sapl/api/views_base.py b/sapl/api/views_base.py index 04dbd3fc9..aec2dc8dc 100644 --- a/sapl/api/views_base.py +++ b/sapl/api/views_base.py @@ -11,22 +11,18 @@ from drfautoapi.drfautoapi import ApiViewSetConstrutor, customize from sapl.api.forms import AutoresPossiveisFilterSet from sapl.api.serializers import ChoiceSerializer from sapl.base.models import Autor, TipoAutor -from sapl.utils import models_with_gr_for_model, SaplGenericRelation - +from sapl.utils import SaplGenericRelation, models_with_gr_for_model logger = logging.getLogger(__name__) ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('contenttypes'), - apps.get_app_config('base') - ] + [apps.get_app_config("contenttypes"), apps.get_app_config("base")] ) @customize(ContentType) class _ContentTypeSet: - http_method_names = ['get', 'head', 'options', 'trace'] + http_method_names = ["get", "head", "options", "trace"] @customize(Autor) @@ -74,7 +70,6 @@ class _AutorViewSet: @classmethod def build(cls): - models_with_gr_for_autor = models_with_gr_for_model(Autor) for _model in models_with_gr_for_autor: @@ -87,10 +82,10 @@ class _AutorViewSet: return self.list_for_content_type(content_type) func = actionclass - func.mapping['get'] = func.kwargs['name'] - func.url_name = func.kwargs['name'] - func.url_path = func.kwargs['name'] - func.__name__ = func.kwargs['name'] + func.mapping["get"] = func.kwargs["name"] + func.url_name = func.kwargs["name"] + func.url_path = func.kwargs["name"] + func.__name__ = func.kwargs["name"] func.__model = _model setattr(cls, _model._meta.model_name, func) @@ -103,7 +98,6 @@ class _AutorViewSet: @action(detail=False) def provaveis(self, request, *args, **kwargs): - self.get_queryset = self.provaveis__get_queryset self.filter_backends = [] @@ -112,15 +106,15 @@ class _AutorViewSet: return self.list(request, *args, **kwargs) def provaveis__get_queryset(self): - params = {'content_type__isnull': False} + params = {"content_type__isnull": False} username = self.request.user.username - tipo = '' + tipo = "" try: - tipo = int(self.request.GET.get('tipo', '')) + tipo = int(self.request.GET.get("tipo", "")) if tipo: - params['id'] = tipo + params["id"] = tipo except Exception as e: - logger.error('user= ' + username + '. ' + str(e)) + logger.error("user= " + username + ". " + str(e)) pass tipos = TipoAutor.objects.filter(**params) @@ -130,14 +124,17 @@ class _AutorViewSet: r = [] for tipo in tipos: - q = self.request.GET.get('q', '').strip() + q = self.request.GET.get("q", "").strip() model_class = tipo.content_type.model_class() - fields = list(filter( - lambda field: isinstance(field, SaplGenericRelation) and - field.related_model == Autor, - model_class._meta.get_fields(include_hidden=True))) + fields = list( + filter( + lambda field: isinstance(field, SaplGenericRelation) + and field.related_model == Autor, + model_class._meta.get_fields(include_hidden=True), + ) + ) """ fields - é um array de SaplGenericRelation que deve possuir o @@ -145,11 +142,13 @@ class _AutorViewSet: a estrutura de fields_search. """ - assert len(fields) >= 1, (_( - 'Não foi encontrado em %(model)s um atributo do tipo ' - 'SaplGenericRelation que use o model %(model_autor)s') % { - 'model': model_class._meta.verbose_name, - 'model_autor': Autor._meta.verbose_name}) + assert len(fields) >= 1, _( + "Não foi encontrado em %(model)s um atributo do tipo " + "SaplGenericRelation que use o model %(model_autor)s" + ) % { + "model": model_class._meta.verbose_name, + "model_autor": Autor._meta.verbose_name, + } qs = model_class.objects.all() @@ -160,19 +159,18 @@ class _AutorViewSet: continue q_fs = Q() for field in item.fields_search: - q_fs = q_fs | Q(**{'%s%s' % ( - field[0], - field[1]): q}) + q_fs = q_fs | Q(**{"%s%s" % (field[0], field[1]): q}) q_filter = q_filter & q_fs - qs = qs.filter(q_filter).distinct( - fields[0].fields_search[0][0]).order_by( - fields[0].fields_search[0][0]) + qs = ( + qs.filter(q_filter) + .distinct(fields[0].fields_search[0][0]) + .order_by(fields[0].fields_search[0][0]) + ) else: qs = qs.order_by(fields[0].fields_search[0][0]) - qs = qs.values_list( - 'id', fields[0].fields_search[0][0]) + qs = qs.values_list("id", fields[0].fields_search[0][0]) r += list(qs) if tipos.count() > 1: diff --git a/sapl/api/views_comissoes.py b/sapl/api/views_comissoes.py index a1722be3b..5635d3fcb 100644 --- a/sapl/api/views_comissoes.py +++ b/sapl/api/views_comissoes.py @@ -1,23 +1,16 @@ - from django.apps.registry import apps - -from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ - customize, wrapper_queryset_response_for_drf_action -from sapl.comissoes.models import Comissao from rest_framework.decorators import action +from drfautoapi.drfautoapi import (ApiViewSetConstrutor, customize, + wrapper_queryset_response_for_drf_action) +from sapl.comissoes.models import Comissao from sapl.materia.models import MateriaEmTramitacao +ApiViewSetConstrutor.build_class([apps.get_app_config("comissoes")]) -ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('comissoes') - ] -) @customize(Comissao) class _ComissaoViewSet: - @action(detail=True) def materiaemtramitacao(self, request, *args, **kwargs): return self.get_materiaemtramitacao(**kwargs) @@ -25,5 +18,5 @@ class _ComissaoViewSet: @wrapper_queryset_response_for_drf_action(model=MateriaEmTramitacao) def get_materiaemtramitacao(self, **kwargs): return self.get_queryset().filter( - unidade_tramitacao_atual__comissao=kwargs['pk'], - ) \ No newline at end of file + unidade_tramitacao_atual__comissao=kwargs["pk"], + ) diff --git a/sapl/api/views_compilacao.py b/sapl/api/views_compilacao.py index 341c0a959..84e463d83 100644 --- a/sapl/api/views_compilacao.py +++ b/sapl/api/views_compilacao.py @@ -1,12 +1,6 @@ - from django.apps.registry import apps -from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ - customize, wrapper_queryset_response_for_drf_action - +from drfautoapi.drfautoapi import (ApiViewSetConstrutor, customize, + wrapper_queryset_response_for_drf_action) -ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('compilacao') - ] -) +ApiViewSetConstrutor.build_class([apps.get_app_config("compilacao")]) diff --git a/sapl/api/views_materia.py b/sapl/api/views_materia.py index d37658afa..f679589f2 100644 --- a/sapl/api/views_materia.py +++ b/sapl/api/views_materia.py @@ -1,21 +1,15 @@ - from django.apps.registry import apps from django.db.models import Q from rest_framework.decorators import action from rest_framework.response import Response -from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ - customize, wrapper_queryset_response_for_drf_action +from drfautoapi.drfautoapi import (ApiViewSetConstrutor, customize, + wrapper_queryset_response_for_drf_action) from sapl.api.permissions import SaplModelPermissions -from sapl.materia.models import TipoMateriaLegislativa, Tramitacao,\ - MateriaLegislativa, Proposicao - +from sapl.materia.models import (MateriaLegislativa, Proposicao, + TipoMateriaLegislativa, Tramitacao) -ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('materia') - ] -) +ApiViewSetConstrutor.build_class([apps.get_app_config("materia")]) @customize(Proposicao) @@ -46,9 +40,8 @@ class _ProposicaoViewSet: """ class ProposicaoPermission(SaplModelPermissions): - def has_permission(self, request, view): - if request.method == 'GET': + if request.method == "GET": return True # se a solicitação é list ou detail, libera o teste de permissão # e deixa o get_queryset filtrar de acordo com a regra de @@ -68,7 +61,6 @@ class _ProposicaoViewSet: q = Q(data_recebimento__isnull=False, object_id__isnull=False) if not self.request.user.is_anonymous: - autor_do_usuario_logado = self.request.user.autor_set.first() # se usuário logado é operador de algum autor @@ -76,9 +68,8 @@ class _ProposicaoViewSet: q = Q(autor=autor_do_usuario_logado) # se é operador de protocolo, ve qualquer coisa enviada - if self.request.user.has_perm('protocoloadm.list_protocolo'): - q = Q(data_envio__isnull=False) | Q( - data_devolucao__isnull=False) + if self.request.user.has_perm("protocoloadm.list_protocolo"): + q = Q(data_envio__isnull=False) | Q(data_devolucao__isnull=False) qs = qs.filter(q) return qs @@ -86,26 +77,26 @@ class _ProposicaoViewSet: @customize(MateriaLegislativa) class _MateriaLegislativaViewSet: - class Meta: - ordering = ['-ano', 'tipo', 'numero'] + ordering = ["-ano", "tipo", "numero"] - @action(detail=True, methods=['GET']) + @action(detail=True, methods=["GET"]) def ultima_tramitacao(self, request, *args, **kwargs): - materia = self.get_object() if not materia.tramitacao_set.exists(): return Response({}) ultima_tramitacao = materia.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() serializer_class = ApiViewSetConstrutor.get_viewset_for_model( - Tramitacao).serializer_class(ultima_tramitacao) + Tramitacao + ).serializer_class(ultima_tramitacao) return Response(serializer_class.data) - @action(detail=True, methods=['GET']) + @action(detail=True, methods=["GET"]) def anexadas(self, request, *args, **kwargs): self.queryset = self.get_object().anexadas.all() return self.list(request, *args, **kwargs) @@ -113,17 +104,13 @@ class _MateriaLegislativaViewSet: @customize(TipoMateriaLegislativa) class _TipoMateriaLegislativaViewSet: - - @action(detail=True, methods=['POST']) + @action(detail=True, methods=["POST"]) def change_position(self, request, *args, **kwargs): - result = { - 'status': 200, - 'message': 'OK' - } + result = {"status": 200, "message": "OK"} d = request.data - if 'pos_ini' in d and 'pos_fim' in d: - if d['pos_ini'] != d['pos_fim']: - pk = kwargs['pk'] - TipoMateriaLegislativa.objects.reposicione(pk, d['pos_fim']) + if "pos_ini" in d and "pos_fim" in d: + if d["pos_ini"] != d["pos_fim"]: + pk = kwargs["pk"] + TipoMateriaLegislativa.objects.reposicione(pk, d["pos_fim"]) return Response(result) diff --git a/sapl/api/views_norma.py b/sapl/api/views_norma.py index 1b962f38d..07305504c 100644 --- a/sapl/api/views_norma.py +++ b/sapl/api/views_norma.py @@ -1,14 +1,8 @@ - from django.apps.registry import apps from rest_framework.decorators import action -from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ - customize, wrapper_queryset_response_for_drf_action +from drfautoapi.drfautoapi import (ApiViewSetConstrutor, customize, + wrapper_queryset_response_for_drf_action) from sapl.norma.models import NormaJuridica - -ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('norma') - ] -) +ApiViewSetConstrutor.build_class([apps.get_app_config("norma")]) diff --git a/sapl/api/views_painel.py b/sapl/api/views_painel.py index 66f918658..76be28488 100644 --- a/sapl/api/views_painel.py +++ b/sapl/api/views_painel.py @@ -1,11 +1,6 @@ - from django.apps.registry import apps -from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ - customize, wrapper_queryset_response_for_drf_action +from drfautoapi.drfautoapi import (ApiViewSetConstrutor, customize, + wrapper_queryset_response_for_drf_action) -ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('painel') - ] -) +ApiViewSetConstrutor.build_class([apps.get_app_config("painel")]) diff --git a/sapl/api/views_parlamentares.py b/sapl/api/views_parlamentares.py index e8888160d..2dec4b412 100644 --- a/sapl/api/views_parlamentares.py +++ b/sapl/api/views_parlamentares.py @@ -1,34 +1,25 @@ - from django.apps.registry import apps from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist from rest_framework.decorators import action from rest_framework.response import Response -from drfautoapi.drfautoapi import customize, ApiViewSetConstrutor, \ - wrapper_queryset_response_for_drf_action - +from drfautoapi.drfautoapi import (ApiViewSetConstrutor, customize, + wrapper_queryset_response_for_drf_action) from sapl.api.permissions import SaplModelPermissions -from sapl.api.serializers import ParlamentarSerializerVerbose, \ - ParlamentarSerializerPublic +from sapl.api.serializers import (ParlamentarSerializerPublic, + ParlamentarSerializerVerbose) from sapl.materia.models import Proposicao -from sapl.parlamentares.models import Mandato, Legislatura -from sapl.parlamentares.models import Parlamentar +from sapl.parlamentares.models import Legislatura, Mandato, Parlamentar -ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('parlamentares') - ] -) +ApiViewSetConstrutor.build_class([apps.get_app_config("parlamentares")]) @customize(Parlamentar) class _ParlamentarViewSet: - class ParlamentarPermission(SaplModelPermissions): - def has_permission(self, request, view): - if request.method == 'GET': + if request.method == "GET": return True else: perm = super().has_permission(request, view) @@ -37,7 +28,7 @@ class _ParlamentarViewSet: permission_classes = (ParlamentarPermission,) def get_serializer(self, *args, **kwargs): - if not self.request.user.has_perm('parlamentares.add_parlamentar'): + if not self.request.user.has_perm("parlamentares.add_parlamentar"): self.serializer_class = ParlamentarSerializerPublic return super().get_serializer(*args, **kwargs) @@ -58,35 +49,30 @@ class _ParlamentarViewSet: @wrapper_queryset_response_for_drf_action(model=Proposicao) def get_proposicoes(self, **kwargs): - return self.get_queryset().filter( data_envio__isnull=False, data_recebimento__isnull=False, cancelado=False, - autor__object_id=kwargs['pk'], - autor__content_type=ContentType.objects.get_for_model(Parlamentar) + autor__object_id=kwargs["pk"], + autor__content_type=ContentType.objects.get_for_model(Parlamentar), ) - @action(detail=False, methods=['GET']) + @action(detail=False, methods=["GET"]) def search_parlamentares(self, request, *args, **kwargs): - nome = request.query_params.get('nome_parlamentar', '') - parlamentares = Parlamentar.objects.filter( - nome_parlamentar__icontains=nome) + nome = request.query_params.get("nome_parlamentar", "") + parlamentares = Parlamentar.objects.filter(nome_parlamentar__icontains=nome) serializer_class = ParlamentarSerializerVerbose( - parlamentares, many=True, context={'request': request}) + parlamentares, many=True, context={"request": request} + ) return Response(serializer_class.data) @customize(Legislatura) class _LegislaturaViewSet: - @action(detail=True) def parlamentares(self, request, *args, **kwargs): - def get_serializer_context(): - return { - 'request': self.request, 'legislatura': kwargs['pk'] - } + return {"request": self.request, "legislatura": kwargs["pk"]} def get_serializer_class(): return ParlamentarSerializerVerbose @@ -98,22 +84,21 @@ class _LegislaturaViewSet: @wrapper_queryset_response_for_drf_action(model=Parlamentar) def get_parlamentares(self): - try: - legislatura = Legislatura.objects.get(pk=self.kwargs['pk']) + legislatura = Legislatura.objects.get(pk=self.kwargs["pk"]) except ObjectDoesNotExist: return Response("") filter_params = { - 'legislatura': legislatura, - 'data_inicio_mandato__gte': legislatura.data_inicio, - 'data_fim_mandato__lte': legislatura.data_fim, + "legislatura": legislatura, + "data_inicio_mandato__gte": legislatura.data_inicio, + "data_fim_mandato__lte": legislatura.data_fim, } - mandatos = Mandato.objects.filter( - **filter_params).order_by('-data_inicio_mandato') + mandatos = Mandato.objects.filter(**filter_params).order_by( + "-data_inicio_mandato" + ) - parlamentares = self.get_queryset().filter( - mandato__in=mandatos).distinct() + parlamentares = self.get_queryset().filter(mandato__in=mandatos).distinct() return parlamentares diff --git a/sapl/api/views_protocoloadm.py b/sapl/api/views_protocoloadm.py index 5ebe77ec1..9f6bdadd3 100644 --- a/sapl/api/views_protocoloadm.py +++ b/sapl/api/views_protocoloadm.py @@ -1,29 +1,23 @@ - from django.apps.registry import apps -from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ - customize, wrapper_queryset_response_for_drf_action +from drfautoapi.drfautoapi import (ApiViewSetConstrutor, customize, + wrapper_queryset_response_for_drf_action) from sapl.api.permissions import SaplModelPermissions -from sapl.base.models import AppConfig, DOC_ADM_OSTENSIVO -from sapl.protocoloadm.models import DocumentoAdministrativo, \ - DocumentoAcessorioAdministrativo, TramitacaoAdministrativo, Anexado - +from sapl.base.models import DOC_ADM_OSTENSIVO, AppConfig +from sapl.protocoloadm.models import (Anexado, + DocumentoAcessorioAdministrativo, + DocumentoAdministrativo, + TramitacaoAdministrativo) -ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('protocoloadm') - ] -) +ApiViewSetConstrutor.build_class([apps.get_app_config("protocoloadm")]) @customize(DocumentoAdministrativo) class _DocumentoAdministrativoViewSet: - class DocumentoAdministrativoPermission(SaplModelPermissions): - def has_permission(self, request, view): - if request.method == 'GET': - comportamento = AppConfig.attr('documentos_administrativos') + if request.method == "GET": + comportamento = AppConfig.attr("documentos_administrativos") if comportamento == DOC_ADM_OSTENSIVO: return True """ @@ -54,9 +48,9 @@ class _DocumentoAdministrativoViewSet: @customize(DocumentoAcessorioAdministrativo) class _DocumentoAcessorioAdministrativoViewSet: - permission_classes = ( - _DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission,) + _DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission, + ) def get_queryset(self): qs = super().get_queryset() @@ -72,10 +66,11 @@ class _TramitacaoAdministrativoViewSet: # tramitacação de adm possui regras previstas de limitação de origem # destino - http_method_names = ['get', 'head', 'options', 'trace'] + http_method_names = ["get", "head", "options", "trace"] permission_classes = ( - _DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission,) + _DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission, + ) def get_queryset(self): qs = super().get_queryset() @@ -89,10 +84,11 @@ class _TramitacaoAdministrativoViewSet: class _AnexadoViewSet: # TODO: Implementar regras de manutenção post, put, patch # anexado deve possuir controle que impeça anexação cíclica - http_method_names = ['get', 'head', 'options', 'trace'] + http_method_names = ["get", "head", "options", "trace"] permission_classes = ( - _DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission,) + _DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission, + ) def get_queryset(self): qs = super().get_queryset() diff --git a/sapl/api/views_sessao.py b/sapl/api/views_sessao.py index 75807f8cd..f3b874386 100644 --- a/sapl/api/views_sessao.py +++ b/sapl/api/views_sessao.py @@ -1,26 +1,19 @@ - from django.apps.registry import apps from rest_framework.decorators import action from rest_framework.response import Response -from drfautoapi.drfautoapi import ApiViewSetConstrutor, \ - customize, wrapper_queryset_response_for_drf_action -from sapl.api.serializers import ChoiceSerializer,\ - SessaoPlenariaECidadaniaSerializer -from sapl.sessao.models import SessaoPlenaria, ExpedienteSessao +from drfautoapi.drfautoapi import (ApiViewSetConstrutor, customize, + wrapper_queryset_response_for_drf_action) +from sapl.api.serializers import (ChoiceSerializer, + SessaoPlenariaECidadaniaSerializer) +from sapl.sessao.models import ExpedienteSessao, SessaoPlenaria from sapl.utils import choice_anos_com_sessaoplenaria - -ApiViewSetConstrutor.build_class( - [ - apps.get_app_config('sessao') - ] -) +ApiViewSetConstrutor.build_class([apps.get_app_config("sessao")]) @customize(SessaoPlenaria) class _SessaoPlenariaViewSet: - @action(detail=False) def years(self, request, *args, **kwargs): years = choice_anos_com_sessaoplenaria() @@ -34,14 +27,14 @@ class _SessaoPlenariaViewSet: @wrapper_queryset_response_for_drf_action(model=ExpedienteSessao) def get_expedientes(self): - return self.get_queryset().filter(sessao_plenaria_id=self.kwargs['pk']) + return self.get_queryset().filter(sessao_plenaria_id=self.kwargs["pk"]) @action(detail=True) def ecidadania(self, request, *args, **kwargs): self.serializer_class = SessaoPlenariaECidadaniaSerializer return self.retrieve(request, *args, **kwargs) - @action(detail=False, url_path='ecidadania') + @action(detail=False, url_path="ecidadania") def ecidadania_list(self, request, *args, **kwargs): self.serializer_class = SessaoPlenariaECidadaniaSerializer return self.list(request, *args, **kwargs) diff --git a/sapl/audiencia/apps.py b/sapl/audiencia/apps.py index 148d4ac5b..fc006b948 100644 --- a/sapl/audiencia/apps.py +++ b/sapl/audiencia/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.audiencia' - label = 'audiencia' - verbose_name = _('Audiência Pública') \ No newline at end of file + name = "sapl.audiencia" + label = "audiencia" + verbose_name = _("Audiência Pública") diff --git a/sapl/audiencia/forms.py b/sapl/audiencia/forms.py index 9629ccf40..8614393f6 100755 --- a/sapl/audiencia/forms.py +++ b/sapl/audiencia/forms.py @@ -1,19 +1,19 @@ import logging - from datetime import datetime +from crispy_forms.layout import HTML, Button, Column, Fieldset, Layout from django import forms from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.db import transaction from django.utils.translation import gettext_lazy as _ -from crispy_forms.layout import Button, Column, Fieldset, HTML, Layout - -from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica, AnexoAudienciaPublica -from sapl.crispy_layout_mixin import form_actions, SaplFormHelper, SaplFormLayout, to_row +from sapl.audiencia.models import (AnexoAudienciaPublica, AudienciaPublica, + TipoAudienciaPublica) +from sapl.crispy_layout_mixin import (SaplFormHelper, SaplFormLayout, + form_actions, to_row) from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.parlamentares.models import Parlamentar -from sapl.utils import timezone, FileFieldCheckMixin, validar_arquivo +from sapl.utils import FileFieldCheckMixin, timezone, validar_arquivo class AudienciaForm(FileFieldCheckMixin, forms.ModelForm): @@ -22,57 +22,83 @@ class AudienciaForm(FileFieldCheckMixin, forms.ModelForm): tipo = forms.ModelChoiceField( required=True, - label=_('Tipo de Audiência Pública'), - queryset=TipoAudienciaPublica.objects.all().order_by('nome')) + label=_("Tipo de Audiência Pública"), + queryset=TipoAudienciaPublica.objects.all().order_by("nome"), + ) tipo_materia = forms.ModelChoiceField( - label=_('Tipo Matéria'), + label=_("Tipo Matéria"), required=False, queryset=TipoMateriaLegislativa.objects.all(), - empty_label=_('Selecione')) + empty_label=_("Selecione"), + ) - numero_materia = forms.CharField( - label=_('Número Matéria'), - required=False) + numero_materia = forms.CharField(label=_("Número Matéria"), required=False) - ano_materia = forms.CharField( - label=_('Ano Matéria'), - required=False) + ano_materia = forms.CharField(label=_("Ano Matéria"), required=False) materia = forms.ModelChoiceField( required=False, widget=forms.HiddenInput(), - queryset=MateriaLegislativa.objects.all()) + queryset=MateriaLegislativa.objects.all(), + ) parlamentar_autor = forms.ModelChoiceField( - label=_("Parlamentar Autor"), - required=False, - queryset=Parlamentar.objects.all()) + label=_("Parlamentar Autor"), required=False, queryset=Parlamentar.objects.all() + ) requerimento = forms.ModelChoiceField( label=_("Requerimento"), required=False, - queryset=MateriaLegislativa.objects.select_related("tipo").filter(tipo__descricao="Requerimento")) + queryset=MateriaLegislativa.objects.select_related("tipo").filter( + tipo__descricao="Requerimento" + ), + ) class Meta: model = AudienciaPublica - fields = ['tipo', 'numero', 'ano', 'nome', - 'tema', 'data', 'hora_inicio', 'hora_fim', - 'observacao', 'audiencia_cancelada', 'parlamentar_autor', 'requerimento', 'url_audio', - 'url_video', 'upload_pauta', 'upload_ata', - 'upload_anexo', 'tipo_materia', 'numero_materia', - 'ano_materia', 'materia'] + fields = [ + "tipo", + "numero", + "ano", + "nome", + "tema", + "data", + "hora_inicio", + "hora_fim", + "observacao", + "audiencia_cancelada", + "parlamentar_autor", + "requerimento", + "url_audio", + "url_video", + "upload_pauta", + "upload_ata", + "upload_anexo", + "tipo_materia", + "numero_materia", + "ano_materia", + "materia", + ] def __init__(self, **kwargs): super(AudienciaForm, self).__init__(**kwargs) tipos = [] - if not self.fields['tipo'].queryset: - tipos.append(TipoAudienciaPublica.objects.create(nome='Audiência Pública', tipo='A')) - tipos.append(TipoAudienciaPublica.objects.create(nome='Plebiscito', tipo='P')) - tipos.append(TipoAudienciaPublica.objects.create(nome='Referendo', tipo='R')) - tipos.append(TipoAudienciaPublica.objects.create(nome='Iniciativa Popular', tipo='I')) + if not self.fields["tipo"].queryset: + tipos.append( + TipoAudienciaPublica.objects.create(nome="Audiência Pública", tipo="A") + ) + tipos.append( + TipoAudienciaPublica.objects.create(nome="Plebiscito", tipo="P") + ) + tipos.append( + TipoAudienciaPublica.objects.create(nome="Referendo", tipo="R") + ) + tipos.append( + TipoAudienciaPublica.objects.create(nome="Iniciativa Popular", tipo="I") + ) for t in tipos: t.save() @@ -82,95 +108,125 @@ class AudienciaForm(FileFieldCheckMixin, forms.ModelForm): if not self.is_valid(): return cleaned_data - materia = cleaned_data['numero_materia'] - ano_materia = cleaned_data['ano_materia'] - tipo_materia = cleaned_data['tipo_materia'] + materia = cleaned_data["numero_materia"] + ano_materia = cleaned_data["ano_materia"] + tipo_materia = cleaned_data["tipo_materia"] parlamentar_autor = cleaned_data["parlamentar_autor"] requerimento = cleaned_data["requerimento"] if cleaned_data["ano"] != cleaned_data["data"].year: - raise ValidationError(f"Ano da audiência ({cleaned_data['ano']}) difere " - f"do ano no campo data ({cleaned_data['data'].year})") + raise ValidationError( + f"Ano da audiência ({cleaned_data['ano']}) difere " + f"do ano no campo data ({cleaned_data['data'].year})" + ) # # TODO: converter hora_inicio e hora_fim para TimeField # # valida hora inicio try: - datetime.strptime(cleaned_data["hora_inicio"], '%H:%M').time() + datetime.strptime(cleaned_data["hora_inicio"], "%H:%M").time() except ValueError: - raise ValidationError(f"Formato de horário de início inválido: {cleaned_data['hora_inicio']}") + raise ValidationError( + f"Formato de horário de início inválido: {cleaned_data['hora_inicio']}" + ) # valida hora fim if cleaned_data["hora_fim"]: try: - datetime.strptime(cleaned_data["hora_fim"], '%H:%M').time() + datetime.strptime(cleaned_data["hora_fim"], "%H:%M").time() except ValueError: - raise ValidationError(f"Formato de horário de fim inválido: {cleaned_data['hora_fim']}") + raise ValidationError( + f"Formato de horário de fim inválido: {cleaned_data['hora_fim']}" + ) if materia and ano_materia and tipo_materia: try: - self.logger.debug("Tentando obter MateriaLegislativa %s nº %s/%s." % (tipo_materia, materia, ano_materia)) + self.logger.debug( + "Tentando obter MateriaLegislativa %s nº %s/%s." + % (tipo_materia, materia, ano_materia) + ) materia = MateriaLegislativa.objects.get( - numero=materia, - ano=ano_materia, - tipo=tipo_materia) + numero=materia, ano=ano_materia, tipo=tipo_materia + ) except ObjectDoesNotExist: - msg = _('A matéria %s nº %s/%s não existe no cadastro' - ' de matérias legislativas.' % (tipo_materia, materia, ano_materia)) + msg = _( + "A matéria %s nº %s/%s não existe no cadastro" + " de matérias legislativas." % (tipo_materia, materia, ano_materia) + ) self.logger.warning( - 'A MateriaLegislativa %s nº %s/%s não existe no cadastro' - ' de matérias legislativas.' % (tipo_materia, materia, ano_materia) + "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)) - cleaned_data['materia'] = materia + self.logger.info( + "MateriaLegislativa %s nº %s/%s obtida com sucesso." + % (tipo_materia, materia, ano_materia) + ) + cleaned_data["materia"] = materia else: campos = [materia, tipo_materia, ano_materia] - if campos.count(None) + campos.count('') < len(campos): - msg = _('Preencha todos os campos relacionados à Matéria Legislativa') + if campos.count(None) + campos.count("") < len(campos): + msg = _("Preencha todos os campos relacionados à Matéria Legislativa") self.logger.warning( - 'Algum campo relacionado à MatériaLegislativa %s nº %s/%s \ - não foi preenchido.' % (tipo_materia, materia, ano_materia) + "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']: - ultima_audiencia = AudienciaPublica.objects.all().order_by('ano', 'numero').last() + if not cleaned_data["numero"]: + ultima_audiencia = ( + AudienciaPublica.objects.all().order_by("ano", "numero").last() + ) if ultima_audiencia: - cleaned_data['numero'] = ultima_audiencia.numero + 1 + cleaned_data["numero"] = ultima_audiencia.numero + 1 else: - cleaned_data['numero'] = 1 + cleaned_data["numero"] = 1 else: - if AudienciaPublica.objects.filter(numero=cleaned_data['numero'], ano=cleaned_data['ano']).exclude(pk=self.instance.pk).exists(): - raise ValidationError(f"Já existe uma audiência pública com a numeração {str(cleaned_data['numero']).rjust(3, '0')}/{cleaned_data['ano']}.") + if ( + AudienciaPublica.objects.filter( + numero=cleaned_data["numero"], ano=cleaned_data["ano"] + ) + .exclude(pk=self.instance.pk) + .exists() + ): + raise ValidationError( + f"Já existe uma audiência pública com a numeração {str(cleaned_data['numero']).rjust(3, '0')}/{cleaned_data['ano']}." + ) - if self.cleaned_data['hora_inicio'] and self.cleaned_data['hora_fim']: - 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.warning( - 'Hora de fim anterior à hora de início.' + if self.cleaned_data["hora_inicio"] and self.cleaned_data["hora_fim"]: + 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.warning("Hora de fim anterior à hora de início.") raise ValidationError(msg) # requerimento é optativo if parlamentar_autor and requerimento: if parlamentar_autor.autor.first() not in requerimento.autores.all(): - raise ValidationError("Parlamentar Autor selecionado não faz" - " parte da autoria do Requerimento " - "selecionado.") + raise ValidationError( + "Parlamentar Autor selecionado não faz" + " parte da autoria do Requerimento " + "selecionado." + ) elif parlamentar_autor: - raise ValidationError("Para informar um autor deve-se informar um requerimento.") + raise ValidationError( + "Para informar um autor deve-se informar um requerimento." + ) elif requerimento: - raise ValidationError("Para informar um requerimento deve-se informar um autor.") + raise ValidationError( + "Para informar um requerimento deve-se informar um autor." + ) - - upload_pauta = self.cleaned_data.get('upload_pauta', False) - upload_ata = self.cleaned_data.get('upload_ata', False) - upload_anexo = self.cleaned_data.get('upload_anexo', False) + upload_pauta = self.cleaned_data.get("upload_pauta", False) + upload_ata = self.cleaned_data.get("upload_ata", False) + upload_anexo = self.cleaned_data.get("upload_anexo", False) if upload_pauta: validar_arquivo(upload_pauta, "Pauta da Audiência Pública") @@ -185,26 +241,20 @@ class AudienciaForm(FileFieldCheckMixin, forms.ModelForm): class AnexoAudienciaPublicaForm(forms.ModelForm): - class Meta: model = AnexoAudienciaPublica - fields = ['arquivo', - 'assunto'] + fields = ["arquivo", "assunto"] def __init__(self, *args, **kwargs): + row1 = to_row([("arquivo", 4)]) - row1 = to_row( - [('arquivo', 4)]) - - row2 = to_row( - [('assunto', 12)]) + row2 = to_row([("assunto", 12)]) self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout( - Fieldset(_('Identificação Básica'), - row1, row2)) - super(AnexoAudienciaPublicaForm, self).__init__( - *args, **kwargs) + Fieldset(_("Identificação Básica"), row1, row2) + ) + super(AnexoAudienciaPublicaForm, self).__init__(*args, **kwargs) def clean(self): super(AnexoAudienciaPublicaForm, self).clean() @@ -212,7 +262,7 @@ class AnexoAudienciaPublicaForm(forms.ModelForm): if not self.is_valid(): return self.cleaned_data - arquivo = self.cleaned_data.get('arquivo', False) + arquivo = self.cleaned_data.get("arquivo", False) if arquivo: validar_arquivo(arquivo, "Arquivo") diff --git a/sapl/audiencia/models.py b/sapl/audiencia/models.py index 1b265140c..0014b05c5 100755 --- a/sapl/audiencia/models.py +++ b/sapl/audiencia/models.py @@ -2,130 +2,147 @@ from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ from model_utils import Choices -from sapl.materia.models import MateriaLegislativa -from sapl.parlamentares.models import (CargoMesa, Parlamentar) -from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, SaplGenericRelation, - restringe_tipos_de_arquivo_txt, texto_upload_path, - OverwriteStorage) +from sapl.materia.models import MateriaLegislativa +from sapl.parlamentares.models import CargoMesa, Parlamentar +from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, OverwriteStorage, + SaplGenericRelation, restringe_tipos_de_arquivo_txt, + texto_upload_path) def get_audiencia_media_path(instance, subpath, filename): - return './sapl/audiencia/%s/%s/%s' % (instance.numero, subpath, filename) + return "./sapl/audiencia/%s/%s/%s" % (instance.numero, subpath, filename) def pauta_upload_path(instance, filename): - return texto_upload_path( - instance, filename, subpath='pauta', pk_first=True) + return texto_upload_path(instance, filename, subpath="pauta", pk_first=True) def ata_upload_path(instance, filename): - return texto_upload_path(instance, filename, subpath='ata', pk_first=True) + return texto_upload_path(instance, filename, subpath="ata", pk_first=True) def anexo_upload_path(instance, filename): - return texto_upload_path( - instance, filename, subpath='anexo', pk_first=True) + return texto_upload_path(instance, filename, subpath="anexo", pk_first=True) class TipoAudienciaPublica(models.Model): - TIPO_AUDIENCIA_CHOICES = Choices(('A', 'audiencia', _('Audiência Pública')), - ('P', 'plebiscito', _('Plebiscito')), - ('R', 'referendo', _('Referendo')), - ('I', 'iniciativa', _('Iniciativa Popular'))) + TIPO_AUDIENCIA_CHOICES = Choices( + ("A", "audiencia", _("Audiência Pública")), + ("P", "plebiscito", _("Plebiscito")), + ("R", "referendo", _("Referendo")), + ("I", "iniciativa", _("Iniciativa Popular")), + ) nome = models.CharField( - max_length=50, verbose_name=_('Nome do Tipo de Audiência Pública'), default='Audiência Pública') + max_length=50, + verbose_name=_("Nome do Tipo de Audiência Pública"), + default="Audiência Pública", + ) tipo = models.CharField( - max_length=1, verbose_name=_('Tipo de Audiência Pública'), choices=TIPO_AUDIENCIA_CHOICES, default='A') + max_length=1, + verbose_name=_("Tipo de Audiência Pública"), + choices=TIPO_AUDIENCIA_CHOICES, + default="A", + ) class Meta: - verbose_name = _('Tipo de Audiência Pública') - verbose_name_plural = _('Tipos de Audiência Pública') - ordering = ['nome'] + verbose_name = _("Tipo de Audiência Pública") + verbose_name_plural = _("Tipos de Audiência Pública") + ordering = ["nome"] def __str__(self): return self.nome class AudienciaPublica(models.Model): - materia = models.ForeignKey( MateriaLegislativa, on_delete=models.PROTECT, null=True, blank=True, - verbose_name=_('Matéria Legislativa')) - tipo = models.ForeignKey(TipoAudienciaPublica, - on_delete=models.PROTECT, - null=True, - blank=True, - verbose_name=_('Tipo de Audiência Pública')) - numero = models.PositiveIntegerField(blank=True, verbose_name=_('Número')) - ano = models.PositiveSmallIntegerField(verbose_name=_('Ano'), - choices=RANGE_ANOS) - nome = models.CharField( - max_length=100, verbose_name=_('Nome da Audiência Pública')) - tema = models.CharField( - max_length=100, verbose_name=_('Tema da Audiência Pública')) - data = models.DateField(verbose_name=_('Data')) + verbose_name=_("Matéria Legislativa"), + ) + tipo = models.ForeignKey( + TipoAudienciaPublica, + on_delete=models.PROTECT, + null=True, + blank=True, + verbose_name=_("Tipo de Audiência Pública"), + ) + numero = models.PositiveIntegerField(blank=True, verbose_name=_("Número")) + ano = models.PositiveSmallIntegerField(verbose_name=_("Ano"), choices=RANGE_ANOS) + nome = models.CharField(max_length=100, verbose_name=_("Nome da Audiência Pública")) + tema = models.CharField(max_length=100, verbose_name=_("Tema da Audiência Pública")) + data = models.DateField(verbose_name=_("Data")) hora_inicio = models.CharField( - max_length=5, verbose_name=_('Horário Início(hh:mm)')) + max_length=5, verbose_name=_("Horário Início(hh:mm)") + ) hora_fim = models.CharField( - max_length=5, blank=True, verbose_name=_('Horário Fim(hh:mm)')) + max_length=5, blank=True, verbose_name=_("Horário Fim(hh:mm)") + ) observacao = models.TextField( - max_length=500, blank=True, verbose_name=_('Observação')) + max_length=500, blank=True, verbose_name=_("Observação") + ) audiencia_cancelada = models.BooleanField( - default=False, - choices=YES_NO_CHOICES, - verbose_name=_('Audiência Cancelada?')) + default=False, choices=YES_NO_CHOICES, verbose_name=_("Audiência Cancelada?") + ) parlamentar_autor = models.ForeignKey( Parlamentar, on_delete=models.PROTECT, null=True, blank=True, - verbose_name=_('Parlamentar Autor')) + verbose_name=_("Parlamentar Autor"), + ) requerimento = models.ForeignKey( MateriaLegislativa, null=True, blank=True, on_delete=models.PROTECT, - verbose_name=_('Requerimento da Audiência Pública'), - related_name=_('requerimento')) + verbose_name=_("Requerimento da Audiência Pública"), + related_name=_("requerimento"), + ) url_audio = models.URLField( - max_length=150, blank=True, - verbose_name=_('URL Arquivo Áudio (Formatos MP3 / AAC)')) + max_length=150, + blank=True, + verbose_name=_("URL Arquivo Áudio (Formatos MP3 / AAC)"), + ) url_video = models.URLField( - max_length=150, blank=True, - verbose_name=_('URL Arquivo Vídeo (Formatos MP4 / FLV / WebM)')) + max_length=150, + blank=True, + verbose_name=_("URL Arquivo Vídeo (Formatos MP4 / FLV / WebM)"), + ) upload_pauta = models.FileField( max_length=300, blank=True, null=True, upload_to=pauta_upload_path, storage=OverwriteStorage(), - verbose_name=_('Pauta da Audiência Pública'), - validators=[restringe_tipos_de_arquivo_txt]) + verbose_name=_("Pauta da Audiência Pública"), + validators=[restringe_tipos_de_arquivo_txt], + ) upload_ata = models.FileField( max_length=300, blank=True, null=True, upload_to=ata_upload_path, - verbose_name=_('Ata da Audiência Pública'), + verbose_name=_("Ata da Audiência Pública"), storage=OverwriteStorage(), - validators=[restringe_tipos_de_arquivo_txt]) + validators=[restringe_tipos_de_arquivo_txt], + ) upload_anexo = models.FileField( max_length=300, blank=True, null=True, upload_to=anexo_upload_path, storage=OverwriteStorage(), - verbose_name=_('Anexo da Audiência Pública')) + verbose_name=_("Anexo da Audiência Pública"), + ) class Meta: - verbose_name = _('Audiência Pública') - verbose_name_plural = _('Audiências Públicas') - ordering = ['ano', 'numero', 'nome', 'tipo'] + verbose_name = _("Audiência Pública") + verbose_name_plural = _("Audiências Públicas") + ordering = ["ano", "numero", "nome", "tipo"] def __str__(self): return self.nome @@ -148,49 +165,52 @@ class AudienciaPublica(models.Model): return result - 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): + 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): upload_pauta = self.upload_pauta upload_ata = self.upload_ata upload_anexo = self.upload_anexo self.upload_pauta = None self.upload_ata = None self.upload_anexo = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.upload_pauta = upload_pauta self.upload_ata = upload_ata self.upload_anexo = upload_anexo - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) class AnexoAudienciaPublica(models.Model): - audiencia = models.ForeignKey(AudienciaPublica, - on_delete=models.PROTECT) + audiencia = models.ForeignKey(AudienciaPublica, on_delete=models.PROTECT) arquivo = models.FileField( max_length=300, upload_to=texto_upload_path, storage=OverwriteStorage(), - verbose_name=_('Arquivo')) - data = models.DateField( - auto_now=timezone.now) - assunto = models.TextField( - verbose_name=_('Assunto')) + verbose_name=_("Arquivo"), + ) + data = models.DateField(auto_now=timezone.now) + assunto = models.TextField(verbose_name=_("Assunto")) class Meta: - verbose_name = _('Anexo de Documento Acessório') - verbose_name_plural = _('Anexo de Documentos Acessórios') - ordering = ('id',) + verbose_name = _("Anexo de Documento Acessório") + verbose_name_plural = _("Anexo de Documentos Acessórios") + ordering = ("id",) def __str__(self): return self.assunto @@ -204,7 +224,9 @@ class AnexoAudienciaPublica(models.Model): return result - def save(self, force_insert=False, force_update=False, using=None, update_fields=None): + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): if not self.pk and self.arquivo: arquivo = self.arquivo self.arquivo = None @@ -213,8 +235,14 @@ class AnexoAudienciaPublica(models.Model): force_insert=force_insert, force_update=force_update, using=using, - update_fields=update_fields) + update_fields=update_fields, + ) self.arquivo = arquivo - return models.Model.save(self, force_insert=force_insert, force_update=force_update, using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) diff --git a/sapl/audiencia/tests/test_audiencia.py b/sapl/audiencia/tests/test_audiencia.py index 62aae2b0b..8274c7fb3 100644 --- a/sapl/audiencia/tests/test_audiencia.py +++ b/sapl/audiencia/tests/test_audiencia.py @@ -1,57 +1,59 @@ -import pytest import datetime -from model_bakery import baker + +import pytest from django.utils.translation import gettext as _ +from model_bakery import baker from sapl.audiencia import forms -from sapl.audiencia.models import AnexoAudienciaPublica -from sapl.audiencia.models import TipoAudienciaPublica, AudienciaPublica +from sapl.audiencia.models import (AnexoAudienciaPublica, AudienciaPublica, + TipoAudienciaPublica) from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa @pytest.mark.django_db(transaction=False) def test_tipo_audiencia_publica_model(): - baker.make(TipoAudienciaPublica, - nome='Teste_Nome_Tipo_Audiencia_Publica', - tipo='A') + baker.make(TipoAudienciaPublica, nome="Teste_Nome_Tipo_Audiencia_Publica", tipo="A") tipo_audiencia_publica = TipoAudienciaPublica.objects.first() - assert tipo_audiencia_publica.nome == 'Teste_Nome_Tipo_Audiencia_Publica' - assert tipo_audiencia_publica.tipo == 'A' + assert tipo_audiencia_publica.nome == "Teste_Nome_Tipo_Audiencia_Publica" + assert tipo_audiencia_publica.tipo == "A" @pytest.mark.django_db(transaction=False) def test_audiencia_publica_model(): - baker.make(AudienciaPublica, - numero=1, - nome='Teste_Nome_Audiencia_Publica', - tema='Teste_Tema_Audiencia_Publica', - data='2016-03-21', - hora_inicio='16:03') + baker.make( + AudienciaPublica, + numero=1, + nome="Teste_Nome_Audiencia_Publica", + tema="Teste_Tema_Audiencia_Publica", + data="2016-03-21", + hora_inicio="16:03", + ) audiencia_publica = AudienciaPublica.objects.first() - data = '2016-03-21' + data = "2016-03-21" teste_data = datetime.datetime.strptime(data, "%Y-%m-%d").date() assert audiencia_publica.numero == 1 - assert audiencia_publica.nome == 'Teste_Nome_Audiencia_Publica' - assert audiencia_publica.tema == 'Teste_Tema_Audiencia_Publica' + assert audiencia_publica.nome == "Teste_Nome_Audiencia_Publica" + assert audiencia_publica.tema == "Teste_Tema_Audiencia_Publica" assert audiencia_publica.data == teste_data - assert audiencia_publica.hora_inicio == '16:03' + assert audiencia_publica.hora_inicio == "16:03" @pytest.mark.django_db(transaction=False) def test_anexo_audiencia_publica_model(): - audiencia = baker.make(AudienciaPublica, - numero=2, - nome='Nome_Audiencia_Publica', - tema='Tema_Audiencia_Publica', - data='2017-04-22', - hora_inicio='17:04') + audiencia = baker.make( + AudienciaPublica, + numero=2, + nome="Nome_Audiencia_Publica", + tema="Tema_Audiencia_Publica", + data="2017-04-22", + hora_inicio="17:04", + ) - baker.make(AnexoAudienciaPublica, - audiencia=audiencia) + baker.make(AnexoAudienciaPublica, audiencia=audiencia) anexo_audiencia_publica = AnexoAudienciaPublica.objects.first() assert anexo_audiencia_publica.audiencia == audiencia @@ -65,11 +67,11 @@ def test_valida_campos_obrigatorios_audiencia_form(): errors = form.errors - assert errors['nome'] == [_('Este campo é obrigatório.')] - assert errors['tema'] == [_('Este campo é obrigatório.')] - assert errors['tipo'] == [_('Este campo é obrigatório.')] - assert errors['data'] == [_('Este campo é obrigatório.')] - assert errors['hora_inicio'] == [_('Este campo é obrigatório.')] + assert errors["nome"] == [_("Este campo é obrigatório.")] + assert errors["tema"] == [_("Este campo é obrigatório.")] + assert errors["tipo"] == [_("Este campo é obrigatório.")] + assert errors["data"] == [_("Este campo é obrigatório.")] + assert errors["hora_inicio"] == [_("Este campo é obrigatório.")] assert len(errors) == 6 @@ -80,11 +82,14 @@ def test_audiencia_form_hora_invalida(): tipo = baker.make(TipoAudienciaPublica) - form = forms.AudienciaForm(data={'nome': 'Nome da Audiencia', - 'tema': 'Tema da Audiencia', - 'tipo': tipo, - 'data': '2016-10-01', - 'hora_inicio': '10:00', - 'hora_fim': '9:00', - }) + form = forms.AudienciaForm( + data={ + "nome": "Nome da Audiencia", + "tema": "Tema da Audiencia", + "tipo": tipo, + "data": "2016-10-01", + "hora_inicio": "10:00", + "hora_fim": "9:00", + } + ) assert not form.is_valid() diff --git a/sapl/audiencia/urls.py b/sapl/audiencia/urls.py index 94064b9e9..486e9b2d0 100755 --- a/sapl/audiencia/urls.py +++ b/sapl/audiencia/urls.py @@ -1,10 +1,15 @@ from django.urls import include, path -from sapl.audiencia.views import (index, AudienciaCrud, AnexoAudienciaPublicaCrud) + +from sapl.audiencia.views import (AnexoAudienciaPublicaCrud, AudienciaCrud, + index) from .apps import AppConfig app_name = AppConfig.name urlpatterns = [ - path('audiencia/', include(AudienciaCrud.get_urls() + AnexoAudienciaPublicaCrud.get_urls())), -] \ No newline at end of file + path( + "audiencia/", + include(AudienciaCrud.get_urls() + AnexoAudienciaPublicaCrud.get_urls()), + ), +] diff --git a/sapl/audiencia/views.py b/sapl/audiencia/views.py index 443fc81e8..5cf8cb3f6 100755 --- a/sapl/audiencia/views.py +++ b/sapl/audiencia/views.py @@ -1,13 +1,13 @@ -import sapl - from django.http import HttpResponse from django.urls import reverse from django.views.decorators.clickjacking import xframe_options_exempt from django.views.generic import UpdateView + +import sapl from sapl.crud.base import RP_DETAIL, RP_LIST, Crud, MasterDetailCrud -from .forms import AudienciaForm, AnexoAudienciaPublicaForm -from .models import AudienciaPublica, AnexoAudienciaPublica +from .forms import AnexoAudienciaPublicaForm, AudienciaForm +from .models import AnexoAudienciaPublica, AudienciaPublica def index(request): @@ -16,11 +16,14 @@ def index(request): class AudienciaCrud(Crud): model = AudienciaPublica - public = [RP_LIST, RP_DETAIL, ] + public = [ + RP_LIST, + RP_DETAIL, + ] class BaseMixin(Crud.BaseMixin): - list_field_names = ['numero', 'nome', 'tipo', 'materia', 'data'] - ordering = '-ano', '-numero', '-data', 'nome', 'tipo' + list_field_names = ["numero", "nome", "tipo", "materia", "data"] + ordering = "-ano", "-numero", "-data", "nome", "tipo" class ListView(Crud.ListView): paginate_by = 10 @@ -28,20 +31,32 @@ class AudienciaCrud(Crud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - audiencia_materia = {str(a.id): (a.materia, a.numero, a.ano) for a in context['object_list']} - - for row in context['rows']: - audiencia_id = row[0][1].split('/')[-1] - tema = str(audiencia_materia[audiencia_id][1]).rjust(3, '0') + '/' + str(audiencia_materia[audiencia_id][2]) + audiencia_materia = { + str(a.id): (a.materia, a.numero, a.ano) for a in context["object_list"] + } + + for row in context["rows"]: + audiencia_id = row[0][1].split("/")[-1] + tema = ( + str(audiencia_materia[audiencia_id][1]).rjust(3, "0") + + "/" + + str(audiencia_materia[audiencia_id][2]) + ) row[0] = (tema, row[0][1]) - coluna_materia = row[3] # Se mudar a ordem de listagem, mudar aqui. + coluna_materia = row[3] # Se mudar a ordem de listagem, mudar aqui. if coluna_materia[0]: materia = audiencia_materia[audiencia_id][0] if materia is not None: - url_materia = reverse('sapl.materia:materialegislativa_detail', kwargs={'pk': materia.id}) + url_materia = reverse( + "sapl.materia:materialegislativa_detail", + kwargs={"pk": materia.id}, + ) else: url_materia = None - row[3] = (coluna_materia[0], url_materia) # Se mudar a ordem de listagem, mudar aqui. + row[3] = ( + coluna_materia[0], + url_materia, + ) # Se mudar a ordem de listagem, mudar aqui. return context class CreateView(Crud.CreateView): @@ -56,17 +71,16 @@ class AudienciaCrud(Crud): def get_initial(self): initial = super(UpdateView, self).get_initial() if self.object.materia: - initial['tipo_materia'] = self.object.materia.tipo.id - initial['numero_materia'] = self.object.materia.numero - initial['ano_materia'] = self.object.materia.ano + initial["tipo_materia"] = self.object.materia.tipo.id + initial["numero_materia"] = self.object.materia.numero + initial["ano_materia"] = self.object.materia.ano return initial - + class DeleteView(Crud.DeleteView): pass class DetailView(Crud.DetailView): - - layout_key = 'AudienciaPublicaDetail' + layout_key = "AudienciaPublicaDetail" @xframe_options_exempt def get(self, request, *args, **kwargs): @@ -74,10 +88,9 @@ class AudienciaCrud(Crud): class AudienciaPublicaMixin: - def has_permission(self): app_config = sapl.base.models.AppConfig.objects.last() - if app_config and app_config.documentos_administrativos == 'O': + if app_config and app_config.documentos_administrativos == "O": return True return super().has_permission() @@ -85,12 +98,15 @@ class AudienciaPublicaMixin: class AnexoAudienciaPublicaCrud(MasterDetailCrud): model = AnexoAudienciaPublica - parent_field = 'audiencia' - help_topic = 'numeracao_docsacess' - public = [RP_LIST, RP_DETAIL, ] + parent_field = "audiencia" + help_topic = "numeracao_docsacess" + public = [ + RP_LIST, + RP_DETAIL, + ] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['assunto'] + list_field_names = ["assunto"] class CreateView(MasterDetailCrud.CreateView): form_class = AnexoAudienciaPublicaForm @@ -100,11 +116,10 @@ class AnexoAudienciaPublicaCrud(MasterDetailCrud): form_class = AnexoAudienciaPublicaForm class ListView(AudienciaPublicaMixin, MasterDetailCrud.ListView): - def get_queryset(self): qs = super(MasterDetailCrud.ListView, self).get_queryset() - kwargs = {self.crud.parent_field: self.kwargs['pk']} - return qs.filter(**kwargs).order_by('-data', '-id') + kwargs = {self.crud.parent_field: self.kwargs["pk"]} + return qs.filter(**kwargs).order_by("-data", "-id") class DetailView(AudienciaPublicaMixin, MasterDetailCrud.DetailView): pass diff --git a/sapl/base/admin.py b/sapl/base/admin.py index 9289254b3..6c1bdb7cb 100644 --- a/sapl/base/admin.py +++ b/sapl/base/admin.py @@ -7,8 +7,8 @@ from sapl.utils import register_all_models_in_admin register_all_models_in_admin(__name__) -admin.site.site_title = 'Administração - SAPL' -admin.site.site_header = 'Administração - SAPL' +admin.site.site_title = "Administração - SAPL" +admin.site.site_header = "Administração - SAPL" class AuditLogAdmin(admin.ModelAdmin): diff --git a/sapl/base/apps.py b/sapl/base/apps.py index b362fbda3..685b4d835 100644 --- a/sapl/base/apps.py +++ b/sapl/base/apps.py @@ -1,12 +1,11 @@ - import django from django.utils.translation import gettext_lazy as _ class AppConfig(django.apps.AppConfig): - name = 'sapl.base' - label = 'base' - verbose_name = _('Dados Básicos') + name = "sapl.base" + label = "base" + verbose_name = _("Dados Básicos") def ready(self): from sapl.base import receivers diff --git a/sapl/base/email_utils.py b/sapl/base/email_utils.py index 86a251079..f329451a1 100644 --- a/sapl/base/email_utils.py +++ b/sapl/base/email_utils.py @@ -1,71 +1,75 @@ -from datetime import datetime as dt import logging +from datetime import datetime as dt from django.core.mail import EmailMultiAlternatives, get_connection, send_mail -from django.urls import reverse from django.template import Context, loader +from django.urls import reverse from django.utils import timezone +from django.utils.translation import gettext_lazy as _ from sapl.base.models import CasaLegislativa from sapl.materia.models import AcompanhamentoMateria from sapl.protocoloadm.models import AcompanhamentoDocumento from sapl.settings import EMAIL_SEND_USER from sapl.utils import mail_service_configured -from django.utils.translation import gettext_lazy as _ def load_email_templates(templates, context={}): - emails = [] for t in templates: tpl = loader.get_template(t) email = tpl.render(context) if t.endswith(".html"): - email = email.replace('\\n', '').replace('\r', '') + email = email.replace("\\n", "").replace("\r", "") emails.append(email) return emails def enviar_emails(sender, recipients, messages): - ''' - Recipients is a string list of email addresses - - Messages is an array of dicts of the form: - {'recipient': 'address', # useless???? - 'subject': 'subject text', - 'txt_message': 'text message', - 'html_message': 'html message' - } - ''' + """ + Recipients is a string list of email addresses + + Messages is an array of dicts of the form: + {'recipient': 'address', # useless???? + 'subject': 'subject text', + 'txt_message': 'text message', + 'html_message': 'html message' + } + """ if len(messages) == 1: # sends an email simultaneously to all recipients - send_mail(messages[0]['subject'], - messages[0]['txt_message'], - sender, - recipients, - html_message=messages[0]['html_message'], - fail_silently=False) + send_mail( + messages[0]["subject"], + messages[0]["txt_message"], + sender, + recipients, + html_message=messages[0]["html_message"], + fail_silently=False, + ) elif len(recipients) > len(messages): - raise ValueError("Message list should have size 1 \ + raise ValueError( + "Message list should have size 1 \ or equal recipient list size. \ - recipients: %s, messages: %s" % (recipients, messages) - ) + recipients: %s, messages: %s" + % (recipients, messages) + ) else: # sends an email simultaneously to all reciepients - for (d, m) in zip(recipients, messages): - send_mail(m['subject'], - m['txt_message'], - sender, - [d], - html_message=m['html_message'], - fail_silently=False) - + for d, m in zip(recipients, messages): + send_mail( + m["subject"], + m["txt_message"], + sender, + [d], + html_message=m["html_message"], + fail_silently=False, + ) -def criar_email_confirmacao(base_url, casa_legislativa, doc_mat, tipo, hash_txt=''): +def criar_email_confirmacao(base_url, casa_legislativa, doc_mat, tipo, hash_txt=""): if not casa_legislativa: raise ValueError("Casa Legislativa é obrigatória") @@ -77,36 +81,44 @@ def criar_email_confirmacao(base_url, casa_legislativa, doc_mat, tipo, hash_txt= raise ValueError(msg) # FIXME i18n - casa_nome = ("{} de {} - {}".format(casa_legislativa.nome, - casa_legislativa.municipio, - casa_legislativa.uf)) + casa_nome = "{} de {} - {}".format( + casa_legislativa.nome, casa_legislativa.municipio, casa_legislativa.uf + ) if tipo == "materia": - doc_mat_url = reverse('sapl.materia:materialegislativa_detail', - kwargs={'pk': doc_mat.id}) - confirmacao_url = reverse('sapl.materia:acompanhar_confirmar', - kwargs={'pk': doc_mat.id}) + doc_mat_url = reverse( + "sapl.materia:materialegislativa_detail", kwargs={"pk": doc_mat.id} + ) + confirmacao_url = reverse( + "sapl.materia:acompanhar_confirmar", kwargs={"pk": doc_mat.id} + ) ementa = doc_mat.ementa autores = [autoria.autor.nome for autoria in doc_mat.autoria_set.all()] else: - doc_mat_url = reverse('sapl.protocoloadm:documentoadministrativo_detail', - kwargs={'pk': doc_mat.id}) - confirmacao_url = reverse('sapl.protocoloadm:acompanhar_confirmar', - kwargs={'pk': doc_mat.id}) + doc_mat_url = reverse( + "sapl.protocoloadm:documentoadministrativo_detail", + kwargs={"pk": doc_mat.id}, + ) + confirmacao_url = reverse( + "sapl.protocoloadm:acompanhar_confirmar", kwargs={"pk": doc_mat.id} + ) ementa = doc_mat.assunto autores = "" - templates = load_email_templates(['email/acompanhar.txt', - 'email/acompanhar.html'], - {"casa_legislativa": casa_nome, - "logotipo": casa_legislativa.logotipo, - "descricao_materia": ementa, - "autoria": autores, - "hash_txt": hash_txt, - "base_url": base_url, - "materia": str(doc_mat), - "materia_url": doc_mat_url, - "confirmacao_url": confirmacao_url, }) + templates = load_email_templates( + ["email/acompanhar.txt", "email/acompanhar.html"], + { + "casa_legislativa": casa_nome, + "logotipo": casa_legislativa.logotipo, + "descricao_materia": ementa, + "autoria": autores, + "hash_txt": hash_txt, + "base_url": base_url, + "materia": str(doc_mat), + "materia_url": doc_mat_url, + "confirmacao_url": confirmacao_url, + }, + ) return templates @@ -117,7 +129,7 @@ def do_envia_email_confirmacao(base_url, casa, tipo, doc_mat, destinatario): if not mail_service_configured(): logger = logging.getLogger(__name__) - logger.warning(_('Servidor de email não configurado.')) + logger.warning(_("Servidor de email não configurado.")) return sender = EMAIL_SEND_USER @@ -130,25 +142,29 @@ def do_envia_email_confirmacao(base_url, casa, tipo, doc_mat, destinatario): messages = [] recipients = [] - email_texts = criar_email_confirmacao(base_url, - casa, - doc_mat, - tipo, - destinatario.hash,) + email_texts = criar_email_confirmacao( + base_url, + casa, + doc_mat, + tipo, + destinatario.hash, + ) recipients.append(destinatario.email) - messages.append({ - 'recipient': destinatario.email, - 'subject': subject, - 'txt_message': email_texts[0], - 'html_message': email_texts[1] - }) + messages.append( + { + "recipient": destinatario.email, + "subject": subject, + "txt_message": email_texts[0], + "html_message": email_texts[1], + } + ) enviar_emails(sender, recipients, messages) -def criar_email_tramitacao(base_url, casa_legislativa, tipo, doc_mat, status, - unidade_destino, hash_txt=''): - +def criar_email_tramitacao( + base_url, casa_legislativa, tipo, doc_mat, status, unidade_destino, hash_txt="" +): if not casa_legislativa: raise ValueError("Casa Legislativa é obrigatória") @@ -160,47 +176,50 @@ def criar_email_tramitacao(base_url, casa_legislativa, tipo, doc_mat, status, raise ValueError(msg) # FIXME i18n - casa_nome = ("{} de {} - {}".format(casa_legislativa.nome, - casa_legislativa.municipio, - casa_legislativa.uf)) + casa_nome = "{} de {} - {}".format( + casa_legislativa.nome, casa_legislativa.municipio, casa_legislativa.uf + ) if tipo == "materia": - doc_mat_url = reverse('sapl.materia:tramitacao_list', - kwargs={'pk': doc_mat.id}) - url_excluir = reverse('sapl.materia:acompanhar_excluir', - kwargs={'pk': doc_mat.id}) + doc_mat_url = reverse("sapl.materia:tramitacao_list", kwargs={"pk": doc_mat.id}) + url_excluir = reverse( + "sapl.materia:acompanhar_excluir", kwargs={"pk": doc_mat.id} + ) ementa = doc_mat.ementa autores = [autoria.autor.nome for autoria in doc_mat.autoria_set.all()] - tramitacao = doc_mat.tramitacao_set.order_by('-data_tramitacao', '-id').first() + tramitacao = doc_mat.tramitacao_set.order_by("-data_tramitacao", "-id").first() else: - doc_mat_url = reverse('sapl.protocoloadm:tramitacaoadministrativo_list', - kwargs={'pk': doc_mat.id}) - url_excluir = reverse('sapl.protocoloadm:acompanhar_excluir', - kwargs={'pk': doc_mat.id}) + doc_mat_url = reverse( + "sapl.protocoloadm:tramitacaoadministrativo_list", kwargs={"pk": doc_mat.id} + ) + url_excluir = reverse( + "sapl.protocoloadm:acompanhar_excluir", kwargs={"pk": doc_mat.id} + ) autores = "" ementa = doc_mat.assunto tramitacao = doc_mat.tramitacaoadministrativo_set.last() - templates = load_email_templates(['email/tramitacao.txt', - 'email/tramitacao.html'], - {"casa_legislativa": casa_nome, - "data_registro": dt.strftime( - timezone.now(), - "%d/%m/%Y"), - "cod_materia": doc_mat.id, - "logotipo": casa_legislativa.logotipo, - "descricao_materia": ementa, - "autoria": autores, - "data": tramitacao.data_tramitacao, - "status": status, - "localizacao": unidade_destino, - "texto_acao": tramitacao.texto, - "hash_txt": hash_txt, - "materia": str(doc_mat), - "base_url": base_url, - "materia_url": doc_mat_url, - "excluir_url": url_excluir}) + templates = load_email_templates( + ["email/tramitacao.txt", "email/tramitacao.html"], + { + "casa_legislativa": casa_nome, + "data_registro": dt.strftime(timezone.now(), "%d/%m/%Y"), + "cod_materia": doc_mat.id, + "logotipo": casa_legislativa.logotipo, + "descricao_materia": ementa, + "autoria": autores, + "data": tramitacao.data_tramitacao, + "status": status, + "localizacao": unidade_destino, + "texto_acao": tramitacao.texto, + "hash_txt": hash_txt, + "materia": str(doc_mat), + "base_url": base_url, + "materia_url": doc_mat_url, + "excluir_url": url_excluir, + }, + ) return templates @@ -211,18 +230,20 @@ def do_envia_email_tramitacao(base_url, tipo, doc_mat, status, unidade_destino): logger = logging.getLogger(__name__) if not mail_service_configured(): - logger.warning(_('Servidor de email não configurado.')) + logger.warning(_("Servidor de email não configurado.")) return if tipo == "materia": - destinatarios = AcompanhamentoMateria.objects.filter(materia=doc_mat, - confirmado=True) + destinatarios = AcompanhamentoMateria.objects.filter( + materia=doc_mat, confirmado=True + ) else: - destinatarios = AcompanhamentoDocumento.objects.filter(documento=doc_mat, - confirmado=True) + destinatarios = AcompanhamentoDocumento.objects.filter( + documento=doc_mat, confirmado=True + ) if not destinatarios: - logger.debug(_('Não existem destinatários cadastrados para essa matéria.')) + logger.debug(_("Não existem destinatários cadastrados para essa matéria.")) return casa = CasaLegislativa.objects.first() @@ -240,20 +261,23 @@ def do_envia_email_tramitacao(base_url, tipo, doc_mat, status, unidade_destino): for destinatario in destinatarios: try: - email_texts = criar_email_tramitacao(base_url, - casa, - tipo, - doc_mat, - status, - unidade_destino, - destinatario.hash) + email_texts = criar_email_tramitacao( + base_url, + casa, + tipo, + doc_mat, + status, + unidade_destino, + destinatario.hash, + ) email = EmailMultiAlternatives( subject, email_texts[0], sender, [destinatario.email], - connection=connection) + connection=connection, + ) email.attach_alternative(email_texts[1], "text/html") email.send() @@ -261,7 +285,6 @@ def do_envia_email_tramitacao(base_url, tipo, doc_mat, status, unidade_destino): # a conexão será fechada except Exception: connection.close() - raise Exception( - 'Erro ao enviar e-mail de acompanhamento de matéria.') + raise Exception("Erro ao enviar e-mail de acompanhamento de matéria.") connection.close() diff --git a/sapl/base/forms.py b/sapl/base/forms.py index aeaa2f1c0..d90e61b56 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -1,15 +1,18 @@ import logging import os -from crispy_forms.bootstrap import FieldWithButtons, InlineRadios, StrictButton, FormActions +import django_filters +from crispy_forms.bootstrap import (FieldWithButtons, FormActions, + InlineRadios, StrictButton) from crispy_forms.helper import FormHelper -from crispy_forms.layout import HTML, Button, Div, Field, Fieldset, Layout, Row, Submit +from crispy_forms.layout import (HTML, Button, Div, Field, Fieldset, Layout, + Row, Submit) from django import forms from django.conf import settings from django.contrib.auth import get_user_model, password_validation from django.contrib.auth.forms import (AuthenticationForm, PasswordResetForm, SetPasswordForm) -from django.contrib.auth.models import Group, User, Permission +from django.contrib.auth.models import Group, Permission, User from django.core.exceptions import ValidationError from django.db import models, transaction from django.db.models import Q @@ -17,146 +20,153 @@ from django.forms import Form, ModelForm from django.utils import timezone from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ -import django_filters from haystack.forms import ModelSearchForm from sapl.audiencia.models import AudienciaPublica -from sapl.base.models import Autor, AuditLog, TipoAutor, OperadorAutor +from sapl.base.models import AuditLog, Autor, OperadorAutor, TipoAutor from sapl.comissoes.models import Reuniao -from sapl.crispy_layout_mixin import (form_actions, to_column, to_row, - SaplFormHelper, SaplFormLayout) +from sapl.crispy_layout_mixin import (SaplFormHelper, SaplFormLayout, + form_actions, to_column, to_row) from sapl.materia.models import (DocumentoAcessorio, MateriaEmTramitacao, - MateriaLegislativa, UnidadeTramitacao, - StatusTramitacao) -from sapl.norma.models import NormaJuridica, NormaEstatisticas -from sapl.parlamentares.models import Partido, SessaoLegislativa, \ - Parlamentar, Votante + MateriaLegislativa, StatusTramitacao, + UnidadeTramitacao) +from sapl.norma.models import NormaEstatisticas, NormaJuridica +from sapl.parlamentares.models import (Parlamentar, Partido, SessaoLegislativa, + Votante) from sapl.protocoloadm.models import DocumentoAdministrativo from sapl.rules import SAPL_GROUP_AUTOR, SAPL_GROUP_VOTANTE from sapl.sessao.models import SessaoPlenaria from sapl.settings import MAX_IMAGE_UPLOAD_SIZE -from sapl.utils import (autor_label, autor_modal, ChoiceWithoutValidationField, - choice_anos_com_normas, choice_anos_com_materias, - FilterOverridesMetaMixin, FileFieldCheckMixin, - ImageThumbnailFileInput, qs_override_django_filter, - RANGE_ANOS, YES_NO_CHOICES, choice_tipos_normas, - GoogleRecapthaMixin, parlamentares_ativos, RANGE_MESES, is_weak_password, delete_cached_entry) +from sapl.utils import (RANGE_ANOS, RANGE_MESES, YES_NO_CHOICES, + ChoiceWithoutValidationField, FileFieldCheckMixin, + FilterOverridesMetaMixin, GoogleRecapthaMixin, + ImageThumbnailFileInput, autor_label, autor_modal, + choice_anos_com_materias, choice_anos_com_normas, + choice_tipos_normas, delete_cached_entry, + is_weak_password, parlamentares_ativos, + qs_override_django_filter) from .models import AppConfig, CasaLegislativa ACTION_CREATE_USERS_AUTOR_CHOICE = [ - ('A', _('Associar um usuário existente')), - ('N', _('Autor sem Usuário de Acesso ao Sapl')), + ("A", _("Associar um usuário existente")), + ("N", _("Autor sem Usuário de Acesso ao Sapl")), ] STATUS_USER_CHOICE = [ - ('R', _('Apenas retirar Perfil de Autor do Usuário que está sendo' - ' desvinculado')), - ('D', _('Retirar Perfil de Autor e desativar Usuário que está sendo' - ' desvinculado')), - ('X', _('Excluir Usuário')), + ( + "R", + _("Apenas retirar Perfil de Autor do Usuário que está sendo" " desvinculado"), + ), + ( + "D", + _("Retirar Perfil de Autor e desativar Usuário que está sendo" " desvinculado"), + ), + ("X", _("Excluir Usuário")), ] class UserAdminForm(ModelForm): - is_active = forms.TypedChoiceField(label=_('Usuário Ativo'), - choices=YES_NO_CHOICES, - coerce=lambda x: x == 'True') + is_active = forms.TypedChoiceField( + label=_("Usuário Ativo"), choices=YES_NO_CHOICES, coerce=lambda x: x == "True" + ) new_password1 = forms.CharField( - label='Nova senha', + label="Nova senha", max_length=50, strip=False, required=False, widget=forms.PasswordInput(), - help_text='Deixe os campos em branco para não fazer alteração de senha') + help_text="Deixe os campos em branco para não fazer alteração de senha", + ) new_password2 = forms.CharField( - label='Confirmar senha', + label="Confirmar senha", max_length=50, strip=False, required=False, widget=forms.PasswordInput(), - help_text='Deixe os campos em branco para não fazer alteração de senha') + help_text="Deixe os campos em branco para não fazer alteração de senha", + ) token = forms.CharField( required=False, label="Token", max_length=40, - widget=forms.TextInput(attrs={'readonly': 'readonly'})) + widget=forms.TextInput(attrs={"readonly": "readonly"}), + ) parlamentar = forms.ModelChoiceField( - label=_('Este usuário é um Parlamentar Votante?'), + label=_("Este usuário é um Parlamentar Votante?"), queryset=Parlamentar.objects.all(), required=False, - help_text='Se o usuário que está sendo cadastrado (ou em edição) é um usuário para que um parlamentar possa votar, você pode selecionar o parlamentar nas opções acima.') + help_text="Se o usuário que está sendo cadastrado (ou em edição) é um usuário para que um parlamentar possa votar, você pode selecionar o parlamentar nas opções acima.", + ) autor = forms.ModelChoiceField( - label=_('Este usuário registrará proposições para um Autor?'), + label=_("Este usuário registrará proposições para um Autor?"), queryset=Autor.objects.all(), required=False, - help_text='Se o usuário que está sendo cadastrado (ou em edição) é um usuário para cadastro de proposições, você pode selecionar para que autor ele registrará proposições.') + help_text="Se o usuário que está sendo cadastrado (ou em edição) é um usuário para cadastro de proposições, você pode selecionar para que autor ele registrará proposições.", + ) class Meta: model = get_user_model() fields = [ get_user_model().USERNAME_FIELD, - 'first_name', - 'last_name', - 'is_active', - - 'token', - - 'new_password1', - 'new_password2', - - 'parlamentar', - 'autor', - - 'groups', - 'user_permissions', + "first_name", + "last_name", + "is_active", + "token", + "new_password1", + "new_password2", + "parlamentar", + "autor", + "groups", + "user_permissions", ] - if get_user_model().USERNAME_FIELD != 'email': - fields.extend(['email']) + if get_user_model().USERNAME_FIELD != "email": + fields.extend(["email"]) def __init__(self, *args, **kwargs): - - self.user_session = kwargs.pop('user_session', None) - self.granular = kwargs.pop('granular', None) - self.instance = kwargs.get('instance', None) + self.user_session = kwargs.pop("user_session", None) + self.granular = kwargs.pop("granular", None) + self.instance = kwargs.get("instance", None) row_pwd = [ - ('username', 4), - ('email', 6), - ('is_active', 2), - ('first_name', 6), - ('last_name', 6), - ('new_password1', 3 if self.instance and self.instance.pk else 6), - ('new_password2', 3 if self.instance and self.instance.pk else 6), + ("username", 4), + ("email", 6), + ("is_active", 2), + ("first_name", 6), + ("last_name", 6), + ("new_password1", 3 if self.instance and self.instance.pk else 6), + ("new_password2", 3 if self.instance and self.instance.pk else 6), ] if self.instance and self.instance.pk: row_pwd += [ ( FieldWithButtons( - 'token', + "token", StrictButton( - 'Renovar', + "Renovar", id="renovar-token", - css_class="btn-outline-primary"), - css_class='' if self.instance and self.instance.pk else 'd-none'), - 6 + css_class="btn-outline-primary", + ), + css_class="" + if self.instance and self.instance.pk + else "d-none", + ), + 6, ) ] row_pwd += [ - - ('parlamentar', 6), - ('autor', 6), - ('groups', 12), - - ] + ([('user_permissions', 12)] if not self.granular is None else []) + ("parlamentar", 6), + ("autor", 6), + ("groups", 12), + ] + ([("user_permissions", 12)] if not self.granular is None else []) row_pwd = to_row(row_pwd) @@ -164,62 +174,71 @@ class UserAdminForm(ModelForm): self.helper.layout = SaplFormLayout(row_pwd) super(UserAdminForm, self).__init__(*args, **kwargs) - self.fields['groups'].widget = forms.CheckboxSelectMultiple() + self.fields["groups"].widget = forms.CheckboxSelectMultiple() - self.fields['parlamentar'].choices = [('', '---------')] + [ + self.fields["parlamentar"].choices = [("", "---------")] + [ (p.id, p) for p in parlamentares_ativos(timezone.now()) ] if not self.instance.pk: - self.fields['groups'].choices = [ - (g.id, g) for g in Group.objects.exclude( - name__in=['Autor', 'Votante'] - ).order_by('name') + self.fields["groups"].choices = [ + (g.id, g) + for g in Group.objects.exclude(name__in=["Autor", "Votante"]).order_by( + "name" + ) ] else: operadorautor = self.instance.operadorautor_set.first() votante = self.instance.votante_set.first() - self.fields['token'].initial = self.instance.auth_token.key \ - if hasattr(self.instance, 'auth_token') else '' - self.fields['autor'].initial = operadorautor.autor if operadorautor else None - self.fields['parlamentar'].initial = votante.parlamentar if votante else None - - self.fields['groups'].choices = [ - (g.id, g) for g in self.instance.groups.exclude( - name__in=['Autor', 'Votante'] - ).order_by('name') + self.fields["token"].initial = ( + self.instance.auth_token.key + if hasattr(self.instance, "auth_token") + else "" + ) + self.fields["autor"].initial = ( + operadorautor.autor if operadorautor else None + ) + self.fields["parlamentar"].initial = ( + votante.parlamentar if votante else None + ) + + self.fields["groups"].choices = [ + (g.id, g) + for g in self.instance.groups.exclude( + name__in=["Autor", "Votante"] + ).order_by("name") ] + [ - (g.id, g) for g in Group.objects.exclude( - user=self.instance).exclude( - name__in=[ - 'Autor', 'Votante'] - ).order_by('name') + (g.id, g) + for g in Group.objects.exclude(user=self.instance) + .exclude(name__in=["Autor", "Votante"]) + .order_by("name") ] - self.fields[ - 'user_permissions'].widget = forms.CheckboxSelectMultiple() + self.fields["user_permissions"].widget = forms.CheckboxSelectMultiple() if not self.granular is None: - self.fields['user_permissions'].choices = [ - (p.id, p) for p in self.instance.user_permissions.all( - ).order_by('content_type__app_label', - 'content_type__model', - 'codename') + self.fields["user_permissions"].choices = [ + (p.id, p) + for p in self.instance.user_permissions.all().order_by( + "content_type__app_label", "content_type__model", "codename" + ) ] + [ - (p.id, p) for p in Permission.objects.filter( + (p.id, p) + for p in Permission.objects.filter( content_type__app_label__in=list( - map(lambda x: x.split('.')[-1], settings.SAPL_APPS)) - ).exclude( - user=self.instance - ).order_by('content_type__app_label', - 'content_type__model', - 'codename') + map(lambda x: x.split(".")[-1], settings.SAPL_APPS) + ) + ) + .exclude(user=self.instance) + .order_by( + "content_type__app_label", "content_type__model", "codename" + ) ] def save(self, commit=True): - if self.cleaned_data['new_password1']: - self.instance.set_password(self.cleaned_data['new_password1']) + if self.cleaned_data["new_password1"]: + self.instance.set_password(self.cleaned_data["new_password1"]) permissions = None votante = None operadorautor = None @@ -239,36 +258,36 @@ class UserAdminForm(ModelForm): g_autor = Group.objects.get(name=SAPL_GROUP_AUTOR) g_votante = Group.objects.get(name=SAPL_GROUP_VOTANTE) - if not self.cleaned_data['autor']: + if not self.cleaned_data["autor"]: inst.groups.remove(g_autor) if operadorautor: operadorautor.delete() else: inst.groups.add(g_autor) if operadorautor: - if operadorautor.autor != self.cleaned_data['autor']: - operadorautor.autor = self.cleaned_data['autor'] + if operadorautor.autor != self.cleaned_data["autor"]: + operadorautor.autor = self.cleaned_data["autor"] operadorautor.save() else: operadorautor = OperadorAutor() operadorautor.user = inst - operadorautor.autor = self.cleaned_data['autor'] + operadorautor.autor = self.cleaned_data["autor"] operadorautor.save() - if not self.cleaned_data['parlamentar']: + if not self.cleaned_data["parlamentar"]: inst.groups.remove(g_votante) if votante: votante.delete() else: inst.groups.add(g_votante) if votante: - if votante.parlamentar != self.cleaned_data['parlamentar']: - votante.parlamentar = self.cleaned_data['parlamentar'] + if votante.parlamentar != self.cleaned_data["parlamentar"]: + votante.parlamentar = self.cleaned_data["parlamentar"] votante.save() else: votante = Votante() votante.user = inst - votante.parlamentar = self.cleaned_data['parlamentar'] + votante.parlamentar = self.cleaned_data["parlamentar"] votante.save() return inst @@ -279,8 +298,8 @@ class UserAdminForm(ModelForm): if self.errors: return data - new_password1 = data.get('new_password1', '') - new_password2 = data.get('new_password2', '') + new_password1 = data.get("new_password1", "") + new_password2 = data.get("new_password2", "") if new_password1 != new_password2: raise forms.ValidationError( @@ -289,32 +308,36 @@ class UserAdminForm(ModelForm): else: if new_password1 and new_password2: if is_weak_password(new_password1): - raise forms.ValidationError(_( - 'A senha deve ter pelo menos 8 caracteres e incluir uma combinação ' - 'de letras maiúsculas e minúsculas, números e caracteres especiais.' - )) - password_validation.validate_password( - new_password1, self.instance) - - parlamentar = data.get('parlamentar', None) - if parlamentar and parlamentar.votante_set.exists() and \ - parlamentar.votante_set.first().user != self.instance: + raise forms.ValidationError( + _( + "A senha deve ter pelo menos 8 caracteres e incluir uma combinação " + "de letras maiúsculas e minúsculas, números e caracteres especiais." + ) + ) + password_validation.validate_password(new_password1, self.instance) + + parlamentar = data.get("parlamentar", None) + if ( + parlamentar + and parlamentar.votante_set.exists() + and parlamentar.votante_set.first().user != self.instance + ): raise forms.ValidationError( mark_safe( - 'O Parlamentar {} ' - 'já está associado a outro usuário: {}.
' - 'Para realizar nova associação, você precisa ' - 'primeiro cancelar esta já existente.'.format( - parlamentar, - parlamentar.votante_set.first().user - )) + "O Parlamentar {} " + "já está associado a outro usuário: {}.
" + "Para realizar nova associação, você precisa " + "primeiro cancelar esta já existente.".format( + parlamentar, parlamentar.votante_set.first().user + ) + ) ) - autor = data.get('autor', None) + autor = data.get("autor", None) if parlamentar and autor: if autor.autor_related != parlamentar: raise forms.ValidationError( - 'Um usuário não deve ser Votante de um parlamentar, e operador de um Autor que possui um parlamentar diferente, ou mesmo outro tipo de Autor.' + "Um usuário não deve ser Votante de um parlamentar, e operador de um Autor que possui um parlamentar diferente, ou mesmo outro tipo de Autor." ) """ @@ -342,39 +365,43 @@ class SessaoLegislativaForm(FileFieldCheckMixin, ModelForm): exclude = [] def clean(self): - cleaned_data = super(SessaoLegislativaForm, self).clean() if not self.is_valid(): return cleaned_data flag_edit = True - data_inicio = cleaned_data['data_inicio'] - data_fim = cleaned_data['data_fim'] - legislatura = cleaned_data['legislatura'] - numero = cleaned_data['numero'] + data_inicio = cleaned_data["data_inicio"] + data_fim = cleaned_data["data_fim"] + legislatura = cleaned_data["legislatura"] + numero = cleaned_data["numero"] data_inicio_leg = legislatura.data_inicio data_fim_leg = legislatura.data_fim - pk = self.initial['id'] if self.initial else None + pk = self.initial["id"] if self.initial else None # Queries para verificar se existem Sessões Legislativas no período selecionado no form # Caso onde a data_inicio e data_fim são iguais a de alguma sessão já # criada primeiro_caso = Q(data_inicio=data_inicio, data_fim=data_fim) # Caso onde a data_inicio está entre o início e o fim de uma Sessão já # existente - segundo_caso = Q(data_inicio__lt=data_inicio, - data_fim__range=(data_inicio, data_fim)) + segundo_caso = Q( + data_inicio__lt=data_inicio, data_fim__range=(data_inicio, data_fim) + ) # Caso onde a data_fim está entre o início e o fim de uma Sessão já # existente - terceiro_caso = Q(data_inicio__range=( - data_inicio, data_fim), data_fim__gt=data_fim) - sessoes_existentes = SessaoLegislativa.objects.filter(primeiro_caso | segundo_caso | terceiro_caso). \ - exclude(pk=pk) + terceiro_caso = Q( + data_inicio__range=(data_inicio, data_fim), data_fim__gt=data_fim + ) + sessoes_existentes = SessaoLegislativa.objects.filter( + primeiro_caso | segundo_caso | terceiro_caso + ).exclude(pk=pk) if sessoes_existentes: - raise ValidationError('Já existe registrado uma Sessão Legislativa que coincide com a data ' - 'inserida, favor verificar as Sessões existentes antes de criar uma ' - 'nova Sessão Legislativa') + raise ValidationError( + "Já existe registrado uma Sessão Legislativa que coincide com a data " + "inserida, favor verificar as Sessões existentes antes de criar uma " + "nova Sessão Legislativa" + ) # sessoes_legislativas = SessaoLegislativa.objects.filter(legislatura=legislatura).exclude(pk=pk) @@ -392,99 +419,123 @@ class SessaoLegislativaForm(FileFieldCheckMixin, ModelForm): if numero <= ult and flag_edit: self.logger.warning( - 'O número da SessaoLegislativa ({}) é menor ou igual ' - 'que o de Sessões Legislativas passadas ({})'.format( - numero, ult) + "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" ) - 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: + if data_inicio < data_inicio_leg or data_inicio > data_fim_leg: self.logger.warning( - '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) + "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" ) - 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: + if data_fim > data_fim_leg or data_fim < data_inicio_leg: self.logger.warning( - '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) + "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" ) - 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.warning( - 'Data início ({}) superior à data fim ({}).'.format( - data_inicio, data_fim) + "Data início ({}) superior à data fim ({}).".format( + data_inicio, data_fim + ) ) - raise ValidationError( - 'Data início não pode ser superior à data fim') + raise ValidationError("Data início não pode ser superior à data fim") if data_fim.year > data_inicio.year + 1: raise ValidationError( - 'A Sessão Legislativa só pode ter, no máximo, dois anos de período.') + "A Sessão Legislativa só pode ter, no máximo, dois anos de período." + ) - data_inicio_intervalo = cleaned_data['data_inicio_intervalo'] - data_fim_intervalo = cleaned_data['data_fim_intervalo'] + data_inicio_intervalo = cleaned_data["data_inicio_intervalo"] + data_fim_intervalo = cleaned_data["data_fim_intervalo"] - if data_inicio_intervalo and data_fim_intervalo and \ - data_inicio_intervalo > data_fim_intervalo: + if ( + data_inicio_intervalo + and data_fim_intervalo + and data_inicio_intervalo > data_fim_intervalo + ): self.logger.warning( - 'Data início de intervalo ({}) superior à ' - 'data fim de intervalo ({}).'.format( - data_inicio_intervalo, data_fim_intervalo) + "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" ) - raise ValidationError('Data início de intervalo não pode ser ' - 'superior à data fim de intervalo') if data_inicio_intervalo: - if data_inicio_intervalo < data_inicio or \ - data_inicio_intervalo < data_inicio_leg or \ - data_inicio_intervalo > data_fim or \ - data_inicio_intervalo > data_fim_leg: + if ( + data_inicio_intervalo < data_inicio + or data_inicio_intervalo < data_inicio_leg + or data_inicio_intervalo > data_fim + or data_inicio_intervalo > data_fim_leg + ): self.logger.warning( - '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 + "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') + 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" + ) if data_fim_intervalo: - if data_fim_intervalo > data_fim or \ - data_fim_intervalo > data_fim_leg or \ - data_fim_intervalo < data_inicio or \ - data_fim_intervalo < data_inicio_leg: + if ( + data_fim_intervalo > data_fim + or data_fim_intervalo > data_fim_leg + or data_fim_intervalo < data_inicio + or data_fim_intervalo < data_inicio_leg + ): self.logger.warning( - '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 + "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') + 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" + ) return cleaned_data class TipoAutorForm(ModelForm): class Meta: model = TipoAutor - fields = ['descricao'] + fields = ["descricao"] def __init__(self, *args, **kwargs): - super(TipoAutorForm, self).__init__(*args, **kwargs) def clean(self): @@ -494,146 +545,144 @@ class TipoAutorForm(ModelForm): return self.cleaned_data cd = self.cleaned_data - lista = ['comissão', - 'comis', - 'parlamentar', - 'bancada', - 'bloco', - 'comissao', - 'vereador', - 'órgão', - 'orgao', - 'deputado', - 'senador', - 'vereadora', - 'frente'] + lista = [ + "comissão", + "comis", + "parlamentar", + "bancada", + "bloco", + "comissao", + "vereador", + "órgão", + "orgao", + "deputado", + "senador", + "vereadora", + "frente", + ] for l in lista: - if l in cd['descricao'].lower(): - raise ValidationError(_('A descrição colocada não pode ser usada ' - 'por ser equivalente a um tipo já existente')) + if l in cd["descricao"].lower(): + raise ValidationError( + _( + "A descrição colocada não pode ser usada " + "por ser equivalente a um tipo já existente" + ) + ) class AutorForm(ModelForm): logger = logging.getLogger(__name__) senha = forms.CharField( - max_length=20, - label=_('Senha'), - required=False, - widget=forms.PasswordInput()) + max_length=20, label=_("Senha"), required=False, widget=forms.PasswordInput() + ) senha_confirma = forms.CharField( max_length=20, - label=_('Confirmar Senha'), + label=_("Confirmar Senha"), required=False, - widget=forms.PasswordInput()) + widget=forms.PasswordInput(), + ) - email = forms.EmailField( - required=False, - label=_('Email')) + email = forms.EmailField(required=False, label=_("Email")) - confirma_email = forms.EmailField( - required=False, - label=_('Confirmar Email')) + confirma_email = forms.EmailField(required=False, label=_("Confirmar Email")) q = forms.CharField( - max_length=120, required=False, - label='Pesquise o nome do Autor com o ' - 'tipo Selecionado e marque o escolhido.') + max_length=120, + required=False, + label="Pesquise o nome do Autor com o " + "tipo Selecionado e marque o escolhido.", + ) - autor_related = ChoiceWithoutValidationField(label='', - required=False, - widget=forms.RadioSelect()) + autor_related = ChoiceWithoutValidationField( + label="", required=False, widget=forms.RadioSelect() + ) operadores = forms.ModelMultipleChoiceField( queryset=get_user_model().objects.all(), widget=forms.CheckboxSelectMultiple(), - label=_('Usuários do SAPL ligados ao autor acima selecionado'), + label=_("Usuários do SAPL ligados ao autor acima selecionado"), required=False, help_text=_( - 'Para ser listado aqui, o usuário não pode estar em nenhum outro autor e deve estar marcado como ativo.') + "Para ser listado aqui, o usuário não pode estar em nenhum outro autor e deve estar marcado como ativo." + ), ) class Meta: model = Autor - fields = ['tipo', - 'nome', - 'cargo', - 'autor_related', - 'q', - 'operadores' - ] + fields = ["tipo", "nome", "cargo", "autor_related", "q", "operadores"] def __init__(self, *args, **kwargs): - autor_related = Div( FieldWithButtons( - Field('q', - placeholder=_('Pesquisar por possíveis autores para ' - 'o Tipo de Autor selecionado.')), + Field( + "q", + placeholder=_( + "Pesquisar por possíveis autores para " + "o Tipo de Autor selecionado." + ), + ), StrictButton( - _('Filtrar'), css_class='btn-outline-primary btn-filtrar-autor', - type='button')), - css_class='hidden', - data_action='create', - data_application='AutorSearch', - data_field='autor_related') - - autor_select = Row(to_column(('tipo', 3)), - Div(to_column(('nome', 7)), - to_column(('cargo', 5)), - css_class="div_nome_cargo row col"), - to_column((autor_related, 9)), - to_column((Div( - Field('autor_related'), - css_class='radiogroup-autor-related hidden'), - 12))) - operadores_select = to_row( - [ - ('operadores', 12) - ] + _("Filtrar"), + css_class="btn-outline-primary btn-filtrar-autor", + type="button", + ), + ), + css_class="hidden", + data_action="create", + data_application="AutorSearch", + data_field="autor_related", + ) + + autor_select = Row( + to_column(("tipo", 3)), + Div( + to_column(("nome", 7)), + to_column(("cargo", 5)), + css_class="div_nome_cargo row col", + ), + to_column((autor_related, 9)), + to_column( + ( + Div( + Field("autor_related"), + css_class="radiogroup-autor-related hidden", + ), + 12, + ) + ), ) + operadores_select = to_row([("operadores", 12)]) self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout(autor_select, *operadores_select) super(AutorForm, self).__init__(*args, **kwargs) - self.fields['operadores'].choices = [ - ( - u.id, - u.username, - u - ) - for u in get_user_model().objects.filter( - operadorautor_set__autor=self.instance - ).order_by('-is_active', - get_user_model().USERNAME_FIELD - ) if self.instance.id + self.fields["operadores"].choices = [ + (u.id, u.username, u) + for u in get_user_model() + .objects.filter(operadorautor_set__autor=self.instance) + .order_by("-is_active", get_user_model().USERNAME_FIELD) + if self.instance.id ] + [ - ( - u.id, - u.username, - u - ) - for u in get_user_model().objects.filter( - operadorautor_set__isnull=True, - is_active=True - ).order_by('-is_active', - get_user_model().USERNAME_FIELD - ) + (u.id, u.username, u) + for u in get_user_model() + .objects.filter(operadorautor_set__isnull=True, is_active=True) + .order_by("-is_active", get_user_model().USERNAME_FIELD) ] if self.instance.pk: if self.instance.autor_related: - self.fields['autor_related'].choices = [ - (self.instance.autor_related.pk, - self.instance.autor_related)] + self.fields["autor_related"].choices = [ + (self.instance.autor_related.pk, self.instance.autor_related) + ] - self.fields['q'].initial = '' + self.fields["q"].initial = "" - self.fields['autor_related'].initial = self.instance.autor_related + self.fields["autor_related"].initial = self.instance.autor_related def valida_igualdade(self, texto1, texto2, msg): if texto1 != texto2: @@ -656,51 +705,57 @@ class AutorForm(ModelForm): if self.instance.pk: qs_autor = qs_autor.exclude(pk=self.instance.pk) - if 'tipo' not in cd or not cd['tipo']: - self.logger.warning('Tipo do Autor não selecionado.') - raise ValidationError( - _('O Tipo do Autor deve ser selecionado.')) + if "tipo" not in cd or not cd["tipo"]: + self.logger.warning("Tipo do Autor não selecionado.") + raise ValidationError(_("O Tipo do Autor deve ser selecionado.")) - tipo = cd['tipo'] + tipo = cd["tipo"] if not tipo.content_type: - if 'nome' not in cd or not cd['nome']: - self.logger.warning('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']) + if "nome" not in cd or not cd["nome"]: + self.logger.warning("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']: + if "autor_related" not in cd or not cd["autor_related"]: self.logger.warning( - 'Registro de %s não escolhido para ser ' - 'vinculado ao cadastro de Autor' % tipo.descricao + "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) + _( + "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(): + if ( + not tipo.content_type.model_class() + .objects.filter(pk=cd["autor_related"]) + .exists() + ): self.logger.warning( - 'O Registro definido (%s-%s) não está na base ' - 'de %s.' % (cd['autor_related'], cd['q'], tipo.descricao) + "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)) + _("O Registro definido (%s-%s) não está na base de %s.") + % (cd["autor_related"], cd["q"], tipo.descricao) + ) qs_autor_selected = qs_autor.filter( - object_id=cd['autor_related'], - content_type_id=cd['tipo'].content_type_id) + object_id=cd["autor_related"], + content_type_id=cd["tipo"].content_type_id, + ) if qs_autor_selected.exists(): autor = qs_autor_selected.first() self.logger.warning( - 'Já existe um autor Cadastrado para ' - '%s' % autor.autor_related + "Já existe um autor Cadastrado para " "%s" % autor.autor_related ) raise ValidationError( - _('Já existe um autor Cadastrado para %s' - ) % autor.autor_related) + _("Já existe um autor Cadastrado para %s") % autor.autor_related + ) return self.cleaned_data @@ -713,8 +768,9 @@ class AutorForm(ModelForm): autor.object_id = None autor.autor_related = None else: - autor.autor_related = autor.tipo.content_type.model_class( - ).objects.get(pk=self.cleaned_data['autor_related']) + autor.autor_related = autor.tipo.content_type.model_class().objects.get( + pk=self.cleaned_data["autor_related"] + ) autor.nome = str(autor.autor_related) autor = super(AutorForm, self).save(commit) @@ -723,161 +779,187 @@ class AutorForm(ModelForm): class AutorFilterSet(django_filters.FilterSet): - nome = django_filters.CharFilter( - label=_('Nome do Autor'), lookup_expr='icontains') + nome = django_filters.CharFilter(label=_("Nome do Autor"), lookup_expr="icontains") class Meta: model = Autor - fields = ['nome'] + fields = ["nome"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - row0 = to_row([('nome', 12)]) + row0 = to_row([("nome", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Autor'), - row0, - form_actions(label='Pesquisar'))) + Fieldset(_("Pesquisa de Autor"), row0, form_actions(label="Pesquisar")) + ) def get_username(): try: - return [(u, u) for u in - get_user_model().objects.all().order_by('username').values_list('username', flat=True)] + return [ + (u, u) + for u in get_user_model() + .objects.all() + .order_by("username") + .values_list("username", flat=True) + ] except: return [] def get_models(): - return [(m, m) for m in - AuditLog.objects.distinct('model_name').order_by('model_name').values_list('model_name', flat=True)] + return [ + (m, m) + for m in AuditLog.objects.distinct("model_name") + .order_by("model_name") + .values_list("model_name", flat=True) + ] class AuditLogFilterSet(django_filters.FilterSet): OPERATION_CHOICES = ( - ('U', 'Atualizado'), - ('C', 'Criado'), - ('D', 'Excluído'), + ("U", "Atualizado"), + ("C", "Criado"), + ("D", "Excluído"), ) - username = django_filters.ChoiceFilter( - choices=get_username(), label=_('Usuário')) - object_id = django_filters.NumberFilter(label=_('Id')) + username = django_filters.ChoiceFilter(choices=get_username(), label=_("Usuário")) + object_id = django_filters.NumberFilter(label=_("Id")) operation = django_filters.ChoiceFilter( - choices=OPERATION_CHOICES, label=_('Operação')) + choices=OPERATION_CHOICES, label=_("Operação") + ) model_name = django_filters.ChoiceFilter( - choices=get_models, label=_('Tipo de Registro')) - timestamp = django_filters.DateRangeFilter(label=_('Período')) + choices=get_models, label=_("Tipo de Registro") + ) + timestamp = django_filters.DateRangeFilter(label=_("Período")) class Meta: model = AuditLog - fields = ['username', 'operation', - 'model_name', 'timestamp', 'object_id'] + fields = ["username", "operation", "model_name", "timestamp", "object_id"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - row0 = to_row([('username', 2), - ('operation', 2), - ('model_name', 4), - ('object_id', 2), - ('timestamp', 2)]) + row0 = to_row( + [ + ("username", 2), + ("operation", 2), + ("model_name", 4), + ("object_id", 2), + ("timestamp", 2), + ] + ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Filtros'), - row0, - form_actions(label='Aplicar Filtro'))) + Fieldset(_("Filtros"), row0, form_actions(label="Aplicar Filtro")) + ) class OperadorAutorForm(ModelForm): class Meta: model = OperadorAutor - fields = ['user', ] + fields = [ + "user", + ] def __init__(self, *args, **kwargs): - row = to_row([('user', 12)]) + row = to_row([("user", 12)]) self.helper = SaplFormHelper() - self.helper.layout = SaplFormLayout( - Fieldset(_('Operador'), row)) + self.helper.layout = SaplFormLayout(Fieldset(_("Operador"), row)) super(OperadorAutorForm, self).__init__(*args, **kwargs) - self.fields['user'].choices = [ + self.fields["user"].choices = [ ( u.id, - '{} - {} - {}'.format( - u.get_full_name(), - getattr(u, u.USERNAME_FIELD), - u.email - ) - ) - for u in get_user_model().objects.all().order_by( - get_user_model().USERNAME_FIELD + "{} - {} - {}".format( + u.get_full_name(), getattr(u, u.USERNAME_FIELD), u.email + ), ) + for u in get_user_model() + .objects.all() + .order_by(get_user_model().USERNAME_FIELD) ] - self.fields['user'].widget = forms.RadioSelect() + self.fields["user"].widget = forms.RadioSelect() class EstatisticasAcessoNormasForm(Form): - ano = forms.ChoiceField(required=True, - label='Ano de acesso', - choices=RANGE_ANOS, - initial=timezone.now().year) - - mes = forms.ChoiceField(required=False, - label='Mês de acesso', - choices=[('', 'Todos os Meses')] + RANGE_MESES, - initial='') - - mais_acessadas = forms.ChoiceField(required=False, - label='Mais Acessadas', - choices=[ - (5, '005 mais acessadas'), - (10, '010 mais acessadas'), - (50, '050 mais acessadas'), - (100, '100 mais acessadas'), - (500, '500 mais acessadas'), - (1000, '1000 mais acessadas'), - ], - initial=5) + ano = forms.ChoiceField( + required=True, + label="Ano de acesso", + choices=RANGE_ANOS, + initial=timezone.now().year, + ) + + mes = forms.ChoiceField( + required=False, + label="Mês de acesso", + choices=[("", "Todos os Meses")] + RANGE_MESES, + initial="", + ) + + mais_acessadas = forms.ChoiceField( + required=False, + label="Mais Acessadas", + choices=[ + (5, "005 mais acessadas"), + (10, "010 mais acessadas"), + (50, "050 mais acessadas"), + (100, "100 mais acessadas"), + (500, "500 mais acessadas"), + (1000, "1000 mais acessadas"), + ], + initial=5, + ) class Meta: - fields = ['ano', 'mes', 'mais_acessadas'] + fields = ["ano", "mes", "mais_acessadas"] def __init__(self, *args, **kwargs): - super(EstatisticasAcessoNormasForm, self).__init__( - *args, **kwargs) + super(EstatisticasAcessoNormasForm, self).__init__(*args, **kwargs) - row1 = to_row([('ano', 3), ('mes', 6), ('mais_acessadas', 3), ]) + row1 = to_row( + [ + ("ano", 3), + ("mes", 6), + ("mais_acessadas", 3), + ] + ) buttons = FormActions( *[ - HTML(''' + HTML( + """
- ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.helper = SaplFormHelper() - self.helper.form_method = 'GET' + self.helper.form_method = "GET" self.helper.layout = Layout( - Fieldset(_('Normas por acessos nos meses do ano.'), - row1, buttons) + Fieldset(_("Normas por acessos nos meses do ano."), row1, buttons) ) - self.fields['ano'].choices = NormaEstatisticas.objects.order_by( - '-ano').distinct().values_list('ano', 'ano') or [ + self.fields["ano"].choices = NormaEstatisticas.objects.order_by( + "-ano" + ).distinct().values_list("ano", "ano") or [ (timezone.now().year, timezone.now().year) ] @@ -889,39 +971,39 @@ class EstatisticasAcessoNormasForm(Form): class CasaLegislativaForm(FileFieldCheckMixin, ModelForm): class Meta: - model = CasaLegislativa - fields = ['codigo', - 'nome', - 'sigla', - 'endereco', - 'cep', - 'municipio', - 'uf', - 'telefone', - 'fax', - 'logotipo', - 'endereco_web', - 'email', - 'informacao_geral'] + fields = [ + "codigo", + "nome", + "sigla", + "endereco", + "cep", + "municipio", + "uf", + "telefone", + "fax", + "logotipo", + "endereco_web", + "email", + "informacao_geral", + ] widgets = { - 'uf': forms.Select(attrs={'class': 'selector'}), - 'cep': forms.TextInput(attrs={'class': 'cep'}), - 'telefone': forms.TextInput(attrs={'class': 'telefone'}), + "uf": forms.Select(attrs={"class": "selector"}), + "cep": forms.TextInput(attrs={"class": "cep"}), + "telefone": forms.TextInput(attrs={"class": "telefone"}), # O campo fax foi ocultado porque não é utilizado. - 'fax': forms.HiddenInput(), + "fax": forms.HiddenInput(), # 'fax': forms.TextInput(attrs={'class': 'telefone'}), - 'logotipo': ImageThumbnailFileInput, - 'informacao_geral': forms.Textarea( - attrs={'id': 'texto-rico'}) + "logotipo": ImageThumbnailFileInput, + "informacao_geral": forms.Textarea(attrs={"id": "texto-rico"}), } def clean_logotipo(self): # chama __clean de FileFieldCheckMixin # por estar em clean de campo super(CasaLegislativaForm, self)._check() - logotipo = self.cleaned_data.get('logotipo') + logotipo = self.cleaned_data.get("logotipo") if logotipo and logotipo.size > MAX_IMAGE_UPLOAD_SIZE: raise ValidationError("Imagem muito grande. ( > 2MB )") return logotipo @@ -932,101 +1014,107 @@ class CasaLegislativaForm(FileFieldCheckMixin, ModelForm): return casa - class LoginForm(AuthenticationForm): username = forms.CharField( - label="Usuário", max_length=30, - widget=forms.TextInput( - attrs={ - 'class': 'form-control', 'name': 'username'})) + label="Usuário", + max_length=30, + widget=forms.TextInput(attrs={"class": "form-control", "name": "username"}), + ) password = forms.CharField( - label="Senha", max_length=30, - widget=forms.PasswordInput( - attrs={ - 'class': 'form-control', 'name': 'password'})) + label="Senha", + max_length=30, + widget=forms.PasswordInput(attrs={"class": "form-control", "name": "password"}), + ) class ConfiguracoesAppForm(ModelForm): logger = logging.getLogger(__name__) mostrar_brasao_painel = forms.BooleanField( - help_text=_('Sugerimos fortemente que faça o upload de imagens com ' - 'o fundo transparente.'), - label=_('Mostrar brasão da Casa no painel?'), - required=False) + help_text=_( + "Sugerimos fortemente que faça o upload de imagens com " + "o fundo transparente." + ), + label=_("Mostrar brasão da Casa no painel?"), + required=False, + ) mostrar_voto = forms.BooleanField( - help_text=_('Se selecionado, exibe qual é o voto, e não apenas a indicação de que já votou, ' - 'com a votação ainda aberta.'), - label=_('Mostrar voto do Parlamentar no painel durante a votação?'), - required=False) + help_text=_( + "Se selecionado, exibe qual é o voto, e não apenas a indicação de que já votou, " + "com a votação ainda aberta." + ), + label=_("Mostrar voto do Parlamentar no painel durante a votação?"), + required=False, + ) google_recaptcha_site_key = forms.CharField( - label=AppConfig._meta.get_field( - 'google_recaptcha_site_key').verbose_name, + label=AppConfig._meta.get_field("google_recaptcha_site_key").verbose_name, max_length=256, required=False, help_text=_( 'Acesse https://www.google.com/recaptcha ' - 'para configurar um Recaptcha para sua casa legislativa. ' - 'Com Recaptcha configurado seu sapl disponibilizará ' - 'Acompanhamentos de Matérias e Documentos Administrativos ' + "para configurar um Recaptcha para sua casa legislativa. " + "Com Recaptcha configurado seu sapl disponibilizará " + "Acompanhamentos de Matérias e Documentos Administrativos " 'e Recuperação de Senha pela opção "Esqueceu sua Senha" ' - 'na tela de login. Esta melhoria na foi necessária com o ' - 'intuito de coibir recorrentes ataques ao serviço de email.'), + "na tela de login. Esta melhoria na foi necessária com o " + "intuito de coibir recorrentes ataques ao serviço de email." + ), ) google_recaptcha_secret_key = forms.CharField( - label=AppConfig._meta.get_field( - 'google_recaptcha_secret_key').verbose_name, + label=AppConfig._meta.get_field("google_recaptcha_secret_key").verbose_name, max_length=256, - required=False) + required=False, + ) google_analytics_id_metrica = forms.CharField( - label=AppConfig._meta.get_field( - 'google_analytics_id_metrica').verbose_name, + label=AppConfig._meta.get_field("google_analytics_id_metrica").verbose_name, max_length=256, - required=False) + required=False, + ) class Meta: model = AppConfig - fields = ['documentos_administrativos', - 'sequencia_numeracao_protocolo', - 'inicio_numeracao_protocolo', - 'sequencia_numeracao_proposicao', - 'esfera_federacao', - # 'painel_aberto', # TODO: a ser implementado na versão 3.2 - 'texto_articulado_proposicao', - 'texto_articulado_materia', - 'texto_articulado_norma', - 'proposicao_incorporacao_obrigatoria', - 'protocolo_manual', - 'cronometro_discurso', - 'cronometro_aparte', - 'cronometro_ordem', - 'cronometro_consideracoes', - 'mostrar_brasao_painel', - 'mostrar_voto', - 'receber_recibo_proposicao', - 'assinatura_ata', - 'estatisticas_acesso_normas', - 'escolher_numero_materia_proposicao', - 'tramitacao_origem_fixa', - 'tramitacao_materia', - 'ordenacao_pesquisa_materia', - 'tramitacao_documento', - 'google_recaptcha_site_key', - 'google_recaptcha_secret_key', - 'google_analytics_id_metrica', - 'identificacao_de_documentos', - ] + fields = [ + "documentos_administrativos", + "sequencia_numeracao_protocolo", + "inicio_numeracao_protocolo", + "sequencia_numeracao_proposicao", + "esfera_federacao", + # 'painel_aberto', # TODO: a ser implementado na versão 3.2 + "texto_articulado_proposicao", + "texto_articulado_materia", + "texto_articulado_norma", + "proposicao_incorporacao_obrigatoria", + "protocolo_manual", + "cronometro_discurso", + "cronometro_aparte", + "cronometro_ordem", + "cronometro_consideracoes", + "mostrar_brasao_painel", + "mostrar_voto", + "receber_recibo_proposicao", + "assinatura_ata", + "estatisticas_acesso_normas", + "escolher_numero_materia_proposicao", + "tramitacao_origem_fixa", + "tramitacao_materia", + "ordenacao_pesquisa_materia", + "tramitacao_documento", + "google_recaptcha_site_key", + "google_recaptcha_secret_key", + "google_analytics_id_metrica", + "identificacao_de_documentos", + ] def __init__(self, *args, **kwargs): super(ConfiguracoesAppForm, self).__init__(*args, **kwargs) - self.fields['cronometro_discurso'].widget.attrs['class'] = 'cronometro' - self.fields['cronometro_aparte'].widget.attrs['class'] = 'cronometro' - self.fields['cronometro_ordem'].widget.attrs['class'] = 'cronometro' - self.fields['cronometro_consideracoes'].widget.attrs['class'] = 'cronometro' + self.fields["cronometro_discurso"].widget.attrs["class"] = "cronometro" + self.fields["cronometro_aparte"].widget.attrs["class"] = "cronometro" + self.fields["cronometro_ordem"].widget.attrs["class"] = "cronometro" + self.fields["cronometro_consideracoes"].widget.attrs["class"] = "cronometro" def clean(self): cleaned_data = super().clean() @@ -1034,21 +1122,21 @@ class ConfiguracoesAppForm(ModelForm): if not self.is_valid(): return cleaned_data - mostrar_brasao_painel = self.cleaned_data.get( - 'mostrar_brasao_painel', False) + mostrar_brasao_painel = self.cleaned_data.get("mostrar_brasao_painel", False) casa = CasaLegislativa.objects.first() if not casa: - self.logger.warning('Não há casa legislativa relacionada.') + self.logger.warning("Não há casa legislativa relacionada.") raise ValidationError("Não há casa legislativa relacionada.") if not casa.logotipo and mostrar_brasao_painel: self.logger.warning( - 'Não há logitipo configurado para esta ' - 'CasaLegislativa ({}).'.format(casa) + "Não há logitipo configurado para esta " + "CasaLegislativa ({}).".format(casa) + ) + raise ValidationError( + "Não há logitipo configurado para esta " "Casa legislativa." ) - raise ValidationError("Não há logitipo configurado para esta " - "Casa legislativa.") return cleaned_data @@ -1057,22 +1145,24 @@ class RecuperarSenhaForm(GoogleRecapthaMixin, PasswordResetForm): logger = logging.getLogger(__name__) def __init__(self, *args, **kwargs): - kwargs['title_label'] = _('Insira o e-mail cadastrado com a sua conta') - kwargs['action_label'] = _('Enviar') + kwargs["title_label"] = _("Insira o e-mail cadastrado com a sua conta") + kwargs["action_label"] = _("Enviar") super().__init__(*args, **kwargs) def clean(self): super(RecuperarSenhaForm, self).clean() - email_existente = get_user_model().objects.filter( - email=self.data['email']).exists() + email_existente = ( + get_user_model().objects.filter(email=self.data["email"]).exists() + ) if not email_existente: - msg = 'Não existe nenhum usuário cadastrado com este e-mail.' + msg = "Não existe nenhum usuário cadastrado com este e-mail." self.logger.warning( - 'Não existe nenhum usuário cadastrado com este e-mail ({}).'.format( - self.data['email']) + "Não existe nenhum usuário cadastrado com este e-mail ({}).".format( + self.data["email"] + ) ) raise ValidationError(msg) @@ -1080,19 +1170,14 @@ class RecuperarSenhaForm(GoogleRecapthaMixin, PasswordResetForm): class NovaSenhaForm(SetPasswordForm): - def __init__(self, user, *args, **kwargs): self.user = user super(NovaSenhaForm, self).__init__(user, *args, **kwargs) - row1 = to_row( - [('new_password1', 6), - ('new_password2', 6)]) + row1 = to_row([("new_password1", 6), ("new_password2", 6)]) self.helper = SaplFormHelper() - self.helper.layout = Layout( - row1, - form_actions(label='Enviar')) + self.helper.layout = Layout(row1, form_actions(label="Enviar")) class AlterarSenhaForm(Form): @@ -1100,33 +1185,27 @@ class AlterarSenhaForm(Form): username = forms.CharField(widget=forms.HiddenInput()) - old_password = forms.CharField(label='Senha atual', - max_length=50, - widget=forms.PasswordInput()) - new_password1 = forms.CharField(label='Nova senha', - max_length=50, - widget=forms.PasswordInput()) - new_password2 = forms.CharField(label='Confirmar senha', - max_length=50, - widget=forms.PasswordInput()) + old_password = forms.CharField( + label="Senha atual", max_length=50, widget=forms.PasswordInput() + ) + new_password1 = forms.CharField( + label="Nova senha", max_length=50, widget=forms.PasswordInput() + ) + new_password2 = forms.CharField( + label="Confirmar senha", max_length=50, widget=forms.PasswordInput() + ) class Meta: - fields = ['username', 'old_password', 'new_password1', 'new_password2'] + fields = ["username", "old_password", "new_password1", "new_password2"] def __init__(self, *args, **kwargs): - super(AlterarSenhaForm, self).__init__(*args, **kwargs) - row1 = to_row([('old_password', 12)]) - row2 = to_row( - [('new_password1', 6), - ('new_password2', 6)]) + row1 = to_row([("old_password", 12)]) + row2 = to_row([("new_password1", 6), ("new_password2", 6)]) self.helper = SaplFormHelper() - self.helper.layout = Layout( - row1, - row2, - form_actions(label='Alterar Senha')) + self.helper.layout = Layout(row1, row2, form_actions(label="Alterar Senha")) def clean(self): super(AlterarSenhaForm, self).clean() @@ -1136,13 +1215,12 @@ class AlterarSenhaForm(Form): data = self.cleaned_data - new_password1 = data['new_password1'] - new_password2 = data['new_password2'] + new_password1 = data["new_password1"] + new_password2 = data["new_password2"] if new_password1 != new_password2: self.logger.warning("'Nova Senha' diferente de 'Confirmar Senha'") - raise ValidationError( - "'Nova Senha' diferente de 'Confirmar Senha'") + raise ValidationError("'Nova Senha' diferente de 'Confirmar Senha'") # TODO: colocar mais regras como: tamanho mínimo, # TODO: caracteres alfanuméricos, maiúsculas (?), @@ -1150,40 +1228,35 @@ class AlterarSenhaForm(Form): if is_weak_password(new_password1): self.logger.warning( - 'A senha deve ter pelo menos 8 caracteres e incluir uma combinação ' - 'de letras maiúsculas e minúsculas, números e caracteres especiais.' + "A senha deve ter pelo menos 8 caracteres e incluir uma combinação " + "de letras maiúsculas e minúsculas, números e caracteres especiais." ) raise ValidationError( - 'A senha deve ter pelo menos 8 caracteres e incluir uma combinação ' - 'de letras maiúsculas e minúsculas, números e caracteres especiais.' + "A senha deve ter pelo menos 8 caracteres e incluir uma combinação " + "de letras maiúsculas e minúsculas, números e caracteres especiais." ) - username = data['username'] - old_password = data['old_password'] + username = data["username"] + old_password = data["old_password"] user = User.objects.get(username=username) if user.is_anonymous: self.logger.warning( - 'Não é possível alterar senha de usuário anônimo ({}).'.format( - username) + "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") + raise ValidationError("Não é possível alterar senha de usuário anônimo") if not user.check_password(old_password): self.logger.warning( - 'Senha atual informada não confere ' - 'com a senha armazenada.' + "Senha atual informada não confere " "com a senha armazenada." + ) + raise ValidationError( + "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.warning( - 'Nova senha igual à senha anterior.' - ) - raise ValidationError( - "Nova senha não pode ser igual à senha anterior") + self.logger.warning("Nova senha igual à senha anterior.") + raise ValidationError("Nova senha não pode ser igual à senha anterior") return self.cleaned_data @@ -1194,7 +1267,6 @@ class PartidoForm(FileFieldCheckMixin, ModelForm): exclude = [] def __init__(self, *args, **kwargs): - super(PartidoForm, self).__init__(*args, **kwargs) # TODO Utilizar esses campos na issue #2161 de alteração de nomes de partidos @@ -1204,39 +1276,39 @@ class PartidoForm(FileFieldCheckMixin, ModelForm): # self.fields['sigla'].widget.attrs['readonly'] = True row1 = to_row( - [('sigla', 2), - ('nome', 6), - ('data_criacao', 2), - ('data_extincao', 2), ]) - row2 = to_row([('observacao', 12)]) - row3 = to_row([('logo_partido', 12)]) + [ + ("sigla", 2), + ("nome", 6), + ("data_criacao", 2), + ("data_extincao", 2), + ] + ) + row2 = to_row([("observacao", 12)]) + row3 = to_row([("logo_partido", 12)]) self.helper = SaplFormHelper() - self.helper.layout = Layout( - row1, row2, row3, - form_actions(label='Salvar')) + self.helper.layout = Layout(row1, row2, row3, form_actions(label="Salvar")) def clean(self): - cleaned_data = super(PartidoForm, self).clean() if not self.is_valid(): return cleaned_data - if cleaned_data['data_criacao'] and cleaned_data['data_extincao']: - if cleaned_data['data_criacao'] > cleaned_data['data_extincao']: + if cleaned_data["data_criacao"] and cleaned_data["data_extincao"]: + if cleaned_data["data_criacao"] > cleaned_data["data_extincao"]: raise ValidationError( - "Certifique-se de que a data de criação seja anterior à data de extinção.") + "Certifique-se de que a data de criação seja anterior à data de extinção." + ) return cleaned_data class SaplSearchForm(ModelSearchForm): - def search(self): sqs = super().search() - return sqs.order_by('-last_update') + return sqs.order_by("-last_update") """def get_models(self): Return a list of the selected models. diff --git a/sapl/base/management/commands/backfill_auditlog.py b/sapl/base/management/commands/backfill_auditlog.py index ba8bb6037..7677f9c9d 100644 --- a/sapl/base/management/commands/backfill_auditlog.py +++ b/sapl/base/management/commands/backfill_auditlog.py @@ -2,6 +2,7 @@ import json import logging from django.core.management.base import BaseCommand + from sapl.base.models import AuditLog logger = logging.getLogger(__name__) @@ -16,8 +17,7 @@ class Command(BaseCommand): update_list = [] for log in logs: try: - obj = log.object[1:-1] \ - if log.object.startswith('[') else log.object + obj = log.object[1:-1] if log.object.startswith("[") else log.object data = json.loads(obj) log.data = data except Exception as e: @@ -27,12 +27,10 @@ class Command(BaseCommand): else: update_list.append(log) if len(update_list) == 1000: - AuditLog.objects.bulk_update(update_list, ['data']) + AuditLog.objects.bulk_update(update_list, ["data"]) update_list = [] if update_list: - AuditLog.objects.bulk_update(update_list, ['data']) + AuditLog.objects.bulk_update(update_list, ["data"]) print(f"Logs backfilled: {len(logs) - error_counter}") print(f"Logs with errors: {error_counter}") print("Finished backfilling") - - diff --git a/sapl/base/models.py b/sapl/base/models.py index c0f56cf23..80a7000eb 100644 --- a/sapl/base/models.py +++ b/sapl/base/models.py @@ -1,9 +1,9 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType -from django.db.models import JSONField from django.core.cache import cache from django.core.serializers.json import DjangoJSONEncoder from django.db import models +from django.db.models import JSONField from django.db.models.deletion import CASCADE from django.db.models.signals import post_migrate from django.db.utils import DEFAULT_DB_ALIAS @@ -12,37 +12,42 @@ from django.utils.translation import gettext_lazy as _ from sapl.utils import (LISTA_DE_UFS, YES_NO_CHOICES, get_settings_auth_user_model, models_with_gr_for_model) +DOC_ADM_OSTENSIVO = "O" +DOC_ADM_RESTRITIVO = "R" -DOC_ADM_OSTENSIVO = 'O' -DOC_ADM_RESTRITIVO = 'R' - -TIPO_DOCUMENTO_ADMINISTRATIVO = ((DOC_ADM_OSTENSIVO, _('Ostensiva')), - (DOC_ADM_RESTRITIVO, _('Restritiva'))) +TIPO_DOCUMENTO_ADMINISTRATIVO = ( + (DOC_ADM_OSTENSIVO, _("Ostensiva")), + (DOC_ADM_RESTRITIVO, _("Restritiva")), +) -RELATORIO_ATOS_ACESSADOS = (('S', _('Sim')), - ('N', _('Não'))) +RELATORIO_ATOS_ACESSADOS = (("S", _("Sim")), ("N", _("Não"))) -SEQUENCIA_NUMERACAO_PROTOCOLO = (('A', _('Sequencial por ano')), - ('L', _('Sequencial por legislatura')), - ('U', _('Sequencial único'))) +SEQUENCIA_NUMERACAO_PROTOCOLO = ( + ("A", _("Sequencial por ano")), + ("L", _("Sequencial por legislatura")), + ("U", _("Sequencial único")), +) -SEQUENCIA_NUMERACAO_PROPOSICAO = (('A', _('Sequencial por ano para cada autor')), - ('B', _('Sequencial por ano indepententemente do autor'))) +SEQUENCIA_NUMERACAO_PROPOSICAO = ( + ("A", _("Sequencial por ano para cada autor")), + ("B", _("Sequencial por ano indepententemente do autor")), +) -ESFERA_FEDERACAO_CHOICES = (('M', _('Municipal')), - ('E', _('Estadual')), - ('F', _('Federal')), - ) +ESFERA_FEDERACAO_CHOICES = ( + ("M", _("Municipal")), + ("E", _("Estadual")), + ("F", _("Federal")), +) ASSINATURA_ATA_CHOICES = ( - ('M', _('Mesa Diretora da Sessão')), - ('P', _('Apenas o Presidente da Sessão')), - ('T', _('Todos os Parlamentares Presentes na Sessão')), + ("M", _("Mesa Diretora da Sessão")), + ("P", _("Apenas o Presidente da Sessão")), + ("T", _("Todos os Parlamentares Presentes na Sessão")), ) ORDENACAO_PESQUISA_MATERIA = ( - ('S', _('Alfabética por Sigla')), - ('R', _('Sequência Regimental')), + ("S", _("Alfabética por Sigla")), + ("R", _("Sequência Regimental")), ) @@ -50,50 +55,40 @@ class CasaLegislativa(models.Model): # TODO ajustar todos os max_length !!!! # cod_casa => id (pk) - codigo = models.CharField(max_length=100, - blank=True, - verbose_name=_('Codigo')) - nome = models.CharField(max_length=100, verbose_name=_('Nome')) - sigla = models.CharField(max_length=100, verbose_name=_('Sigla')) - endereco = models.CharField(max_length=100, verbose_name=_('Endereço')) - cep = models.CharField(max_length=100, blank=True, verbose_name=_('CEP')) - municipio = models.CharField(max_length=50, verbose_name=_('Município')) - uf = models.CharField(max_length=2, - choices=LISTA_DE_UFS, - verbose_name=_('UF')) - telefone = models.CharField( - max_length=100, blank=True, verbose_name=_('Telefone')) - fax = models.CharField( - max_length=100, blank=True, verbose_name=_('Fax')) + codigo = models.CharField(max_length=100, blank=True, verbose_name=_("Codigo")) + nome = models.CharField(max_length=100, verbose_name=_("Nome")) + sigla = models.CharField(max_length=100, verbose_name=_("Sigla")) + endereco = models.CharField(max_length=100, verbose_name=_("Endereço")) + cep = models.CharField(max_length=100, blank=True, verbose_name=_("CEP")) + municipio = models.CharField(max_length=50, verbose_name=_("Município")) + uf = models.CharField(max_length=2, choices=LISTA_DE_UFS, verbose_name=_("UF")) + telefone = models.CharField(max_length=100, blank=True, verbose_name=_("Telefone")) + fax = models.CharField(max_length=100, blank=True, verbose_name=_("Fax")) logotipo = models.ImageField( - blank=True, - upload_to='sapl/public/casa/logotipo/', - verbose_name=_('Logotipo')) + blank=True, upload_to="sapl/public/casa/logotipo/", verbose_name=_("Logotipo") + ) endereco_web = models.URLField( - max_length=100, blank=True, verbose_name=_('HomePage')) - email = models.EmailField( - max_length=100, blank=True, verbose_name=_('E-mail')) + max_length=100, blank=True, verbose_name=_("HomePage") + ) + email = models.EmailField(max_length=100, blank=True, verbose_name=_("E-mail")) informacao_geral = models.TextField( - max_length=100, - blank=True, - verbose_name=_('Informação Geral')) + max_length=100, blank=True, verbose_name=_("Informação Geral") + ) class Meta: - verbose_name = _('Casa Legislativa') - verbose_name_plural = _('Casa Legislativa') - ordering = ('id',) + verbose_name = _("Casa Legislativa") + verbose_name_plural = _("Casa Legislativa") + ordering = ("id",) def __str__(self): - return _('Casa Legislativa de %(municipio)s') % { - 'municipio': self.municipio} + return _("Casa Legislativa de %(municipio)s") % {"municipio": self.municipio} class AppConfig(models.Model): - POLITICA_PROTOCOLO_CHOICES = ( - ('O', _('Sempre Gerar Protocolo')), - ('C', _('Perguntar se é pra gerar protocolo ao incorporar')), - ('N', _('Nunca Protocolar ao incorporar uma proposição')), + ("O", _("Sempre Gerar Protocolo")), + ("C", _("Perguntar se é pra gerar protocolo ao incorporar")), + ("N", _("Nunca Protocolar ao incorporar uma proposição")), ) # MANTENHA A SEQUÊNCIA EQUIVALENTE COM /sapl/templates/base/layout.yaml @@ -105,8 +100,9 @@ class AppConfig(models.Model): max_length=1, blank=True, default="", - verbose_name=_('Esfera Federação'), - choices=ESFERA_FEDERACAO_CHOICES) + verbose_name=_("Esfera Federação"), + choices=ESFERA_FEDERACAO_CHOICES, + ) # MÓDULO PARLAMENTARES @@ -120,29 +116,37 @@ class AppConfig(models.Model): # Linha 1 ------------------------- documentos_administrativos = models.CharField( max_length=1, - verbose_name=_('Visibilidade dos Documentos Administrativos'), - choices=TIPO_DOCUMENTO_ADMINISTRATIVO, default='O') + verbose_name=_("Visibilidade dos Documentos Administrativos"), + choices=TIPO_DOCUMENTO_ADMINISTRATIVO, + default="O", + ) tramitacao_documento = models.BooleanField( verbose_name=_( - 'Tramitar documentos anexados junto com os documentos principais?'), - choices=YES_NO_CHOICES, default=True) + "Tramitar documentos anexados junto com os documentos principais?" + ), + choices=YES_NO_CHOICES, + default=True, + ) # Linha 2 ------------------------- protocolo_manual = models.BooleanField( - verbose_name=_('Permitir informe manual de data e hora de protocolo?'), - choices=YES_NO_CHOICES, default=False) + verbose_name=_("Permitir informe manual de data e hora de protocolo?"), + choices=YES_NO_CHOICES, + default=False, + ) sequencia_numeracao_protocolo = models.CharField( max_length=1, - verbose_name=_('Sequência de numeração de protocolos'), - choices=SEQUENCIA_NUMERACAO_PROTOCOLO, default='A') + verbose_name=_("Sequência de numeração de protocolos"), + choices=SEQUENCIA_NUMERACAO_PROTOCOLO, + default="A", + ) inicio_numeracao_protocolo = models.PositiveIntegerField( - verbose_name=_('Início da numeração de protocolo'), - default=1 + verbose_name=_("Início da numeração de protocolo"), default=1 ) # Linha 3 ------------------------- identificacao_de_documentos = models.CharField( max_length=254, - verbose_name=_('Formato da identificação dos documentos'), - default='{sigla} Nº {numero}/{ano}{-}{complemento} - {nome}', + verbose_name=_("Formato da identificação dos documentos"), + default="{sigla} Nº {numero}/{ano}{-}{complemento} - {nome}", help_text=""" Como mostrar a identificação dos documentos administrativos? Você pode usar um conjunto de combinações que pretender. @@ -153,102 +157,124 @@ class AppConfig(models.Model): Ainda pode ser usado {/}, {-}, {.} se você quiser que uma barra, traço, ou ponto seja adicionado apenas se o próximo campo que será usado tenha algum conteúdo (não use dois destes destes condicionais em sequência, somente o último será considerado). - """ + """, ) # MÓDULO PROPOSIÇÕES # Linha 1 ---------- sequencia_numeracao_proposicao = models.CharField( max_length=1, - verbose_name=_('Sequência de numeração de proposições'), - choices=SEQUENCIA_NUMERACAO_PROPOSICAO, default='A') + verbose_name=_("Sequência de numeração de proposições"), + choices=SEQUENCIA_NUMERACAO_PROPOSICAO, + default="A", + ) receber_recibo_proposicao = models.BooleanField( - verbose_name=_('Protocolar proposição somente com recibo?'), - choices=YES_NO_CHOICES, default=True) + verbose_name=_("Protocolar proposição somente com recibo?"), + choices=YES_NO_CHOICES, + default=True, + ) proposicao_incorporacao_obrigatoria = models.CharField( - verbose_name=_('Regra de incorporação de proposições e protocolo'), - max_length=1, choices=POLITICA_PROTOCOLO_CHOICES, default='O') + verbose_name=_("Regra de incorporação de proposições e protocolo"), + max_length=1, + choices=POLITICA_PROTOCOLO_CHOICES, + default="O", + ) escolher_numero_materia_proposicao = models.BooleanField( - verbose_name=_( - 'Indicar número da matéria a ser gerada na proposição?'), - choices=YES_NO_CHOICES, default=False) + verbose_name=_("Indicar número da matéria a ser gerada na proposição?"), + choices=YES_NO_CHOICES, + default=False, + ) # MÓDULO MATÉRIA LEGISLATIVA # Linha 1 ------------------ tramitacao_origem_fixa = models.BooleanField( verbose_name=_( - 'Fixar origem de novas tramitações como sendo a tramitação de destino da última tramitação?'), + "Fixar origem de novas tramitações como sendo a tramitação de destino da última tramitação?" + ), choices=YES_NO_CHOICES, default=True, - help_text=_('Ao utilizar a opção NÂO, você compreende que os controles ' - 'de origem e destino das tramitações são anulados, ' - 'podendo seu operador registrar quaisquer origem e ' - 'destino para as tramitações. Se você colocar Não, ' - 'fizer tramitações aleatórias e voltar para SIM, ' - 'o destino da tramitação mais recente será utilizado ' - 'para a origem de uma nova inserção!')) + help_text=_( + "Ao utilizar a opção NÂO, você compreende que os controles " + "de origem e destino das tramitações são anulados, " + "podendo seu operador registrar quaisquer origem e " + "destino para as tramitações. Se você colocar Não, " + "fizer tramitações aleatórias e voltar para SIM, " + "o destino da tramitação mais recente será utilizado " + "para a origem de uma nova inserção!" + ), + ) tramitacao_materia = models.BooleanField( - verbose_name=_( - 'Tramitar matérias anexadas junto com as matérias principais?'), - choices=YES_NO_CHOICES, default=True) + verbose_name=_("Tramitar matérias anexadas junto com as matérias principais?"), + choices=YES_NO_CHOICES, + default=True, + ) ordenacao_pesquisa_materia = models.CharField( max_length=1, - verbose_name=_( - 'Ordenação de Pesquisa da Matéria?'), - choices=ORDENACAO_PESQUISA_MATERIA, default='S') + verbose_name=_("Ordenação de Pesquisa da Matéria?"), + choices=ORDENACAO_PESQUISA_MATERIA, + default="S", + ) # MÓDULO NORMAS JURÍDICAS # MÓDULO TEXTOS ARTICULADOS # Linha 1 ----------------- texto_articulado_proposicao = models.BooleanField( - verbose_name=_('Usar Textos Articulados para Proposições'), - choices=YES_NO_CHOICES, default=False) + verbose_name=_("Usar Textos Articulados para Proposições"), + choices=YES_NO_CHOICES, + default=False, + ) texto_articulado_materia = models.BooleanField( - verbose_name=_('Usar Textos Articulados para Matérias'), - choices=YES_NO_CHOICES, default=False) + verbose_name=_("Usar Textos Articulados para Matérias"), + choices=YES_NO_CHOICES, + default=False, + ) texto_articulado_norma = models.BooleanField( - verbose_name=_('Usar Textos Articulados para Normas'), - choices=YES_NO_CHOICES, default=True) + verbose_name=_("Usar Textos Articulados para Normas"), + choices=YES_NO_CHOICES, + default=True, + ) # MÓDULO SESSÃO PLENÁRIA assinatura_ata = models.CharField( - verbose_name=_('Quem deve assinar a ata'), - max_length=1, choices=ASSINATURA_ATA_CHOICES, default='T') + verbose_name=_("Quem deve assinar a ata"), + max_length=1, + choices=ASSINATURA_ATA_CHOICES, + default="T", + ) # MÓDULO PAINEL cronometro_discurso = models.DurationField( - verbose_name=_('Cronômetro do Discurso'), - blank=True, - null=True) + verbose_name=_("Cronômetro do Discurso"), blank=True, null=True + ) cronometro_aparte = models.DurationField( - verbose_name=_('Cronômetro do Aparte'), - blank=True, - null=True) + verbose_name=_("Cronômetro do Aparte"), blank=True, null=True + ) cronometro_ordem = models.DurationField( - verbose_name=_('Cronômetro da Ordem'), - blank=True, - null=True) + verbose_name=_("Cronômetro da Ordem"), blank=True, null=True + ) cronometro_consideracoes = models.DurationField( - verbose_name=_('Cronômetro de Considerações Finais'), - blank=True, - null=True) + verbose_name=_("Cronômetro de Considerações Finais"), blank=True, null=True + ) mostrar_brasao_painel = models.BooleanField( - default=False, - verbose_name=_('Mostrar brasão da Casa no painel?')) + default=False, verbose_name=_("Mostrar brasão da Casa no painel?") + ) mostrar_voto = models.BooleanField( - verbose_name=_( - 'Exibir voto do Parlamentar antes de encerrar a votação?'), - choices=YES_NO_CHOICES, default=False) + verbose_name=_("Exibir voto do Parlamentar antes de encerrar a votação?"), + choices=YES_NO_CHOICES, + default=False, + ) # MÓDULO ESTATÍSTICAS DE ACESSO estatisticas_acesso_normas = models.CharField( max_length=1, - verbose_name=_('Estatísticas de acesso a normas'), - choices=RELATORIO_ATOS_ACESSADOS, default='N') + verbose_name=_("Estatísticas de acesso a normas"), + choices=RELATORIO_ATOS_ACESSADOS, + default="N", + ) # MÓDULO SEGURANÇA @@ -260,37 +286,48 @@ class AppConfig(models.Model): # choices=YES_NO_CHOICES, default=False) google_recaptcha_site_key = models.CharField( - verbose_name=_('Chave pública gerada pelo Google Recaptcha'), - max_length=256, default='') + verbose_name=_("Chave pública gerada pelo Google Recaptcha"), + max_length=256, + default="", + ) google_recaptcha_secret_key = models.CharField( - verbose_name=_('Chave privada gerada pelo Google Recaptcha'), - max_length=256, default='') + verbose_name=_("Chave privada gerada pelo Google Recaptcha"), + max_length=256, + default="", + ) google_analytics_id_metrica = models.CharField( - verbose_name=_('ID da Métrica do Google Analytics'), - max_length=256, default='') + verbose_name=_("ID da Métrica do Google Analytics"), max_length=256, default="" + ) class Meta: - verbose_name = _('Configurações da Aplicação') - verbose_name_plural = _('Configurações da Aplicação') + verbose_name = _("Configurações da Aplicação") + verbose_name_plural = _("Configurações da Aplicação") permissions = ( - ('menu_sistemas', _('Renderizar Menu Sistemas')), - ('view_tabelas_auxiliares', _('Visualizar Tabelas Auxiliares')), + ("menu_sistemas", _("Renderizar Menu Sistemas")), + ("view_tabelas_auxiliares", _("Visualizar Tabelas Auxiliares")), ) - ordering = ('-id',) + ordering = ("-id",) - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): fields = self._meta.get_fields() for f in fields: - if f.name != 'id' and not cache.get(f'sapl_{f.name}') is None: - cache.set(f'sapl_{f.name}', getattr(self, f.name), 600) - - return models.Model.save(self, force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields) + if f.name != "id" and not cache.get(f"sapl_{f.name}") is None: + cache.set(f"sapl_{f.name}", getattr(self, f.name), 600) + + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) @classmethod def attr(cls, attr): - value = cache.get(f'sapl_{attr}') + value = cache.get(f"sapl_{attr}") if not value is None: return value @@ -301,34 +338,33 @@ class AppConfig(models.Model): config.save() value = getattr(config, attr) - cache.set(f'sapl_{attr}', value, 600) + cache.set(f"sapl_{attr}", value, 600) return value def __str__(self): - return _('Configurações da Aplicação - %(id)s') % { - 'id': self.id} + return _("Configurações da Aplicação - %(id)s") % {"id": self.id} class TipoAutor(models.Model): descricao = models.CharField( max_length=50, - verbose_name=_('Descrição'), - help_text=_( - 'Obs: Não crie tipos de autores semelhante aos tipos fixos. ') + verbose_name=_("Descrição"), + help_text=_("Obs: Não crie tipos de autores semelhante aos tipos fixos. "), ) content_type = models.OneToOneField( ContentType, null=True, default=None, - verbose_name=_('Modelagem no SAPL'), - on_delete=models.PROTECT) + verbose_name=_("Modelagem no SAPL"), + on_delete=models.PROTECT, + ) class Meta: - ordering = ['descricao'] - verbose_name = _('Tipo de Autor') - verbose_name_plural = _('Tipos de Autor') + ordering = ["descricao"] + verbose_name = _("Tipo de Autor") + verbose_name_plural = _("Tipos de Autor") def __str__(self): return self.descricao @@ -337,40 +373,29 @@ class TipoAutor(models.Model): class Autor(models.Model): operadores = models.ManyToManyField( get_settings_auth_user_model(), - through='OperadorAutor', - through_fields=('autor', 'user'), + through="OperadorAutor", + through_fields=("autor", "user"), symmetrical=False, - related_name='autor_set', - verbose_name='Operadores') + related_name="autor_set", + verbose_name="Operadores", + ) tipo = models.ForeignKey( - TipoAutor, - verbose_name=_('Tipo do Autor'), - on_delete=models.PROTECT) + TipoAutor, verbose_name=_("Tipo do Autor"), on_delete=models.PROTECT + ) content_type = models.ForeignKey( - ContentType, - blank=True, - null=True, - default=None, - on_delete=models.PROTECT) - object_id = models.PositiveIntegerField( - 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')) - cargo = models.CharField( - max_length=50, - blank=True) + ContentType, blank=True, null=True, default=None, on_delete=models.PROTECT + ) + object_id = models.PositiveIntegerField(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")) + cargo = models.CharField(max_length=50, blank=True) class Meta: - verbose_name = _('Autor') - verbose_name_plural = _('Autores') - unique_together = (('content_type', 'object_id'), ) - ordering = ('nome',) + verbose_name = _("Autor") + verbose_name_plural = _("Autores") + unique_together = (("content_type", "object_id"),) + ordering = ("nome",) def __str__(self): if self.autor_related: @@ -378,107 +403,103 @@ class Autor(models.Model): else: if self.nome: if self.cargo: - return '{} - {}'.format(self.nome, self.cargo) + return "{} - {}".format(self.nome, self.cargo) else: return str(self.nome) - return '?' + return "?" class OperadorAutor(models.Model): - user = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Operador do Autor'), - related_name='operadorautor_set', - on_delete=CASCADE) + verbose_name=_("Operador do Autor"), + related_name="operadorautor_set", + on_delete=CASCADE, + ) autor = models.ForeignKey( Autor, - related_name='operadorautor_set', - verbose_name=_('Autor'), - on_delete=CASCADE) + related_name="operadorautor_set", + verbose_name=_("Autor"), + on_delete=CASCADE, + ) @property def user_name(self): - return '%s - %s' % ( - self.autor, - self.user) + return "%s - %s" % (self.autor, self.user) class Meta: - verbose_name = _('Operador do Autor') - verbose_name_plural = _('Operadores do Autor') + verbose_name = _("Operador do Autor") + verbose_name_plural = _("Operadores do Autor") unique_together = ( - ('user', 'autor', ),) + ( + "user", + "autor", + ), + ) def __str__(self): return self.user_name class AuditLog(models.Model): - - operation = ('C', 'D', 'U') + operation = ("C", "D", "U") MAX_DATA_LENGTH = 4096 # 4KB de texto - username = models.CharField(max_length=100, - verbose_name=_('username'), - blank=True, - db_index=True) - operation = models.CharField(max_length=1, - verbose_name=_('operation'), - db_index=True) - timestamp = models.DateTimeField(verbose_name=_('timestamp'), - db_index=True) + username = models.CharField( + max_length=100, verbose_name=_("username"), blank=True, db_index=True + ) + operation = models.CharField( + max_length=1, verbose_name=_("operation"), db_index=True + ) + timestamp = models.DateTimeField(verbose_name=_("timestamp"), db_index=True) # DEPRECATED FIELD! TO BE REMOVED (EVENTUALLY) - object = models.CharField(max_length=MAX_DATA_LENGTH, - blank=True, - verbose_name=_('object')) - data = JSONField(null=True, verbose_name=_('data')) - object_id = models.PositiveIntegerField(verbose_name=_('object_id'), - db_index=True) - model_name = models.CharField(max_length=100, - verbose_name=_('model'), - db_index=True) - app_name = models.CharField(max_length=100, - verbose_name=_('app'), - db_index=True) + object = models.CharField( + max_length=MAX_DATA_LENGTH, blank=True, verbose_name=_("object") + ) + data = JSONField(null=True, verbose_name=_("data")) + object_id = models.PositiveIntegerField(verbose_name=_("object_id"), db_index=True) + model_name = models.CharField( + max_length=100, verbose_name=_("model"), db_index=True + ) + app_name = models.CharField(max_length=100, verbose_name=_("app"), db_index=True) class Meta: - verbose_name = _('AuditLog') - verbose_name_plural = _('AuditLogs') - ordering = ('-id', '-timestamp') + verbose_name = _("AuditLog") + verbose_name_plural = _("AuditLogs") + ordering = ("-id", "-timestamp") def __str__(self): - return "[%s] %s %s.%s %s" % (self.timestamp, - self.operation, - self.app_name, - self.model_name, - self.username, - ) + return "[%s] %s %s.%s %s" % ( + self.timestamp, + self.operation, + self.app_name, + self.model_name, + self.username, + ) class Metadata(models.Model): content_type = models.ForeignKey( - ContentType, + ContentType, blank=True, null=True, default=None, on_delete=models.PROTECT + ) + object_id = models.PositiveIntegerField(blank=True, null=True, default=None) + content_object = GenericForeignKey("content_type", "object_id") + + metadata = JSONField( + verbose_name=_("Metadados"), blank=True, null=True, default=None, - on_delete=models.PROTECT) - object_id = models.PositiveIntegerField( - blank=True, - null=True, - default=None) - content_object = GenericForeignKey('content_type', 'object_id') - - metadata = JSONField( - verbose_name=_('Metadados'), - blank=True, null=True, default=None, encoder=DjangoJSONEncoder) + encoder=DjangoJSONEncoder, + ) class Meta: - verbose_name = _('Metadado') - verbose_name_plural = _('Metadados') - unique_together = (('content_type', 'object_id'), ) + verbose_name = _("Metadado") + verbose_name_plural = _("Metadados") + unique_together = (("content_type", "object_id"),) def __str__(self): - return f'Metadata de {self.content_object}' + return f"Metadata de {self.content_object}" diff --git a/sapl/base/receivers.py b/sapl/base/receivers.py index 281f4e818..bc2252489 100644 --- a/sapl/base/receivers.py +++ b/sapl/base/receivers.py @@ -1,37 +1,36 @@ -from datetime import datetime import inspect import logging +from datetime import datetime -from PyPDF4.pdf import PdfFileReader from asn1crypto import cms from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.core import serializers from django.core.files.uploadedfile import InMemoryUploadedFile, UploadedFile from django.db.models.fields.files import FileField -from django.db.models.signals import post_delete, post_save, \ - post_migrate, pre_save, pre_migrate +from django.db.models.signals import (post_delete, post_migrate, post_save, + pre_migrate, pre_save) from django.db.utils import DEFAULT_DB_ALIAS from django.dispatch import receiver from django.utils import timezone from django.utils.translation import gettext_lazy as _ +from PyPDF4.pdf import PdfFileReader from sapl.base.email_utils import do_envia_email_tramitacao -from sapl.base.models import AuditLog, TipoAutor, Autor, Metadata +from sapl.base.models import AuditLog, Autor, Metadata, TipoAutor from sapl.decorators import receiver_multi_senders from sapl.materia.models import Tramitacao from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import TramitacaoAdministrativo from sapl.utils import get_base_url, models_with_gr_for_model - models_with_gr_for_autor = models_with_gr_for_model(Autor) @receiver_multi_senders(post_save, senders=models_with_gr_for_autor) def handle_update_autor_related(sender, **kwargs): # for m in models_with_gr_for_autor: - instance = kwargs.get('instance') + instance = kwargs.get("instance") autor = instance.autor.first() if autor: autor.nome = str(instance) @@ -43,7 +42,7 @@ def handle_update_autor_related(sender, **kwargs): def handle_tramitacao_signal(sender, **kwargs): logger = logging.getLogger(__name__) - tramitacao = kwargs.get('instance') + tramitacao = kwargs.get("instance") if isinstance(tramitacao, Tramitacao): tipo = "materia" @@ -54,9 +53,9 @@ def handle_tramitacao_signal(sender, **kwargs): pilha_de_execucao = inspect.stack() for i in pilha_de_execucao: - if i.function == 'migrate': + if i.function == "migrate": return - request = i.frame.f_locals.get('request', None) + request = i.frame.f_locals.get("request", None) if request: break @@ -69,22 +68,25 @@ def handle_tramitacao_signal(sender, **kwargs): tipo, doc_mat, tramitacao.status, - tramitacao.unidade_tramitacao_destino) + tramitacao.unidade_tramitacao_destino, + ) except Exception as e: - logger.error(f'user={request.user.username}. Tramitação criada, mas e-mail de acompanhamento ' - 'de matéria não enviado. Há problemas na configuração ' - 'do e-mail. ' + str(e)) + logger.error( + f"user={request.user.username}. Tramitação criada, mas e-mail de acompanhamento " + "de matéria não enviado. Há problemas na configuração " + "do e-mail. " + str(e) + ) @receiver(post_delete) def status_tramitacao_materia(sender, instance, **kwargs): if sender == Tramitacao: - if instance.status.indicador == 'F': + if instance.status.indicador == "F": materia = instance.materia materia.em_tramitacao = True materia.save() elif sender == TramitacaoAdministrativo: - if instance.status.indicador == 'F': + if instance.status.indicador == "F": documento = instance.documento documento.tramitacao = True documento.save() @@ -92,15 +94,17 @@ def status_tramitacao_materia(sender, instance, **kwargs): def audit_log_function(sender, **kwargs): try: - if not (sender._meta.app_config.name.startswith('sapl') or - sender._meta.label == settings.AUTH_USER_MODEL): + if not ( + sender._meta.app_config.name.startswith("sapl") + or sender._meta.label == settings.AUTH_USER_MODEL + ): return except: # não é necessário usar logger, aqui é usada apenas para # eliminar um o if complexo return - instance = kwargs.get('instance') + instance = kwargs.get("instance") if instance._meta.model == AuditLog: return @@ -109,9 +113,9 @@ def audit_log_function(sender, **kwargs): u = None pilha_de_execucao = inspect.stack() for i in pilha_de_execucao: - if i.function == 'migrate': + if i.function == "migrate": return - r = i.frame.f_locals.get('request', None) + r = i.frame.f_locals.get("request", None) try: if r.user._meta.label == settings.AUTH_USER_MODEL: u = r.user @@ -122,15 +126,16 @@ def audit_log_function(sender, **kwargs): pass try: - operation = kwargs.get('operation') + operation = kwargs.get("operation") user = u model_name = instance.__class__.__name__ app_name = instance._meta.app_label object_id = instance.id try: import json + # [1:-1] below removes the surrounding square brackets - str_data = serializers.serialize('json', [instance])[1:-1] + str_data = serializers.serialize("json", [instance])[1:-1] data = json.loads(str_data) except: # old version capped string at AuditLog.MAX_DATA_LENGTH @@ -140,58 +145,61 @@ def audit_log_function(sender, **kwargs): if user: username = user.username else: - username = '' - - AuditLog.objects.create(username=username, - operation=operation, - model_name=model_name, - app_name=app_name, - timestamp=timezone.now(), - object_id=object_id, - object='', - data=data) + username = "" + + AuditLog.objects.create( + username=username, + operation=operation, + model_name=model_name, + app_name=app_name, + timestamp=timezone.now(), + object_id=object_id, + object="", + data=data, + ) except Exception as e: - logger.error('Error saving auditing log object') + logger.error("Error saving auditing log object") logger.error(e) @receiver(post_delete) def audit_log_post_delete(sender, **kwargs): - audit_log_function(sender, operation='D', **kwargs) + audit_log_function(sender, operation="D", **kwargs) @receiver(post_save) def audit_log_post_save(sender, **kwargs): - operation = 'C' if kwargs.get('created') else 'U' + operation = "C" if kwargs.get("created") else "U" audit_log_function(sender, operation=operation, **kwargs) -def cria_models_tipo_autor(app_config=None, verbosity=2, interactive=True, - using=DEFAULT_DB_ALIAS, **kwargs): - - print("\n\033[93m\033[1m{}\033[0m".format( - _('Atualizando registros TipoAutor do SAPL:'))) +def cria_models_tipo_autor( + app_config=None, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, **kwargs +): + print( + "\n\033[93m\033[1m{}\033[0m".format( + _("Atualizando registros TipoAutor do SAPL:") + ) + ) for model in models_with_gr_for_autor: content_type = ContentType.objects.get_for_model(model) - tipo_autor = TipoAutor.objects.filter( - content_type=content_type.id).exists() + tipo_autor = TipoAutor.objects.filter(content_type=content_type.id).exists() if tipo_autor: - msg1 = "Carga de {} não efetuada.".format( - TipoAutor._meta.verbose_name) + msg1 = "Carga de {} não efetuada.".format(TipoAutor._meta.verbose_name) msg2 = " Já Existe um {} {} relacionado...".format( - TipoAutor._meta.verbose_name, - model._meta.verbose_name) + TipoAutor._meta.verbose_name, model._meta.verbose_name + ) msg = " {}{}".format(msg1, msg2) else: novo_autor = TipoAutor() novo_autor.content_type_id = content_type.id novo_autor.descricao = model._meta.verbose_name novo_autor.save() - msg1 = "Carga de {} efetuada.".format( - TipoAutor._meta.verbose_name) + msg1 = "Carga de {} efetuada.".format(TipoAutor._meta.verbose_name) msg2 = " {} {} criado...".format( - TipoAutor._meta.verbose_name, content_type.model) + TipoAutor._meta.verbose_name, content_type.model + ) msg = " {}{}".format(msg1, msg2) print(msg) # Disconecta função para evitar a chamada repetidas vezes. @@ -202,62 +210,60 @@ post_migrate.connect(receiver=cria_models_tipo_autor) def signed_files_extraction_function(sender, instance, **kwargs): - def run_signed_name_and_date_via_fields(fields): signs = [] for key, field in fields.items(): - - if '/FT' not in field and field['/FT'] != '/Sig': + if "/FT" not in field and field["/FT"] != "/Sig": continue - if '/V' not in field: + if "/V" not in field: continue - content_sign = field['/V']['/Contents'] - nome = 'Nome do assinante não localizado.' - oname = '' + content_sign = field["/V"]["/Contents"] + nome = "Nome do assinante não localizado." + oname = "" try: info = cms.ContentInfo.load(content_sign) - signed_data = info['content'] + signed_data = info["content"] oun_old = [] - for cert in signed_data['certificates']: - subject = cert.native['tbs_certificate']['subject'] - issuer = cert.native['tbs_certificate']['issuer'] - oname = issuer.get('organization_name', '') + for cert in signed_data["certificates"]: + subject = cert.native["tbs_certificate"]["subject"] + issuer = cert.native["tbs_certificate"]["issuer"] + oname = issuer.get("organization_name", "") - if oname in ('Gov-Br', '1Doc'): - nome = subject['common_name'].split(':')[0] + if oname in ("Gov-Br", "1Doc"): + nome = subject["common_name"].split(":")[0] continue - oun = subject['organizational_unit_name'] + oun = subject["organizational_unit_name"] if isinstance(oun, str): continue if len(oun) > len(oun_old): oun_old = oun - nome = subject['common_name'].split(':')[0] + nome = subject["common_name"].split(":")[0] if oun and isinstance(oun, list) and len(oun) == 4: - oname += ' - ' + oun[3] + oname += " - " + oun[3] break except: - if '/Name' in field['/V']: - nome = field['/V']['/Name'] + if "/Name" in field["/V"]: + nome = field["/V"]["/Name"] fd = None try: - data = str(field['/V']['/M']) + data = str(field["/V"]["/M"]) - if 'D:' not in data: + if "D:" not in data: data = None else: - if not data.endswith('Z'): - data = data.replace('Z', '+') - data = data.replace("'", '') + if not data.endswith("Z"): + data = data.replace("Z", "+") + data = data.replace("'", "") - fd = datetime.strptime(data[2:], '%Y%m%d%H%M%S%z') + fd = datetime.strptime(data[2:], "%Y%m%d%H%M%S%z") except: pass @@ -288,13 +294,17 @@ def signed_files_extraction_function(sender, instance, **kwargs): pdf = PdfFileReader(file) fields = pdf.getFields() fields_br = list( - map(lambda x: x.get('/V', {}).get('/ByteRange', []), fields.values())) + map(lambda x: x.get("/V", {}).get("/ByteRange", []), fields.values()) + ) except Exception as e: try: pdf = PdfFileReader(file, strict=False) fields = pdf.getFields() fields_br = list( - map(lambda x: x.get('/V', {}).get('/ByteRange', []), fields.values())) + map( + lambda x: x.get("/V", {}).get("/ByteRange", []), fields.values() + ) + ) except Exception as ee: fields = ee @@ -307,50 +317,49 @@ def signed_files_extraction_function(sender, instance, **kwargs): return signs for n in byterange: - start = pdfdata.find(b"[", n) stop = pdfdata.find(b"]", start) assert n != -1 and start != -1 and stop != -1 n += 1 - br = [int(i, 10) for i in pdfdata[start + 1: stop].split()] + br = [int(i, 10) for i in pdfdata[start + 1 : stop].split()] if br in fields_br: continue - contents = pdfdata[br[0] + br[1] + 1: br[2] - 1] + contents = pdfdata[br[0] + br[1] + 1 : br[2] - 1] bcontents = bytes.fromhex(contents.decode("utf8")) - data1 = pdfdata[br[0]: br[0] + br[1]] - data2 = pdfdata[br[2]: br[2] + br[3]] - #signedData = data1 + data2 + data1 = pdfdata[br[0] : br[0] + br[1]] + data2 = pdfdata[br[2] : br[2] + br[3]] + # signedData = data1 + data2 - not_nome = nome = 'Nome do assinante não localizado.' - oname = '' + not_nome = nome = "Nome do assinante não localizado." + oname = "" try: info = cms.ContentInfo.load(bcontents) - signed_data = info['content'] + signed_data = info["content"] oun_old = [] - for cert in signed_data['certificates']: - subject = cert.native['tbs_certificate']['subject'] - issuer = cert.native['tbs_certificate']['issuer'] - oname = issuer.get('organization_name', '') + for cert in signed_data["certificates"]: + subject = cert.native["tbs_certificate"]["subject"] + issuer = cert.native["tbs_certificate"]["issuer"] + oname = issuer.get("organization_name", "") - if oname in ('Gov-Br', '1Doc'): - nome = subject['common_name'].split(':')[0] + if oname in ("Gov-Br", "1Doc"): + nome = subject["common_name"].split(":")[0] continue - oun = subject['organizational_unit_name'] + oun = subject["organizational_unit_name"] if isinstance(oun, str): continue if len(oun) > len(oun_old): oun_old = oun - nome = subject['common_name'].split(':')[0] + nome = subject["common_name"].split(":")[0] if oun and isinstance(oun, list) and len(oun) == 4: - oname += ' - ' + oun[3] + oname += " - " + oun[3] break except Exception as e: @@ -366,50 +375,51 @@ def signed_files_extraction_function(sender, instance, **kwargs): return signs def signed_name_and_date_extract(file): - try: signs = run_signed_name_and_date_extract(file) except: return {} - signs = sorted(signs, key=lambda sign: ( - sign[0], sign[1][1], sign[1][0])) + signs = sorted(signs, key=lambda sign: (sign[0], sign[1][1], sign[1][0])) signs_dict = {} for s in signs: - if s[0] not in signs_dict or 'ICP' in s[1][1] and 'ICP' not in signs_dict[s[0]][1]: + if ( + s[0] not in signs_dict + or "ICP" in s[1][1] + and "ICP" not in signs_dict[s[0]][1] + ): signs_dict[s[0]] = s[1] - signs = sorted(signs_dict.items(), key=lambda sign: ( - sign[0], sign[1][1], sign[1][0])) + signs = sorted( + signs_dict.items(), key=lambda sign: (sign[0], sign[1][1], sign[1][0]) + ) sr = [] for s in signs: - tt = s[0].title().split(' ') + tt = s[0].title().split(" ") for idx, t in enumerate(tt): - if t in ('Dos', 'De', 'Da', 'Do', 'Das', 'E'): + if t in ("Dos", "De", "Da", "Do", "Das", "E"): tt[idx] = t.lower() - sr.append((' '.join(tt), s[1])) + sr.append((" ".join(tt), s[1])) signs = sr - meta_signs = { - 'autores': [], - 'admin': [] - } + meta_signs = {"autores": [], "admin": []} for s in signs: # cn = # settings.CERT_PRIVATE_KEY_NAME - #meta_signs['admin' if s[0] == cn else 'autores'].append(s) - meta_signs['autores'].append(s) + # meta_signs['admin' if s[0] == cn else 'autores'].append(s) + meta_signs["autores"].append(s) return meta_signs def filefield_from_model(m): fields = m._meta.get_fields() - fields = tuple(map(lambda f: f.name, filter( - lambda x: isinstance(x, FileField), fields))) + fields = tuple( + map(lambda f: f.name, filter(lambda x: isinstance(x, FileField), fields)) + ) return fields FIELDFILE_NAME = filefield_from_model(instance) @@ -419,19 +429,17 @@ def signed_files_extraction_function(sender, instance, **kwargs): try: md = Metadata.objects.get( - content_type=ContentType.objects.get_for_model( - instance._meta.model), - object_id=instance.id,).metadata + content_type=ContentType.objects.get_for_model(instance._meta.model), + object_id=instance.id, + ).metadata except: md = {} for fn in FIELDFILE_NAME: # fn -> field_name ff = getattr(instance, fn) # ff -> file_field - if md and 'signs' in md and \ - fn in md['signs'] and\ - md['signs'][fn]: - md['signs'][fn] = {} + if md and "signs" in md and fn in md["signs"] and md["signs"][fn]: + md["signs"][fn] = {} if not ff: continue @@ -448,35 +456,34 @@ def signed_files_extraction_function(sender, instance, **kwargs): file.seek(0) meta_signs = signed_name_and_date_extract(file) - if not meta_signs or not meta_signs['autores'] and not meta_signs['admin']: + if not meta_signs or not meta_signs["autores"] and not meta_signs["admin"]: continue if not md: - md = {'signs': {}} + md = {"signs": {}} - if 'signs' not in md: - md['signs'] = {} + if "signs" not in md: + md["signs"] = {} - md['signs'][fn] = meta_signs + md["signs"][fn] = meta_signs except Exception as e: # print(e) pass if md: metadata = Metadata.objects.get_or_create( - content_type=ContentType.objects.get_for_model( - instance._meta.model), - object_id=instance.id,) + content_type=ContentType.objects.get_for_model(instance._meta.model), + object_id=instance.id, + ) metadata[0].metadata = md metadata[0].save() -@receiver(pre_save, dispatch_uid='signed_files_extraction_pre_save_signal') +@receiver(pre_save, dispatch_uid="signed_files_extraction_pre_save_signal") def signed_files_extraction_pre_save_signal(sender, instance, **kwargs): - signed_files_extraction_function(sender, instance, **kwargs) -@receiver(pre_migrate, dispatch_uid='disconnect_signals_pre_migrate') +@receiver(pre_migrate, dispatch_uid="disconnect_signals_pre_migrate") def disconnect_signals_pre_migrate(*args, **kwargs): - pre_save.disconnect(dispatch_uid='signed_files_extraction_pre_save_signal') + pre_save.disconnect(dispatch_uid="signed_files_extraction_pre_save_signal") diff --git a/sapl/base/search_indexes.py b/sapl/base/search_indexes.py index d0432aded..41f3cb5b3 100644 --- a/sapl/base/search_indexes.py +++ b/sapl/base/search_indexes.py @@ -21,7 +21,6 @@ from sapl.utils import RemoveTag class TextExtractField(CharField): - backend = None logger = logging.getLogger(__name__) @@ -30,39 +29,40 @@ class TextExtractField(CharField): assert self.model_attr if not isinstance(self.model_attr, (list, tuple)): - self.model_attr = (self.model_attr, ) + self.model_attr = (self.model_attr,) def solr_extraction(self, arquivo): if not self.backend: - self.backend = connections['default'].get_backend() + self.backend = connections["default"].get_backend() try: - with open(arquivo.path, 'rb') as f: + with open(arquivo.path, "rb") as f: content = self.backend.extract_file_contents(f) - data = '' + data = "" if content: # update from Solr 7.5 to 8.9 - if content['contents']: - data += content['contents'] - if content['file']: - data += content['file'] + if content["contents"]: + data += content["contents"] + if content["file"]: + data += content["file"] return data except Exception as e: - print('erro processando arquivo: ' % arquivo.path) + print("erro processando arquivo: " % arquivo.path) self.logger.error(arquivo.path) - self.logger.error('erro processando arquivo: ' % arquivo.path) - data = '' + self.logger.error("erro processando arquivo: " % arquivo.path) + data = "" return data def print_error(self, arquivo, error): - msg = 'Erro inesperado processando arquivo %s erro: %s' % ( - arquivo.path, error) + msg = "Erro inesperado processando arquivo %s erro: %s" % (arquivo.path, error) print(msg, error) self.logger.error(msg, error) def file_extractor(self, arquivo): - if not os.path.exists(arquivo.path) or \ - not os.path.splitext(arquivo.path)[1][:1]: - return '' + if ( + not os.path.exists(arquivo.path) + or not os.path.splitext(arquivo.path)[1][:1] + ): + return "" # Em ambiente de produção utiliza-se o SOLR if SOLR_URL: @@ -71,33 +71,34 @@ class TextExtractField(CharField): except Exception as err: print(str(err)) self.print_error(arquivo, err) - return '' + return "" def ta_extractor(self, value): r = [] - for ta in value.filter(privacidade__in=[ - STATUS_TA_PUBLIC, - STATUS_TA_IMMUTABLE_PUBLIC]): - dispositivos = Dispositivo.objects.filter( - Q(ta=ta) | Q(ta_publicado=ta) - ).order_by( - 'ordem' - ).annotate( - rotulo_texto=Concat( - F('rotulo'), Value(' '), F('texto'), - output_field=TextField(), + for ta in value.filter( + privacidade__in=[STATUS_TA_PUBLIC, STATUS_TA_IMMUTABLE_PUBLIC] + ): + dispositivos = ( + Dispositivo.objects.filter(Q(ta=ta) | Q(ta_publicado=ta)) + .order_by("ordem") + .annotate( + rotulo_texto=Concat( + F("rotulo"), + Value(" "), + F("texto"), + output_field=TextField(), + ) ) - ).values_list( - 'rotulo_texto', flat=True) + .values_list("rotulo_texto", flat=True) + ) r += list(filter(lambda x: x.strip(), dispositivos)) - return ' '.join(r) + return " ".join(r) def string_extractor(self, value): return value def extract_data(self, obj): - - data = '' + data = "" for attr, func in self.model_attr: if not hasattr(obj, attr) or not hasattr(self, func): @@ -106,32 +107,33 @@ class TextExtractField(CharField): value = getattr(obj, attr) if not value: continue - data += getattr(self, func)(value) + ' ' + data += getattr(self, func)(value) + " " - data = data.replace('\\n', ' ') + data = data.replace("\\n", " ") return data def prepare_template(self, obj): app_label, model_name = get_model_ct_tuple(obj) - template_names = ['search/indexes/%s/%s_%s.txt' % - (app_label, model_name, self.instance_name)] + template_names = [ + "search/indexes/%s/%s_%s.txt" % (app_label, model_name, self.instance_name) + ] t = loader.select_template(template_names) - return t.render({'object': obj, - 'extracted': self.extract_data(obj)}) + return t.render({"object": obj, "extracted": self.extract_data(obj)}) class DocumentoAcessorioIndex(SearchIndex, Indexable): model = DocumentoAcessorio text = TextExtractField( - document=True, use_template=True, + document=True, + use_template=True, model_attr=( - ('arquivo', 'file_extractor'), - ('ementa', 'string_extractor'), - ('indexacao', 'string_extractor'), - ) + ("arquivo", "file_extractor"), + ("ementa", "string_extractor"), + ("indexacao", "string_extractor"), + ), ) def __init__(self, **kwargs): @@ -145,44 +147,47 @@ class DocumentoAcessorioIndex(SearchIndex, Indexable): return self.get_model().objects.all() def get_updated_field(self): - return 'data_ultima_atualizacao' + return "data_ultima_atualizacao" class NormaJuridicaIndex(DocumentoAcessorioIndex): model = NormaJuridica text = TextExtractField( - document=True, use_template=True, + document=True, + use_template=True, model_attr=( - ('texto_integral', 'file_extractor'), - ('texto_articulado', 'ta_extractor'), - ('ementa', 'string_extractor'), - ('indexacao', 'string_extractor'), - ('observacao', 'string_extractor'), - ) + ("texto_integral", "file_extractor"), + ("texto_articulado", "ta_extractor"), + ("ementa", "string_extractor"), + ("indexacao", "string_extractor"), + ("observacao", "string_extractor"), + ), ) class MateriaLegislativaIndex(DocumentoAcessorioIndex): model = MateriaLegislativa text = TextExtractField( - document=True, use_template=True, + document=True, + use_template=True, model_attr=( - ('texto_original', 'file_extractor'), - ('texto_articulado', 'ta_extractor'), - ('ementa', 'string_extractor'), - ('indexacao', 'string_extractor'), - ('observacao', 'string_extractor'), - ) + ("texto_original", "file_extractor"), + ("texto_articulado", "ta_extractor"), + ("ementa", "string_extractor"), + ("indexacao", "string_extractor"), + ("observacao", "string_extractor"), + ), ) class SessaoPlenariaIndex(DocumentoAcessorioIndex): model = SessaoPlenaria text = TextExtractField( - document=True, use_template=True, + document=True, + use_template=True, model_attr=( - ('upload_ata', 'file_extractor'), - ('upload_anexo', 'file_extractor'), - ('upload_pauta', 'file_extractor'), - ) + ("upload_ata", "file_extractor"), + ("upload_anexo", "file_extractor"), + ("upload_pauta", "file_extractor"), + ), ) diff --git a/sapl/base/templatetags/base_tags.py b/sapl/base/templatetags/base_tags.py index 1583cd75f..9e5bde5c5 100644 --- a/sapl/base/templatetags/base_tags.py +++ b/sapl/base/templatetags/base_tags.py @@ -1,4 +1,3 @@ - from django import template register = template.Library() @@ -6,4 +5,6 @@ register = template.Library() @register.filter def tipoautor_contenttype_list(tipo): - return 'sapl.' + tipo.content_type.app_label + ':' + tipo.content_type.model + '_list' + return ( + "sapl." + tipo.content_type.app_label + ":" + tipo.content_type.model + "_list" + ) diff --git a/sapl/base/templatetags/common_tags.py b/sapl/base/templatetags/common_tags.py index 84f61b64f..cfcc38145 100644 --- a/sapl/base/templatetags/common_tags.py +++ b/sapl/base/templatetags/common_tags.py @@ -7,22 +7,24 @@ from django.utils.safestring import mark_safe from webpack_loader import utils from sapl.base.models import AppConfig -from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa, Proposicao +from sapl.materia.models import (DocumentoAcessorio, MateriaLegislativa, + Proposicao) from sapl.norma.models import NormaJuridica from sapl.parlamentares.models import Filiacao from sapl.sessao.models import SessaoPlenaria -from sapl.utils import filiacao_data, SEPARADOR_HASH_PROPOSICAO, is_report_allowed +from sapl.utils import (SEPARADOR_HASH_PROPOSICAO, filiacao_data, + is_report_allowed) register = template.Library() def get_class(class_string): - if not hasattr(class_string, '__bases__'): + if not hasattr(class_string, "__bases__"): class_string = str(class_string) - dot = class_string.rindex('.') - mod_name, class_name = class_string[:dot], class_string[dot + 1:] + dot = class_string.rindex(".") + mod_name, class_name = class_string[:dot], class_string[dot + 1 :] if class_name: - return getattr(__import__(mod_name, {}, {}, [str('')]), class_name) + return getattr(__import__(mod_name, {}, {}, [str("")]), class_name) @register.simple_tag @@ -66,7 +68,13 @@ def model_verbose_name_plural(class_name): @register.filter def obfuscate_value(value, key): - if key in ["hash", "google_recaptcha_secret_key", "password", "google_recaptcha_site_key", "hash_code"]: + if key in [ + "hash", + "google_recaptcha_secret_key", + "password", + "google_recaptcha_site_key", + "hash_code", + ]: return "***************" return value @@ -98,7 +106,7 @@ def meta_model_value(instance, attr): try: return getattr(instance._meta, attr) except: - return '' + return "" @register.filter @@ -121,15 +129,16 @@ def sort_by_keys(value, key): transformed = [] id_props = [x.id for x in value] qs = Proposicao.objects.filter(pk__in=id_props) - key_descricao = {'1': 'data_envio', - '-1': '-data_envio', - '2': 'tipo', - '-2': '-tipo', - '3': 'descricao', - '-3': '-descricao', - '4': 'autor', - '-4': '-autor' - } + key_descricao = { + "1": "data_envio", + "-1": "-data_envio", + "2": "tipo", + "-2": "-tipo", + "3": "descricao", + "-3": "-descricao", + "4": "autor", + "-4": "-autor", + } transformed = qs.order_by(key_descricao[key]) return transformed @@ -176,7 +185,7 @@ def isinst(value, class_str): @register.filter @stringfilter def strip_hash(value): - vet = value.split('/') + vet = value.split("/") if len(vet) == 2: return vet[0][1:] else: @@ -193,7 +202,7 @@ def get_add_perm(value, arg): except AttributeError: return None nome_model = view.__class__.model.__name__.lower() - can_add = '.add_' + nome_model + can_add = ".add_" + nome_model return perm.__contains__(nome_app + can_add) @@ -208,7 +217,7 @@ def get_change_perm(value, arg): except AttributeError: return None nome_model = view.__class__.model.__name__.lower() - can_change = '.change_' + nome_model + can_change = ".change_" + nome_model return perm.__contains__(nome_app + can_change) @@ -223,7 +232,7 @@ def get_delete_perm(value, arg): except AttributeError: return None nome_model = view.__class__.model.__name__.lower() - can_delete = '.delete_' + nome_model + can_delete = ".delete_" + nome_model return perm.__contains__(nome_app + can_delete) @@ -232,8 +241,9 @@ def get_delete_perm(value, arg): def ultima_filiacao(value): parlamentar = value - ultima_filiacao = Filiacao.objects.filter( - parlamentar=parlamentar).order_by('-data').first() + ultima_filiacao = ( + Filiacao.objects.filter(parlamentar=parlamentar).order_by("-data").first() + ) if ultima_filiacao: return ultima_filiacao.partido @@ -249,28 +259,27 @@ def get_config_attr(attribute): @register.filter def str2intabs(value): if not isinstance(value, str): - return '' + return "" try: v = int(value) v = abs(v) return v except: - return '' + return "" @register.filter def has_iframe(request): - - iframe = request.session.get('iframe', False) - if not iframe and 'iframe' in request.GET: - ival = request.GET['iframe'] + iframe = request.session.get("iframe", False) + if not iframe and "iframe" in request.GET: + ival = request.GET["iframe"] if ival and int(ival) == 1: - request.session['iframe'] = True + request.session["iframe"] = True return True - elif 'iframe' in request.GET: - ival = request.GET['iframe'] + elif "iframe" in request.GET: + ival = request.GET["iframe"] if ival and int(ival) == 0: - del request.session['iframe'] + del request.session["iframe"] return False return iframe @@ -278,7 +287,7 @@ def has_iframe(request): @register.filter def url(value): - if value.startswith('http://') or value.startswith('https://'): + if value.startswith("http://") or value.startswith("https://"): return True return False @@ -308,33 +317,37 @@ def youtube_url(value): @register.filter def facebook_url(value): value = value.lower() - facebook_pattern = r"^((https?://)?((www|pt-br)\.)?facebook\.com(\/.+)?\/videos(\/.*)?)" + facebook_pattern = ( + r"^((https?://)?((www|pt-br)\.)?facebook\.com(\/.+)?\/videos(\/.*)?)" + ) r = re.findall(facebook_pattern, value) return True if r else False @register.filter def youtube_id(value): - from urllib.parse import urlparse, parse_qs + from urllib.parse import parse_qs, urlparse + u_pars = urlparse(value) - quer_v = parse_qs(u_pars.query).get('v') + quer_v = parse_qs(u_pars.query).get("v") if quer_v: return quer_v[0] - return '' + return "" @register.filter def file_extension(value): import pathlib - return pathlib.Path(value).suffix.replace('.', '') + + return pathlib.Path(value).suffix.replace(".", "") @register.filter def cronometro_to_seconds(value): - if not AppConfig.attr('cronometro_' + value): + if not AppConfig.attr("cronometro_" + value): return 0 - return AppConfig.attr('cronometro_' + value).seconds + return AppConfig.attr("cronometro_" + value).seconds @register.filter @@ -345,27 +358,25 @@ def to_list_pk(object_list): @register.filter def search_get_model(object): if type(object) == MateriaLegislativa: - return 'm' + return "m" elif type(object) == DocumentoAcessorio: - return 'd' + return "d" elif type(object) == NormaJuridica: - return 'n' + return "n" elif type(object) == SessaoPlenaria: - return 's' + return "s" return None @register.filter def urldetail_content_type(obj, value): - return '%s:%s_detail' % ( - value._meta.app_config.name, obj.content_type.model) + return "%s:%s_detail" % (value._meta.app_config.name, obj.content_type.model) @register.filter def urldetail(obj): - return '%s:%s_detail' % ( - obj._meta.app_config.name, obj._meta.model_name) + return "%s:%s_detail" % (obj._meta.app_config.name, obj._meta.model_name) @register.filter @@ -373,7 +384,7 @@ def filiacao_data_filter(parlamentar, data_inicio): try: filiacao = filiacao_data(parlamentar, data_inicio) except Exception: - filiacao = '' + filiacao = "" return filiacao @@ -382,7 +393,7 @@ def filiacao_intervalo_filter(parlamentar, date_range): try: filiacao = filiacao_data(parlamentar, date_range[0], date_range[1]) except Exception: - filiacao = '' + filiacao = "" return filiacao @@ -390,10 +401,11 @@ def filiacao_intervalo_filter(parlamentar, date_range): def render_chunk_vendors(extension=None): try: tags = utils.get_as_tags( - 'chunk-vendors', extension=extension, config='DEFAULT', attrs='') - return mark_safe('\n'.join(tags)) + "chunk-vendors", extension=extension, config="DEFAULT", attrs="" + ) + return mark_safe("\n".join(tags)) except: - return '' + return "" @register.filter(is_safe=True) @@ -416,4 +428,4 @@ def is_report_visible(request, url_path=None): @register.filter def sort_by_index(queryset, index): - return sorted(queryset, key=lambda x: x[index]) \ No newline at end of file + return sorted(queryset, key=lambda x: x[index]) diff --git a/sapl/base/templatetags/menus.py b/sapl/base/templatetags/menus.py index 93158bf05..b7030e2a9 100644 --- a/sapl/base/templatetags/menus.py +++ b/sapl/base/templatetags/menus.py @@ -1,27 +1,26 @@ import logging +import yaml from django import template from django.urls import reverse from django.utils.translation import gettext_lazy as _ -import yaml - register = template.Library() logger = logging.getLogger(__name__) -@register.inclusion_tag('menus/menu.html', takes_context=True) +@register.inclusion_tag("menus/menu.html", takes_context=True) def menu(context, path=None): return nav_run(context, path) -@register.inclusion_tag('menus/subnav.html', takes_context=True) +@register.inclusion_tag("menus/subnav.html", takes_context=True) def subnav(context, path=None): return nav_run(context, path) -@register.inclusion_tag('menus/nav.html', takes_context=True) +@register.inclusion_tag("menus/nav.html", takes_context=True) def navbar(context, path=None): return nav_run(context, path) @@ -42,14 +41,14 @@ def nav_run(context, path=None): será realizado o teste de permissão para renderizá-lo. """ menu = None - root_pk = context.get('root_pk', None) + root_pk = context.get("root_pk", None) if not root_pk: - obj = context.get('object', None) + obj = context.get("object", None) if obj: root_pk = obj.pk - if root_pk or 'subnav_template_name' in context or path: - request = context['request'] + if root_pk or "subnav_template_name" in context or path: + request = context["request"] """ As implementações das Views de Modelos que são dados auxiliares e @@ -60,14 +59,14 @@ def nav_run(context, path=None): """ rm = request.resolver_match - app_template = rm.app_name.rsplit('.', 1)[-1] + app_template = rm.app_name.rsplit(".", 1)[-1] if path: yaml_path = path - elif 'subnav_template_name' in context: - yaml_path = context['subnav_template_name'] + elif "subnav_template_name" in context: + yaml_path = context["subnav_template_name"] else: - yaml_path = '%s/%s' % (app_template, 'subnav.yaml') + yaml_path = "%s/%s" % (app_template, "subnav.yaml") if not yaml_path: return @@ -88,44 +87,47 @@ def nav_run(context, path=None): menu = yaml.load(rendered, yaml.Loader) resolve_urls_inplace(menu, root_pk, rm, context) except Exception as e: - raise Exception(_("""Erro na conversão do yaml %s. App: %s. + raise Exception( + _( + """Erro na conversão do yaml %s. App: %s. Erro: %s - """) % ( - yaml_path, rm.app_name, str(e))) + """ + ) + % (yaml_path, rm.app_name, str(e)) + ) - return {'menu': menu} + return {"menu": menu} def resolve_urls_inplace(menu, pk, rm, context): if isinstance(menu, list): - list_active = '' + list_active = "" for item in menu: menuactive = resolve_urls_inplace(item, pk, rm, context) list_active = menuactive if menuactive else list_active if not isinstance(item, list): - item['active'] = menuactive + item["active"] = menuactive return list_active else: - if 'url' in menu: - - url_name = menu['url'] - - if 'check_permission' in menu and not context[ - 'request'].user.has_perm(menu['check_permission']): - menu['url'] = '' - menu['active'] = '' + if "url" in menu: + url_name = menu["url"] + + if "check_permission" in menu and not context["request"].user.has_perm( + menu["check_permission"] + ): + menu["url"] = "" + menu["active"] = "" else: - if '/' in url_name: + if "/" in url_name: pass - elif ':' in url_name: + elif ":" in url_name: try: - menu['url'] = reverse('%s' % menu['url']) + menu["url"] = reverse("%s" % menu["url"]) except: try: - menu['url'] = reverse('%s' % menu['url'], - kwargs={'pk': pk}) + menu["url"] = reverse("%s" % menu["url"], kwargs={"pk": pk}) except: # tem que ser root_pk pois quando está sendo # renderizado um detail, update, delete @@ -149,18 +151,20 @@ def resolve_urls_inplace(menu, pk, rm, context): 2) Se existe no contexto um desses itens: - context['root_pk'] pk do master - context['object'] objeto do master - """.format(menu['title'], menu['url']) + """.format( + menu["title"], menu["url"] + ) logger.error(log) raise Exception(log) else: try: - menu['url'] = reverse('%s:%s' % ( - rm.app_name, menu['url'])) + menu["url"] = reverse("%s:%s" % (rm.app_name, menu["url"])) except: try: - menu['url'] = reverse('%s:%s' % ( - rm.app_name, menu['url']), kwargs={'pk': pk}) + menu["url"] = reverse( + "%s:%s" % (rm.app_name, menu["url"]), kwargs={"pk": pk} + ) except: log = """Erro na construção do Menu: menu: {} @@ -169,13 +173,16 @@ def resolve_urls_inplace(menu, pk, rm, context): 2) Se existe no contexto um desses itens: - context['root_pk'] pk do master - context['object'] objeto do master - """.format(menu['title'], menu['url']) + """.format( + menu["title"], menu["url"] + ) logger.error(log) raise Exception(log) - menu['active'] = 'active'\ - if context['request'].path == menu['url'] else '' - if not menu['active']: + menu["active"] = ( + "active" if context["request"].path == menu["url"] else "" + ) + if not menu["active"]: """ Se não encontrada diretamente, procura a url acionada dentro do crud, caso seja um. @@ -184,26 +191,29 @@ def resolve_urls_inplace(menu, pk, rm, context): - visualização de detalhes, adição, edição, remoção. """ try: - if 'view' in context: - view = context['view'] - if hasattr(view, 'crud'): + if "view" in context: + view = context["view"] + if hasattr(view, "crud"): urls = view.crud.get_urls() for u in urls: - if (u.name == url_name or - 'urls_extras' in menu and - u.name in menu['urls_extras']): - menu['active'] = 'active' + if ( + u.name == url_name + or "urls_extras" in menu + and u.name in menu["urls_extras"] + ): + menu["active"] = "active" break except: - url_active = menu.get('url', '') + url_active = menu.get("url", "") logger.warning( - f'Não foi possível definir se url {url_active} é a url ativa.') - elif 'check_permission' in menu and not context[ - 'request'].user.has_perm(menu['check_permission']): - menu['active'] = '' - del menu['children'] - - if 'children' in menu: - menu['active'] = resolve_urls_inplace( - menu['children'], pk, rm, context) - return menu['active'] + f"Não foi possível definir se url {url_active} é a url ativa." + ) + elif "check_permission" in menu and not context["request"].user.has_perm( + menu["check_permission"] + ): + menu["active"] = "" + del menu["children"] + + if "children" in menu: + menu["active"] = resolve_urls_inplace(menu["children"], pk, rm, context) + return menu["active"] diff --git a/sapl/base/tests/test_base.py b/sapl/base/tests/test_base.py index 952de6f97..c24af2dba 100644 --- a/sapl/base/tests/test_base.py +++ b/sapl/base/tests/test_base.py @@ -6,19 +6,21 @@ from sapl.base.models import CasaLegislativa @pytest.mark.django_db(transaction=False) def test_casa_legislativa_model(): - baker.make(CasaLegislativa, - nome='Teste_Nome_Casa_Legislativa', - sigla='TSCL', - endereco='Teste_Endereço_Casa_Legislativa', - cep='12345678', - municipio='Teste_Municipio_Casa_Legislativa', - uf='DF') + baker.make( + CasaLegislativa, + nome="Teste_Nome_Casa_Legislativa", + sigla="TSCL", + endereco="Teste_Endereço_Casa_Legislativa", + cep="12345678", + municipio="Teste_Municipio_Casa_Legislativa", + uf="DF", + ) casa_legislativa = CasaLegislativa.objects.first() - assert casa_legislativa.nome == 'Teste_Nome_Casa_Legislativa' - assert casa_legislativa.sigla == 'TSCL' - assert casa_legislativa.endereco == 'Teste_Endereço_Casa_Legislativa' - assert casa_legislativa.cep == '12345678' - assert casa_legislativa.municipio == 'Teste_Municipio_Casa_Legislativa' - assert casa_legislativa.uf == 'DF' + assert casa_legislativa.nome == "Teste_Nome_Casa_Legislativa" + assert casa_legislativa.sigla == "TSCL" + assert casa_legislativa.endereco == "Teste_Endereço_Casa_Legislativa" + assert casa_legislativa.cep == "12345678" + assert casa_legislativa.municipio == "Teste_Municipio_Casa_Legislativa" + assert casa_legislativa.uf == "DF" diff --git a/sapl/base/tests/test_form.py b/sapl/base/tests/test_form.py index d6a8c4b25..a70475891 100644 --- a/sapl/base/tests/test_form.py +++ b/sapl/base/tests/test_form.py @@ -11,31 +11,34 @@ def test_valida_campos_obrigatorios_casa_legislativa_form(): errors = form.errors - assert errors['nome'] == [_('Este campo é obrigatório.')] - assert errors['sigla'] == [_('Este campo é obrigatório.')] - assert errors['endereco'] == [_('Este campo é obrigatório.')] - assert errors['cep'] == [_('Este campo é obrigatório.')] - assert errors['municipio'] == [_('Este campo é obrigatório.')] - assert errors['uf'] == [_('Este campo é obrigatório.')] + assert errors["nome"] == [_("Este campo é obrigatório.")] + assert errors["sigla"] == [_("Este campo é obrigatório.")] + assert errors["endereco"] == [_("Este campo é obrigatório.")] + assert errors["cep"] == [_("Este campo é obrigatório.")] + assert errors["municipio"] == [_("Este campo é obrigatório.")] + assert errors["uf"] == [_("Este campo é obrigatório.")] assert len(errors) == 6 @pytest.mark.django_db(transaction=False) def test_casa_legislativa_form_invalido(): - form = CasaLegislativaForm(data={'codigo': 'codigo', - 'nome': 'nome', - 'sigla': 'sg', - 'endereco': 'endereco', - 'cep': '7000000', - 'municipio': 'municipio', - 'uf': 'uf', - 'telefone': '33333333', - 'fax': '33333333', - 'logotipo': 'image', - 'endereco_web': 'web', - 'email': 'email', - 'informacao_geral': 'informacao_geral' - }) + form = CasaLegislativaForm( + data={ + "codigo": "codigo", + "nome": "nome", + "sigla": "sg", + "endereco": "endereco", + "cep": "7000000", + "municipio": "municipio", + "uf": "uf", + "telefone": "33333333", + "fax": "33333333", + "logotipo": "image", + "endereco_web": "web", + "email": "email", + "informacao_geral": "informacao_geral", + } + ) assert not form.is_valid() diff --git a/sapl/base/tests/test_login.py b/sapl/base/tests/test_login.py index 6c6a75cb8..2813d78fd 100755 --- a/sapl/base/tests/test_login.py +++ b/sapl/base/tests/test_login.py @@ -1,28 +1,28 @@ # -*- coding: utf-8 -*- -from django.contrib.auth import get_user_model import pytest - +from django.contrib.auth import get_user_model pytestmark = pytest.mark.django_db @pytest.fixture def user(): - return get_user_model().objects.create_user('jfirmino', password='123') + return get_user_model().objects.create_user("jfirmino", password="123") def test_login_aparece_na_barra_para_usuario_nao_logado(client): - response = client.get('/') - assert '' in str( - response.content) + response = client.get("/") + assert ( + '' + in str(response.content) + ) def test_username_do_usuario_logado_aparece_na_barra(client, user): - assert client.login(username='jfirmino', password='123') - response = client.get('/') - assert 'Login' not in str( - response.content) - assert 'jfirmino' in str(response.content) + assert client.login(username="jfirmino", password="123") + response = client.get("/") + assert 'Login' not in str(response.content) + assert "jfirmino" in str(response.content) assert 'Sair' in str(response.content) @@ -38,35 +38,41 @@ def test_username_do_usuario_logado_aparece_na_barra(client, user): # assert 'Sair' in str(response.content) -@pytest.mark.urls('sapl.base.tests.teststub_urls') -@pytest.mark.parametrize("link_login,destino", [ - # login redireciona para home - ('/login/', '/'), -]) +@pytest.mark.urls("sapl.base.tests.teststub_urls") +@pytest.mark.parametrize( + "link_login,destino", + [ + # login redireciona para home + ("/login/", "/"), + ], +) def test_login(app, user, link_login, destino): pagina_login = app.get(link_login) - form = pagina_login.forms['login-form'] - form['username'] = 'jfirmino' - form['password'] = '123' + form = pagina_login.forms["login-form"] + form["username"] = "jfirmino" + form["password"] = "123" res = form.submit() # login - assert str(user.pk) == app.session['_auth_user_id'] + assert str(user.pk) == app.session["_auth_user_id"] assert res.url == destino -@pytest.mark.parametrize("link_logout,destino", [ - # logout redireciona para a pagina de login - ('/logout/', '/login/'), -]) +@pytest.mark.parametrize( + "link_logout,destino", + [ + # logout redireciona para a pagina de login + ("/logout/", "/login/"), + ], +) def test_logout(client, user, link_logout, destino): # com um usuário logado ... - assert client.login(username='jfirmino', password='123') - assert str(user.pk) == client.session['_auth_user_id'] + assert client.login(username="jfirmino", password="123") + assert str(user.pk) == client.session["_auth_user_id"] # ... acionamos o link de logout res = client.get(link_logout, follow=True) destino_real = res.redirect_chain[-1][0] - assert '_auth_user_id' not in client.session + assert "_auth_user_id" not in client.session assert destino_real == destino diff --git a/sapl/base/tests/test_view_base.py b/sapl/base/tests/test_view_base.py index 507fb7ba8..74bd6dd20 100644 --- a/sapl/base/tests/test_view_base.py +++ b/sapl/base/tests/test_view_base.py @@ -1,638 +1,584 @@ -import pytest -from model_bakery import baker import datetime + +import pytest from django.urls import reverse from django.utils.translation import gettext_lazy as _ from model_bakery import baker from sapl.base.models import Autor, TipoAutor -from sapl.comissoes.models import Comissao, TipoComissao -from sapl.sessao.models import Bancada -from sapl.protocoloadm.models import (Protocolo, DocumentoAdministrativo, - TipoDocumentoAdministrativo, Anexado) -from sapl.materia.models import (TipoMateriaLegislativa, RegimeTramitacao, - MateriaLegislativa, Anexada) -from sapl.parlamentares.models import (Parlamentar, Partido, Filiacao, - Legislatura, Mandato) - -from sapl.base.views import (protocolos_duplicados, protocolos_com_materias, +from sapl.base.views import (anexados_ciclicos, autores_duplicados, + bancada_comissao_autor_externo, + mandato_sem_data_inicio, materias_protocolo_inexistente, - mandato_sem_data_inicio, parlamentares_duplicados, - parlamentares_mandatos_intersecao, + parlamentares_duplicados, parlamentares_filiacoes_intersecao, - autores_duplicados, - bancada_comissao_autor_externo, anexados_ciclicos) + parlamentares_mandatos_intersecao, + protocolos_com_materias, protocolos_duplicados) +from sapl.comissoes.models import Comissao, TipoComissao +from sapl.materia.models import (Anexada, MateriaLegislativa, RegimeTramitacao, + TipoMateriaLegislativa) +from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato, + Parlamentar, Partido) +from sapl.protocoloadm.models import (Anexado, DocumentoAdministrativo, + Protocolo, TipoDocumentoAdministrativo) +from sapl.sessao.models import Bancada @pytest.mark.django_db(transaction=False) def test_lista_protocolos_com_materias(): - baker.make( - Protocolo, - numero=15, - ano=2035 - ) - baker.make( - Protocolo, - numero=33, - ano=2035 - ) - - tipo_materia = baker.make( - TipoMateriaLegislativa, - descricao="Tipo_Materia_Teste" - ) - regime_tramitacao = baker.make( - RegimeTramitacao, - descricao="Regime_Tramitacao_Teste" - ) - baker.make( - MateriaLegislativa, - numero=16, - ano=2035, - data_apresentacao='2035-06-02', - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia, - numero_protocolo=15 - ) - baker.make( - MateriaLegislativa, - numero=17, - ano=2035, - data_apresentacao='2035-06-05', - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia, - numero_protocolo=15 - ) - - lista_protocolos_com_materias = protocolos_com_materias() - - assert len(lista_protocolos_com_materias) == 1 - assert lista_protocolos_com_materias[0][1] == 2 - assert lista_protocolos_com_materias[0][0].numero_protocolo == 15 - assert lista_protocolos_com_materias[0][0].ano == 2035 + baker.make(Protocolo, numero=15, ano=2035) + baker.make(Protocolo, numero=33, ano=2035) + + tipo_materia = baker.make(TipoMateriaLegislativa, descricao="Tipo_Materia_Teste") + regime_tramitacao = baker.make( + RegimeTramitacao, descricao="Regime_Tramitacao_Teste" + ) + baker.make( + MateriaLegislativa, + numero=16, + ano=2035, + data_apresentacao="2035-06-02", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + numero_protocolo=15, + ) + baker.make( + MateriaLegislativa, + numero=17, + ano=2035, + data_apresentacao="2035-06-05", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + numero_protocolo=15, + ) + + lista_protocolos_com_materias = protocolos_com_materias() + + assert len(lista_protocolos_com_materias) == 1 + assert lista_protocolos_com_materias[0][1] == 2 + assert lista_protocolos_com_materias[0][0].numero_protocolo == 15 + assert lista_protocolos_com_materias[0][0].ano == 2035 @pytest.mark.django_db(transaction=False) def test_lista_materias_protocolo_inexistente(): - protocolo_a = baker.make( - Protocolo, - numero=15, - ano=2031 - ) - - tipo_materia = baker.make( - TipoMateriaLegislativa, - descricao="Tipo_Materia_Teste" - ) - regime_tramitacao = baker.make( - RegimeTramitacao, - descricao="Regime_Tramitacao_Teste" - ) - baker.make( - MateriaLegislativa, - numero=16, - ano=2031, - data_apresentacao='2031-06-02', - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia, - numero_protocolo=15 - ) - materia = baker.make( - MateriaLegislativa, - numero=17, - ano=2031, - data_apresentacao='2031-06-02', - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia, - numero_protocolo=16 - ) - - lista_materias_protocolo_inexistente = materias_protocolo_inexistente() - - assert len(lista_materias_protocolo_inexistente) == 1 - assert lista_materias_protocolo_inexistente == [(materia, 2031, 16)] + protocolo_a = baker.make(Protocolo, numero=15, ano=2031) + + tipo_materia = baker.make(TipoMateriaLegislativa, descricao="Tipo_Materia_Teste") + regime_tramitacao = baker.make( + RegimeTramitacao, descricao="Regime_Tramitacao_Teste" + ) + baker.make( + MateriaLegislativa, + numero=16, + ano=2031, + data_apresentacao="2031-06-02", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + numero_protocolo=15, + ) + materia = baker.make( + MateriaLegislativa, + numero=17, + ano=2031, + data_apresentacao="2031-06-02", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + numero_protocolo=16, + ) + + lista_materias_protocolo_inexistente = materias_protocolo_inexistente() + + assert len(lista_materias_protocolo_inexistente) == 1 + assert lista_materias_protocolo_inexistente == [(materia, 2031, 16)] @pytest.mark.django_db(transaction=False) def test_lista_mandatos_sem_data_inicio(): - parlamentar = baker.make( - Parlamentar, - nome_completo="Nome_Completo_Parlamentar_Teste", - nome_parlamentar="Nome_Parlamentar_Teste", - sexo='M' - ) - legislatura = baker.make( - Legislatura, - numero=1, - data_inicio='2015-05-02', - data_fim='2024-02-04', - data_eleicao='2015-02-05' - ) - - mandato_a = baker.make( - Mandato, - parlamentar=parlamentar, - legislatura=legislatura - ) - baker.make( - Mandato, - parlamentar=parlamentar, - legislatura=legislatura, - data_inicio_mandato='2015-05-27' - ) - - lista_mandatos_sem_data_inicio = mandato_sem_data_inicio() - - assert len(lista_mandatos_sem_data_inicio) == 1 - assert lista_mandatos_sem_data_inicio[0] == mandato_a + parlamentar = baker.make( + Parlamentar, + nome_completo="Nome_Completo_Parlamentar_Teste", + nome_parlamentar="Nome_Parlamentar_Teste", + sexo="M", + ) + legislatura = baker.make( + Legislatura, + numero=1, + data_inicio="2015-05-02", + data_fim="2024-02-04", + data_eleicao="2015-02-05", + ) + + mandato_a = baker.make(Mandato, parlamentar=parlamentar, legislatura=legislatura) + baker.make( + Mandato, + parlamentar=parlamentar, + legislatura=legislatura, + data_inicio_mandato="2015-05-27", + ) + + lista_mandatos_sem_data_inicio = mandato_sem_data_inicio() + + assert len(lista_mandatos_sem_data_inicio) == 1 + assert lista_mandatos_sem_data_inicio[0] == mandato_a @pytest.mark.django_db(transaction=False) def test_lista_parlamentares_duplicados(): - baker.make( - Parlamentar, - nome_completo="Nome_Completo_Parlamentar_Teste", - nome_parlamentar="Nome_Parlamentar_Teste", - sexo='M' - ) - baker.make( - Parlamentar, - nome_completo="Nome_Completo_Parlamentar_Teste", - nome_parlamentar="Nome_Parlamentar_Teste", - sexo='M' - ) - baker.make( - Parlamentar, - nome_completo="Nome_Completo_Parlamentar_Teste-1", - nome_parlamentar="Nome_Parlamentar_Teste-1", - sexo='M' - ) - - lista_dict_parlamentares_duplicados = parlamentares_duplicados() - parlamentar_duplicado = list( - lista_dict_parlamentares_duplicados[0].values() - ) - parlamentar_duplicado.sort(key=str) - - assert len(lista_dict_parlamentares_duplicados) == 1 - assert parlamentar_duplicado == [2, "Nome_Parlamentar_Teste"] + baker.make( + Parlamentar, + nome_completo="Nome_Completo_Parlamentar_Teste", + nome_parlamentar="Nome_Parlamentar_Teste", + sexo="M", + ) + baker.make( + Parlamentar, + nome_completo="Nome_Completo_Parlamentar_Teste", + nome_parlamentar="Nome_Parlamentar_Teste", + sexo="M", + ) + baker.make( + Parlamentar, + nome_completo="Nome_Completo_Parlamentar_Teste-1", + nome_parlamentar="Nome_Parlamentar_Teste-1", + sexo="M", + ) + + lista_dict_parlamentares_duplicados = parlamentares_duplicados() + parlamentar_duplicado = list(lista_dict_parlamentares_duplicados[0].values()) + parlamentar_duplicado.sort(key=str) + + assert len(lista_dict_parlamentares_duplicados) == 1 + assert parlamentar_duplicado == [2, "Nome_Parlamentar_Teste"] @pytest.mark.django_db(transaction=False) def test_lista_parlamentares_mandatos_intersecao(): - legislatura = baker.make( - Legislatura, - numero=1, - data_inicio='2017-07-04', - data_fim='2170-05-01', - data_eleicao='2017-04-07' - ) - parlamentar_a = baker.make( - Parlamentar, - nome_completo="Nome_Completo_Parlamentar_Teste", - nome_parlamentar="Nome_Parlamentar_Teste", - sexo='M' - ) - parlamentar_b = baker.make( - Parlamentar, - nome_completo="Nome_Completo_Parlamentar_Teste-1", - nome_parlamentar="Nome_Parlamentar_Teste-1", - sexo='M' - ) - - mandato_a = baker.make( - Mandato, - parlamentar=parlamentar_a, - legislatura=legislatura, - data_inicio_mandato='2017-07-08', - data_fim_mandato='2018-01-07' - ) - mandato_b = baker.make( - Mandato, - parlamentar=parlamentar_a, - legislatura=legislatura, - data_inicio_mandato='2017-07-09' - ) - baker.make( - Mandato, - parlamentar=parlamentar_b, - legislatura=legislatura, - data_inicio_mandato='2017-11-17', - data_fim_mandato='2018-08-02' - ) - baker.make( - Mandato, - parlamentar=parlamentar_b, - legislatura=legislatura, - data_inicio_mandato='2018-08-03' - ) - - lista_parlamentares = parlamentares_mandatos_intersecao() - - assert len(lista_parlamentares) == 1 - assert lista_parlamentares == [(parlamentar_a, mandato_a, mandato_b)] + legislatura = baker.make( + Legislatura, + numero=1, + data_inicio="2017-07-04", + data_fim="2170-05-01", + data_eleicao="2017-04-07", + ) + parlamentar_a = baker.make( + Parlamentar, + nome_completo="Nome_Completo_Parlamentar_Teste", + nome_parlamentar="Nome_Parlamentar_Teste", + sexo="M", + ) + parlamentar_b = baker.make( + Parlamentar, + nome_completo="Nome_Completo_Parlamentar_Teste-1", + nome_parlamentar="Nome_Parlamentar_Teste-1", + sexo="M", + ) + + mandato_a = baker.make( + Mandato, + parlamentar=parlamentar_a, + legislatura=legislatura, + data_inicio_mandato="2017-07-08", + data_fim_mandato="2018-01-07", + ) + mandato_b = baker.make( + Mandato, + parlamentar=parlamentar_a, + legislatura=legislatura, + data_inicio_mandato="2017-07-09", + ) + baker.make( + Mandato, + parlamentar=parlamentar_b, + legislatura=legislatura, + data_inicio_mandato="2017-11-17", + data_fim_mandato="2018-08-02", + ) + baker.make( + Mandato, + parlamentar=parlamentar_b, + legislatura=legislatura, + data_inicio_mandato="2018-08-03", + ) + + lista_parlamentares = parlamentares_mandatos_intersecao() + + assert len(lista_parlamentares) == 1 + assert lista_parlamentares == [(parlamentar_a, mandato_a, mandato_b)] @pytest.mark.django_db(transaction=False) def test_lista_parlamentares_filiacoes_intersecao(): - partido = baker.make( - Partido, - sigla="ST", - nome="Nome_Partido_Teste" - ) - parlamentar_a = baker.make( - Parlamentar, - nome_completo="Nome_Completo_Parlamentar_Teste", - nome_parlamentar="Nome_Parlamentar_Teste", - sexo='M' - ) - parlamentar_b = baker.make( - Parlamentar, - nome_completo="Nome_Completo_Parlamentar_Teste-1", - nome_parlamentar="Nome_Parlamentar_Teste-1", - sexo='M' - ) - - filiacao_a = baker.make( - Filiacao, - parlamentar=parlamentar_a, - partido=partido, - data='2018-02-02', - data_desfiliacao='2019-08-01' - ) - filiacao_b = baker.make( - Filiacao, - parlamentar=parlamentar_a, - partido=partido, - data='2018-02-23', - data_desfiliacao='2020-02-04' - ) - baker.make( - Filiacao, - parlamentar=parlamentar_b, - partido=partido, - data='2018-02-07', - data_desfiliacao='2018-02-27' - ) - baker.make( - Filiacao, - parlamentar=parlamentar_b, - partido=partido, - data='2018-02-28' - ) - - lista_parlamentares = parlamentares_filiacoes_intersecao() - - assert len(lista_parlamentares) == 1 - assert lista_parlamentares == [(parlamentar_a, filiacao_b, filiacao_a)] + partido = baker.make(Partido, sigla="ST", nome="Nome_Partido_Teste") + parlamentar_a = baker.make( + Parlamentar, + nome_completo="Nome_Completo_Parlamentar_Teste", + nome_parlamentar="Nome_Parlamentar_Teste", + sexo="M", + ) + parlamentar_b = baker.make( + Parlamentar, + nome_completo="Nome_Completo_Parlamentar_Teste-1", + nome_parlamentar="Nome_Parlamentar_Teste-1", + sexo="M", + ) + + filiacao_a = baker.make( + Filiacao, + parlamentar=parlamentar_a, + partido=partido, + data="2018-02-02", + data_desfiliacao="2019-08-01", + ) + filiacao_b = baker.make( + Filiacao, + parlamentar=parlamentar_a, + partido=partido, + data="2018-02-23", + data_desfiliacao="2020-02-04", + ) + baker.make( + Filiacao, + parlamentar=parlamentar_b, + partido=partido, + data="2018-02-07", + data_desfiliacao="2018-02-27", + ) + baker.make(Filiacao, parlamentar=parlamentar_b, partido=partido, data="2018-02-28") + + lista_parlamentares = parlamentares_filiacoes_intersecao() + + assert len(lista_parlamentares) == 1 + assert lista_parlamentares == [(parlamentar_a, filiacao_b, filiacao_a)] @pytest.mark.django_db(transaction=False) def test_lista_autores_duplicados(): - tipo_autor = baker.make( - TipoAutor, - descricao="Tipo_Autor_Teste" - ) - - baker.make( - Autor, - tipo=tipo_autor, - nome="Nome_Autor_Teste" - ) - baker.make( - Autor, - tipo=tipo_autor, - nome="Nome_Autor_Teste" - ) - baker.make( - Autor, - tipo=tipo_autor, - nome="Nome_Autor_Teste-1" - ) - - lista_autores_duplicados = autores_duplicados() - - assert len(lista_autores_duplicados) == 1 - assert lista_autores_duplicados[0]['count'] == 2 - assert lista_autores_duplicados[0]['nome'] == "Nome_Autor_Teste" + tipo_autor = baker.make(TipoAutor, descricao="Tipo_Autor_Teste") + + baker.make(Autor, tipo=tipo_autor, nome="Nome_Autor_Teste") + baker.make(Autor, tipo=tipo_autor, nome="Nome_Autor_Teste") + baker.make(Autor, tipo=tipo_autor, nome="Nome_Autor_Teste-1") + + lista_autores_duplicados = autores_duplicados() + + assert len(lista_autores_duplicados) == 1 + assert lista_autores_duplicados[0]["count"] == 2 + assert lista_autores_duplicados[0]["nome"] == "Nome_Autor_Teste" @pytest.mark.django_db(transaction=False) def test_lista_bancada_comissao_autor_externo(): - tipo_autor = baker.make( - TipoAutor, - descricao="Tipo_Autor_Teste" - ) - tipo_autor_externo = baker.make( - TipoAutor, - descricao="Externo" - ) - - legislatura = baker.make( - Legislatura, - numero=1, - data_inicio='2012-01-03', - data_fim='2013-01-02', - data_eleicao='2011-10-04' - ) - - bancada_a = baker.make( - Bancada, - legislatura=legislatura, - nome="Bancada_Teste", - data_criacao='2012-01-08', - ) - bancada_a.autor.create( - nome="Nome_Autor_Teste", - tipo=tipo_autor - ) - - bancada_b = baker.make( - Bancada, - legislatura=legislatura, - nome="Bancada_Teste-1", - data_criacao='2012-02-02' - ) - autor_bancada_b = bancada_b.autor.create( - nome="Nome_Autor_Externo_Teste", - tipo=tipo_autor_externo - ) - - tipo_comissao = baker.make( - TipoComissao, - nome="Tipo_Comissao_Teste", - natureza='T', - sigla="TCT" - ) - - comissao_a = baker.make( - Comissao, - nome="Comissao_Teste", - sigla="CT", - data_criacao='2012-03-08', - ) - comissao_a.autor.create( - nome="Nome_Autor_Teste", - tipo=tipo_autor - ) - - comissao_b = baker.make( - Comissao, - nome="Comissao_Teste-1", - sigla="CT1", - data_criacao='2012-04-01', - ) - autor_comissao_b = comissao_b.autor.create( - nome="Nome_Autor_Externo_Teste", - tipo=tipo_autor_externo - ) - - lista_bancada_comissao = bancada_comissao_autor_externo() - - assert len(lista_bancada_comissao) == 2 - assert lista_bancada_comissao[0][0:2] == (autor_bancada_b, bancada_b) - assert lista_bancada_comissao[0][2:4] == ('Bancada', 'sistema/bancada') - assert lista_bancada_comissao[1][0:2] == (autor_comissao_b, comissao_b) - assert lista_bancada_comissao[1][2:4] == ('Comissão', 'comissao') + tipo_autor = baker.make(TipoAutor, descricao="Tipo_Autor_Teste") + tipo_autor_externo = baker.make(TipoAutor, descricao="Externo") + + legislatura = baker.make( + Legislatura, + numero=1, + data_inicio="2012-01-03", + data_fim="2013-01-02", + data_eleicao="2011-10-04", + ) + + bancada_a = baker.make( + Bancada, + legislatura=legislatura, + nome="Bancada_Teste", + data_criacao="2012-01-08", + ) + bancada_a.autor.create(nome="Nome_Autor_Teste", tipo=tipo_autor) + + bancada_b = baker.make( + Bancada, + legislatura=legislatura, + nome="Bancada_Teste-1", + data_criacao="2012-02-02", + ) + autor_bancada_b = bancada_b.autor.create( + nome="Nome_Autor_Externo_Teste", tipo=tipo_autor_externo + ) + + tipo_comissao = baker.make( + TipoComissao, nome="Tipo_Comissao_Teste", natureza="T", sigla="TCT" + ) + + comissao_a = baker.make( + Comissao, + nome="Comissao_Teste", + sigla="CT", + data_criacao="2012-03-08", + ) + comissao_a.autor.create(nome="Nome_Autor_Teste", tipo=tipo_autor) + + comissao_b = baker.make( + Comissao, + nome="Comissao_Teste-1", + sigla="CT1", + data_criacao="2012-04-01", + ) + autor_comissao_b = comissao_b.autor.create( + nome="Nome_Autor_Externo_Teste", tipo=tipo_autor_externo + ) + + lista_bancada_comissao = bancada_comissao_autor_externo() + + assert len(lista_bancada_comissao) == 2 + assert lista_bancada_comissao[0][0:2] == (autor_bancada_b, bancada_b) + assert lista_bancada_comissao[0][2:4] == ("Bancada", "sistema/bancada") + assert lista_bancada_comissao[1][0:2] == (autor_comissao_b, comissao_b) + assert lista_bancada_comissao[1][2:4] == ("Comissão", "comissao") @pytest.mark.django_db(transaction=False) def test_lista_anexados_ciclicas(): - ## DocumentoAdministrativo - tipo_documento = baker.make( - TipoDocumentoAdministrativo, - sigla="TT", - descricao="Tipo_Teste" - ) - - documento_a = baker.make( - DocumentoAdministrativo, - tipo=tipo_documento, - numero=26, - ano=2019, - data='2019-05-15', - ) - documento_b = baker.make( - DocumentoAdministrativo, - tipo=tipo_documento, - numero=27, - ano=2019, - data='2019-05-16', - ) - documento_c = baker.make( - DocumentoAdministrativo, - tipo=tipo_documento, - numero=28, - ano=2019, - data='2019-05-17', - ) - documento_a1 = baker.make( - DocumentoAdministrativo, - tipo=tipo_documento, - numero=29, - ano=2019, - data='2019-05-18', - ) - documento_b1 = baker.make( - DocumentoAdministrativo, - tipo=tipo_documento, - numero=30, - ano=2019, - data='2019-05-19', - ) - documento_c1 = baker.make( - DocumentoAdministrativo, - tipo=tipo_documento, - numero=31, - ano=2019, - data='2019-05-20', - ) - - baker.make( - Anexado, - documento_principal=documento_a, - documento_anexado=documento_b, - data_anexacao='2019-05-21' - ) - baker.make( - Anexado, - documento_principal=documento_a, - documento_anexado=documento_c, - data_anexacao='2019-05-22' - ) - baker.make( - Anexado, - documento_principal=documento_b, - documento_anexado=documento_c, - data_anexacao='2019-05-23' - ) - baker.make( - Anexado, - documento_principal=documento_a1, - documento_anexado=documento_b1, - data_anexacao='2019-05-24' - ) - baker.make( - Anexado, - documento_principal=documento_a1, - documento_anexado=documento_c1, - data_anexacao='2019-05-25' - ) - baker.make( - Anexado, - documento_principal=documento_b1, - documento_anexado=documento_c1, - data_anexacao='2019-05-26' - ) - baker.make( - Anexado, - documento_principal=documento_c1, - documento_anexado=documento_b1, - data_anexacao='2019-05-27' - ) - - lista_documento_ciclicos = anexados_ciclicos(False) - - ## Matéria - tipo_materia = baker.make( - TipoMateriaLegislativa, - descricao="Tipo_Teste" - ) - regime_tramitacao = baker.make( - RegimeTramitacao, - descricao="Regime_Teste" - ) - - materia_a = baker.make( - MateriaLegislativa, - numero=20, - ano=2018, - data_apresentacao="2018-01-04", - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia - ) - materia_b = baker.make( - MateriaLegislativa, - numero=21, - ano=2019, - data_apresentacao="2019-05-04", - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia - ) - materia_c = baker.make( - MateriaLegislativa, - numero=22, - ano=2019, - data_apresentacao="2019-05-05", - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia - ) - materia_a1 = baker.make( - MateriaLegislativa, - numero=23, - ano=2018, - data_apresentacao="2019-05-06", - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia - ) - materia_b1 = baker.make( - MateriaLegislativa, - numero=24, - ano=2019, - data_apresentacao="2019-05-07", - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia - ) - materia_c1 = baker.make( - MateriaLegislativa, - numero=25, - ano=2019, - data_apresentacao="2019-05-08", - regime_tramitacao=regime_tramitacao, - tipo=tipo_materia - ) - - baker.make( - Anexada, - materia_principal=materia_a, - materia_anexada=materia_b, - data_anexacao='2019-05-11' - ) - baker.make( - Anexada, - materia_principal=materia_a, - materia_anexada=materia_c, - data_anexacao='2019-05-12' - ) - baker.make( - Anexada, - materia_principal=materia_b, - materia_anexada=materia_c, - data_anexacao='2019-05-13' - ) - baker.make( - Anexada, - materia_principal=materia_a1, - materia_anexada=materia_b1, - data_anexacao='2019-05-11' - ) - baker.make( - Anexada, - materia_principal=materia_a1, - materia_anexada=materia_c1, - data_anexacao='2019-05-12' - ) - baker.make( - Anexada, - materia_principal=materia_b1, - materia_anexada=materia_c1, - data_anexacao='2019-05-13' - ) - baker.make( - Anexada, - materia_principal=materia_c1, - materia_anexada=materia_b1, - data_anexacao='2019-05-14' - ) - - lista_materias_ciclicas = anexados_ciclicos(True) - - assert len(lista_materias_ciclicas) == 2 - assert lista_materias_ciclicas[0] == (datetime.date(2019,5,13), materia_b1, materia_c1) - assert lista_materias_ciclicas[1] == (datetime.date(2019,5,14), materia_c1, materia_b1) - - assert len(lista_documento_ciclicos) == 2 - assert lista_documento_ciclicos[0] == (datetime.date(2019,5,26), documento_b1, documento_c1) - assert lista_documento_ciclicos[1] == (datetime.date(2019,5,27), documento_c1, documento_b1) + ## DocumentoAdministrativo + tipo_documento = baker.make( + TipoDocumentoAdministrativo, sigla="TT", descricao="Tipo_Teste" + ) + + documento_a = baker.make( + DocumentoAdministrativo, + tipo=tipo_documento, + numero=26, + ano=2019, + data="2019-05-15", + ) + documento_b = baker.make( + DocumentoAdministrativo, + tipo=tipo_documento, + numero=27, + ano=2019, + data="2019-05-16", + ) + documento_c = baker.make( + DocumentoAdministrativo, + tipo=tipo_documento, + numero=28, + ano=2019, + data="2019-05-17", + ) + documento_a1 = baker.make( + DocumentoAdministrativo, + tipo=tipo_documento, + numero=29, + ano=2019, + data="2019-05-18", + ) + documento_b1 = baker.make( + DocumentoAdministrativo, + tipo=tipo_documento, + numero=30, + ano=2019, + data="2019-05-19", + ) + documento_c1 = baker.make( + DocumentoAdministrativo, + tipo=tipo_documento, + numero=31, + ano=2019, + data="2019-05-20", + ) + + baker.make( + Anexado, + documento_principal=documento_a, + documento_anexado=documento_b, + data_anexacao="2019-05-21", + ) + baker.make( + Anexado, + documento_principal=documento_a, + documento_anexado=documento_c, + data_anexacao="2019-05-22", + ) + baker.make( + Anexado, + documento_principal=documento_b, + documento_anexado=documento_c, + data_anexacao="2019-05-23", + ) + baker.make( + Anexado, + documento_principal=documento_a1, + documento_anexado=documento_b1, + data_anexacao="2019-05-24", + ) + baker.make( + Anexado, + documento_principal=documento_a1, + documento_anexado=documento_c1, + data_anexacao="2019-05-25", + ) + baker.make( + Anexado, + documento_principal=documento_b1, + documento_anexado=documento_c1, + data_anexacao="2019-05-26", + ) + baker.make( + Anexado, + documento_principal=documento_c1, + documento_anexado=documento_b1, + data_anexacao="2019-05-27", + ) + + lista_documento_ciclicos = anexados_ciclicos(False) + + ## Matéria + tipo_materia = baker.make(TipoMateriaLegislativa, descricao="Tipo_Teste") + regime_tramitacao = baker.make(RegimeTramitacao, descricao="Regime_Teste") + + materia_a = baker.make( + MateriaLegislativa, + numero=20, + ano=2018, + data_apresentacao="2018-01-04", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + ) + materia_b = baker.make( + MateriaLegislativa, + numero=21, + ano=2019, + data_apresentacao="2019-05-04", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + ) + materia_c = baker.make( + MateriaLegislativa, + numero=22, + ano=2019, + data_apresentacao="2019-05-05", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + ) + materia_a1 = baker.make( + MateriaLegislativa, + numero=23, + ano=2018, + data_apresentacao="2019-05-06", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + ) + materia_b1 = baker.make( + MateriaLegislativa, + numero=24, + ano=2019, + data_apresentacao="2019-05-07", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + ) + materia_c1 = baker.make( + MateriaLegislativa, + numero=25, + ano=2019, + data_apresentacao="2019-05-08", + regime_tramitacao=regime_tramitacao, + tipo=tipo_materia, + ) + + baker.make( + Anexada, + materia_principal=materia_a, + materia_anexada=materia_b, + data_anexacao="2019-05-11", + ) + baker.make( + Anexada, + materia_principal=materia_a, + materia_anexada=materia_c, + data_anexacao="2019-05-12", + ) + baker.make( + Anexada, + materia_principal=materia_b, + materia_anexada=materia_c, + data_anexacao="2019-05-13", + ) + baker.make( + Anexada, + materia_principal=materia_a1, + materia_anexada=materia_b1, + data_anexacao="2019-05-11", + ) + baker.make( + Anexada, + materia_principal=materia_a1, + materia_anexada=materia_c1, + data_anexacao="2019-05-12", + ) + baker.make( + Anexada, + materia_principal=materia_b1, + materia_anexada=materia_c1, + data_anexacao="2019-05-13", + ) + baker.make( + Anexada, + materia_principal=materia_c1, + materia_anexada=materia_b1, + data_anexacao="2019-05-14", + ) + + lista_materias_ciclicas = anexados_ciclicos(True) + + assert len(lista_materias_ciclicas) == 2 + assert lista_materias_ciclicas[0] == ( + datetime.date(2019, 5, 13), + materia_b1, + materia_c1, + ) + assert lista_materias_ciclicas[1] == ( + datetime.date(2019, 5, 14), + materia_c1, + materia_b1, + ) + + assert len(lista_documento_ciclicos) == 2 + assert lista_documento_ciclicos[0] == ( + datetime.date(2019, 5, 26), + documento_b1, + documento_c1, + ) + assert lista_documento_ciclicos[1] == ( + datetime.date(2019, 5, 27), + documento_c1, + documento_b1, + ) @pytest.mark.django_db(transaction=False) def test_incluir_casa_legislativa_errors(admin_client): - - response = admin_client.post(reverse('sapl.base:casalegislativa_create'), - {'salvar': 'salvar'}, - follow=True) - - assert (response.context_data['form'].errors['nome'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['sigla'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['endereco'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['cep'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['municipio'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['uf'] == - [_('Este campo é obrigatório.')]) + response = admin_client.post( + reverse("sapl.base:casalegislativa_create"), {"salvar": "salvar"}, follow=True + ) + + assert response.context_data["form"].errors["nome"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["sigla"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["endereco"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["cep"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["municipio"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["uf"] == [ + _("Este campo é obrigatório.") + ] @pytest.mark.django_db(transaction=False) def test_incluir_tipo_autor_errors(admin_client): + response = admin_client.post( + reverse("sapl.base:tipoautor_create"), {"salvar": "salvar"}, follow=True + ) - response = admin_client.post(reverse('sapl.base:tipoautor_create'), - {'salvar': 'salvar'}, - follow=True) - - assert (response.context_data['form'].errors['descricao'] == - [_('Este campo é obrigatório.')]) + assert response.context_data["form"].errors["descricao"] == [ + _("Este campo é obrigatório.") + ] diff --git a/sapl/base/tests/teststub_urls.py b/sapl/base/tests/teststub_urls.py index 8bf2ae2bd..61a434f82 100644 --- a/sapl/base/tests/teststub_urls.py +++ b/sapl/base/tests/teststub_urls.py @@ -3,7 +3,5 @@ from django.views.generic.base import TemplateView from sapl.urls import urlpatterns as original_patterns -ptrn = [path('zzzz', - TemplateView.as_view( - template_name='index.html'), name='zzzz')] +ptrn = [path("zzzz", TemplateView.as_view(template_name="index.html"), name="zzzz")] urlpatterns = original_patterns + ptrn diff --git a/sapl/base/urls.py b/sapl/base/urls.py index 36cef7210..363730c91 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -1,137 +1,205 @@ import os -from django.urls import include, path, re_path from django.contrib.auth import views from django.contrib.auth.decorators import permission_required +from django.urls import include, path, re_path from django.views.generic.base import RedirectView, TemplateView -from sapl.base.views import (AutorCrud, ConfirmarEmailView, TipoAutorCrud, get_estatistica, - RecuperarSenhaEmailView, RecuperarSenhaFinalizadoView, - RecuperarSenhaConfirmaView, RecuperarSenhaCompletoView, IndexView, UserCrud) -from sapl.settings import MEDIA_URL, LOGOUT_REDIRECT_URL +from sapl.base.views import (AutorCrud, ConfirmarEmailView, IndexView, + RecuperarSenhaCompletoView, + RecuperarSenhaConfirmaView, + RecuperarSenhaEmailView, + RecuperarSenhaFinalizadoView, TipoAutorCrud, + UserCrud, get_estatistica) +from sapl.settings import LOGOUT_REDIRECT_URL, MEDIA_URL + from .apps import AppConfig -from .views import (LoginSapl, AlterarSenha, AppConfigCrud, CasaLegislativaCrud, - HelpTopicView, LogotipoView, PesquisarAuditLogView, - SaplSearchView, - ListarInconsistenciasView, - ListarProtocolosDuplicadosView, ListarProtocolosComMateriasView, ListarMatProtocoloInexistenteView, - ListarParlamentaresDuplicadosView, ListarFiliacoesSemDataFiliacaoView, - ListarMandatoSemDataInicioView, ListarParlMandatosIntersecaoView, ListarParlFiliacoesIntersecaoView, - ListarAutoresDuplicadosView, ListarBancadaComissaoAutorExternoView, ListarLegislaturaInfindavelView, - ListarAnexadasCiclicasView, ListarAnexadosCiclicosView, pesquisa_textual) +from .views import (AlterarSenha, AppConfigCrud, CasaLegislativaCrud, + HelpTopicView, ListarAnexadasCiclicasView, + ListarAnexadosCiclicosView, ListarAutoresDuplicadosView, + ListarBancadaComissaoAutorExternoView, + ListarFiliacoesSemDataFiliacaoView, + ListarInconsistenciasView, ListarLegislaturaInfindavelView, + ListarMandatoSemDataInicioView, + ListarMatProtocoloInexistenteView, + ListarParlamentaresDuplicadosView, + ListarParlFiliacoesIntersecaoView, + ListarParlMandatosIntersecaoView, + ListarProtocolosComMateriasView, + ListarProtocolosDuplicadosView, LoginSapl, LogotipoView, + PesquisarAuditLogView, SaplSearchView, pesquisa_textual) app_name = AppConfig.name admin_user = [ - path('sistema/usuario/', include(UserCrud.get_urls())), - + path("sistema/usuario/", include(UserCrud.get_urls())), ] alterar_senha = [ - path('sistema/alterar-senha/', - AlterarSenha.as_view(), - name='alterar_senha'), - + path("sistema/alterar-senha/", AlterarSenha.as_view(), name="alterar_senha"), ] recuperar_senha = [ - path('recuperar-senha/email/', RecuperarSenhaEmailView.as_view(), - name='recuperar_senha_email'), - path('recuperar-senha/finalizado/', - RecuperarSenhaFinalizadoView.as_view(), name='recuperar_senha_finalizado'), - re_path(r'^recuperar-senha/(?P[0-9A-Za-z_\-]+)/(?P.+)/$', RecuperarSenhaConfirmaView.as_view(), - name='recuperar_senha_confirma'), - path('recuperar-senha/completo/', - RecuperarSenhaCompletoView.as_view(), name='recuperar_senha_completo'), + path( + "recuperar-senha/email/", + RecuperarSenhaEmailView.as_view(), + name="recuperar_senha_email", + ), + path( + "recuperar-senha/finalizado/", + RecuperarSenhaFinalizadoView.as_view(), + name="recuperar_senha_finalizado", + ), + re_path( + r"^recuperar-senha/(?P[0-9A-Za-z_\-]+)/(?P.+)/$", + RecuperarSenhaConfirmaView.as_view(), + name="recuperar_senha_confirma", + ), + path( + "recuperar-senha/completo/", + RecuperarSenhaCompletoView.as_view(), + name="recuperar_senha_completo", + ), ] -urlpatterns = [ - path('', IndexView.as_view(template_name='index.html'), name='sapl_index'), - - path('sistema/autor/tipo/', include(TipoAutorCrud.get_urls())), - path('sistema/autor/', include(AutorCrud.get_urls())), - - re_path(r'^sistema/ajuda/(?P\w+)$', - HelpTopicView.as_view(), name='help_topic'), - path('sistema/ajuda/', TemplateView.as_view(template_name='ajuda.html'), - name='help'), - path('sistema/casa-legislativa/', include(CasaLegislativaCrud.get_urls()), - name="casa_legislativa"), - path('sistema/app-config/', include(AppConfigCrud.get_urls())), - - re_path(r'^email/validate/(?P[0-9A-Za-z_\-]+)/' - '(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})$', - ConfirmarEmailView.as_view(), name='confirmar_email'), - - path('sistema/inconsistencias/', - ListarInconsistenciasView.as_view(), - name='lista_inconsistencias'), - path('sistema/inconsistencias/protocolos_duplicados', - ListarProtocolosDuplicadosView.as_view(), - name='lista_protocolos_duplicados'), - path('sistema/inconsistencias/protocolos_com_materias', - ListarProtocolosComMateriasView.as_view(), - name='lista_protocolos_com_materias'), - path('sistema/inconsistencias/materias_protocolo_inexistente', - ListarMatProtocoloInexistenteView.as_view(), - name='lista_materias_protocolo_inexistente'), - path('sistema/inconsistencias/filiacoes_sem_data_filiacao', - ListarFiliacoesSemDataFiliacaoView.as_view(), - name='lista_filiacoes_sem_data_filiacao'), - re_path(r'^sistema/inconsistencias/mandato_sem_data_inicio', - ListarMandatoSemDataInicioView.as_view(), - name='lista_mandato_sem_data_inicio'), - path('sistema/inconsistencias/parlamentares_duplicados', - ListarParlamentaresDuplicadosView.as_view(), - name='lista_parlamentares_duplicados'), - path('sistema/inconsistencias/parlamentares_mandatos_intersecao', - ListarParlMandatosIntersecaoView.as_view(), - name='lista_parlamentares_mandatos_intersecao'), - path('sistema/inconsistencias/parlamentares_filiacoes_intersecao', - ListarParlFiliacoesIntersecaoView.as_view(), - name='lista_parlamentares_filiacoes_intersecao'), - path('sistema/inconsistencias/autores_duplicados', - ListarAutoresDuplicadosView.as_view(), - name='lista_autores_duplicados'), - path('sistema/inconsistencias/bancada_comissao_autor_externo', - ListarBancadaComissaoAutorExternoView.as_view(), - name='lista_bancada_comissao_autor_externo'), - path('sistema/inconsistencias/legislatura_infindavel', - ListarLegislaturaInfindavelView.as_view(), - name='lista_legislatura_infindavel'), - path('sistema/inconsistencias/anexadas_ciclicas', - ListarAnexadasCiclicasView.as_view(), - name='lista_anexadas_ciclicas'), - path('sistema/inconsistencias/anexados_ciclicos', - ListarAnexadosCiclicosView.as_view(), - name='lista_anexados_ciclicos'), - - re_path(r'^sistema/pesquisa-textual', - pesquisa_textual, - name='pesquisa_textual'), - - re_path(r'^sistema/estatisticas', get_estatistica), - - # todos os sublinks de sistema devem vir acima deste - path('sistema/', permission_required('base.view_tabelas_auxiliares') - (TemplateView.as_view(template_name='sistema.html')), - name='sistema'), - - path('login/', LoginSapl.as_view(), name='login'), - path('logout/', views.LogoutView.as_view(), - {'next_page': LOGOUT_REDIRECT_URL}, name='logout'), - - re_path(r'^sistema/search/', SaplSearchView(), name='haystack_search'), - - path('sistema/auditlog/', PesquisarAuditLogView.as_view(), name='pesquisar_auditlog'), - - # Folhas XSLT e extras referenciadas por documentos migrados do sapl 2.5 - re_path(r'^(sapl/)?XSLT/HTML/(?P.*)$', RedirectView.as_view( - url=os.path.join(MEDIA_URL, 'sapl/public/XSLT/HTML/%(path)s'), - permanent=False)), - # url do logotipo usada em documentos migrados do sapl 2.5 - re_path(r'^(sapl/)?sapl_documentos/props_sapl/logo_casa', - LogotipoView.as_view(), name='logotipo'), - - -] + recuperar_senha + alterar_senha + admin_user +urlpatterns = ( + [ + path("", IndexView.as_view(template_name="index.html"), name="sapl_index"), + path("sistema/autor/tipo/", include(TipoAutorCrud.get_urls())), + path("sistema/autor/", include(AutorCrud.get_urls())), + re_path( + r"^sistema/ajuda/(?P\w+)$", + HelpTopicView.as_view(), + name="help_topic", + ), + path( + "sistema/ajuda/", + TemplateView.as_view(template_name="ajuda.html"), + name="help", + ), + path( + "sistema/casa-legislativa/", + include(CasaLegislativaCrud.get_urls()), + name="casa_legislativa", + ), + path("sistema/app-config/", include(AppConfigCrud.get_urls())), + re_path( + r"^email/validate/(?P[0-9A-Za-z_\-]+)/" + "(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})$", + ConfirmarEmailView.as_view(), + name="confirmar_email", + ), + path( + "sistema/inconsistencias/", + ListarInconsistenciasView.as_view(), + name="lista_inconsistencias", + ), + path( + "sistema/inconsistencias/protocolos_duplicados", + ListarProtocolosDuplicadosView.as_view(), + name="lista_protocolos_duplicados", + ), + path( + "sistema/inconsistencias/protocolos_com_materias", + ListarProtocolosComMateriasView.as_view(), + name="lista_protocolos_com_materias", + ), + path( + "sistema/inconsistencias/materias_protocolo_inexistente", + ListarMatProtocoloInexistenteView.as_view(), + name="lista_materias_protocolo_inexistente", + ), + path( + "sistema/inconsistencias/filiacoes_sem_data_filiacao", + ListarFiliacoesSemDataFiliacaoView.as_view(), + name="lista_filiacoes_sem_data_filiacao", + ), + re_path( + r"^sistema/inconsistencias/mandato_sem_data_inicio", + ListarMandatoSemDataInicioView.as_view(), + name="lista_mandato_sem_data_inicio", + ), + path( + "sistema/inconsistencias/parlamentares_duplicados", + ListarParlamentaresDuplicadosView.as_view(), + name="lista_parlamentares_duplicados", + ), + path( + "sistema/inconsistencias/parlamentares_mandatos_intersecao", + ListarParlMandatosIntersecaoView.as_view(), + name="lista_parlamentares_mandatos_intersecao", + ), + path( + "sistema/inconsistencias/parlamentares_filiacoes_intersecao", + ListarParlFiliacoesIntersecaoView.as_view(), + name="lista_parlamentares_filiacoes_intersecao", + ), + path( + "sistema/inconsistencias/autores_duplicados", + ListarAutoresDuplicadosView.as_view(), + name="lista_autores_duplicados", + ), + path( + "sistema/inconsistencias/bancada_comissao_autor_externo", + ListarBancadaComissaoAutorExternoView.as_view(), + name="lista_bancada_comissao_autor_externo", + ), + path( + "sistema/inconsistencias/legislatura_infindavel", + ListarLegislaturaInfindavelView.as_view(), + name="lista_legislatura_infindavel", + ), + path( + "sistema/inconsistencias/anexadas_ciclicas", + ListarAnexadasCiclicasView.as_view(), + name="lista_anexadas_ciclicas", + ), + path( + "sistema/inconsistencias/anexados_ciclicos", + ListarAnexadosCiclicosView.as_view(), + name="lista_anexados_ciclicos", + ), + re_path( + r"^sistema/pesquisa-textual", pesquisa_textual, name="pesquisa_textual" + ), + re_path(r"^sistema/estatisticas", get_estatistica), + # todos os sublinks de sistema devem vir acima deste + path( + "sistema/", + permission_required("base.view_tabelas_auxiliares")( + TemplateView.as_view(template_name="sistema.html") + ), + name="sistema", + ), + path("login/", LoginSapl.as_view(), name="login"), + path( + "logout/", + views.LogoutView.as_view(), + {"next_page": LOGOUT_REDIRECT_URL}, + name="logout", + ), + re_path(r"^sistema/search/", SaplSearchView(), name="haystack_search"), + path( + "sistema/auditlog/", + PesquisarAuditLogView.as_view(), + name="pesquisar_auditlog", + ), + # Folhas XSLT e extras referenciadas por documentos migrados do sapl 2.5 + re_path( + r"^(sapl/)?XSLT/HTML/(?P.*)$", + RedirectView.as_view( + url=os.path.join(MEDIA_URL, "sapl/public/XSLT/HTML/%(path)s"), + permanent=False, + ), + ), + # url do logotipo usada em documentos migrados do sapl 2.5 + re_path( + r"^(sapl/)?sapl_documentos/props_sapl/logo_casa", + LogotipoView.as_view(), + name="logotipo", + ), + ] + + recuperar_senha + + alterar_senha + + admin_user +) diff --git a/sapl/base/views.py b/sapl/base/views.py index 32b25deb7..8b60b3c19 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -1,20 +1,21 @@ import collections -import collections import itertools import logging import os from django.apps.registry import apps from django.contrib import messages -from django.contrib.auth import authenticate, login, get_user_model, views +from django.contrib.auth import authenticate, get_user_model, login, views from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.auth.models import Group from django.contrib.auth.tokens import default_token_generator -from django.contrib.auth.views import (PasswordResetView, PasswordResetConfirmView, PasswordResetCompleteView, - PasswordResetDoneView) +from django.contrib.auth.views import (PasswordResetCompleteView, + PasswordResetConfirmView, + PasswordResetDoneView, + PasswordResetView) from django.core.exceptions import PermissionDenied, ValidationError from django.core.mail import send_mail -from django.db.models import Count, Q, Max +from django.db.models import Count, Max, Q from django.http import Http404, HttpResponseRedirect, JsonResponse from django.shortcuts import redirect from django.template import TemplateDoesNotExist @@ -25,7 +26,7 @@ from django.utils.decorators import method_decorator from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode from django.utils.translation import gettext_lazy as _ -from django.views.generic import (FormView, ListView) +from django.views.generic import FormView, ListView from django.views.generic.base import RedirectView, TemplateView from django_filters.views import FilterView from haystack.query import SearchQuerySet @@ -33,26 +34,28 @@ from haystack.views import SearchView from ratelimit.decorators import ratelimit from sapl import settings -from sapl.base.forms import (AutorForm, TipoAutorForm, RecuperarSenhaForm, - NovaSenhaForm, UserAdminForm, AuditLogFilterSet, - LoginForm, SaplSearchForm) +from sapl.base.forms import (AuditLogFilterSet, AutorForm, LoginForm, + NovaSenhaForm, RecuperarSenhaForm, SaplSearchForm, + TipoAutorForm, UserAdminForm) from sapl.base.models import AuditLog, Autor, TipoAutor from sapl.comissoes.models import Comissao -from sapl.crud.base import CrudAux, make_pagination, Crud, \ - ListWithSearchForm -from sapl.materia.models import (Anexada, MateriaLegislativa, - Proposicao) +from sapl.crud.base import Crud, CrudAux, ListWithSearchForm, make_pagination +from sapl.materia.models import Anexada, MateriaLegislativa, Proposicao from sapl.norma.models import NormaJuridica, ViewNormasEstatisticas -from sapl.parlamentares.models import ( - Filiacao, Legislatura, Mandato, Parlamentar) -from sapl.protocoloadm.models import (Anexado, Protocolo) -from sapl.relatorios.views import (relatorio_estatisticas_acesso_normas) -from sapl.sessao.models import (Bancada, SessaoPlenaria) +from sapl.parlamentares.models import (Filiacao, Legislatura, Mandato, + Parlamentar) +from sapl.protocoloadm.models import Anexado, Protocolo +from sapl.relatorios.views import relatorio_estatisticas_acesso_normas +from sapl.sessao.models import Bancada, SessaoPlenaria from sapl.settings import EMAIL_SEND_USER -from sapl.utils import (gerar_hash_arquivo, intervalos_tem_intersecao, mail_service_configured, - SEPARADOR_HASH_PROPOSICAO, show_results_filter_set, google_recaptcha_configured, - get_client_ip, sapn_is_enabled, is_weak_password) -from .forms import (AlterarSenhaForm, CasaLegislativaForm, ConfiguracoesAppForm, EstatisticasAcessoNormasForm) +from sapl.utils import (SEPARADOR_HASH_PROPOSICAO, gerar_hash_arquivo, + get_client_ip, google_recaptcha_configured, + intervalos_tem_intersecao, is_weak_password, + mail_service_configured, sapn_is_enabled, + show_results_filter_set) + +from .forms import (AlterarSenhaForm, CasaLegislativaForm, + ConfiguracoesAppForm, EstatisticasAcessoNormasForm) from .models import AppConfig, CasaLegislativa @@ -63,28 +66,33 @@ def get_casalegislativa(): class IndexView(TemplateView): def get(self, request, *args, **kwargs): if sapn_is_enabled(): - return redirect('/norma/pesquisar') + return redirect("/norma/pesquisar") return TemplateView.get(self, request, *args, **kwargs) -@method_decorator(ratelimit(key=lambda group, request: get_client_ip(request), - rate='20/m', - method=ratelimit.UNSAFE, - block=True), name='dispatch') +@method_decorator( + ratelimit( + key=lambda group, request: get_client_ip(request), + rate="20/m", + method=ratelimit.UNSAFE, + block=True, + ), + name="dispatch", +) class LoginSapl(views.LoginView): - template_name = 'base/login.html' + template_name = "base/login.html" authentication_form = LoginForm def form_valid(self, form): """Override do comportamento padrão para verificar senha fraca""" - username = form.cleaned_data.get('username') - password = form.cleaned_data.get('password') + username = form.cleaned_data.get("username") + password = form.cleaned_data.get("password") user = authenticate(self.request, username=username, password=password) if user is not None: login(self.request, user) if is_weak_password(password): - self.request.session['weak_password'] = True + self.request.session["weak_password"] = True return redirect(self.get_success_url()) # Fallback se falhar a autenticação (tecnicamente não devia chegar aqui) @@ -95,7 +103,7 @@ class ConfirmarEmailView(TemplateView): template_name = "email/confirma.html" def get(self, request, *args, **kwargs): - uid = urlsafe_base64_decode(self.kwargs['uidb64']) + uid = urlsafe_base64_decode(self.kwargs["uidb64"]) user = get_user_model().objects.get(id=uid) user.is_active = True user.save() @@ -106,58 +114,56 @@ class ConfirmarEmailView(TemplateView): class RecuperarSenhaEmailView(PasswordResetView): logger = logging.getLogger(__name__) - success_url = reverse_lazy('sapl.base:recuperar_senha_finalizado') - email_template_name = 'base/recuperar_senha_email.html' - html_email_template_name = 'base/recuperar_senha_email.html' - template_name = 'base/recuperar_senha_email_form.html' + success_url = reverse_lazy("sapl.base:recuperar_senha_finalizado") + email_template_name = "base/recuperar_senha_email.html" + html_email_template_name = "base/recuperar_senha_email.html" + template_name = "base/recuperar_senha_email_form.html" from_email = EMAIL_SEND_USER form_class = RecuperarSenhaForm def get(self, request, *args, **kwargs): - if not google_recaptcha_configured(): - self.logger.warning(_('Google Recaptcha não configurado!')) - messages.error(request, _('Google Recaptcha não configurado!')) - return redirect(request.headers.get('referer', '/')) + self.logger.warning(_("Google Recaptcha não configurado!")) + messages.error(request, _("Google Recaptcha não configurado!")) + return redirect(request.headers.get("referer", "/")) return PasswordResetView.get(self, request, *args, **kwargs) def post(self, request, *args, **kwargs): - if not google_recaptcha_configured(): - self.logger.warning(_('Google Recaptcha não configurado!')) - messages.error(request, _('Google Recaptcha não configurado!')) - return redirect(request.headers.get('referer', '/')) + self.logger.warning(_("Google Recaptcha não configurado!")) + messages.error(request, _("Google Recaptcha não configurado!")) + return redirect(request.headers.get("referer", "/")) return PasswordResetView.post(self, request, *args, **kwargs) class RecuperarSenhaFinalizadoView(PasswordResetDoneView): - template_name = 'base/recupera_senha_email_enviado.html' + template_name = "base/recupera_senha_email_enviado.html" class RecuperarSenhaConfirmaView(PasswordResetConfirmView): - success_url = reverse_lazy('sapl.base:recuperar_senha_completo') - template_name = 'base/nova_senha_form.html' + success_url = reverse_lazy("sapl.base:recuperar_senha_completo") + template_name = "base/nova_senha_form.html" form_class = NovaSenhaForm class RecuperarSenhaCompletoView(PasswordResetCompleteView): - template_name = 'base/recuperar_senha_completo.html' + template_name = "base/recuperar_senha_completo.html" class TipoAutorCrud(CrudAux): model = TipoAutor - help_topic = 'tipo-autor' + help_topic = "tipo-autor" class BaseMixin(CrudAux.BaseMixin): - list_field_names = ['descricao'] + list_field_names = ["descricao"] form_class = TipoAutorForm @property def verbose_name(self): vn = super().verbose_name - vn = "{} {}".format(vn, _('Externo ao SAPL')) + vn = "{} {}".format(vn, _("Externo ao SAPL")) return vn class ListView(CrudAux.ListView): @@ -171,13 +177,11 @@ class TipoAutorCrud(CrudAux): def get_context_data(self, **kwargs): context = CrudAux.ListView.get_context_data(self, **kwargs) - context['tipos_sapl'] = TipoAutor.objects.filter( - content_type__isnull=False) + context["tipos_sapl"] = TipoAutor.objects.filter(content_type__isnull=False) return context class TipoAutorMixin: - def dispatch(self, request, *args, **kwargs): object = self.get_object() if object.content_type: @@ -196,91 +200,101 @@ class TipoAutorCrud(CrudAux): class AutorCrud(CrudAux): model = Autor - help_topic = 'autor' + help_topic = "autor" class BaseMixin(CrudAux.BaseMixin): - list_field_names = ['nome', 'tipo', 'operadores'] + list_field_names = ["nome", "tipo", "operadores"] def send_mail_operadores(self): username = self.request.user.username if not mail_service_configured(): - self.logger.warning(_('Registro de Autor sem envio de email. ' - 'Servidor de email não configurado.')) + self.logger.warning( + _( + "Registro de Autor sem envio de email. " + "Servidor de email não configurado." + ) + ) return try: - self.logger.debug('user=' + username + - '. Enviando email na criação de Autores.') + self.logger.debug( + "user=" + username + ". Enviando email na criação de Autores." + ) kwargs = {} for user in self.object.operadores.all(): - if not user.email: self.logger.warning( - _('Registro de Autor sem envio de email. ' - 'Usuário sem um email cadastrado.')) + _( + "Registro de Autor sem envio de email. " + "Usuário sem um email cadastrado." + ) + ) continue - kwargs['token'] = default_token_generator.make_token(user) - kwargs['uidb64'] = urlsafe_base64_encode( - force_bytes(user.pk)) + kwargs["token"] = default_token_generator.make_token(user) + kwargs["uidb64"] = urlsafe_base64_encode(force_bytes(user.pk)) assunto = "SAPL - Confirmação de Conta" full_url = self.request.get_raw_uri() - url_base = full_url[:full_url.find('sistema') - 1] + url_base = full_url[: full_url.find("sistema") - 1] mensagem = ( - "Este e-mail foi utilizado para fazer cadastro no " + - "SAPL com o perfil de Autor. Agora você pode " + - "criar/editar/enviar Proposições.\n" + - "Seu nome de usuário é: " + - self.request.POST['username'] + "\n" - "Caso você não tenha feito este cadastro, por favor " + - "ignore esta mensagem. Caso tenha, clique " + - "no link abaixo\n" + url_base + - reverse('sapl.base:confirmar_email', kwargs=kwargs)) + "Este e-mail foi utilizado para fazer cadastro no " + + "SAPL com o perfil de Autor. Agora você pode " + + "criar/editar/enviar Proposições.\n" + + "Seu nome de usuário é: " + + self.request.POST["username"] + + "\n" + "Caso você não tenha feito este cadastro, por favor " + + "ignore esta mensagem. Caso tenha, clique " + + "no link abaixo\n" + + url_base + + reverse("sapl.base:confirmar_email", kwargs=kwargs) + ) remetente = settings.EMAIL_SEND_USER destinatario = [user.email] - send_mail(assunto, mensagem, remetente, destinatario, - fail_silently=False) + send_mail( + assunto, mensagem, remetente, destinatario, fail_silently=False + ) except Exception as e: - print( - _('Erro no envio de email na criação de Autores.')) + print(_("Erro no envio de email na criação de Autores.")) self.logger.error( - 'user=' + username + '. Erro no envio de email na criação de Autores. ' + str(e)) + "user=" + + username + + ". Erro no envio de email na criação de Autores. " + + str(e) + ) class DeleteView(CrudAux.DeleteView): - def delete(self, *args, **kwargs): self.object = self.get_object() - grupo = Group.objects.filter(name='Autor')[0] + grupo = Group.objects.filter(name="Autor")[0] lista_operadores = list(self.object.operadores.all()) response = CrudAux.DeleteView.delete(self, *args, **kwargs) - if not Autor.objects.filter(pk=kwargs['pk']).exists(): + if not Autor.objects.filter(pk=kwargs["pk"]).exists(): for u in lista_operadores: u.groups.remove(grupo) return response class DetailView(CrudAux.DetailView): - def hook_operadores(self, obj): - r = '
    {}
'.format( - ''.join( + r = "
    {}
".format( + "".join( [ - '
  • {} - ({}) - ' - '{}' - '
  • '.format(u.first_name, u, u.email) + "
  • {} - ({}) - " + "{}" + "
  • ".format(u.first_name, u, u.email) for u in obj.operadores.all() ] ) - ) - return 'Operadores', r + return "Operadores", r class UpdateView(CrudAux.UpdateView): logger = logging.getLogger(__name__) @@ -304,20 +318,19 @@ class AutorCrud(CrudAux): form_search_class = ListWithSearchForm def hook_operadores(self, *args, **kwargs): - r = '
      {}
    '.format( - ''.join( + r = "
      {}
    ".format( + "".join( [ - '
  • {} - ({})
  • '.format(u.first_name, u) + "
  • {} - ({})
  • ".format(u.first_name, u) for u in args[0].operadores.all() ] ) - ) - return r, '' + return r, "" def get_queryset(self): qs = self.model.objects.all() - q_param = self.request.GET.get('q', '') + q_param = self.request.GET.get("q", "") if q_param: q = Q(nome__icontains=q_param) q |= Q(cargo__icontains=q_param) @@ -325,46 +338,54 @@ class AutorCrud(CrudAux): q |= Q(operadores__username__icontains=q_param) q |= Q(operadores__email__icontains=q_param) qs = qs.filter(q) - return qs.distinct('nome', 'id').order_by('nome', 'id') + return qs.distinct("nome", "id").order_by("nome", "id") class EstatisticasAcessoNormas(TemplateView): - template_name = 'base/EstatisticasAcessoNormas_filter.html' + template_name = "base/EstatisticasAcessoNormas_filter.html" def get(self, request, *args, **kwargs): - context = super(EstatisticasAcessoNormas, - self).get_context_data(**kwargs) - context['title'] = _('Estatísticas de Acesso às Normas Jurídicas') + context = super(EstatisticasAcessoNormas, self).get_context_data(**kwargs) + context["title"] = _("Estatísticas de Acesso às Normas Jurídicas") form = EstatisticasAcessoNormasForm(request.GET or None) - context['form'] = form + context["form"] = form if not form.is_valid(): return self.render_to_response(context) - context['ano'] = self.request.GET['ano'] - context['mes'] = self.request.GET.get('mes', '') - context['mais_acessadas'] = int( - self.request.GET.get('mais_acessadas', 5)) + context["ano"] = self.request.GET["ano"] + context["mes"] = self.request.GET.get("mes", "") + context["mais_acessadas"] = int(self.request.GET.get("mais_acessadas", 5)) - if not context['mes'] and context['mais_acessadas'] > 10: - context['mais_acessadas'] = 10 + if not context["mes"] and context["mais_acessadas"] > 10: + context["mais_acessadas"] = 10 params = { - 'ano_est': context['ano'], - 'mais_acessadas__lte': context['mais_acessadas'] + "ano_est": context["ano"], + "mais_acessadas__lte": context["mais_acessadas"], } - if context['mes']: - params['mes_est'] = context['mes'] + if context["mes"]: + params["mes_est"] = context["mes"] - estatisticas = ViewNormasEstatisticas.objects.filter( - **params - ) + estatisticas = ViewNormasEstatisticas.objects.filter(**params) normas_count_mes = collections.OrderedDict() normas_mes = collections.OrderedDict() - meses = {1: 'Janeiro', 2: 'Fevereiro', 3: 'Março', 4: 'Abril', 5: 'Maio', 6: 'Junho', - 7: 'Julho', 8: 'Agosto', 9: 'Setembro', 10: 'Outubro', 11: 'Novembro', 12: 'Dezembro'} + meses = { + 1: "Janeiro", + 2: "Fevereiro", + 3: "Março", + 4: "Abril", + 5: "Maio", + 6: "Junho", + 7: "Julho", + 8: "Agosto", + 9: "Setembro", + 10: "Outubro", + 11: "Novembro", + 12: "Dezembro", + } for norma in estatisticas: if not meses[norma.mes_est] in normas_mes: @@ -374,14 +395,13 @@ class EstatisticasAcessoNormas(TemplateView): normas_count_mes[meses[norma.mes_est]] += norma.norma_count normas_mes[meses[norma.mes_est]].append(norma) - context['normas_mes'] = normas_mes + context["normas_mes"] = normas_mes - context['normas_count_mes'] = normas_count_mes + context["normas_count_mes"] = normas_count_mes - is_relatorio = request.GET.get('relatorio') + is_relatorio = request.GET.get("relatorio") - context['show_results'] = show_results_filter_set( - self.request.GET.copy()) + context["show_results"] = show_results_filter_set(self.request.GET.copy()) if is_relatorio: return relatorio_estatisticas_acesso_normas(self, request, context) @@ -391,89 +411,98 @@ class EstatisticasAcessoNormas(TemplateView): class ListarInconsistenciasView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/lista_inconsistencias.html' - context_object_name = 'tabela_inconsistencias' - permission_required = ('base.list_appconfig',) + template_name = "base/lista_inconsistencias.html" + context_object_name = "tabela_inconsistencias" + permission_required = ("base.list_appconfig",) def get_queryset(self): tabela = [] tabela.append( - ('protocolos_duplicados', - 'Protocolos duplicados', - len(protocolos_duplicados()) - ) + ( + "protocolos_duplicados", + "Protocolos duplicados", + len(protocolos_duplicados()), + ) ) tabela.append( - ('protocolos_com_materias', - 'Protocolos que excedem o limite de matérias vinculadas', - len(protocolos_com_materias()) - ) + ( + "protocolos_com_materias", + "Protocolos que excedem o limite de matérias vinculadas", + len(protocolos_com_materias()), + ) ) tabela.append( - ('materias_protocolo_inexistente', - 'Matérias Legislativas com protocolo inexistente', - len(materias_protocolo_inexistente()) - ) + ( + "materias_protocolo_inexistente", + "Matérias Legislativas com protocolo inexistente", + len(materias_protocolo_inexistente()), + ) ) tabela.append( - ('filiacoes_sem_data_filiacao', - 'Filiações sem data filiação', - len(filiacoes_sem_data_filiacao()) - ) + ( + "filiacoes_sem_data_filiacao", + "Filiações sem data filiação", + len(filiacoes_sem_data_filiacao()), + ) ) tabela.append( - ('mandato_sem_data_inicio', - 'Mandatos sem data inicial', - len(mandato_sem_data_inicio()) - ) + ( + "mandato_sem_data_inicio", + "Mandatos sem data inicial", + len(mandato_sem_data_inicio()), + ) ) tabela.append( - ('parlamentares_duplicados', - 'Parlamentares duplicados', - len(parlamentares_duplicados()) - ) + ( + "parlamentares_duplicados", + "Parlamentares duplicados", + len(parlamentares_duplicados()), + ) ) tabela.append( - ('parlamentares_mandatos_intersecao', - 'Parlamentares com mandatos em interseção', - len(parlamentares_mandatos_intersecao()) - ) + ( + "parlamentares_mandatos_intersecao", + "Parlamentares com mandatos em interseção", + len(parlamentares_mandatos_intersecao()), + ) ) tabela.append( - ('parlamentares_filiacoes_intersecao', - 'Parlamentares com filiações em interseção', - len(parlamentares_filiacoes_intersecao()) - ) + ( + "parlamentares_filiacoes_intersecao", + "Parlamentares com filiações em interseção", + len(parlamentares_filiacoes_intersecao()), + ) ) tabela.append( - ('autores_duplicados', - 'Autores duplicados', - len(autores_duplicados()) - ) + ("autores_duplicados", "Autores duplicados", len(autores_duplicados())) ) tabela.append( - ('bancada_comissao_autor_externo', - 'Bancadas e Comissões com autor externo', - len(bancada_comissao_autor_externo()) - ) + ( + "bancada_comissao_autor_externo", + "Bancadas e Comissões com autor externo", + len(bancada_comissao_autor_externo()), + ) ) tabela.append( - ('legislatura_infindavel', - 'Legislaturas sem data fim', - len(legislatura_infindavel()) - ) + ( + "legislatura_infindavel", + "Legislaturas sem data fim", + len(legislatura_infindavel()), + ) ) tabela.append( - ('anexadas_ciclicas', - 'Matérias Anexadas cíclicas', - len(materias_anexadas_ciclicas()) - ) + ( + "anexadas_ciclicas", + "Matérias Anexadas cíclicas", + len(materias_anexadas_ciclicas()), + ) ) tabela.append( - ('anexados_ciclicos', - 'Documentos Anexados cíclicos', - len(anexados_ciclicos(False)) - ) + ( + "anexados_ciclicos", + "Documentos Anexados cíclicos", + len(anexados_ciclicos(False)), + ) ) return tabela @@ -481,10 +510,12 @@ class ListarInconsistenciasView(PermissionRequiredMixin, ListView): def materias_anexadas_ciclicas(): ciclos = [] - for a in Anexada.objects.select_related('materia_principal', - 'materia_anexada', - 'materia_principal__tipo', - 'materia_anexada__tipo'): + for a in Anexada.objects.select_related( + "materia_principal", + "materia_anexada", + "materia_principal__tipo", + "materia_anexada__tipo", + ): visitados = [a.materia_principal] anexadas = [a.materia_anexada] while len(anexadas) > 0: @@ -492,7 +523,11 @@ def materias_anexadas_ciclicas(): if ma not in visitados: visitados.append(ma) anexadas.extend( - [a.materia_anexada for a in Anexada.objects.filter(materia_principal=ma)]) + [ + a.materia_anexada + for a in Anexada.objects.filter(materia_principal=ma) + ] + ) else: ciclo_list = visitados + [ma] ciclos.append(ciclo_list) @@ -519,36 +554,38 @@ def anexados_ciclicos(ofMateriaLegislativa): ciclicos = [] if ofMateriaLegislativa: - principais = Anexada.objects.values( - 'materia_principal' - ).annotate( - count=Count('materia_principal') - ).filter(count__gt=0).order_by('-data_anexacao') + principais = ( + Anexada.objects.values("materia_principal") + .annotate(count=Count("materia_principal")) + .filter(count__gt=0) + .order_by("-data_anexacao") + ) else: - principais = Anexado.objects.values( - 'documento_principal' - ).annotate( - count=Count('documento_principal') - ).filter(count__gt=0).order_by('-data_anexacao') + principais = ( + Anexado.objects.values("documento_principal") + .annotate(count=Count("documento_principal")) + .filter(count__gt=0) + .order_by("-data_anexacao") + ) for principal in principais: anexados_total = [] if ofMateriaLegislativa: anexados = Anexada.objects.filter( - materia_principal=principal['materia_principal'] - ).order_by('-data_anexacao') + materia_principal=principal["materia_principal"] + ).order_by("-data_anexacao") else: anexados = Anexado.objects.filter( - documento_principal=principal['documento_principal'] - ).order_by('-data_anexacao') + documento_principal=principal["documento_principal"] + ).order_by("-data_anexacao") anexados_temp = list(anexados) while anexados_temp: anexado = anexados_temp.pop() if ofMateriaLegislativa: if anexado.materia_anexada not in anexados_total: - if not principal['materia_principal'] == anexado.materia_anexada.pk: + if not principal["materia_principal"] == anexado.materia_anexada.pk: anexados_total.append(anexado.materia_anexada) anexados_anexado = Anexada.objects.filter( materia_principal=anexado.materia_anexada @@ -556,10 +593,18 @@ def anexados_ciclicos(ofMateriaLegislativa): anexados_temp.extend(anexados_anexado) else: ciclicos.append( - (anexado.data_anexacao, anexado.materia_principal, anexado.materia_anexada)) + ( + anexado.data_anexacao, + anexado.materia_principal, + anexado.materia_anexada, + ) + ) else: if anexado.documento_anexado not in anexados_total: - if not principal['documento_principal'] == anexado.documento_anexado.pk: + if ( + not principal["documento_principal"] + == anexado.documento_anexado.pk + ): anexados_total.append(anexado.documento_anexado) anexados_anexado = Anexado.objects.filter( documento_principal=anexado.documento_anexado @@ -567,112 +612,106 @@ def anexados_ciclicos(ofMateriaLegislativa): anexados_temp.extend(anexados_anexado) else: ciclicos.append( - (anexado.data_anexacao, anexado.documento_principal, anexado.documento_anexado)) + ( + anexado.data_anexacao, + anexado.documento_principal, + anexado.documento_anexado, + ) + ) return ciclicos class ListarAnexadosCiclicosView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/anexados_ciclicos.html' - context_object_name = 'anexados_ciclicos' - permission_required = ('base.list_appconfig',) + template_name = "base/anexados_ciclicos.html" + context_object_name = "anexados_ciclicos" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return anexados_ciclicos(False) def get_context_data(self, **kwargs): - context = super( - ListarAnexadosCiclicosView, self - ).get_context_data(**kwargs) + context = super(ListarAnexadosCiclicosView, self).get_context_data(**kwargs) - paginator = context['paginator'] - page_obj = context['page_obj'] + paginator = context["paginator"] + page_obj = context["page_obj"] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages - ) - context['NO_ENTRIES_MSG'] = 'Nenhum encontrado.' + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) + context["NO_ENTRIES_MSG"] = "Nenhum encontrado." return context class ListarAnexadasCiclicasView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/anexadas_ciclicas.html' - context_object_name = 'anexadas_ciclicas' - permission_required = ('base.list_appconfig',) + template_name = "base/anexadas_ciclicas.html" + context_object_name = "anexadas_ciclicas" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return materias_anexadas_ciclicas() def get_context_data(self, **kwargs): - context = super( - ListarAnexadasCiclicasView, self - ).get_context_data(**kwargs) + context = super(ListarAnexadasCiclicasView, self).get_context_data(**kwargs) - paginator = context['paginator'] - page_obj = context['page_obj'] + paginator = context["paginator"] + page_obj = context["page_obj"] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages - ) - context['NO_ENTRIES_MSG'] = 'Nenhuma encontrada.' + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) + context["NO_ENTRIES_MSG"] = "Nenhuma encontrada." return context def legislatura_infindavel(): - return Legislatura.objects.filter(data_fim__isnull=True).order_by('-numero') + return Legislatura.objects.filter(data_fim__isnull=True).order_by("-numero") class ListarLegislaturaInfindavelView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/legislatura_infindavel.html' - context_object_name = 'legislatura_infindavel' - permission_required = ('base.list_appconfig',) + template_name = "base/legislatura_infindavel.html" + context_object_name = "legislatura_infindavel" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return legislatura_infindavel() def get_context_data(self, **kwargs): - context = super( - ListarLegislaturaInfindavelView, self - ).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' - ] = 'Nenhuma encontrada.' + context = super(ListarLegislaturaInfindavelView, self).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"] = "Nenhuma encontrada." return context def bancada_comissao_autor_externo(): - tipo_autor_externo = TipoAutor.objects.filter(descricao='Externo') + tipo_autor_externo = TipoAutor.objects.filter(descricao="Externo") lista_bancada_autor_externo = [] - for bancada in Bancada.objects.all().order_by('nome'): + for bancada in Bancada.objects.all().order_by("nome"): autor_externo = bancada.autor.filter(tipo__in=tipo_autor_externo) if autor_externo: q_autor_externo = bancada.autor.get(tipo__in=tipo_autor_externo) lista_bancada_autor_externo.append( - (q_autor_externo, bancada, 'Bancada', 'sistema/bancada') + (q_autor_externo, bancada, "Bancada", "sistema/bancada") ) lista_comissao_autor_externo = [] - for comissao in Comissao.objects.all().order_by('nome'): + for comissao in Comissao.objects.all().order_by("nome"): autor_externo = comissao.autor.filter(tipo__in=tipo_autor_externo) if autor_externo: q_autor_externo = comissao.autor.get(tipo__in=tipo_autor_externo) lista_comissao_autor_externo.append( - (q_autor_externo, comissao, 'Comissão', 'comissao') + (q_autor_externo, comissao, "Comissão", "comissao") ) return lista_bancada_autor_externo + lista_comissao_autor_externo @@ -680,37 +719,39 @@ def bancada_comissao_autor_externo(): class ListarBancadaComissaoAutorExternoView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/bancada_comissao_autor_externo.html' - context_object_name = 'bancada_comissao_autor_externo' - permission_required = ('base.list_appconfig',) + template_name = "base/bancada_comissao_autor_externo.html" + context_object_name = "bancada_comissao_autor_externo" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return bancada_comissao_autor_externo() def get_context_data(self, **kwargs): - context = super( - ListarBancadaComissaoAutorExternoView, self - ).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' - ] = 'Nenhuma encontrada.' + context = super(ListarBancadaComissaoAutorExternoView, self).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"] = "Nenhuma encontrada." return context def autores_duplicados(): - return [autor for autor in Autor.objects.values('nome').annotate(count=Count('nome')).filter(count__gt=1)] + return [ + autor + for autor in Autor.objects.values("nome") + .annotate(count=Count("nome")) + .filter(count__gt=1) + ] class ListarAutoresDuplicadosView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/autores_duplicados.html' - context_object_name = 'autores_duplicados' - permission_required = ('base.list_appconfig',) + template_name = "base/autores_duplicados.html" + context_object_name = "autores_duplicados" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): @@ -718,36 +759,39 @@ class ListarAutoresDuplicadosView(PermissionRequiredMixin, ListView): 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 encontrado.' + paginator = context["paginator"] + page_obj = context["page_obj"] + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) + context["NO_ENTRIES_MSG"] = "Nenhum encontrado." return context def parlamentares_filiacoes_intersecao(): intersecoes = [] - for parlamentar in Parlamentar.objects.all().order_by('nome_parlamentar'): + for parlamentar in Parlamentar.objects.all().order_by("nome_parlamentar"): filiacoes = parlamentar.filiacao_set.all() combinacoes = itertools.combinations(filiacoes, 2) for c in combinacoes: data_filiacao1 = c[0].data - data_desfiliacao1 = c[0].data_desfiliacao if c[0].data_desfiliacao else timezone.now( - ).date() + data_desfiliacao1 = ( + c[0].data_desfiliacao + if c[0].data_desfiliacao + else timezone.now().date() + ) data_filiacao2 = c[1].data - data_desfiliacao2 = c[1].data_desfiliacao if c[1].data_desfiliacao else timezone.now( - ).date() + data_desfiliacao2 = ( + c[1].data_desfiliacao + if c[1].data_desfiliacao + else timezone.now().date() + ) if data_filiacao1 and data_filiacao2: exists = intervalos_tem_intersecao( - data_filiacao1, data_desfiliacao1, - data_filiacao2, data_desfiliacao2) + data_filiacao1, data_desfiliacao1, data_filiacao2, data_desfiliacao2 + ) if exists: intersecoes.append((parlamentar, c[0], c[1])) return intersecoes @@ -755,47 +799,54 @@ def parlamentares_filiacoes_intersecao(): class ListarParlFiliacoesIntersecaoView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/parlamentares_filiacoes_intersecao.html' - context_object_name = 'parlamentares_filiacoes_intersecao' - permission_required = ('base.list_appconfig',) + template_name = "base/parlamentares_filiacoes_intersecao.html" + context_object_name = "parlamentares_filiacoes_intersecao" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return parlamentares_filiacoes_intersecao() def get_context_data(self, **kwargs): - context = super( - ListarParlFiliacoesIntersecaoView, self).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 encontrado.' + context = super(ListarParlFiliacoesIntersecaoView, self).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 encontrado." return context def parlamentares_mandatos_intersecao(): intersecoes = [] - for parlamentar in Parlamentar.objects.all().order_by('nome_parlamentar'): + for parlamentar in Parlamentar.objects.all().order_by("nome_parlamentar"): mandatos = parlamentar.mandato_set.all() combinacoes = itertools.combinations(mandatos, 2) for c in combinacoes: data_inicio_mandato1 = c[0].data_inicio_mandato - data_fim_mandato1 = c[0].data_fim_mandato if c[0].data_fim_mandato else timezone.now( - ).date() + data_fim_mandato1 = ( + c[0].data_fim_mandato + if c[0].data_fim_mandato + else timezone.now().date() + ) data_inicio_mandato2 = c[1].data_inicio_mandato - data_fim_mandato2 = c[1].data_fim_mandato if c[1].data_fim_mandato else timezone.now( - ).date() + data_fim_mandato2 = ( + c[1].data_fim_mandato + if c[1].data_fim_mandato + else timezone.now().date() + ) if data_inicio_mandato1 and data_inicio_mandato2: exists = intervalos_tem_intersecao( - data_inicio_mandato1, data_fim_mandato1, - data_inicio_mandato2, data_fim_mandato2) + data_inicio_mandato1, + data_fim_mandato1, + data_inicio_mandato2, + data_fim_mandato2, + ) if exists: intersecoes.append((parlamentar, c[0], c[1])) @@ -804,58 +855,60 @@ def parlamentares_mandatos_intersecao(): class ListarParlMandatosIntersecaoView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/parlamentares_mandatos_intersecao.html' - context_object_name = 'parlamentares_mandatos_intersecao' - permission_required = ('base.list_appconfig',) + template_name = "base/parlamentares_mandatos_intersecao.html" + context_object_name = "parlamentares_mandatos_intersecao" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return parlamentares_mandatos_intersecao() def get_context_data(self, **kwargs): - context = super( - ListarParlMandatosIntersecaoView, self).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 encontrado.' + context = super(ListarParlMandatosIntersecaoView, self).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 encontrado." return context def parlamentares_duplicados(): - return [parlamentar for parlamentar in Parlamentar.objects.values( - 'nome_parlamentar').order_by('nome_parlamentar').annotate(count=Count( - 'nome_parlamentar')).filter(count__gt=1)] + return [ + parlamentar + for parlamentar in Parlamentar.objects.values("nome_parlamentar") + .order_by("nome_parlamentar") + .annotate(count=Count("nome_parlamentar")) + .filter(count__gt=1) + ] class ListarParlamentaresDuplicadosView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/parlamentares_duplicados.html' - context_object_name = 'parlamentares_duplicados' - permission_required = ('base.list_appconfig',) + template_name = "base/parlamentares_duplicados.html" + context_object_name = "parlamentares_duplicados" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return parlamentares_duplicados() def get_context_data(self, **kwargs): - context = super( - ListarParlamentaresDuplicadosView, self).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 encontrado.' + context = super(ListarParlamentaresDuplicadosView, self).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 encontrado." return context def mandato_sem_data_inicio(): - return Mandato.objects.filter(data_inicio_mandato__isnull=True).order_by('parlamentar') + return Mandato.objects.filter(data_inicio_mandato__isnull=True).order_by( + "parlamentar" + ) def get_estatistica(request): @@ -863,117 +916,117 @@ def get_estatistica(request): 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() + 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(), ] - 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({ - "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() - }) + 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( + { + "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): model = get_user_model() - template_name = 'base/mandato_sem_data_inicio.html' - context_object_name = 'mandato_sem_data_inicio' - permission_required = ('base.list_appconfig',) + template_name = "base/mandato_sem_data_inicio.html" + context_object_name = "mandato_sem_data_inicio" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return mandato_sem_data_inicio() def get_context_data(self, **kwargs): - context = super( - ListarMandatoSemDataInicioView, self - ).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 encontrado.' + context = super(ListarMandatoSemDataInicioView, self).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 encontrado." return context def filiacoes_sem_data_filiacao(): - return Filiacao.objects.filter(data__isnull=True).order_by('parlamentar') + return Filiacao.objects.filter(data__isnull=True).order_by("parlamentar") class ListarFiliacoesSemDataFiliacaoView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/filiacoes_sem_data_filiacao.html' - context_object_name = 'filiacoes_sem_data_filiacao' - permission_required = ('base.list_appconfig',) + template_name = "base/filiacoes_sem_data_filiacao.html" + context_object_name = "filiacoes_sem_data_filiacao" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return filiacoes_sem_data_filiacao() def get_context_data(self, **kwargs): - context = super( - ListarFiliacoesSemDataFiliacaoView, self - ).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' - ] = 'Nenhuma encontrada.' + context = super(ListarFiliacoesSemDataFiliacaoView, self).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"] = "Nenhuma encontrada." return context def materias_protocolo_inexistente(): materias = [] - for materia in MateriaLegislativa.objects.filter(numero_protocolo__isnull=False).order_by('-ano', 'numero'): + for materia in MateriaLegislativa.objects.filter( + numero_protocolo__isnull=False + ).order_by("-ano", "numero"): exists = Protocolo.objects.filter( - ano=materia.ano, numero=materia.numero_protocolo).exists() + ano=materia.ano, numero=materia.numero_protocolo + ).exists() if not exists: - materias.append( - (materia, materia.ano, materia.numero_protocolo)) + materias.append((materia, materia.ano, materia.numero_protocolo)) return materias class ListarMatProtocoloInexistenteView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/materias_protocolo_inexistente.html' - context_object_name = 'materias_protocolo_inexistente' - permission_required = ('base.list_appconfig',) + template_name = "base/materias_protocolo_inexistente.html" + context_object_name = "materias_protocolo_inexistente" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return materias_protocolo_inexistente() def get_context_data(self, **kwargs): - context = super( - ListarMatProtocoloInexistenteView, self - ).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' - ] = 'Nenhuma encontrada.' + context = super(ListarMatProtocoloInexistenteView, self).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"] = "Nenhuma encontrada." return context def protocolos_com_materias(): protocolos = {} - for m in MateriaLegislativa.objects.filter(numero_protocolo__isnull=False).order_by('-ano', 'numero_protocolo'): + for m in MateriaLegislativa.objects.filter(numero_protocolo__isnull=False).order_by( + "-ano", "numero_protocolo" + ): if Protocolo.objects.filter(numero=m.numero_protocolo, ano=m.ano).exists(): key = "{}/{}".format(m.numero_protocolo, m.ano) val = protocolos.get(key, list()) @@ -985,54 +1038,51 @@ def protocolos_com_materias(): class ListarProtocolosComMateriasView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/protocolos_com_materias.html' - context_object_name = 'protocolos_com_materias' - permission_required = ('base.list_appconfig',) + template_name = "base/protocolos_com_materias.html" + context_object_name = "protocolos_com_materias" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return protocolos_com_materias() def get_context_data(self, **kwargs): - context = super( - ListarProtocolosComMateriasView, self).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 encontrado.' + context = super(ListarProtocolosComMateriasView, self).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 encontrado." return context def protocolos_duplicados(): return [ - protocolo for protocolo in Protocolo.objects.values( - 'numero', 'ano').order_by('-ano', 'numero').annotate(total=Count('numero')).filter(total__gt=1) + protocolo + for protocolo in Protocolo.objects.values("numero", "ano") + .order_by("-ano", "numero") + .annotate(total=Count("numero")) + .filter(total__gt=1) ] class ListarProtocolosDuplicadosView(PermissionRequiredMixin, ListView): model = get_user_model() - template_name = 'base/protocolos_duplicados.html' - context_object_name = 'protocolos_duplicados' - permission_required = ('base.list_appconfig',) + template_name = "base/protocolos_duplicados.html" + context_object_name = "protocolos_duplicados" + permission_required = ("base.list_appconfig",) paginate_by = 10 def get_queryset(self): return protocolos_duplicados() def get_context_data(self, **kwargs): - context = super( - ListarProtocolosDuplicadosView, self).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 encontrado.' + context = super(ListarProtocolosDuplicadosView, self).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 encontrado." return context @@ -1040,21 +1090,16 @@ class UserCrud(Crud): model = get_user_model() class BaseMixin(Crud.BaseMixin): - list_field_names = [ - 'usuario', 'groups', 'is_active' - ] + list_field_names = ["usuario", "groups", "is_active"] def openapi_url(self): - return '' + return "" def resolve_url(self, suffix, args=None): - return reverse('sapl.base:%s' % self.url_name(suffix), - args=args) + return reverse("sapl.base:%s" % self.url_name(suffix), args=args) def get_layout(self): - return super().get_layout( - 'base/layouts.yaml' - ) + return super().get_layout("base/layouts.yaml") def get_context_object_name(self, *args, **kwargs): return None @@ -1069,33 +1114,35 @@ class UserCrud(Crud): def get_form_kwargs(self): kwargs = Crud.UpdateView.get_form_kwargs(self) - kwargs['user_session'] = self.request.user - granular = self.request.GET.get('granular', None) + kwargs["user_session"] = self.request.user + granular = self.request.GET.get("granular", None) if not granular is None: - kwargs['granular'] = granular + kwargs["granular"] = granular return kwargs class DetailView(Crud.DetailView): - layout_key = 'UserDetail' + layout_key = "UserDetail" def hook_usuario(self, obj): - return 'Usuário', '{}
    {}'.format( - obj.get_full_name() or '...', - obj.email + return "Usuário", "{}
    {}".format( + obj.get_full_name() or "...", obj.email ) def hook_auth_token(self, obj): - return 'Token', str(obj.auth_token) if hasattr(obj, 'auth_token') else ' ' + return ( + "Token", + str(obj.auth_token) if hasattr(obj, "auth_token") else " ", + ) def hook_username(self, obj): - return 'username', obj.username + return "username", obj.username def get_context_data(self, **kwargs): context = Crud.DetailView.get_context_data(self, **kwargs) - context['title'] = '{} ({})
    {}'.format( - self.object.get_full_name() or '...', + context["title"] = "{} ({})
    {}".format( + self.object.get_full_name() or "...", self.object.username, - self.object.email + self.object.email, ) return context @@ -1103,10 +1150,11 @@ class UserCrud(Crud): def extras_url(self): btns = [ ( - '{}?granular'.format(reverse('sapl.base:user_update', - kwargs={'pk': self.object.pk})), - 'btn-outline-primary', - _('Edição granular') + "{}?granular".format( + reverse("sapl.base:user_update", kwargs={"pk": self.object.pk}) + ), + "btn-outline-primary", + _("Edição granular"), ) ] @@ -1118,29 +1166,30 @@ class UserCrud(Crud): def get_context_data(self, **kwargs): context = Crud.ListView.get_context_data(self, **kwargs) - context['subnav_template_name'] = None - context['title'] = _('Usuários') + context["subnav_template_name"] = None + context["title"] = _("Usuários") return context def hook_header_usuario(self, *args, **kwargs): - return 'Usuário' + return "Usuário" def hook_header_groups(self, *args, **kwargs): - return 'Grupos' + return "Grupos" def hook_header_is_active(self, *args, **kwargs): - return 'Ativo' + return "Ativo" def hook_usuario(self, *args, **kwargs): - return '{} ({})
    {}'.format( - args[0].get_full_name() or '...', - args[0].username, - args[0].email - ), args[2] + return ( + "{} ({})
    {}".format( + args[0].get_full_name() or "...", args[0].username, args[0].email + ), + args[2], + ) def get_queryset(self): qs = self.model.objects.all() - q_param = self.request.GET.get('q', '') + q_param = self.request.GET.get("q", "") if q_param: q = Q(first_name__icontains=q_param) q |= Q(last_name__icontains=q_param) @@ -1149,52 +1198,57 @@ class UserCrud(Crud): q |= Q(groups__name__icontains=q_param) qs = qs.filter(q) - return qs.distinct('id').order_by('-id') + return qs.distinct("id").order_by("-id") class CasaLegislativaCrud(CrudAux): model = CasaLegislativa class BaseMixin(CrudAux.BaseMixin): - list_field_names = ['codigo', 'nome', 'sigla'] + list_field_names = ["codigo", "nome", "sigla"] form_class = CasaLegislativaForm class ListView(CrudAux.ListView): - def get(self, request, *args, **kwargs): casa = get_casalegislativa() if casa: return HttpResponseRedirect( - reverse('sapl.base:casalegislativa_detail', - kwargs={'pk': casa.pk})) + reverse("sapl.base:casalegislativa_detail", kwargs={"pk": casa.pk}) + ) else: - return HttpResponseRedirect( - reverse('sapl.base:casalegislativa_create')) + return HttpResponseRedirect(reverse("sapl.base:casalegislativa_create")) class DetailView(CrudAux.DetailView): - def get(self, request, *args, **kwargs): return HttpResponseRedirect( - reverse('sapl.base:casalegislativa_update', - kwargs={'pk': self.kwargs['pk']})) + reverse( + "sapl.base:casalegislativa_update", kwargs={"pk": self.kwargs["pk"]} + ) + ) class HelpTopicView(TemplateView): logger = logging.getLogger(__name__) def get_template_names(self): - username = self.request.user.username - topico = self.kwargs['topic'] + topico = self.kwargs["topic"] try: - self.logger.debug('user=' + username + - '. Tentando obter template %s.html.' % topico) - get_template('ajuda/%s.html' % topico) + self.logger.debug( + "user=" + username + ". Tentando obter template %s.html." % topico + ) + get_template("ajuda/%s.html" % topico) except TemplateDoesNotExist as e: self.logger.error( - 'user=' + username + '. Erro ao obter template {}.html. Template não existe. '.format(topico) + str(e)) + "user=" + + username + + ". Erro ao obter template {}.html. Template não existe. ".format( + topico + ) + + str(e) + ) raise Http404() - return ['ajuda/%s.html' % topico] + return ["ajuda/%s.html" % topico] class AppConfigCrud(CrudAux): @@ -1202,23 +1256,26 @@ class AppConfigCrud(CrudAux): class BaseMixin(CrudAux.BaseMixin): form_class = ConfiguracoesAppForm - list_url = '' - create_url = '' + list_url = "" + create_url = "" def form_valid(self, form): 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: + recibo_prop_novo = self.request.POST["receber_recibo_proposicao"] + if recibo_prop_novo == "False" and recibo_prop_atual: props = Proposicao.objects.filter( - hash_code='', data_recebimento__isnull=True).exclude(data_envio__isnull=True) + hash_code="", data_recebimento__isnull=True + ).exclude(data_envio__isnull=True) for prop in props: try: self.gerar_hash(prop) except ValidationError as e: - form.add_error('receber_recibo_proposicao', 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)) + prop + ) + ) messages.error(self.request, msg) return super().form_invalid(form) return super().form_valid(form) @@ -1227,18 +1284,21 @@ class AppConfigCrud(CrudAux): if inst.texto_original: try: inst.hash_code = gerar_hash_arquivo( - inst.texto_original.path, str(inst.pk)) + inst.texto_original.path, str(inst.pk) + ) inst.save() except IOError: raise ValidationError( - "Existem proposicoes com arquivos inexistentes.") + "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.hash_code = ( + "P" + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(inst.pk) + ) inst.save() class CreateView(CrudAux.CreateView): - def get(self, request, *args, **kwargs): app_config = AppConfig.objects.first() @@ -1247,48 +1307,47 @@ class AppConfigCrud(CrudAux): app_config.save() return HttpResponseRedirect( - reverse('sapl.base:appconfig_update', - kwargs={'pk': app_config.pk})) + reverse("sapl.base:appconfig_update", kwargs={"pk": app_config.pk}) + ) class UpdateView(CrudAux.UpdateView): form_class = ConfiguracoesAppForm def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['title'] = self.model._meta.verbose_name + context["title"] = self.model._meta.verbose_name return context def get(self, request, *args, **kwargs): - if 'jsidd' in request.GET: - return self.json_simular_identificacao_de_documentos(request, *args, **kwargs) + if "jsidd" in request.GET: + return self.json_simular_identificacao_de_documentos( + request, *args, **kwargs + ) return super().get(request, *args, **kwargs) def json_simular_identificacao_de_documentos(self, request, *args, **kwargs): - DocumentoAdministrativo = apps.get_model( - 'protocoloadm', - 'DocumentoAdministrativo' + "protocoloadm", "DocumentoAdministrativo" ) - d = DocumentoAdministrativo.objects.order_by('-id').first() + d = DocumentoAdministrativo.objects.order_by("-id").first() - jsidd = request.GET.get('jsidd', '') + jsidd = request.GET.get("jsidd", "") values = { - '{sigla}': d.tipo.sigla if d else 'OF', - '{nome}': d.tipo.descricao if d else 'Ofício', - '{numero}': f'{d.numero:0>3}' if d else '001', - '{ano}': f'{d.ano}' if d else str(timezone.now().year), - '{complemento}': d.complemento if d else 'GAB', - '{assunto}': d.assunto if d else 'Simulação de Identificação de Documentos' + "{sigla}": d.tipo.sigla if d else "OF", + "{nome}": d.tipo.descricao if d else "Ofício", + "{numero}": f"{d.numero:0>3}" if d else "001", + "{ano}": f"{d.ano}" if d else str(timezone.now().year), + "{complemento}": d.complemento if d else "GAB", + "{assunto}": d.assunto + if d + else "Simulação de Identificação de Documentos", } result = DocumentoAdministrativo.mask_to_str(values, jsidd) - return JsonResponse({ - 'jsidd': result[0], - 'error': list(result[1]) - }) + return JsonResponse({"jsidd": result[0], "error": list(result[1])}) def form_valid(self, form): numeracao = AppConfig.objects.last().sequencia_numeracao_protocolo @@ -1298,14 +1357,14 @@ class AppConfigCrud(CrudAux): numeracao_nova = self.object.inicio_numeracao_protocolo if numeracao_nova != numeracao_antiga: - if numeracao == 'A': + if numeracao == "A": numero_max = Protocolo.objects.filter( ano=timezone.now().year - ).aggregate(Max('numero'))['numero__max'] - elif numeracao == 'L': + ).aggregate(Max("numero"))["numero__max"] + elif numeracao == "L": legislatura = Legislatura.objects.filter( data_inicio__year__lte=timezone.now().year, - data_fim__year__gte=timezone.now().year + data_fim__year__gte=timezone.now().year, ).first() data_inicio = legislatura.data_inicio @@ -1315,56 +1374,64 @@ class AppConfigCrud(CrudAux): data_fim_utc = from_date_to_datetime_utc(data_fim) numero_max = Protocolo.objects.filter( - Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) | - Q( - timestamp__isnull=False, timestamp__gte=data_inicio_utc, - timestamp__lte=data_fim_utc - ) | Q( + Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) + | Q( + timestamp__isnull=False, + timestamp__gte=data_inicio_utc, + timestamp__lte=data_fim_utc, + ) + | Q( timestamp_data_hora_manual__isnull=False, timestamp_data_hora_manual__gte=data_inicio_utc, timestamp_data_hora_manual__lte=data_fim_utc, ) - ).aggregate(Max('numero'))['numero__max'] - elif numeracao == 'U': - numero_max = Protocolo.objects.all().aggregate( - Max('numero') - )['numero__max'] + ).aggregate(Max("numero"))["numero__max"] + elif numeracao == "U": + numero_max = Protocolo.objects.all().aggregate(Max("numero"))[ + "numero__max" + ] ultimo_numero_cadastrado = int(numero_max) if numero_max else 0 - if numeracao_nova <= ultimo_numero_cadastrado and numeracao != 'U': - msg = "O novo início da numeração de protocolo entrará em vigor na " \ - "próxima sequência, pois já existe protocolo cadastrado com " \ - "número superior ou igual ao número inicial definido." + if numeracao_nova <= ultimo_numero_cadastrado and numeracao != "U": + msg = ( + "O novo início da numeração de protocolo entrará em vigor na " + "próxima sequência, pois já existe protocolo cadastrado com " + "número superior ou igual ao número inicial definido." + ) messages.warning(self.request, msg) return super().form_valid(form) class ListView(CrudAux.ListView): - def get(self, request, *args, **kwargs): - return HttpResponseRedirect(reverse('sapl.base:appconfig_create')) + return HttpResponseRedirect(reverse("sapl.base:appconfig_create")) class DetailView(CrudAux.DetailView): - def get(self, request, *args, **kwargs): - return HttpResponseRedirect(reverse('sapl.base:appconfig_create')) + return HttpResponseRedirect(reverse("sapl.base:appconfig_create")) class DeleteView(CrudAux.DeleteView): - def get(self, request, *args, **kwargs): - return HttpResponseRedirect(reverse('sapl.base:appconfig_create')) + return HttpResponseRedirect(reverse("sapl.base:appconfig_create")) class SaplSearchView(SearchView): results_per_page = 10 - def __init__(self, template=None, load_all=True, form_class=None, searchqueryset=None, results_per_page=None): + def __init__( + self, + template=None, + load_all=True, + form_class=None, + searchqueryset=None, + results_per_page=None, + ): super().__init__( template=template, load_all=load_all, form_class=SaplSearchForm, searchqueryset=None, - results_per_page=results_per_page + results_per_page=results_per_page, ) def get_context(self): @@ -1373,28 +1440,26 @@ class SaplSearchView(SearchView): data = self.request.GET or self.request.POST data = data.copy() - if 'models' in self.request.GET: - models = self.request.GET.getlist('models') + if "models" in self.request.GET: + models = self.request.GET.getlist("models") else: models = [] - context['models'] = '' - context['is_paginated'] = True + context["models"] = "" + context["is_paginated"] = True - page_obj = context['page'] - context['page_obj'] = page_obj - paginator = context['paginator'] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + page_obj = context["page"] + context["page_obj"] = page_obj + paginator = context["paginator"] + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) - if 'page' in data: - del data['page'] + if "page" in data: + del data["page"] - context['filter_url'] = ( - '&' + data.urlencode()) if len(data) > 0 else '' + context["filter_url"] = ("&" + data.urlencode()) if len(data) > 0 else "" for m in models: - context['models'] = context['models'] + '&models=' + m + context["models"] = context["models"] + "&models=" + m return context @@ -1404,60 +1469,56 @@ class PesquisarAuditLogView(PermissionRequiredMixin, FilterView): filterset_class = AuditLogFilterSet paginate_by = 20 - permission_required = ('base.list_appconfig',) + permission_required = ("base.list_appconfig",) def get_filterset_kwargs(self, filterset_class): - super(PesquisarAuditLogView, self).get_filterset_kwargs( - filterset_class - ) + super(PesquisarAuditLogView, self).get_filterset_kwargs(filterset_class) - return ({ + return { "data": self.request.GET or None, - "queryset": self.get_queryset().order_by("-id") - }) + "queryset": self.get_queryset().order_by("-id"), + } def get_context_data(self, **kwargs): - context = super(PesquisarAuditLogView, self).get_context_data( - **kwargs - ) + context = super(PesquisarAuditLogView, self).get_context_data(**kwargs) paginator = context["paginator"] page_obj = context["page_obj"] qr = self.request.GET.copy() - if 'page' in qr: - del qr['page'] - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' - context['show_results'] = show_results_filter_set(qr) - - context.update({ - "page_range": make_pagination( - page_obj.number, paginator.num_pages - ), - "NO_ENTRIES_MSG": "Nenhum registro de log encontrado!", - "title": _("Pesquisar Logs de Auditoria") - }) + if "page" in qr: + del qr["page"] + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" + context["show_results"] = show_results_filter_set(qr) + + context.update( + { + "page_range": make_pagination(page_obj.number, paginator.num_pages), + "NO_ENTRIES_MSG": "Nenhum registro de log encontrado!", + "title": _("Pesquisar Logs de Auditoria"), + } + ) return context def get(self, request, *args, **kwargs): - timefilter = request.GET.get('timestamp', None) + timefilter = request.GET.get("timestamp", None) if not timefilter: newgetrequest = request.GET.copy() - newgetrequest['timestamp'] = 'week' + newgetrequest["timestamp"] = "week" request.GET = newgetrequest super(PesquisarAuditLogView, self).get(request) data = self.filterset.data - url = '' + url = "" if data: - url = '&' + str(self.request.META["QUERY_STRING"]) + url = "&" + str(self.request.META["QUERY_STRING"]) if url.startswith("&page"): - url = '' + url = "" resultados = self.object_list # if 'page' in self.request.META['QUERY_STRING']: @@ -1465,14 +1526,14 @@ class PesquisarAuditLogView(PermissionRequiredMixin, FilterView): # else: # resultados = [] - context = self.get_context_data(filter=self.filterset, - object_list=resultados, - filter_url=url, - numero_res=len(resultados) - ) + context = self.get_context_data( + filter=self.filterset, + object_list=resultados, + filter_url=url, + numero_res=len(resultados), + ) - context['show_results'] = show_results_filter_set( - self.request.GET.copy()) + context["show_results"] = show_results_filter_set(self.request.GET.copy()) return self.render_to_response(context) @@ -1481,31 +1542,30 @@ class AlterarSenha(FormView): from sapl.settings import LOGIN_URL form_class = AlterarSenhaForm - template_name = 'base/alterar_senha.html' + template_name = "base/alterar_senha.html" success_url = LOGIN_URL def get_initial(self): initial = super(AlterarSenha, self).get_initial() - initial['username'] = self.request.user + initial["username"] = self.request.user return initial def form_valid(self, form): - new_password = form.cleaned_data['new_password1'] + new_password = form.cleaned_data["new_password1"] user = self.request.user user.set_password(new_password) user.save() - self.request.session.pop('weak_password', None) + self.request.session.pop("weak_password", None) return super().form_valid(form) -STATIC_LOGO = os.path.join(settings.STATIC_URL, 'img/logo.png') +STATIC_LOGO = os.path.join(settings.STATIC_URL, "img/logo.png") class LogotipoView(RedirectView): - def get_redirect_url(self, *args, **kwargs): casa = get_casalegislativa() logo = casa and casa.logotipo and casa.logotipo.name @@ -1513,16 +1573,18 @@ class LogotipoView(RedirectView): def filtro_campos(dicionario): - chaves_desejadas = ['ementa', - 'ano', - 'numero', - 'em_tramitacao', - 'data_apresentacao', - 'apelido', - 'indexacao', - 'data_publicacao', - 'data', - 'data_vigencia'] + chaves_desejadas = [ + "ementa", + "ano", + "numero", + "em_tramitacao", + "data_apresentacao", + "apelido", + "indexacao", + "data_publicacao", + "data", + "data_vigencia", + ] del_list = [] for key in dicionario.keys(): if key not in chaves_desejadas: @@ -1535,32 +1597,30 @@ def filtro_campos(dicionario): def pesquisa_textual(request): - if 'q' not in request.GET: - return JsonResponse({'total': 0, - 'resultados': []}) + if "q" not in request.GET: + return JsonResponse({"total": 0, "resultados": []}) - results = SearchQuerySet().filter(content=request.GET['q']) + results = SearchQuerySet().filter(content=request.GET["q"]) json_dict = { - 'total': results.count(), - 'parametros': request.GET['q'], - 'resultados': [], + "total": results.count(), + "parametros": request.GET["q"], + "resultados": [], } for e in results: - sec_dict = {} try: - sec_dict['pk'] = e.object.pk + sec_dict["pk"] = e.object.pk except: # Index and db are out of sync. Object has been deleted from # database continue dici = filtro_campos(e.object.__dict__) - sec_dict['objeto'] = str(dici) - sec_dict['text'] = str(e.object.ementa) + sec_dict["objeto"] = str(dici) + sec_dict["text"] = str(e.object.ementa) - sec_dict['model'] = str(type(e.object)) + sec_dict["model"] = str(type(e.object)) - json_dict['resultados'].append(sec_dict) + json_dict["resultados"].append(sec_dict) return JsonResponse(json_dict) diff --git a/sapl/comissoes/apps.py b/sapl/comissoes/apps.py index 49a63c70c..179c23a1e 100644 --- a/sapl/comissoes/apps.py +++ b/sapl/comissoes/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.comissoes' - label = 'comissoes' - verbose_name = _('Comissões') + name = "sapl.comissoes" + label = "comissoes" + verbose_name = _("Comissões") diff --git a/sapl/comissoes/forms.py b/sapl/comissoes/forms.py index 7fd2cfa1c..693477b6f 100644 --- a/sapl/comissoes/forms.py +++ b/sapl/comissoes/forms.py @@ -1,34 +1,30 @@ -import django_filters import logging +import django_filters from crispy_forms.layout import Fieldset, Layout - from django import forms from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError from django.db import transaction from django.db.models import Q from django.forms import ModelForm -from django.utils.translation import gettext_lazy as _ from django.utils import timezone +from django.utils.translation import gettext_lazy as _ from sapl.base.models import Autor, TipoAutor -from sapl.comissoes.models import (Comissao, Composicao, - DocumentoAcessorio, Participacao, - Periodo, Reuniao) -from sapl.crispy_layout_mixin import (form_actions, SaplFormHelper, - to_row) +from sapl.comissoes.models import (Comissao, Composicao, DocumentoAcessorio, + Participacao, Periodo, Reuniao) +from sapl.crispy_layout_mixin import SaplFormHelper, form_actions, to_row from sapl.materia.models import MateriaEmTramitacao, PautaReuniao -from sapl.parlamentares.models import (Legislatura, Mandato, - Parlamentar) -from sapl.utils import (FileFieldCheckMixin, - FilterOverridesMetaMixin, validar_arquivo) +from sapl.parlamentares.models import Legislatura, Mandato, Parlamentar +from sapl.utils import (FileFieldCheckMixin, FilterOverridesMetaMixin, + validar_arquivo) class ComposicaoForm(forms.ModelForm): - comissao = forms.CharField( - required=False, label='Comissao', widget=forms.HiddenInput()) + required=False, label="Comissao", widget=forms.HiddenInput() + ) logger = logging.getLogger(__name__) class Meta: @@ -37,48 +33,60 @@ class ComposicaoForm(forms.ModelForm): def __init__(self, user=None, **kwargs): super(ComposicaoForm, self).__init__(**kwargs) - self.fields['comissao'].widget.attrs['disabled'] = 'disabled' + self.fields["comissao"].widget.attrs["disabled"] = "disabled" def clean(self): data = super().clean() - data['comissao'] = self.initial['comissao'] - comissao_pk = self.initial['comissao'].id + data["comissao"] = self.initial["comissao"] + comissao_pk = self.initial["comissao"].id if not self.is_valid(): return data - periodo = data['periodo'] + periodo = data["periodo"] if periodo.data_fim: intersecao_periodo = Composicao.objects.filter( - Q(periodo__data_inicio__lte=periodo.data_fim, periodo__data_fim__gte=periodo.data_fim) | - Q(periodo__data_inicio__gte=periodo.data_inicio, periodo__data_fim__lte=periodo.data_inicio), - comissao_id=comissao_pk) + Q( + periodo__data_inicio__lte=periodo.data_fim, + periodo__data_fim__gte=periodo.data_fim, + ) + | Q( + periodo__data_inicio__gte=periodo.data_inicio, + periodo__data_fim__lte=periodo.data_inicio, + ), + comissao_id=comissao_pk, + ) else: intersecao_periodo = Composicao.objects.filter( - Q(periodo__data_inicio__gte=periodo.data_inicio, periodo__data_fim__lte=periodo.data_inicio), - comissao_id=comissao_pk) + Q( + periodo__data_inicio__gte=periodo.data_inicio, + periodo__data_fim__lte=periodo.data_inicio, + ), + comissao_id=comissao_pk, + ) if intersecao_periodo: if periodo.data_fim: self.logger.warning( - 'O período informado ({} a {}) choca com períodos já cadastrados para esta comissão'.format( + "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.warning( - 'O período informado ({} - ) choca com períodos já cadastrados para esta comissão'.format( + "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') + raise ValidationError( + "O período informado choca com períodos já cadastrados para esta comissão" + ) return data class PeriodoForm(forms.ModelForm): - logger = logging.getLogger(__name__) class Meta: @@ -91,54 +99,57 @@ class PeriodoForm(forms.ModelForm): if not self.is_valid(): return cleaned_data - data_inicio = cleaned_data['data_inicio'] - data_fim = cleaned_data['data_fim'] + data_inicio = cleaned_data["data_inicio"] + data_fim = cleaned_data["data_fim"] if data_fim and data_fim < data_inicio: self.logger.warning( - 'A Data Final ({}) é menor que ' - 'a Data Inicial({}).'.format(data_fim, data_inicio) + "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" ) - raise ValidationError('A Data Final não pode ser menor que ' - 'a Data Inicial') # Evita NoneType exception se não preenchida a data_fim if not data_fim: data_fim = data_inicio - legislatura = Legislatura.objects.filter(data_inicio__lte=data_inicio, - data_fim__gte=data_fim, - ) + legislatura = Legislatura.objects.filter( + data_inicio__lte=data_inicio, + data_fim__gte=data_fim, + ) if not legislatura: self.logger.warning( - 'O período informado ({} a {})' - 'não está contido em uma única ' - 'legislatura existente'.format(data_inicio, data_fim) + "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" ) - raise ValidationError('O período informado ' - 'deve estar contido em uma única ' - 'legislatura existente') return cleaned_data class ParticipacaoCreateForm(forms.ModelForm): - logger = logging.getLogger(__name__) parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput()) class Meta: model = Participacao - fields = '__all__' - exclude = ['composicao'] + fields = "__all__" + exclude = ["composicao"] def __init__(self, user=None, **kwargs): super(ParticipacaoCreateForm, self).__init__(**kwargs) if self.instance: - comissao = kwargs['initial'] - comissao_pk = int(comissao['parent_pk']) + comissao = kwargs["initial"] + comissao_pk = int(comissao["parent_pk"]) composicao = Composicao.objects.get(id=comissao_pk) participantes = composicao.participacao_set.all() id_part = [p.parlamentar.id for p in participantes] @@ -147,22 +158,25 @@ class ParticipacaoCreateForm(forms.ModelForm): qs = self.create_participacao() - parlamentares = Mandato.objects.filter(qs, - parlamentar__ativo=True - ).prefetch_related('parlamentar').\ - values_list('parlamentar', - flat=True - ).distinct() - qs = Parlamentar.objects.filter(id__in=parlamentares).distinct().\ - exclude(id__in=id_part) + parlamentares = ( + Mandato.objects.filter(qs, parlamentar__ativo=True) + .prefetch_related("parlamentar") + .values_list("parlamentar", flat=True) + .distinct() + ) + qs = ( + Parlamentar.objects.filter(id__in=parlamentares) + .distinct() + .exclude(id__in=id_part) + ) eligible = self.verifica() result = list(set(qs) & set(eligible)) if result == eligible: - self.fields['parlamentar'].queryset = qs + self.fields["parlamentar"].queryset = qs else: ids = [e.id for e in eligible] qs = Parlamentar.objects.filter(id__in=ids) - self.fields['parlamentar'].queryset = qs + self.fields["parlamentar"].queryset = qs def clean(self): cleaned_data = super(ParticipacaoCreateForm, self).clean() @@ -170,51 +184,62 @@ class ParticipacaoCreateForm(forms.ModelForm): if not self.is_valid(): return cleaned_data - data_designacao = cleaned_data['data_designacao'] - data_desligamento = cleaned_data['data_desligamento'] + data_designacao = cleaned_data["data_designacao"] + data_desligamento = cleaned_data["data_desligamento"] - if data_desligamento and \ - data_designacao > data_desligamento: + if data_desligamento and data_designacao > data_desligamento: self.logger.warning( - 'Data de designação ({}) superior ' - 'à data de desligamento ({})'.format(data_designacao, data_desligamento) + "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") ) - raise ValidationError(_('Data de designação não pode ser superior ' - 'à data de desligamento')) - composicao = Composicao.objects.get(id=self.initial['parent_pk']) + composicao = Composicao.objects.get(id=self.initial["parent_pk"]) cargos_unicos = [ - c.cargo.nome for c in composicao.participacao_set.filter(cargo__unico=True)] + c.cargo.nome for c in composicao.participacao_set.filter(cargo__unico=True) + ] - if cleaned_data['cargo'].nome in cargos_unicos: - msg = _('Este cargo é único para esta Comissão.') + if cleaned_data["cargo"].nome in cargos_unicos: + msg = _("Este cargo é único para esta Comissão.") self.logger.warning( - 'Este cargo ({}) é único para esta Comissão.'.format( - cleaned_data['cargo'].nome + "Este cargo ({}) é único para esta Comissão.".format( + cleaned_data["cargo"].nome ) ) raise ValidationError(msg) return cleaned_data def create_participacao(self): - composicao = Composicao.objects.get(id=self.initial['parent_pk']) + composicao = Composicao.objects.get(id=self.initial["parent_pk"]) data_inicio_comissao = composicao.periodo.data_inicio - data_fim_comissao = composicao.periodo.data_fim if composicao.periodo.data_fim else timezone.now() - q1 = Q(data_fim_mandato__isnull=False, - data_fim_mandato__gte=data_inicio_comissao) - q2 = Q(data_inicio_mandato__gte=data_inicio_comissao) \ - & Q(data_inicio_mandato__lte=data_fim_comissao) - q3 = Q(data_fim_mandato__isnull=True, - data_inicio_mandato__lte=data_inicio_comissao) + data_fim_comissao = ( + composicao.periodo.data_fim + if composicao.periodo.data_fim + else timezone.now() + ) + q1 = Q( + data_fim_mandato__isnull=False, data_fim_mandato__gte=data_inicio_comissao + ) + q2 = Q(data_inicio_mandato__gte=data_inicio_comissao) & Q( + data_inicio_mandato__lte=data_fim_comissao + ) + q3 = Q( + data_fim_mandato__isnull=True, data_inicio_mandato__lte=data_inicio_comissao + ) qs = q1 | q2 | q3 return qs def verifica(self): - composicao = Composicao.objects.get(id=self.initial['parent_pk']) + composicao = Composicao.objects.get(id=self.initial["parent_pk"]) participantes = composicao.participacao_set.all() participantes_id = [p.parlamentar.id for p in participantes] - parlamentares = Parlamentar.objects.all().exclude( - id__in=participantes_id).order_by('nome_completo') + parlamentares = ( + Parlamentar.objects.all() + .exclude(id__in=participantes_id) + .order_by("nome_completo") + ) parlamentares = [p for p in parlamentares if p.ativo] lista = [] @@ -226,9 +251,13 @@ class ParticipacaoCreateForm(forms.ModelForm): data_fim = m.data_fim_mandato comp_data_inicio = composicao.periodo.data_inicio comp_data_fim = composicao.periodo.data_fim - if (data_fim and data_fim >= comp_data_inicio)\ - or (data_inicio >= comp_data_inicio and data_inicio <= comp_data_fim)\ - or (data_fim is None and data_inicio <= comp_data_inicio): + if ( + (data_fim and data_fim >= comp_data_inicio) + or ( + data_inicio >= comp_data_inicio and data_inicio <= comp_data_fim + ) + or (data_fim is None and data_inicio <= comp_data_inicio) + ): lista.append(p) lista = list(set(lista)) @@ -237,25 +266,32 @@ class ParticipacaoCreateForm(forms.ModelForm): class ParticipacaoEditForm(forms.ModelForm): - logger = logging.getLogger(__name__) parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput()) - nome_parlamentar = forms.CharField(required=False, label='Parlamentar') + nome_parlamentar = forms.CharField(required=False, label="Parlamentar") class Meta: model = Participacao - fields = ['nome_parlamentar', 'parlamentar', 'cargo', 'titular', - 'data_designacao', 'data_desligamento', - 'motivo_desligamento', 'observacao'] + fields = [ + "nome_parlamentar", + "parlamentar", + "cargo", + "titular", + "data_designacao", + "data_desligamento", + "motivo_desligamento", + "observacao", + ] widgets = { - 'parlamentar': forms.HiddenInput(), + "parlamentar": forms.HiddenInput(), } def __init__(self, user=None, **kwargs): super(ParticipacaoEditForm, self).__init__(**kwargs) - self.initial['nome_parlamentar'] = Parlamentar.objects.get( - id=self.initial['parlamentar']).nome_parlamentar - self.fields['nome_parlamentar'].widget.attrs['disabled'] = 'disabled' + self.initial["nome_parlamentar"] = Parlamentar.objects.get( + id=self.initial["parlamentar"] + ).nome_parlamentar + self.fields["nome_parlamentar"].widget.attrs["disabled"] = "disabled" def clean(self): cleaned_data = super(ParticipacaoEditForm, self).clean() @@ -263,29 +299,33 @@ class ParticipacaoEditForm(forms.ModelForm): if not self.is_valid(): return cleaned_data - data_designacao = cleaned_data['data_designacao'] - data_desligamento = cleaned_data['data_desligamento'] + data_designacao = cleaned_data["data_designacao"] + data_desligamento = cleaned_data["data_desligamento"] - if data_desligamento and \ - data_designacao > data_desligamento: + if data_desligamento and data_designacao > data_desligamento: self.logger.warning( - 'Data de designação ({}) superior ' - 'à data de desligamento ({})'.format(data_designacao, data_desligamento) + "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") ) - raise ValidationError(_('Data de designação não pode ser superior ' - 'à data de desligamento')) composicao_id = self.instance.composicao_id composicao = Composicao.objects.get(id=composicao_id) - cargos_unicos = [c.cargo.nome for c in - composicao.participacao_set.filter(cargo__unico=True).exclude(id=self.instance.pk)] + cargos_unicos = [ + c.cargo.nome + for c in composicao.participacao_set.filter(cargo__unico=True).exclude( + id=self.instance.pk + ) + ] - if cleaned_data['cargo'].nome in cargos_unicos: - msg = _('Este cargo é único para esta Comissão.') + if cleaned_data["cargo"].nome in cargos_unicos: + msg = _("Este cargo é único para esta Comissão.") self.logger.warning( - 'Este cargo ({}) é único para esta Comissão (id={}).'.format( - cleaned_data['cargo'].nome, composicao_id + "Este cargo ({}) é único para esta Comissão (id={}).".format( + cleaned_data["cargo"].nome, composicao_id ) ) raise ValidationError(msg) @@ -294,23 +334,28 @@ class ParticipacaoEditForm(forms.ModelForm): class ComissaoForm(forms.ModelForm): - logger = logging.getLogger(__name__) class Meta: model = Comissao - fields = '__all__' + fields = "__all__" def __init__(self, user=None, **kwargs): super(ComissaoForm, self).__init__(**kwargs) inst = self.instance if inst.pk: - if inst.tipo.natureza == 'P': - self.fields['apelido_temp'].widget.attrs['disabled'] = 'disabled' - self.fields['data_instalacao_temp'].widget.attrs['disabled'] = 'disabled' - self.fields['data_final_prevista_temp'].widget.attrs['disabled'] = 'disabled' - self.fields['data_prorrogada_temp'].widget.attrs['disabled'] = 'disabled' - self.fields['data_fim_comissao'].widget.attrs['disabled'] = 'disabled' + if inst.tipo.natureza == "P": + self.fields["apelido_temp"].widget.attrs["disabled"] = "disabled" + self.fields["data_instalacao_temp"].widget.attrs[ + "disabled" + ] = "disabled" + self.fields["data_final_prevista_temp"].widget.attrs[ + "disabled" + ] = "disabled" + self.fields["data_prorrogada_temp"].widget.attrs[ + "disabled" + ] = "disabled" + self.fields["data_fim_comissao"].widget.attrs["disabled"] = "disabled" def clean(self): super(ComissaoForm, self).clean() @@ -318,71 +363,92 @@ class ComissaoForm(forms.ModelForm): if not self.is_valid(): return self.cleaned_data - 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.warning( - 'Nome da Comissão deve ter no máximo 50 caracteres.' + 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.warning("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') + 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.warning( - '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'] + "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') + 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.warning( - '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'] + "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') + 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.warning( - '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'] + "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') + 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.warning( - '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'] + "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']): + 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.') + "Data Prevista para Término não pode ser menor que a de Instalação." + ) self.logger.warning( - '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'] + "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.') + 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.warning( - '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'] + "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) @@ -396,12 +462,9 @@ class ComissaoForm(forms.ModelForm): content_type = ContentType.objects.get_for_model(Comissao) object_id = comissao.pk tipo = TipoAutor.objects.get(content_type=content_type) - nome = comissao.sigla + ' - ' + comissao.nome + nome = comissao.sigla + " - " + comissao.nome Autor.objects.create( - content_type=content_type, - object_id=object_id, - tipo=tipo, - nome=nome + content_type=content_type, object_id=object_id, tipo=tipo, nome=nome ) return comissao else: @@ -410,14 +473,14 @@ class ComissaoForm(forms.ModelForm): class ReuniaoForm(ModelForm): - logger = logging.getLogger(__name__) - comissao = forms.ModelChoiceField(queryset=Comissao.objects.all(), - widget=forms.HiddenInput()) + comissao = forms.ModelChoiceField( + queryset=Comissao.objects.all(), widget=forms.HiddenInput() + ) class Meta: model = Reuniao - exclude = ['cod_andamento_reuniao'] + exclude = ["cod_andamento_reuniao"] def clean(self): super(ReuniaoForm, self).clean() @@ -425,28 +488,28 @@ class ReuniaoForm(ModelForm): if not self.is_valid(): return self.cleaned_data - if self.cleaned_data['hora_fim']: - if (self.cleaned_data['hora_fim'] < - self.cleaned_data['hora_inicio']): + if self.cleaned_data["hora_fim"]: + if self.cleaned_data["hora_fim"] < self.cleaned_data["hora_inicio"]: msg = _( - 'A hora de término da reunião não pode ser menor que a de início') + "A hora de término da reunião não pode ser menor que a de início" + ) self.logger.warning( "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.cleaned_data["hora_fim"], self.cleaned_data["hora_inicio"] ) ) raise ValidationError(msg) - upload_pauta = self.cleaned_data.get('upload_pauta', False) - upload_ata = self.cleaned_data.get('upload_ata', False) - upload_anexo = self.cleaned_data.get('upload_anexo', False) + upload_pauta = self.cleaned_data.get("upload_pauta", False) + upload_ata = self.cleaned_data.get("upload_ata", False) + upload_anexo = self.cleaned_data.get("upload_anexo", False) if upload_pauta: validar_arquivo(upload_pauta, "Pauta da Reunião") - + if upload_ata: validar_arquivo(upload_ata, "Ata da Reunião") - + if upload_anexo: validar_arquivo(upload_anexo, "Anexo da Reunião") @@ -454,59 +517,62 @@ class ReuniaoForm(ModelForm): class PautaReuniaoFilterSet(django_filters.FilterSet): - class Meta(FilterOverridesMetaMixin): model = MateriaEmTramitacao - fields = ['materia__tipo', 'materia__ano', 'materia__numero', 'materia__data_apresentacao'] + fields = [ + "materia__tipo", + "materia__ano", + "materia__numero", + "materia__data_apresentacao", + ] def __init__(self, *args, **kwargs): super(PautaReuniaoFilterSet, self).__init__(*args, **kwargs) - self.filters['materia__tipo'].label = "Tipo da Matéria" - self.filters['materia__ano'].label = "Ano da Matéria" - self.filters['materia__numero'].label = "Número da Matéria" - self.filters['materia__data_apresentacao'].label = "Data (Inicial - Final)" + self.filters["materia__tipo"].label = "Tipo da Matéria" + self.filters["materia__ano"].label = "Ano da Matéria" + self.filters["materia__numero"].label = "Número da Matéria" + self.filters["materia__data_apresentacao"].label = "Data (Inicial - Final)" - row1 = to_row([('materia__tipo', 4), ('materia__ano', 4), ('materia__numero', 4)]) - row2 = to_row([('materia__data_apresentacao', 12)]) + row1 = to_row( + [("materia__tipo", 4), ("materia__ano", 4), ("materia__numero", 4)] + ) + row2 = to_row([("materia__data_apresentacao", 12)]) self.form.helper = SaplFormHelper() self.form.helper.form_method = "GET" self.form.helper.layout = Layout( Fieldset( - _("Pesquisa de Matérias"), row1, row2, - form_actions(label="Pesquisar") + _("Pesquisa de Matérias"), row1, row2, form_actions(label="Pesquisar") ) ) class PautaReuniaoForm(forms.ModelForm): - class Meta: model = PautaReuniao - exclude = ['reuniao'] + exclude = ["reuniao"] class DocumentoAcessorioCreateForm(FileFieldCheckMixin, forms.ModelForm): - parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput()) class Meta: model = DocumentoAcessorio - exclude = ['reuniao'] + exclude = ["reuniao"] def __init__(self, user=None, **kwargs): super(DocumentoAcessorioCreateForm, self).__init__(**kwargs) if self.instance: - reuniao = Reuniao.objects.get(id=self.initial['parent_pk']) + reuniao = Reuniao.objects.get(id=self.initial["parent_pk"]) comissao = reuniao.comissao comissao_pk = comissao.id documentos = reuniao.documentoacessorio_set.all() return self.create_documentoacessorio() def create_documentoacessorio(self): - reuniao = Reuniao.objects.get(id=self.initial['parent_pk']) + reuniao = Reuniao.objects.get(id=self.initial["parent_pk"]) def clean(self): super(DocumentoAcessorioCreateForm, self).clean() @@ -514,7 +580,7 @@ class DocumentoAcessorioCreateForm(FileFieldCheckMixin, forms.ModelForm): if not self.is_valid(): return self.cleaned_data - arquivo = self.cleaned_data.get('arquivo') + arquivo = self.cleaned_data.get("arquivo") if arquivo: validar_arquivo(arquivo, "Texto Integral") @@ -529,13 +595,11 @@ class DocumentoAcessorioCreateForm(FileFieldCheckMixin, forms.ModelForm): class DocumentoAcessorioEditForm(FileFieldCheckMixin, forms.ModelForm): - parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput()) class Meta: model = DocumentoAcessorio - fields = ['nome', 'data', 'autor', 'ementa', - 'indexacao', 'arquivo'] + fields = ["nome", "data", "autor", "ementa", "indexacao", "arquivo"] def __init__(self, user=None, **kwargs): super(DocumentoAcessorioEditForm, self).__init__(**kwargs) @@ -546,7 +610,7 @@ class DocumentoAcessorioEditForm(FileFieldCheckMixin, forms.ModelForm): if not self.is_valid(): return self.cleaned_data - arquivo = self.cleaned_data.get('arquivo') + arquivo = self.cleaned_data.get("arquivo") if arquivo: validar_arquivo(arquivo, "Texto Integral") diff --git a/sapl/comissoes/models.py b/sapl/comissoes/models.py index 0245a2d8a..2b365da65 100644 --- a/sapl/comissoes/models.py +++ b/sapl/comissoes/models.py @@ -4,261 +4,276 @@ from model_utils import Choices from sapl.base.models import Autor from sapl.parlamentares.models import Parlamentar -from sapl.utils import (YES_NO_CHOICES, SaplGenericRelation, - restringe_tipos_de_arquivo_txt, texto_upload_path, - OverwriteStorage) +from sapl.utils import (YES_NO_CHOICES, OverwriteStorage, SaplGenericRelation, + restringe_tipos_de_arquivo_txt, texto_upload_path) class TipoComissao(models.Model): - NATUREZA_CHOICES = Choices(('T', 'temporaria', _('Temporária')), - ('P', 'permanente', _('Permanente'))) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) + NATUREZA_CHOICES = Choices( + ("T", "temporaria", _("Temporária")), ("P", "permanente", _("Permanente")) + ) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) natureza = models.CharField( - max_length=1, verbose_name=_('Natureza'), choices=NATUREZA_CHOICES) - sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) + max_length=1, verbose_name=_("Natureza"), choices=NATUREZA_CHOICES + ) + sigla = models.CharField(max_length=10, verbose_name=_("Sigla")) dispositivo_regimental = models.CharField( - max_length=50, - blank=True, - verbose_name=_('Dispositivo Regimental')) + max_length=50, blank=True, verbose_name=_("Dispositivo Regimental") + ) class Meta: - verbose_name = _('Tipo de Comissão') - verbose_name_plural = _('Tipos de Comissão') - ordering = ('id',) + verbose_name = _("Tipo de Comissão") + verbose_name_plural = _("Tipos de Comissão") + ordering = ("id",) def __str__(self): return self.nome class Comissao(models.Model): - tipo = models.ForeignKey(TipoComissao, - on_delete=models.PROTECT, - verbose_name=_('Tipo')) - nome = models.CharField(max_length=100, verbose_name=_('Nome')) - sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) - data_criacao = models.DateField(verbose_name=_('Data de Criação')) + tipo = models.ForeignKey( + TipoComissao, on_delete=models.PROTECT, verbose_name=_("Tipo") + ) + nome = models.CharField(max_length=100, verbose_name=_("Nome")) + sigla = models.CharField(max_length=10, verbose_name=_("Sigla")) + data_criacao = models.DateField(verbose_name=_("Data de Criação")) data_extincao = models.DateField( - blank=True, null=True, verbose_name=_('Data de Extinção')) + blank=True, null=True, verbose_name=_("Data de Extinção") + ) apelido_temp = models.CharField( - max_length=100, blank=True, verbose_name=_('Apelido')) + max_length=100, blank=True, verbose_name=_("Apelido") + ) data_instalacao_temp = models.DateField( - blank=True, null=True, verbose_name=_('Data Instalação')) + blank=True, null=True, verbose_name=_("Data Instalação") + ) data_final_prevista_temp = models.DateField( - blank=True, null=True, verbose_name=_('Data Prevista Término')) + blank=True, null=True, verbose_name=_("Data Prevista Término") + ) data_prorrogada_temp = models.DateField( - blank=True, null=True, verbose_name=_('Novo Prazo')) + blank=True, null=True, verbose_name=_("Novo Prazo") + ) data_fim_comissao = models.DateField( - blank=True, null=True, verbose_name=_('Data Término')) + blank=True, null=True, verbose_name=_("Data Término") + ) secretario = models.CharField( - max_length=30, blank=True, verbose_name=_('Secretário')) + max_length=30, blank=True, verbose_name=_("Secretário") + ) telefone_reuniao = models.CharField( - max_length=15, blank=True, - verbose_name=_('Tel. Sala Reunião')) + max_length=15, blank=True, verbose_name=_("Tel. Sala Reunião") + ) endereco_secretaria = models.CharField( - max_length=100, blank=True, - verbose_name=_('Endereço Secretaria')) + max_length=100, blank=True, verbose_name=_("Endereço Secretaria") + ) telefone_secretaria = models.CharField( - max_length=15, blank=True, - verbose_name=_('Tel. Secretaria')) + max_length=15, blank=True, verbose_name=_("Tel. Secretaria") + ) fax_secretaria = models.CharField( - max_length=15, blank=True, verbose_name=_('Fax Secretaria')) + max_length=15, blank=True, verbose_name=_("Fax Secretaria") + ) agenda_reuniao = models.CharField( - max_length=100, blank=True, - verbose_name=_('Data/Hora Reunião')) + max_length=100, blank=True, verbose_name=_("Data/Hora Reunião") + ) local_reuniao = models.CharField( - max_length=100, blank=True, verbose_name=_('Local Reunião')) - finalidade = models.TextField( - blank=True, verbose_name=_('Finalidade')) - email = models.EmailField(max_length=100, - blank=True, - verbose_name=_('E-mail')) + max_length=100, blank=True, verbose_name=_("Local Reunião") + ) + finalidade = models.TextField(blank=True, verbose_name=_("Finalidade")) + email = models.EmailField(max_length=100, blank=True, verbose_name=_("E-mail")) unidade_deliberativa = models.BooleanField( - choices=YES_NO_CHOICES, - verbose_name=_('Unidade Deliberativa'), - default=False) + choices=YES_NO_CHOICES, verbose_name=_("Unidade Deliberativa"), default=False + ) ativa = models.BooleanField( - default=False, - choices=YES_NO_CHOICES, - verbose_name=_('Comissão Ativa?')) - autor = SaplGenericRelation(Autor, - related_query_name='comissao_set', - fields_search=( - ('nome', '__icontains'), - ('sigla', '__icontains') - )) + default=False, choices=YES_NO_CHOICES, verbose_name=_("Comissão Ativa?") + ) + autor = SaplGenericRelation( + Autor, + related_query_name="comissao_set", + fields_search=(("nome", "__icontains"), ("sigla", "__icontains")), + ) class Meta: - verbose_name = _('Comissão') - verbose_name_plural = _('Comissões') - ordering = ['nome'] + verbose_name = _("Comissão") + verbose_name_plural = _("Comissões") + ordering = ["nome"] def __str__(self): - return self.sigla + ' - ' + self.nome + return self.sigla + " - " + self.nome class Periodo(models.Model): # PeriodoCompComissao - data_inicio = models.DateField(verbose_name=_('Data Início')) - data_fim = models.DateField( - blank=True, null=True, verbose_name=_('Data Fim')) + data_inicio = models.DateField(verbose_name=_("Data Início")) + data_fim = models.DateField(blank=True, null=True, verbose_name=_("Data Fim")) class Meta: - verbose_name = _('Período de composição de Comissão') - verbose_name_plural = _('Períodos de composição de Comissão') - ordering = ['-data_inicio', '-data_fim'] + verbose_name = _("Período de composição de Comissão") + verbose_name_plural = _("Períodos de composição de Comissão") + ordering = ["-data_inicio", "-data_fim"] def __str__(self): if self.data_inicio and self.data_fim: - return '%s - %s' % (self.data_inicio.strftime("%d/%m/%Y"), - self.data_fim.strftime("%d/%m/%Y")) + return "%s - %s" % ( + self.data_inicio.strftime("%d/%m/%Y"), + self.data_fim.strftime("%d/%m/%Y"), + ) elif self.data_inicio and not self.data_fim: - return '%s - ' % self.data_inicio.strftime("%d/%m/%Y") + return "%s - " % self.data_inicio.strftime("%d/%m/%Y") else: - return '-' + return "-" class CargoComissao(models.Model): id_ordenacao = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Posição na Ordenação'), + blank=True, + null=True, + verbose_name=_("Posição na Ordenação"), ) - nome = models.CharField(max_length=50, verbose_name=_('Nome do Cargo')) + nome = models.CharField(max_length=50, verbose_name=_("Nome do Cargo")) unico = models.BooleanField( - choices=YES_NO_CHOICES, verbose_name=_('Cargo Único'), default=True + choices=YES_NO_CHOICES, verbose_name=_("Cargo Único"), default=True ) class Meta: - verbose_name = _('Cargo de Comissão') - verbose_name_plural = _('Cargos de Comissão') - ordering = ['id_ordenacao'] + verbose_name = _("Cargo de Comissão") + verbose_name_plural = _("Cargos de Comissão") + ordering = ["id_ordenacao"] def __str__(self): return self.nome class Composicao(models.Model): # IGNORE - comissao = models.ForeignKey(Comissao, - on_delete=models.CASCADE, - verbose_name=_('Comissão')) - periodo = models.ForeignKey(Periodo, - on_delete=models.PROTECT, - verbose_name=_('Período')) + comissao = models.ForeignKey( + Comissao, on_delete=models.CASCADE, verbose_name=_("Comissão") + ) + periodo = models.ForeignKey( + Periodo, on_delete=models.PROTECT, verbose_name=_("Período") + ) class Meta: - verbose_name = _('Composição de Comissão') - verbose_name_plural = _('Composições de Comissão') - ordering = ['periodo'] + verbose_name = _("Composição de Comissão") + verbose_name_plural = _("Composições de Comissão") + ordering = ["periodo"] def __str__(self): - return '%s: %s' % (self.comissao.sigla, self.periodo) + return "%s: %s" % (self.comissao.sigla, self.periodo) class Participacao(models.Model): # ComposicaoComissao - composicao = models.ForeignKey(Composicao, - related_name='participacao_set', - on_delete=models.CASCADE, - verbose_name=_('Composição')) - parlamentar = models.ForeignKey(Parlamentar, - on_delete=models.PROTECT, - verbose_name='Parlamentar') - cargo = models.ForeignKey(CargoComissao, - on_delete=models.PROTECT, - verbose_name='Cargo') + composicao = models.ForeignKey( + Composicao, + related_name="participacao_set", + on_delete=models.CASCADE, + verbose_name=_("Composição"), + ) + parlamentar = models.ForeignKey( + Parlamentar, on_delete=models.PROTECT, verbose_name="Parlamentar" + ) + cargo = models.ForeignKey( + CargoComissao, on_delete=models.PROTECT, verbose_name="Cargo" + ) titular = models.BooleanField( - verbose_name=_('Titular'), - default=False, - choices=YES_NO_CHOICES) - data_designacao = models.DateField(verbose_name=_('Data Designação')) - data_desligamento = models.DateField(blank=True, - null=True, - verbose_name=_('Data Desligamento')) + verbose_name=_("Titular"), default=False, choices=YES_NO_CHOICES + ) + data_designacao = models.DateField(verbose_name=_("Data Designação")) + data_desligamento = models.DateField( + blank=True, null=True, verbose_name=_("Data Desligamento") + ) motivo_desligamento = models.TextField( - blank=True, verbose_name=_('Motivo Desligamento')) - observacao = models.TextField( - blank=True, verbose_name=_('Observação')) + blank=True, verbose_name=_("Motivo Desligamento") + ) + observacao = models.TextField(blank=True, verbose_name=_("Observação")) class Meta: - verbose_name = _('Participação em Comissão') - verbose_name_plural = _('Participações em Comissão') - ordering = ['-titular', 'cargo__id_ordenacao'] + verbose_name = _("Participação em Comissão") + verbose_name_plural = _("Participações em Comissão") + ordering = ["-titular", "cargo__id_ordenacao"] def __str__(self): - return '%s : %s' % (self.cargo, self.parlamentar) + return "%s : %s" % (self.cargo, self.parlamentar) def get_comissao_media_path(instance, subpath, filename): - return './sapl/comissao/%s/%s/%s' % (instance.numero, subpath, filename) + return "./sapl/comissao/%s/%s/%s" % (instance.numero, subpath, filename) def pauta_upload_path(instance, filename): - - return texto_upload_path(instance, filename, subpath='pauta', pk_first=True) + return texto_upload_path(instance, filename, subpath="pauta", pk_first=True) def ata_upload_path(instance, filename): - return texto_upload_path(instance, filename, subpath='ata', pk_first=True) + return texto_upload_path(instance, filename, subpath="ata", pk_first=True) def anexo_upload_path(instance, filename): - return texto_upload_path(instance, filename, subpath='anexo', pk_first=True) + return texto_upload_path(instance, filename, subpath="anexo", pk_first=True) class Reuniao(models.Model): - periodo = models. ForeignKey( + periodo = models.ForeignKey( Periodo, null=True, on_delete=models.PROTECT, - verbose_name=_('Periodo da Composicão da Comissão')) + verbose_name=_("Periodo da Composicão da Comissão"), + ) comissao = models.ForeignKey( - Comissao, - on_delete=models.CASCADE, - verbose_name=_('Comissão')) - numero = models.PositiveIntegerField(verbose_name=_('Número')) - nome = models.CharField( - max_length=150, verbose_name=_('Nome da Reunião')) + Comissao, on_delete=models.CASCADE, verbose_name=_("Comissão") + ) + numero = models.PositiveIntegerField(verbose_name=_("Número")) + nome = models.CharField(max_length=150, verbose_name=_("Nome da Reunião")) tema = models.CharField( - max_length=150, blank=True, verbose_name=_('Tema da Reunião')) - data = models.DateField(verbose_name=_('Data')) + max_length=150, blank=True, verbose_name=_("Tema da Reunião") + ) + data = models.DateField(verbose_name=_("Data")) hora_inicio = models.TimeField( - null=True, - verbose_name=_('Horário de Início (hh:mm)')) + null=True, verbose_name=_("Horário de Início (hh:mm)") + ) hora_fim = models.TimeField( - blank=True, - null=True, - verbose_name=_('Horário de Término (hh:mm)')) + blank=True, null=True, verbose_name=_("Horário de Término (hh:mm)") + ) local_reuniao = models.CharField( - max_length=100, blank=True, verbose_name=_('Local da Reunião')) - observacao = models.TextField( - blank=True, verbose_name=_('Observação')) + max_length=100, blank=True, verbose_name=_("Local da Reunião") + ) + observacao = models.TextField(blank=True, verbose_name=_("Observação")) url_audio = models.URLField( - max_length=150, blank=True, - verbose_name=_('URL do Arquivo de Áudio (Formatos MP3 / AAC)')) + max_length=150, + blank=True, + verbose_name=_("URL do Arquivo de Áudio (Formatos MP3 / AAC)"), + ) url_video = models.URLField( - max_length=150, blank=True, - verbose_name=_('URL do Arquivo de Vídeo (Formatos MP4 / FLV / WebM)')) + max_length=150, + blank=True, + verbose_name=_("URL do Arquivo de Vídeo (Formatos MP4 / FLV / WebM)"), + ) upload_pauta = models.FileField( max_length=300, - blank=True, null=True, + blank=True, + null=True, upload_to=pauta_upload_path, - verbose_name=_('Pauta da Reunião'), + verbose_name=_("Pauta da Reunião"), storage=OverwriteStorage(), - validators=[restringe_tipos_de_arquivo_txt]) + validators=[restringe_tipos_de_arquivo_txt], + ) upload_ata = models.FileField( max_length=300, - blank=True, null=True, + blank=True, + null=True, upload_to=ata_upload_path, - verbose_name=_('Ata da Reunião'), + verbose_name=_("Ata da Reunião"), storage=OverwriteStorage(), - validators=[restringe_tipos_de_arquivo_txt]) + validators=[restringe_tipos_de_arquivo_txt], + ) upload_anexo = models.FileField( max_length=300, - blank=True, null=True, + blank=True, + null=True, upload_to=anexo_upload_path, storage=OverwriteStorage(), - verbose_name=_('Anexo da Reunião')) + verbose_name=_("Anexo da Reunião"), + ) class Meta: - verbose_name = _('Reunião de Comissão') - verbose_name_plural = _('Reuniões de Comissão') - ordering = ('-data', '-nome') + verbose_name = _("Reunião de Comissão") + verbose_name_plural = _("Reuniões de Comissão") + ordering = ("-data", "-nome") def __str__(self): return self.nome @@ -281,67 +296,68 @@ class Reuniao(models.Model): return result - 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): + 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): upload_pauta = self.upload_pauta upload_ata = self.upload_ata upload_anexo = self.upload_anexo self.upload_pauta = None self.upload_ata = None self.upload_anexo = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.upload_pauta = upload_pauta self.upload_ata = upload_ata self.upload_anexo = upload_anexo - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) class DocumentoAcessorio(models.Model): - reuniao = models.ForeignKey(Reuniao, - related_name='documentoacessorio_set', - on_delete=models.PROTECT) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) - - data = models.DateField(blank=True, null=True, - default=None, verbose_name=_('Data')) - autor = models.CharField( - max_length=200, verbose_name=_('Autor')) - ementa = models.TextField(blank=True, verbose_name=_('Ementa')) + reuniao = models.ForeignKey( + Reuniao, related_name="documentoacessorio_set", on_delete=models.PROTECT + ) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) + + data = models.DateField(blank=True, null=True, default=None, verbose_name=_("Data")) + autor = models.CharField(max_length=200, verbose_name=_("Autor")) + ementa = models.TextField(blank=True, verbose_name=_("Ementa")) indexacao = models.TextField(blank=True) arquivo = models.FileField( max_length=300, blank=True, null=True, upload_to=anexo_upload_path, - verbose_name=_('Texto Integral'), + verbose_name=_("Texto Integral"), storage=OverwriteStorage(), - validators=[restringe_tipos_de_arquivo_txt]) + validators=[restringe_tipos_de_arquivo_txt], + ) data_ultima_atualizacao = models.DateTimeField( - blank=True, null=True, - auto_now=True, - verbose_name=_('Data')) + blank=True, null=True, auto_now=True, verbose_name=_("Data") + ) class Meta: - verbose_name = _('Documento Acessório') - verbose_name_plural = _('Documentos Acessórios') - ordering = ('data', 'id') + verbose_name = _("Documento Acessório") + verbose_name_plural = _("Documentos Acessórios") + ordering = ("data", "id") def __str__(self): - return _('%(nome)s por %(autor)s') % { - 'nome': self.nome, - 'autor': self.autor} + return _("%(nome)s por %(autor)s") % {"nome": self.nome, "autor": self.autor} def delete(self, using=None, keep_parents=False): arquivo = self.arquivo @@ -352,19 +368,25 @@ class DocumentoAcessorio(models.Model): return result - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): - + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): if not self.pk and self.arquivo: arquivo = self.arquivo self.arquivo = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.arquivo = arquivo - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) diff --git a/sapl/comissoes/tests/test_comissoes.py b/sapl/comissoes/tests/test_comissoes.py index 9a3c30dd8..33b718410 100644 --- a/sapl/comissoes/tests/test_comissoes.py +++ b/sapl/comissoes/tests/test_comissoes.py @@ -3,61 +3,55 @@ from django.urls import reverse from django.utils.translation import gettext as _ from model_bakery import baker -from sapl.comissoes.models import Comissao, Composicao, Periodo -from sapl.comissoes.models import TipoComissao, Reuniao -from sapl.parlamentares.models import Filiacao, Parlamentar, Partido from sapl.comissoes import forms +from sapl.comissoes.models import (Comissao, Composicao, Periodo, Reuniao, + TipoComissao) +from sapl.parlamentares.models import Filiacao, Parlamentar, Partido def make_composicao(comissao): - periodo = baker.make(Periodo, - data_inicio='2016-01-01', - data_fim='2016-12-31') - baker.make(Composicao, - periodo=periodo, - comissao=comissao) + periodo = baker.make(Periodo, data_inicio="2016-01-01", data_fim="2016-12-31") + baker.make(Composicao, periodo=periodo, comissao=comissao) return Composicao.objects.first() def make_comissao(): tipo = baker.make(TipoComissao) - baker.make(Comissao, - tipo=tipo, - nome='Comissão Teste', - sigla='CT', - data_criacao='2016-03-22') + baker.make( + Comissao, + tipo=tipo, + nome="Comissão Teste", + sigla="CT", + data_criacao="2016-03-22", + ) return Comissao.objects.first() def make_filiacao(): - partido = baker.make(Partido, - nome='Partido Meu', - sigla='PM') - parlamentar = baker.make(Parlamentar, - nome_parlamentar='Eduardo', - nome_completo='Eduardo', - sexo='M', - ativo=True) - baker.make(Filiacao, - data='2016-03-22', - parlamentar=parlamentar, - partido=partido) + partido = baker.make(Partido, nome="Partido Meu", sigla="PM") + parlamentar = baker.make( + Parlamentar, + nome_parlamentar="Eduardo", + nome_completo="Eduardo", + sexo="M", + ativo=True, + ) + baker.make(Filiacao, data="2016-03-22", parlamentar=parlamentar, partido=partido) return Filiacao.objects.first() @pytest.mark.django_db(transaction=False) def test_tipo_comissao_model(): - baker.make(TipoComissao, - nome='Teste_Nome_Tipo_Comissao', - natureza='T', - sigla='TSTC') + baker.make( + TipoComissao, nome="Teste_Nome_Tipo_Comissao", natureza="T", sigla="TSTC" + ) tipo_comissao = TipoComissao.objects.first() - assert tipo_comissao.nome == 'Teste_Nome_Tipo_Comissao' - assert tipo_comissao.natureza == 'T' - assert tipo_comissao.sigla == 'TSTC' + assert tipo_comissao.nome == "Teste_Nome_Tipo_Comissao" + assert tipo_comissao.natureza == "T" + assert tipo_comissao.sigla == "TSTC" @pytest.mark.django_db(transaction=False) @@ -65,67 +59,72 @@ def test_incluir_parlamentar_errors(admin_client): comissao = make_comissao() composicao = make_composicao(comissao) - response = admin_client.post(reverse('sapl.comissoes:participacao_create', - kwargs={'pk': composicao.pk}), - {'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse("sapl.comissoes:participacao_create", kwargs={"pk": composicao.pk}), + {"salvar": "salvar"}, + follow=True, + ) - assert (response.context_data['form'].errors['parlamentar'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['cargo'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['data_designacao'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["parlamentar"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["cargo"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["data_designacao"] == [ + "Este campo é obrigatório." + ] @pytest.mark.django_db(transaction=False) def test_incluir_comissao_submit(admin_client): - tipo = baker.make(TipoComissao, - sigla='T', - nome='Teste') - - response = admin_client.post(reverse('sapl.comissoes:comissao_create'), - {'tipo': tipo.pk, - 'nome': 'Comissão Teste', - 'sigla': 'CT', - 'ativa': True, - 'data_criacao': '2016-03-22', - 'unidade_deliberativa': True, - 'salvar': 'salvar'}, - follow=True) + tipo = baker.make(TipoComissao, sigla="T", nome="Teste") + + response = admin_client.post( + reverse("sapl.comissoes:comissao_create"), + { + "tipo": tipo.pk, + "nome": "Comissão Teste", + "sigla": "CT", + "ativa": True, + "data_criacao": "2016-03-22", + "unidade_deliberativa": True, + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 - + comissao = Comissao.objects.first() - assert comissao.nome == 'Comissão Teste' + assert comissao.nome == "Comissão Teste" assert comissao.tipo == tipo @pytest.mark.django_db(transaction=False) def test_incluir_comissao_errors(admin_client): + response = admin_client.post( + reverse("sapl.comissoes:comissao_create"), {"salvar": "salvar"}, follow=True + ) - response = admin_client.post(reverse('sapl.comissoes:comissao_create'), - {'salvar': 'salvar'}, - follow=True) - - assert (response.context_data['form'].errors['tipo'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['nome'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['sigla'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['data_criacao'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["tipo"] == ["Este campo é obrigatório."] + assert response.context_data["form"].errors["nome"] == ["Este campo é obrigatório."] + assert response.context_data["form"].errors["sigla"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["data_criacao"] == [ + "Este campo é obrigatório." + ] @pytest.mark.django_db(transaction=False) def test_periodo_invalidas(): - - form = forms.PeriodoForm(data={'data_inicio': '10/11/2017', - 'data_fim': '09/11/2017' - }) + form = forms.PeriodoForm( + data={"data_inicio": "10/11/2017", "data_fim": "09/11/2017"} + ) assert not form.is_valid() - assert form.errors['__all__'] == [_('A Data Final não pode ser menor que ' - 'a Data Inicial')] + assert form.errors["__all__"] == [ + _("A Data Final não pode ser menor que " "a Data Inicial") + ] @pytest.mark.django_db(transaction=False) @@ -136,7 +135,7 @@ def test_valida_campos_obrigatorios_periodo_form(): errors = form.errors - assert errors['data_inicio'] == [_('Este campo é obrigatório.')] + assert errors["data_inicio"] == [_("Este campo é obrigatório.")] assert len(errors) == 1 @@ -149,11 +148,11 @@ def test_valida_campos_obrigatorios_reuniao_form(): errors = form.errors - assert errors['comissao'] == [_('Este campo é obrigatório.')] - assert errors['periodo'] == [_('Este campo é obrigatório.')] - assert errors['numero'] == [_('Este campo é obrigatório.')] - assert errors['nome'] == [_('Este campo é obrigatório.')] - assert errors['data'] == [_('Este campo é obrigatório.')] - assert errors['hora_inicio'] == [_('Este campo é obrigatório.')] + assert errors["comissao"] == [_("Este campo é obrigatório.")] + assert errors["periodo"] == [_("Este campo é obrigatório.")] + assert errors["numero"] == [_("Este campo é obrigatório.")] + assert errors["nome"] == [_("Este campo é obrigatório.")] + assert errors["data"] == [_("Este campo é obrigatório.")] + assert errors["hora_inicio"] == [_("Este campo é obrigatório.")] assert len(errors) == 6 diff --git a/sapl/comissoes/urls.py b/sapl/comissoes/urls.py index 2bb6bce65..cd1943677 100644 --- a/sapl/comissoes/urls.py +++ b/sapl/comissoes/urls.py @@ -1,30 +1,48 @@ from django.urls import include, path, re_path -from sapl.comissoes.views import (AdicionaPautaView, CargoComissaoCrud, ComissaoCrud, - ComposicaoCrud, DocumentoAcessorioCrud, + +from sapl.comissoes.views import (AdicionaPautaView, CargoComissaoCrud, + ComissaoCrud, ComposicaoCrud, + DocumentoAcessorioCrud, MateriasTramitacaoListView, ParticipacaoCrud, - get_participacoes_comissao, PeriodoComposicaoCrud, - RemovePautaView, ReuniaoCrud, TipoComissaoCrud) + PeriodoComposicaoCrud, RemovePautaView, + ReuniaoCrud, TipoComissaoCrud, + get_participacoes_comissao) from .apps import AppConfig app_name = AppConfig.name urlpatterns = [ - path('comissao/', include(ComissaoCrud.get_urls() + - ComposicaoCrud.get_urls() + - ReuniaoCrud.get_urls() + - ParticipacaoCrud.get_urls() + - DocumentoAcessorioCrud.get_urls())), - - path('comissao//materias-em-tramitacao', - MateriasTramitacaoListView.as_view(), name='materias_em_tramitacao'), - - re_path(r'^comissao/(?P\d+)/pauta/add', AdicionaPautaView.as_view(), name='pauta_add'), - re_path(r'^comissao/(?P\d+)/pauta/remove', RemovePautaView.as_view(), name='pauta_remove'), - - path('sistema/comissao/cargo/', include(CargoComissaoCrud.get_urls())), - path('sistema/comissao/periodo-composicao/', - include(PeriodoComposicaoCrud.get_urls())), - path('sistema/comissao/tipo/', include(TipoComissaoCrud.get_urls())), - re_path(r'^sistema/comissao/recupera-participacoes', get_participacoes_comissao), + path( + "comissao/", + include( + ComissaoCrud.get_urls() + + ComposicaoCrud.get_urls() + + ReuniaoCrud.get_urls() + + ParticipacaoCrud.get_urls() + + DocumentoAcessorioCrud.get_urls() + ), + ), + path( + "comissao//materias-em-tramitacao", + MateriasTramitacaoListView.as_view(), + name="materias_em_tramitacao", + ), + re_path( + r"^comissao/(?P\d+)/pauta/add", + AdicionaPautaView.as_view(), + name="pauta_add", + ), + re_path( + r"^comissao/(?P\d+)/pauta/remove", + RemovePautaView.as_view(), + name="pauta_remove", + ), + path("sistema/comissao/cargo/", include(CargoComissaoCrud.get_urls())), + path( + "sistema/comissao/periodo-composicao/", + include(PeriodoComposicaoCrud.get_urls()), + ), + path("sistema/comissao/tipo/", include(TipoComissaoCrud.get_urls())), + re_path(r"^sistema/comissao/recupera-participacoes", get_participacoes_comissao), ] diff --git a/sapl/comissoes/views.py b/sapl/comissoes/views.py index a53c1c21b..518395b03 100644 --- a/sapl/comissoes/views.py +++ b/sapl/comissoes/views.py @@ -2,16 +2,15 @@ import logging from django.contrib import messages from django.contrib.auth.mixins import PermissionRequiredMixin -from django.urls import reverse from django.db.models import F from django.http.response import HttpResponseRedirect, JsonResponse +from django.urls import reverse +from django.utils.translation import gettext_lazy as _ from django.views.decorators.clickjacking import xframe_options_exempt from django.views.generic import CreateView, DeleteView, FormView, ListView from django.views.generic.base import RedirectView from django.views.generic.detail import DetailView from django.views.generic.edit import FormMixin, UpdateView -from django.utils.translation import gettext_lazy as _ - from django_filters.views import FilterView from sapl.base.models import AppConfig as AppsAppConfig @@ -19,13 +18,12 @@ from sapl.comissoes.apps import AppConfig from sapl.comissoes.forms import (ComissaoForm, ComposicaoForm, DocumentoAcessorioCreateForm, DocumentoAcessorioEditForm, - ParticipacaoCreateForm, - ParticipacaoEditForm, + ParticipacaoCreateForm, ParticipacaoEditForm, PautaReuniaoFilterSet, PautaReuniaoForm, PeriodoForm, ReuniaoForm) -from sapl.crud.base import (Crud, CrudAux, MasterDetailCrud, - PermissionRequiredForAppCrudMixin, RP_DETAIL, - RP_LIST) +from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, + MasterDetailCrud, + PermissionRequiredForAppCrudMixin) from sapl.materia.models import (MateriaEmTramitacao, MateriaLegislativa, PautaReuniao, Tramitacao) from sapl.utils import show_results_filter_set @@ -37,24 +35,26 @@ from .models import (CargoComissao, Comissao, Composicao, DocumentoAcessorio, def pegar_url_composicao(pk): participacao = Participacao.objects.get(id=pk) comp_pk = participacao.composicao.pk - url = reverse('sapl.comissoes:composicao_detail', kwargs={'pk': comp_pk}) + url = reverse("sapl.comissoes:composicao_detail", kwargs={"pk": comp_pk}) return url def pegar_url_reuniao(pk): documentoacessorio = DocumentoAcessorio.objects.get(id=pk) r_pk = documentoacessorio.reuniao.pk - url = reverse('sapl.comissoes:reuniao_detail', kwargs={'pk': r_pk}) + url = reverse("sapl.comissoes:reuniao_detail", kwargs={"pk": r_pk}) return url + CargoComissaoCrud = CrudAux.build( - CargoComissao, 'cargo_comissao', - list_field_names=['nome', 'id_ordenacao', 'unico'] + CargoComissao, "cargo_comissao", list_field_names=["nome", "id_ordenacao", "unico"] ) TipoComissaoCrud = CrudAux.build( - TipoComissao, 'tipo_comissao', list_field_names=[ - 'sigla', 'nome', 'natureza', 'dispositivo_regimental']) + TipoComissao, + "tipo_comissao", + list_field_names=["sigla", "nome", "natureza", "dispositivo_regimental"], +) class PeriodoComposicaoCrud(CrudAux): @@ -71,48 +71,55 @@ class PeriodoComposicaoCrud(CrudAux): class ParticipacaoCrud(MasterDetailCrud): model = Participacao - parent_field = 'composicao__comissao' - public = [RP_DETAIL, ] + parent_field = "composicao__comissao" + public = [ + RP_DETAIL, + ] ListView = None link_return_to_parent_field = True class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['composicao', 'parlamentar', 'cargo'] + list_field_names = ["composicao", "parlamentar", "cargo"] class CreateView(MasterDetailCrud.CreateView): form_class = ParticipacaoCreateForm def get_initial(self): initial = super().get_initial() - initial['parent_pk'] = self.kwargs['pk'] + initial["parent_pk"] = self.kwargs["pk"] return initial class UpdateView(MasterDetailCrud.UpdateView): - layout_key = 'ParticipacaoEdit' + layout_key = "ParticipacaoEdit" form_class = ParticipacaoEditForm class DeleteView(MasterDetailCrud.DeleteView): - def get_success_url(self): composicao_comissao_pk = self.object.composicao.comissao.pk composicao_pk = self.object.composicao.pk - return '{}?pk={}'.format(reverse('sapl.comissoes:composicao_list', - args=[composicao_comissao_pk]), - composicao_pk) + return "{}?pk={}".format( + reverse( + "sapl.comissoes:composicao_list", args=[composicao_comissao_pk] + ), + composicao_pk, + ) class ComposicaoCrud(MasterDetailCrud): model = Composicao - parent_field = 'comissao' - model_set = 'participacao_set' - public = [RP_LIST, RP_DETAIL, ] + parent_field = "comissao" + model_set = "participacao_set" + public = [ + RP_LIST, + RP_DETAIL, + ] class CreateView(MasterDetailCrud.CreateView): form_class = ComposicaoForm def get_initial(self): - comissao = Comissao.objects.get(id=self.kwargs['pk']) - return {'comissao': comissao} + comissao = Comissao.objects.get(id=self.kwargs["pk"]) + return {"comissao": comissao} class ListView(MasterDetailCrud.ListView): logger = logging.getLogger(__name__) @@ -120,13 +127,19 @@ class ComposicaoCrud(MasterDetailCrud): paginate_by = None def take_composicao_pk(self): - username = self.request.user.username try: - self.logger.debug('user=' + username + '. Tentando obter pk da composição.') - return int(self.request.GET['pk']) + self.logger.debug( + "user=" + username + ". Tentando obter pk da composição." + ) + return int(self.request.GET["pk"]) except Exception as e: - self.logger.error('user=' + username + '. Erro ao obter pk da composição. Retornado 0. ' + str(e)) + self.logger.error( + "user=" + + username + + ". Erro ao obter pk da composição. Retornado 0. " + + str(e) + ) return 0 def get_context_data(self, **kwargs): @@ -137,17 +150,17 @@ class ComposicaoCrud(MasterDetailCrud): if composicao_pk == 0: # Composicao eh ordenada por Periodo, que por sua vez esta em # ordem descrescente de data de inicio (issue #1920) - ultima_composicao = context['composicao_list'].first() + ultima_composicao = context["composicao_list"].first() if ultima_composicao: - context['composicao_pk'] = ultima_composicao.pk + context["composicao_pk"] = ultima_composicao.pk else: - context['composicao_pk'] = 0 + context["composicao_pk"] = 0 else: - context['composicao_pk'] = composicao_pk + context["composicao_pk"] = composicao_pk - context['participacao_set'] = Participacao.objects.filter( - composicao__pk=context['composicao_pk'] - ).order_by('-titular', 'cargo__id_ordenacao', 'id') + context["participacao_set"] = Participacao.objects.filter( + composicao__pk=context["composicao_pk"] + ).order_by("-titular", "cargo__id_ordenacao", "id") return context class DeleteView(MasterDetailCrud.DeleteView): @@ -155,18 +168,31 @@ class ComposicaoCrud(MasterDetailCrud): composicao = self.get_object() composicao.delete() return HttpResponseRedirect( - reverse('sapl.comissoes:composicao_list', kwargs={'pk': composicao.comissao.pk})) + reverse( + "sapl.comissoes:composicao_list", + kwargs={"pk": composicao.comissao.pk}, + ) + ) class ComissaoCrud(Crud): model = Comissao - help_topic = 'modulo_comissoes' - public = [RP_LIST, RP_DETAIL, ] + help_topic = "modulo_comissoes" + public = [ + RP_LIST, + RP_DETAIL, + ] class BaseMixin(Crud.BaseMixin): - list_field_names = ['nome', 'sigla', 'tipo', - 'data_criacao', 'data_extincao', 'ativa'] - ordering = '-ativa', 'sigla' + list_field_names = [ + "nome", + "sigla", + "tipo", + "data_criacao", + "data_extincao", + "ativa", + ] + ordering = "-ativa", "sigla" class CreateView(Crud.CreateView): form_class = ComissaoForm @@ -185,8 +211,8 @@ class ComissaoCrud(Crud): def lista_materias_comissao(comissao_pk): materias = MateriaEmTramitacao.objects.filter( tramitacao__unidade_tramitacao_destino__comissao=comissao_pk - ).order_by('materia__tipo', '-materia__ano', '-materia__numero') - + ).order_by("materia__tipo", "-materia__ano", "-materia__numero") + return materias @@ -195,23 +221,25 @@ class MateriasTramitacaoListView(ListView): paginate_by = 10 def get_queryset(self): - return list(lista_materias_comissao(self.kwargs['pk'])) + return list(lista_materias_comissao(self.kwargs["pk"])) def get_context_data(self, **kwargs): - context = super( - MateriasTramitacaoListView, self).get_context_data(**kwargs) - context['object'] = Comissao.objects.get(id=self.kwargs['pk']) - context['qtde'] = len(self.object_list) + context = super(MateriasTramitacaoListView, self).get_context_data(**kwargs) + context["object"] = Comissao.objects.get(id=self.kwargs["pk"]) + context["qtde"] = len(self.object_list) return context class ReuniaoCrud(MasterDetailCrud): model = Reuniao - parent_field = 'comissao' - public = [RP_LIST, RP_DETAIL, ] + parent_field = "comissao" + public = [ + RP_LIST, + RP_DETAIL, + ] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['data', 'nome', 'tema', 'upload_ata'] + list_field_names = ["data", "nome", "tema", "upload_ata"] class DetailView(MasterDetailCrud.DetailView): template_name = "comissoes/reuniao_detail.html" @@ -220,23 +248,25 @@ class ReuniaoCrud(MasterDetailCrud): context = super().get_context_data(**kwargs) docs = [] - documentos = DocumentoAcessorio.objects.filter(reuniao=self.kwargs['pk']).order_by('nome') + documentos = DocumentoAcessorio.objects.filter( + reuniao=self.kwargs["pk"] + ).order_by("nome") docs.extend(documentos) - context['docs'] = docs - context['num_docs'] = len(docs) + context["docs"] = docs + context["num_docs"] = len(docs) mats = [] - materias_pauta = PautaReuniao.objects.filter(reuniao=self.kwargs['pk']) + materias_pauta = PautaReuniao.objects.filter(reuniao=self.kwargs["pk"]) materias_pk = [materia_pauta.materia.pk for materia_pauta in materias_pauta] - - context['mats'] = MateriaLegislativa.objects.filter( + + context["mats"] = MateriaLegislativa.objects.filter( pk__in=materias_pk - ).order_by('tipo', '-ano', 'numero') - context['num_mats'] = len(context['mats']) + ).order_by("tipo", "-ano", "numero") + context["num_mats"] = len(context["mats"]) + + context["reuniao_pk"] = self.kwargs["pk"] - context['reuniao_pk'] = self.kwargs['pk'] - return context class ListView(MasterDetailCrud.ListView): @@ -244,13 +274,19 @@ class ReuniaoCrud(MasterDetailCrud): paginate_by = 10 def take_reuniao_pk(self): - username = self.request.user.username try: - self.logger.debug('user=' + username + '. Tentando obter pk da reunião.') - return int(self.request.GET['pk']) + self.logger.debug( + "user=" + username + ". Tentando obter pk da reunião." + ) + return int(self.request.GET["pk"]) except Exception as e: - self.logger.error('user=' + username + '. Erro ao obter pk da reunião. Retornado 0. ' + str(e)) + self.logger.error( + "user=" + + username + + ". Erro ao obter pk da reunião. Retornado 0. " + + str(e) + ) return 0 def get_context_data(self, **kwargs): @@ -259,176 +295,183 @@ class ReuniaoCrud(MasterDetailCrud): reuniao_pk = self.take_reuniao_pk() if reuniao_pk == 0: - ultima_reuniao = list(context['reuniao_list']) + ultima_reuniao = list(context["reuniao_list"]) if len(ultima_reuniao) > 0: ultimo = ultima_reuniao[-1] - context['reuniao_pk'] = ultimo.pk + context["reuniao_pk"] = ultimo.pk else: - context['reuniao_pk'] = 0 + context["reuniao_pk"] = 0 else: - context['reuniao_pk'] = reuniao_pk + context["reuniao_pk"] = reuniao_pk - context['documentoacessorio_set'] = DocumentoAcessorio.objects.filter( - reuniao__pk=context['reuniao_pk'] - ).order_by('id') + context["documentoacessorio_set"] = DocumentoAcessorio.objects.filter( + reuniao__pk=context["reuniao_pk"] + ).order_by("id") return context class UpdateView(MasterDetailCrud.UpdateView): form_class = ReuniaoForm def get_initial(self): - return {'comissao': self.object.comissao} + return {"comissao": self.object.comissao} class CreateView(MasterDetailCrud.CreateView): form_class = ReuniaoForm def get_initial(self): - comissao = Comissao.objects.get(id=self.kwargs['pk']) + comissao = Comissao.objects.get(id=self.kwargs["pk"]) - return {'comissao': comissao} + return {"comissao": comissao} class RemovePautaView(PermissionRequiredMixin, CreateView): model = PautaReuniao form_class = PautaReuniaoForm - template_name = 'comissoes/pauta.html' - permission_required = ('comissoes.add_reuniao', ) + template_name = "comissoes/pauta.html" + permission_required = ("comissoes.add_reuniao",) def get_context_data(self, **kwargs): - context = super( - RemovePautaView, self - ).get_context_data(**kwargs) + context = super(RemovePautaView, self).get_context_data(**kwargs) # Remove = 0; Adiciona = 1 - context['opcao'] = 0 + context["opcao"] = 0 - context['object'] = Reuniao.objects.get(pk=self.kwargs['pk']) - context['root_pk'] = context['object'].comissao.pk + context["object"] = Reuniao.objects.get(pk=self.kwargs["pk"]) + context["root_pk"] = context["object"].comissao.pk - materias_pauta = PautaReuniao.objects.filter(reuniao=context['object']) + materias_pauta = PautaReuniao.objects.filter(reuniao=context["object"]) materias_pk = [materia_pauta.materia.pk for materia_pauta in materias_pauta] - - context['materias'] = MateriaLegislativa.objects.filter( + + context["materias"] = MateriaLegislativa.objects.filter( pk__in=materias_pk - ).order_by('tipo', '-ano', 'numero') - context['numero_materias'] = len(context['materias']) + ).order_by("tipo", "-ano", "numero") + context["numero_materias"] = len(context["materias"]) return context def post(self, request, *args, **kwargs): - success_url = reverse('sapl.comissoes:reuniao_detail', kwargs={'pk':kwargs['pk']}) - marcadas = request.POST.getlist('materia_id') + success_url = reverse( + "sapl.comissoes:reuniao_detail", kwargs={"pk": kwargs["pk"]} + ) + marcadas = request.POST.getlist("materia_id") if not marcadas: - msg=_('Nenhuma matéria foi selecionada.') + msg = _("Nenhuma matéria foi selecionada.") messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(success_url) - reuniao = Reuniao.objects.get(pk=kwargs['pk']) + reuniao = Reuniao.objects.get(pk=kwargs["pk"]) for materia in MateriaLegislativa.objects.filter(id__in=marcadas): - PautaReuniao.objects.filter(reuniao=reuniao,materia=materia).delete() + PautaReuniao.objects.filter(reuniao=reuniao, materia=materia).delete() - msg=_('Matéria(s) removida(s) com sucesso!') + msg = _("Matéria(s) removida(s) com sucesso!") messages.add_message(request, messages.SUCCESS, msg) return HttpResponseRedirect(success_url) class AdicionaPautaView(PermissionRequiredMixin, FilterView): filterset_class = PautaReuniaoFilterSet - template_name = 'comissoes/pauta.html' - permission_required = ('comissoes.add_reuniao', ) + template_name = "comissoes/pauta.html" + permission_required = ("comissoes.add_reuniao",) def get_context_data(self, **kwargs): - context = super( - AdicionaPautaView, self - ).get_context_data(**kwargs) + context = super(AdicionaPautaView, self).get_context_data(**kwargs) # Adiciona = 1; Remove = 0 - context['opcao'] = 1 + context["opcao"] = 1 - context['object'] = Reuniao.objects.get(pk=self.kwargs['pk']) - context['root_pk'] = context['object'].comissao.pk + context["object"] = Reuniao.objects.get(pk=self.kwargs["pk"]) + context["root_pk"] = context["object"].comissao.pk qr = self.request.GET.copy() - materias_pauta = PautaReuniao.objects.filter(reuniao=context['object']) + materias_pauta = PautaReuniao.objects.filter(reuniao=context["object"]) nao_listar = [mp.materia.pk for mp in materias_pauta] if not len(qr): - context['object_list'] = [] + context["object_list"] = [] else: - context['object_list'] = context['object_list'].filter( - tramitacao__unidade_tramitacao_destino__comissao=context['root_pk'] - ).exclude(materia__pk__in=nao_listar).order_by( - "materia__tipo", "-materia__ano", "materia__numero" + context["object_list"] = ( + context["object_list"] + .filter( + tramitacao__unidade_tramitacao_destino__comissao=context["root_pk"] + ) + .exclude(materia__pk__in=nao_listar) + .order_by("materia__tipo", "-materia__ano", "materia__numero") ) - context['numero_resultados'] = len(context['object_list']) - context['show_results'] = show_results_filter_set(qr) + context["numero_resultados"] = len(context["object_list"]) + context["show_results"] = show_results_filter_set(qr) return context - + def post(self, request, *args, **kwargs): - success_url = reverse('sapl.comissoes:reuniao_detail', kwargs={'pk':kwargs['pk']}) - marcadas = request.POST.getlist('materia_id') + success_url = reverse( + "sapl.comissoes:reuniao_detail", kwargs={"pk": kwargs["pk"]} + ) + marcadas = request.POST.getlist("materia_id") if not marcadas: - msg = _('Nenhuma máteria foi selecionada.') + msg = _("Nenhuma máteria foi selecionada.") messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(success_url) - - reuniao = Reuniao.objects.get(pk=kwargs['pk']) + + reuniao = Reuniao.objects.get(pk=kwargs["pk"]) pautas = [] for materia in MateriaLegislativa.objects.filter(id__in=marcadas): - pauta = PautaReuniao() - pauta.reuniao = reuniao - pauta.materia = materia - pautas.append(pauta) + pauta = PautaReuniao() + pauta.reuniao = reuniao + pauta.materia = materia + pautas.append(pauta) PautaReuniao.objects.bulk_create(pautas) - - msg = _('Matéria(s) adicionada(s) com sucesso!') + + msg = _("Matéria(s) adicionada(s) com sucesso!") messages.add_message(request, messages.SUCCESS, msg) return HttpResponseRedirect(success_url) class DocumentoAcessorioCrud(MasterDetailCrud): model = DocumentoAcessorio - parent_field = 'reuniao__comissao' - public = [RP_DETAIL, ] + parent_field = "reuniao__comissao" + public = [ + RP_DETAIL, + ] ListView = None link_return_to_parent_field = True class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['nome', 'tipo', 'data', 'autor', 'arquivo'] + list_field_names = ["nome", "tipo", "data", "autor", "arquivo"] class CreateView(MasterDetailCrud.CreateView): form_class = DocumentoAcessorioCreateForm def get_initial(self): initial = super().get_initial() - initial['parent_pk'] = self.kwargs['pk'] + initial["parent_pk"] = self.kwargs["pk"] return initial class UpdateView(MasterDetailCrud.UpdateView): - layout_key = 'DocumentoAcessorioEdit' + layout_key = "DocumentoAcessorioEdit" form_class = DocumentoAcessorioEditForm class DeleteView(MasterDetailCrud.DeleteView): - def delete(self, *args, **kwargs): obj = self.get_object() obj.delete() return HttpResponseRedirect( - reverse('sapl.comissoes:reuniao_detail', - kwargs={'pk': obj.reuniao.pk})) + reverse("sapl.comissoes:reuniao_detail", kwargs={"pk": obj.reuniao.pk}) + ) def get_participacoes_comissao(request): parlamentares = [] - composicao_id = request.GET.get('composicao_id') + composicao_id = request.GET.get("composicao_id") if composicao_id: - parlamentares = [{'nome': p.parlamentar.nome_parlamentar, 'id': p.parlamentar.id} for p in - Participacao.objects.filter(composicao_id=composicao_id).order_by( - 'parlamentar__nome_parlamentar')] + parlamentares = [ + {"nome": p.parlamentar.nome_parlamentar, "id": p.parlamentar.id} + for p in Participacao.objects.filter(composicao_id=composicao_id).order_by( + "parlamentar__nome_parlamentar" + ) + ] return JsonResponse(parlamentares, safe=False) diff --git a/sapl/compilacao/admin.py b/sapl/compilacao/admin.py index 6f1ffbd5a..512e4eb0b 100644 --- a/sapl/compilacao/admin.py +++ b/sapl/compilacao/admin.py @@ -1,4 +1,5 @@ from django.contrib import admin + from sapl.compilacao.models import TipoDispositivo from sapl.utils import register_all_models_in_admin @@ -8,5 +9,8 @@ admin.site.unregister(TipoDispositivo) @admin.register(TipoDispositivo) class TipoDispositivoAdmin(admin.ModelAdmin): - readonly_fields = ("rotulo_prefixo_texto", "rotulo_sufixo_texto",) - list_display = [f.name for f in TipoDispositivo._meta.fields if f.name != 'id'] + readonly_fields = ( + "rotulo_prefixo_texto", + "rotulo_sufixo_texto", + ) + list_display = [f.name for f in TipoDispositivo._meta.fields if f.name != "id"] diff --git a/sapl/compilacao/apps.py b/sapl/compilacao/apps.py index f786fb36b..fda4ef482 100644 --- a/sapl/compilacao/apps.py +++ b/sapl/compilacao/apps.py @@ -1,4 +1,3 @@ - from django import apps from django.conf import settings from django.db import connection, models @@ -7,36 +6,39 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.compilacao' - label = 'compilacao' - verbose_name = _('Compilação') + name = "sapl.compilacao" + label = "compilacao" + verbose_name = _("Compilação") @staticmethod def import_pattern(): + from django.contrib.contenttypes.models import ContentType + from unipath import Path from sapl.compilacao.models import TipoTextoArticulado from sapl.compilacao.utils import get_integrations_view_names - from django.contrib.contenttypes.models import ContentType - from unipath import Path - compilacao_app = Path(__file__).ancestor(1) # print(compilacao_app) - with open(compilacao_app + '/compilacao_data_tables.sql', 'r') as f: + with open(compilacao_app + "/compilacao_data_tables.sql", "r") as f: lines = f.readlines() - lines = [line.rstrip('\n') for line in lines] + lines = [line.rstrip("\n") for line in lines] with connection.cursor() as cursor: for line in lines: line = line.strip() - if not line or line.startswith('#'): + if not line or line.startswith("#"): continue try: cursor.execute(line) except IntegrityError as e: if not settings.DEBUG: - print("{} {} {}".format(_('Ocorreu erro na importação:'), line, str(e))) + print( + "{} {} {}".format( + _("Ocorreu erro na importação:"), line, str(e) + ) + ) except Exception as ee: print(ee) @@ -46,12 +48,12 @@ class AppConfig(apps.AppConfig): verbose_name = verbose_name.upper().split() if len(verbose_name) == 1: verbose_name = verbose_name[0] - sigla = '' + sigla = "" for letra in verbose_name: - if letra in 'BCDFGHJKLMNPQRSTVWXYZ': + if letra in "BCDFGHJKLMNPQRSTVWXYZ": sigla += letra else: - sigla = ''.join([palavra[0] for palavra in verbose_name]) + sigla = "".join([palavra[0] for palavra in verbose_name]) return sigla[:3] for view in integrations_view_names: @@ -60,28 +62,31 @@ class AppConfig(apps.AppConfig): tipo.sigla = cria_sigla( view.model._meta.verbose_name if view.model._meta.verbose_name - else view.model._meta.model_name) + else view.model._meta.model_name + ) tipo.descricao = view.model._meta.verbose_name tipo.content_type = ContentType.objects.get_by_natural_key( - view.model._meta.app_label, view.model._meta.model_name) + view.model._meta.app_label, view.model._meta.model_name + ) tipo.save() except IntegrityError as e: if not settings.DEBUG: - print("{} {}".format(_('Ocorreu erro na criação tipo de ta:'), str(e))) - + print( + "{} {}".format(_("Ocorreu erro na criação tipo de ta:"), str(e)) + ) -def init_compilacao_base(app_config, verbosity=2, interactive=True, - using=DEFAULT_DB_ALIAS, **kwargs): +def init_compilacao_base( + app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, **kwargs +): if app_config != AppConfig and not isinstance(app_config, AppConfig): return from sapl.compilacao.models import TipoDispositivo - if not TipoDispositivo.objects.exists(): - print('') - print("\033[93m\033[1m{}\033[0m".format(_('Iniciando Textos Articulados...'))) + if not TipoDispositivo.objects.exists(): + print("") + print("\033[93m\033[1m{}\033[0m".format(_("Iniciando Textos Articulados..."))) AppConfig.import_pattern() -models.signals.post_migrate.connect( - receiver=init_compilacao_base) +models.signals.post_migrate.connect(receiver=init_compilacao_base) diff --git a/sapl/compilacao/forms.py b/sapl/compilacao/forms.py index 390107fb5..99fdbf4b5 100644 --- a/sapl/compilacao/forms.py +++ b/sapl/compilacao/forms.py @@ -24,8 +24,8 @@ from sapl.compilacao.models import (NOTAS_PUBLICIDADE_CHOICES, TipoTextoArticulado, TipoVide, VeiculoPublicacao, Vide) from sapl.compilacao.utils import DISPOSITIVO_SELECT_RELATED -from sapl.crispy_layout_mixin import SaplFormHelper -from sapl.crispy_layout_mixin import SaplFormLayout, to_column, to_row +from sapl.crispy_layout_mixin import (SaplFormHelper, SaplFormLayout, + to_column, to_row) from sapl.utils import YES_NO_CHOICES, FileFieldCheckMixin @@ -35,90 +35,96 @@ class CustomImageCropWidget(ImageCropWidget): We use this trick, and place it right under the CropWidget so that it looks like the user is seeing the image and clearing the image. """ + template_with_initial = ( # '%(initial_text)s: %(initial)s ' - '%(clear_template)s
    %(input_text)s: %(input)s' + "%(clear_template)s
    %(input_text)s: %(input)s" ) error_messages = { - 'required': _('Este campo é obrigatório'), - 'invalid': _('URL inválida.') + "required": _("Este campo é obrigatório"), + "invalid": _("URL inválida."), } ta_error_messages = { - 'required': _('Este campo é obrigatório'), + "required": _("Este campo é obrigatório"), } class TipoTaForm(ModelForm): sigla = forms.CharField( - label=TipoTextoArticulado._meta.get_field( - 'sigla').verbose_name) + label=TipoTextoArticulado._meta.get_field("sigla").verbose_name + ) descricao = forms.CharField( - label=TipoTextoArticulado._meta.get_field( - 'descricao').verbose_name) + label=TipoTextoArticulado._meta.get_field("descricao").verbose_name + ) participacao_social = forms.ChoiceField( - label=TipoTextoArticulado._meta.get_field( - 'participacao_social').verbose_name, + label=TipoTextoArticulado._meta.get_field("participacao_social").verbose_name, choices=YES_NO_CHOICES, widget=forms.RadioSelect(), - required=True) + required=True, + ) publicacao_func = forms.ChoiceField( - label=TipoTextoArticulado._meta.get_field( - 'publicacao_func').verbose_name, + label=TipoTextoArticulado._meta.get_field("publicacao_func").verbose_name, choices=YES_NO_CHOICES, widget=forms.RadioSelect(), - required=True) + required=True, + ) rodape_global = forms.CharField( - label=TipoTextoArticulado._meta.get_field( - 'rodape_global').verbose_name, - widget=forms.Textarea(attrs={'id': 'texto-rico'}), - required=False + label=TipoTextoArticulado._meta.get_field("rodape_global").verbose_name, + widget=forms.Textarea(attrs={"id": "texto-rico"}), + required=False, ) class Meta: model = TipoTextoArticulado - fields = ['sigla', - 'descricao', - 'content_type', - 'participacao_social', - 'publicacao_func', - 'perfis', - 'rodape_global' - ] - - widgets = {'perfis': widgets.CheckboxSelectMultiple(), - 'rodape_global': forms.Textarea} + fields = [ + "sigla", + "descricao", + "content_type", + "participacao_social", + "publicacao_func", + "perfis", + "rodape_global", + ] + + widgets = { + "perfis": widgets.CheckboxSelectMultiple(), + "rodape_global": forms.Textarea, + } def __init__(self, *args, **kwargs): + row1 = to_row( + [ + ("sigla", 3), + ("descricao", 5), + ("content_type", 4), + ] + ) + row2 = to_row( + [ + (InlineRadios("participacao_social"), 3), + (InlineRadios("publicacao_func"), 3), + ("perfis", 12), + ] + ) - row1 = to_row([ - ('sigla', 3), - ('descricao', 5), - ('content_type', 4), - ]) - row2 = to_row([ - (InlineRadios('participacao_social'), 3), - (InlineRadios('publicacao_func'), 3), - ('perfis', 12), - ]) - - row3 = to_row([ - ('rodape_global', 12), - ]) + row3 = to_row( + [ + ("rodape_global", 12), + ] + ) self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout( - Fieldset(_('Identificação Básica'), - row1, css_class="col-md-12"), - Fieldset(_('Funcionalidades'), - row2, css_class="col-md-12"), - Fieldset(_('Nota de Rodapé Global'), - row3, css_class="col-md-12")) + Fieldset(_("Identificação Básica"), row1, css_class="col-md-12"), + Fieldset(_("Funcionalidades"), row2, css_class="col-md-12"), + Fieldset(_("Nota de Rodapé Global"), row3, css_class="col-md-12"), + ) super(TipoTaForm, self).__init__(*args, **kwargs) @@ -127,194 +133,206 @@ class TaForm(ModelForm): label=TipoTextoArticulado._meta.verbose_name, queryset=TipoTextoArticulado.objects.all(), required=True, - empty_label=None) + empty_label=None, + ) numero = forms.CharField( - label=TextoArticulado._meta.get_field( - 'numero').verbose_name, - required=True) + label=TextoArticulado._meta.get_field("numero").verbose_name, required=True + ) ano = forms.IntegerField( - label=TextoArticulado._meta.get_field( - 'ano').verbose_name, - required=True) + label=TextoArticulado._meta.get_field("ano").verbose_name, required=True + ) data = forms.DateField( - label=TextoArticulado._meta.get_field( - 'data').verbose_name, - input_formats=['%d/%m/%Y'], + label=TextoArticulado._meta.get_field("data").verbose_name, + input_formats=["%d/%m/%Y"], required=True, - widget=forms.DateInput( - format='%d/%m/%Y'), - error_messages=ta_error_messages + widget=forms.DateInput(format="%d/%m/%Y"), + error_messages=ta_error_messages, ) ementa = forms.CharField( - label='', - widget=forms.Textarea, - error_messages=ta_error_messages) + label="", widget=forms.Textarea, error_messages=ta_error_messages + ) observacao = forms.CharField( - label='', + label="", widget=forms.Textarea, error_messages=ta_error_messages, - required=False) + required=False, + ) participacao_social = forms.NullBooleanField( - label=TextoArticulado._meta.get_field( - 'participacao_social').verbose_name, + label=TextoArticulado._meta.get_field("participacao_social").verbose_name, widget=forms.Select(choices=PARTICIPACAO_SOCIAL_CHOICES), - required=False) + required=False, + ) class Meta: model = TextoArticulado - fields = ['tipo_ta', - 'numero', - 'ano', - 'data', - 'ementa', - 'observacao', - 'participacao_social', - ] + fields = [ + "tipo_ta", + "numero", + "ano", + "data", + "ementa", + "observacao", + "participacao_social", + ] def __init__(self, *args, **kwargs): - - row1 = to_row([ - ('tipo_ta', 3), - ('numero', 2), - ('ano', 2), - ('data', 2), - ('participacao_social', 3), - ]) + row1 = to_row( + [ + ("tipo_ta", 3), + ("numero", 2), + ("ano", 2), + ("data", 2), + ("participacao_social", 3), + ] + ) self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout( - Fieldset(_('Identificação Básica'), row1, css_class="col-md-12"), + Fieldset(_("Identificação Básica"), row1, css_class="col-md-12"), Fieldset( - TextoArticulado._meta.get_field('ementa').verbose_name, - Column('ementa'), css_class="col-md-12"), + TextoArticulado._meta.get_field("ementa").verbose_name, + Column("ementa"), + css_class="col-md-12", + ), Fieldset( - TextoArticulado._meta.get_field('observacao').verbose_name, - Column('observacao'), css_class="col-md-12"), - + TextoArticulado._meta.get_field("observacao").verbose_name, + Column("observacao"), + css_class="col-md-12", + ), ) super(TaForm, self).__init__(*args, **kwargs) - instance = getattr(self, 'instance', None) + instance = getattr(self, "instance", None) if instance and instance.pk: - self.fields['tipo_ta'].widget.attrs['disabled'] = True - self.fields['tipo_ta'].required = False + self.fields["tipo_ta"].widget.attrs["disabled"] = True + self.fields["tipo_ta"].required = False def clean_tipo_ta(self): - instance = getattr(self, 'instance', None) + instance = getattr(self, "instance", None) if instance and instance.pk: return instance.tipo_ta else: - return self.cleaned_data['tipo_ta'] + return self.cleaned_data["tipo_ta"] class NotaForm(ModelForm): - titulo = forms.CharField( - label=Nota._meta.get_field('titulo').verbose_name, required=False) + label=Nota._meta.get_field("titulo").verbose_name, required=False + ) texto = forms.CharField( - label=Nota._meta.get_field('texto').verbose_name, + label=Nota._meta.get_field("texto").verbose_name, widget=forms.Textarea, - error_messages=error_messages) + error_messages=error_messages, + ) url_externa = forms.URLField( - label=Nota._meta.get_field('url_externa').verbose_name, + label=Nota._meta.get_field("url_externa").verbose_name, required=False, - error_messages=error_messages) + error_messages=error_messages, + ) publicidade = forms.ChoiceField( required=True, - label=Nota._meta.get_field('publicidade').verbose_name, + label=Nota._meta.get_field("publicidade").verbose_name, choices=NOTAS_PUBLICIDADE_CHOICES, - widget=forms.Select(attrs={'class': 'selector'})) + widget=forms.Select(attrs={"class": "selector"}), + ) tipo = forms.ModelChoiceField( - label=Nota._meta.get_field('tipo').verbose_name, + label=Nota._meta.get_field("tipo").verbose_name, queryset=TipoNota.objects.all(), - empty_label=None) + empty_label=None, + ) publicacao = forms.DateField( - label=Nota._meta.get_field('publicacao').verbose_name, - input_formats=['%d/%m/%Y', '%d%m%Y'], + label=Nota._meta.get_field("publicacao").verbose_name, + input_formats=["%d/%m/%Y", "%d%m%Y"], required=True, - widget=forms.DateInput( - format='%d/%m/%Y'), - error_messages=error_messages + widget=forms.DateInput(format="%d/%m/%Y"), + error_messages=error_messages, ) efetividade = forms.DateField( - label=Nota._meta.get_field('efetividade').verbose_name, - input_formats=['%d/%m/%Y', '%d%m%Y'], + label=Nota._meta.get_field("efetividade").verbose_name, + input_formats=["%d/%m/%Y", "%d%m%Y"], required=True, - widget=forms.DateInput( - format='%d/%m/%Y'), - error_messages=error_messages) - dispositivo = forms.ModelChoiceField(queryset=Dispositivo.objects.all(), - widget=forms.HiddenInput()) - pk = forms.IntegerField(widget=forms.HiddenInput(), - required=False) + widget=forms.DateInput(format="%d/%m/%Y"), + error_messages=error_messages, + ) + dispositivo = forms.ModelChoiceField( + queryset=Dispositivo.objects.all(), widget=forms.HiddenInput() + ) + pk = forms.IntegerField(widget=forms.HiddenInput(), required=False) class Meta: model = Nota - fields = ['titulo', - 'texto', - 'url_externa', - 'publicidade', - 'publicacao', - 'efetividade', - 'tipo', - 'dispositivo', - 'pk' - ] + fields = [ + "titulo", + "texto", + "url_externa", + "publicidade", + "publicacao", + "efetividade", + "tipo", + "dispositivo", + "pk", + ] def __init__(self, *args, **kwargs): - - row1 = to_row([ - ('tipo', 4), - ]) + row1 = to_row( + [ + ("tipo", 4), + ] + ) row1.append( Column( - Field( - 'titulo', - placeholder=_('Título da Nota (opcional)') - ), - css_class='col-md-8')) + Field("titulo", placeholder=_("Título da Nota (opcional)")), + css_class="col-md-8", + ) + ) - row3 = to_row([ - ('publicidade', 6), - ('publicacao', 3), - ('efetividade', 3), - ('dispositivo', 0), - ('pk', 0), - ]) + row3 = to_row( + [ + ("publicidade", 6), + ("publicacao", 3), + ("efetividade", 3), + ("dispositivo", 0), + ("pk", 0), + ] + ) buttons = FormActions( *[ - HTML('%s' % _('Cancelar')) + HTML( + '%s' % _("Cancelar") + ) ], - Button( - 'submit-form', - 'Salvar', - css_class='btn btn-primary float-right'), - css_class='form-group row justify-content-between mr-1 ml-1' + Button("submit-form", "Salvar", css_class="btn btn-primary float-right"), + css_class="form-group row justify-content-between mr-1 ml-1" ) self.helper = SaplFormHelper() self.helper.layout = Layout( - Div( - Div(HTML(_('Notas')), css_class='card-header bg-light'), + Div(HTML(_("Notas")), css_class="card-header bg-light"), Div( row1, - to_row([(Field( - 'texto', - placeholder=_('Adicionar Nota')), 12)]), - to_row([(Field( - 'url_externa', - placeholder=_('URL Externa (opcional)')), 12)]), + to_row([(Field("texto", placeholder=_("Adicionar Nota")), 12)]), + to_row( + [ + ( + Field( + "url_externa", + placeholder=_("URL Externa (opcional)"), + ), + 12, + ) + ] + ), row3, to_row([(buttons, 12)]), - css_class="card-body" + css_class="card-body", ), - css_class="card" + css_class="card", ) ) @@ -323,333 +341,353 @@ class NotaForm(ModelForm): class VideForm(ModelForm): dispositivo_base = forms.ModelChoiceField( - queryset=Dispositivo.objects.all(), - widget=forms.HiddenInput()) + queryset=Dispositivo.objects.all(), widget=forms.HiddenInput() + ) dispositivo_ref = forms.ModelChoiceField( - label=Vide._meta.get_field( - 'dispositivo_ref').verbose_name, - queryset=Dispositivo.objects.all()) + label=Vide._meta.get_field("dispositivo_ref").verbose_name, + queryset=Dispositivo.objects.all(), + ) tipo = forms.ModelChoiceField( label=TipoVide._meta.verbose_name, queryset=TipoVide.objects.all(), required=True, - error_messages=error_messages) + error_messages=error_messages, + ) texto = forms.CharField( required=False, - label=Vide._meta.get_field( - 'texto').verbose_name, - widget=forms.Textarea()) + label=Vide._meta.get_field("texto").verbose_name, + widget=forms.Textarea(), + ) pk = forms.IntegerField(widget=forms.HiddenInput(), required=False) class Meta: model = Vide - fields = ['dispositivo_base', - 'dispositivo_ref', - 'texto', - 'tipo', - 'pk'] + fields = ["dispositivo_base", "dispositivo_ref", "texto", "tipo", "pk"] error_messages = { NON_FIELD_ERRORS: { - 'unique_together': - _("Ja existe um Vide deste tipo para o Dispositivo Referido "), + "unique_together": _( + "Ja existe um Vide deste tipo para o Dispositivo Referido " + ), } } def __init__(self, *args, **kwargs): - buttons = FormActions( *[ - HTML('%s' % _('Cancelar')) + HTML( + '%s' % _("Cancelar") + ) ], - Button( - 'submit-form', - 'Salvar', - css_class='btn btn-primary float-right'), - css_class='form-group row justify-content-between mr-1 ml-1' + Button("submit-form", "Salvar", css_class="btn btn-primary float-right"), + css_class="form-group row justify-content-between mr-1 ml-1" ) dispositivo_ref = Field( - 'dispositivo_ref', - data_sapl_ta='DispositivoSearch', - data_field='dispositivo_ref', - data_type_selection='radio', - template="compilacao/layout/dispositivo_radio.html") + "dispositivo_ref", + data_sapl_ta="DispositivoSearch", + data_field="dispositivo_ref", + data_type_selection="radio", + template="compilacao/layout/dispositivo_radio.html", + ) fields_form = [] - fields_form.append(Div( - Row(to_column((Field( - 'tipo', - placeholder=_('Selecione um Tipo de Vide')), 12))), - Row(to_column((dispositivo_ref, 12))), - Row(to_column((buttons, 12))))) - - fields_form.append(Div( - Row(to_column((Field( - 'texto', - placeholder=_('Texto Adicional ao Vide')), 12))))) + fields_form.append( + Div( + Row( + to_column( + (Field("tipo", placeholder=_("Selecione um Tipo de Vide")), 12) + ) + ), + Row(to_column((dispositivo_ref, 12))), + Row(to_column((buttons, 12))), + ) + ) + + fields_form.append( + Div( + Row( + to_column( + (Field("texto", placeholder=_("Texto Adicional ao Vide")), 12) + ) + ) + ) + ) self.helper = SaplFormHelper() self.helper.layout = Layout( Div( - Div(HTML(_('Vides')), css_class='card-header bg-light'), + Div(HTML(_("Vides")), css_class="card-header bg-light"), Div( to_column((fields_form[0], 6)), to_column((fields_form[1], 6)), - to_column(('dispositivo_base', 0)), - to_column(('pk', 0)), - css_class="card-body row" + to_column(("dispositivo_base", 0)), + to_column(("pk", 0)), + css_class="card-body row", ), - css_class="card" + css_class="card", ) ) super(VideForm, self).__init__(*args, **kwargs) - self.fields['dispositivo_ref'].choices = [] + self.fields["dispositivo_ref"].choices = [] if self.instance and self.instance.dispositivo_ref_id: - self.fields['dispositivo_ref'].choices = [ - (self.instance.dispositivo_ref.pk, - self.instance.dispositivo_ref)] + self.fields["dispositivo_ref"].choices = [ + (self.instance.dispositivo_ref.pk, self.instance.dispositivo_ref) + ] class PublicacaoForm(ModelForm): - tipo_publicacao = forms.ModelChoiceField( - label=TipoPublicacao._meta.verbose_name, - queryset=TipoPublicacao.objects.all()) + label=TipoPublicacao._meta.verbose_name, queryset=TipoPublicacao.objects.all() + ) veiculo_publicacao = forms.ModelChoiceField( label=VeiculoPublicacao._meta.verbose_name, - queryset=VeiculoPublicacao.objects.all()) + queryset=VeiculoPublicacao.objects.all(), + ) url_externa = forms.CharField( - label=Publicacao._meta.get_field('url_externa').verbose_name, - required=False) + label=Publicacao._meta.get_field("url_externa").verbose_name, required=False + ) data = forms.DateField( - label=Publicacao._meta.get_field('data').verbose_name, - input_formats=['%d/%m/%Y'], + label=Publicacao._meta.get_field("data").verbose_name, + input_formats=["%d/%m/%Y"], required=True, - widget=forms.DateInput( - format='%d/%m/%Y'), - error_messages=error_messages + widget=forms.DateInput(format="%d/%m/%Y"), + error_messages=error_messages, ) hora = forms.TimeField( - label=Publicacao._meta.get_field('hora').verbose_name, + label=Publicacao._meta.get_field("hora").verbose_name, required=False, - widget=forms.TextInput( - attrs={'class': 'hora_hms'})) + widget=forms.TextInput(attrs={"class": "hora_hms"}), + ) numero = forms.IntegerField( - label=Publicacao._meta.get_field( - 'numero').verbose_name, - required=False) - ano = forms.IntegerField( - label=Publicacao._meta.get_field( - 'ano').verbose_name) + label=Publicacao._meta.get_field("numero").verbose_name, required=False + ) + ano = forms.IntegerField(label=Publicacao._meta.get_field("ano").verbose_name) edicao = forms.IntegerField( - label=Publicacao._meta.get_field( - 'edicao').verbose_name, - required=False) + label=Publicacao._meta.get_field("edicao").verbose_name, required=False + ) pagina_inicio = forms.IntegerField( - label=Publicacao._meta.get_field( - 'pagina_inicio').verbose_name, - required=False) + label=Publicacao._meta.get_field("pagina_inicio").verbose_name, required=False + ) pagina_fim = forms.IntegerField( - label=Publicacao._meta.get_field( - 'pagina_fim').verbose_name, - required=False) - ta = forms.ModelChoiceField(queryset=TextoArticulado.objects.all(), - widget=forms.HiddenInput()) + label=Publicacao._meta.get_field("pagina_fim").verbose_name, required=False + ) + ta = forms.ModelChoiceField( + queryset=TextoArticulado.objects.all(), widget=forms.HiddenInput() + ) class Meta: model = Publicacao - fields = ['tipo_publicacao', - 'veiculo_publicacao', - 'url_externa', - 'data', - 'hora', - 'numero', - 'ano', - 'edicao', - 'pagina_inicio', - 'pagina_fim', - 'ta'] + fields = [ + "tipo_publicacao", + "veiculo_publicacao", + "url_externa", + "data", + "hora", + "numero", + "ano", + "edicao", + "pagina_inicio", + "pagina_fim", + "ta", + ] def __init__(self, *args, **kwargs): + row1 = to_row( + [ + ("tipo_publicacao", 4), + ("veiculo_publicacao", 6), + ("ano", 2), + ] + ) - row1 = to_row([ - ('tipo_publicacao', 4), - ('veiculo_publicacao', 6), - ('ano', 2), - ]) - - row2 = to_row([ - ('data', 4), - ('hora', 4), - ('numero', 2), - ('edicao', 2), - ]) - - row3 = to_row([ - ('pagina_inicio', 2), - ('pagina_fim', 2), - ('url_externa', 8), - ]) + row2 = to_row( + [ + ("data", 4), + ("hora", 4), + ("numero", 2), + ("edicao", 2), + ] + ) + + row3 = to_row( + [ + ("pagina_inicio", 2), + ("pagina_fim", 2), + ("url_externa", 8), + ] + ) self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout( - Fieldset(Publicacao._meta.verbose_name, - row1, row2, row3, css_class="col-md-12")) + Fieldset( + Publicacao._meta.verbose_name, row1, row2, row3, css_class="col-md-12" + ) + ) super(PublicacaoForm, self).__init__(*args, **kwargs) pass class DispositivoIntegerField(forms.IntegerField): - def __init__(self, field_name=None, *args, **kwargs): - - if 'required' not in kwargs: - kwargs.setdefault('required', False) + if "required" not in kwargs: + kwargs.setdefault("required", False) self.widget = forms.NumberInput( - attrs={'title': Dispositivo._meta.get_field( - field_name).verbose_name, - 'onchange': 'atualizaRotulo()'}) + attrs={ + "title": Dispositivo._meta.get_field(field_name).verbose_name, + "onchange": "atualizaRotulo()", + } + ) - super(DispositivoIntegerField, self).__init__( - min_value=0, *args, **kwargs) + super(DispositivoIntegerField, self).__init__(min_value=0, *args, **kwargs) class DispositivoEdicaoBasicaForm(FileFieldCheckMixin, ModelForm): - class Meta: model = Dispositivo - fields = ['imagem', 'imagem_cropping'] + fields = ["imagem", "imagem_cropping"] widgets = { - 'imagem': CustomImageCropWidget(), - 'imagem_cropping': CropWidget(), + "imagem": CustomImageCropWidget(), + "imagem_cropping": CropWidget(), } error_messages = { NON_FIELD_ERRORS: { - 'unique_together': - _("Já existe um Dispositivo com características idênticas."), + "unique_together": _( + "Já existe um Dispositivo com características idênticas." + ), } } def __init__(self, *args, **kwargs): - layout = [] - inst = kwargs['instance'] if 'instance' in kwargs else None - texto_articulado_do_editor = kwargs['initial'][ - 'texto_articulado_do_editor'] if\ - 'texto_articulado_do_editor' in kwargs['initial'] else None + inst = kwargs["instance"] if "instance" in kwargs else None + texto_articulado_do_editor = ( + kwargs["initial"]["texto_articulado_do_editor"] + if "texto_articulado_do_editor" in kwargs["initial"] + else None + ) - editor_type = kwargs['initial']['editor_type']\ - if'editor_type' in kwargs['initial'] else '' + editor_type = ( + kwargs["initial"]["editor_type"] + if "editor_type" in kwargs["initial"] + else "" + ) if inst and inst.tipo_dispositivo.formato_variacao0 in [ - TipoDispositivo.FNC8, TipoDispositivo.FNCN]: + TipoDispositivo.FNC8, + TipoDispositivo.FNCN, + ]: # remove edição do rótulo se o tipo de disp. for não numerável - if 'rotulo' in DispositivoEdicaoBasicaForm.Meta.fields: - DispositivoEdicaoBasicaForm.Meta.fields.remove('rotulo') + if "rotulo" in DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.remove("rotulo") for i in range(6): - DispositivoEdicaoBasicaForm.Meta.fields.remove( - 'dispositivo%s' % i) - elif editor_type == 'get_form_base': + DispositivoEdicaoBasicaForm.Meta.fields.remove("dispositivo%s" % i) + elif editor_type == "get_form_base": # remove edição do rótulo se a req do form vier do editor dinamico - if 'rotulo' in DispositivoEdicaoBasicaForm.Meta.fields: - DispositivoEdicaoBasicaForm.Meta.fields.remove('rotulo') + if "rotulo" in DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.remove("rotulo") for i in range(6): - DispositivoEdicaoBasicaForm.Meta.fields.remove( - 'dispositivo%s' % i) + DispositivoEdicaoBasicaForm.Meta.fields.remove("dispositivo%s" % i) else: # adiciona campos de rótulo no formulário - if 'rotulo' not in DispositivoEdicaoBasicaForm.Meta.fields: - DispositivoEdicaoBasicaForm.Meta.fields.append('rotulo') + if "rotulo" not in DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.append("rotulo") for i in range(6): - DispositivoEdicaoBasicaForm.Meta.fields.append( - 'dispositivo%s' % i) + DispositivoEdicaoBasicaForm.Meta.fields.append("dispositivo%s" % i) self.dispositivo0 = forms.IntegerField( min_value=0, - label=Dispositivo._meta.get_field('dispositivo0').verbose_name, + label=Dispositivo._meta.get_field("dispositivo0").verbose_name, widget=forms.NumberInput( - attrs={'title': _('Valor 0(zero) é permitido apenas para ' - 'Dispositivos com tipos variáveis.'), - 'onchange': 'atualizaRotulo()'})) + attrs={ + "title": _( + "Valor 0(zero) é permitido apenas para " + "Dispositivos com tipos variáveis." + ), + "onchange": "atualizaRotulo()", + } + ), + ) self.dispositivo1 = DispositivoIntegerField( - label=('1ª %s' % _('Variação')), - field_name='dispositivo1') + label=("1ª %s" % _("Variação")), field_name="dispositivo1" + ) self.dispositivo2 = DispositivoIntegerField( - label=('2ª'), - field_name='dispositivo2') + label=("2ª"), field_name="dispositivo2" + ) self.dispositivo3 = DispositivoIntegerField( - label=('3ª'), - field_name='dispositivo3') + label=("3ª"), field_name="dispositivo3" + ) self.dispositivo4 = DispositivoIntegerField( - label=('4ª'), - field_name='dispositivo4') + label=("4ª"), field_name="dispositivo4" + ) self.dispositivo5 = DispositivoIntegerField( - label=('5ª'), - field_name='dispositivo5') - - self.rotulo = forms.CharField( - required=False, label=_('Rótulo Resultante')) + label=("5ª"), field_name="dispositivo5" + ) - rotulo_fieldset = to_row([ - ('dispositivo0', 3), - ('dispositivo1', 2), - ('dispositivo2', 1), - ('dispositivo3', 1), - ('dispositivo4', 1), - ('dispositivo5', 1), - ('rotulo', 3)]) + self.rotulo = forms.CharField(required=False, label=_("Rótulo Resultante")) + + rotulo_fieldset = to_row( + [ + ("dispositivo0", 3), + ("dispositivo1", 2), + ("dispositivo2", 1), + ("dispositivo3", 1), + ("dispositivo4", 1), + ("dispositivo5", 1), + ("rotulo", 3), + ] + ) - layout.append(Fieldset(_('Construção do Rótulo'), rotulo_fieldset, - css_class="col-md-12")) + layout.append( + Fieldset( + _("Construção do Rótulo"), rotulo_fieldset, css_class="col-md-12" + ) + ) if inst and inst.tipo_dispositivo.dispositivo_de_articulacao: - if 'texto' in DispositivoEdicaoBasicaForm.Meta.fields: - DispositivoEdicaoBasicaForm.Meta.fields.remove('texto') + if "texto" in DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.remove("texto") else: - if 'texto' not in DispositivoEdicaoBasicaForm.Meta.fields: - DispositivoEdicaoBasicaForm.Meta.fields.append('texto') + if "texto" not in DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.append("texto") - self.texto = forms.CharField(required=False, - label='', - widget=forms.Textarea()) - row_texto = to_row([('texto', 12)]) + self.texto = forms.CharField( + required=False, label="", widget=forms.Textarea() + ) + row_texto = to_row([("texto", 12)]) layout.append( - Fieldset(Dispositivo._meta.get_field('texto').verbose_name, - row_texto, - css_class="col-md-12")) + Fieldset( + Dispositivo._meta.get_field("texto").verbose_name, + row_texto, + css_class="col-md-12", + ) + ) - if editor_type == 'get_form_base' and inst.dispositivo_atualizador_id: + if editor_type == "get_form_base" and inst.dispositivo_atualizador_id: if inst and inst.tipo_dispositivo.dispositivo_de_articulacao: - if 'texto_atualizador' in\ - DispositivoEdicaoBasicaForm.Meta.fields: - DispositivoEdicaoBasicaForm.Meta.fields.remove( - 'texto_atualizador') - DispositivoEdicaoBasicaForm.Meta.fields.remove( - 'visibilidade') + if "texto_atualizador" in DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.remove("texto_atualizador") + DispositivoEdicaoBasicaForm.Meta.fields.remove("visibilidade") else: - if 'texto_atualizador' not in\ - DispositivoEdicaoBasicaForm.Meta.fields: - DispositivoEdicaoBasicaForm.Meta.fields.append( - 'texto_atualizador') - DispositivoEdicaoBasicaForm.Meta.fields.append( - 'visibilidade') + if "texto_atualizador" not in DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.append("texto_atualizador") + DispositivoEdicaoBasicaForm.Meta.fields.append("visibilidade") self.texto_atualizador = forms.CharField( required=False, - label='', + label="", widget=forms.Textarea(), help_text=_( """%s é um campo para ser informado apenas @@ -661,341 +699,409 @@ class DispositivoEdicaoBasicaForm(FileFieldCheckMixin, ModelForm): uma expressão terminou com um (.) ponto final mas faz mais sentido que no documento anterior seja colocado com (;) um ponto e virgula. - """ % ( + """ + % ( Dispositivo._meta.get_field( - 'texto_atualizador').verbose_name, + "texto_atualizador" + ).verbose_name, inst.ta_publicado, - inst.ta - ))) + inst.ta, + ) + ), + ) self.visibilidade = forms.ChoiceField( - label=Dispositivo._meta.get_field( - 'visibilidade').verbose_name, + label=Dispositivo._meta.get_field("visibilidade").verbose_name, choices=utils.YES_NO_CHOICES, - widget=forms.RadioSelect()) + widget=forms.RadioSelect(), + ) layout.append( - Fieldset(Dispositivo._meta.get_field( - 'texto_atualizador').verbose_name, - to_row([(InlineRadios('visibilidade'), 12)]), - to_row([('texto_atualizador', 12)]), - css_class="col-md-12")) + Fieldset( + Dispositivo._meta.get_field("texto_atualizador").verbose_name, + to_row([(InlineRadios("visibilidade"), 12)]), + to_row([("texto_atualizador", 12)]), + css_class="col-md-12", + ) + ) else: - if 'texto_atualizador' in\ - DispositivoEdicaoBasicaForm.Meta.fields: - DispositivoEdicaoBasicaForm.Meta.fields.remove( - 'texto_atualizador') - DispositivoEdicaoBasicaForm.Meta.fields.remove( - 'visibilidade') - - if 'texto' in DispositivoEdicaoBasicaForm.Meta.fields and\ - not editor_type: + if "texto_atualizador" in DispositivoEdicaoBasicaForm.Meta.fields: + DispositivoEdicaoBasicaForm.Meta.fields.remove("texto_atualizador") + DispositivoEdicaoBasicaForm.Meta.fields.remove("visibilidade") + + if "texto" in DispositivoEdicaoBasicaForm.Meta.fields and not editor_type: layout.append( - Fieldset('Anexar Imagem', - to_row([('imagem', 7), ('imagem_cropping', 5), ]), - css_class="col-md-12")) - DispositivoEdicaoBasicaForm.Meta.fields.append('imagem') - DispositivoEdicaoBasicaForm.Meta.fields.append('imagem_cropping') + Fieldset( + "Anexar Imagem", + to_row( + [ + ("imagem", 7), + ("imagem_cropping", 5), + ] + ), + css_class="col-md-12", + ) + ) + DispositivoEdicaoBasicaForm.Meta.fields.append("imagem") + DispositivoEdicaoBasicaForm.Meta.fields.append("imagem_cropping") for f in DispositivoEdicaoBasicaForm.Meta.fields: if hasattr(self, f): self.base_fields.update({f: getattr(self, f)}) - for f in set(self.base_fields.keys()) - set(DispositivoEdicaoBasicaForm.Meta.fields): + for f in set(self.base_fields.keys()) - set( + DispositivoEdicaoBasicaForm.Meta.fields + ): self.base_fields.pop(f) self.helper = SaplFormHelper() self.helper.include_media = False if not editor_type: - cancel_label = _('Ir para o Editor Sequencial') - self.helper.layout = SaplFormLayout( - *layout, cancel_label=cancel_label) + cancel_label = _("Ir para o Editor Sequencial") + self.helper.layout = SaplFormLayout(*layout, cancel_label=cancel_label) elif editor_type == "get_form_base": getattr(self, "actions_" + editor_type)( - layout, inst, texto_articulado_do_editor) + layout, inst, texto_articulado_do_editor + ) super(DispositivoEdicaoBasicaForm, self).__init__(*args, **kwargs) - #imagem = self.fields['imagem'].widget + # imagem = self.fields['imagem'].widget # imagem.attrs.update( # get_attrs(self.instance.imagem, 'imagem') - #) + # ) # if 'class' in imagem.attrs: # imagem.attrs.pop('class') - def actions_get_form_base(self, layout, - inst, - texto_articulado_do_editor=None): - cancel_label = _('Fechar') + def actions_get_form_base(self, layout, inst, texto_articulado_do_editor=None): + cancel_label = _("Fechar") more = [ - HTML('%s' % - cancel_label), + HTML('%s' % cancel_label), ] btns_excluir = [] - if not (inst.tipo_dispositivo.dispositivo_de_alteracao and - inst.tipo_dispositivo.dispositivo_de_articulacao): + if not ( + inst.tipo_dispositivo.dispositivo_de_alteracao + and inst.tipo_dispositivo.dispositivo_de_articulacao + ): btns_excluir = [ - HTML('%s' % (_('Excluir apenas este dispositivo.'), - inst.pk, - _('Excluir Dispositivo')))] - - if (inst.dispositivos_filhos_set.filter( - auto_inserido=False).exists() or ( - inst.tipo_dispositivo.dispositivo_de_alteracao and - inst.tipo_dispositivo.dispositivo_de_articulacao)) and ( - inst.ta_id == int(texto_articulado_do_editor) - if texto_articulado_do_editor else 0): + HTML( + '%s" + % ( + _("Excluir apenas este dispositivo."), + inst.pk, + _("Excluir Dispositivo"), + ) + ) + ] + + if ( + inst.dispositivos_filhos_set.filter(auto_inserido=False).exists() + or ( + inst.tipo_dispositivo.dispositivo_de_alteracao + and inst.tipo_dispositivo.dispositivo_de_articulacao + ) + ) and ( + inst.ta_id == int(texto_articulado_do_editor) + if texto_articulado_do_editor + else 0 + ): btns_excluir.append( HTML( '%s' % (_('Excluir este dispositivo ' - 'e toda sua estrutura.'), - inst.pk, - _('Excluir Bloco Completo.')))) + ">%s" + % ( + _("Excluir este dispositivo " "e toda sua estrutura."), + inst.pk, + _("Excluir Bloco Completo."), + ) + ) + ) if btns_excluir and (not inst.auto_inserido or inst.ta_publicado): - css_class = 'btn-group float-right btns-excluir' + css_class = "btn-group float-right btns-excluir" more.append(Div(*btns_excluir, css_class=css_class)) if not inst.tipo_dispositivo.dispositivo_de_articulacao: - more.append(Submit('salvar', _('Salvar'), css_class='float-right')) + more.append(Submit("salvar", _("Salvar"), css_class="float-right")) - buttons = FormActions(*more, css_class='form-group') + buttons = FormActions(*more, css_class="form-group") - _fields = [Div(*layout, css_class="row")] + \ - [to_row([(buttons, 12)])] + _fields = [Div(*layout, css_class="row")] + [to_row([(buttons, 12)])] self.helper.layout = Layout(*_fields) class DispositivoSearchModalForm(Form): - TIPO_RESULTADO_CHOICES = Choices( - ('C', 'coincidentes', _('Apenas Coincidentes')), - ('I', 'internos', _('Incluir Internos')), - ('S', 'coin_sequentes', _('Coincidentes e seus sequentes')), + ("C", "coincidentes", _("Apenas Coincidentes")), + ("I", "internos", _("Incluir Internos")), + ("S", "coin_sequentes", _("Coincidentes e seus sequentes")), ) tipo_ta = forms.ModelChoiceField( - label=_('Tipo do Texto Articulado'), + label=_("Tipo do Texto Articulado"), queryset=TipoTextoArticulado.objects.all(), - required=False) + required=False, + ) - tipo_model = forms.ChoiceField( - choices=[], - label=_('Tipos de...'), required=False) + tipo_model = forms.ChoiceField(choices=[], label=_("Tipos de..."), required=False) - num_ta = forms.IntegerField( - label=_('Número do Documento'), required=False) - ano_ta = forms.IntegerField( - label=_('Ano do Documento'), required=False) + num_ta = forms.IntegerField(label=_("Número do Documento"), required=False) + ano_ta = forms.IntegerField(label=_("Ano do Documento"), required=False) tipo_resultado = forms.ChoiceField( - label=_('Tipo do Resultado?'), + label=_("Tipo do Resultado?"), choices=TIPO_RESULTADO_CHOICES, widget=forms.RadioSelect(), - required=False) + required=False, + ) max_results = forms.ChoiceField( - label=_('Limite de Listagem'), - choices=[(10, _('Dez Dispositivos')), - (30, _('Trinta Dispositivos')), - (50, _('Cinquenta Dispositivos')), - (100, _('Cem Dispositivos'))], + label=_("Limite de Listagem"), + choices=[ + (10, _("Dez Dispositivos")), + (30, _("Trinta Dispositivos")), + (50, _("Cinquenta Dispositivos")), + (100, _("Cem Dispositivos")), + ], widget=forms.Select(), - required=False) + required=False, + ) - rotulo_dispositivo = forms.CharField( - label=_('Rótulo'), - required=False) + rotulo_dispositivo = forms.CharField(label=_("Rótulo"), required=False) - texto_dispositivo = forms.CharField( - label=_('Pesquisa Textual'), - required=False) + texto_dispositivo = forms.CharField(label=_("Pesquisa Textual"), required=False) def __init__(self, *args, **kwargs): - fields_search = Fieldset( - _('Busca por um Dispositivo'), + _("Busca por um Dispositivo"), Row( - to_column(('num_ta', 4)), - to_column(('ano_ta', 4)), - to_column(('max_results', 4))), - + to_column(("num_ta", 4)), + to_column(("ano_ta", 4)), + to_column(("max_results", 4)), + ), Row( - to_column(('tipo_resultado', 3)), + to_column(("tipo_resultado", 3)), to_column( ( Div( Row( - to_column(('tipo_ta', 6)), - to_column(('tipo_model', 6))), + to_column(("tipo_ta", 6)), to_column(("tipo_model", 6)) + ), Row( - to_column(('rotulo_dispositivo', 4)), + to_column(("rotulo_dispositivo", 4)), to_column( ( FieldWithButtons( Field( - 'texto_dispositivo', - placeholder=_('Digite palavras, letras, ' - 'números ou algo' - ' que estejam no texto.')), + "texto_dispositivo", + placeholder=_( + "Digite palavras, letras, " + "números ou algo" + " que estejam no texto." + ), + ), StrictButton( - _('Buscar'), - css_class='btn-busca btn-primary')), 8)) - ) - ), 9 + _("Buscar"), + css_class="btn-busca btn-primary", + ), + ), + 8, + ) + ), + ), + ), + 9, ) - ) - )) + ), + ), + ) self.helper = SaplFormHelper() self.helper.layout = Layout( fields_search, - Row(to_column((Div(css_class='result-busca-dispositivo'), 12)))) - - if 'choice_model_type_foreignkey_in_extenal_views' in kwargs: - ch = kwargs.pop('choice_model_type_foreignkey_in_extenal_views') - if 'data' in kwargs: - choice = ch(kwargs['data']['tipo_ta']) - self.base_fields['tipo_model'].choices = choice - elif 'instance' in kwargs and\ - isinstance(kwargs['instance'], Dispositivo): - choice = ch(kwargs['instance'].ta.tipo_ta_id) - self.base_fields['tipo_model'].choices = choice - - kwargs['initial'].update({'tipo_resultado': 'C'}) + Row(to_column((Div(css_class="result-busca-dispositivo"), 12))), + ) + + if "choice_model_type_foreignkey_in_extenal_views" in kwargs: + ch = kwargs.pop("choice_model_type_foreignkey_in_extenal_views") + if "data" in kwargs: + choice = ch(kwargs["data"]["tipo_ta"]) + self.base_fields["tipo_model"].choices = choice + elif "instance" in kwargs and isinstance(kwargs["instance"], Dispositivo): + choice = ch(kwargs["instance"].ta.tipo_ta_id) + self.base_fields["tipo_model"].choices = choice + + kwargs["initial"].update({"tipo_resultado": "C"}) super(DispositivoSearchModalForm, self).__init__(*args, **kwargs) class DispositivoEdicaoVigenciaForm(ModelForm): inconstitucionalidade = forms.ChoiceField( - label=Dispositivo._meta.get_field( - 'inconstitucionalidade').verbose_name, + label=Dispositivo._meta.get_field("inconstitucionalidade").verbose_name, choices=utils.YES_NO_CHOICES, - widget=forms.RadioSelect()) + widget=forms.RadioSelect(), + ) dispositivo_vigencia = forms.ModelChoiceField( - label=Dispositivo._meta.get_field( - 'dispositivo_vigencia').verbose_name, + label=Dispositivo._meta.get_field("dispositivo_vigencia").verbose_name, required=False, - queryset=Dispositivo.objects.all()) + queryset=Dispositivo.objects.all(), + ) extensao = forms.ChoiceField( - label=_('Extender a seleção abaixo como Dispositivo de Vigência ' - 'para todos dependentes originais ' - 'deste Dispositivo em edição?'), + label=_( + "Extender a seleção abaixo como Dispositivo de Vigência " + "para todos dependentes originais " + "deste Dispositivo em edição?" + ), choices=utils.YES_NO_CHOICES, widget=forms.RadioSelect(), - required=False) + required=False, + ) class Meta: model = Dispositivo - fields = ['inicio_vigencia', - 'fim_vigencia', - 'inicio_eficacia', - 'fim_eficacia', - 'publicacao', - 'inconstitucionalidade', - 'dispositivo_vigencia' - ] + fields = [ + "inicio_vigencia", + "fim_vigencia", + "inicio_eficacia", + "fim_eficacia", + "publicacao", + "inconstitucionalidade", + "dispositivo_vigencia", + ] error_messages = { NON_FIELD_ERRORS: { - 'unique_together': - _("Já existe um Dispositivo com características idênticas."), + "unique_together": _( + "Já existe um Dispositivo com características idênticas." + ), } } def __init__(self, *args, **kwargs): - layout = [] - row_publicacao = to_row([ - ('publicacao', 6), - (InlineRadios('inconstitucionalidade'), 3), ]) + row_publicacao = to_row( + [ + ("publicacao", 6), + (InlineRadios("inconstitucionalidade"), 3), + ] + ) row_publicacao.fields.append( Alert( - css_class='alert-info col-md-3', - content='%s %s' % ( - _('Dica!'), _('Inclua uma Nota de Dispositivo informando ' - 'sobre a Inconstitucionalidade.')))) + css_class="alert-info col-md-3", + content="%s %s" + % ( + _("Dica!"), + _( + "Inclua uma Nota de Dispositivo informando " + "sobre a Inconstitucionalidade." + ), + ), + ) + ) layout.append( - Fieldset(_('Registro de Publicação e Validade'), - row_publicacao, - css_class="col-md-12")) + Fieldset( + _("Registro de Publicação e Validade"), + row_publicacao, + css_class="col-md-12", + ) + ) - row_datas = to_row([ - ('inicio_vigencia', 3), - ('fim_vigencia', 3), - ('inicio_eficacia', 3), - ('fim_eficacia', 3), ]) + row_datas = to_row( + [ + ("inicio_vigencia", 3), + ("fim_vigencia", 3), + ("inicio_eficacia", 3), + ("fim_eficacia", 3), + ] + ) - inst = kwargs['instance'] + inst = kwargs["instance"] while inst.auto_inserido and inst.dispositivo_pai: inst = inst.dispositivo_pai - if (inst.dispositivos_vigencias_set.exists()): + if inst.dispositivos_vigencias_set.exists(): row_datas.fields.append( Alert( - css_class='alert-info col-md-12', - content='%s %s' % ( - _('Atenção!'), - _('O Dispositivo em edição define vigência de outros ' - 'dispositivos. Alterar as datas de vigência ' - 'alterará as datas de vigência dos dispositivos ' - 'vigêntes por este em edição.')))) + css_class="alert-info col-md-12", + content="%s %s" + % ( + _("Atenção!"), + _( + "O Dispositivo em edição define vigência de outros " + "dispositivos. Alterar as datas de vigência " + "alterará as datas de vigência dos dispositivos " + "vigêntes por este em edição." + ), + ), + ) + ) layout.append( - Fieldset(_('Datas de Controle de Vigência'), - row_datas, - css_class="col-md-12")) + Fieldset( + _("Datas de Controle de Vigência"), row_datas, css_class="col-md-12" + ) + ) row_vigencia = Field( - 'dispositivo_vigencia', - data_sapl_ta='DispositivoSearch', - data_field='dispositivo_vigencia', - data_type_selection='radio', - template="compilacao/layout/dispositivo_radio.html") + "dispositivo_vigencia", + data_sapl_ta="DispositivoSearch", + data_field="dispositivo_vigencia", + data_type_selection="radio", + template="compilacao/layout/dispositivo_radio.html", + ) layout.append( - Fieldset(_('Dispositivo de Vigência'), - to_row([(InlineRadios('extensao'), 12)]), - row_vigencia, - css_class="col-md-12")) + Fieldset( + _("Dispositivo de Vigência"), + to_row([(InlineRadios("extensao"), 12)]), + row_vigencia, + css_class="col-md-12", + ) + ) self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout( - *layout, - cancel_label=_('Ir para o Editor Sequencial')) + *layout, cancel_label=_("Ir para o Editor Sequencial") + ) super(DispositivoEdicaoVigenciaForm, self).__init__(*args, **kwargs) - pubs = Publicacao.objects.order_by( - '-data', '-hora').filter(Q(ta=self.instance.ta) | - Q(ta=self.instance.ta_publicado)) - self.fields['publicacao'].choices = [("", "---------")] + [( - p.pk, _('%s realizada em %s. %s') % ( - p.tipo_publicacao, - defaultfilters.date( - p.data, r"d \d\e F \d\e Y"), - str(p.ta))) for p in pubs] + pubs = Publicacao.objects.order_by("-data", "-hora").filter( + Q(ta=self.instance.ta) | Q(ta=self.instance.ta_publicado) + ) + self.fields["publicacao"].choices = [("", "---------")] + [ + ( + p.pk, + _("%s realizada em %s. %s") + % ( + p.tipo_publicacao, + defaultfilters.date(p.data, r"d \d\e F \d\e Y"), + str(p.ta), + ), + ) + for p in pubs + ] - dvs = Dispositivo.objects.order_by('ordem').filter( - pk=self.instance.dispositivo_vigencia_id) - self.fields['dispositivo_vigencia'].choices = [(d.pk, d) for d in dvs] + dvs = Dispositivo.objects.order_by("ordem").filter( + pk=self.instance.dispositivo_vigencia_id + ) + self.fields["dispositivo_vigencia"].choices = [(d.pk, d) for d in dvs] def clean_dispositivo_vigencia(self): - dv = self.cleaned_data['dispositivo_vigencia'] + dv = self.cleaned_data["dispositivo_vigencia"] if dv and dv.auto_inserido: dv = dv.dispositivo_pai @@ -1019,23 +1125,22 @@ class DispositivoEdicaoVigenciaForm(ModelForm): instance = dp - dv = data['dispositivo_vigencia'] + dv = data["dispositivo_vigencia"] if dv and dv.auto_inserido: dv = dv.dispositivo_pai - extensao = 'extensao' in data and data['extensao'] == 'True' + extensao = "extensao" in data and data["extensao"] == "True" if extensao: dv_pk = dv.pk if dv else None def extenderPara(dpt_pk): - Dispositivo.objects.filter( - dispositivo_pai_id=dpt_pk, - ta_publicado__isnull=True).update( - dispositivo_vigencia_id=dv_pk) + dispositivo_pai_id=dpt_pk, ta_publicado__isnull=True + ).update(dispositivo_vigencia_id=dv_pk) filhos = Dispositivo.objects.filter( - dispositivo_pai_id=dpt_pk).values_list('pk', flat=True) + dispositivo_pai_id=dpt_pk + ).values_list("pk", flat=True) for d in filhos: extenderPara(d) @@ -1046,184 +1151,191 @@ class DispositivoEdicaoVigenciaForm(ModelForm): while instance.auto_inserido and instance.dispositivo_pai: instance = instance.dispositivo_pai - inst.dispositivos_vigencias_set.filter( - ta_publicado__isnull=True).update( - inicio_vigencia=inst.inicio_vigencia, - inicio_eficacia=inst.inicio_eficacia, - fim_vigencia=inst.fim_vigencia, - fim_eficacia=inst.fim_eficacia) + inst.dispositivos_vigencias_set.filter(ta_publicado__isnull=True).update( + inicio_vigencia=inst.inicio_vigencia, + inicio_eficacia=inst.inicio_eficacia, + fim_vigencia=inst.fim_vigencia, + fim_eficacia=inst.fim_eficacia, + ) - inst.dispositivos_vigencias_set.filter( - ta_publicado__isnull=False).update( - inicio_vigencia=inst.inicio_eficacia, - inicio_eficacia=inst.inicio_eficacia, - fim_vigencia=inst.fim_eficacia, - fim_eficacia=inst.fim_eficacia) + inst.dispositivos_vigencias_set.filter(ta_publicado__isnull=False).update( + inicio_vigencia=inst.inicio_eficacia, + inicio_eficacia=inst.inicio_eficacia, + fim_vigencia=inst.fim_eficacia, + fim_eficacia=inst.fim_eficacia, + ) return inst class MultipleChoiceWithoutValidationField(forms.MultipleChoiceField): - def validate(self, value): if self.required and not value: - raise ValidationError( - self.error_messages['required'], code='required') + raise ValidationError(self.error_messages["required"], code="required") class DispositivoDefinidorVigenciaForm(Form): - dispositivo_vigencia = MultipleChoiceWithoutValidationField( - label=Dispositivo._meta.get_field( - 'dispositivo_vigencia').verbose_name, - required=False) + label=Dispositivo._meta.get_field("dispositivo_vigencia").verbose_name, + required=False, + ) def __init__(self, *args, **kwargs): - layout = [] row_vigencia = Field( - 'dispositivo_vigencia', - data_sapl_ta='DispositivoSearch', - data_field='dispositivo_vigencia', - data_type_selection='checkbox', - template="compilacao/layout/dispositivo_checkbox.html") + "dispositivo_vigencia", + data_sapl_ta="DispositivoSearch", + data_field="dispositivo_vigencia", + data_type_selection="checkbox", + template="compilacao/layout/dispositivo_checkbox.html", + ) layout.append( - Fieldset(_('Definidor de Vigência dos Dispositívos abaixo'), - row_vigencia, - css_class="col-md-12")) + Fieldset( + _("Definidor de Vigência dos Dispositívos abaixo"), + row_vigencia, + css_class="col-md-12", + ) + ) self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout( - *layout, - cancel_label=_('Ir para o Editor Sequencial')) + *layout, cancel_label=_("Ir para o Editor Sequencial") + ) - pk = kwargs.pop('pk') + pk = kwargs.pop("pk") super(DispositivoDefinidorVigenciaForm, self).__init__(*args, **kwargs) - dvs = Dispositivo.objects.order_by('ta', 'ordem').filter( - dispositivo_vigencia_id=pk).select_related( - *DISPOSITIVO_SELECT_RELATED) - self.initial['dispositivo_vigencia'] = [d.pk for d in dvs] - - TA_TA_PUB = 'ta_id', 'ta_publicado_id' - tas = Dispositivo.objects.order_by( - *TA_TA_PUB).filter(dispositivo_vigencia_id=pk).distinct( - *TA_TA_PUB).values_list( - *TA_TA_PUB) + dvs = ( + Dispositivo.objects.order_by("ta", "ordem") + .filter(dispositivo_vigencia_id=pk) + .select_related(*DISPOSITIVO_SELECT_RELATED) + ) + self.initial["dispositivo_vigencia"] = [d.pk for d in dvs] + + TA_TA_PUB = "ta_id", "ta_publicado_id" + tas = ( + Dispositivo.objects.order_by(*TA_TA_PUB) + .filter(dispositivo_vigencia_id=pk) + .distinct(*TA_TA_PUB) + .values_list(*TA_TA_PUB) + ) tas = list(set().union(*list(map(list, zip(*tas))))) if not tas: - tas = Dispositivo.objects.filter(pk=pk).values_list('ta_id') + tas = Dispositivo.objects.filter(pk=pk).values_list("ta_id") - dvs = Dispositivo.objects.order_by( - '-ta__data', '-ta__ano', '-ta__numero', 'ta', 'ordem').filter( - ta__in=tas).select_related(*DISPOSITIVO_SELECT_RELATED) - self.fields['dispositivo_vigencia'].choices = [ - (d.pk, d) - for d in dvs - if d.pk in self.initial['dispositivo_vigencia']] + dvs = ( + Dispositivo.objects.order_by( + "-ta__data", "-ta__ano", "-ta__numero", "ta", "ordem" + ) + .filter(ta__in=tas) + .select_related(*DISPOSITIVO_SELECT_RELATED) + ) + self.fields["dispositivo_vigencia"].choices = [ + (d.pk, d) for d in dvs if d.pk in self.initial["dispositivo_vigencia"] + ] class DispositivoEdicaoAlteracaoForm(ModelForm): - class Meta: model = Dispositivo fields = [ - 'dispositivo_atualizador', - 'dispositivo_substituido', - 'dispositivo_subsequente', + "dispositivo_atualizador", + "dispositivo_substituido", + "dispositivo_subsequente", ] error_messages = { NON_FIELD_ERRORS: { - 'unique_together': - _("Já existe um Dispositivo com características idênticas."), + "unique_together": _( + "Já existe um Dispositivo com características idênticas." + ), } } def __init__(self, *args, **kwargs): - layout = [] self.dispositivo_substituido = forms.ModelChoiceField( - label=Dispositivo._meta.get_field( - 'dispositivo_substituido').verbose_name, + label=Dispositivo._meta.get_field("dispositivo_substituido").verbose_name, required=False, - queryset=Dispositivo.objects.all()) + queryset=Dispositivo.objects.all(), + ) self.dispositivo_subsequente = forms.ModelChoiceField( - label=Dispositivo._meta.get_field( - 'dispositivo_subsequente').verbose_name, + label=Dispositivo._meta.get_field("dispositivo_subsequente").verbose_name, required=False, - queryset=Dispositivo.objects.all()) + queryset=Dispositivo.objects.all(), + ) self.dispositivo_atualizador = forms.ModelChoiceField( - label=Dispositivo._meta.get_field( - 'dispositivo_atualizador').verbose_name, + label=Dispositivo._meta.get_field("dispositivo_atualizador").verbose_name, required=False, - queryset=Dispositivo.objects.all()) + queryset=Dispositivo.objects.all(), + ) substituido = Field( - 'dispositivo_substituido', - data_sapl_ta='DispositivoSearch', - data_field='dispositivo_substituido', - data_type_selection='radio', - template="compilacao/layout/dispositivo_radio.html") + "dispositivo_substituido", + data_sapl_ta="DispositivoSearch", + data_field="dispositivo_substituido", + data_type_selection="radio", + template="compilacao/layout/dispositivo_radio.html", + ) subsequente = Field( - 'dispositivo_subsequente', - data_sapl_ta='DispositivoSearch', - data_field='dispositivo_subsequente', - data_type_selection='radio', - template="compilacao/layout/dispositivo_radio.html") + "dispositivo_subsequente", + data_sapl_ta="DispositivoSearch", + data_field="dispositivo_subsequente", + data_type_selection="radio", + template="compilacao/layout/dispositivo_radio.html", + ) alterador = Field( - 'dispositivo_atualizador', - data_sapl_ta='DispositivoSearch', - data_field='dispositivo_atualizador', - data_type_selection='radio', - data_function='alterador', - template="compilacao/layout/dispositivo_radio.html") + "dispositivo_atualizador", + data_sapl_ta="DispositivoSearch", + data_field="dispositivo_atualizador", + data_type_selection="radio", + data_function="alterador", + template="compilacao/layout/dispositivo_radio.html", + ) layout.append( - to_row([ - (Fieldset(_('Dispositivo Subsitituido'), substituido), 6), - (Fieldset(_('Dispositivo Subsequente'), subsequente), 6)])) + to_row( + [ + (Fieldset(_("Dispositivo Subsitituido"), substituido), 6), + (Fieldset(_("Dispositivo Subsequente"), subsequente), 6), + ] + ) + ) layout.append( - Fieldset( - _('Dispositivo Alterador'), - Div(alterador), - css_class="col-md-12")) + Fieldset(_("Dispositivo Alterador"), Div(alterador), css_class="col-md-12") + ) - inst = kwargs['instance'] if 'instance' in kwargs else None + inst = kwargs["instance"] if "instance" in kwargs else None if inst and inst.tipo_dispositivo.dispositivo_de_articulacao: - if 'texto_atualizador' in\ - DispositivoEdicaoAlteracaoForm.Meta.fields: - DispositivoEdicaoAlteracaoForm.Meta.fields.remove( - 'texto_atualizador') - DispositivoEdicaoAlteracaoForm.Meta.fields.remove( - 'visibilidade') + if "texto_atualizador" in DispositivoEdicaoAlteracaoForm.Meta.fields: + DispositivoEdicaoAlteracaoForm.Meta.fields.remove("texto_atualizador") + DispositivoEdicaoAlteracaoForm.Meta.fields.remove("visibilidade") else: - if 'texto_atualizador' not in\ - DispositivoEdicaoAlteracaoForm.Meta.fields: - DispositivoEdicaoAlteracaoForm.Meta.fields.append( - 'texto_atualizador') - DispositivoEdicaoAlteracaoForm.Meta.fields.append( - 'visibilidade') - - self.texto_atualizador = forms.CharField(required=False, - label='', - widget=forms.Textarea()) + if "texto_atualizador" not in DispositivoEdicaoAlteracaoForm.Meta.fields: + DispositivoEdicaoAlteracaoForm.Meta.fields.append("texto_atualizador") + DispositivoEdicaoAlteracaoForm.Meta.fields.append("visibilidade") + + self.texto_atualizador = forms.CharField( + required=False, label="", widget=forms.Textarea() + ) self.visibilidade = forms.ChoiceField( - label=Dispositivo._meta.get_field( - 'visibilidade').verbose_name, + label=Dispositivo._meta.get_field("visibilidade").verbose_name, choices=utils.YES_NO_CHOICES, - widget=forms.RadioSelect()) + widget=forms.RadioSelect(), + ) layout.append( - Fieldset(Dispositivo._meta.get_field( - 'texto_atualizador').verbose_name, - to_row([(InlineRadios('visibilidade'), 12)]), - to_row([('texto_atualizador', 12)]), - css_class="col-md-12")) + Fieldset( + Dispositivo._meta.get_field("texto_atualizador").verbose_name, + to_row([(InlineRadios("visibilidade"), 12)]), + to_row([("texto_atualizador", 12)]), + css_class="col-md-12", + ) + ) fields = DispositivoEdicaoAlteracaoForm.Meta.fields if fields: @@ -1234,28 +1346,28 @@ class DispositivoEdicaoAlteracaoForm(ModelForm): self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout( - *layout, - cancel_label=_('Ir para o Editor Sequencial')) + *layout, cancel_label=_("Ir para o Editor Sequencial") + ) super(DispositivoEdicaoAlteracaoForm, self).__init__(*args, **kwargs) - self.fields['dispositivo_substituido'].choices = [] - self.fields['dispositivo_subsequente'].choices = [] - self.fields['dispositivo_atualizador'].choices = [] + self.fields["dispositivo_substituido"].choices = [] + self.fields["dispositivo_subsequente"].choices = [] + self.fields["dispositivo_atualizador"].choices = [] if inst.dispositivo_substituido: - self.fields['dispositivo_substituido'].choices = [ - (inst.dispositivo_substituido.pk, - inst.dispositivo_substituido)] + self.fields["dispositivo_substituido"].choices = [ + (inst.dispositivo_substituido.pk, inst.dispositivo_substituido) + ] if inst.dispositivo_subsequente: - self.fields['dispositivo_subsequente'].choices = [ - (inst.dispositivo_subsequente.pk, - inst.dispositivo_subsequente)] + self.fields["dispositivo_subsequente"].choices = [ + (inst.dispositivo_subsequente.pk, inst.dispositivo_subsequente) + ] if inst.dispositivo_atualizador: - self.fields['dispositivo_atualizador'].choices = [ - (inst.dispositivo_atualizador.pk, - inst.dispositivo_atualizador)] + self.fields["dispositivo_atualizador"].choices = [ + (inst.dispositivo_atualizador.pk, inst.dispositivo_atualizador) + ] def clean(self): super(DispositivoEdicaoAlteracaoForm, self).clean() @@ -1268,38 +1380,66 @@ class DispositivoEdicaoAlteracaoForm(ModelForm): """ data = self.cleaned_data - dst = data['dispositivo_substituido'] - dsq = data['dispositivo_subsequente'] - da = data['dispositivo_atualizador'] + dst = data["dispositivo_substituido"] + dsq = data["dispositivo_subsequente"] + da = data["dispositivo_atualizador"] if dst == self.instance: - raise ValidationError(_('Não é permitido selecionar o próprio ' - 'Dispositivo como seu substituto.')) + raise ValidationError( + _( + "Não é permitido selecionar o próprio " + "Dispositivo como seu substituto." + ) + ) if dst and dst.ta != self.instance.ta: - raise ValidationError(_('Não é permitido selecionar um ' - 'Dispositivo de outro Texto Articulado.')) + raise ValidationError( + _( + "Não é permitido selecionar um " + "Dispositivo de outro Texto Articulado." + ) + ) if dst and dst.tipo_dispositivo != self.instance.tipo_dispositivo: - raise ValidationError(_('Não é permitido selecionar um ' - 'Dispositivo de outro Tipo.')) + raise ValidationError( + _("Não é permitido selecionar um " "Dispositivo de outro Tipo.") + ) if dsq == self.instance: - raise ValidationError(_('Não é permitido selecionar o próprio ' - 'Dispositivo como seu subsequente.')) + raise ValidationError( + _( + "Não é permitido selecionar o próprio " + "Dispositivo como seu subsequente." + ) + ) if dsq and dsq.ta != self.instance.ta: - raise ValidationError(_('Não é permitido selecionar um ' - 'Dispositivo de outro Texto Articulado.')) + raise ValidationError( + _( + "Não é permitido selecionar um " + "Dispositivo de outro Texto Articulado." + ) + ) if dsq and dsq.tipo_dispositivo != self.instance.tipo_dispositivo: - raise ValidationError(_('Não é permitido selecionar um ' - 'Dispositivo de outro Tipo.')) + raise ValidationError( + _("Não é permitido selecionar um " "Dispositivo de outro Tipo.") + ) - if da and not (da.tipo_dispositivo.dispositivo_de_alteracao and - da.tipo_dispositivo.dispositivo_de_articulacao): - raise ValidationError(_('O Dispositivo de Atualização selecionado ' - 'não é um Bloco de Alteração.')) + if da and not ( + da.tipo_dispositivo.dispositivo_de_alteracao + and da.tipo_dispositivo.dispositivo_de_articulacao + ): + raise ValidationError( + _( + "O Dispositivo de Atualização selecionado " + "não é um Bloco de Alteração." + ) + ) if not da and dst: - raise ValidationError(_('Não é permitido substituir um ' - 'Dispositivo sem haver um ' - 'Dispositivo Alterador.')) + raise ValidationError( + _( + "Não é permitido substituir um " + "Dispositivo sem haver um " + "Dispositivo Alterador." + ) + ) """if dst.inicio_vigencia > self.instance.inicio_vigencia: raise ValidationError(_('Não é permitido substituir um ' @@ -1321,9 +1461,9 @@ class DispositivoEdicaoAlteracaoForm(ModelForm): od = Dispositivo.objects.get(pk=self.instance.pk) nd = self.instance - ndst = data['dispositivo_substituido'] - ndsq = data['dispositivo_subsequente'] - nda = data['dispositivo_atualizador'] + ndst = data["dispositivo_substituido"] + ndsq = data["dispositivo_subsequente"] + nda = data["dispositivo_atualizador"] # Se o dispositivo substituído foi trocado na edição if ndst != od.dispositivo_substituido: @@ -1372,31 +1512,43 @@ class DispositivoEdicaoAlteracaoForm(ModelForm): super(DispositivoEdicaoAlteracaoForm, self).save() if nd.dispositivo_subsequente: - nd.fim_vigencia = nd.dispositivo_subsequente.inicio_vigencia - \ - timedelta(days=1) - nd.fim_eficacia = nd.dispositivo_subsequente.inicio_eficacia - \ - timedelta(days=1) + nd.fim_vigencia = nd.dispositivo_subsequente.inicio_vigencia - timedelta( + days=1 + ) + nd.fim_eficacia = nd.dispositivo_subsequente.inicio_eficacia - timedelta( + days=1 + ) nd.save() class TextNotificacoesForm(Form): - type_notificacoes = forms.MultipleChoiceField( - label=_('Níveis de Notificações'), - choices=[('default', _('Dispositivos sem Notificações!')), - ('success', _('Informações!')), - ('info', _('Boas Práticas!')), - ('warning', _('Alertas!')), - ('danger', _('Erros!'))], + label=_("Níveis de Notificações"), + choices=[ + ("default", _("Dispositivos sem Notificações!")), + ("success", _("Informações!")), + ("info", _("Boas Práticas!")), + ("warning", _("Alertas!")), + ("danger", _("Erros!")), + ], required=False, - widget=widgets.CheckboxSelectMultiple()) + widget=widgets.CheckboxSelectMultiple(), + ) def __init__(self, *args, **kwargs): - - field_type_notificacoes = to_row([(InlineCheckboxes( - 'type_notificacoes'), 10), - (Submit('submit-form', _('Filtrar'), - css_class='btn btn-primary float-right'), 2)]) + field_type_notificacoes = to_row( + [ + (InlineCheckboxes("type_notificacoes"), 10), + ( + Submit( + "submit-form", + _("Filtrar"), + css_class="btn btn-primary float-right", + ), + 2, + ), + ] + ) self.helper = SaplFormHelper() self.helper.layout = Layout(field_type_notificacoes) @@ -1405,155 +1557,166 @@ class TextNotificacoesForm(Form): class DispositivoRegistroAlteracaoForm(Form): - dispositivo_alterado = forms.ModelChoiceField( - label=_('Dispositivo a ser alterado'), + label=_("Dispositivo a ser alterado"), required=False, - queryset=Dispositivo.objects.all()) + queryset=Dispositivo.objects.all(), + ) - dispositivo_search_form = forms.CharField(widget=forms.HiddenInput(), - required=False) + dispositivo_search_form = forms.CharField( + widget=forms.HiddenInput(), required=False + ) def __init__(self, *args, **kwargs): - layout = [] - kwargs.pop('instance') - kwargs['initial'].pop('editor_type') + kwargs.pop("instance") + kwargs["initial"].pop("editor_type") row_dispositivo = Field( - 'dispositivo_alterado', - data_sapl_ta='DispositivoSearch', - data_field='dispositivo_alterado', - data_type_selection='checkbox', - template="compilacao/layout/dispositivo_radio.html") - - layout.append(Fieldset(_('Registro de Alteração - ' - 'Seleção do Dispositivo a ser alterado'), - row_dispositivo, - css_class="col-md-12")) - layout.append(Field('dispositivo_search_form')) + "dispositivo_alterado", + data_sapl_ta="DispositivoSearch", + data_field="dispositivo_alterado", + data_type_selection="checkbox", + template="compilacao/layout/dispositivo_radio.html", + ) + + layout.append( + Fieldset( + _("Registro de Alteração - " "Seleção do Dispositivo a ser alterado"), + row_dispositivo, + css_class="col-md-12", + ) + ) + layout.append(Field("dispositivo_search_form")) more = [ - HTML('%s' % - _('Cancelar')), + HTML('%s' % _("Cancelar")), ] - more.append(Submit('salvar', _('Salvar'), css_class='float-right')) + more.append(Submit("salvar", _("Salvar"), css_class="float-right")) - buttons = FormActions(*more, css_class='form-group') + buttons = FormActions(*more, css_class="form-group") - _fields = [Div(*layout, css_class="row")] + \ - [to_row([(buttons, 12)])] + _fields = [Div(*layout, css_class="row")] + [to_row([(buttons, 12)])] self.helper = SaplFormHelper() self.helper.layout = Layout(*_fields) super(DispositivoRegistroAlteracaoForm, self).__init__(*args, **kwargs) - self.fields['dispositivo_alterado'].choices = [] + self.fields["dispositivo_alterado"].choices = [] class DispositivoRegistroRevogacaoForm(Form): - dispositivo_revogado = forms.ModelChoiceField( - label=_('Dispositivo a ser revogado'), + label=_("Dispositivo a ser revogado"), required=False, - queryset=Dispositivo.objects.all()) + queryset=Dispositivo.objects.all(), + ) revogacao_em_bloco = forms.ChoiceField( label=_( - 'Revogar todos os dispositivos internos dos ' - 'dispositivos abaixo selecionados?'), + "Revogar todos os dispositivos internos dos " + "dispositivos abaixo selecionados?" + ), choices=YES_NO_CHOICES, widget=forms.RadioSelect(), - required=True) + required=True, + ) - dispositivo_search_form = forms.CharField(widget=forms.HiddenInput(), - required=False) + dispositivo_search_form = forms.CharField( + widget=forms.HiddenInput(), required=False + ) def __init__(self, *args, **kwargs): - layout = [] - kwargs.pop('instance') - kwargs['initial'].pop('editor_type') + kwargs.pop("instance") + kwargs["initial"].pop("editor_type") row_dispositivo = Field( - 'dispositivo_revogado', - data_sapl_ta='DispositivoSearch', - data_field='dispositivo_revogado', - data_type_selection='checkbox', - template="compilacao/layout/dispositivo_radio.html") - - layout.append(Fieldset(_('Registro de Revogação - ' - 'Seleção do Dispositivo a ser Revogado'), - Field(InlineRadios('revogacao_em_bloco')), - row_dispositivo, - css_class="col-md-12")) - layout.append(Field('dispositivo_search_form')) + "dispositivo_revogado", + data_sapl_ta="DispositivoSearch", + data_field="dispositivo_revogado", + data_type_selection="checkbox", + template="compilacao/layout/dispositivo_radio.html", + ) + + layout.append( + Fieldset( + _("Registro de Revogação - " "Seleção do Dispositivo a ser Revogado"), + Field(InlineRadios("revogacao_em_bloco")), + row_dispositivo, + css_class="col-md-12", + ) + ) + layout.append(Field("dispositivo_search_form")) more = [ - HTML('%s' % - _('Cancelar')), + HTML('%s' % _("Cancelar")), ] - more.append(Submit('salvar', _('Salvar'), css_class='float-right')) + more.append(Submit("salvar", _("Salvar"), css_class="float-right")) - buttons = FormActions(*more, css_class='form-group') + buttons = FormActions(*more, css_class="form-group") - _fields = [Div(*layout, css_class="row")] + \ - [to_row([(buttons, 12)])] + _fields = [Div(*layout, css_class="row")] + [to_row([(buttons, 12)])] self.helper = SaplFormHelper() self.helper.layout = Layout(*_fields) super(DispositivoRegistroRevogacaoForm, self).__init__(*args, **kwargs) - self.fields['dispositivo_revogado'].choices = [] + self.fields["dispositivo_revogado"].choices = [] class DispositivoRegistroInclusaoForm(Form): - dispositivo_base_para_inclusao = forms.ModelChoiceField( - label=_('Dispositivo Base para inclusão de novo dispositivo'), + label=_("Dispositivo Base para inclusão de novo dispositivo"), required=False, - queryset=Dispositivo.objects.all()) + queryset=Dispositivo.objects.all(), + ) - dispositivo_search_form = forms.CharField(widget=forms.HiddenInput(), - required=False) + dispositivo_search_form = forms.CharField( + widget=forms.HiddenInput(), required=False + ) def __init__(self, *args, **kwargs): - layout = [] - kwargs.pop('instance') - kwargs['initial'].pop('editor_type') + kwargs.pop("instance") + kwargs["initial"].pop("editor_type") row_dispositivo = Field( - 'dispositivo_base_para_inclusao', - data_sapl_ta='DispositivoSearch', - data_field='dispositivo_base_para_inclusao', - data_type_selection='checkbox', - template="compilacao/layout/dispositivo_radio.html") - - layout.append(Fieldset(_('Registro de Inclusão - ' - 'Seleção do Dispositivo Base para inclusão ' - 'de novo dispositivo.'), - row_dispositivo, - css_class="col-md-12")) - layout.append(Field('dispositivo_search_form')) + "dispositivo_base_para_inclusao", + data_sapl_ta="DispositivoSearch", + data_field="dispositivo_base_para_inclusao", + data_type_selection="checkbox", + template="compilacao/layout/dispositivo_radio.html", + ) + + layout.append( + Fieldset( + _( + "Registro de Inclusão - " + "Seleção do Dispositivo Base para inclusão " + "de novo dispositivo." + ), + row_dispositivo, + css_class="col-md-12", + ) + ) + layout.append(Field("dispositivo_search_form")) layout.append(Div(css_class="allowed_inserts col-md-12")) more = [ - HTML('%s' % - _('Cancelar')), + HTML('%s' % _("Cancelar")), ] # more.append(Submit('salvar', _('Salvar'), css_class='float-right')) - buttons = FormActions(*more, css_class='form-group') + buttons = FormActions(*more, css_class="form-group") - _fields = [Div(*layout, css_class="row")] + \ - [to_row([(buttons, 12)])] + _fields = [Div(*layout, css_class="row")] + [to_row([(buttons, 12)])] self.helper = SaplFormHelper() self.helper.layout = Layout(*_fields) super(DispositivoRegistroInclusaoForm, self).__init__(*args, **kwargs) - self.fields['dispositivo_base_para_inclusao'].choices = [] + self.fields["dispositivo_base_para_inclusao"].choices = [] diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py index 42e06cbb1..c179a0b16 100644 --- a/sapl/compilacao/models.py +++ b/sapl/compilacao/models.py @@ -15,23 +15,23 @@ from image_cropping.fields import ImageCropField, ImageRatioField 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,\ - texto_upload_path, restringe_tipos_de_arquivo_img +from sapl.utils import (YES_NO_CHOICES, get_settings_auth_user_model, + restringe_tipos_de_arquivo_img, texto_upload_path) class TimestampedMixin(models.Model): created = models.DateTimeField( - verbose_name=_('created'), - editable=False, blank=True, auto_now_add=True) + verbose_name=_("created"), editable=False, blank=True, auto_now_add=True + ) modified = models.DateTimeField( - verbose_name=_('modified'), editable=False, blank=True, auto_now=True) + verbose_name=_("modified"), editable=False, blank=True, auto_now=True + ) class Meta: abstract = True class BaseModel(models.Model): - class Meta: abstract = True @@ -50,28 +50,39 @@ class BaseModel(models.Model): for field_name in field_tuple: field_value = getattr(self, field_name) if getattr(self, field_name) is None: - unique_filter['%s__isnull' % field_name] = True + unique_filter["%s__isnull" % field_name] = True null_found = True else: - unique_filter['%s' % field_name] = field_value + unique_filter["%s" % field_name] = field_value unique_fields.append(field_name) if null_found: - unique_queryset = self.__class__.objects.filter( - **unique_filter) + unique_queryset = self.__class__.objects.filter(**unique_filter) if self.pk: unique_queryset = unique_queryset.exclude(pk=self.pk) if unique_queryset.exists(): msg = self.unique_error_message( - self.__class__, tuple(unique_fields)) + self.__class__, tuple(unique_fields) + ) raise ValidationError(msg) - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None, clean=True): + def save( + self, + force_insert=False, + force_update=False, + using=None, + update_fields=None, + clean=True, + ): # método clean não pode ser chamado no caso do save que está sendo # executado é o save de revision_pre_delete_signal import inspect - funcs = list(filter(lambda x: x == 'revision_pre_delete_signal', - map(lambda x: x[3], inspect.stack()))) + + funcs = list( + filter( + lambda x: x == "revision_pre_delete_signal", + map(lambda x: x[3], inspect.stack()), + ) + ) if clean and not funcs: self.clean() @@ -81,29 +92,32 @@ class BaseModel(models.Model): force_insert=force_insert, force_update=force_update, using=using, - update_fields=update_fields) + update_fields=update_fields, + ) class PerfilEstruturalTextoArticulado(BaseModel): - sigla = models.CharField( - max_length=10, unique=True, verbose_name=_('Sigla')) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) + sigla = models.CharField(max_length=10, unique=True, verbose_name=_("Sigla")) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) padrao = models.BooleanField( - default=False, - choices=YES_NO_CHOICES, verbose_name=_('Padrão')) + default=False, choices=YES_NO_CHOICES, verbose_name=_("Padrão") + ) parent = models.ForeignKey( - 'self', - blank=True, null=True, default=None, - related_name='perfil_parent_set', + "self", + blank=True, + null=True, + default=None, + related_name="perfil_parent_set", on_delete=PROTECT, - verbose_name=_('Perfil Herdado')) + verbose_name=_("Perfil Herdado"), + ) class Meta: - verbose_name = _('Perfil Estrutural de Texto Articulado') - verbose_name_plural = _('Perfis Estruturais de Textos Articulados') + verbose_name = _("Perfil Estrutural de Texto Articulado") + verbose_name_plural = _("Perfis Estruturais de Textos Articulados") - ordering = ['-padrao', 'sigla'] + ordering = ["-padrao", "sigla"] def __str__(self): return self.nome @@ -113,57 +127,72 @@ class PerfilEstruturalTextoArticulado(BaseModel): if not self.parent: return [] - parents = self.parent.parents + [self.parent, ] + parents = self.parent.parents + [ + self.parent, + ] return parents class TipoTextoArticulado(models.Model): - sigla = models.CharField(max_length=3, verbose_name=_('Sigla')) - descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) + sigla = models.CharField(max_length=3, verbose_name=_("Sigla")) + descricao = models.CharField(max_length=50, verbose_name=_("Descrição")) content_type = models.OneToOneField( ContentType, - blank=True, null=True, + blank=True, + null=True, on_delete=models.SET_NULL, - verbose_name=_('Modelo Integrado')) + verbose_name=_("Modelo Integrado"), + ) participacao_social = models.BooleanField( - blank=False, default=False, + blank=False, + default=False, choices=YES_NO_CHOICES, - verbose_name=_('Participação Social')) + verbose_name=_("Participação Social"), + ) publicacao_func = models.BooleanField( choices=YES_NO_CHOICES, - blank=False, default=False, - verbose_name=_('Histórico de Publicação')) + blank=False, + default=False, + verbose_name=_("Histórico de Publicação"), + ) perfis = models.ManyToManyField( PerfilEstruturalTextoArticulado, - blank=True, verbose_name=_('Perfis Estruturais de Textos Articulados'), - help_text=_(""" + blank=True, + verbose_name=_("Perfis Estruturais de Textos Articulados"), + help_text=_( + """ Apenas os perfis selecionados aqui estarão disponíveis para o editor de Textos Articulados cujo Tipo seja este em edição. - """)) + """ + ), + ) rodape_global = models.TextField( - verbose_name=_('Rodapé Global'), - help_text=_('A cada Tipo de Texto Articulado pode ser adicionado ' - 'uma nota global de rodapé!'), - default='' + verbose_name=_("Rodapé Global"), + help_text=_( + "A cada Tipo de Texto Articulado pode ser adicionado " + "uma nota global de rodapé!" + ), + default="", ) class Meta: - verbose_name = _('Tipo de Texto Articulado') - verbose_name_plural = _('Tipos de Texto Articulados') - ordering = ('id',) + verbose_name = _("Tipo de Texto Articulado") + verbose_name_plural = _("Tipos de Texto Articulados") + ordering = ("id",) def __str__(self): return self.descricao PARTICIPACAO_SOCIAL_CHOICES = [ - (None, _('Padrão definido no Tipo')), - (True, _('Sim')), - (False, _('Não'))] + (None, _("Padrão definido no Tipo")), + (True, _("Sim")), + (False, _("Não")), +] STATUS_TA_PRIVATE = 99 # Só os donos podem ver @@ -175,44 +204,34 @@ STATUS_TA_IMMUTABLE_PUBLIC = 69 STATUS_TA_PUBLIC = 0 PRIVACIDADE_STATUS = ( - (STATUS_TA_PRIVATE, _('Privado')), # só dono ve e edita + (STATUS_TA_PRIVATE, _("Privado")), # só dono ve e edita # só quem tem permissão para ver - (STATUS_TA_IMMUTABLE_RESTRICT, _('Imotável Restrito')), + (STATUS_TA_IMMUTABLE_RESTRICT, _("Imotável Restrito")), # só quem tem permissão para ver - (STATUS_TA_IMMUTABLE_PUBLIC, _('Imutável Público')), - (STATUS_TA_EDITION, _('Em Edição')), # só quem tem permissão para editar - (STATUS_TA_PUBLIC, _('Público')), # visualização pública + (STATUS_TA_IMMUTABLE_PUBLIC, _("Imutável Público")), + (STATUS_TA_EDITION, _("Em Edição")), # só quem tem permissão para editar + (STATUS_TA_PUBLIC, _("Público")), # visualização pública ) class TextoArticulado(TimestampedMixin): - data = models.DateField( - blank=True, - null=True, - verbose_name=_('Data') - ) + data = models.DateField(blank=True, null=True, verbose_name=_("Data")) - ementa = models.TextField(verbose_name=_('Ementa')) + ementa = models.TextField(verbose_name=_("Ementa")) - observacao = models.TextField( - blank=True, - verbose_name=_('Observação') - ) + observacao = models.TextField(blank=True, verbose_name=_("Observação")) - numero = models.CharField( - max_length=8, - verbose_name=_('Número') - ) + numero = models.CharField(max_length=8, verbose_name=_("Número")) - ano = models.PositiveSmallIntegerField(verbose_name=_('Ano')) + ano = models.PositiveSmallIntegerField(verbose_name=_("Ano")) tipo_ta = models.ForeignKey( TipoTextoArticulado, blank=True, null=True, default=None, - verbose_name=_('Tipo de Texto Articulado'), - on_delete=models.PROTECT + verbose_name=_("Tipo de Texto Articulado"), + on_delete=models.PROTECT, ) participacao_social = models.BooleanField( @@ -220,93 +239,93 @@ class TextoArticulado(TimestampedMixin): null=True, default=False, choices=PARTICIPACAO_SOCIAL_CHOICES, - verbose_name=_('Participação Social') + verbose_name=_("Participação Social"), ) content_type = models.ForeignKey( - ContentType, - blank=True, - null=True, - default=None, - on_delete=models.PROTECT + ContentType, blank=True, null=True, default=None, on_delete=models.PROTECT ) - object_id = models.PositiveIntegerField( - blank=True, - null=True, - default=None) + object_id = models.PositiveIntegerField(blank=True, null=True, default=None) - content_object = GenericForeignKey('content_type', 'object_id') + content_object = GenericForeignKey("content_type", "object_id") owners = models.ManyToManyField( get_settings_auth_user_model(), blank=True, - verbose_name=_('Donos do Texto Articulado') + verbose_name=_("Donos do Texto Articulado"), ) editable_only_by_owners = models.BooleanField( choices=YES_NO_CHOICES, default=True, - verbose_name=_('Editável apenas pelos donos do Texto Articulado?') + verbose_name=_("Editável apenas pelos donos do Texto Articulado?"), ) editing_locked = models.BooleanField( choices=YES_NO_CHOICES, default=True, - verbose_name=_('Texto Articulado em Edição?') + verbose_name=_("Texto Articulado em Edição?"), ) privacidade = models.IntegerField( - _('Privacidade'), - choices=PRIVACIDADE_STATUS, - default=STATUS_TA_PRIVATE + _("Privacidade"), choices=PRIVACIDADE_STATUS, default=STATUS_TA_PRIVATE ) class Meta: - verbose_name = _('Texto Articulado') - verbose_name_plural = _('Textos Articulados') - ordering = ['-data', '-numero'] + verbose_name = _("Texto Articulado") + verbose_name_plural = _("Textos Articulados") + ordering = ["-data", "-numero"] permissions = ( - ('view_restricted_textoarticulado', - _('Pode ver qualquer Texto Articulado')), - ('lock_unlock_textoarticulado', - _('Pode bloquear/desbloquear edição de Texto Articulado')), + ( + "view_restricted_textoarticulado", + _("Pode ver qualquer Texto Articulado"), + ), + ( + "lock_unlock_textoarticulado", + _("Pode bloquear/desbloquear edição de Texto Articulado"), + ), ) def __str__(self): if self.content_object: - assert hasattr(self.content_object, 'epigrafe'), _( - 'Modelos integrados aos Textos Articulados devem possuir a ' - 'property "epigrafe"') + assert hasattr(self.content_object, "epigrafe"), _( + "Modelos integrados aos Textos Articulados devem possuir a " + 'property "epigrafe"' + ) return str(self.content_object.epigrafe) else: numero = self.numero if numero.isnumeric(): - numero = '{0:,}'.format(int(self.numero)).replace(',', '.') + numero = "{0:,}".format(int(self.numero)).replace(",", ".") - return _('%(tipo)s nº %(numero)s, de %(data)s') % { - 'tipo': self.tipo_ta, - 'numero': numero, - 'data': defaultfilters.date(self.data, r"d \d\e F \d\e Y").lower()} + return _("%(tipo)s nº %(numero)s, de %(data)s") % { + "tipo": self.tipo_ta, + "numero": numero, + "data": defaultfilters.date(self.data, r"d \d\e F \d\e Y").lower(), + } def hash(self): - from django.core import serializers import hashlib + + from django.core import serializers + data = serializers.serialize( - "xml", Dispositivo.objects.filter( - Q(ta_id=self.id) | Q(ta_publicado_id=self.id))) + "xml", + Dispositivo.objects.filter(Q(ta_id=self.id) | Q(ta_publicado_id=self.id)), + ) md5 = hashlib.md5() - md5.update(data.encode('utf-8')) + md5.update(data.encode("utf-8")) return md5.hexdigest() def can_use_dynamic_editing(self, user): - return not self.editing_locked and\ - (not self.editable_only_by_owners and - user.has_perm( - 'compilacao.change_dispositivo_edicao_dinamica') or - self.editable_only_by_owners and user in self.owners.all() and - user.has_perm( - 'compilacao.change_your_dispositivo_edicao_dinamica')) + return not self.editing_locked and ( + not self.editable_only_by_owners + and user.has_perm("compilacao.change_dispositivo_edicao_dinamica") + or self.editable_only_by_owners + and user in self.owners.all() + and user.has_perm("compilacao.change_your_dispositivo_edicao_dinamica") + ) def has_view_permission(self, request=None): if self.privacidade in (STATUS_TA_IMMUTABLE_PUBLIC, STATUS_TA_PUBLIC): @@ -318,18 +337,16 @@ class TextoArticulado(TimestampedMixin): if request.user in self.owners.all(): return True - if self.privacidade == STATUS_TA_IMMUTABLE_RESTRICT and\ - request.user.has_perm( - 'compilacao.view_restricted_textoarticulado'): + if self.privacidade == STATUS_TA_IMMUTABLE_RESTRICT and request.user.has_perm( + "compilacao.view_restricted_textoarticulado" + ): return True elif self.privacidade == STATUS_TA_EDITION: - if request.user.has_perm( - 'compilacao.change_dispositivo_edicao_dinamica'): + if request.user.has_perm("compilacao.change_dispositivo_edicao_dinamica"): return True else: - messages.error(request, _( - 'Este Texto Articulado está em edição.')) + messages.error(request, _("Este Texto Articulado está em edição.")) elif self.privacidade == STATUS_TA_PRIVATE: if request.user in self.owners.all(): @@ -340,50 +357,59 @@ class TextoArticulado(TimestampedMixin): return False def has_edit_permission(self, request): - if self.privacidade == STATUS_TA_PRIVATE: if request.user not in self.owners.all(): raise Http404() if not self.can_use_dynamic_editing(request.user): - messages.error(request, _( - 'Usuário sem permissão para edição.')) + messages.error(request, _("Usuário sem permissão para edição.")) return False else: return True if self.privacidade == STATUS_TA_IMMUTABLE_RESTRICT: - messages.error(request, _( - 'A edição deste Texto Articulado está bloqueada. ' - 'Este documento é imutável e de acesso é restrito.')) + messages.error( + request, + _( + "A edição deste Texto Articulado está bloqueada. " + "Este documento é imutável e de acesso é restrito." + ), + ) return False if self.privacidade == STATUS_TA_IMMUTABLE_PUBLIC: - messages.error(request, _( - 'A edição deste Texto Articulado está bloqueada. ' - 'Este documento é imutável.')) + messages.error( + request, + _( + "A edição deste Texto Articulado está bloqueada. " + "Este documento é imutável." + ), + ) return False - if self.editing_locked and\ - self.privacidade in (STATUS_TA_PUBLIC, STATUS_TA_EDITION) and\ - not request.user.has_perm( - 'compilacao.lock_unlock_textoarticulado'): - messages.error(request, _( - 'A edição deste Texto Articulado está bloqueada. ' - 'É necessário acessar com usuário que possui ' - 'permissão de desbloqueio.')) + if ( + self.editing_locked + and self.privacidade in (STATUS_TA_PUBLIC, STATUS_TA_EDITION) + and not request.user.has_perm("compilacao.lock_unlock_textoarticulado") + ): + messages.error( + request, + _( + "A edição deste Texto Articulado está bloqueada. " + "É necessário acessar com usuário que possui " + "permissão de desbloqueio." + ), + ) return False - if not request.user.has_perm( - 'compilacao.change_dispositivo_edicao_dinamica'): - messages.error(request, _( - 'Usuário sem permissão para edição.')) + if not request.user.has_perm("compilacao.change_dispositivo_edicao_dinamica"): + messages.error(request, _("Usuário sem permissão para edição.")) return False - if self.editable_only_by_owners and\ - request.user not in self.owners.all(): - messages.error(request, _( - 'Apenas usuários donos do Texto Articulado podem editá-lo.')) + if self.editable_only_by_owners and request.user not in self.owners.all(): + messages.error( + request, _("Apenas usuários donos do Texto Articulado podem editá-lo.") + ) return False return True @@ -391,57 +417,58 @@ class TextoArticulado(TimestampedMixin): @classonlymethod def update_or_create(cls, view_integracao, obj): map_fields = view_integracao.map_fields - ta_values = getattr(view_integracao, 'ta_values', {}) + ta_values = getattr(view_integracao, "ta_values", {}) related_object_type = ContentType.objects.get_for_model(obj) ta = TextoArticulado.objects.filter( - object_id=obj.pk, - content_type=related_object_type) + object_id=obj.pk, content_type=related_object_type + ) ta_exists = bool(ta.exists()) if not ta_exists: tipo_ta = TipoTextoArticulado.objects.filter( - content_type=related_object_type).first() + content_type=related_object_type + ).first() ta = TextoArticulado() ta.tipo_ta = tipo_ta ta.content_object = obj - ta.privacidade = ta_values.get('privacidade', STATUS_TA_EDITION) - ta.editing_locked = ta_values.get('editing_locked', False) - ta.editable_only_by_owners = ta_values.get( - 'editable_only_by_owners', False) + ta.privacidade = ta_values.get("privacidade", STATUS_TA_EDITION) + ta.editing_locked = ta_values.get("editing_locked", False) + ta.editable_only_by_owners = ta_values.get("editable_only_by_owners", False) else: ta = ta[0] if not ta.data: - ta.data = getattr(obj, map_fields['data'] - if map_fields['data'] else 'xxx', - timezone.now()) + ta.data = getattr( + obj, map_fields["data"] if map_fields["data"] else "xxx", timezone.now() + ) if not ta.data: ta.data = timezone.now() ta.ementa = getattr( - obj, map_fields['ementa'] - if map_fields['ementa'] else 'xxx', _( - 'Integração com %s sem ementa.') % obj) + obj, + map_fields["ementa"] if map_fields["ementa"] else "xxx", + _("Integração com %s sem ementa.") % obj, + ) ta.observacao = getattr( - obj, map_fields['observacao'] - if map_fields['observacao'] else 'xxx', '') + obj, map_fields["observacao"] if map_fields["observacao"] else "xxx", "" + ) now = timezone.now() ta.numero = getattr( - obj, map_fields['numero'] - if map_fields['numero'] else 'xxx', int('%s%s%s' % ( - int(now.year), - int(now.month), - int(now.day)))) + obj, + map_fields["numero"] if map_fields["numero"] else "xxx", + int("%s%s%s" % (int(now.year), int(now.month), int(now.day))), + ) - ta.ano = getattr(obj, map_fields['ano'] - if map_fields['ano'] else 'xxx', now.year) + ta.ano = getattr( + obj, map_fields["ano"] if map_fields["ano"] else "xxx", now.year + ) ta.save() return ta @@ -452,26 +479,28 @@ class TextoArticulado(TimestampedMixin): # Os dispositivos a clonar será com base no Texto Articulado assert self.tipo_ta and self.tipo_ta.content_type, _( - 'Não é permitido chamar o método clone_for ' - 'para Textos Articulados independentes.') + "Não é permitido chamar o método clone_for " + "para Textos Articulados independentes." + ) - view_integracao = list(filter(lambda x: - x.model == obj._meta.model, - get_integrations_view_names())) + view_integracao = list( + filter(lambda x: x.model == obj._meta.model, get_integrations_view_names()) + ) assert len(view_integracao) > 0, _( - 'Não é permitido chamar o método clone_for ' - 'se não existe integração.') + "Não é permitido chamar o método clone_for " "se não existe integração." + ) assert len(view_integracao) == 1, _( - 'Não é permitido haver mais de uma integração para um Model.') + "Não é permitido haver mais de uma integração para um Model." + ) view_integracao = view_integracao[0] origem = self destino = TextoArticulado.update_or_create(view_integracao, obj) - dispositivos = Dispositivo.objects.filter(ta=origem).order_by('ordem') + dispositivos = Dispositivo.objects.filter(ta=origem).order_by("ordem") with transaction.atomic(): map_ids = {} @@ -496,8 +525,7 @@ class TextoArticulado(TimestampedMixin): d.save() map_ids[id_old] = d.id - dispositivos = Dispositivo.objects.filter( - ta=destino).order_by('ordem') + dispositivos = Dispositivo.objects.filter(ta=destino).order_by("ordem") for d in dispositivos: if not d.dispositivo_pai: @@ -508,17 +536,19 @@ class TextoArticulado(TimestampedMixin): return destino def reagrupar_ordem_de_dispositivos(self): - dpts = Dispositivo.objects.filter(ta=self) if not dpts.exists(): return ordem_max = dpts.last().ordem - dpts.update(ordem=F('ordem') + ordem_max) + dpts.update(ordem=F("ordem") + ordem_max) - dpts = Dispositivo.objects.filter( - ta=self).values_list('pk', flat=True).order_by('ordem') + dpts = ( + Dispositivo.objects.filter(ta=self) + .values_list("pk", flat=True) + .order_by("ordem") + ) count = 0 for d in dpts: @@ -526,19 +556,19 @@ class TextoArticulado(TimestampedMixin): Dispositivo.objects.filter(pk=d).update(ordem=count) def reordenar_dispositivos(self): - dpts = Dispositivo.objects.filter(ta=self) if not dpts.exists(): return ordem_max = dpts.last().ordem - dpts.update(ordem=F('ordem') + ordem_max) + dpts.update(ordem=F("ordem") + ordem_max) - raizes = Dispositivo.objects.filter( - ta=self, - dispositivo_pai__isnull=True).values_list( - 'pk', flat=True).order_by('ordem') + raizes = ( + Dispositivo.objects.filter(ta=self, dispositivo_pai__isnull=True) + .values_list("pk", flat=True) + .order_by("ordem") + ) count = [] count.append(Dispositivo.INTERVALO_ORDEM) @@ -546,9 +576,11 @@ class TextoArticulado(TimestampedMixin): def update(dpk): Dispositivo.objects.filter(pk=dpk).update(ordem=count[0]) count[0] = count[0] + Dispositivo.INTERVALO_ORDEM - filhos = Dispositivo.objects.filter( - dispositivo_pai_id=dpk).values_list( - 'pk', flat=True).order_by('ordem') + filhos = ( + Dispositivo.objects.filter(dispositivo_pai_id=dpk) + .values_list("pk", flat=True) + .order_by("ordem") + ) for dpk in filhos: update(dpk) @@ -558,33 +590,30 @@ class TextoArticulado(TimestampedMixin): class TipoNota(models.Model): - sigla = models.CharField( - max_length=10, unique=True, verbose_name=_('Sigla')) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) - modelo = models.TextField( - blank=True, verbose_name=_('Modelo')) + sigla = models.CharField(max_length=10, unique=True, verbose_name=_("Sigla")) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) + modelo = models.TextField(blank=True, verbose_name=_("Modelo")) class Meta: - verbose_name = _('Tipo de Nota') - verbose_name_plural = _('Tipos de Nota') - ordering = ('id',) + verbose_name = _("Tipo de Nota") + verbose_name_plural = _("Tipos de Nota") + ordering = ("id",) def __str__(self): - return '%s: %s' % (self.sigla, self.nome) + return "%s: %s" % (self.sigla, self.nome) class TipoVide(models.Model): - sigla = models.CharField( - max_length=10, unique=True, verbose_name=_('Sigla')) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) + sigla = models.CharField(max_length=10, unique=True, verbose_name=_("Sigla")) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) class Meta: - verbose_name = _('Tipo de Vide') - verbose_name_plural = _('Tipos de Vide') - ordering = ('id',) + verbose_name = _("Tipo de Vide") + verbose_name_plural = _("Tipos de Vide") + ordering = ("id",) def __str__(self): - return '%s: %s' % (self.sigla, self.nome) + return "%s: %s" % (self.sigla, self.nome) class TipoDispositivo(BaseModel): @@ -604,21 +633,22 @@ class TipoDispositivo(BaseModel): - revogação de dispositivo_de_articulacao revogam todo o conteúdo """ - FNC1 = '1' - FNCI = 'I' - FNCi = 'i' - FNCA = 'A' - FNCa = 'a' - FNC8 = '*' - FNCN = 'N' + + FNC1 = "1" + FNCI = "I" + FNCi = "i" + FNCA = "A" + FNCa = "a" + FNC8 = "*" + FNCN = "N" FORMATO_NUMERACAO_CHOICES = ( - (FNC1, _('1-Numérico')), - (FNCI, _('I-Romano Maiúsculo')), - (FNCi, _('i-Romano Minúsculo')), - (FNCA, _('A-Alfabético Maiúsculo')), - (FNCa, _('a-Alfabético Minúsculo')), - (FNC8, _('Tópico - Sem contagem')), - (FNCN, _('Sem renderização')), + (FNC1, _("1-Numérico")), + (FNCI, _("I-Romano Maiúsculo")), + (FNCi, _("i-Romano Minúsculo")), + (FNCA, _("A-Alfabético Maiúsculo")), + (FNCa, _("a-Alfabético Minúsculo")), + (FNC8, _("Tópico - Sem contagem")), + (FNCN, _("Sem renderização")), ) # Choice básico. Porém pode ser melhorado dando a opção de digitar outro @@ -629,128 +659,141 @@ class TipoDispositivo(BaseModel): TNRN = 0 TNR9 = 9 TIPO_NUMERO_ROTULO = ( - (TNRN, _('Numeração Cardinal.')), - (TNRT, _('Numeração Ordinal.')), - (TNR9, _('Numeração Ordinal até o item nove.')), + (TNRN, _("Numeração Cardinal.")), + (TNRT, _("Numeração Ordinal.")), + (TNR9, _("Numeração Ordinal até o item nove.")), ) - nome = models.CharField( - max_length=50, unique=True, verbose_name=_('Nome')) + nome = models.CharField(max_length=50, unique=True, verbose_name=_("Nome")) class_css = models.CharField( - blank=True, - max_length=256, - verbose_name=_('Classe CSS')) + blank=True, max_length=256, verbose_name=_("Classe CSS") + ) rotulo_prefixo_html = models.TextField( - blank=True, - verbose_name=_('Prefixo html do rótulo')) + blank=True, verbose_name=_("Prefixo html do rótulo") + ) rotulo_prefixo_texto = models.TextField( - blank=True, - verbose_name=_('Prefixo de Edição do rótulo')) + blank=True, verbose_name=_("Prefixo de Edição do rótulo") + ) rotulo_ordinal = models.IntegerField( - choices=TIPO_NUMERO_ROTULO, - verbose_name=_('Tipo de número do rótulo')) + choices=TIPO_NUMERO_ROTULO, verbose_name=_("Tipo de número do rótulo") + ) rotulo_separador_variacao01 = models.CharField( blank=False, max_length=1, default="-", - verbose_name=_('Separador entre Numeração e Variação 1')) + verbose_name=_("Separador entre Numeração e Variação 1"), + ) rotulo_separador_variacao12 = models.CharField( blank=False, max_length=1, default="-", - verbose_name=_('Separador entre Variação 1 e Variação 2')) + verbose_name=_("Separador entre Variação 1 e Variação 2"), + ) rotulo_separador_variacao23 = models.CharField( blank=False, max_length=1, default="-", - verbose_name=_('Separador entre Variação 2 e Variação 3')) + verbose_name=_("Separador entre Variação 2 e Variação 3"), + ) rotulo_separador_variacao34 = models.CharField( blank=False, max_length=1, default="-", - verbose_name=_('Separador entre Variação 3 e Variação 4')) + verbose_name=_("Separador entre Variação 3 e Variação 4"), + ) rotulo_separador_variacao45 = models.CharField( blank=False, max_length=1, default="-", - verbose_name=_('Separador entre Variação 4 e Variação 5')) + verbose_name=_("Separador entre Variação 4 e Variação 5"), + ) rotulo_sufixo_texto = models.TextField( - blank=True, - verbose_name=_('Sufixo de Edição do rótulo')) + blank=True, verbose_name=_("Sufixo de Edição do rótulo") + ) rotulo_sufixo_html = models.TextField( - blank=True, - verbose_name=_('Sufixo html do rótulo')) + blank=True, verbose_name=_("Sufixo html do rótulo") + ) texto_prefixo_html = models.TextField( - blank=True, - verbose_name=_('Prefixo html do texto')) + blank=True, verbose_name=_("Prefixo html do texto") + ) texto_sufixo_html = models.TextField( - blank=True, - verbose_name=_('Sufixo html do texto')) + blank=True, verbose_name=_("Sufixo html do texto") + ) nota_automatica_prefixo_html = models.TextField( - blank=True, - verbose_name=_('Prefixo html da nota automática')) + blank=True, verbose_name=_("Prefixo html da nota automática") + ) nota_automatica_sufixo_html = models.TextField( - blank=True, - verbose_name=_('Sufixo html da nota automática')) + blank=True, verbose_name=_("Sufixo html da nota automática") + ) contagem_continua = models.BooleanField( - choices=YES_NO_CHOICES, verbose_name=_('Contagem contínua'), default=False) + choices=YES_NO_CHOICES, verbose_name=_("Contagem contínua"), default=False + ) dispositivo_de_articulacao = models.BooleanField( choices=YES_NO_CHOICES, default=False, - verbose_name=_('Dispositivo de Articulação (Sem Texto)')) + verbose_name=_("Dispositivo de Articulação (Sem Texto)"), + ) dispositivo_de_alteracao = models.BooleanField( choices=YES_NO_CHOICES, default=False, - verbose_name=_('Dispositivo de Alteração')) + verbose_name=_("Dispositivo de Alteração"), + ) formato_variacao0 = models.CharField( max_length=1, choices=FORMATO_NUMERACAO_CHOICES, default=FNC1, - verbose_name=_('Formato da Numeração')) + verbose_name=_("Formato da Numeração"), + ) formato_variacao1 = models.CharField( max_length=1, choices=FORMATO_NUMERACAO_CHOICES, default=FNC1, - verbose_name=_('Formato da Variação 1')) + verbose_name=_("Formato da Variação 1"), + ) formato_variacao2 = models.CharField( max_length=1, choices=FORMATO_NUMERACAO_CHOICES, default=FNC1, - verbose_name=_('Formato da Variação 2')) + verbose_name=_("Formato da Variação 2"), + ) formato_variacao3 = models.CharField( max_length=1, choices=FORMATO_NUMERACAO_CHOICES, default=FNC1, - verbose_name=_('Formato da Variação 3')) + verbose_name=_("Formato da Variação 3"), + ) formato_variacao4 = models.CharField( max_length=1, choices=FORMATO_NUMERACAO_CHOICES, default=FNC1, - verbose_name=_('Formato da Variação 4')) + verbose_name=_("Formato da Variação 4"), + ) formato_variacao5 = models.CharField( max_length=1, choices=FORMATO_NUMERACAO_CHOICES, default=FNC1, - verbose_name=_('Formato da Variação 5')) + verbose_name=_("Formato da Variação 5"), + ) relacoes_diretas_pai_filho = models.ManyToManyField( - 'self', - through='TipoDispositivoRelationship', - through_fields=('pai', 'filho_permitido'), + "self", + through="TipoDispositivoRelationship", + through_fields=("pai", "filho_permitido"), symmetrical=False, - related_name='relacaoes_pai_filho') + related_name="relacaoes_pai_filho", + ) class Meta: - verbose_name = _('Tipo de Dispositivo') - verbose_name_plural = _('Tipos de Dispositivo') - ordering = ['id'] + verbose_name = _("Tipo de Dispositivo") + verbose_name_plural = _("Tipos de Dispositivo") + ordering = ["id"] def __str__(self): return self.nome def permitido_inserir_in( - self, pai_relativo, include_relative_autos=True, perfil_pk=None): - + self, pai_relativo, include_relative_autos=True, perfil_pk=None + ): perfil = PerfilEstruturalTextoArticulado.objects.all() if not perfil_pk: perfil = perfil.filter(padrao=True) @@ -774,7 +817,6 @@ class TipoDispositivo(BaseModel): return False def permitido_variacao(self, base, perfil_pk=None): - perfil = PerfilEstruturalTextoArticulado.objects.all() if not perfil_pk: perfil = perfil.filter(padrao=True) @@ -798,285 +840,226 @@ class TipoDispositivo(BaseModel): class TipoDispositivoRelationship(BaseModel): pai = models.ForeignKey( - TipoDispositivo, - related_name='filhos_permitidos', - on_delete=models.PROTECT + TipoDispositivo, related_name="filhos_permitidos", on_delete=models.PROTECT ) filho_permitido = models.ForeignKey( - TipoDispositivo, - related_name='possiveis_pais', - on_delete=models.PROTECT + TipoDispositivo, related_name="possiveis_pais", on_delete=models.PROTECT ) perfil = models.ForeignKey( - PerfilEstruturalTextoArticulado, - on_delete=models.PROTECT + PerfilEstruturalTextoArticulado, on_delete=models.PROTECT ) filho_de_insercao_automatica = models.BooleanField( default=False, choices=YES_NO_CHOICES, - verbose_name=_('Filho de Inserção Automática') + verbose_name=_("Filho de Inserção Automática"), ) permitir_variacao = models.BooleanField( default=True, choices=YES_NO_CHOICES, - verbose_name=_('Permitir Variação Numérica') + verbose_name=_("Permitir Variação Numérica"), ) quantidade_permitida = models.IntegerField( - default=-1, - verbose_name=_('Quantidade permitida nesta relação') + default=-1, verbose_name=_("Quantidade permitida nesta relação") ) class Meta: - verbose_name = _('Relação Direta Permitida') - verbose_name_plural = _('Relaçõe Diretas Permitidas') - ordering = ['pai', 'filho_permitido'] - unique_together = ( - ('pai', 'filho_permitido', 'perfil'),) + verbose_name = _("Relação Direta Permitida") + verbose_name_plural = _("Relaçõe Diretas Permitidas") + ordering = ["pai", "filho_permitido"] + unique_together = (("pai", "filho_permitido", "perfil"),) def __str__(self): - return '%s - %s' % ( + return "%s - %s" % ( self.pai.nome, - self.filho_permitido.nome if self.filho_permitido else '') + self.filho_permitido.nome if self.filho_permitido else "", + ) class TipoPublicacao(models.Model): - sigla = models.CharField( - max_length=10, unique=True, verbose_name=_('Sigla')) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) + sigla = models.CharField(max_length=10, unique=True, verbose_name=_("Sigla")) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) class Meta: - verbose_name = _('Tipo de Publicação') - verbose_name_plural = _('Tipos de Publicação') - ordering = ('id',) + verbose_name = _("Tipo de Publicação") + verbose_name_plural = _("Tipos de Publicação") + ordering = ("id",) def __str__(self): return self.nome class VeiculoPublicacao(models.Model): - sigla = models.CharField( - max_length=10, unique=True, verbose_name=_('Sigla')) - nome = models.CharField(max_length=60, verbose_name=_('Nome')) + sigla = models.CharField(max_length=10, unique=True, verbose_name=_("Sigla")) + nome = models.CharField(max_length=60, verbose_name=_("Nome")) class Meta: - verbose_name = _('Veículo de Publicação') - verbose_name_plural = _('Veículos de Publicação') - ordering = ('id',) + verbose_name = _("Veículo de Publicação") + verbose_name_plural = _("Veículos de Publicação") + ordering = ("id",) def __str__(self): - return '%s: %s' % (self.sigla, self.nome) + return "%s: %s" % (self.sigla, self.nome) class Publicacao(TimestampedMixin): ta = models.ForeignKey( - TextoArticulado, - verbose_name=_('Texto Articulado'), - on_delete=models.CASCADE + TextoArticulado, verbose_name=_("Texto Articulado"), on_delete=models.CASCADE ) veiculo_publicacao = models.ForeignKey( VeiculoPublicacao, - verbose_name=_('Veículo de Publicação'), - on_delete=models.PROTECT + verbose_name=_("Veículo de Publicação"), + on_delete=models.PROTECT, ) tipo_publicacao = models.ForeignKey( - TipoPublicacao, - verbose_name=_('Tipo de Publicação'), - on_delete=models.PROTECT + TipoPublicacao, verbose_name=_("Tipo de Publicação"), on_delete=models.PROTECT ) - data = models.DateField(verbose_name=_('Data de Publicação')) + data = models.DateField(verbose_name=_("Data de Publicação")) hora = models.TimeField( - blank=True, - null=True, - verbose_name=_('Horário de Publicação') + blank=True, null=True, verbose_name=_("Horário de Publicação") ) numero = models.PositiveIntegerField( - blank=True, - null=True, - verbose_name=_('Número') + blank=True, null=True, verbose_name=_("Número") ) - ano = models.PositiveIntegerField( - blank=True, - null=True, - verbose_name=_('Ano') - ) + ano = models.PositiveIntegerField(blank=True, null=True, verbose_name=_("Ano")) edicao = models.PositiveIntegerField( - blank=True, - null=True, - verbose_name=_('Edição') + blank=True, null=True, verbose_name=_("Edição") ) url_externa = models.URLField( - max_length=1024, - blank=True, - verbose_name=_('Link para Versão Eletrônica') + max_length=1024, blank=True, verbose_name=_("Link para Versão Eletrônica") ) pagina_inicio = models.PositiveIntegerField( - blank=True, - null=True, - verbose_name=_('Pg. Início') + blank=True, null=True, verbose_name=_("Pg. Início") ) pagina_fim = models.PositiveIntegerField( - blank=True, - null=True, - verbose_name=_('Pg. Fim') + blank=True, null=True, verbose_name=_("Pg. Fim") ) class Meta: - verbose_name = _('Publicação') - verbose_name_plural = _('Publicações') - ordering = ('id',) + verbose_name = _("Publicação") + verbose_name_plural = _("Publicações") + ordering = ("id",) def __str__(self): - return _('%s realizada em %s \n %s') % ( + return _("%s realizada em %s \n %s") % ( self.tipo_publicacao, defaultfilters.date(self.data, r"d \d\e F \d\e Y"), - self.ta) + self.ta, + ) def imagem_upload_path(instance, filename): - return texto_upload_path(instance, filename, subpath='') + return texto_upload_path(instance, filename, subpath="") class Dispositivo(BaseModel, TimestampedMixin): - TEXTO_PADRAO_DISPOSITIVO_REVOGADO = force_str(_('(Revogado)')) + TEXTO_PADRAO_DISPOSITIVO_REVOGADO = force_str(_("(Revogado)")) INTERVALO_ORDEM = 1000 ordem = models.PositiveIntegerField( - default=0, - verbose_name=_('Ordem de Renderização') + default=0, verbose_name=_("Ordem de Renderização") ) ordem_bloco_atualizador = models.PositiveIntegerField( - default=0, - verbose_name=_('Ordem de Renderização no Bloco Atualizador') + default=0, verbose_name=_("Ordem de Renderização no Bloco Atualizador") ) # apenas articulacao recebe nivel zero nivel = models.PositiveIntegerField( - default=0, - blank=True, - null=True, - verbose_name=_('Nível Estrutural') + default=0, blank=True, null=True, verbose_name=_("Nível Estrutural") ) dispositivo0 = models.PositiveIntegerField( - default=0, - verbose_name=_('Número do Dispositivo') + default=0, verbose_name=_("Número do Dispositivo") ) dispositivo1 = models.PositiveIntegerField( - default=0, - blank=True, - null=True, - verbose_name=_('Primeiro Nível de Variação') + default=0, blank=True, null=True, verbose_name=_("Primeiro Nível de Variação") ) dispositivo2 = models.PositiveIntegerField( - default=0, - blank=True, - null=True, - verbose_name=_('Segundo Nível de Variação') + default=0, blank=True, null=True, verbose_name=_("Segundo Nível de Variação") ) dispositivo3 = models.PositiveIntegerField( - default=0, - blank=True, - null=True, - verbose_name=_('Terceiro Nível de Variação') + default=0, blank=True, null=True, verbose_name=_("Terceiro Nível de Variação") ) dispositivo4 = models.PositiveIntegerField( - default=0, - blank=True, - null=True, - verbose_name=_('Quarto Nível de Variação') + default=0, blank=True, null=True, verbose_name=_("Quarto Nível de Variação") ) dispositivo5 = models.PositiveIntegerField( - default=0, - blank=True, - null=True, - verbose_name=_('Quinto Nível de Variação') + default=0, blank=True, null=True, verbose_name=_("Quinto Nível de Variação") ) rotulo = models.CharField( - max_length=50, - blank=True, - default='', - verbose_name=_('Rótulo') + max_length=50, blank=True, default="", verbose_name=_("Rótulo") ) texto = models.TextField( - blank=True, - default='', - verbose_name=_('Texto do Dispositivo') + blank=True, default="", verbose_name=_("Texto do Dispositivo") ) texto_atualizador = models.TextField( blank=True, - default='', - verbose_name=_('Texto do Dispositivo no Dispositivo Atualizador') + default="", + verbose_name=_("Texto do Dispositivo no Dispositivo Atualizador"), ) - inicio_vigencia = models.DateField(verbose_name=_('Início de Vigência')) + inicio_vigencia = models.DateField(verbose_name=_("Início de Vigência")) fim_vigencia = models.DateField( - blank=True, - null=True, - verbose_name=_('Fim de Vigência') + blank=True, null=True, verbose_name=_("Fim de Vigência") ) - inicio_eficacia = models.DateField(verbose_name=_('Início de Eficácia')) + inicio_eficacia = models.DateField(verbose_name=_("Início de Eficácia")) fim_eficacia = models.DateField( - blank=True, - null=True, - verbose_name=_('Fim de Eficácia') + blank=True, null=True, verbose_name=_("Fim de Eficácia") ) inconstitucionalidade = models.BooleanField( default=False, choices=YES_NO_CHOICES, - verbose_name=_('Declarado Inconstitucional') + verbose_name=_("Declarado Inconstitucional"), ) auto_inserido = models.BooleanField( - default=False, - choices=YES_NO_CHOICES, - verbose_name=_('Auto Inserido') + default=False, choices=YES_NO_CHOICES, verbose_name=_("Auto Inserido") ) visibilidade = models.BooleanField( default=False, choices=YES_NO_CHOICES, - verbose_name=_('Visibilidade no Texto Articulado Publicado') + verbose_name=_("Visibilidade no Texto Articulado Publicado"), ) dispositivo_de_revogacao = models.BooleanField( default=False, choices=YES_NO_CHOICES, - verbose_name=_('Dispositivo de Revogação') + verbose_name=_("Dispositivo de Revogação"), ) tipo_dispositivo = models.ForeignKey( TipoDispositivo, on_delete=models.PROTECT, - related_name='dispositivos_do_tipo_set', - verbose_name=_('Tipo do Dispositivo') + related_name="dispositivos_do_tipo_set", + verbose_name=_("Tipo do Dispositivo"), ) publicacao = models.ForeignKey( @@ -1084,15 +1067,15 @@ class Dispositivo(BaseModel, TimestampedMixin): blank=True, null=True, default=None, - verbose_name=_('Publicação'), + verbose_name=_("Publicação"), on_delete=models.SET_NULL, ) ta = models.ForeignKey( TextoArticulado, on_delete=models.CASCADE, - related_name='dispositivos_set', - verbose_name=_('Texto Articulado'), + related_name="dispositivos_set", + verbose_name=_("Texto Articulado"), ) ta_publicado = models.ForeignKey( @@ -1101,158 +1084,192 @@ class Dispositivo(BaseModel, TimestampedMixin): blank=True, null=True, default=None, - related_name='dispositivos_alterados_pelo_ta_set', - verbose_name=_('Texto Articulado Publicado') + related_name="dispositivos_alterados_pelo_ta_set", + verbose_name=_("Texto Articulado Publicado"), ) dispositivo_subsequente = models.ForeignKey( - 'self', + "self", blank=True, null=True, default=None, - related_name='dispositivo_subsequente_set', + related_name="dispositivo_subsequente_set", on_delete=models.SET_NULL, - verbose_name=_('Dispositivo Subsequente') + verbose_name=_("Dispositivo Subsequente"), ) dispositivo_substituido = models.ForeignKey( - 'self', + "self", blank=True, null=True, default=None, - related_name='dispositivo_substituido_set', + related_name="dispositivo_substituido_set", on_delete=models.SET_NULL, - verbose_name=_('Dispositivo Substituido') + verbose_name=_("Dispositivo Substituido"), ) dispositivo_pai = models.ForeignKey( - 'self', + "self", blank=True, null=True, default=None, - related_name='dispositivos_filhos_set', - verbose_name=_('Dispositivo Pai'), + related_name="dispositivos_filhos_set", + verbose_name=_("Dispositivo Pai"), on_delete=models.CASCADE, ) dispositivo_raiz = models.ForeignKey( - 'self', + "self", blank=True, null=True, default=None, - related_name='nodes', - verbose_name=_('Dispositivo Raiz'), + related_name="nodes", + verbose_name=_("Dispositivo Raiz"), on_delete=models.CASCADE, ) dispositivo_vigencia = models.ForeignKey( - 'self', + "self", blank=True, null=True, default=None, on_delete=models.SET_NULL, - related_name='dispositivos_vigencias_set', - verbose_name=_('Dispositivo de Vigência') + related_name="dispositivos_vigencias_set", + verbose_name=_("Dispositivo de Vigência"), ) dispositivo_atualizador = models.ForeignKey( - 'self', + "self", blank=True, null=True, default=None, - related_name='dispositivos_alterados_set', - verbose_name=_('Dispositivo Atualizador'), + related_name="dispositivos_alterados_set", + verbose_name=_("Dispositivo Atualizador"), on_delete=models.SET_NULL, ) contagem_continua = models.BooleanField( - default=False, - choices=YES_NO_CHOICES, - verbose_name=_('Contagem contínua') + default=False, choices=YES_NO_CHOICES, verbose_name=_("Contagem contínua") ) imagem = ImageCropField( - verbose_name=_('Imagem'), - upload_to=imagem_upload_path, null=True, blank=True) + verbose_name=_("Imagem"), upload_to=imagem_upload_path, null=True, blank=True + ) imagem_cropping = ImageRatioField( - 'imagem', '100x100', verbose_name=_('Recorte de Imagem'), - free_crop=True, size_warning=True, - help_text=_('O recorte de imagem ' - 'é possível após a atualização.')) + "imagem", + "100x100", + verbose_name=_("Recorte de Imagem"), + free_crop=True, + size_warning=True, + help_text=_("O recorte de imagem " "é possível após a atualização."), + ) # define custom manager class SelectRelatedManager(models.Manager): def get_queryset(self): - return super().get_queryset().select_related('tipo_dispositivo', - 'publicacao', - 'ta', - 'ta_publicado', - 'dispositivo_subsequente', - 'dispositivo_substituido', - 'dispositivo_pai', - 'dispositivo_pai__tipo_dispositivo', - 'dispositivo_raiz', - 'dispositivo_vigencia', - 'dispositivo_atualizador' - ) + return ( + super() + .get_queryset() + .select_related( + "tipo_dispositivo", + "publicacao", + "ta", + "ta_publicado", + "dispositivo_subsequente", + "dispositivo_substituido", + "dispositivo_pai", + "dispositivo_pai__tipo_dispositivo", + "dispositivo_raiz", + "dispositivo_vigencia", + "dispositivo_atualizador", + ) + ) + # Replace the default manager with custom manager objects = SelectRelatedManager() class Meta: - verbose_name = _('Dispositivo') - verbose_name_plural = _('Dispositivos') - ordering = ['ta', 'ordem'] + verbose_name = _("Dispositivo") + verbose_name_plural = _("Dispositivos") + ordering = ["ta", "ordem"] unique_together = ( - ('ta', 'ordem',), - ('ta', - 'dispositivo0', - 'dispositivo1', - 'dispositivo2', - 'dispositivo3', - 'dispositivo4', - 'dispositivo5', - 'tipo_dispositivo', - 'dispositivo_raiz', - 'dispositivo_pai', - 'dispositivo_atualizador', - 'ta_publicado', - 'publicacao',), - ('ta', - 'dispositivo0', - 'dispositivo1', - 'dispositivo2', - 'dispositivo3', - 'dispositivo4', - 'dispositivo5', - 'tipo_dispositivo', - 'contagem_continua', - 'dispositivo_raiz', - 'dispositivo_atualizador', - 'ta_publicado', - 'publicacao',), + ( + "ta", + "ordem", + ), + ( + "ta", + "dispositivo0", + "dispositivo1", + "dispositivo2", + "dispositivo3", + "dispositivo4", + "dispositivo5", + "tipo_dispositivo", + "dispositivo_raiz", + "dispositivo_pai", + "dispositivo_atualizador", + "ta_publicado", + "publicacao", + ), + ( + "ta", + "dispositivo0", + "dispositivo1", + "dispositivo2", + "dispositivo3", + "dispositivo4", + "dispositivo5", + "tipo_dispositivo", + "contagem_continua", + "dispositivo_raiz", + "dispositivo_atualizador", + "ta_publicado", + "publicacao", + ), ) permissions = ( - ('change_dispositivo_edicao_dinamica', _( - 'Permissão de edição de dispositivos originais ' - 'via editor dinâmico.')), - ('change_your_dispositivo_edicao_dinamica', _( - 'Permissão de edição de dispositivos originais ' - 'via editor dinâmico desde que seja dono.')), - ('change_dispositivo_edicao_avancada', _( - 'Permissão de edição de dispositivos originais ' - 'via formulários de edição avançada.')), - ('change_dispositivo_registros_compilacao', _( - 'Permissão de registro de compilação via editor dinâmico.')), - ('view_dispositivo_notificacoes', _( - 'Permissão de acesso às notificações de pendências.')), - ('change_dispositivo_de_vigencia_global', _( - 'Permissão alteração global do dispositivo de vigência')), + ( + "change_dispositivo_edicao_dinamica", + _( + "Permissão de edição de dispositivos originais " + "via editor dinâmico." + ), + ), + ( + "change_your_dispositivo_edicao_dinamica", + _( + "Permissão de edição de dispositivos originais " + "via editor dinâmico desde que seja dono." + ), + ), + ( + "change_dispositivo_edicao_avancada", + _( + "Permissão de edição de dispositivos originais " + "via formulários de edição avançada." + ), + ), + ( + "change_dispositivo_registros_compilacao", + _("Permissão de registro de compilação via editor dinâmico."), + ), + ( + "view_dispositivo_notificacoes", + _("Permissão de acesso às notificações de pendências."), + ), + ( + "change_dispositivo_de_vigencia_global", + _("Permissão alteração global do dispositivo de vigência"), + ), ) def ws_sync(self): return self.ta and self.ta.privacidade in ( - STATUS_TA_IMMUTABLE_PUBLIC, STATUS_TA_PUBLIC) + STATUS_TA_IMMUTABLE_PUBLIC, + STATUS_TA_PUBLIC, + ) def clean(self): """ @@ -1267,28 +1284,32 @@ class Dispositivo(BaseModel, TimestampedMixin): for field_name in field_tuple: field_value = getattr(self, field_name) if getattr(self, field_name) is None: - unique_filter['%s__isnull' % field_name] = True + unique_filter["%s__isnull" % field_name] = True null_found = True else: - unique_filter['%s' % field_name] = field_value + unique_filter["%s" % field_name] = field_value unique_fields.append(field_name) if null_found: - unique_queryset = self.__class__.objects.filter( - **unique_filter) + unique_queryset = self.__class__.objects.filter(**unique_filter) if self.pk: unique_queryset = unique_queryset.exclude(pk=self.pk) - if not self.contagem_continua and \ - 'contagem_continua' in field_tuple: + if not self.contagem_continua and "contagem_continua" in field_tuple: continue if unique_queryset.exists(): msg = self.unique_error_message( - self.__class__, tuple(unique_fields)) + self.__class__, tuple(unique_fields) + ) raise ValidationError(msg) - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None, clean=True): - + def save( + self, + force_insert=False, + force_update=False, + using=None, + update_fields=None, + clean=True, + ): self.dispositivo_raiz = self.get_raiz() if self.dispositivo_raiz == self: self.dispositivo_raiz = None @@ -1306,12 +1327,17 @@ class Dispositivo(BaseModel, TimestampedMixin): pass""" return super().save( - force_insert=force_insert, force_update=force_update, using=using, - update_fields=update_fields, clean=clean) + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + clean=clean, + ) def __str__(self): - return '%(rotulo)s' % { - 'rotulo': (self.rotulo if self.rotulo else self.tipo_dispositivo)} + return "%(rotulo)s" % { + "rotulo": (self.rotulo if self.rotulo else self.tipo_dispositivo) + } def get_raiz(self): dp = self @@ -1322,22 +1348,22 @@ class Dispositivo(BaseModel, TimestampedMixin): def rotulo_padrao(self, local_insert=0, for_insert_in=0): """ 0 = Sem inserção - com nomeclatura padrao - 1 = Inserção com transformação de parágrafo único para §1º """ + 1 = Inserção com transformação de parágrafo único para §1º""" - r = '' + r = "" t = self.tipo_dispositivo - prefixo = t.rotulo_prefixo_texto.split(';') + prefixo = t.rotulo_prefixo_texto.split(";") if len(prefixo) > 1: - if for_insert_in: irmaos_mesmo_tipo = Dispositivo.objects.filter( - tipo_dispositivo=self.tipo_dispositivo, - dispositivo_pai=self) + tipo_dispositivo=self.tipo_dispositivo, dispositivo_pai=self + ) else: irmaos_mesmo_tipo = Dispositivo.objects.filter( tipo_dispositivo=self.tipo_dispositivo, - dispositivo_pai=self.dispositivo_pai) + dispositivo_pai=self.dispositivo_pai, + ) if not irmaos_mesmo_tipo.exists(): r += prefixo[1] @@ -1350,14 +1376,15 @@ class Dispositivo(BaseModel, TimestampedMixin): elif irmaos_mesmo_tipo.count() == 1: self.transform_in_next() self.transform_in_next() - r += _('Transformar %s em %s%s e criar %s1%s') % ( + r += _("Transformar %s em %s%s e criar %s1%s") % ( prefixo[1].strip(), prefixo[0], self.get_nomenclatura_completa(), prefixo[0], - 'º' if - self.tipo_dispositivo.rotulo_ordinal >= 0 - else '',) + "º" + if self.tipo_dispositivo.rotulo_ordinal >= 0 + else "", + ) else: self.dispositivo0 = 1 r += prefixo[0] @@ -1373,31 +1400,34 @@ class Dispositivo(BaseModel, TimestampedMixin): r += self.get_nomenclatura_completa() else: if local_insert == 1 and irmaos_mesmo_tipo.count() == 1: - if Dispositivo.objects.filter( - ordem__gt=self.ordem, - ordem__lt=irmaos_mesmo_tipo[0].ordem).exists(): + ordem__gt=self.ordem, ordem__lt=irmaos_mesmo_tipo[0].ordem + ).exists(): self.dispositivo0 = 2 - r += _('Transformar %s em %s%s e criar %s1%s') % ( + r += _("Transformar %s em %s%s e criar %s1%s") % ( prefixo[1].strip(), prefixo[0], self.get_nomenclatura_completa(), prefixo[0], - 'º' if - self.tipo_dispositivo.rotulo_ordinal >= 0 - else '',) + "º" + if self.tipo_dispositivo.rotulo_ordinal >= 0 + else "", + ) else: - r += _('Transformar %s em %s%s e criar %s 2%s') % ( + r += _("Transformar %s em %s%s e criar %s 2%s") % ( prefixo[1].strip(), prefixo[0], self.get_nomenclatura_completa(), prefixo[0], - 'º' if - self.tipo_dispositivo. - rotulo_ordinal >= 0 else '',) - elif irmaos_mesmo_tipo.count() == 1 and\ - irmaos_mesmo_tipo[0].dispositivo0 == 0 and\ - self.dispositivo0 == 1: + "º" + if self.tipo_dispositivo.rotulo_ordinal >= 0 + else "", + ) + elif ( + irmaos_mesmo_tipo.count() == 1 + and irmaos_mesmo_tipo[0].dispositivo0 == 0 + and self.dispositivo0 == 1 + ): irmao = irmaos_mesmo_tipo[0] irmao.dispositivo0 = 1 rr = prefixo[0] @@ -1523,10 +1553,10 @@ class Dispositivo(BaseModel, TimestampedMixin): self.dispositivo2, self.dispositivo3, self.dispositivo4, - self.dispositivo5] + self.dispositivo5, + ] def get_nomenclatura_completa(self): - numero = self.get_numero_completo() formato = [ @@ -1535,21 +1565,23 @@ class Dispositivo(BaseModel, TimestampedMixin): self.tipo_dispositivo.formato_variacao2, self.tipo_dispositivo.formato_variacao3, self.tipo_dispositivo.formato_variacao4, - self.tipo_dispositivo.formato_variacao5] + self.tipo_dispositivo.formato_variacao5, + ] separadores = [ - '', + "", self.tipo_dispositivo.rotulo_separador_variacao01, self.tipo_dispositivo.rotulo_separador_variacao12, self.tipo_dispositivo.rotulo_separador_variacao23, self.tipo_dispositivo.rotulo_separador_variacao34, - self.tipo_dispositivo.rotulo_separador_variacao45] + self.tipo_dispositivo.rotulo_separador_variacao45, + ] numero.reverse() formato.reverse() separadores.reverse() - result = '' + result = "" flag_obrigatorio = False for i in range(len(numero)): @@ -1560,74 +1592,71 @@ class Dispositivo(BaseModel, TimestampedMixin): if i + 1 == len(numero) and numero[i] == 0: continue - if i + 1 == len(numero) and \ - (self.tipo_dispositivo.rotulo_ordinal == -1 or - 0 < numero[i] <= self.tipo_dispositivo.rotulo_ordinal): - result = 'º' + result + if i + 1 == len(numero) and ( + self.tipo_dispositivo.rotulo_ordinal == -1 + or 0 < numero[i] <= self.tipo_dispositivo.rotulo_ordinal + ): + result = "º" + result if formato[i] == TipoDispositivo.FNC1: result = separadores[i] + str(numero[i]) + result elif formato[i] == TipoDispositivo.FNCI: - result = separadores[i] + \ - int_to_roman(numero[i]) + result + result = separadores[i] + int_to_roman(numero[i]) + result elif formato[i] == TipoDispositivo.FNCi: - result = separadores[i] + \ - int_to_roman(numero[i]).lower() + result + result = separadores[i] + int_to_roman(numero[i]).lower() + result elif formato[i] == TipoDispositivo.FNCA: - result = separadores[i] + \ - int_to_letter(numero[i]) + result + result = separadores[i] + int_to_letter(numero[i]) + result elif formato[i] == TipoDispositivo.FNCa: - result = separadores[i] + \ - int_to_letter(numero[i]).lower() + result + result = separadores[i] + int_to_letter(numero[i]).lower() + result elif formato[i] == TipoDispositivo.FNC8: - result = separadores[i] + '*' + result + result = separadores[i] + "*" + result elif formato[i] == TipoDispositivo.FNCN: result = separadores[i] + result return result def criar_espaco(self, espaco_a_criar, local=None): - - if local == 'json_add_next': - proximo_bloco = Dispositivo.objects.filter( - ordem__gt=self.ordem, - nivel__lte=self.nivel, - ta_id=self.ta_id).first() - elif local == 'json_add_in': + if local == "json_add_next": proximo_bloco = Dispositivo.objects.filter( - ordem__gt=self.ordem, - nivel__lte=self.nivel + 1, - ta_id=self.ta_id).exclude(auto_inserido=True).first() - elif local == 'json_add_in_with_auto': + ordem__gt=self.ordem, nivel__lte=self.nivel, ta_id=self.ta_id + ).first() + elif local == "json_add_in": + proximo_bloco = ( + Dispositivo.objects.filter( + ordem__gt=self.ordem, nivel__lte=self.nivel + 1, ta_id=self.ta_id + ) + .exclude(auto_inserido=True) + .first() + ) + elif local == "json_add_in_with_auto": proximo_bloco = Dispositivo.objects.filter( - ordem__gt=self.ordem, - nivel__lte=self.nivel + 1, - ta_id=self.ta_id).first() + ordem__gt=self.ordem, nivel__lte=self.nivel + 1, ta_id=self.ta_id + ).first() else: proximo_bloco = Dispositivo.objects.filter( - ordem__gte=self.ordem, - ta_id=self.ta_id).first() + ordem__gte=self.ordem, ta_id=self.ta_id + ).first() if proximo_bloco: ordem = proximo_bloco.ordem - proximo_bloco = Dispositivo.objects.order_by('-ordem').filter( - ordem__gte=ordem, - ta_id=self.ta_id) + proximo_bloco = Dispositivo.objects.order_by("-ordem").filter( + ordem__gte=ordem, ta_id=self.ta_id + ) - proximo_bloco.update(ordem=F('ordem') + 1) + proximo_bloco.update(ordem=F("ordem") + 1) proximo_bloco.update( - ordem=F('ordem') + ( - Dispositivo.INTERVALO_ORDEM * espaco_a_criar - 1)) + ordem=F("ordem") + (Dispositivo.INTERVALO_ORDEM * espaco_a_criar - 1) + ) else: # inserção no fim do ta - ordem_max = Dispositivo.objects.order_by( - 'ordem').filter( - ta_id=self.ta_id).aggregate( - Max('ordem')) - if ordem_max['ordem__max'] is None: - raise Exception( - _('Não existem registros base neste Texto Articulado')) - ordem = ordem_max['ordem__max'] + Dispositivo.INTERVALO_ORDEM + ordem_max = ( + Dispositivo.objects.order_by("ordem") + .filter(ta_id=self.ta_id) + .aggregate(Max("ordem")) + ) + if ordem_max["ordem__max"] is None: + raise Exception(_("Não existem registros base neste Texto Articulado")) + ordem = ordem_max["ordem__max"] + Dispositivo.INTERVALO_ORDEM return ordem def organizar_niveis(self): @@ -1636,20 +1665,19 @@ class Dispositivo(BaseModel, TimestampedMixin): else: self.nivel = self.dispositivo_pai.nivel + 1 - filhos = Dispositivo.objects.filter( - dispositivo_pai_id=self.pk) + filhos = Dispositivo.objects.filter(dispositivo_pai_id=self.pk) for filho in filhos: filho.nivel = self.nivel + 1 filho.save() filho.organizar_niveis() - def get_parents(self, ordem='desc'): + def get_parents(self, ordem="desc"): dp = self p = [] while dp.dispositivo_pai: dp = dp.dispositivo_pai - if ordem == 'desc': + if ordem == "desc": p.append(dp) else: p.insert(0, dp) @@ -1657,47 +1685,61 @@ class Dispositivo(BaseModel, TimestampedMixin): return p def get_parents_asc(self): - return self.get_parents(ordem='asc') + return self.get_parents(ordem="asc") def incrementar_irmaos(self, variacao=0, tipoadd=[], force=True): - if not self.tipo_dispositivo.contagem_continua: - irmaos = list(Dispositivo.objects.filter( - Q(ordem__gt=self.ordem) | Q(dispositivo0=0), - dispositivo_pai_id=self.dispositivo_pai_id, - tipo_dispositivo_id=self.tipo_dispositivo.pk)) + irmaos = list( + Dispositivo.objects.filter( + Q(ordem__gt=self.ordem) | Q(dispositivo0=0), + dispositivo_pai_id=self.dispositivo_pai_id, + tipo_dispositivo_id=self.tipo_dispositivo.pk, + ) + ) elif self.dispositivo_pai is None: - irmaos = list(Dispositivo.objects.filter( - ordem__gt=self.ordem, - ta_id=self.ta_id, - tipo_dispositivo_id=self.tipo_dispositivo.pk)) + irmaos = list( + Dispositivo.objects.filter( + ordem__gt=self.ordem, + ta_id=self.ta_id, + tipo_dispositivo_id=self.tipo_dispositivo.pk, + ) + ) else: # contagem continua restrita a articulacao proxima_articulacao = self.select_next_root() if proxima_articulacao is None: - irmaos = list(Dispositivo.objects.filter( - ordem__gt=self.ordem, - ta_id=self.ta_id, - tipo_dispositivo_id=self.tipo_dispositivo.pk)) + irmaos = list( + Dispositivo.objects.filter( + ordem__gt=self.ordem, + ta_id=self.ta_id, + tipo_dispositivo_id=self.tipo_dispositivo.pk, + ) + ) else: - irmaos = list(Dispositivo.objects.filter( - Q(ordem__gt=self.ordem) & - Q(ordem__lt=proxima_articulacao.ordem), - ta_id=self.ta_id, - tipo_dispositivo_id=self.tipo_dispositivo.pk)) + irmaos = list( + Dispositivo.objects.filter( + Q(ordem__gt=self.ordem) + & Q(ordem__lt=proxima_articulacao.ordem), + ta_id=self.ta_id, + tipo_dispositivo_id=self.tipo_dispositivo.pk, + ) + ) dp_profundidade = self.get_profundidade() - if (not force and not variacao and len(irmaos) > 0 and - irmaos[0].get_numero_completo() > self.get_numero_completo()): + if ( + not force + and not variacao + and len(irmaos) > 0 + and irmaos[0].get_numero_completo() > self.get_numero_completo() + ): return irmaos_a_salvar = [] ultimo_irmao = None for irmao in irmaos: - if irmao.ordem <= self.ordem or irmao.dispositivo0 == 0: irmaos_a_salvar.append(irmao) continue @@ -1709,17 +1751,14 @@ class Dispositivo(BaseModel, TimestampedMixin): if irmao.get_numero_completo() < self.get_numero_completo(): if irmao_profundidade > dp_profundidade: if ultimo_irmao is None: - irmao.transform_in_next( - dp_profundidade - irmao_profundidade) - irmao.transform_in_next( - irmao_profundidade - dp_profundidade) + irmao.transform_in_next(dp_profundidade - irmao_profundidade) + irmao.transform_in_next(irmao_profundidade - dp_profundidade) else: - irmao.set_numero_completo( - ultimo_irmao.get_numero_completo()) + irmao.set_numero_completo(ultimo_irmao.get_numero_completo()) irmao.transform_in_next( - irmao_profundidade - - ultimo_irmao.get_profundidade()) + irmao_profundidade - ultimo_irmao.get_profundidade() + ) ultimo_irmao = irmao else: @@ -1734,11 +1773,13 @@ class Dispositivo(BaseModel, TimestampedMixin): irmao.rotulo = irmao.rotulo_padrao() irmaos_a_salvar.append(irmao) else: - if dp_profundidade < irmao_profundidade and \ - dp_profundidade > 0 and \ - self.get_numero_completo()[:dp_profundidade] >= \ - irmao.get_numero_completo()[:dp_profundidade] and\ - ultimo_irmao is None: + if ( + dp_profundidade < irmao_profundidade + and dp_profundidade > 0 + and self.get_numero_completo()[:dp_profundidade] + >= irmao.get_numero_completo()[:dp_profundidade] + and ultimo_irmao is None + ): break else: ultimo_irmao = irmao @@ -1750,14 +1791,16 @@ class Dispositivo(BaseModel, TimestampedMixin): irmaos_a_salvar.reverse() for irmao in irmaos_a_salvar: - if (irmao.dispositivo0 == 0 and - irmao.ordem <= self.ordem) and variacao == 0: + if ( + irmao.dispositivo0 == 0 and irmao.ordem <= self.ordem + ) and variacao == 0: irmao.dispositivo0 = 1 irmao.rotulo = irmao.rotulo_padrao() self.dispositivo0 = 2 self.rotulo = self.rotulo_padrao() - elif (irmao.dispositivo0 == 0 and - irmao.ordem > self.ordem) and variacao == 0: + elif ( + irmao.dispositivo0 == 0 and irmao.ordem > self.ordem + ) and variacao == 0: irmao.dispositivo0 = 2 irmao.rotulo = irmao.rotulo_padrao() self.dispositivo0 = 1 @@ -1767,8 +1810,7 @@ class Dispositivo(BaseModel, TimestampedMixin): irmao.save() def select_roots(self): - return Dispositivo.objects.order_by( - 'ordem').filter(nivel=0, ta_id=self.ta_id) + return Dispositivo.objects.order_by("ordem").filter(nivel=0, ta_id=self.ta_id) def select_next_root(self): return self.select_roots().filter(ordem__gt=self.ordem).first() @@ -1782,14 +1824,13 @@ class Dispositivo(BaseModel, TimestampedMixin): # pp possiveis_pais if not perfil_pk: - perfis = PerfilEstruturalTextoArticulado.objects.filter( - padrao=True)[:1] + perfis = PerfilEstruturalTextoArticulado.objects.filter(padrao=True)[:1] if perfis.exists(): perfil_pk = perfis[0].pk pp = self.tipo_dispositivo.possiveis_pais.filter( - pai=self.dispositivo_pai.tipo_dispositivo, - perfil_id=perfil_pk) + pai=self.dispositivo_pai.tipo_dispositivo, perfil_id=perfil_pk + ) if pp.exists(): if pp[0].filho_de_insercao_automatica: @@ -1812,10 +1853,9 @@ class Dispositivo(BaseModel, TimestampedMixin): dp.tipo_dispositivo = tipo_base - dp.set_numero_completo( - dispositivo_base.get_numero_completo()) + dp.set_numero_completo(dispositivo_base.get_numero_completo()) dp.nivel = dispositivo_base.nivel - dp.texto = '' + dp.texto = "" dp.visibilidade = True # dp.auto_inserido = dispositivo_base.auto_inserido dp.ta = dispositivo_base.ta @@ -1829,8 +1869,9 @@ class Dispositivo(BaseModel, TimestampedMixin): dp.dispositivo_atualizador = b.dispositivo_atualizador if dp.ta_publicado: - dp.ordem_bloco_atualizador = b.ordem_bloco_atualizador + \ - Dispositivo.INTERVALO_ORDEM + dp.ordem_bloco_atualizador = ( + b.ordem_bloco_atualizador + Dispositivo.INTERVALO_ORDEM + ) dp.dispositivo_vigencia = dispositivo_base.dispositivo_vigencia if dp.dispositivo_vigencia: @@ -1850,97 +1891,125 @@ class Dispositivo(BaseModel, TimestampedMixin): @staticmethod def set_numero_for_add_in(dispositivo_base, dispositivo, tipo_base): - if tipo_base.contagem_continua: raiz = dispositivo_base.get_raiz() - disps = Dispositivo.objects.order_by('-ordem').filter( + disps = Dispositivo.objects.order_by("-ordem").filter( tipo_dispositivo_id=tipo_base.pk, ordem__lte=dispositivo_base.ordem, ordem__gt=raiz.ordem, - ta_id=dispositivo_base.ta_id)[:1] + ta_id=dispositivo_base.ta_id, + )[:1] if disps.exists(): - dispositivo.set_numero_completo( - disps[0].get_numero_completo()) + dispositivo.set_numero_completo(disps[0].get_numero_completo()) # dispositivo.transform_in_next() else: - dispositivo.set_numero_completo([0, 0, 0, 0, 0, 0, ]) + dispositivo.set_numero_completo( + [ + 0, + 0, + 0, + 0, + 0, + 0, + ] + ) else: - if ';' in tipo_base.rotulo_prefixo_texto: - + if ";" in tipo_base.rotulo_prefixo_texto: if dispositivo != dispositivo_base: irmaos_mesmo_tipo = Dispositivo.objects.filter( - tipo_dispositivo=tipo_base, - dispositivo_pai=dispositivo_base) - - dispositivo.set_numero_completo([ - 1 if irmaos_mesmo_tipo.exists() else 0, - 0, 0, 0, 0, 0, ]) + tipo_dispositivo=tipo_base, dispositivo_pai=dispositivo_base + ) + + dispositivo.set_numero_completo( + [ + 1 if irmaos_mesmo_tipo.exists() else 0, + 0, + 0, + 0, + 0, + 0, + ] + ) else: - dispositivo.set_numero_completo([0, 0, 0, 0, 0, 0, ]) + dispositivo.set_numero_completo( + [ + 0, + 0, + 0, + 0, + 0, + 0, + ] + ) else: - dispositivo.set_numero_completo([1, 0, 0, 0, 0, 0, ]) + dispositivo.set_numero_completo( + [ + 1, + 0, + 0, + 0, + 0, + 0, + ] + ) def ordenar_bloco_alteracao(self): - if not self.tipo_dispositivo.dispositivo_de_articulacao or\ - not self.tipo_dispositivo.dispositivo_de_alteracao: + if ( + not self.tipo_dispositivo.dispositivo_de_articulacao + or not self.tipo_dispositivo.dispositivo_de_alteracao + ): return - filhos = Dispositivo.objects.order_by( - 'ordem_bloco_atualizador').filter( - Q(dispositivo_pai_id=self.pk) | - Q(dispositivo_atualizador_id=self.pk)) + filhos = Dispositivo.objects.order_by("ordem_bloco_atualizador").filter( + Q(dispositivo_pai_id=self.pk) | Q(dispositivo_atualizador_id=self.pk) + ) if not filhos.exists(): return ordem_max = filhos.last().ordem_bloco_atualizador - filhos.update( - ordem_bloco_atualizador=F('ordem_bloco_atualizador') + ordem_max) + filhos.update(ordem_bloco_atualizador=F("ordem_bloco_atualizador") + ordem_max) - filhos = filhos.values_list( - 'pk', flat=True).order_by('ordem_bloco_atualizador') + filhos = filhos.values_list("pk", flat=True).order_by("ordem_bloco_atualizador") count = 0 for d in filhos: count += Dispositivo.INTERVALO_ORDEM - Dispositivo.objects.filter(pk=d).update( - ordem_bloco_atualizador=count) + Dispositivo.objects.filter(pk=d).update(ordem_bloco_atualizador=count) class Vide(TimestampedMixin): - texto = models.TextField(verbose_name=_('Texto do Vide')) + texto = models.TextField(verbose_name=_("Texto do Vide")) tipo = models.ForeignKey( - TipoVide, - verbose_name=_('Tipo do Vide'), - on_delete=models.PROTECT + TipoVide, verbose_name=_("Tipo do Vide"), on_delete=models.PROTECT ) dispositivo_base = models.ForeignKey( Dispositivo, - verbose_name=_('Dispositivo Base'), - related_name='dispositivo_base_set', - on_delete=models.PROTECT + verbose_name=_("Dispositivo Base"), + related_name="dispositivo_base_set", + on_delete=models.PROTECT, ) dispositivo_ref = models.ForeignKey( Dispositivo, - related_name='dispositivo_citado_set', - verbose_name=_('Dispositivo Referido'), - on_delete=models.PROTECT + related_name="dispositivo_citado_set", + verbose_name=_("Dispositivo Referido"), + on_delete=models.PROTECT, ) class Meta: - verbose_name = _('Vide') - verbose_name_plural = _('Vides') - ordering = ('id',) - unique_together = ['dispositivo_base', 'dispositivo_ref', 'tipo'] + verbose_name = _("Vide") + verbose_name_plural = _("Vides") + ordering = ("id",) + unique_together = ["dispositivo_base", "dispositivo_ref", "tipo"] def __str__(self): - return _('Vide %s') % self.texto + return _("Vide %s") % self.texto NPRIV = 1 @@ -1948,69 +2017,58 @@ NINST = 2 NPUBL = 3 NOTAS_PUBLICIDADE_CHOICES = ( # Only the owner of the note has visibility. - (NPRIV, _('Nota Privada')), + (NPRIV, _("Nota Privada")), # All authenticated users have visibility. - (NINST, _('Nota Institucional')), + (NINST, _("Nota Institucional")), # All users have visibility. - (NPUBL, _('Nota Pública')), + (NPUBL, _("Nota Pública")), ) class Nota(TimestampedMixin): - NPRIV = 1 NINST = 2 NPUBL = 3 titulo = models.CharField( - verbose_name=_('Título'), - max_length=100, - default='', - blank=True + verbose_name=_("Título"), max_length=100, default="", blank=True ) - texto = models.TextField(verbose_name=_('Texto')) + texto = models.TextField(verbose_name=_("Texto")) url_externa = models.URLField( - max_length=1024, - blank=True, - verbose_name=_('Url externa') + max_length=1024, blank=True, verbose_name=_("Url externa") ) - publicacao = models.DateTimeField(verbose_name=_('Data de Publicação')) + publicacao = models.DateTimeField(verbose_name=_("Data de Publicação")) - efetividade = models.DateTimeField(verbose_name=_('Data de Efeito')) + efetividade = models.DateTimeField(verbose_name=_("Data de Efeito")) tipo = models.ForeignKey( - TipoNota, - verbose_name=_('Tipo da Nota'), - on_delete=models.PROTECT + TipoNota, verbose_name=_("Tipo da Nota"), on_delete=models.PROTECT ) dispositivo = models.ForeignKey( Dispositivo, - verbose_name=_('Dispositivo da Nota'), - related_name='dispositivo_nota_set', - on_delete=models.PROTECT + verbose_name=_("Dispositivo da Nota"), + related_name="dispositivo_nota_set", + on_delete=models.PROTECT, ) owner = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Dono da Nota'), - on_delete=models.PROTECT + verbose_name=_("Dono da Nota"), + on_delete=models.PROTECT, ) publicidade = models.PositiveSmallIntegerField( - choices=NOTAS_PUBLICIDADE_CHOICES, - verbose_name=_('Nível de Publicidade')) + choices=NOTAS_PUBLICIDADE_CHOICES, verbose_name=_("Nível de Publicidade") + ) class Meta: - verbose_name = _('Nota') - verbose_name_plural = _('Notas') - ordering = ['-publicacao', '-modified'] + verbose_name = _("Nota") + verbose_name_plural = _("Notas") + ordering = ["-publicacao", "-modified"] def __str__(self): - return '%s: %s' % ( - self.tipo, - self.get_publicidade_display() - ) + return "%s: %s" % (self.tipo, self.get_publicidade_display()) diff --git a/sapl/compilacao/templatetags/compilacao_filters.py b/sapl/compilacao/templatetags/compilacao_filters.py index 0e8d896ae..e6e652050 100644 --- a/sapl/compilacao/templatetags/compilacao_filters.py +++ b/sapl/compilacao/templatetags/compilacao_filters.py @@ -1,4 +1,3 @@ - from django import template from django.core.signing import Signer from django.db.models import Q @@ -11,7 +10,6 @@ register = template.Library() class DispositivoTreeNode(template.Node): - def __init__(self, template_nodes, dispositivo_list_var): self.template_nodes = template_nodes self.dispositivo_list_var = dispositivo_list_var @@ -20,103 +18,108 @@ class DispositivoTreeNode(template.Node): bits_alts = [] bits_filhos = [] context.push() - for child in node['alts']: + for child in node["alts"]: bits_alts.append(self._render_node(context, child)) - for child in node['filhos']: + for child in node["filhos"]: bits_filhos.append(self._render_node(context, child)) - context['node'] = node - context['alts'] = mark_safe(''.join(bits_alts)) - context['filhos'] = mark_safe(''.join(bits_filhos)) + context["node"] = node + context["alts"] = mark_safe("".join(bits_alts)) + context["filhos"] = mark_safe("".join(bits_filhos)) rendered = self.template_nodes.render(context) context.pop() return rendered def render(self, context): dispositivo_list_var = self.dispositivo_list_var.resolve(context) - bits = [self._render_node(context, node) - for node in dispositivo_list_var] - return ''.join(bits) + bits = [self._render_node(context, node) for node in dispositivo_list_var] + return "".join(bits) @register.tag def dispositivotree(parser, token): - bits = token.contents.split() if len(bits) != 2: - raise template.TemplateSyntaxError( - _('%s tag requires a queryset') % bits[0]) + raise template.TemplateSyntaxError(_("%s tag requires a queryset") % bits[0]) dispositivo_list_var = template.Variable(bits[1]) - template_nodes = parser.parse(('enddispositivotree',)) + template_nodes = parser.parse(("enddispositivotree",)) parser.delete_first_token() return DispositivoTreeNode(template_nodes, dispositivo_list_var) + # -------------------------------------------------------------- @register.filter def get_bloco_atualizador(pk_atualizador): - return Dispositivo.objects.order_by('ordem_bloco_atualizador').filter( - Q(dispositivo_pai_id=pk_atualizador) | - Q(dispositivo_atualizador_id=pk_atualizador)).select_related() + return ( + Dispositivo.objects.order_by("ordem_bloco_atualizador") + .filter( + Q(dispositivo_pai_id=pk_atualizador) + | Q(dispositivo_atualizador_id=pk_atualizador) + ) + .select_related() + ) @register.simple_tag def dispositivo_desativado(dispositivo, inicio_vigencia, fim_vigencia): if dispositivo.dispositivo_de_revogacao: - return 'revogado' + return "revogado" if inicio_vigencia and fim_vigencia: if dispositivo.fim_vigencia is None: - return '' + return "" elif dispositivo.fim_vigencia >= fim_vigencia: - return '' - return 'desativado' + return "" + return "desativado" else: if dispositivo.fim_vigencia is not None: - return 'desativado' - return '' + return "desativado" + return "" @register.simple_tag def nota_automatica(dispositivo, ta_pub_list): - - if dispositivo.ta_publicado and dispositivo.dispositivo_atualizador is not None and dispositivo.dispositivo_atualizador.dispositivo_pai is not None: + if ( + dispositivo.ta_publicado + and dispositivo.dispositivo_atualizador is not None + and dispositivo.dispositivo_atualizador.dispositivo_pai is not None + ): d = dispositivo.dispositivo_atualizador.dispositivo_pai if d.auto_inserido: d = d.dispositivo_pai - ta_publicado = ta_pub_list[dispositivo.ta_publicado_id] if\ - ta_pub_list else dispositivo.ta_publicado + ta_publicado = ( + ta_pub_list[dispositivo.ta_publicado_id] + if ta_pub_list + else dispositivo.ta_publicado + ) if dispositivo.dispositivo_de_revogacao: - return _('Revogado pelo %s - %s.') % ( - d, ta_publicado) + return _("Revogado pelo %s - %s.") % (d, ta_publicado) elif not dispositivo.dispositivo_substituido_id: - return _('Inclusão feita pelo %s - %s.') % ( - d, ta_publicado) + return _("Inclusão feita pelo %s - %s.") % (d, ta_publicado) else: if dispositivo.tipo_dispositivo.dispositivo_de_articulacao: - return _('Alteração de rótulo feita pelo %s - %s.') % ( - d, ta_publicado) + return _("Alteração de rótulo feita pelo %s - %s.") % (d, ta_publicado) else: - return _('Alteração feita pelo %s - %s.') % ( - d, ta_publicado) + return _("Alteração feita pelo %s - %s.") % (d, ta_publicado) - return '' + return "" @register.simple_tag def set_nivel_old(view, value): view.flag_nivel_old = value - return '' + return "" @register.simple_tag def close_div(value_max, value_min, varr): - return mark_safe('' * (int(value_max) - int(value_min) + 1 + varr)) + return mark_safe("" * (int(value_max) - int(value_min) + 1 + varr)) @register.filter @@ -124,7 +127,8 @@ def get_sign_vigencia(value): string = "%s,%s,%s" % ( value.ta_publicado_id if value.ta_publicado_id else 0, value.inicio_vigencia, - value.fim_vigencia) + value.fim_vigencia, + ) signer = Signer() return signer.sign(str(string)) @@ -142,8 +146,7 @@ def isinst(value, class_str): @register.filter def render_actions_head(view, d_atual): - - if view.__class__.__name__ != 'DispositivoSimpleEditView': + if view.__class__.__name__ != "DispositivoSimpleEditView": return False # Menu @@ -160,45 +163,51 @@ def render_actions_head(view, d_atual): @register.filter def short_string(str, length): if len(str) > length: - return str[:length] + '...' + return str[:length] + "..." else: return str @register.filter def nomenclatura(d): - result = '' - if d.rotulo != '': - if d.tipo_dispositivo.rotulo_prefixo_texto != '': + result = "" + if d.rotulo != "": + if d.tipo_dispositivo.rotulo_prefixo_texto != "": result = d.rotulo else: - result = '(' + d.tipo_dispositivo.nome + ' ' + \ - d.rotulo + ')' + result = "(" + d.tipo_dispositivo.nome + " " + d.rotulo + ")" else: r = d.rotulo_padrao() if r: - r += ' ' - result = '(' + d.tipo_dispositivo.nome + r + ')' + r += " " + result = "(" + d.tipo_dispositivo.nome + r + ")" return result def update_dispositivos_parents(dpts_parents, ta_id): - - dpts = Dispositivo.objects.order_by('ordem').filter( - ta_id=ta_id).values_list( - 'pk', 'dispositivo_pai_id', 'rotulo', 'tipo_dispositivo__nome', - 'tipo_dispositivo__rotulo_prefixo_texto') + dpts = ( + Dispositivo.objects.order_by("ordem") + .filter(ta_id=ta_id) + .values_list( + "pk", + "dispositivo_pai_id", + "rotulo", + "tipo_dispositivo__nome", + "tipo_dispositivo__rotulo_prefixo_texto", + ) + ) for d in dpts: - dpts_parents[str(d[0])] = { - 'd': d, 'p': [], 'h': None} + dpts_parents[str(d[0])] = {"d": d, "p": [], "h": None} def parents(k): - pai = dpts_parents[str(k)]['d'][1] - p = dpts_parents[str(k)]['p'] + pai = dpts_parents[str(k)]["d"][1] + p = dpts_parents[str(k)]["p"] if not p: if pai: - parent_k = [pai, ] + parents(pai) + parent_k = [ + pai, + ] + parents(pai) else: parent_k = [] else: @@ -207,12 +216,12 @@ def update_dispositivos_parents(dpts_parents, ta_id): return parent_k for k in dpts_parents: - dpts_parents[str(k)]['p'] = parents(k) + dpts_parents[str(k)]["p"] = parents(k) @register.simple_tag def heranca(request, d, ignore_ultimo=0, ignore_primeiro=0): - ta_dpts_parents = request.session.get('herancas') + ta_dpts_parents = request.session.get("herancas") if not ta_dpts_parents: ta_dpts_parents = {} @@ -225,7 +234,7 @@ def heranca(request, d, ignore_ultimo=0, ignore_primeiro=0): ta_dpts_parents[ta_id] = dpts_parents update_dispositivos_parents(dpts_parents, ta_id) - herancas_fila = request.session.get('herancas_fila') + herancas_fila = request.session.get("herancas_fila") if not herancas_fila: herancas_fila = [] @@ -234,22 +243,21 @@ def heranca(request, d, ignore_ultimo=0, ignore_primeiro=0): ta_remove = herancas_fila.pop(0) del ta_dpts_parents[str(ta_remove)] - request.session['herancas_fila'] = herancas_fila - request.session['herancas'] = ta_dpts_parents + request.session["herancas_fila"] = herancas_fila + request.session["herancas"] = ta_dpts_parents - h = ta_dpts_parents[ta_id][d_pk]['h'] + h = ta_dpts_parents[ta_id][d_pk]["h"] if h: return h dpts_parents = ta_dpts_parents[ta_id] - parents = dpts_parents[d_pk]['p'] - result = '' + parents = dpts_parents[d_pk]["p"] + result = "" if parents: pk_last = parents[-1] for pk in parents: - if ignore_ultimo and pk == pk_last: break @@ -257,23 +265,21 @@ def heranca(request, d, ignore_ultimo=0, ignore_primeiro=0): ignore_primeiro = 0 continue - p = dpts_parents[str(pk)]['d'] + p = dpts_parents[str(pk)]["d"] - if p[4] != '': - result = p[2] + ' ' + result + if p[4] != "": + result = p[2] + " " + result else: - result = '(' + p[3] + ' ' + \ - p[2] + ')' + ' ' + result + result = "(" + p[3] + " " + p[2] + ")" + " " + result - dpts_parents[d_pk]['h'] = result + dpts_parents[d_pk]["h"] = result return result @register.simple_tag def nomenclatura_heranca(d, ignore_ultimo=0, ignore_primeiro=0): - result = '' + result = "" while d is not None: - if ignore_ultimo and d.dispositivo_pai is None: break if ignore_primeiro: @@ -281,22 +287,27 @@ def nomenclatura_heranca(d, ignore_ultimo=0, ignore_primeiro=0): d = d.dispositivo_pai continue - if d.rotulo != '': - if d.tipo_dispositivo.rotulo_prefixo_texto != '': - result = d.rotulo + ' ' + result + if d.rotulo != "": + if d.tipo_dispositivo.rotulo_prefixo_texto != "": + result = d.rotulo + " " + result else: - result = '(' + d.tipo_dispositivo.nome + ' ' + \ - d.rotulo + ')' + ' ' + result + result = ( + "(" + d.tipo_dispositivo.nome + " " + d.rotulo + ")" + " " + result + ) else: - result = '(' + d.tipo_dispositivo.nome + \ - d.rotulo_padrao() + ')' + ' ' + result + result = ( + "(" + d.tipo_dispositivo.nome + d.rotulo_padrao() + ")" + " " + result + ) d = d.dispositivo_pai return result + @register.filter def list(obj): - return [obj, ] + return [ + obj, + ] @register.filter diff --git a/sapl/compilacao/tests/test_compilacao.py b/sapl/compilacao/tests/test_compilacao.py index fec382392..345d8d749 100644 --- a/sapl/compilacao/tests/test_compilacao.py +++ b/sapl/compilacao/tests/test_compilacao.py @@ -1,104 +1,85 @@ import pytest from model_bakery import baker -from sapl.compilacao.models import PerfilEstruturalTextoArticulado -from sapl.compilacao.models import TipoTextoArticulado -from sapl.compilacao.models import TextoArticulado, TipoNota -from sapl.compilacao.models import TipoVide, TipoDispositivo -from sapl.compilacao.models import TipoDispositivoRelationship +from sapl.compilacao.models import (PerfilEstruturalTextoArticulado, + TextoArticulado, TipoDispositivo, + TipoDispositivoRelationship, TipoNota, + TipoTextoArticulado, TipoVide) @pytest.mark.django_db(transaction=False) def test_perfil_estrutural_texto_articulado_model(): perfil_estrutural_texto_articulado = baker.make( - PerfilEstruturalTextoArticulado, - nome='Teste_Nome_Perfil', - sigla='TSPETA') + PerfilEstruturalTextoArticulado, nome="Teste_Nome_Perfil", sigla="TSPETA" + ) - assert perfil_estrutural_texto_articulado.nome == 'Teste_Nome_Perfil' - assert perfil_estrutural_texto_articulado.sigla == 'TSPETA' + assert perfil_estrutural_texto_articulado.nome == "Teste_Nome_Perfil" + assert perfil_estrutural_texto_articulado.sigla == "TSPETA" @pytest.mark.django_db(transaction=False) def test_tipo_texto_articulado_model(): tipo_texto_articulado = baker.make( - TipoTextoArticulado, - sigla='TTP', - descricao='T_Desc_Tipo_Texto_Articulado' + TipoTextoArticulado, sigla="TTP", descricao="T_Desc_Tipo_Texto_Articulado" ) - assert tipo_texto_articulado.sigla == 'TTP' - assert tipo_texto_articulado.descricao == 'T_Desc_Tipo_Texto_Articulado' + assert tipo_texto_articulado.sigla == "TTP" + assert tipo_texto_articulado.descricao == "T_Desc_Tipo_Texto_Articulado" @pytest.mark.django_db(transaction=False) def test_texto_articulado_model(): texto_articulado = baker.make( TextoArticulado, - ementa='Teste_Ementa_Texto_Articulado', - numero='12345678', + ementa="Teste_Ementa_Texto_Articulado", + numero="12345678", ano=2016, ) - assert texto_articulado.ementa == 'Teste_Ementa_Texto_Articulado' - assert texto_articulado.numero == '12345678' + assert texto_articulado.ementa == "Teste_Ementa_Texto_Articulado" + assert texto_articulado.numero == "12345678" assert texto_articulado.ano == 2016 @pytest.mark.django_db(transaction=False) def test_tipo_nota_model(): - tipo_nota = baker.make( - TipoNota, - sigla='TTN', - nome='Teste_Nome_Tipo_Nota' - ) + tipo_nota = baker.make(TipoNota, sigla="TTN", nome="Teste_Nome_Tipo_Nota") - assert tipo_nota.sigla == 'TTN' - assert tipo_nota.nome == 'Teste_Nome_Tipo_Nota' + assert tipo_nota.sigla == "TTN" + assert tipo_nota.nome == "Teste_Nome_Tipo_Nota" @pytest.mark.django_db(transaction=False) def test_tipo_vide_model(): - tipo_vide = baker.make( - TipoVide, - sigla='TTV', - nome='Teste_Nome_Tipo_Vide' - ) + tipo_vide = baker.make(TipoVide, sigla="TTV", nome="Teste_Nome_Tipo_Vide") - assert tipo_vide.sigla == 'TTV' - assert tipo_vide.nome == 'Teste_Nome_Tipo_Vide' + assert tipo_vide.sigla == "TTV" + assert tipo_vide.nome == "Teste_Nome_Tipo_Vide" @pytest.mark.django_db(transaction=False) def test_tipo_dispositivo_model(): tipo_dispositivo = baker.make( - TipoDispositivo, - nome='Teste_Nome_Tipo_Dispositivo', - rotulo_ordinal=0 + TipoDispositivo, nome="Teste_Nome_Tipo_Dispositivo", rotulo_ordinal=0 ) - assert tipo_dispositivo.nome == 'Teste_Nome_Tipo_Dispositivo' + assert tipo_dispositivo.nome == "Teste_Nome_Tipo_Dispositivo" assert tipo_dispositivo.rotulo_ordinal == 0 @pytest.mark.django_db(transaction=False) def test_tipo_dispositivo_relationship_model(): tipo_dispositivo_pai = baker.make( - TipoDispositivo, - nome='Tipo_Dispositivo_Pai', - rotulo_ordinal=0 + TipoDispositivo, nome="Tipo_Dispositivo_Pai", rotulo_ordinal=0 ) t_dispositivo_filho = baker.make( - TipoDispositivo, - nome='Tipo_Dispositivo_Filho', - rotulo_ordinal=0 + TipoDispositivo, nome="Tipo_Dispositivo_Filho", rotulo_ordinal=0 ) p_e_texto_articulado = baker.make( - PerfilEstruturalTextoArticulado, - nome='Teste_Nome_Perfil', - sigla='TSPETA') + PerfilEstruturalTextoArticulado, nome="Teste_Nome_Perfil", sigla="TSPETA" + ) tipo_dispositivo_relationship = baker.make( TipoDispositivoRelationship, diff --git a/sapl/compilacao/tests/test_tipo_texto_articulado_form.py b/sapl/compilacao/tests/test_tipo_texto_articulado_form.py index 8c58f6cfd..3476a7e33 100644 --- a/sapl/compilacao/tests/test_tipo_texto_articulado_form.py +++ b/sapl/compilacao/tests/test_tipo_texto_articulado_form.py @@ -14,10 +14,10 @@ def test_valida_campos_obrigatorios_tipo_texto_articulado_form(): errors = form.errors - assert errors['sigla'] == [_('Este campo é obrigatório.')] - assert errors['descricao'] == [_('Este campo é obrigatório.')] - assert errors['participacao_social'] == [_('Este campo é obrigatório.')] - assert errors['publicacao_func'] == [_('Este campo é obrigatório.')] + assert errors["sigla"] == [_("Este campo é obrigatório.")] + assert errors["descricao"] == [_("Este campo é obrigatório.")] + assert errors["participacao_social"] == [_("Este campo é obrigatório.")] + assert errors["publicacao_func"] == [_("Este campo é obrigatório.")] assert len(errors) == 4 @@ -29,12 +29,12 @@ def test_valida_campos_obrigatorios_nota_form(): errors = form.errors - assert errors['texto'] == [_('Este campo é obrigatório')] - assert errors['publicidade'] == [_('Este campo é obrigatório.')] - assert errors['tipo'] == [_('Este campo é obrigatório.')] - assert errors['publicacao'] == [_('Este campo é obrigatório')] - assert errors['efetividade'] == [_('Este campo é obrigatório')] - assert errors['dispositivo'] == [_('Este campo é obrigatório.')] + assert errors["texto"] == [_("Este campo é obrigatório")] + assert errors["publicidade"] == [_("Este campo é obrigatório.")] + assert errors["tipo"] == [_("Este campo é obrigatório.")] + assert errors["publicacao"] == [_("Este campo é obrigatório")] + assert errors["efetividade"] == [_("Este campo é obrigatório")] + assert errors["dispositivo"] == [_("Este campo é obrigatório.")] assert len(errors) == 6 @@ -43,15 +43,18 @@ def test_valida_campos_obrigatorios_nota_form(): def test_nota_form_invalido(): tipo = baker.make(TipoNota) - form = forms.NotaForm(data={'titulo': 'titulo', - 'texto': 'teste', - 'url_externa': 'www.test.com', - 'publicidade': 'publicidade', - 'tipo': str(tipo.pk), - 'publicacao': '10/05/2017', - 'efetividade': '10/05/2017', - 'dispositivo': 'dispositivo', - 'pk': 'pk' - }) + form = forms.NotaForm( + data={ + "titulo": "titulo", + "texto": "teste", + "url_externa": "www.test.com", + "publicidade": "publicidade", + "tipo": str(tipo.pk), + "publicacao": "10/05/2017", + "efetividade": "10/05/2017", + "dispositivo": "dispositivo", + "pk": "pk", + } + ) assert not form.is_valid() diff --git a/sapl/compilacao/urls.py b/sapl/compilacao/urls.py index 10947b756..0c616c8d6 100644 --- a/sapl/compilacao/urls.py +++ b/sapl/compilacao/urls.py @@ -2,117 +2,139 @@ from django.urls import include, path, re_path from sapl.compilacao import views from sapl.compilacao.views import (TipoDispositivoCrud, TipoNotaCrud, - TipoPublicacaoCrud, TipoVideCrud, - VeiculoPublicacaoCrud, - TipoTextoArticuladoCrud) + TipoPublicacaoCrud, TipoTextoArticuladoCrud, + TipoVideCrud, VeiculoPublicacaoCrud) from .apps import AppConfig app_name = AppConfig.name urlpatterns_compilacao = [ - path('', views.TaListView.as_view(), name='ta_list'), - path('create', views.TaCreateView.as_view(), name='ta_create'), - path('', views.TaDetailView.as_view(), name='ta_detail'), - path('/edit', - views.TaUpdateView.as_view(), name='ta_edit'), - path('/delete', - views.TaDeleteView.as_view(), name='ta_delete'), - - - path('/text', - views.TextView.as_view(), name='ta_text'), - - re_path(r'^(?P[0-9]+)/text/vigencia/(?P.*:[A-Za-z0-9_-]+)/$', - views.TextView.as_view(), name='ta_vigencia'), - - re_path(r'^(?P[0-9]+)/text/edit', - views.TextEditView.as_view(), name='ta_text_edit'), - - re_path(r'^(?P[0-9]+)/text/notifications', - views.TextNotificacoesView.as_view(), name='ta_text_notificacoes'), - - path('/text//', - views.DispositivoView.as_view(), name='dispositivo'), - - re_path(r'^(?P[0-9]+)/text/(?P[0-9]+)/refresh', + path("", views.TaListView.as_view(), name="ta_list"), + path("create", views.TaCreateView.as_view(), name="ta_create"), + path("", views.TaDetailView.as_view(), name="ta_detail"), + path("/edit", views.TaUpdateView.as_view(), name="ta_edit"), + path("/delete", views.TaDeleteView.as_view(), name="ta_delete"), + path("/text", views.TextView.as_view(), name="ta_text"), + re_path( + r"^(?P[0-9]+)/text/vigencia/(?P.*:[A-Za-z0-9_-]+)/$", + views.TextView.as_view(), + name="ta_vigencia", + ), + re_path( + r"^(?P[0-9]+)/text/edit", + views.TextEditView.as_view(), + name="ta_text_edit", + ), + re_path( + r"^(?P[0-9]+)/text/notifications", + views.TextNotificacoesView.as_view(), + name="ta_text_notificacoes", + ), + path( + "/text//", + views.DispositivoView.as_view(), + name="dispositivo", + ), + re_path( + r"^(?P[0-9]+)/text/(?P[0-9]+)/refresh", views.DispositivoDinamicEditView.as_view(), - name='dispositivo_refresh'), - - path('/text//edit', - views.DispositivoEdicaoBasicaView.as_view(), name='dispositivo_edit'), - - re_path(r'^(?P[0-9]+)/text/(?P[0-9]+)/edit/vigencia', + name="dispositivo_refresh", + ), + path( + "/text//edit", + views.DispositivoEdicaoBasicaView.as_view(), + name="dispositivo_edit", + ), + re_path( + r"^(?P[0-9]+)/text/(?P[0-9]+)/edit/vigencia", views.DispositivoEdicaoVigenciaView.as_view(), - name='dispositivo_edit_vigencia'), - - re_path(r'^(?P[0-9]+)/text/(?P[0-9]+)/edit/alteracao', + name="dispositivo_edit_vigencia", + ), + re_path( + r"^(?P[0-9]+)/text/(?P[0-9]+)/edit/alteracao", views.DispositivoEdicaoAlteracaoView.as_view(), - name='dispositivo_edit_alteracao'), - - re_path(r'^(?P[0-9]+)/text/(?P[0-9]+)/edit/definidor_vigencia', + name="dispositivo_edit_alteracao", + ), + re_path( + r"^(?P[0-9]+)/text/(?P[0-9]+)/edit/definidor_vigencia", views.DispositivoDefinidorVigenciaView.as_view(), - name='dispositivo_edit_definidor_vigencia'), - - - path('/text//nota/create', - views.NotasCreateView.as_view(), name='nota_create'), - - path('/text//nota//edit', - views.NotasEditView.as_view(), name='nota_edit'), - - path('/text//nota//delete', - views.NotasDeleteView.as_view(), name='nota_delete'), - - path('/text//vide/create', - views.VideCreateView.as_view(), name='vide_create'), - - path('/text//vide//edit', - views.VideEditView.as_view(), name='vide_edit'), - - path('/text//vide//delete', - views.VideDeleteView.as_view(), name='vide_delete'), - - path('search_fragment_form', + name="dispositivo_edit_definidor_vigencia", + ), + path( + "/text//nota/create", + views.NotasCreateView.as_view(), + name="nota_create", + ), + path( + "/text//nota//edit", + views.NotasEditView.as_view(), + name="nota_edit", + ), + path( + "/text//nota//delete", + views.NotasDeleteView.as_view(), + name="nota_delete", + ), + path( + "/text//vide/create", + views.VideCreateView.as_view(), + name="vide_create", + ), + path( + "/text//vide//edit", + views.VideEditView.as_view(), + name="vide_edit", + ), + path( + "/text//vide//delete", + views.VideDeleteView.as_view(), + name="vide_delete", + ), + path( + "search_fragment_form", views.DispositivoSearchFragmentFormView.as_view(), - name='dispositivo_fragment_form'), - - path('search_form', + name="dispositivo_fragment_form", + ), + path( + "search_form", views.DispositivoSearchModalView.as_view(), - name='dispositivo_search_form'), - - - path('/publicacao', - views.PublicacaoListView.as_view(), name='ta_pub_list'), - path('/publicacao/create', - views.PublicacaoCreateView.as_view(), name='ta_pub_create'), - path('/publicacao/', - views.PublicacaoDetailView.as_view(), name='ta_pub_detail'), - path('/publicacao//edit', - views.PublicacaoUpdateView.as_view(), name='ta_pub_edit'), - path('/publicacao//delete', - views.PublicacaoDeleteView.as_view(), name='ta_pub_delete'), - - - + name="dispositivo_search_form", + ), + path( + "/publicacao", views.PublicacaoListView.as_view(), name="ta_pub_list" + ), + path( + "/publicacao/create", + views.PublicacaoCreateView.as_view(), + name="ta_pub_create", + ), + path( + "/publicacao/", + views.PublicacaoDetailView.as_view(), + name="ta_pub_detail", + ), + path( + "/publicacao//edit", + views.PublicacaoUpdateView.as_view(), + name="ta_pub_edit", + ), + path( + "/publicacao//delete", + views.PublicacaoDeleteView.as_view(), + name="ta_pub_delete", + ), ] urlpatterns = [ - path('ta/', include(urlpatterns_compilacao)), - - path('sistema/ta/config/tipo-nota/', - include(TipoNotaCrud.get_urls())), - path('sistema/ta/config/tipo-vide/', - include(TipoVideCrud.get_urls())), - path('sistema/ta/config/tipo-publicacao/', - include(TipoPublicacaoCrud.get_urls())), - path('sistema/ta/config/veiculo-publicacao/', - include(VeiculoPublicacaoCrud.get_urls())), - path('sistema/ta/config/tipo/', - include(TipoTextoArticuladoCrud.get_urls())), - path('sistema/ta/config/tipodispositivo/', - include(TipoDispositivoCrud.get_urls())), - - - + path("ta/", include(urlpatterns_compilacao)), + path("sistema/ta/config/tipo-nota/", include(TipoNotaCrud.get_urls())), + path("sistema/ta/config/tipo-vide/", include(TipoVideCrud.get_urls())), + path("sistema/ta/config/tipo-publicacao/", include(TipoPublicacaoCrud.get_urls())), + path( + "sistema/ta/config/veiculo-publicacao/", + include(VeiculoPublicacaoCrud.get_urls()), + ), + path("sistema/ta/config/tipo/", include(TipoTextoArticuladoCrud.get_urls())), + path("sistema/ta/config/tipodispositivo/", include(TipoDispositivoCrud.get_urls())), ] diff --git a/sapl/compilacao/utils.py b/sapl/compilacao/utils.py index aa1793484..5673d4c53 100644 --- a/sapl/compilacao/utils.py +++ b/sapl/compilacao/utils.py @@ -1,29 +1,31 @@ import sys DISPOSITIVO_SELECT_RELATED = ( - 'tipo_dispositivo', - 'ta_publicado', - 'ta', - 'dispositivo_atualizador', - 'dispositivo_atualizador__dispositivo_pai', - 'dispositivo_atualizador__dispositivo_pai__ta', - 'dispositivo_atualizador__dispositivo_pai__ta__tipo_ta', - 'dispositivo_pai', - 'dispositivo_pai__tipo_dispositivo', - 'ta_publicado', - 'ta',) + "tipo_dispositivo", + "ta_publicado", + "ta", + "dispositivo_atualizador", + "dispositivo_atualizador__dispositivo_pai", + "dispositivo_atualizador__dispositivo_pai__ta", + "dispositivo_atualizador__dispositivo_pai__ta__tipo_ta", + "dispositivo_pai", + "dispositivo_pai__tipo_dispositivo", + "ta_publicado", + "ta", +) DISPOSITIVO_SELECT_RELATED_EDIT = ( - 'ta_publicado', - 'ta', - 'dispositivo_atualizador', - 'dispositivo_atualizador__dispositivo_pai', - 'dispositivo_atualizador__dispositivo_pai__ta', - 'dispositivo_atualizador__dispositivo_pai__ta__tipo_ta', - 'dispositivo_pai', - 'dispositivo_pai__tipo_dispositivo', - 'ta_publicado', - 'ta',) + "ta_publicado", + "ta", + "dispositivo_atualizador", + "dispositivo_atualizador__dispositivo_pai", + "dispositivo_atualizador__dispositivo_pai__ta", + "dispositivo_atualizador__dispositivo_pai__ta__tipo_ta", + "dispositivo_pai", + "dispositivo_pai__tipo_dispositivo", + "ta_publicado", + "ta", +) def int_to_roman(int_value): @@ -32,8 +34,7 @@ def int_to_roman(int_value): if not 0 < int_value < 4000: raise ValueError("Argument must be between 1 and 3999") ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1) - nums = ('M', 'CM', 'D', 'CD', 'C', 'XC', - 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I') + nums = ("M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I") result = "" for i in range(len(ints)): count = int(int_value / ints[i]) @@ -43,9 +44,9 @@ def int_to_roman(int_value): def int_to_letter(int_value): - result = '' + result = "" if not int_value: - return '0' + return "0" int_value -= 1 while int_value >= 26: rest = int_value % 26 @@ -59,10 +60,10 @@ def get_integrations_view_names(): result = [] modules = sys.modules for key, value in modules.items(): - if key.endswith('.views'): + if key.endswith(".views"): for v in value.__dict__.values(): - if hasattr(v, '__bases__'): + if hasattr(v, "__bases__"): for base in v.__bases__: - if 'IntegracaoTaView' in str(base): + if "IntegracaoTaView" in str(base): result.append(v) return result diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py index 68650bfe9..5dba344ef 100644 --- a/sapl/compilacao/views.py +++ b/sapl/compilacao/views.py @@ -1,7 +1,7 @@ -from collections import OrderedDict -from datetime import timedelta import logging import sys +from collections import OrderedDict +from datetime import timedelta from braces.views import FormMessagesMixin from bs4 import BeautifulSoup @@ -11,13 +11,13 @@ from django.conf import settings from django.contrib import messages from django.contrib.auth.mixins import PermissionRequiredMixin from django.contrib.contenttypes.models import ContentType -from django.core.exceptions import ValidationError, PermissionDenied +from django.core.exceptions import PermissionDenied, ValidationError from django.core.signing import Signer from django.db import transaction from django.db.models import Q from django.db.models.query import QuerySet -from django.http.response import (HttpResponse, HttpResponseRedirect, - JsonResponse, Http404) +from django.http.response import (Http404, HttpResponse, HttpResponseRedirect, + JsonResponse) from django.shortcuts import get_object_or_404, redirect from django.urls import reverse, reverse_lazy from django.utils.dateparse import parse_date @@ -50,30 +50,29 @@ from sapl.compilacao.models import (STATUS_TA_EDITION, STATUS_TA_PRIVATE, from sapl.compilacao.utils import (DISPOSITIVO_SELECT_RELATED, DISPOSITIVO_SELECT_RELATED_EDIT, get_integrations_view_names) -from sapl.crud.base import RP_DETAIL, RP_LIST, Crud, CrudAux, CrudListView,\ - make_pagination +from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, CrudListView, + make_pagination) from sapl.settings import BASE_DIR - -TipoNotaCrud = CrudAux.build(TipoNota, 'tipo_nota') -TipoVideCrud = CrudAux.build(TipoVide, 'tipo_vide') -TipoPublicacaoCrud = CrudAux.build(TipoPublicacao, 'tipo_publicacao') -VeiculoPublicacaoCrud = CrudAux.build(VeiculoPublicacao, 'veiculo_publicacao') +TipoNotaCrud = CrudAux.build(TipoNota, "tipo_nota") +TipoVideCrud = CrudAux.build(TipoVide, "tipo_vide") +TipoPublicacaoCrud = CrudAux.build(TipoPublicacao, "tipo_publicacao") +VeiculoPublicacaoCrud = CrudAux.build(VeiculoPublicacao, "veiculo_publicacao") class TipoDispositivoCrud(CrudAux): model = TipoDispositivo class BaseMixin(CrudAux.BaseMixin): - list_field_names = ('nome', ) + list_field_names = ("nome",) @property def delete_url(self): - return '' + return "" @property def create_url(self): - return '' + return "" class CreateView(CrudAux.CreateView): def has_permission(self): @@ -84,7 +83,7 @@ class TipoDispositivoCrud(CrudAux): return False class UpdateView(CrudAux.UpdateView): - layout_key = 'TipoDispositivoUpdate' + layout_key = "TipoDispositivoUpdate" class ListView(CrudAux.ListView): paginate_by = 100 @@ -92,21 +91,21 @@ class TipoDispositivoCrud(CrudAux): def choice_models_in_extenal_views(): integrations_view_names = get_integrations_view_names() - result = [(None, '-------------'), ] + result = [ + (None, "-------------"), + ] for item in integrations_view_names: - if hasattr(item, 'model') and hasattr(item, 'model_type_foreignkey'): + if hasattr(item, "model") and hasattr(item, "model_type_foreignkey"): ct = ContentType.objects.filter( - model=item.model.__name__.lower(), - app_label=item.model._meta.app_label) + model=item.model.__name__.lower(), app_label=item.model._meta.app_label + ) if ct.exists(): - result.append(( - ct[0].pk, - item.model._meta.verbose_name_plural)) + result.append((ct[0].pk, item.model._meta.verbose_name_plural)) return result def choice_model_type_foreignkey_in_extenal_views(id_tipo_ta=None): - yield None, '-------------' + yield None, "-------------" if not id_tipo_ta: return @@ -115,44 +114,50 @@ def choice_model_type_foreignkey_in_extenal_views(id_tipo_ta=None): integrations_view_names = get_integrations_view_names() for item in integrations_view_names: - if hasattr(item, 'model_type_foreignkey'): - if (tipo_ta.content_type.model == item.model.__name__.lower() and - tipo_ta.content_type.app_label == - item.model._meta.app_label): + if hasattr(item, "model_type_foreignkey"): + if ( + tipo_ta.content_type.model == item.model.__name__.lower() + and tipo_ta.content_type.app_label == item.model._meta.app_label + ): for i in item.model_type_foreignkey.objects.all(): yield i.pk, i class IntegracaoTaView(TemplateView): - def get_redirect_deactivated(self): messages.error( self.request, - _('O modulo de Textos Articulados para %s está desativado.' - ) % self.model._meta.verbose_name_plural) - return redirect('/') + _("O modulo de Textos Articulados para %s está desativado.") + % self.model._meta.verbose_name_plural, + ) + return redirect("/") def get(self, request, *args, **kwargs): - try: if settings.DEBUG or not TipoDispositivo.objects.exists(): AppConfig.import_pattern() - if hasattr(self, 'map_funcs'): + if hasattr(self, "map_funcs"): tipo_ta = TipoTextoArticulado.objects.get( - content_type=ContentType.objects.get_for_model( - self.model)) + content_type=ContentType.objects.get_for_model(self.model) + ) for key, value in self.map_funcs.items(): setattr(tipo_ta, key, value) tipo_ta.save() except Exception as e: - print("{} {}".format( - _('Ocorreu erro na importação do arquivo base dos Tipos de Dispositivos, entre outras informações iniciais.'), str(e))) + print( + "{} {}".format( + _( + "Ocorreu erro na importação do arquivo base dos Tipos de Dispositivos, entre outras informações iniciais." + ), + str(e), + ) + ) return self.get_redirect_deactivated() - assert hasattr(self, 'map_fields'), _( + assert hasattr(self, "map_fields"), _( """ O mapa dos campos não foi definido. Ele deve seguir a estrutura de chaves abaixo: @@ -168,36 +173,27 @@ class IntegracaoTaView(TemplateView): Caso o model de integração não possua um dos campos, implemente, ou passe `None` para as chaves que são fixas. - """) + """ + ) - ta_values = getattr(self, 'ta_values', {}) + ta_values = getattr(self, "ta_values", {}) - item = get_object_or_404(self.model, pk=kwargs['pk']) + item = get_object_or_404(self.model, pk=kwargs["pk"]) related_object_type = ContentType.objects.get_for_model(item) ta = TextoArticulado.objects.filter( - object_id=item.pk, - content_type=related_object_type) + object_id=item.pk, content_type=related_object_type + ) ta_exists = bool(ta.exists()) self.object = ta = ta.first() ta_perm_edit = ( - ( - request.user.has_perm( - 'compilacao.change_dispositivo_edicao_dinamica') and - ta_values.get( - 'privacidade', - STATUS_TA_EDITION - ) != STATUS_TA_PRIVATE - ) or ( - request.user.has_perm( - 'compilacao.change_your_dispositivo_edicao_dinamica') and - ta_values.get( - 'privacidade', - STATUS_TA_EDITION - ) == STATUS_TA_PRIVATE - ) + request.user.has_perm("compilacao.change_dispositivo_edicao_dinamica") + and ta_values.get("privacidade", STATUS_TA_EDITION) != STATUS_TA_PRIVATE + ) or ( + request.user.has_perm("compilacao.change_your_dispositivo_edicao_dinamica") + and ta_values.get("privacidade", STATUS_TA_EDITION) == STATUS_TA_PRIVATE ) """ @@ -214,28 +210,31 @@ class IntegracaoTaView(TemplateView): """ if not ta_exists and not ta_perm_edit: - messages.info(request, _('%s não possui %s.') % ( - item, TextoArticulado._meta.verbose_name)) - return redirect('/message') + messages.info( + request, + _("%s não possui %s.") % (item, TextoArticulado._meta.verbose_name), + ) + return redirect("/message") if ta_perm_edit: self.object = ta = TextoArticulado.update_or_create(self, item) if not ta_exists: - if ta.editable_only_by_owners and\ - not self.request.user.is_anonymous: + if ta.editable_only_by_owners and not self.request.user.is_anonymous: ta.owners.add(self.request.user) - if not Dispositivo.objects.filter(ta_id=ta.pk).exists() and\ - ta.can_use_dynamic_editing(self.request.user): - return redirect(to=reverse_lazy('sapl.compilacao:ta_text_edit', - kwargs={'ta_id': ta.pk})) + if not Dispositivo.objects.filter( + ta_id=ta.pk + ).exists() and ta.can_use_dynamic_editing(self.request.user): + return redirect( + to=reverse_lazy("sapl.compilacao:ta_text_edit", kwargs={"ta_id": ta.pk}) + ) else: return redirect( - to='%s?%s' % ( - reverse_lazy('sapl.compilacao:ta_text', - kwargs={'ta_id': ta.pk}), - request.META['QUERY_STRING'] + to="%s?%s" + % ( + reverse_lazy("sapl.compilacao:ta_text", kwargs={"ta_id": ta.pk}), + request.META["QUERY_STRING"], ) ) @@ -256,7 +255,8 @@ class CompMixin(PermissionRequiredMixin): def ta(self): try: ta = TextoArticulado.objects.get( - pk=self.kwargs.get('ta_id', self.kwargs.get('pk', 0))) + pk=self.kwargs.get("ta_id", self.kwargs.get("pk", 0)) + ) except TextoArticulado.DoesNotExist: raise Http404() @@ -265,192 +265,303 @@ class CompMixin(PermissionRequiredMixin): def get_context_data(self, **kwargs): context = super(CompMixin, self).get_context_data(**kwargs) - if hasattr(self, 'model') and not hasattr(self, 'object'): + if hasattr(self, "model") and not hasattr(self, "object"): context.update( - {'title': self.model._meta.verbose_name_plural - if isinstance(self, ListView) - else self.model._meta.verbose_name}) + { + "title": self.model._meta.verbose_name_plural + if isinstance(self, ListView) + else self.model._meta.verbose_name + } + ) if isinstance(self, ListView): - context['NO_ENTRIES_MSG'] = CrudListView.no_entries_msg + context["NO_ENTRIES_MSG"] = CrudListView.no_entries_msg return context def get_notificacoes(self, object_list=None, type_notificacoes=None): - p = [] - def padd(r, type_notificacao, reverse_url=None, test=True, msg='', - kwargs=None, to_position=None): - + def padd( + r, + type_notificacao, + reverse_url=None, + test=True, + msg="", + kwargs=None, + to_position=None, + ): if not test: return r.contextual_class = type_notificacao if not kwargs: - kwargs = {'ta_id': r.ta_id, 'pk': r.pk} + kwargs = {"ta_id": r.ta_id, "pk": r.pk} if reverse_url: - p.append((type_notificacao, msg, - reverse_lazy(reverse_url, kwargs=kwargs), - to_position)) + p.append( + ( + type_notificacao, + msg, + reverse_lazy(reverse_url, kwargs=kwargs), + to_position, + ) + ) else: p.append((type_notificacao, msg, None, to_position)) def success(r): - type_notificacao = 'success' - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - r.inconstitucionalidade, - _('Declarado Inconstitucional.')) + type_notificacao = "success" + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + r.inconstitucionalidade, + _("Declarado Inconstitucional."), + ) - padd(r, type_notificacao, 'sapl.compilacao:ta_text_edit', - r.ta_publicado and r.dispositivo_atualizador, - _('Dispositivo alterado em %s' % r.ta_publicado), - {'ta_id': r.ta_publicado_id}, r.dispositivo_atualizador_id) + padd( + r, + type_notificacao, + "sapl.compilacao:ta_text_edit", + r.ta_publicado and r.dispositivo_atualizador, + _("Dispositivo alterado em %s" % r.ta_publicado), + {"ta_id": r.ta_publicado_id}, + r.dispositivo_atualizador_id, + ) def info(r): - type_notificacao = 'info' - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - r.publicacao and - r.dispositivo_vigencia and - r.publicacao.data != r.dispositivo_vigencia.inicio_vigencia, - _('Data da publicação associada ao Dispositivo difere da data' - ' de inicio de vigência do Dispositivo de vigência.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - r.publicacao and r.publicacao.data != r.inicio_vigencia, - _('Data da publicação associada ao Dispositivo difere ' - 'da data de inicio de vigência.')) - - padd(r, type_notificacao, 'sapl.compilacao:dispositivo_edit', - r.rotulo != r.rotulo_padrao(local_insert=1), - _('Rótulo Diferente do Padrão')) - - padd(r, type_notificacao, 'sapl.compilacao:dispositivo_edit', - r.texto_atualizador and r.texto_atualizador != r.texto, - _('Texto do Dispositivo para o Documento ' - 'está diferente do texto para o Documento Alterador.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_alteracao', - r.texto_atualizador and r.texto_atualizador == r.texto, - _('Texto do Dispositivo no Documento Alterador ' - 'está igual ao Texto no Documento Original. ' - 'Não é necessário manter armazenado o texto no Documento ' - 'Alterador.')) + type_notificacao = "info" + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + r.publicacao + and r.dispositivo_vigencia + and r.publicacao.data != r.dispositivo_vigencia.inicio_vigencia, + _( + "Data da publicação associada ao Dispositivo difere da data" + " de inicio de vigência do Dispositivo de vigência." + ), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + r.publicacao and r.publicacao.data != r.inicio_vigencia, + _( + "Data da publicação associada ao Dispositivo difere " + "da data de inicio de vigência." + ), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit", + r.rotulo != r.rotulo_padrao(local_insert=1), + _("Rótulo Diferente do Padrão"), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit", + r.texto_atualizador and r.texto_atualizador != r.texto, + _( + "Texto do Dispositivo para o Documento " + "está diferente do texto para o Documento Alterador." + ), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_alteracao", + r.texto_atualizador and r.texto_atualizador == r.texto, + _( + "Texto do Dispositivo no Documento Alterador " + "está igual ao Texto no Documento Original. " + "Não é necessário manter armazenado o texto no Documento " + "Alterador." + ), + ) def warning(r): - type_notificacao = 'warning' - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - r.dispositivo_vigencia and r.inicio_vigencia != - r.dispositivo_vigencia.inicio_vigencia, - _('Data de início de Vigência difere da data início de ' - 'Vigência do Dispositivo de Vigência')) - - padd(r, type_notificacao, 'sapl.compilacao:ta_text', - r.inconstitucionalidade and not r.notas.exists(), - _('Dispositivo está definido como inconstitucional. É ' - 'aconcelhavel inserir uma Nota informando esta condição.'), - kwargs={'ta_id': r.ta_id}, - to_position=r.pk) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - r.inconstitucionalidade and not ( - r.inicio_vigencia == r.fim_vigencia and - r.fim_vigencia == r.inicio_eficacia and - r.inicio_eficacia == r.fim_eficacia), - _('Dispositivo está definido como inconstitucional porém ' - 'existe diferença entre as datas início e fim de ' - 'vigência e eficácia.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - r.publicacao and - r.ta_publicado and r.ta_publicado != r.publicacao.ta, - _('A Publicação associada a este Dispositivo não é ' - 'uma publicação do Texto Articulado Alterador.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - not r.publicacao, - _('Dispositivo sem registro de publicação.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - r.texto and r.tipo_dispositivo.dispositivo_de_articulacao, - _('Dispositivos de Articulação não ' - 'deveriam armazenar texto.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - not r.texto and - not r.tipo_dispositivo.dispositivo_de_articulacao, - _('Dispositivo está sem texto.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_alteracao', - r.texto_atualizador and not r.ta_publicado, - _('Existe Texto Atualizador, porém este Dispositivo não ' - 'está associado a nenhum Documento Atualizador.')) + type_notificacao = "warning" + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + r.dispositivo_vigencia + and r.inicio_vigencia != r.dispositivo_vigencia.inicio_vigencia, + _( + "Data de início de Vigência difere da data início de " + "Vigência do Dispositivo de Vigência" + ), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:ta_text", + r.inconstitucionalidade and not r.notas.exists(), + _( + "Dispositivo está definido como inconstitucional. É " + "aconcelhavel inserir uma Nota informando esta condição." + ), + kwargs={"ta_id": r.ta_id}, + to_position=r.pk, + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + r.inconstitucionalidade + and not ( + r.inicio_vigencia == r.fim_vigencia + and r.fim_vigencia == r.inicio_eficacia + and r.inicio_eficacia == r.fim_eficacia + ), + _( + "Dispositivo está definido como inconstitucional porém " + "existe diferença entre as datas início e fim de " + "vigência e eficácia." + ), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + r.publicacao and r.ta_publicado and r.ta_publicado != r.publicacao.ta, + _( + "A Publicação associada a este Dispositivo não é " + "uma publicação do Texto Articulado Alterador." + ), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + not r.publicacao, + _("Dispositivo sem registro de publicação."), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + r.texto and r.tipo_dispositivo.dispositivo_de_articulacao, + _("Dispositivos de Articulação não " "deveriam armazenar texto."), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + not r.texto and not r.tipo_dispositivo.dispositivo_de_articulacao, + _("Dispositivo está sem texto."), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_alteracao", + r.texto_atualizador and not r.ta_publicado, + _( + "Existe Texto Atualizador, porém este Dispositivo não " + "está associado a nenhum Documento Atualizador." + ), + ) def danger(r): - type_notificacao = 'danger' - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - not r.dispositivo_vigencia, - _('Dispositivo sem definição de Dispositivo de Vigência.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_vigencia', - r.inconstitucionalidade and - r.inicio_vigencia != r.fim_vigencia, - _('Dispositivo está definido como inconstitucional porém ' - 'existe período de vigência.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_alteracao', - r.ta_publicado and not r.dispositivo_atualizador, - _('Dispositivo está associado a um Texto Articulado ' - 'Atualizador mas, a nenhum Dispositivo Atualizador.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_alteracao', - not r.dispositivo_atualizador and - r.dispositivo_substituido, - _('Dispositivo está substituindo outro mas não foi informado ' - 'o Dispositivo Atualizador.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_alteracao', - r.dispositivo_substituido and - r.dispositivo_substituido.tipo_dispositivo != - r.tipo_dispositivo, - _('Dispositivo está substituindo um Dispositivo ' - 'de outro tipo.')) - - padd(r, type_notificacao, - 'sapl.compilacao:dispositivo_edit_alteracao', - r.dispositivo_substituido and - r.dispositivo_substituido.ta != r.ta, - _('Dispositivo está substituindo um Dispositivo de outro ' - 'Texto Articulado.')) - - padd(r.dispositivo_substituido, type_notificacao, - 'sapl.compilacao:dispositivo_edit_alteracao', - r.dispositivo_substituido and - r.dispositivo_substituido.dispositivo_subsequente != r, - _('Dispositivo está substituindo um Dispositivo que não ' - 'possui este como seu Dispositivo Subsequente.')) - - padd(r.dispositivo_subsequente, type_notificacao, - 'sapl.compilacao:dispositivo_edit_alteracao', - r.dispositivo_subsequente and - r.dispositivo_subsequente.dispositivo_substituido != r, - _('Dispositivo foi substituído por outro que não ' - 'possui este como seu Dispositivo Substituído.')) + type_notificacao = "danger" + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + not r.dispositivo_vigencia, + _("Dispositivo sem definição de Dispositivo de Vigência."), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_vigencia", + r.inconstitucionalidade and r.inicio_vigencia != r.fim_vigencia, + _( + "Dispositivo está definido como inconstitucional porém " + "existe período de vigência." + ), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_alteracao", + r.ta_publicado and not r.dispositivo_atualizador, + _( + "Dispositivo está associado a um Texto Articulado " + "Atualizador mas, a nenhum Dispositivo Atualizador." + ), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_alteracao", + not r.dispositivo_atualizador and r.dispositivo_substituido, + _( + "Dispositivo está substituindo outro mas não foi informado " + "o Dispositivo Atualizador." + ), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_alteracao", + r.dispositivo_substituido + and r.dispositivo_substituido.tipo_dispositivo != r.tipo_dispositivo, + _("Dispositivo está substituindo um Dispositivo " "de outro tipo."), + ) + + padd( + r, + type_notificacao, + "sapl.compilacao:dispositivo_edit_alteracao", + r.dispositivo_substituido and r.dispositivo_substituido.ta != r.ta, + _( + "Dispositivo está substituindo um Dispositivo de outro " + "Texto Articulado." + ), + ) + + padd( + r.dispositivo_substituido, + type_notificacao, + "sapl.compilacao:dispositivo_edit_alteracao", + r.dispositivo_substituido + and r.dispositivo_substituido.dispositivo_subsequente != r, + _( + "Dispositivo está substituindo um Dispositivo que não " + "possui este como seu Dispositivo Subsequente." + ), + ) + + padd( + r.dispositivo_subsequente, + type_notificacao, + "sapl.compilacao:dispositivo_edit_alteracao", + r.dispositivo_subsequente + and r.dispositivo_subsequente.dispositivo_substituido != r, + _( + "Dispositivo foi substituído por outro que não " + "possui este como seu Dispositivo Substituído." + ), + ) rr = [] for r in object_list: @@ -458,24 +569,28 @@ class CompMixin(PermissionRequiredMixin): r.contextual_class = "" for f in type_notificacoes: - if f != 'default': + if f != "default": locals()[f](r) r.notificacoes = p - if p or 'default' in type_notificacoes: + if p or "default" in type_notificacoes: rr.append(r) if r.dispositivos_alterados_set.exists(): rr += self.get_notificacoes( - r.dispositivos_alterados_set.all(), type_notificacoes) + r.dispositivos_alterados_set.all(), type_notificacoes + ) return rr class TipoTextoArticuladoCrud(CrudAux): model = TipoTextoArticulado - public = [RP_LIST, RP_DETAIL, ] + public = [ + RP_LIST, + RP_DETAIL, + ] class CreateView(CrudAux.CreateView): form_class = TipoTaForm @@ -483,9 +598,11 @@ class TipoTextoArticuladoCrud(CrudAux): def get(self, request, *args, **kwargs): self.object = None form = self.get_form() - form.fields['content_type'] = forms.ChoiceField( + form.fields["content_type"] = forms.ChoiceField( choices=choice_models_in_extenal_views(), - label=_('Modelo Integrado'), required=False) + label=_("Modelo Integrado"), + required=False, + ) return self.render_to_response(self.get_context_data(form=form)) @@ -495,9 +612,11 @@ class TipoTextoArticuladoCrud(CrudAux): def get(self, request, *args, **kwargs): self.object = self.get_object() form = self.get_form() - form.fields['content_type'] = forms.ChoiceField( + form.fields["content_type"] = forms.ChoiceField( choices=choice_models_in_extenal_views(), - label=_('Modelo Integrado'), required=False) + label=_("Modelo Integrado"), + required=False, + ) return self.render_to_response(self.get_context_data(form=form)) @@ -505,7 +624,7 @@ class TaListView(CompMixin, ListView): model = TextoArticulado paginate_by = 10 verbose_name = model._meta.verbose_name - permission_required = 'compilacao.list_textoarticulado' + permission_required = "compilacao.list_textoarticulado" @property def title(self): @@ -513,34 +632,35 @@ class TaListView(CompMixin, ListView): @property def create_url(self): - return reverse_lazy('sapl.compilacao:ta_create') + return reverse_lazy("sapl.compilacao:ta_create") def get_context_data(self, **kwargs): context = super(TaListView, self).get_context_data(**kwargs) - paginator = context['paginator'] - page_obj = context['page_obj'] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + paginator = context["paginator"] + page_obj = context["page_obj"] + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) return context def get_queryset(self): qs = ListView.get_queryset(self) - qs = qs.exclude( - ~Q(owners=self.request.user.id), - privacidade=STATUS_TA_PRIVATE) + qs = qs.exclude(~Q(owners=self.request.user.id), privacidade=STATUS_TA_PRIVATE) - if 'check' in self.request.GET: + if "check" in self.request.GET: qs = qs.filter( temp_check_migrations=False, privacidade=0, ).exclude(dispositivos_set__tipo_dispositivo_id=3) - if 'check_dvt' in self.request.GET: - qs = qs.filter( - ).filter( - dispositivos_set__isnull=False, - dispositivos_set__dispositivo_vigencia__isnull=True).distinct() + if "check_dvt" in self.request.GET: + qs = ( + qs.filter() + .filter( + dispositivos_set__isnull=False, + dispositivos_set__dispositivo_vigencia__isnull=True, + ) + .distinct() + ) return qs @@ -559,10 +679,11 @@ class TaDetailView(CompMixin, DetailView): def title(self): if self.get_object().content_object: return _( - 'Metadados para o Texto Articulado de %s\n' - '%s') % ( + "Metadados para o Texto Articulado de %s\n" "%s" + ) % ( self.get_object().content_object._meta.verbose_name_plural, - self.get_object().content_object.epigrafe) + self.get_object().content_object.epigrafe, + ) else: return self.get_object() @@ -571,24 +692,23 @@ class TaCreateView(CompMixin, FormMessagesMixin, CreateView): model = TextoArticulado form_class = TaForm template_name = "crud/form.html" - form_valid_message = _('Registro criado com sucesso!') - form_invalid_message = _('O registro não foi criado.') - permission_required = 'compilacao.add_tipotextoarticulado' + form_valid_message = _("Registro criado com sucesso!") + form_invalid_message = _("O registro não foi criado.") + permission_required = "compilacao.add_tipotextoarticulado" def get_success_url(self): - return reverse_lazy('sapl.compilacao:ta_detail', - kwargs={'pk': self.object.id}) + return reverse_lazy("sapl.compilacao:ta_detail", kwargs={"pk": self.object.id}) @property def cancel_url(self): - return reverse_lazy('sapl.compilacao:ta_list') + return reverse_lazy("sapl.compilacao:ta_list") class TaUpdateView(CompMixin, UpdateView): model = TextoArticulado form_class = TaForm template_name = "crud/form.html" - permission_required = 'compilacao.change_textoarticulado' + permission_required = "compilacao.change_textoarticulado" def get(self, request, *args, **kwargs): self.object = self.get_object() @@ -599,19 +719,21 @@ class TaUpdateView(CompMixin, UpdateView): return self.render_to_response(self.get_context_data(form=form)) def get_success_url(self): - return reverse_lazy('sapl.compilacao:ta_detail', - kwargs={'pk': self.kwargs['pk']}) + return reverse_lazy( + "sapl.compilacao:ta_detail", kwargs={"pk": self.kwargs["pk"]} + ) @property def cancel_url(self): - return reverse_lazy('sapl.compilacao:ta_detail', - kwargs={'pk': self.kwargs['pk']}) + return reverse_lazy( + "sapl.compilacao:ta_detail", kwargs={"pk": self.kwargs["pk"]} + ) class TaDeleteView(CompMixin, DeleteView): model = TextoArticulado template_name = "crud/confirm_delete.html" - permission_required = 'compilacao.delete_textoarticulado' + permission_required = "compilacao.delete_textoarticulado" def post(self, request, *args, **kwargs): if not request.user.is_superuser: @@ -620,59 +742,60 @@ class TaDeleteView(CompMixin, DeleteView): @property def detail_url(self): - return reverse_lazy('sapl.compilacao:ta_detail', - kwargs={'pk': self.kwargs['pk']}) + return reverse_lazy( + "sapl.compilacao:ta_detail", kwargs={"pk": self.kwargs["pk"]} + ) def get_success_url(self): - messages.info(self.request, 'Texto Articulado excluido com sucesso!') + messages.info(self.request, "Texto Articulado excluido com sucesso!") - reverse_url = '%s:%s_detail' % ( + reverse_url = "%s:%s_detail" % ( self.object.content_object._meta.app_config.name, - self.object.content_object._meta.model_name) + self.object.content_object._meta.model_name, + ) - return reverse_lazy(reverse_url, - kwargs={'pk': self.object.content_object.pk}) + return reverse_lazy(reverse_url, kwargs={"pk": self.object.content_object.pk}) @property def title(self): - return 'Texto Articulado: %s' % self.object + return "Texto Articulado: %s" % self.object class DispositivoSuccessUrlMixin(CompMixin): - def get_success_url(self): return reverse_lazy( - 'sapl.compilacao:dispositivo', kwargs={ - 'ta_id': self.kwargs[ - 'ta_id'], - 'dispositivo_id': self.kwargs[ - 'dispositivo_id']}) + "sapl.compilacao:dispositivo", + kwargs={ + "ta_id": self.kwargs["ta_id"], + "dispositivo_id": self.kwargs["dispositivo_id"], + }, + ) class NotaMixin(DispositivoSuccessUrlMixin): - def get_modelo_nota(self, request): - if 'action' in request.GET and request.GET['action'] == 'modelo_nota': - tn = TipoNota.objects.get(pk=request.GET['id_tipo']) + if "action" in request.GET and request.GET["action"] == "modelo_nota": + tn = TipoNota.objects.get(pk=request.GET["id_tipo"]) return True, tn.modelo - return False, '' + return False, "" def get_initial(self): dispositivo = get_object_or_404( - Dispositivo, pk=self.kwargs.get('dispositivo_id')) - initial = {'dispositivo': dispositivo} + Dispositivo, pk=self.kwargs.get("dispositivo_id") + ) + initial = {"dispositivo": dispositivo} - if 'pk' in self.kwargs: - initial['pk'] = self.kwargs.get('pk') + if "pk" in self.kwargs: + initial["pk"] = self.kwargs.get("pk") return initial class NotasCreateView(NotaMixin, CreateView): logger = logging.getLogger(__name__) - template_name = 'compilacao/ajax_form.html' + template_name = "compilacao/ajax_form.html" form_class = NotaForm - permission_required = 'compilacao.add_nota' + permission_required = "compilacao.add_nota" def get(self, request, *args, **kwargs): flag_action, modelo_nota = self.get_modelo_nota(request) @@ -682,21 +805,20 @@ class NotasCreateView(NotaMixin, CreateView): return super(NotasCreateView, self).get(request, *args, **kwargs) def post(self, request, *args, **kwargs): - username = request.user.username self.object = None try: - ta_id = kwargs.pop('ta_id') - dispositivo_id = kwargs.pop('dispositivo_id') + ta_id = kwargs.pop("ta_id") + dispositivo_id = kwargs.pop("dispositivo_id") form = NotaForm(request.POST, request.FILES, **kwargs) - kwargs['ta_id'] = ta_id - kwargs['dispositivo_id'] = dispositivo_id + kwargs["ta_id"] = ta_id + kwargs["dispositivo_id"] = dispositivo_id if form.is_valid(): nt = form.save(commit=False) nt.owner_id = request.user.pk nt.save() - self.kwargs['pk'] = nt.pk + self.kwargs["pk"] = nt.pk return self.form_valid(form) else: return self.form_invalid(form) @@ -709,9 +831,9 @@ class NotasCreateView(NotaMixin, CreateView): class NotasEditView(NotaMixin, UpdateView): model = Nota - template_name = 'compilacao/ajax_form.html' + template_name = "compilacao/ajax_form.html" form_class = NotaForm - permission_required = 'compilacao.change_nota' + permission_required = "compilacao.change_nota" def get(self, request, *args, **kwargs): flag_action, modelo_nota = self.get_modelo_nota(request) @@ -722,33 +844,34 @@ class NotasEditView(NotaMixin, UpdateView): class NotasDeleteView(NotaMixin, TemplateView): - - permission_required = 'compilacao.delete_nota' + permission_required = "compilacao.delete_nota" def get(self, request, *args, **kwargs): - nt = Nota.objects.get(pk=self.kwargs['pk']) + nt = Nota.objects.get(pk=self.kwargs["pk"]) nt.delete() return HttpResponseRedirect(self.get_success_url()) class VideMixin(DispositivoSuccessUrlMixin): - def get_initial(self): dispositivo_base = get_object_or_404( - Dispositivo, pk=self.kwargs.get('dispositivo_id')) - initial = {'dispositivo_base': dispositivo_base, } + Dispositivo, pk=self.kwargs.get("dispositivo_id") + ) + initial = { + "dispositivo_base": dispositivo_base, + } - if 'pk' in self.kwargs: - initial['pk'] = self.kwargs.get('pk') + if "pk" in self.kwargs: + initial["pk"] = self.kwargs.get("pk") return initial class VideCreateView(VideMixin, CreateView): model = Vide - template_name = 'compilacao/ajax_form.html' + template_name = "compilacao/ajax_form.html" form_class = VideForm - permission_required = 'compilacao.add_vide' + permission_required = "compilacao.add_vide" def get(self, request, *args, **kwargs): self.object = None @@ -758,32 +881,37 @@ class VideCreateView(VideMixin, CreateView): class VideEditView(VideMixin, UpdateView): model = Vide - template_name = 'compilacao/ajax_form.html' + template_name = "compilacao/ajax_form.html" form_class = VideForm - permission_required = 'compilacao.change_vide' + permission_required = "compilacao.change_vide" class VideDeleteView(VideMixin, TemplateView): - permission_required = 'compilacao.delete_vide' + permission_required = "compilacao.delete_vide" def get(self, request, *args, **kwargs): - vd = Vide.objects.get(pk=self.kwargs['pk']) + vd = Vide.objects.get(pk=self.kwargs["pk"]) vd.delete() return HttpResponseRedirect(self.get_success_url()) class PublicacaoMixin(CompMixin): - def dispatch(self, request, *args, **kwargs): ta = self.ta if not ta.tipo_ta.publicacao_func: - messages.error(request, _( - 'A funcionalidade de %s está desativada para %s.') % ( - TipoTextoArticulado._meta.get_field( - 'publicacao_func').verbose_name, - ta.tipo_ta.descricao)) - return redirect(reverse('sapl.compilacao:ta_text', - kwargs={'ta_id': self.kwargs['ta_id']})) + messages.error( + request, + _("A funcionalidade de %s está desativada para %s.") + % ( + TipoTextoArticulado._meta.get_field("publicacao_func").verbose_name, + ta.tipo_ta.descricao, + ), + ) + return redirect( + reverse( + "sapl.compilacao:ta_text", kwargs={"ta_id": self.kwargs["ta_id"]} + ) + ) return PermissionRequiredMixin.dispatch(self, request, *args, **kwargs) @@ -795,25 +923,25 @@ class PublicacaoListView(PublicacaoMixin, ListView): @property def title(self): - return _('%s (%s)' % ( - self.model._meta.verbose_name_plural, - self.ta)) + return _( + "%s (%s)" % (self.model._meta.verbose_name_plural, self.ta) + ) @property def create_url(self): return reverse_lazy( - 'sapl.compilacao:ta_pub_create', - kwargs={'ta_id': self.kwargs['ta_id']}) + "sapl.compilacao:ta_pub_create", kwargs={"ta_id": self.kwargs["ta_id"]} + ) def get_queryset(self): - pubs = Publicacao.objects.filter(ta_id=self.kwargs['ta_id']) + pubs = Publicacao.objects.filter(ta_id=self.kwargs["ta_id"]) return pubs def get_context_data(self, **kwargs): context = super(PublicacaoListView, self).get_context_data(**kwargs) - context['title'] = self.title - context['object'] = self.ta - context['NO_ENTRIES_MSG'] = CrudListView.no_entries_msg + context["title"] = self.title + context["object"] = self.ta + context["NO_ENTRIES_MSG"] = CrudListView.no_entries_msg return context @@ -821,25 +949,24 @@ class PublicacaoCreateView(PublicacaoMixin, FormMessagesMixin, CreateView): model = Publicacao form_class = PublicacaoForm template_name = "crud/form.html" - form_valid_message = _('Registro criado com sucesso!') - form_invalid_message = _('O registro não foi criado.') - permission_required = 'compilacao.add_publicacao' + form_valid_message = _("Registro criado com sucesso!") + form_invalid_message = _("O registro não foi criado.") + permission_required = "compilacao.add_publicacao" def get_success_url(self): return reverse_lazy( - 'sapl.compilacao:ta_pub_detail', - kwargs={ - 'pk': self.object.id, - 'ta_id': self.kwargs['ta_id']}) + "sapl.compilacao:ta_pub_detail", + kwargs={"pk": self.object.id, "ta_id": self.kwargs["ta_id"]}, + ) @property def cancel_url(self): return reverse_lazy( - 'sapl.compilacao:ta_pub_list', - kwargs={'ta_id': self.kwargs['ta_id']}) + "sapl.compilacao:ta_pub_list", kwargs={"ta_id": self.kwargs["ta_id"]} + ) def get_initial(self): - return {'ta': self.kwargs['ta_id']} + return {"ta": self.kwargs["ta_id"]} class PublicacaoDetailView(PublicacaoMixin, DetailView): @@ -848,9 +975,9 @@ class PublicacaoDetailView(PublicacaoMixin, DetailView): @property def list_url(self): - return reverse_lazy('sapl.compilacao:ta_pub_list', - kwargs={ - 'ta_id': self.kwargs['ta_id']}) + return reverse_lazy( + "sapl.compilacao:ta_pub_list", kwargs={"ta_id": self.kwargs["ta_id"]} + ) @property def verbose_name_plural(self): @@ -861,7 +988,7 @@ class PublicacaoUpdateView(PublicacaoMixin, UpdateView): model = Publicacao form_class = PublicacaoForm template_name = "crud/form.html" - permission_required = 'compilacao.change_publicacao' + permission_required = "compilacao.change_publicacao" def get(self, request, *args, **kwargs): self.object = self.get_object() @@ -872,10 +999,10 @@ class PublicacaoUpdateView(PublicacaoMixin, UpdateView): return self.render_to_response(self.get_context_data(form=form)) def get_success_url(self): - return reverse_lazy('sapl.compilacao:ta_pub_detail', - kwargs={ - 'pk': self.object.id, - 'ta_id': self.kwargs['ta_id']}) + return reverse_lazy( + "sapl.compilacao:ta_pub_detail", + kwargs={"pk": self.object.id, "ta_id": self.kwargs["ta_id"]}, + ) @property def cancel_url(self): @@ -885,22 +1012,23 @@ class PublicacaoUpdateView(PublicacaoMixin, UpdateView): class PublicacaoDeleteView(PublicacaoMixin, DeleteView): model = Publicacao template_name = "crud/confirm_delete.html" - permission_required = 'compilacao.delete_publicacao' + permission_required = "compilacao.delete_publicacao" @property def detail_url(self): - return reverse_lazy('sapl.compilacao:ta_pub_detail', - kwargs={ - 'pk': self.object.id, - 'ta_id': self.kwargs['ta_id']}) + return reverse_lazy( + "sapl.compilacao:ta_pub_detail", + kwargs={"pk": self.object.id, "ta_id": self.kwargs["ta_id"]}, + ) def get_success_url(self): - return reverse_lazy('sapl.compilacao:ta_pub_list', - kwargs={'ta_id': self.kwargs['ta_id']}) + return reverse_lazy( + "sapl.compilacao:ta_pub_list", kwargs={"ta_id": self.kwargs["ta_id"]} + ) class TextView(CompMixin, ListView): - template_name = 'compilacao/text_list.html' + template_name = "compilacao/text_list.html" flag_alteradora = -1 @@ -915,69 +1043,72 @@ class TextView(CompMixin, ListView): @property def title(self): - return 'Texto Articulado: %s' % self.object + return "Texto Articulado: %s" % self.object def has_permission(self): self.object = self.ta return self.object.has_view_permission(self.request) def get(self, request, *args, **kwargs): - if 'print' in request.GET: - self.template_name = 'compilacao/text_list__print_version.html' - if 'embedded' in request.GET: - self.template_name = 'compilacao/text_list__embedded.html' + if "print" in request.GET: + self.template_name = "compilacao/text_list__print_version.html" + if "embedded" in request.GET: + self.template_name = "compilacao/text_list__embedded.html" return ListView.get(self, request, *args, **kwargs) def get_context_data(self, **kwargs): context = super(TextView, self).get_context_data(**kwargs) - context['object'] = TextoArticulado.objects.get( - pk=self.kwargs['ta_id']) + context["object"] = TextoArticulado.objects.get(pk=self.kwargs["ta_id"]) cita = Vide.objects.filter( - Q(dispositivo_base__ta_id=self.kwargs['ta_id'])).\ - select_related( - 'dispositivo_ref', - 'dispositivo_ref__ta', - 'dispositivo_ref__dispositivo_pai', - 'dispositivo_ref__dispositivo_pai__ta', 'tipo') - - context['cita'] = {} + Q(dispositivo_base__ta_id=self.kwargs["ta_id"]) + ).select_related( + "dispositivo_ref", + "dispositivo_ref__ta", + "dispositivo_ref__dispositivo_pai", + "dispositivo_ref__dispositivo_pai__ta", + "tipo", + ) + + context["cita"] = {} for c in cita: - if c.dispositivo_base_id not in context['cita']: - context['cita'][c.dispositivo_base_id] = [] - context['cita'][c.dispositivo_base_id].append(c) + if c.dispositivo_base_id not in context["cita"]: + context["cita"][c.dispositivo_base_id] = [] + context["cita"][c.dispositivo_base_id].append(c) citado = Vide.objects.filter( - Q(dispositivo_ref__ta_id=self.kwargs['ta_id'])).\ - select_related( - 'dispositivo_base', - 'dispositivo_base__ta', - 'dispositivo_base__dispositivo_pai', - 'dispositivo_base__dispositivo_pai__ta', 'tipo') - - context['citado'] = {} + Q(dispositivo_ref__ta_id=self.kwargs["ta_id"]) + ).select_related( + "dispositivo_base", + "dispositivo_base__ta", + "dispositivo_base__dispositivo_pai", + "dispositivo_base__dispositivo_pai__ta", + "tipo", + ) + + context["citado"] = {} for c in citado: - if c.dispositivo_ref_id not in context['citado']: - context['citado'][c.dispositivo_ref_id] = [] - context['citado'][c.dispositivo_ref_id].append(c) + if c.dispositivo_ref_id not in context["citado"]: + context["citado"][c.dispositivo_ref_id] = [] + context["citado"][c.dispositivo_ref_id].append(c) notas = Nota.objects.filter( - dispositivo__ta_id=self.kwargs['ta_id']).select_related( - 'owner', 'tipo') + dispositivo__ta_id=self.kwargs["ta_id"] + ).select_related("owner", "tipo") - context['notas'] = {} + context["notas"] = {} for n in notas: - if n.dispositivo_id not in context['notas']: - context['notas'][n.dispositivo_id] = [] - context['notas'][n.dispositivo_id].append(n) + if n.dispositivo_id not in context["notas"]: + context["notas"][n.dispositivo_id] = [] + context["notas"][n.dispositivo_id].append(n) tas_pub = [d.ta_publicado for d in self.object_list if d.ta_publicado] tas_pub = set(tas_pub) ta_pub_list = {} for ta in tas_pub: ta_pub_list[ta.pk] = str(ta) - context['ta_pub_list'] = ta_pub_list + context["ta_pub_list"] = ta_pub_list # context['vigencias'] = self.get_vigencias() @@ -991,46 +1122,44 @@ class TextView(CompMixin, ListView): self.inicio_vigencia = None self.fim_vigencia = None self.ta_vigencia = None - params = { - 'ordem__gt': 0, - 'ta_id': self.kwargs['ta_id'] - } - if 'sign' in self.kwargs: + params = {"ordem__gt": 0, "ta_id": self.kwargs["ta_id"]} + if "sign" in self.kwargs: signer = Signer() try: - string = signer.unsign(self.kwargs['sign']).split(',') + string = signer.unsign(self.kwargs["sign"]).split(",") self.ta_vigencia = int(string[0]) self.inicio_vigencia = parse_date(string[1]) self.fim_vigencia = parse_date(string[2]) except: - return Dispositivo.objects.filter( - **params - ).select_related(*DISPOSITIVO_SELECT_RELATED) + return Dispositivo.objects.filter(**params).select_related( + *DISPOSITIVO_SELECT_RELATED + ) if self.fim_vigencia: - params['inicio_vigencia__lte'] = self.fim_vigencia - return Dispositivo.objects.filter( - **params - ).select_related(*DISPOSITIVO_SELECT_RELATED) + params["inicio_vigencia__lte"] = self.fim_vigencia + return Dispositivo.objects.filter(**params).select_related( + *DISPOSITIVO_SELECT_RELATED + ) else: - r = Dispositivo.objects.filter( - **params - ).select_related(*DISPOSITIVO_SELECT_RELATED) + r = Dispositivo.objects.filter(**params).select_related( + *DISPOSITIVO_SELECT_RELATED + ) return r def get_vigencias(self): - itens = Dispositivo.objects.filter( - ta_id=self.kwargs['ta_id'] - ).order_by( - 'dispositivo_vigencia__inicio_vigencia', 'ta_publicado__id', 'ordem' - ).distinct( - 'dispositivo_vigencia__inicio_vigencia', 'ta_publicado__id' - ).select_related( - 'ta_publicado', - 'ta', - 'ta_publicado__tipo_ta', - 'ta__tipo_ta', + itens = ( + Dispositivo.objects.filter(ta_id=self.kwargs["ta_id"]) + .order_by( + "dispositivo_vigencia__inicio_vigencia", "ta_publicado__id", "ordem" + ) + .distinct("dispositivo_vigencia__inicio_vigencia", "ta_publicado__id") + .select_related( + "ta_publicado", + "ta", + "ta_publicado__tipo_ta", + "ta__tipo_ta", + ) ) ajuste_datas_vigencia = [] @@ -1041,21 +1170,21 @@ class TextView(CompMixin, ListView): lenLista = len(ajuste_datas_vigencia) for i in range(lenLista): if i + 1 < lenLista: - if ajuste_datas_vigencia[ - i].inicio_vigencia == ajuste_datas_vigencia[ - i + 1].inicio_vigencia: - + if ( + ajuste_datas_vigencia[i].inicio_vigencia + == ajuste_datas_vigencia[i + 1].inicio_vigencia + ): if i + 2 < lenLista: - ajuste_datas_vigencia[ - i].fim_vigencia = ajuste_datas_vigencia[ - i + 2].inicio_vigencia - timedelta(days=1) + ajuste_datas_vigencia[i].fim_vigencia = ajuste_datas_vigencia[ + i + 2 + ].inicio_vigencia - timedelta(days=1) else: ajuste_datas_vigencia[i].fim_vigencia = None else: - ajuste_datas_vigencia[ - i].fim_vigencia = ajuste_datas_vigencia[ - i + 1].inicio_vigencia - timedelta(days=1) + ajuste_datas_vigencia[i].fim_vigencia = ajuste_datas_vigencia[ + i + 1 + ].inicio_vigencia - timedelta(days=1) else: ajuste_datas_vigencia[i].fim_vigencia = None @@ -1066,38 +1195,48 @@ class TextView(CompMixin, ListView): for item in ajuste_datas_vigencia: idx += 1 if idx == 0: - self.itens_de_vigencia[0] = [item, ] + self.itens_de_vigencia[0] = [ + item, + ] continue if idx + 1 < length: - ano = item.ta_publicado.ano if item.ta_publicado else\ - item.ta.ano + ano = item.ta_publicado.ano if item.ta_publicado else item.ta.ano if ano in self.itens_de_vigencia: self.itens_de_vigencia[ano].append(item) else: - self.itens_de_vigencia[ano] = [item, ] + self.itens_de_vigencia[ano] = [ + item, + ] else: - self.itens_de_vigencia[9999] = [item, ] + self.itens_de_vigencia[9999] = [ + item, + ] if len(self.itens_de_vigencia.keys()) <= 1: return {} self.itens_de_vigencia = OrderedDict( - sorted(self.itens_de_vigencia.items(), key=lambda t: t[0])) + sorted(self.itens_de_vigencia.items(), key=lambda t: t[0]) + ) return self.itens_de_vigencia def is_ta_alterador(self): if self.flag_alteradora == -1: - self.flag_alteradora = Dispositivo.objects.select_related( - 'dispositivos_alterados_pelo_texto_articulado_set' - ).filter(ta_id=self.kwargs['ta_id']).count() + self.flag_alteradora = ( + Dispositivo.objects.select_related( + "dispositivos_alterados_pelo_texto_articulado_set" + ) + .filter(ta_id=self.kwargs["ta_id"]) + .count() + ) return self.flag_alteradora > 0 class DispositivoView(TextView): # template_name = 'compilacao/index.html' - template_name = 'compilacao/text_list_bloco.html' + template_name = "compilacao/text_list_bloco.html" def get_queryset(self): self.flag_alteradora = -1 @@ -1105,7 +1244,7 @@ class DispositivoView(TextView): self.flag_nivel_old = -1 try: - bloco = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) + bloco = Dispositivo.objects.get(pk=self.kwargs["dispositivo_id"]) except Dispositivo.DoesNotExist: return [] @@ -1113,49 +1252,57 @@ class DispositivoView(TextView): self.flag_nivel_ini = bloco.nivel proximo_bloco = Dispositivo.objects.filter( - ordem__gt=bloco.ordem, - nivel__lte=bloco.nivel, - ta_id=self.kwargs['ta_id'])[:1] + ordem__gt=bloco.ordem, nivel__lte=bloco.nivel, ta_id=self.kwargs["ta_id"] + )[:1] if proximo_bloco.count() == 0: itens = Dispositivo.objects.filter( - ordem__gte=bloco.ordem, - ta_id=self.kwargs['ta_id'] + ordem__gte=bloco.ordem, ta_id=self.kwargs["ta_id"] ).select_related(*DISPOSITIVO_SELECT_RELATED) else: itens = Dispositivo.objects.filter( ordem__gte=bloco.ordem, ordem__lt=proximo_bloco[0].ordem, - ta_id=self.kwargs['ta_id'] + ta_id=self.kwargs["ta_id"], ).select_related(*DISPOSITIVO_SELECT_RELATED) return itens class TextEditView(CompMixin, TemplateView): - template_name = 'compilacao/text_edit.html' + template_name = "compilacao/text_edit.html" def has_permission(self): self.object = self.ta return self.object.has_edit_permission(self.request) def importar_texto_materia(self, request, *args, **kwargs): - rd = redirect(to=reverse_lazy( - 'sapl.compilacao:ta_text_edit', kwargs={ - 'ta_id': self.object.id})) + rd = redirect( + to=reverse_lazy( + "sapl.compilacao:ta_text_edit", kwargs={"ta_id": self.object.id} + ) + ) if self.object.dispositivos_set.count() > 1: messages.error( request, - _('Este Texto Articulado possui conteúdo, ' - 'para fazer a importação você deve deixar ' - 'apenas uma única Articulação inicial.')) + _( + "Este Texto Articulado possui conteúdo, " + "para fazer a importação você deve deixar " + "apenas uma única Articulação inicial." + ), + ) return rd materia = self.materia_da_norma_deste_texto_articulado() if not materia: messages.error( request, - _('A Norma [{}] não está vinculada a nenhuma matéria.'.format(self.object.content_object))) + _( + "A Norma [{}] não está vinculada a nenhuma matéria.".format( + self.object.content_object + ) + ), + ) return rd self.object.dispositivos_set.all().delete() @@ -1164,82 +1311,96 @@ class TextEditView(CompMixin, TemplateView): try: ta_materia.clone_for(self.object.content_object) - #TextoArticulado.clone(ta_materia, self.object) + # TextoArticulado.clone(ta_materia, self.object) except Exception as e: messages.error( - request, - _('Ocorreu erro na importação e o procedimento foi cancelado!')) + request, _("Ocorreu erro na importação e o procedimento foi cancelado!") + ) return rd def get(self, request, *args, **kwargs): - - if 'importar_texto_materia' in request.GET: + if "importar_texto_materia" in request.GET: return self.importar_texto_materia(request, *args, **kwargs) if self.object.editing_locked: - if 'unlock' not in request.GET: + if "unlock" not in request.GET: messages.error( - request, _( - 'A edição deste Texto Articulado está bloqueada.')) - return redirect(to=reverse_lazy( - 'sapl.compilacao:ta_text', kwargs={ - 'ta_id': self.object.id})) + request, _("A edição deste Texto Articulado está bloqueada.") + ) + return redirect( + to=reverse_lazy( + "sapl.compilacao:ta_text", kwargs={"ta_id": self.object.id} + ) + ) else: # TODO - implementar logging de ação de usuário self.object.editing_locked = False self.object.privacidade = STATUS_TA_EDITION self.object.save() - messages.success(request, _( - 'Texto Articulado desbloqueado com sucesso.')) + messages.success( + request, _("Texto Articulado desbloqueado com sucesso.") + ) if self.object.content_object: self.object.content_object.save() else: - if 'lock' in request.GET or 'check' in request.GET: - + if "lock" in request.GET or "check" in request.GET: # TODO - implementar logging de ação de usuário notificacoes = self.get_notificacoes( object_list=self.object.dispositivos_set.all(), - type_notificacoes=['danger', ]) + type_notificacoes=[ + "danger", + ], + ) if notificacoes: messages.error( request, - _('Existem erros a serem corrigidos que impedem a ' - 'publicação deste Texto Articulado. ' - 'Corrija os erros apontados nas notificações.')) - self.request.session[ - 'type_notificacoes'] = ['danger', ] - return redirect(to=reverse_lazy( - 'sapl.compilacao:ta_text_notificacoes', kwargs={ - 'ta_id': self.object.id})) - - if 'lock' in request.GET: + _( + "Existem erros a serem corrigidos que impedem a " + "publicação deste Texto Articulado. " + "Corrija os erros apontados nas notificações." + ), + ) + self.request.session["type_notificacoes"] = [ + "danger", + ] + return redirect( + to=reverse_lazy( + "sapl.compilacao:ta_text_notificacoes", + kwargs={"ta_id": self.object.id}, + ) + ) + + if "lock" in request.GET: self.object.editing_locked = True self.object.privacidade = STATUS_TA_PUBLIC self.object.save() - messages.success(request, _( - 'Texto Articulado publicado com sucesso.')) + messages.success( + request, _("Texto Articulado publicado com sucesso.") + ) else: self.object.temp_check_migrations = True self.object.save() - messages.success(request, _( - 'Texto Articulado Checado...')) + messages.success(request, _("Texto Articulado Checado...")) if self.object.content_object: self.object.content_object.save() - return redirect(to=reverse_lazy( - 'sapl.compilacao:ta_text', kwargs={ - 'ta_id': self.object.id})) + return redirect( + to=reverse_lazy( + "sapl.compilacao:ta_text", kwargs={"ta_id": self.object.id} + ) + ) return TemplateView.get(self, request, *args, **kwargs) def get_context_data(self, **kwargs): - dispositivo_id = int(self.kwargs['dispositivo_id']) \ - if 'dispositivo_id' in self.kwargs else 0 + dispositivo_id = ( + int(self.kwargs["dispositivo_id"]) if "dispositivo_id" in self.kwargs else 0 + ) if dispositivo_id: self.object = Dispositivo.objects.get(pk=dispositivo_id) @@ -1247,14 +1408,14 @@ class TextEditView(CompMixin, TemplateView): context = super(TemplateView, self).get_context_data(**kwargs) if not dispositivo_id: - ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id']) + ta = TextoArticulado.objects.get(pk=self.kwargs["ta_id"]) self.object = ta - context['object'] = self.object - context['dispositivos_list'] = self.dispositivos_list() + context["object"] = self.object + context["dispositivos_list"] = self.dispositivos_list() - if 'action' in self.request.GET: - context['action'] = self.request.GET['action'] + if "action" in self.request.GET: + context["action"] = self.request.GET["action"] return context @@ -1263,10 +1424,10 @@ class TextEditView(CompMixin, TemplateView): tds = {td.pk: td for td in TipoDispositivo.objects.all()} - dispositivo_id = int(self.kwargs['dispositivo_id']) \ - if 'dispositivo_id' in self.kwargs else 0 - ta_id = int(self.kwargs['ta_id']) \ - if 'ta_id' in self.kwargs else 0 + dispositivo_id = ( + int(self.kwargs["dispositivo_id"]) if "dispositivo_id" in self.kwargs else 0 + ) + ta_id = int(self.kwargs["ta_id"]) if "ta_id" in self.kwargs else 0 q = Q(ta_id=ta_id) @@ -1275,43 +1436,50 @@ class TextEditView(CompMixin, TemplateView): if dispositivo_id: bloco = Dispositivo.objects.get(pk=dispositivo_id) - if (tds[bloco.tipo_dispositivo_id].dispositivo_de_alteracao and - not tds[bloco.tipo_dispositivo_id - ].dispositivo_de_articulacao) or ( - bloco.ta_id != ta_id and bloco.ta_publicado_id == ta_id): - dispositivos = [bloco, ] + if ( + tds[bloco.tipo_dispositivo_id].dispositivo_de_alteracao + and not tds[bloco.tipo_dispositivo_id].dispositivo_de_articulacao + ) or (bloco.ta_id != ta_id and bloco.ta_publicado_id == ta_id): + dispositivos = [ + bloco, + ] else: proximo_bloco = Dispositivo.objects.filter( - ordem__gt=bloco.ordem, - nivel__lte=bloco.nivel, - ta_id=ta_id)[:1] + ordem__gt=bloco.ordem, nivel__lte=bloco.nivel, ta_id=ta_id + )[:1] if not proximo_bloco.exists(): q = q & Q(ordem__gte=bloco.ordem) else: - q = q & Q(ordem__gte=bloco.ordem) & \ - Q(ordem__lt=proximo_bloco[0].ordem) + q = ( + q + & Q(ordem__gte=bloco.ordem) + & Q(ordem__lt=proximo_bloco[0].ordem) + ) dispositivos_de_alteracao = Dispositivo.objects.filter( ta_id=ta_id, tipo_dispositivo__dispositivo_de_alteracao=True, - tipo_dispositivo__dispositivo_de_articulacao=False + tipo_dispositivo__dispositivo_de_articulacao=False, ).select_related(*DISPOSITIVO_SELECT_RELATED_EDIT) if not dispositivos: - dispositivos = Dispositivo.objects.filter( - q).select_related(*DISPOSITIVO_SELECT_RELATED_EDIT) + dispositivos = Dispositivo.objects.filter(q).select_related( + *DISPOSITIVO_SELECT_RELATED_EDIT + ) - dispositivos_alterados = Dispositivo.objects.filter( - ta_publicado_id=ta_id) + dispositivos_alterados = Dispositivo.objects.filter(ta_publicado_id=ta_id) dispositivos_alteradores = Dispositivo.objects.filter( - dispositivos_alterados_set__ta_id=ta_id) + dispositivos_alterados_set__ta_id=ta_id + ) - dpts = list(dispositivos) + \ - list(dispositivos_de_alteracao) + \ - list(dispositivos_alterados) + \ - list(dispositivos_alteradores) + dpts = ( + list(dispositivos) + + list(dispositivos_de_alteracao) + + list(dispositivos_alterados) + + list(dispositivos_alteradores) + ) tas_pub = [d.ta_publicado for d in dispositivos if d.ta_publicado] tas_pub = set(tas_pub) @@ -1319,66 +1487,74 @@ class TextEditView(CompMixin, TemplateView): for ta in tas_pub: lista_ta_publicado[ta.pk] = str(ta) - dpts = {d.pk: { - 'dpt': d, - 'filhos': [], - 'alts': [], - 'pai': None, - 'st': None, # dispositivo substituido - 'sq': None, # dispositivo subsequente - 'da': None, # dispositivo atualizador - 'td': tds[d.tipo_dispositivo_id], # tipo do dispositivo - 'na': self.nota_alteracao(d, lista_ta_publicado)\ - if d.ta_id == ta_id else None - } for d in dpts} + dpts = { + d.pk: { + "dpt": d, + "filhos": [], + "alts": [], + "pai": None, + "st": None, # dispositivo substituido + "sq": None, # dispositivo subsequente + "da": None, # dispositivo atualizador + "td": tds[d.tipo_dispositivo_id], # tipo do dispositivo + "na": self.nota_alteracao(d, lista_ta_publicado) + if d.ta_id == ta_id + else None, + } + for d in dpts + } apagar = [] for d in dispositivos: try: if d.dispositivo_substituido_id: - dpts[d.pk]['st'] = dpts[d.dispositivo_substituido_id] + dpts[d.pk]["st"] = dpts[d.dispositivo_substituido_id] except: pass try: if d.dispositivo_subsequente_id: - dpts[d.pk]['sq'] = dpts[d.dispositivo_subsequente_id] + dpts[d.pk]["sq"] = dpts[d.dispositivo_subsequente_id] except: pass try: if d.dispositivo_atualizador_id: - dpts[d.pk]['da'] = dpts[d.dispositivo_atualizador_id] + dpts[d.pk]["da"] = dpts[d.dispositivo_atualizador_id] except: pass try: if d.dispositivo_pai_id: - """ Pode não ser possível vincular a estrutura do pai + """Pode não ser possível vincular a estrutura do pai devido a busca de bloco não envolver o pai do bloco, por isso os try's except's""" - dpts[d.pk]['pai'] = dpts[d.dispositivo_pai_id] + dpts[d.pk]["pai"] = dpts[d.dispositivo_pai_id] - if tds[d.tipo_dispositivo_id].\ - dispositivo_de_alteracao and not\ - tds[d.tipo_dispositivo_id].\ - dispositivo_de_articulacao: + if ( + tds[d.tipo_dispositivo_id].dispositivo_de_alteracao + and not tds[d.tipo_dispositivo_id].dispositivo_de_articulacao + ): apagar.append(d.pk) else: - dpts[d.dispositivo_pai_id]['filhos'].append(dpts[d.pk]) + dpts[d.dispositivo_pai_id]["filhos"].append(dpts[d.pk]) apagar.append(d.pk) except: pass try: - if tds[d.tipo_dispositivo_id].dispositivo_de_alteracao and\ - tds[d.tipo_dispositivo_id].dispositivo_de_articulacao: - - alts = Dispositivo.objects.values_list( - 'pk', flat=True).order_by( - 'ordem_bloco_atualizador').filter( - Q(dispositivo_pai_id=d.pk) | - Q(dispositivo_atualizador_id=d.pk)) + if ( + tds[d.tipo_dispositivo_id].dispositivo_de_alteracao + and tds[d.tipo_dispositivo_id].dispositivo_de_articulacao + ): + alts = ( + Dispositivo.objects.values_list("pk", flat=True) + .order_by("ordem_bloco_atualizador") + .filter( + Q(dispositivo_pai_id=d.pk) + | Q(dispositivo_atualizador_id=d.pk) + ) + ) for dAlt in alts: - dpts[d.pk]['alts'].append(dpts[dAlt]) - dpts[dAlt]['da'] = dpts[d.pk] + dpts[d.pk]["alts"].append(dpts[dAlt]) + dpts[dAlt]["da"] = dpts[d.pk] except: pass @@ -1398,45 +1574,52 @@ class TextEditView(CompMixin, TemplateView): if d.auto_inserido: d = d.dispositivo_pai - ta_publicado = lista_ta_publicado[dispositivo.ta_publicado_id] if\ - lista_ta_publicado else dispositivo.ta_publicado + ta_publicado = ( + lista_ta_publicado[dispositivo.ta_publicado_id] + if lista_ta_publicado + else dispositivo.ta_publicado + ) if dispositivo.dispositivo_de_revogacao: - return _('Revogado pelo %s - %s.') % ( - d, ta_publicado) + return _("Revogado pelo %s - %s.") % (d, ta_publicado) elif not dispositivo.dispositivo_substituido_id: - return _('Inclusão feita pelo %s - %s.') % ( - d, ta_publicado) + return _("Inclusão feita pelo %s - %s.") % (d, ta_publicado) else: - return _('Alteração feita pelo %s - %s.') % ( - d, ta_publicado) + return _("Alteração feita pelo %s - %s.") % (d, ta_publicado) - return '' + return "" def materia_da_norma_deste_texto_articulado(self): - NormaJuridica = apps.get_model( - 'norma', 'NormaJuridica') + NormaJuridica = apps.get_model("norma", "NormaJuridica") ta = self.ta - if isinstance(ta.content_object, NormaJuridica) and\ - ta.content_object.materia: + if isinstance(ta.content_object, NormaJuridica) and ta.content_object.materia: return ta.content_object.materia return None def runBase(self): - result = Dispositivo.objects.filter(ta_id=self.kwargs['ta_id']) + result = Dispositivo.objects.filter(ta_id=self.kwargs["ta_id"]) if not result.exists(): # FIXME a inserção básica deve ser refatorada para não depender # das classes css ta = self.object - td = TipoDispositivo.objects.filter(class_css='articulacao')[0] + td = TipoDispositivo.objects.filter(class_css="articulacao")[0] a = Dispositivo() a.nivel = 0 a.ordem = Dispositivo.INTERVALO_ORDEM a.ordem_bloco_atualizador = 0 - a.set_numero_completo([1, 0, 0, 0, 0, 0, ]) + a.set_numero_completo( + [ + 1, + 0, + 0, + 0, + 0, + 0, + ] + ) a.ta = ta a.tipo_dispositivo = td a.inicio_vigencia = ta.data @@ -1445,12 +1628,21 @@ class TextEditView(CompMixin, TemplateView): return - td = TipoDispositivo.objects.filter(class_css='ementa')[0] + td = TipoDispositivo.objects.filter(class_css="ementa")[0] e = Dispositivo() e.nivel = 1 e.ordem = a.ordem + Dispositivo.INTERVALO_ORDEM e.ordem_bloco_atualizador = 0 - e.set_numero_completo([1, 0, 0, 0, 0, 0, ]) + e.set_numero_completo( + [ + 1, + 0, + 0, + 0, + 0, + 0, + ] + ) e.ta = ta e.tipo_dispositivo = td e.inicio_vigencia = ta.data @@ -1463,27 +1655,37 @@ class TextEditView(CompMixin, TemplateView): a.nivel = 0 a.ordem = e.ordem + Dispositivo.INTERVALO_ORDEM a.ordem_bloco_atualizador = 0 - a.set_numero_completo([2, 0, 0, 0, 0, 0, ]) + a.set_numero_completo( + [ + 2, + 0, + 0, + 0, + 0, + 0, + ] + ) a.save() class ActionsCommonsMixin: - def set_message(self, data, _type, message, time=None, modal=False): - data['message'] = { - 'type': _type, - 'value': str(message)} + data["message"] = {"type": _type, "value": str(message)} if time: - data['message']['time'] = time - data['message']['modal'] = modal + data["message"]["time"] = time + data["message"]["modal"] = modal return def get_json_for_refresh(self, dp, dpauto=None): - if dp.tipo_dispositivo.contagem_continua: pais = [] if dp.dispositivo_pai is None: - data = {'pk': dp.pk, 'pai': [-1, ]} + data = { + "pk": dp.pk, + "pai": [ + -1, + ], + } else: pkfilho = dp.pk dp = dp.dispositivo_pai @@ -1495,12 +1697,12 @@ class ActionsCommonsMixin: ta_id=dp.ta_id, ordem__gte=dp.ordem, ordem__lt=proxima_articulacao.ordem, - nivel__lte=dp.nivel) + nivel__lte=dp.nivel, + ) else: parents = Dispositivo.objects.filter( - ta_id=dp.ta_id, - ordem__gte=dp.ordem, - nivel__lte=dp.nivel) + ta_id=dp.ta_id, ordem__gte=dp.ordem, nivel__lte=dp.nivel + ) nivel = sys.maxsize for p in parents: @@ -1508,38 +1710,39 @@ class ActionsCommonsMixin: continue pais.append(p.pk) nivel = p.nivel - data = { - 'pk': pkfilho if not dpauto else dpauto.pk, 'pai': pais} + data = {"pk": pkfilho if not dpauto else dpauto.pk, "pai": pais} else: - data = {'pk': dp.pk if not dpauto else dpauto.pk, 'pai': [ - dp.dispositivo_pai.pk, ]} + data = { + "pk": dp.pk if not dpauto else dpauto.pk, + "pai": [ + dp.dispositivo_pai.pk, + ], + } return data class ActionDragAndMoveDispositivoAlteradoMixin(ActionsCommonsMixin): - def json_drag_move_dpt_alterado(self, context): - - bloco = Dispositivo.objects.get(pk=self.request.GET['bloco_pk']) - dpt = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) + bloco = Dispositivo.objects.get(pk=self.request.GET["bloco_pk"]) + dpt = Dispositivo.objects.get(pk=self.kwargs["dispositivo_id"]) if dpt.tipo_dispositivo.dispositivo_de_alteracao: dpt.dispositivo_pai = bloco else: dpt.dispositivo_atualizador = bloco - filhos = Dispositivo.objects.order_by( - 'ordem_bloco_atualizador').filter( - Q(dispositivo_pai_id=bloco.pk) | - Q(dispositivo_atualizador_id=bloco.pk)) + filhos = Dispositivo.objects.order_by("ordem_bloco_atualizador").filter( + Q(dispositivo_pai_id=bloco.pk) | Q(dispositivo_atualizador_id=bloco.pk) + ) if not filhos.exists(): dpt.ordem_bloco_atualizador = Dispositivo.INTERVALO_ORDEM else: - index = int(self.request.GET['index']) - fpks = filhos.values_list( - 'pk', flat=True).order_by('ordem_bloco_atualizador') + index = int(self.request.GET["index"]) + fpks = filhos.values_list("pk", flat=True).order_by( + "ordem_bloco_atualizador" + ) index_dpt = 0 try: @@ -1547,17 +1750,15 @@ class ActionDragAndMoveDispositivoAlteradoMixin(ActionsCommonsMixin): except: pass - filho_index = filhos[ - index if index_dpt >= index - else index + 1] if ( - index if index_dpt >= index - else index + 1) < filhos.count() else filhos.last() + filho_index = ( + filhos[index if index_dpt >= index else index + 1] + if (index if index_dpt >= index else index + 1) < filhos.count() + else filhos.last() + ) if filhos.last() == filho_index: - dpt.ordem_bloco_atualizador = \ - filho_index.ordem_bloco_atualizador + 1 + dpt.ordem_bloco_atualizador = filho_index.ordem_bloco_atualizador + 1 else: - dpt.ordem_bloco_atualizador = \ - filho_index.ordem_bloco_atualizador - 1 + dpt.ordem_bloco_atualizador = filho_index.ordem_bloco_atualizador - 1 dpt.save() bloco.ordenar_bloco_alteracao() @@ -1566,20 +1767,20 @@ class ActionDragAndMoveDispositivoAlteradoMixin(ActionsCommonsMixin): class ActionDeleteDispositivoMixin(ActionsCommonsMixin): - logger = logging.getLogger(__name__) def json_delete_item_dispositivo(self, context): return self.json_delete_bloco_dispositivo(context, bloco=False) def json_delete_bloco_dispositivo(self, context, bloco=True): - base = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) + base = Dispositivo.objects.get(pk=self.kwargs["dispositivo_id"]) ta_base = base.ta - base_anterior = Dispositivo.objects.order_by('-ordem').filter( - ta_id=base.ta_id, - ordem__lt=base.ordem - ).first() + base_anterior = ( + Dispositivo.objects.order_by("-ordem") + .filter(ta_id=base.ta_id, ordem__lt=base.ordem) + .first() + ) data = {} if not base_anterior or base == base.get_raiz(): @@ -1589,34 +1790,38 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): data = self.get_json_for_refresh(base_anterior) if base == base_anterior: - data['pk'] = base.pk - self.set_message(data, 'danger', _( - 'Base Inicial não pode ser removida!'), modal=True) + data["pk"] = base.pk + self.set_message( + data, "danger", _("Base Inicial não pode ser removida!"), modal=True + ) else: if base != base.get_raiz(): - data['pai'] = [base.get_raiz().pk] + data["pai"] = [base.get_raiz().pk] - if ta_base.id != int(self.kwargs['ta_id']): - data['pai'] = [base.dispositivo_atualizador.pk] - data['pk'] = base.dispositivo_atualizador.pk + if ta_base.id != int(self.kwargs["ta_id"]): + data["pai"] = [base.dispositivo_atualizador.pk] + data["pk"] = base.dispositivo_atualizador.pk try: with transaction.atomic(): message = str(self.remover_dispositivo(base, bloco)) if message: - self.set_message(data, 'warning', message, modal=True) + self.set_message(data, "warning", message, modal=True) else: - self.set_message(data, 'success', _( - 'Exclusão efetuada com sucesso!'), modal=True) + self.set_message( + data, + "success", + _("Exclusão efetuada com sucesso!"), + modal=True, + ) ta_base.reagrupar_ordem_de_dispositivos() except Exception as e: - data['pk'] = self.kwargs['dispositivo_id'] - self.set_message(data, 'danger', str(e), modal=True) + data["pk"] = self.kwargs["dispositivo_id"] + self.set_message(data, "danger", str(e), modal=True) return data def remover_dispositivo(self, base, bloco): - if base.tipo_dispositivo.dispositivo_de_alteracao: bloco = False for d in base.dispositivos_alterados_set.all(): @@ -1649,7 +1854,7 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): p.dispositivos_filhos_set.add(d) p.save() except Exception as e: - self.logger.error("user=" + username + '. ' + str(e)) + self.logger.error("user=" + username + ". " + str(e)) print(e) base.delete() else: @@ -1661,7 +1866,7 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): # inserções automáticas são excluidas junto com sua base, # independente da escolha do usuário - """ TODO: Criar possibilidade de transferência de filhos + """TODO: Criar possibilidade de transferência de filhos de dispositivos automáticos ex: na exclusão de artigos, na versão atual, os caputs serão excluidos automáticamente mesmo que a @@ -1677,79 +1882,122 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): # possível dos parents do dispostivo # imediatamente anterior ao dispositivo base - anterior = Dispositivo.objects.order_by('-ordem').filter( - ta_id=base.ta_id, - ordem__lt=d.ordem).exclude( - pk=base.pk).exclude( - dispositivo_pai=base).first() + anterior = ( + Dispositivo.objects.order_by("-ordem") + .filter(ta_id=base.ta_id, ordem__lt=d.ordem) + .exclude(pk=base.pk) + .exclude(dispositivo_pai=base) + .first() + ) if not anterior: - self.logger.error("user=" + username + ". Não é possível excluir este Dispositivo (id={}) sem" - " excluir toda a sua estrutura!!!".format(base.id)) + self.logger.error( + "user=" + + username + + ". Não é possível excluir este Dispositivo (id={}) sem" + " excluir toda a sua estrutura!!!".format(base.id) + ) raise Exception( - _('Não é possível excluir este Dispositivo sem' - ' excluir toda a sua estrutura!!!')) + _( + "Não é possível excluir este Dispositivo sem" + " excluir toda a sua estrutura!!!" + ) + ) if anterior.tipo_dispositivo == d.tipo_dispositivo: d.dispositivo_pai = anterior.dispositivo_pai d.nivel = anterior.nivel if not d.tipo_dispositivo.contagem_continua: - d.set_numero_completo( - anterior.get_numero_completo()) + d.set_numero_completo(anterior.get_numero_completo()) if d.dispositivo_substituido != anterior: d.transform_in_next() d.rotulo = d.rotulo_padrao() else: - parents = [anterior, ] + anterior.get_parents() + parents = [ + anterior, + ] + anterior.get_parents() for candidato in parents: if candidato == base: - self.logger.error("user=" + username + ". Não é possível excluir este " - "Dispositivo (id={}) sem " - "excluir toda a sua estrutura!!!".format(candidato.id)) + self.logger.error( + "user=" + + username + + ". Não é possível excluir este " + "Dispositivo (id={}) sem " + "excluir toda a sua estrutura!!!".format( + candidato.id + ) + ) raise Exception( - _('Não é possível excluir este ' - 'Dispositivo sem ' - 'excluir toda a sua estrutura!!!')) - if (candidato.tipo_dispositivo == - d.tipo_dispositivo): + _( + "Não é possível excluir este " + "Dispositivo sem " + "excluir toda a sua estrutura!!!" + ) + ) + if candidato.tipo_dispositivo == d.tipo_dispositivo: d.dispositivo_pai = candidato.dispositivo_pai d.nivel = candidato.nivel if not d.tipo_dispositivo.contagem_continua: d.set_numero_completo( - candidato.get_numero_completo()) + candidato.get_numero_completo() + ) if d.dispositivo_substituido != candidato: d.transform_in_next() d.rotulo = d.rotulo_padrao() break - elif (candidato.tipo_dispositivo == - d.dispositivo_pai.tipo_dispositivo): + elif ( + candidato.tipo_dispositivo + == d.dispositivo_pai.tipo_dispositivo + ): d.dispositivo_pai = candidato d.nivel = candidato.nivel + 1 break elif d.tipo_dispositivo.possiveis_pais.filter( - pai=candidato.tipo_dispositivo, - perfil__padrao=True).exists(): + pai=candidato.tipo_dispositivo, perfil__padrao=True + ).exists(): d.dispositivo_pai = candidato - if ';' in d.tipo_dispositivo.\ - rotulo_prefixo_texto: - d.set_numero_completo([0, 0, 0, 0, 0, 0, ]) + if ";" in d.tipo_dispositivo.rotulo_prefixo_texto: + d.set_numero_completo( + [ + 0, + 0, + 0, + 0, + 0, + 0, + ] + ) else: - d.set_numero_completo([1, 0, 0, 0, 0, 0, ]) + d.set_numero_completo( + [ + 1, + 0, + 0, + 0, + 0, + 0, + ] + ) d.nivel = candidato.nivel + 1 d.rotulo = d.rotulo_padrao() break else: - self.logger.error("user=" + username + ". Não é possível excluir este " - "Dispositivo (id={}) sem excluir toda " - "a sua estrutura!!!".format(candidato.id)) + self.logger.error( + "user=" + username + ". Não é possível excluir este " + "Dispositivo (id={}) sem excluir toda " + "a sua estrutura!!!".format(candidato.id) + ) raise Exception( - _('Não é possível excluir este ' - 'Dispositivo sem ' - 'excluir toda a sua estrutura!!!')) + _( + "Não é possível excluir este " + "Dispositivo sem " + "excluir toda a sua estrutura!!!" + ) + ) if not parents: d.dispositivo_pai = anterior @@ -1764,22 +2012,24 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): # Localizar irmaos posteriores do mesmo tipo de base # se não DCC if not base.tipo_dispositivo.contagem_continua: - irmaos_posteriores = pai_base.dispositivos_filhos_set.\ - filter( - ordem__gt=base_ordem, - tipo_dispositivo=base.tipo_dispositivo) + irmaos_posteriores = pai_base.dispositivos_filhos_set.filter( + ordem__gt=base_ordem, tipo_dispositivo=base.tipo_dispositivo + ) # se DCC else: irmaos_posteriores = Dispositivo.objects.order_by( - 'ordem').filter( + "ordem" + ).filter( ta_id=base.ta_id, ordem__gt=base_ordem, - tipo_dispositivo_id=base.tipo_dispositivo_id) + tipo_dispositivo_id=base.tipo_dispositivo_id, + ) if proxima_articulacao: irmaos_posteriores = irmaos_posteriores.exclude( - ordem__gte=proxima_articulacao.ordem) + ordem__gte=proxima_articulacao.ordem + ) # excluir e renumerar irmaos profundidade_base = base.get_profundidade() @@ -1788,41 +2038,48 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): for irmao in irmaos_posteriores: try: - irmao.transform_in_prior( - profundidade=profundidade_base) + irmao.transform_in_prior(profundidade=profundidade_base) irmao.rotulo = irmao.rotulo_padrao() irmao.save() except Exception as e: - self.logger.error( - "user=" + username + "." + str(e)) + self.logger.error("user=" + username + "." + str(e)) break - irmaos = pai_base.dispositivos_filhos_set.\ - filter(tipo_dispositivo=base.tipo_dispositivo) + irmaos = pai_base.dispositivos_filhos_set.filter( + tipo_dispositivo=base.tipo_dispositivo + ) - if (irmaos.count() == 1 and - ';' in irmaos[0]. - tipo_dispositivo.rotulo_prefixo_texto): + if ( + irmaos.count() == 1 + and ";" in irmaos[0].tipo_dispositivo.rotulo_prefixo_texto + ): i = irmaos[0] - i.set_numero_completo([0, 0, 0, 0, 0, 0, ]) + i.set_numero_completo( + [ + 0, + 0, + 0, + 0, + 0, + 0, + ] + ) i.rotulo = i.rotulo_padrao(local_insert=1) i.save() - if not irmaos.exists() and \ - auto_inserido_base and \ - pai_base.nivel: + if not irmaos.exists() and auto_inserido_base and pai_base.nivel: self.remover_dispositivo(pai_base, False) else: # Renumerar Dispostivos de Contagem Contínua # de dentro da base se pai - dcc = Dispositivo.objects.order_by('ordem').filter( + dcc = Dispositivo.objects.order_by("ordem").filter( ta_id=base.ta_id, ordem__gt=base.ordem, - tipo_dispositivo__contagem_continua=True) + tipo_dispositivo__contagem_continua=True, + ) if proxima_articulacao: - dcc = dcc.exclude( - ordem__gte=proxima_articulacao.ordem) + dcc = dcc.exclude(ordem__gte=proxima_articulacao.ordem) base_adicao = {} @@ -1834,25 +2091,27 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): dcc = list(dcc) for d in dcc: # ultimo DCC do tipo encontrado - if d.tipo_dispositivo.class_css not in base_adicao: - ultimo_dcc = Dispositivo.objects.order_by( - 'ordem').filter( - ta_id=base.ta_id, - ordem__lt=base.ordem, - ordem__gt=nivel_zero_anterior, - tipo_dispositivo__contagem_continua=True, - tipo_dispositivo=d.tipo_dispositivo).last() + ultimo_dcc = ( + Dispositivo.objects.order_by("ordem") + .filter( + ta_id=base.ta_id, + ordem__lt=base.ordem, + ordem__gt=nivel_zero_anterior, + tipo_dispositivo__contagem_continua=True, + tipo_dispositivo=d.tipo_dispositivo, + ) + .last() + ) if not ultimo_dcc: break base_adicao[ - d.tipo_dispositivo.class_css] = ultimo_dcc.\ - dispositivo0 + d.tipo_dispositivo.class_css + ] = ultimo_dcc.dispositivo0 - d.dispositivo0 += base_adicao[ - d.tipo_dispositivo.class_css] + d.dispositivo0 += base_adicao[d.tipo_dispositivo.class_css] d.rotulo = d.rotulo_padrao() dcc.reverse() @@ -1863,44 +2122,47 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): # em Bloco else: - # Religar numeração de dispositivos de contagem contínua # que serão excluidos # pbi - proxima base independente - pbi = Dispositivo.objects.\ - order_by('ordem').filter( - ta_id=base.ta_id, - ordem__gt=base_ordem, - nivel__lte=base.nivel).first() + pbi = ( + Dispositivo.objects.order_by("ordem") + .filter( + ta_id=base.ta_id, ordem__gt=base_ordem, nivel__lte=base.nivel + ) + .first() + ) if pbi: - dcc_a_excluir = Dispositivo.objects.order_by( - 'ordem').filter( + dcc_a_excluir = Dispositivo.objects.order_by("ordem").filter( ta_id=base.ta_id, ordem__gte=base_ordem, ordem__lt=pbi.ordem, - tipo_dispositivo__contagem_continua=True) + tipo_dispositivo__contagem_continua=True, + ) if proxima_articulacao: dcc_a_excluir = dcc_a_excluir.exclude( - ordem__gte=proxima_articulacao.ordem) + ordem__gte=proxima_articulacao.ordem + ) religado = {} for d in dcc_a_excluir: if d.tipo_dispositivo.class_css in religado: continue - religado[ - d.tipo_dispositivo.class_css] = d.dispositivo0 + religado[d.tipo_dispositivo.class_css] = d.dispositivo0 dcc_a_religar = Dispositivo.objects.filter( ta_id=d.ta_id, ordem__gte=pbi.ordem, - tipo_dispositivo=d.tipo_dispositivo) + tipo_dispositivo=d.tipo_dispositivo, + ) if proxima_articulacao: dcc_a_religar = dcc_a_religar.exclude( - ordem__gte=proxima_articulacao.ordem) + ordem__gte=proxima_articulacao.ordem + ) primeiro_a_religar = True profundidade = d.get_profundidade() @@ -1917,8 +2179,7 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): try: dr.save(clean=base != dr) except Exception as e: - self.logger.error( - "user=" + username + ". " + str(e)) + self.logger.error("user=" + username + ". " + str(e)) break # Pode não ser religavável @@ -1938,7 +2199,8 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): if base.tipo_dispositivo.dispositivo_de_alteracao: dpts = base.dispositivos_alterados_set.all().order_by( - '-ordem_bloco_atualizador') + "-ordem_bloco_atualizador" + ) for dpt in dpts: try: self.remover_dispositivo(dpt, False) @@ -1956,49 +2218,53 @@ class ActionDeleteDispositivoMixin(ActionsCommonsMixin): continua internos extra bloco. Depois do bloco limpo, a função é chamada novamente para excluir realmente a escolha do usuário - e religar seus irmaos + e religar seus irmaos """ self.remover_dispositivo(base, False) - return '' + return "" class ActionDispositivoCreateMixin(ActionsCommonsMixin): - logger = logging.getLogger(__name__) def allowed_inserts(self, _base=None): request = self.request try: base = Dispositivo.objects.get( - pk=self.kwargs['dispositivo_id'] if not _base else _base) + pk=self.kwargs["dispositivo_id"] if not _base else _base + ) result = [ { - 'tipo_insert': force_str("{} {}".format(_('Inserir Após'), base.tipo_dispositivo.nome)), - 'icone': '↷ ', - 'action': 'json_add_next', - 'itens': []}, + "tipo_insert": force_str( + "{} {}".format(_("Inserir Após"), base.tipo_dispositivo.nome) + ), + "icone": "↷ ", + "action": "json_add_next", + "itens": [], + }, { - 'tipo_insert': force_str("{} {}".format(_('Inserir em'), base.tipo_dispositivo.nome)), - 'icone': '⇲ ', - 'action': 'json_add_in', - 'itens': [] + "tipo_insert": force_str( + "{} {}".format(_("Inserir em"), base.tipo_dispositivo.nome) + ), + "icone": "⇲ ", + "action": "json_add_in", + "itens": [], }, { - 'tipo_insert': force_str(_('Inserir Antes')), - 'icone': '↶ ', - 'action': 'json_add_prior', - 'itens': [] - } + "tipo_insert": force_str(_("Inserir Antes")), + "icone": "↶ ", + "action": "json_add_prior", + "itens": [], + }, ] - perfil_pk = request.session['perfil_estrutural'] + perfil_pk = request.session["perfil_estrutural"] prox_possivel = Dispositivo.objects.filter( - ordem__gt=base.ordem, - nivel__lte=base.nivel, - ta_id=base.ta_id)[:1] + ordem__gt=base.ordem, nivel__lte=base.nivel, ta_id=base.ta_id + )[:1] if prox_possivel.exists(): prox_possivel = prox_possivel[0] @@ -2010,20 +2276,20 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): parents.insert(0, base) nivel = sys.maxsize for dp in parents: - if dp.nivel >= nivel: continue if dp.auto_inserido: continue - if prox_possivel and \ - dp.tipo_dispositivo != base.tipo_dispositivo and\ - dp.nivel < prox_possivel.nivel and\ - not prox_possivel.tipo_dispositivo.permitido_inserir_in( - dp.tipo_dispositivo, - perfil_pk=perfil_pk): - + if ( + prox_possivel + and dp.tipo_dispositivo != base.tipo_dispositivo + and dp.nivel < prox_possivel.nivel + and not prox_possivel.tipo_dispositivo.permitido_inserir_in( + dp.tipo_dispositivo, perfil_pk=perfil_pk + ) + ): if dp.tipo_dispositivo != prox_possivel.tipo_dispositivo: continue @@ -2031,19 +2297,24 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): # um do mesmo para inserção antes if dp == base: - result[2]['itens'].append({ - 'class_css': dp.tipo_dispositivo.class_css, - 'tipo_pk': dp.tipo_dispositivo.pk, - 'variacao': 0, - 'provavel': '%s (%s)' % ( - dp.rotulo_padrao(local_insert=1), - dp.tipo_dispositivo.nome,), - 'dispositivo_base': base.pk}) + result[2]["itens"].append( + { + "class_css": dp.tipo_dispositivo.class_css, + "tipo_pk": dp.tipo_dispositivo.pk, + "variacao": 0, + "provavel": "%s (%s)" + % ( + dp.rotulo_padrao(local_insert=1), + dp.tipo_dispositivo.nome, + ), + "dispositivo_base": base.pk, + } + ) if dp.dispositivo_pai: flag_pv = dp.tipo_dispositivo.permitido_variacao( - dp.dispositivo_pai.tipo_dispositivo, - perfil_pk=perfil_pk) + dp.dispositivo_pai.tipo_dispositivo, perfil_pk=perfil_pk + ) else: flag_pv = False @@ -2060,30 +2331,42 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): if not rt[0]: break flag_variacao += rt[1] - r.append({'class_css': dp.tipo_dispositivo.class_css, - 'tipo_pk': dp.tipo_dispositivo.pk, - 'variacao': flag_variacao, - 'provavel': '%s (%s)' % ( - dp.rotulo_padrao(local_insert), - dp.tipo_dispositivo.nome,), - 'dispositivo_base': base.pk}) + r.append( + { + "class_css": dp.tipo_dispositivo.class_css, + "tipo_pk": dp.tipo_dispositivo.pk, + "variacao": flag_variacao, + "provavel": "%s (%s)" + % ( + dp.rotulo_padrao(local_insert), + dp.tipo_dispositivo.nome, + ), + "dispositivo_base": base.pk, + } + ) flag_direcao = -1 r.reverse() if not flag_pv: - r = [r[0], ] - - if len(r) > 0 and dp.tipo_dispositivo.formato_variacao0 == \ - TipoDispositivo.FNCN: - r = [r[0], ] + r = [ + r[0], + ] + + if ( + len(r) > 0 + and dp.tipo_dispositivo.formato_variacao0 == TipoDispositivo.FNCN + ): + r = [ + r[0], + ] if dp.tipo_dispositivo == base.tipo_dispositivo: - result[0]['itens'] += r + result[0]["itens"] += r else: - result[0]['itens'] += r - result[2]['itens'] += r + result[0]["itens"] += r + result[2]["itens"] += r if nivel == 0: break @@ -2095,44 +2378,45 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): if paradentro: # Outros Tipos de Dispositivos PARA DENTRO otds = TipoDispositivo.objects.order_by( - '-contagem_continua', 'id').all() + "-contagem_continua", "id" + ).all() else: # Outros Tipos de Dispositivos PARA FORA classes_ja_inseridas = [] - for c in result[0]['itens']: - if c['class_css'] not in classes_ja_inseridas: - classes_ja_inseridas.append(c['class_css']) - for c in result[1]['itens']: - if c['class_css'] not in classes_ja_inseridas: - classes_ja_inseridas.append(c['class_css']) - otds = TipoDispositivo.objects.order_by( - '-contagem_continua', 'id').all().exclude( - class_css__in=classes_ja_inseridas) + for c in result[0]["itens"]: + if c["class_css"] not in classes_ja_inseridas: + classes_ja_inseridas.append(c["class_css"]) + for c in result[1]["itens"]: + if c["class_css"] not in classes_ja_inseridas: + classes_ja_inseridas.append(c["class_css"]) + otds = ( + TipoDispositivo.objects.order_by("-contagem_continua", "id") + .all() + .exclude(class_css__in=classes_ja_inseridas) + ) for td in otds: - if td.dispositivo_de_alteracao: if not self.request.user.has_perm( - 'compilacao.' - 'change_dispositivo_registros_compilacao'): + "compilacao." "change_dispositivo_registros_compilacao" + ): continue if paradentro and not td.permitido_inserir_in( - tipb, - include_relative_autos=True, - perfil_pk=perfil_pk): + tipb, include_relative_autos=True, perfil_pk=perfil_pk + ): continue base.tipo_dispositivo = td if not paradentro: - flag_insercao = False for possivelpai in parents: if td.permitido_inserir_in( possivelpai.tipo_dispositivo, include_relative_autos=True, - perfil_pk=perfil_pk): + perfil_pk=perfil_pk, + ): flag_insercao = True break @@ -2144,24 +2428,26 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): if prox_possivel: if prox_possivel.nivel == base.nivel: - if prox_possivel.tipo_dispositivo != td and\ - not prox_possivel.tipo_dispositivo.\ - permitido_inserir_in( - td, perfil_pk=perfil_pk): + if ( + prox_possivel.tipo_dispositivo != td + and not prox_possivel.tipo_dispositivo.permitido_inserir_in( + td, perfil_pk=perfil_pk + ) + ): continue else: - if possivelpai.tipo_dispositivo != \ - prox_possivel.tipo_dispositivo and\ - not prox_possivel.tipo_dispositivo.\ - permitido_inserir_in( - possivelpai.tipo_dispositivo, - perfil_pk=perfil_pk) and \ - possivelpai.nivel < \ - prox_possivel.nivel: + if ( + possivelpai.tipo_dispositivo + != prox_possivel.tipo_dispositivo + and not prox_possivel.tipo_dispositivo.permitido_inserir_in( + possivelpai.tipo_dispositivo, + perfil_pk=perfil_pk, + ) + and possivelpai.nivel < prox_possivel.nivel + ): continue base.dispositivo_pai = possivelpai - Dispositivo.set_numero_for_add_in( - possivelpai, base, td) + Dispositivo.set_numero_for_add_in(possivelpai, base, td) else: Dispositivo.set_numero_for_add_in(base, base, td) @@ -2182,46 +2468,59 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): if not rt[0]: break flag_variacao += rt[1] - r.append({'class_css': td.class_css, - 'tipo_pk': td.pk, - 'variacao': flag_variacao, - 'provavel': '%s (%s)' % ( - base.rotulo_padrao(local_insert), - base.tipo_dispositivo.nome,), - 'dispositivo_base': base.pk}) + r.append( + { + "class_css": td.class_css, + "tipo_pk": td.pk, + "variacao": flag_variacao, + "provavel": "%s (%s)" + % ( + base.rotulo_padrao(local_insert), + base.tipo_dispositivo.nome, + ), + "dispositivo_base": base.pk, + } + ) flag_direcao = -1 r.reverse() - if len(r) > 0 and td.formato_variacao0 == \ - TipoDispositivo.FNCN: - r = [r[0], ] + if len(r) > 0 and td.formato_variacao0 == TipoDispositivo.FNCN: + r = [ + r[0], + ] else: if td.contagem_continua: base.transform_in_next() - r = [{'class_css': td.class_css, - 'tipo_pk': td.pk, - 'variacao': 0, - 'provavel': '%s (%s)' % ( - base.rotulo_padrao(1, paradentro), - td.nome,), - 'dispositivo_base': base.pk}] + r = [ + { + "class_css": td.class_css, + "tipo_pk": td.pk, + "variacao": 0, + "provavel": "%s (%s)" + % ( + base.rotulo_padrao(1, paradentro), + td.nome, + ), + "dispositivo_base": base.pk, + } + ] if paradentro == 1: - result[1]['itens'] += r + result[1]["itens"] += r else: - result[2]['itens'] += r - result[0]['itens'] += r + result[2]["itens"] += r + result[0]["itens"] += r # FIXME para liberar as opções de inserção antes, # o método json_add_prior deve ser implementado if len(result) > 2: result.pop() - result[0]['itens'] = result[1]['itens'] + result[0]['itens'] - result[0]['tipo_insert'] = 'Inserção' - result[1]['itens'] = [] + result[0]["itens"] = result[1]["itens"] + result[0]["itens"] + result[0]["tipo_insert"] = "Inserção" + result[1]["itens"] = [] return result @@ -2234,22 +2533,21 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): def json_set_dvt(self, context): # Dispositivo de Vigência do Texto Original e de Dpts Alterados - dvt = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) + dvt = Dispositivo.objects.get(pk=self.kwargs["dispositivo_id"]) if dvt.auto_inserido: dvt = dvt.dispositivo_pai try: - Dispositivo.objects.filter( - ta=dvt.ta, ta_publicado__isnull=True - ).update( + Dispositivo.objects.filter(ta=dvt.ta, ta_publicado__isnull=True).update( dispositivo_vigencia=dvt, inicio_vigencia=dvt.inicio_vigencia, - inicio_eficacia=dvt.inicio_eficacia) + inicio_eficacia=dvt.inicio_eficacia, + ) - Dispositivo.objects.filter(ta_publicado=dvt.ta - ).update( + Dispositivo.objects.filter(ta_publicado=dvt.ta).update( dispositivo_vigencia=dvt, inicio_vigencia=dvt.inicio_vigencia, - inicio_eficacia=dvt.inicio_eficacia) + inicio_eficacia=dvt.inicio_eficacia, + ) dps = Dispositivo.objects.filter(dispositivo_vigencia=dvt) for d in dps: @@ -2265,22 +2563,31 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): d.fim_eficacia = ds.inicio_eficacia - timedelta(days=1) d.save() - data = {'pk': dvt.pk, - 'pai': [dvt.pk, ]} - self.set_message(data, 'success', - _('Dispositivo de Vigência atualizado ' - 'com sucesso!!!')) + data = { + "pk": dvt.pk, + "pai": [ + dvt.pk, + ], + } + self.set_message( + data, + "success", + _("Dispositivo de Vigência atualizado " "com sucesso!!!"), + ) return data except Exception as e: data = {} username = self.request.user.username - self.logger.error("user=" + username + ". Ocorreu um erro ({}) na atualização do " - "Dispositivo de Vigência".format(str(e))) - self.set_message(data, - 'success', - _('Ocorreu um erro na atualização do ' - 'Dispositivo de Vigência')) + self.logger.error( + "user=" + username + ". Ocorreu um erro ({}) na atualização do " + "Dispositivo de Vigência".format(str(e)) + ) + self.set_message( + data, + "success", + _("Ocorreu um erro na atualização do " "Dispositivo de Vigência"), + ) return data @@ -2288,41 +2595,47 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): return {} def json_add_in(self, context): - return self.json_add_next(context, local_add='json_add_in') + return self.json_add_next(context, local_add="json_add_in") def json_add_next( self, - context, local_add='json_add_next', + context, + local_add="json_add_next", create_auto_inserts=True, - registro_inclusao=False + registro_inclusao=False, ): - try: - dp_auto_insert = None - base = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) + base = Dispositivo.objects.get(pk=self.kwargs["dispositivo_id"]) if base.dispositivo_atualizador: registro_inclusao = True - tipo = TipoDispositivo.objects.get(pk=context['tipo_pk']) - pub_last = Publicacao.objects.order_by( - 'data', 'hora').filter(ta=base.ta).last() + tipo = TipoDispositivo.objects.get(pk=context["tipo_pk"]) + pub_last = ( + Publicacao.objects.order_by("data", "hora").filter(ta=base.ta).last() + ) - variacao = int(context['variacao']) - parents = [base, ] + base.get_parents() + variacao = int(context["variacao"]) + parents = [ + base, + ] + base.get_parents() - if 'perfil_pk' not in context: + if "perfil_pk" not in context: perfil_padrao = PerfilEstruturalTextoArticulado.objects.filter( - padrao=True).first() + padrao=True + ).first() if perfil_padrao: - context['perfil_pk'] = perfil_padrao.pk + context["perfil_pk"] = perfil_padrao.pk else: - raise Exception('Não existe perfil padrão!') + raise Exception("Não existe perfil padrão!") perfil_parents = PerfilEstruturalTextoArticulado.objects.get( - pk=context['perfil_pk']) - perfil_parents = perfil_parents.parents + [perfil_parents, ] + pk=context["perfil_pk"] + ) + perfil_parents = perfil_parents.parents + [ + perfil_parents, + ] perfil_parents.reverse() dp_irmao = None @@ -2333,41 +2646,74 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): break if tipo.permitido_inserir_in( - dp.tipo_dispositivo, - perfil_pk=context['perfil_pk']): + dp.tipo_dispositivo, perfil_pk=context["perfil_pk"] + ): dp_pai = dp break dp_pai = dp if dp_irmao is not None: dp = Dispositivo.new_instance_based_on( - dp_irmao, tipo, base_alteracao=base) + dp_irmao, tipo, base_alteracao=base + ) dp.transform_in_next(variacao) else: # Inserção sem precedente dp = Dispositivo.new_instance_based_on( - dp_pai, tipo, base_alteracao=base) + dp_pai, tipo, base_alteracao=base + ) dp.dispositivo_pai = dp_pai dp.nivel += 1 if tipo.contagem_continua: - ultimo_irmao = Dispositivo.objects.order_by( - '-ordem').filter( - ordem__lte=base.ordem, - ordem__gte=parents[-1].ordem, - tipo_dispositivo_id=tipo.pk, - ta_id=base.ta_id).first() + ultimo_irmao = ( + Dispositivo.objects.order_by("-ordem") + .filter( + ordem__lte=base.ordem, + ordem__gte=parents[-1].ordem, + tipo_dispositivo_id=tipo.pk, + ta_id=base.ta_id, + ) + .first() + ) dp.set_numero_completo( - [1, 0, 0, 0, 0, 0, ] if not ultimo_irmao else - ultimo_irmao.get_numero_completo()) + [ + 1, + 0, + 0, + 0, + 0, + 0, + ] + if not ultimo_irmao + else ultimo_irmao.get_numero_completo() + ) if ultimo_irmao: dp.transform_in_next(variacao) else: - if ';' in tipo.rotulo_prefixo_texto: - dp.set_numero_completo([0, 0, 0, 0, 0, 0, ]) + if ";" in tipo.rotulo_prefixo_texto: + dp.set_numero_completo( + [ + 0, + 0, + 0, + 0, + 0, + 0, + ] + ) else: - dp.set_numero_completo([1, 0, 0, 0, 0, 0, ]) + dp.set_numero_completo( + [ + 1, + 0, + 0, + 0, + 0, + 0, + ] + ) if dp.dispositivo_atualizador: registro_inclusao = True @@ -2376,38 +2722,50 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): if dp.dispositivo_pai: for perfil in perfil_parents: pp = dp.tipo_dispositivo.possiveis_pais.filter( - pai_id=dp.dispositivo_pai.tipo_dispositivo_id, - perfil=perfil) + pai_id=dp.dispositivo_pai.tipo_dispositivo_id, perfil=perfil + ) if pp.exists() and pp[0].quantidade_permitida >= 0: qtd_existente = Dispositivo.objects.filter( ta_id=dp.ta_id, tipo_dispositivo_id=dp.tipo_dispositivo_id, - dispositivo_pai=dp.dispositivo_pai).count() + dispositivo_pai=dp.dispositivo_pai, + ).count() if qtd_existente >= pp[0].quantidade_permitida: - data = {'pk': None - if base.dispositivo_pai else - base.pk, - 'pai': [ - base.dispositivo_pai.pk if - base.dispositivo_pai else - base.pk, - ]} - self.set_message(data, 'danger', - _('Limite de inserções de ' - 'dispositivos deste tipo ' - 'foi excedido.'), time=6000) + data = { + "pk": None if base.dispositivo_pai else base.pk, + "pai": [ + base.dispositivo_pai.pk + if base.dispositivo_pai + else base.pk, + ], + } + self.set_message( + data, + "danger", + _( + "Limite de inserções de " + "dispositivos deste tipo " + "foi excedido." + ), + time=6000, + ) return data - ordem = base.criar_espaco( - espaco_a_criar=1, local=local_add) + ordem = base.criar_espaco(espaco_a_criar=1, local=local_add) dp.rotulo = dp.rotulo_padrao() dp.ordem = ordem if not registro_inclusao: - dp.incrementar_irmaos(variacao, [local_add, ], force=False) + dp.incrementar_irmaos( + variacao, + [ + local_add, + ], + force=False, + ) dp.publicacao = pub_last @@ -2417,8 +2775,8 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): if create_auto_inserts: for perfil in perfil_parents: tipos_dp_auto_insert = tipo.filhos_permitidos.filter( - filho_de_insercao_automatica=True, - perfil=perfil) + filho_de_insercao_automatica=True, perfil=perfil + ) for tipoauto in tipos_dp_auto_insert: qtdp = tipoauto.quantidade_permitida @@ -2426,7 +2784,7 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): qtdp -= Dispositivo.objects.filter( ta_id=dp.ta_id, dispositivo_pai_id=dp.id, - tipo_dispositivo_id=tipoauto.filho_permitido.pk + tipo_dispositivo_id=tipoauto.filho_permitido.pk, ).count() if qtdp > 0: count_auto_insert += 1 @@ -2438,9 +2796,9 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): # Inserção automática if count_auto_insert: - ordem = dp.criar_espaco( - espaco_a_criar=count_auto_insert, local='json_add_in') + espaco_a_criar=count_auto_insert, local="json_add_in" + ) dp_pk = dp.pk dp.ordem = ordem @@ -2449,12 +2807,30 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): dp.dispositivo_pai_id = dp_pk dp.pk = None dp.tipo_dispositivo = tipoauto.filho_permitido - if ';' in dp.tipo_dispositivo.rotulo_prefixo_texto: - dp.set_numero_completo([0, 0, 0, 0, 0, 0, ]) + if ";" in dp.tipo_dispositivo.rotulo_prefixo_texto: + dp.set_numero_completo( + [ + 0, + 0, + 0, + 0, + 0, + 0, + ] + ) else: - dp.set_numero_completo([1, 0, 0, 0, 0, 0, ]) + dp.set_numero_completo( + [ + 1, + 0, + 0, + 0, + 0, + 0, + ] + ) dp.rotulo = dp.rotulo_padrao() - dp.texto = '' + dp.texto = "" dp.publicacao = pub_last dp.auto_inserido = True @@ -2468,32 +2844,33 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): dp.ordem_bloco_atualizador = 0 dp.save(clean=False) - ''' Reenquadrar todos os dispositivos que possuem pai + """ Reenquadrar todos os dispositivos que possuem pai antes da inserção atual e que são inferiores a dp, - redirecionando para o novo pai''' + redirecionando para o novo pai""" nivel = sys.maxsize flag_niveis = False if not dp.tipo_dispositivo.dispositivo_de_alteracao: possiveis_filhos = Dispositivo.objects.filter( - ordem__gt=dp.ordem, - ta_id=dp.ta_id) + ordem__gt=dp.ordem, ta_id=dp.ta_id + ) for filho in possiveis_filhos: - if filho.nivel > nivel: continue - if not filho.dispositivo_pai or\ - filho.dispositivo_pai.ordem >= dp.ordem: + if ( + not filho.dispositivo_pai + or filho.dispositivo_pai.ordem >= dp.ordem + ): continue nivel = filho.nivel if not filho.tipo_dispositivo.permitido_inserir_in( - dp.tipo_dispositivo, - perfil_pk=context['perfil_pk']): + dp.tipo_dispositivo, perfil_pk=context["perfil_pk"] + ): continue filho.dispositivo_pai = dp @@ -2505,15 +2882,13 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): numtipos = {} - ''' Renumerar filhos imediatos que - não possuam contagem continua''' + """ Renumerar filhos imediatos que + não possuam contagem continua""" if flag_niveis: - filhos = Dispositivo.objects.filter( - dispositivo_pai_id=dp.pk) + filhos = Dispositivo.objects.filter(dispositivo_pai_id=dp.pk) for filho in filhos: - if filho.tipo_dispositivo.contagem_continua: continue @@ -2522,12 +2897,13 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): numtipos[filho.tipo_dispositivo.class_css] += 1 else: t = filho.tipo_dispositivo - prefixo = t.rotulo_prefixo_texto.split(';') + prefixo = t.rotulo_prefixo_texto.split(";") if len(prefixo) > 1: count_irmaos_m_tipo = Dispositivo.objects.filter( ~Q(pk=filho.pk), tipo_dispositivo=t, - dispositivo_pai=filho.dispositivo_pai)[:1] + dispositivo_pai=filho.dispositivo_pai, + )[:1] if count_irmaos_m_tipo.exists(): numtipos[filho.tipo_dispositivo.class_css] = 1 @@ -2536,50 +2912,56 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): else: numtipos[filho.tipo_dispositivo.class_css] = 1 - filho.dispositivo0 = numtipos[ - filho.tipo_dispositivo.class_css] + filho.dispositivo0 = numtipos[filho.tipo_dispositivo.class_css] filho.rotulo = filho.rotulo_padrao() filho.save() - ''' Renumerar dispositivos de + """ Renumerar dispositivos de contagem continua, caso a inserção seja uma articulação. - Desde que não seja um registro de inclusão através de compilação''' + Desde que não seja um registro de inclusão através de compilação""" if dp.nivel == 0 and not registro_inclusao: - proxima_articulacao = dp.select_next_root() if not proxima_articulacao: - filhos_continuos = list(Dispositivo.objects.filter( - ordem__gt=dp.ordem, - ta_id=dp.ta_id, - tipo_dispositivo__contagem_continua=True)) + filhos_continuos = list( + Dispositivo.objects.filter( + ordem__gt=dp.ordem, + ta_id=dp.ta_id, + tipo_dispositivo__contagem_continua=True, + ) + ) else: - filhos_continuos = list(Dispositivo.objects.filter( - ordem__gt=dp.ordem, - ordem__lt=proxima_articulacao.ordem, - ta_id=dp.ta_id, - tipo_dispositivo__contagem_continua=True)) + filhos_continuos = list( + Dispositivo.objects.filter( + ordem__gt=dp.ordem, + ordem__lt=proxima_articulacao.ordem, + ta_id=dp.ta_id, + tipo_dispositivo__contagem_continua=True, + ) + ) base_reducao = {} for filho in filhos_continuos: if filho.tipo_dispositivo.class_css not in base_reducao: - base_reducao[filho.tipo_dispositivo.class_css] = \ + base_reducao[filho.tipo_dispositivo.class_css] = ( filho.dispositivo0 - 1 + ) - filho.dispositivo0 -= base_reducao[ - filho.tipo_dispositivo.class_css] + filho.dispositivo0 -= base_reducao[filho.tipo_dispositivo.class_css] filho.rotulo = filho.rotulo_padrao() filho.save() - ''' Reordenar bloco atualizador caso a inserção seja - dentro de um bloco de alteração''' + """ Reordenar bloco atualizador caso a inserção seja + dentro de um bloco de alteração""" - if dp.tipo_dispositivo.dispositivo_de_alteracao and\ - not dp.tipo_dispositivo.dispositivo_de_articulacao: + if ( + dp.tipo_dispositivo.dispositivo_de_alteracao + and not dp.tipo_dispositivo.dispositivo_de_articulacao + ): dp.dispositivo_pai.ordenar_bloco_alteracao() if dp_auto_insert is None: @@ -2597,37 +2979,42 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): return {} -class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, - ActionDeleteDispositivoMixin, - ActionDispositivoCreateMixin): +class ActionsEditMixin( + ActionDragAndMoveDispositivoAlteradoMixin, + ActionDeleteDispositivoMixin, + ActionDispositivoCreateMixin, +): logger = logging.getLogger(__name__) def render_to_json_response(self, context, **response_kwargs): + action = getattr(self, context["action"]) - action = getattr(self, context['action']) - - if 'tipo_pk' in self.request.GET: - context['tipo_pk'] = self.request.GET['tipo_pk'] + if "tipo_pk" in self.request.GET: + context["tipo_pk"] = self.request.GET["tipo_pk"] - if 'variacao' in self.request.GET: - context['variacao'] = self.request.GET['variacao'] + if "variacao" in self.request.GET: + context["variacao"] = self.request.GET["variacao"] - if 'pk_bloco' in self.request.GET: - context['pk_bloco'] = self.request.GET['pk_bloco'] + if "pk_bloco" in self.request.GET: + context["pk_bloco"] = self.request.GET["pk_bloco"] - if 'perfil_estrutural' in self.request.session: - context['perfil_pk'] = self.request.session['perfil_estrutural'] + if "perfil_estrutural" in self.request.session: + context["perfil_pk"] = self.request.session["perfil_estrutural"] data = action(context) - if 'message' in context and 'message' not in data: - data['message'] = context['message'] + if "message" in context and "message" not in data: + data["message"] = context["message"] return JsonResponse(data, safe=False) def json_get_perfis(self, context): - data = {'pk': self.kwargs['dispositivo_id'], - 'pai': [self.kwargs['dispositivo_id'], ]} + data = { + "pk": self.kwargs["dispositivo_id"], + "pai": [ + self.kwargs["dispositivo_id"], + ], + } return data @@ -2636,45 +3023,48 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, request = self.request ta = None - if hasattr(self, 'object') and isinstance(self.object, Dispositivo): + if hasattr(self, "object") and isinstance(self.object, Dispositivo): ta = self.object.ta - elif hasattr(self, 'object') and isinstance( - self.object, TextoArticulado): + elif hasattr(self, "object") and isinstance(self.object, TextoArticulado): ta = self.object else: - ta_id = self.kwargs.get('ta_id', 0) + ta_id = self.kwargs.get("ta_id", 0) if ta_id: ta = TextoArticulado.objects.get(pk=ta_id) if ta: - if ta.content_object and hasattr(ta.content_object, 'perfis'): + if ta.content_object and hasattr(ta.content_object, "perfis"): qs = ta.content_object.perfis else: qs = ta.tipo_ta.perfis.all() - perfil_get = request.GET.get('perfil_pk', 0) + perfil_get = request.GET.get("perfil_pk", 0) if perfil_get and qs.filter(id=perfil_get).exists(): - request.session['perfil_estrutural'] = int(perfil_get) + request.session["perfil_estrutural"] = int(perfil_get) return qs - perfil_session = request.session.get('perfil_estrutural', perfil_get) + perfil_session = request.session.get("perfil_estrutural", perfil_get) if perfil_session and qs.filter(id=perfil_session).exists(): - request.session['perfil_estrutural'] = int(perfil_session) + request.session["perfil_estrutural"] = int(perfil_session) return qs if qs.exists(): - request.session['perfil_estrutural'] = qs.first().id + request.session["perfil_estrutural"] = qs.first().id return qs - def json_add_next_registra_inclusao( - self, context, local_add='json_add_next'): - - bloco_alteracao = Dispositivo.objects.get(pk=context['pk_bloco']) + def json_add_next_registra_inclusao(self, context, local_add="json_add_next"): + bloco_alteracao = Dispositivo.objects.get(pk=context["pk_bloco"]) data = {} - data.update({'pk': bloco_alteracao.pk, - 'pai': [bloco_alteracao.pk, ]}) + data.update( + { + "pk": bloco_alteracao.pk, + "pai": [ + bloco_alteracao.pk, + ], + } + ) """if bloco_alteracao.inicio_vigencia < base.inicio_vigencia: self.set_message( @@ -2684,14 +3074,15 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, 'alteração não pode ser retroativo!'), time=10000) return data""" - data = self.json_add_next(context, - local_add=local_add, - create_auto_inserts=True, - registro_inclusao=True) - - if data and data['pk']: + data = self.json_add_next( + context, + local_add=local_add, + create_auto_inserts=True, + registro_inclusao=True, + ) - ndp = Dispositivo.objects.get(pk=data['pk']) + if data and data["pk"]: + ndp = Dispositivo.objects.get(pk=data["pk"]) ndp.dispositivo_atualizador = bloco_alteracao ndp.ta_publicado = bloco_alteracao.ta @@ -2704,47 +3095,58 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, ndp.inicio_eficacia = bloco_alteracao.inicio_eficacia ndp.inicio_vigencia = bloco_alteracao.inicio_vigencia - dispositivos_do_bloco = \ - bloco_alteracao.dispositivos_alterados_set.order_by( - 'ordem_bloco_atualizador') + dispositivos_do_bloco = bloco_alteracao.dispositivos_alterados_set.order_by( + "ordem_bloco_atualizador" + ) if dispositivos_do_bloco.exists(): - ndp.ordem_bloco_atualizador = dispositivos_do_bloco.last( - ).ordem_bloco_atualizador + Dispositivo.INTERVALO_ORDEM + ndp.ordem_bloco_atualizador = ( + dispositivos_do_bloco.last().ordem_bloco_atualizador + + Dispositivo.INTERVALO_ORDEM + ) ndp.save() bloco_alteracao.ordenar_bloco_alteracao() - data.update({'pk': ndp.pk, - 'pai': [bloco_alteracao.pk, ]}) + data.update( + { + "pk": ndp.pk, + "pai": [ + bloco_alteracao.pk, + ], + } + ) else: - data.update({'pk': bloco_alteracao.pk, - 'pai': [bloco_alteracao.pk, ]}) + data.update( + { + "pk": bloco_alteracao.pk, + "pai": [ + bloco_alteracao.pk, + ], + } + ) self.set_message( - data, 'danger', - _('Não é possível incluir seu Registro de Inclusão, ' - 'verifique a opção escolhida e as variações possíveis!'), - time=10000) + data, + "danger", + _( + "Não é possível incluir seu Registro de Inclusão, " + "verifique a opção escolhida e as variações possíveis!" + ), + time=10000, + ) return data def json_add_in_registra_inclusao(self, context): - return self.json_add_next_registra_inclusao( - context, local_add='json_add_in') + return self.json_add_next_registra_inclusao(context, local_add="json_add_in") def registra_revogacao(self, bloco_alteracao, dsp_a_rev, em_bloco=False): - return self.registra_alteracao( - bloco_alteracao, - dsp_a_rev, - revogacao=True, - em_bloco=em_bloco + bloco_alteracao, dsp_a_rev, revogacao=True, em_bloco=em_bloco ) - def registra_alteracao(self, - bloco_alteracao, - dsp_a_alterar, - revogacao=False, - em_bloco=False): + def registra_alteracao( + self, bloco_alteracao, dsp_a_alterar, revogacao=False, em_bloco=False + ): """ Caracteristicas: 1 - Se é um dispositivo simples e sem subsequente @@ -2767,35 +3169,48 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, """ data = {} - data.update({'pk': bloco_alteracao.pk, - 'pai': [bloco_alteracao.pk, ]}) + data.update( + { + "pk": bloco_alteracao.pk, + "pai": [ + bloco_alteracao.pk, + ], + } + ) if isinstance(dsp_a_alterar, list): - parents = map(lambda x: x.id, bloco_alteracao.get_parents()) - parents = set(map(lambda x: int(x), dsp_a_alterar)) & \ - set(parents) + parents = set(map(lambda x: int(x), dsp_a_alterar)) & set(parents) if parents: self.set_message( - data, 'danger', - _('Não é possível incluir em um Bloco de Alteração ' - 'um dispositivo ao qual o próprio bloco pertence!'), time=10000) + data, + "danger", + _( + "Não é possível incluir em um Bloco de Alteração " + "um dispositivo ao qual o próprio bloco pertence!" + ), + time=10000, + ) return data dsps = Dispositivo.objects.filter(id__in=dsp_a_alterar) dsps_ids = set() for d in dsps: - if d.ta == bloco_alteracao.ta: self.set_message( - data, 'danger', - _('Não é possível incluir em um Bloco de Alteração ' - 'um dispositivo do Texto Articulado ao qual o bloco ' - 'também é pertencente! ' - 'Blocos de Alteração ' - 'devem ser utilizados para registrar mudanças em ' - 'textos anteriores a este, não neste mesmo em simutâneo.'), time=20000) + data, + "danger", + _( + "Não é possível incluir em um Bloco de Alteração " + "um dispositivo do Texto Articulado ao qual o bloco " + "também é pertencente! " + 'Blocos de Alteração ' + "devem ser utilizados para registrar mudanças em " + "textos anteriores a este, não neste mesmo em simutâneo." + ), + time=20000, + ) return data ds = d @@ -2809,58 +3224,56 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, if em_bloco: proximo_bloco = Dispositivo.objects.filter( - ordem__gt=ds.ordem, - nivel__lte=ds.nivel, - ta_id=ds.ta_id).first() + ordem__gt=ds.ordem, nivel__lte=ds.nivel, ta_id=ds.ta_id + ).first() params = { - 'ta_id': ds.ta_id, - 'nivel__gte': ds.nivel, - 'ordem__gte': ds.ordem, - 'dispositivo_subsequente__isnull': True, + "ta_id": ds.ta_id, + "nivel__gte": ds.nivel, + "ordem__gte": ds.ordem, + "dispositivo_subsequente__isnull": True, } if revogacao: params.update( { - 'dispositivo_de_revogacao': False, - 'tipo_dispositivo__dispositivo_de_articulacao': False + "dispositivo_de_revogacao": False, + "tipo_dispositivo__dispositivo_de_articulacao": False, } - ) if proximo_bloco: - params['ordem__lt'] = proximo_bloco.ordem + params["ordem__lt"] = proximo_bloco.ordem - bloco = Dispositivo.objects.filter( - **params).values_list('id', 'auto_inserido') + bloco = Dispositivo.objects.filter(**params).values_list( + "id", "auto_inserido" + ) for id, auto in bloco: if auto: - dsp_pai = Dispositivo.objects.filter( - pk=id - ).values_list('dispositivo_pai', flat=True).first() + dsp_pai = ( + Dispositivo.objects.filter(pk=id) + .values_list("dispositivo_pai", flat=True) + .first() + ) if dsp_pai in dsps_ids: dsps_ids.remove(dsp_pai) dsps_ids.add(id) - dsps_ids = Dispositivo.objects.filter( - id__in=dsps_ids - ).values_list('id', flat="True").order_by('ordem') + dsps_ids = ( + Dispositivo.objects.filter(id__in=dsps_ids) + .values_list("id", flat="True") + .order_by("ordem") + ) with transaction.atomic(): for dsp in dsps_ids: data.update( - self.registra_alteracao( - bloco_alteracao, - dsp, - revogacao - ) + self.registra_alteracao(bloco_alteracao, dsp, revogacao) ) - if 'message' in data and 'danger' in data['message']['type']: + if "message" in data and "danger" in data["message"]["type"]: return data return data - dsp_a_alterar = Dispositivo.objects.get( - pk=dsp_a_alterar) + dsp_a_alterar = Dispositivo.objects.get(pk=dsp_a_alterar) history = dsp_a_alterar.history() @@ -2869,26 +3282,35 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, dsp_a_alterar = d break - if (dsp_a_alterar.inicio_vigencia > - bloco_alteracao.inicio_vigencia): + if dsp_a_alterar.inicio_vigencia > bloco_alteracao.inicio_vigencia: self.set_message( - data, 'danger', - _('Não é possível alterar um Dispositivo com início de ' - 'Vigência posterior a data de Vigência do Dispositivo ' - 'Alterador!'), time=10000) + data, + "danger", + _( + "Não é possível alterar um Dispositivo com início de " + "Vigência posterior a data de Vigência do Dispositivo " + "Alterador!" + ), + time=10000, + ) return data - if dsp_a_alterar.tipo_dispositivo.dispositivo_de_articulacao\ - and not revogacao: + if dsp_a_alterar.tipo_dispositivo.dispositivo_de_articulacao and not revogacao: self.set_message( - data, 'warning', - _('Registrar alteração de um dispositivo de articulação ' - 'só é relevante para o caso de alterações de rótulo. ' - 'Se não é este o caso, a alteração deve ser específica ' - 'para o dispositivo que se quer alterar.'), modal=True) + data, + "warning", + _( + "Registrar alteração de um dispositivo de articulação " + "só é relevante para o caso de alterações de rótulo. " + "Se não é este o caso, a alteração deve ser específica " + "para o dispositivo que se quer alterar." + ), + modal=True, + ) ndp = Dispositivo.new_instance_based_on( - dsp_a_alterar, dsp_a_alterar.tipo_dispositivo) + dsp_a_alterar, dsp_a_alterar.tipo_dispositivo + ) ndp.auto_inserido = dsp_a_alterar.auto_inserido ndp.rotulo = dsp_a_alterar.rotulo ndp.publicacao = bloco_alteracao.publicacao @@ -2910,7 +3332,8 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, try: ordem = dsp_a_alterar.criar_espaco( - espaco_a_criar=1, local='json_add_in_with_auto') + espaco_a_criar=1, local="json_add_in_with_auto" + ) ndp.ordem = ordem ndp.dispositivo_atualizador = bloco_alteracao @@ -2923,19 +3346,19 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, ndp.dispositivo_subsequente = n if n: - ndp.fim_eficacia = n.inicio_eficacia - \ - timedelta(days=1) - ndp.fim_vigencia = n.inicio_vigencia - \ - timedelta(days=1) + ndp.fim_eficacia = n.inicio_eficacia - timedelta(days=1) + ndp.fim_vigencia = n.inicio_vigencia - timedelta(days=1) # Coloca o novo dispostivo no final do bloco - dispositivos_do_bloco = \ - bloco_alteracao.dispositivos_alterados_set.order_by( - 'ordem_bloco_atualizador') + dispositivos_do_bloco = bloco_alteracao.dispositivos_alterados_set.order_by( + "ordem_bloco_atualizador" + ) if dispositivos_do_bloco.exists(): - ndp.ordem_bloco_atualizador = dispositivos_do_bloco.last( - ).ordem_bloco_atualizador + Dispositivo.INTERVALO_ORDEM + ndp.ordem_bloco_atualizador = ( + dispositivos_do_bloco.last().ordem_bloco_atualizador + + Dispositivo.INTERVALO_ORDEM + ) else: ndp.ordem_bloco_atualizador = Dispositivo.INTERVALO_ORDEM @@ -2962,59 +3385,73 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, # bloco_alteracao.ordenar_bloco_alteracao() if not revogacao: - if 'message' not in data: + if "message" not in data: self.set_message( - data, 'success', - _('Dispositivo de Alteração adicionado com sucesso.')) + data, + "success", + _("Dispositivo de Alteração adicionado com sucesso."), + ) else: self.set_message( - data, 'success', - _('Dispositivo de Revogação adicionado com sucesso.')) + data, + "success", + _("Dispositivo de Revogação adicionado com sucesso."), + ) # data.update({'pk': ndp.pk, # 'pai': [bloco_alteracao.pk, ]}) except ValidationError as ve: self.set_message( - data, 'danger', - _('O dispositivo ({} - {}) já existe neste bloco.'.format( - ndp.tipo_dispositivo, - ndp.get_nomenclatura_completa())), time=10000) + data, + "danger", + _( + "O dispositivo ({} - {}) já existe neste bloco.".format( + ndp.tipo_dispositivo, ndp.get_nomenclatura_completa() + ) + ), + time=10000, + ) except Exception as e: username = self.request.user.username self.logger.error("user=" + username + ". " + str(e)) self.set_message( - data, 'danger', - _('Não é foi possível registrar sua solicitação!'), time=10000) + data, + "danger", + _("Não é foi possível registrar sua solicitação!"), + time=10000, + ) return data -class DispositivoDinamicEditView( - ActionsEditMixin, TextEditView, UpdateView): - template_name = 'compilacao/text_edit_bloco.html' +class DispositivoDinamicEditView(ActionsEditMixin, TextEditView, UpdateView): + template_name = "compilacao/text_edit_bloco.html" model = Dispositivo form_class = DispositivoEdicaoBasicaForm def get_initial(self): initial = UpdateView.get_initial(self) - if 'action' in self.request.GET: - initial.update({'editor_type': self.request.GET['action']}) + if "action" in self.request.GET: + initial.update({"editor_type": self.request.GET["action"]}) - if self.action.startswith('get_form_'): - if self.action.endswith('_radio_allowed_inserts'): - initial.update({'allowed_inserts': self.allowed_inserts()}) + if self.action.startswith("get_form_"): + if self.action.endswith("_radio_allowed_inserts"): + initial.update({"allowed_inserts": self.allowed_inserts()}) - initial.update({'texto_articulado_do_editor': - self.kwargs['ta_id']}) + initial.update({"texto_articulado_do_editor": self.kwargs["ta_id"]}) - initial.update({'dispositivo_search_form': reverse_lazy( - 'sapl.compilacao:dispositivo_search_form')}) + initial.update( + { + "dispositivo_search_form": reverse_lazy( + "sapl.compilacao:dispositivo_search_form" + ) + } + ) return initial def get_form(self, form_class=None): - - if self.action and self.action.startswith('get_form_'): + if self.action and self.action.startswith("get_form_"): if form_class is None: form_class = self.get_form_class() return form_class(**self.get_form_kwargs()) @@ -3022,152 +3459,155 @@ class DispositivoDinamicEditView( return None def get(self, request, *args, **kwargs): - - if 'action' not in request.GET: + if "action" not in request.GET: self.action = None - self.template_name = 'compilacao/text_edit_bloco.html' + self.template_name = "compilacao/text_edit_bloco.html" return TextEditView.get(self, request, *args, **kwargs) - self.object = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) + self.object = Dispositivo.objects.get(pk=self.kwargs["dispositivo_id"]) perfil_estrutural_list = self.update_perfis() - self.template_name = 'compilacao/ajax_form.html' - self.action = request.GET['action'] + self.template_name = "compilacao/ajax_form.html" + self.action = request.GET["action"] - if self.action.startswith('get_form_'): - if self.action.endswith('_base'): + if self.action.startswith("get_form_"): + if self.action.endswith("_base"): self.form_class = DispositivoEdicaoBasicaForm - elif self.action.endswith('_alteracao'): + elif self.action.endswith("_alteracao"): self.form_class = DispositivoRegistroAlteracaoForm - elif self.action.endswith('_revogacao'): + elif self.action.endswith("_revogacao"): self.form_class = DispositivoRegistroRevogacaoForm - elif self.action.endswith('_inclusao'): + elif self.action.endswith("_inclusao"): self.form_class = DispositivoRegistroInclusaoForm context = self.get_context_data() return self.render_to_response(context) - elif self.action.startswith('get_actions'): + elif self.action.startswith("get_actions"): self.form_class = None - ta_id = self.kwargs['ta_id'] + ta_id = self.kwargs["ta_id"] context = {} - context['object'] = self.object + context["object"] = self.object - if self.action.endswith('_allowed_inserts_registro_inclusao'): - self.template_name = ('compilacao/' - 'ajax_actions_registro_inclusao.html') - context['allowed_inserts'] = self.allowed_inserts() + if self.action.endswith("_allowed_inserts_registro_inclusao"): + self.template_name = "compilacao/" "ajax_actions_registro_inclusao.html" + context["allowed_inserts"] = self.allowed_inserts() else: - self.template_name = ('compilacao/' - 'ajax_actions_dinamic_edit.html') + self.template_name = "compilacao/" "ajax_actions_dinamic_edit.html" if ta_id == str(self.object.ta_id): - context['perfil_estrutural_list'] = perfil_estrutural_list - context['allowed_inserts'] = self.allowed_inserts() + context["perfil_estrutural_list"] = perfil_estrutural_list + context["allowed_inserts"] = self.allowed_inserts() return self.render_to_response(context) - elif self.action.startswith('json_'): + elif self.action.startswith("json_"): context = self.get_context_data() return self.render_to_json_response(context) return JsonResponse({}, safe=False) def post(self, request, *args, **kwargs): + d = Dispositivo.objects.get(pk=self.kwargs["dispositivo_id"]) - d = Dispositivo.objects.get( - pk=self.kwargs['dispositivo_id']) - - formtype = request.POST['formtype'] - if formtype == 'get_form_alteracao': - + formtype = request.POST["formtype"] + if formtype == "get_form_alteracao": data = self.registra_alteracao( - d, request.POST.getlist('dispositivo_alterado[]', [])) - - elif formtype == 'get_form_revogacao': + d, request.POST.getlist("dispositivo_alterado[]", []) + ) + elif formtype == "get_form_revogacao": data = self.registra_revogacao( d, - request.POST.getlist('dispositivo_revogado[]', []), - request.POST.get("revogacao_em_bloco") == "True" + request.POST.getlist("dispositivo_revogado[]", []), + request.POST.get("revogacao_em_bloco") == "True", ) - if formtype == 'get_form_inclusao': - + if formtype == "get_form_inclusao": dispositivo_base_para_inclusao = Dispositivo.objects.get( - pk=request.POST['dispositivo_base_para_inclusao']) + pk=request.POST["dispositivo_base_para_inclusao"] + ) data = self.registra_inclusao(d, dispositivo_base_para_inclusao) - elif formtype == 'get_form_base': - texto = request.POST['texto'].strip() - texto_atualizador = request.POST['texto_atualizador'].strip() - texto_atualizador = texto_atualizador \ - if texto != texto_atualizador else '' - visibilidade = request.POST['visibilidade'] + elif formtype == "get_form_base": + texto = request.POST["texto"].strip() + texto_atualizador = request.POST["texto_atualizador"].strip() + texto_atualizador = texto_atualizador if texto != texto_atualizador else "" + visibilidade = request.POST["visibilidade"] d_texto = d.texto d.texto = texto.strip() d.texto_atualizador = texto_atualizador.strip() - d.visibilidade = not visibilidade or visibilidade == 'True' + d.visibilidade = not visibilidade or visibilidade == "True" d.save() - if texto != '' and d.ta_id == int(self.kwargs['ta_id']): + if texto != "" and d.ta_id == int(self.kwargs["ta_id"]): dnext = Dispositivo.objects.filter( ta_id=d.ta_id, ordem__gt=d.ordem, - texto='', - tipo_dispositivo__dispositivo_de_articulacao=False)[:1] + texto="", + tipo_dispositivo__dispositivo_de_articulacao=False, + )[:1] if not dnext.exists(): dnext = [] dnext.append(d) - pais = [d.dispositivo_pai_id, ] + pais = [ + d.dispositivo_pai_id, + ] else: - if dnext[0].nivel > d.nivel: - pais = [d.pk, ] + pais = [ + d.pk, + ] else: if dnext[0].dispositivo_pai_id == d.dispositivo_pai_id: - pais = [dnext[0].dispositivo_pai_id, ] - else: pais = [ dnext[0].dispositivo_pai_id, - d.dispositivo_pai_id] + ] + else: + pais = [dnext[0].dispositivo_pai_id, d.dispositivo_pai_id] - data = {'pk': dnext[0].pk - if not d_texto else 0, 'pai': pais} - elif d.ta_id != int(self.kwargs['ta_id']): - data = {'pk': 0, - 'pai': [d.dispositivo_atualizador_id, ]} + data = {"pk": dnext[0].pk if not d_texto else 0, "pai": pais} + elif d.ta_id != int(self.kwargs["ta_id"]): + data = { + "pk": 0, + "pai": [ + d.dispositivo_atualizador_id, + ], + } else: - data = {'pk': d.pk - if not d_texto or not d.texto else 0, 'pai': [d.pk, ]} + data = { + "pk": d.pk if not d_texto or not d.texto else 0, + "pai": [ + d.pk, + ], + } - self.set_message(data, 'success', - _('Dispositivo alterado com sucesso.')) + self.set_message(data, "success", _("Dispositivo alterado com sucesso.")) return JsonResponse(data, safe=False) class DispositivoSearchFragmentFormView(ListView): - template_name = 'compilacao/dispositivo_form_search_fragment.html' + template_name = "compilacao/dispositivo_form_search_fragment.html" logger = logging.getLogger(__name__) def get(self, request, *args, **kwargs): - - if 'action' in request.GET and request.GET['action'] == 'get_tipos': + if "action" in request.GET and request.GET["action"] == "get_tipos": result = choice_model_type_foreignkey_in_extenal_views( - id_tipo_ta=request.GET['tipo_ta']) + id_tipo_ta=request.GET["tipo_ta"] + ) itens = [] for i in result: item = {} - item[i[0] if i[0] else ''] = str(i[1]) + item[i[0] if i[0] else ""] = str(i[1]) itens.append(item) return JsonResponse(itens, safe=False) @@ -3177,17 +3617,17 @@ class DispositivoSearchFragmentFormView(ListView): result = [] try: - tipo_model = self.request.GET.get('tipo_model', '') - limit = int(self.request.GET.get('max_results', 100)) - tipo_ta = self.request.GET.get('tipo_ta', '') - num_ta = self.request.GET.get('num_ta', '') - ano_ta = self.request.GET.get('ano_ta', '') - rotulo = self.request.GET.get('rotulo', '') - str_texto = self.request.GET.get('texto', '') - texto = str_texto.split(' ') - - tipo_resultado = self.request.GET.get('tipo_resultado', '') - tipo_resultado = '' if tipo_resultado == 'False' else tipo_resultado + tipo_model = self.request.GET.get("tipo_model", "") + limit = int(self.request.GET.get("max_results", 100)) + tipo_ta = self.request.GET.get("tipo_ta", "") + num_ta = self.request.GET.get("num_ta", "") + ano_ta = self.request.GET.get("ano_ta", "") + rotulo = self.request.GET.get("rotulo", "") + str_texto = self.request.GET.get("texto", "") + texto = str_texto.split(" ") + + tipo_resultado = self.request.GET.get("tipo_resultado", "") + tipo_resultado = "" if tipo_resultado == "False" else tipo_resultado model_class = None @@ -3197,65 +3637,68 @@ class DispositivoSearchFragmentFormView(ListView): if tipo_ta and tipo_model: integrations_view_names = get_integrations_view_names() for item in integrations_view_names: - if hasattr(item, 'model_type_foreignkey') and\ - hasattr(item, 'model'): - if (tipo_ta.content_type.model == - item.model.__name__.lower() and - tipo_ta.content_type.app_label == - item.model._meta.app_label): - + if hasattr(item, "model_type_foreignkey") and hasattr( + item, "model" + ): + if ( + tipo_ta.content_type.model == item.model.__name__.lower() + and tipo_ta.content_type.app_label + == item.model._meta.app_label + ): model_class = item.model model_type_class = item.model_type_foreignkey tipo_model = item.model_type_foreignkey.objects.get( - pk=tipo_model) + pk=tipo_model + ) break - column_field = '' + column_field = "" if model_class: for field in model_class._meta.fields: if field.related_model == model_type_class: column_field = field.column break - dts = self.request.GET.get('data_type_selection', '') - df = self.request.GET.get('data_function', '') + dts = self.request.GET.get("data_type_selection", "") + df = self.request.GET.get("data_function", "") - AND_CONTROLS = '' - if dts == 'checkbox': - AND_CONTROLS = 'AND td.dispositivo_de_alteracao = false' + AND_CONTROLS = "" + if dts == "checkbox": + AND_CONTROLS = "AND td.dispositivo_de_alteracao = false" else: - if df == 'alterador': - AND_CONTROLS = '''AND td.dispositivo_de_alteracao = true - AND td.dispositivo_de_articulacao = true''' + if df == "alterador": + AND_CONTROLS = """AND td.dispositivo_de_alteracao = true + AND td.dispositivo_de_articulacao = true""" texto = list(map("d.texto ~* '{}'".format, texto)) - AND_TEXTO_ROTULO = '' + AND_TEXTO_ROTULO = "" if str_texto and rotulo: - AND_TEXTO_ROTULO = '''AND ( ({BUSCA_TEXTO} AND d.rotulo ~* '{BUSCA_ROTULO}') OR + AND_TEXTO_ROTULO = """AND ( ({BUSCA_TEXTO} AND d.rotulo ~* '{BUSCA_ROTULO}') OR ({BUSCA_TEXTO} AND d.rotulo = '' AND dp.rotulo ~* '{BUSCA_ROTULO}') - )'''.format( - BUSCA_TEXTO=' AND '.join(texto), - BUSCA_ROTULO=rotulo + )""".format( + BUSCA_TEXTO=" AND ".join(texto), BUSCA_ROTULO=rotulo ) elif str_texto: - AND_TEXTO_ROTULO = ' AND %s' % ' AND '.join(texto) + AND_TEXTO_ROTULO = " AND %s" % " AND ".join(texto) elif rotulo: AND_TEXTO_ROTULO = "AND d.rotulo ~* '{BUSCA_ROTULO}'".format( - BUSCA_ROTULO=rotulo) + BUSCA_ROTULO=rotulo + ) else: - AND_TEXTO_ROTULO = '' + AND_TEXTO_ROTULO = "" - jtms = '' # JOIN_TYPE_MODEL_SELECTED - atms = '' # AND_TYPE_MODEL_SELECTED + jtms = "" # JOIN_TYPE_MODEL_SELECTED + atms = "" # AND_TYPE_MODEL_SELECTED if tipo_model: - jtms = 'JOIN {gfk_table} gfkt on (gfkt.id = ta.object_id)'.format( - gfk_table=model_class._meta.db_table) - atms = 'AND gfkt.{gfk_field_type} = {gfk_field_type_id}'.format( + jtms = "JOIN {gfk_table} gfkt on (gfkt.id = ta.object_id)".format( + gfk_table=model_class._meta.db_table + ) + atms = "AND gfkt.{gfk_field_type} = {gfk_field_type_id}".format( gfk_field_type=column_field, gfk_field_type_id=tipo_model.id, ) - sql = ''' + sql = """ SELECT d.* FROM compilacao_dispositivo d JOIN compilacao_dispositivo dp on (d.dispositivo_pai_id = dp.id) JOIN compilacao_tipodispositivo td on (d.tipo_dispositivo_id = td.id) @@ -3278,24 +3721,17 @@ class DispositivoSearchFragmentFormView(ListView): ta.id desc, d.ordem {limit}; - '''.format( - - limit='limit {}'.format(limit) if limit else '', - + """.format( + limit="limit {}".format(limit) if limit else "", JOIN_TYPE_MODEL_SELECTED=jtms, AND_TYPE_MODEL_SELECTED=atms, - - AND3_TIPO_TA="AND ta.tipo_ta_id = {}".format( - tipo_ta.id) if tipo_ta else '', - - AND2_ANO="AND ta.ano = {}".format( - ano_ta) if ano_ta else '', - - AND1_NUMERO="AND ta.numero ~* '{}'".format( - num_ta) if num_ta else '', - - AND_TEXTO_ROTULO=AND_TEXTO_ROTULO if AND_TEXTO_ROTULO else '', - AND_CONTROLS=AND_CONTROLS if AND_CONTROLS else '' + AND3_TIPO_TA="AND ta.tipo_ta_id = {}".format(tipo_ta.id) + if tipo_ta + else "", + AND2_ANO="AND ta.ano = {}".format(ano_ta) if ano_ta else "", + AND1_NUMERO="AND ta.numero ~* '{}'".format(num_ta) if num_ta else "", + AND_TEXTO_ROTULO=AND_TEXTO_ROTULO if AND_TEXTO_ROTULO else "", + AND_CONTROLS=AND_CONTROLS if AND_CONTROLS else "", ) result = Dispositivo.objects.raw(sql) @@ -3304,30 +3740,29 @@ class DispositivoSearchFragmentFormView(ListView): ids = set() def proc_dispositivos(ds): - for d in ds: - if d.id not in ids: r.append(d) ids.add(d.id) - if tipo_resultado == 'I': + if tipo_resultado == "I": if ds != result: d.I = True - proc_dispositivos(d.dispositivos_filhos_set.filter( - tipo_dispositivo__dispositivo_de_alteracao=False - )) - elif tipo_resultado == 'S' and ds == result: - + proc_dispositivos( + d.dispositivos_filhos_set.filter( + tipo_dispositivo__dispositivo_de_alteracao=False + ) + ) + elif tipo_resultado == "S" and ds == result: seq = Dispositivo.objects.filter( ta=d.ta, ordem__gt=d.ordem, nivel__gt=0, - tipo_dispositivo__dispositivo_de_alteracao=False + tipo_dispositivo__dispositivo_de_alteracao=False, ) proc_dispositivos(seq[:limit]) - elif tipo_resultado == 'S': + elif tipo_resultado == "S": d.S = True proc_dispositivos(result) @@ -3342,46 +3777,49 @@ class DispositivoSearchFragmentFormView(ListView): class DispositivoSearchModalView(FormView): - template_name = 'compilacao/dispositivo_form_search.html' + template_name = "compilacao/dispositivo_form_search.html" form_class = DispositivoSearchModalForm class DispositivoEdicaoBasicaView(CompMixin, FormMessagesMixin, UpdateView): model = Dispositivo - template_name = 'compilacao/dispositivo_form_edicao_basica.html' + template_name = "compilacao/dispositivo_form_edicao_basica.html" form_class = DispositivoEdicaoBasicaForm - form_valid_message = _('Alterações no Dispositivo realizadas com sucesso!') - form_invalid_message = _('Houve erro em registrar ' - 'as alterações no Dispositivo') + form_valid_message = _("Alterações no Dispositivo realizadas com sucesso!") + form_invalid_message = _("Houve erro em registrar " "as alterações no Dispositivo") - permission_required = 'compilacao.change_dispositivo_edicao_avancada' + permission_required = "compilacao.change_dispositivo_edicao_avancada" logger = logging.getLogger(__name__) @property def cancel_url(self): - return reverse_lazy( - 'sapl.compilacao:ta_text_edit', - kwargs={'ta_id': self.kwargs['ta_id']}) + '#' + str(self.object.pk) + return ( + reverse_lazy( + "sapl.compilacao:ta_text_edit", kwargs={"ta_id": self.kwargs["ta_id"]} + ) + + "#" + + str(self.object.pk) + ) def get_success_url(self): return reverse_lazy( - 'sapl.compilacao:dispositivo_edit', - kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']}) + "sapl.compilacao:dispositivo_edit", + kwargs={"ta_id": self.kwargs["ta_id"], "pk": self.kwargs["pk"]}, + ) def get_url_this_view(self): - return 'sapl.compilacao:dispositivo_edit' + return "sapl.compilacao:dispositivo_edit" def run_actions(self, request): - if 'action' in request.GET and\ - request.GET['action'] == 'atualiza_rotulo': + if "action" in request.GET and request.GET["action"] == "atualiza_rotulo": try: - d = Dispositivo.objects.get(pk=self.kwargs['pk']) - d.dispositivo0 = int(request.GET['dispositivo0']) - d.dispositivo1 = int(request.GET['dispositivo1']) - d.dispositivo2 = int(request.GET['dispositivo2']) - d.dispositivo3 = int(request.GET['dispositivo3']) - d.dispositivo4 = int(request.GET['dispositivo4']) - d.dispositivo5 = int(request.GET['dispositivo5']) + d = Dispositivo.objects.get(pk=self.kwargs["pk"]) + d.dispositivo0 = int(request.GET["dispositivo0"]) + d.dispositivo1 = int(request.GET["dispositivo1"]) + d.dispositivo2 = int(request.GET["dispositivo2"]) + d.dispositivo3 = int(request.GET["dispositivo3"]) + d.dispositivo4 = int(request.GET["dispositivo4"]) + d.dispositivo5 = int(request.GET["dispositivo5"]) d.rotulo = d.rotulo_padrao() numero = d.get_numero_completo()[1:] @@ -3395,28 +3833,41 @@ class DispositivoEdicaoBasicaView(CompMixin, FormMessagesMixin, UpdateView): numero[i] = 0 if zerar: - d.set_numero_completo([d.dispositivo0, ] + numero) + d.set_numero_completo( + [ + d.dispositivo0, + ] + + numero + ) d.rotulo = d.rotulo_padrao() except Exception as e: username = self.request.user.username self.logger.error( - "user=" + username + ". Ocorreu erro ({}) na atualização do rótulo.".format(str(e))) - return True, JsonResponse({'message': str( - _('Ocorreu erro na atualização do rótulo'))}, safe=False) - return True, JsonResponse({ - 'rotulo': d.rotulo, - 'dispositivo0': d.dispositivo0, - 'dispositivo1': d.dispositivo1, - 'dispositivo2': d.dispositivo2, - 'dispositivo3': d.dispositivo3, - 'dispositivo4': d.dispositivo4, - 'dispositivo5': d.dispositivo5}, safe=False) - - return False, '' + "user=" + + username + + ". Ocorreu erro ({}) na atualização do rótulo.".format(str(e)) + ) + return True, JsonResponse( + {"message": str(_("Ocorreu erro na atualização do rótulo"))}, + safe=False, + ) + return True, JsonResponse( + { + "rotulo": d.rotulo, + "dispositivo0": d.dispositivo0, + "dispositivo1": d.dispositivo1, + "dispositivo2": d.dispositivo2, + "dispositivo3": d.dispositivo3, + "dispositivo4": d.dispositivo4, + "dispositivo5": d.dispositivo5, + }, + safe=False, + ) - def get(self, request, *args, **kwargs): + return False, "" + def get(self, request, *args, **kwargs): flag_action, render_json_response = self.run_actions(request) if flag_action: return render_json_response @@ -3426,77 +3877,89 @@ class DispositivoEdicaoBasicaView(CompMixin, FormMessagesMixin, UpdateView): class DispositivoEdicaoVigenciaView(CompMixin, FormMessagesMixin, UpdateView): model = Dispositivo - template_name = 'compilacao/dispositivo_form_vigencia.html' + template_name = "compilacao/dispositivo_form_vigencia.html" form_class = DispositivoEdicaoVigenciaForm - form_valid_message = _('Alterações no Dispositivo realizadas com sucesso!') - form_invalid_message = _('Houve erro em registrar ' - 'as alterações no Dispositivo') + form_valid_message = _("Alterações no Dispositivo realizadas com sucesso!") + form_invalid_message = _("Houve erro em registrar " "as alterações no Dispositivo") - permission_required = 'compilacao.change_dispositivo_edicao_avancada' + permission_required = "compilacao.change_dispositivo_edicao_avancada" @property def cancel_url(self): - return reverse_lazy( - 'sapl.compilacao:ta_text_edit', - kwargs={'ta_id': self.kwargs['ta_id']}) + '#' + str(self.object.pk) + return ( + reverse_lazy( + "sapl.compilacao:ta_text_edit", kwargs={"ta_id": self.kwargs["ta_id"]} + ) + + "#" + + str(self.object.pk) + ) def get_url_this_view(self): - return 'sapl.compilacao:dispositivo_edit_vigencia' + return "sapl.compilacao:dispositivo_edit_vigencia" def get_success_url(self): return reverse_lazy( - 'sapl.compilacao:dispositivo_edit_vigencia', - kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']}) + "sapl.compilacao:dispositivo_edit_vigencia", + kwargs={"ta_id": self.kwargs["ta_id"], "pk": self.kwargs["pk"]}, + ) class DispositivoDefinidorVigenciaView(CompMixin, FormMessagesMixin, FormView): model = Dispositivo - template_name = 'compilacao/dispositivo_form_definidor_vigencia.html' + template_name = "compilacao/dispositivo_form_definidor_vigencia.html" form_class = DispositivoDefinidorVigenciaForm - form_valid_message = _('Alterações no Dispositivo realizadas com sucesso!') - form_invalid_message = _('Houve erro em registrar ' - 'as alterações no Dispositivo') + form_valid_message = _("Alterações no Dispositivo realizadas com sucesso!") + form_invalid_message = _("Houve erro em registrar " "as alterações no Dispositivo") - permission_required = ('compilacao.change_dispositivo_edicao_avancada', - 'compilacao.change_dispositivo_de_vigencia_global') + permission_required = ( + "compilacao.change_dispositivo_edicao_avancada", + "compilacao.change_dispositivo_de_vigencia_global", + ) logger = logging.getLogger(__name__) def get_form_kwargs(self): kwargs = FormView.get_form_kwargs(self) - kwargs.update({ - 'pk': self.kwargs['pk'], - }) + kwargs.update( + { + "pk": self.kwargs["pk"], + } + ) return kwargs @property def cancel_url(self): - return reverse_lazy( - 'sapl.compilacao:ta_text_edit', - kwargs={'ta_id': self.kwargs['ta_id']}) + '#' + str(self.object.pk) + return ( + reverse_lazy( + "sapl.compilacao:ta_text_edit", kwargs={"ta_id": self.kwargs["ta_id"]} + ) + + "#" + + str(self.object.pk) + ) def get_url_this_view(self): - return 'sapl.compilacao:dispositivo_edit_definidor_vigencia' + return "sapl.compilacao:dispositivo_edit_definidor_vigencia" def get_success_url(self): return reverse_lazy( - 'sapl.compilacao:dispositivo_edit_definidor_vigencia', - kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']}) + "sapl.compilacao:dispositivo_edit_definidor_vigencia", + kwargs={"ta_id": self.kwargs["ta_id"], "pk": self.kwargs["pk"]}, + ) def get(self, request, *args, **kwargs): - self.object = get_object_or_404(Dispositivo, pk=kwargs['pk']) + self.object = get_object_or_404(Dispositivo, pk=kwargs["pk"]) return FormView.get(self, request, *args, **kwargs) def get_context_data(self, **kwargs): context = FormView.get_context_data(self, **kwargs) - context.update({'object': self.object}) + context.update({"object": self.object}) return context def post(self, request, *args, **kwargs): - self.object = get_object_or_404(Dispositivo, pk=kwargs['pk']) + self.object = get_object_or_404(Dispositivo, pk=kwargs["pk"]) form = self.get_form() if form.is_valid(): - dvs = form.cleaned_data['dispositivo_vigencia'] + dvs = form.cleaned_data["dispositivo_vigencia"] try: with transaction.atomic(): self.object.dispositivos_vigencias_set.clear() @@ -3514,31 +3977,35 @@ class DispositivoDefinidorVigenciaView(CompMixin, FormMessagesMixin, FormView): class DispositivoEdicaoAlteracaoView(CompMixin, FormMessagesMixin, UpdateView): model = Dispositivo - template_name = 'compilacao/dispositivo_form_alteracao.html' + template_name = "compilacao/dispositivo_form_alteracao.html" form_class = DispositivoEdicaoAlteracaoForm - form_valid_message = _('Alterações no Dispositivo realizadas com sucesso!') - form_invalid_message = _('Houve erro em registrar ' - 'as alterações no Dispositivo') + form_valid_message = _("Alterações no Dispositivo realizadas com sucesso!") + form_invalid_message = _("Houve erro em registrar " "as alterações no Dispositivo") - permission_required = 'compilacao.change_dispositivo_registros_compilacao' + permission_required = "compilacao.change_dispositivo_registros_compilacao" logger = logging.getLogger(__name__) @property def cancel_url(self): - return reverse_lazy( - 'sapl.compilacao:ta_text_edit', - kwargs={'ta_id': self.kwargs['ta_id']}) + '#' + str(self.object.pk) + return ( + reverse_lazy( + "sapl.compilacao:ta_text_edit", kwargs={"ta_id": self.kwargs["ta_id"]} + ) + + "#" + + str(self.object.pk) + ) def get_url_this_view(self): - return 'sapl.compilacao:dispositivo_edit_alteracao' + return "sapl.compilacao:dispositivo_edit_alteracao" def get_success_url(self): return reverse_lazy( - 'sapl.compilacao:dispositivo_edit_alteracao', - kwargs={'ta_id': self.kwargs['ta_id'], 'pk': self.kwargs['pk']}) + "sapl.compilacao:dispositivo_edit_alteracao", + kwargs={"ta_id": self.kwargs["ta_id"], "pk": self.kwargs["pk"]}, + ) def post(self, request, *args, **kwargs): - self.object = get_object_or_404(Dispositivo, pk=kwargs['pk']) + self.object = get_object_or_404(Dispositivo, pk=kwargs["pk"]) form = self.get_form() if form.is_valid(): @@ -3554,57 +4021,56 @@ class DispositivoEdicaoAlteracaoView(CompMixin, FormMessagesMixin, UpdateView): class TextNotificacoesView(CompMixin, ListView, FormView): - template_name = 'compilacao/text_notificacoes.html' + template_name = "compilacao/text_notificacoes.html" form_class = TextNotificacoesForm - permission_required = 'compilacao.view_dispositivo_notificacoes' + permission_required = "compilacao.view_dispositivo_notificacoes" def get(self, request, *args, **kwargs): - self.object = TextoArticulado.objects.get(pk=self.kwargs['ta_id']) + self.object = TextoArticulado.objects.get(pk=self.kwargs["ta_id"]) return super(TextNotificacoesView, self).get(request, *args, **kwargs) def post(self, request, *args, **kwargs): - self.object = TextoArticulado.objects.get(pk=self.kwargs['ta_id']) + self.object = TextoArticulado.objects.get(pk=self.kwargs["ta_id"]) return FormView.post(self, request, *args, **kwargs) def get_context_data(self, **kwargs): - if 'object' not in kwargs: - kwargs['object'] = self.object + if "object" not in kwargs: + kwargs["object"] = self.object return ListView.get_context_data(self, **kwargs) def get_success_url(self): - return reverse_lazy('sapl.compilacao:ta_text_notificacoes', - kwargs=self.kwargs) + return reverse_lazy("sapl.compilacao:ta_text_notificacoes", kwargs=self.kwargs) def get_initial(self): initial = {} - if self.request.method == 'POST': - if 'type_notificacoes' in self.request.POST: - self.request.session[ - 'type_notificacoes'] = self.request.POST.getlist( - 'type_notificacoes') + if self.request.method == "POST": + if "type_notificacoes" in self.request.POST: + self.request.session["type_notificacoes"] = self.request.POST.getlist( + "type_notificacoes" + ) else: - self.request.session['type_notificacoes'] = [] - elif 'type_notificacoes' in self.request.session: - initial['type_notificacoes'] = self.request.session[ - 'type_notificacoes'] + self.request.session["type_notificacoes"] = [] + elif "type_notificacoes" in self.request.session: + initial["type_notificacoes"] = self.request.session["type_notificacoes"] else: - initial['type_notificacoes'] = [] + initial["type_notificacoes"] = [] return initial def get_queryset(self): - - result = Dispositivo.objects.filter( - ta_id=self.kwargs['ta_id'] - ).select_related(*DISPOSITIVO_SELECT_RELATED) + result = Dispositivo.objects.filter(ta_id=self.kwargs["ta_id"]).select_related( + *DISPOSITIVO_SELECT_RELATED + ) type_notificacoes = [] - if 'type_notificacoes' in self.request.session: - type_notificacoes = self.request.session['type_notificacoes'] + if "type_notificacoes" in self.request.session: + type_notificacoes = self.request.session["type_notificacoes"] if type_notificacoes and not isinstance(type_notificacoes, list): - type_notificacoes = [type_notificacoes, ] + type_notificacoes = [ + type_notificacoes, + ] return self.get_notificacoes(result, type_notificacoes) diff --git a/sapl/context_processors.py b/sapl/context_processors.py index 352326a6b..c08f4af13 100644 --- a/sapl/context_processors.py +++ b/sapl/context_processors.py @@ -2,13 +2,16 @@ import logging from django.utils.translation import gettext_lazy as _ -from sapl.utils import google_recaptcha_configured as \ - google_recaptcha_configured_utils, sapn_is_enabled, cached_call, get_base_url +from sapl.utils import cached_call, get_base_url +from sapl.utils import \ + google_recaptcha_configured as google_recaptcha_configured_utils from sapl.utils import mail_service_configured as mail_service_configured_utils +from sapl.utils import sapn_is_enabled def parliament_info(request): from sapl.base.views import get_casalegislativa + casa = get_casalegislativa() if casa: return casa.__dict__ @@ -19,32 +22,37 @@ def parliament_info(request): def mail_service_configured(request): if not mail_service_configured_utils(request): logger = logging.getLogger(__name__) - logger.warning(_('Servidor de email não configurado.')) - return {'mail_service_configured': False} - return {'mail_service_configured': True} + logger.warning(_("Servidor de email não configurado.")) + return {"mail_service_configured": False} + return {"mail_service_configured": True} def google_recaptcha_configured(request): if not google_recaptcha_configured_utils(): logger = logging.getLogger(__name__) - logger.warning(_('Google Recaptcha não configurado.')) - return {'google_recaptcha_configured': False} - return {'google_recaptcha_configured': True} + logger.warning(_("Google Recaptcha não configurado.")) + return {"google_recaptcha_configured": False} + return {"google_recaptcha_configured": True} @cached_call("site-title", timeout=60 * 2) def enable_sapn(request): - verbose_name = _('Sistema de Apoio ao Processo Legislativo') \ - if not sapn_is_enabled() \ - else _('Sistema de Apoio à Publicação de Leis e Normas') + verbose_name = ( + _("Sistema de Apoio ao Processo Legislativo") + if not sapn_is_enabled() + else _("Sistema de Apoio à Publicação de Leis e Normas") + ) from sapl.base.models import CasaLegislativa + casa_legislativa = CasaLegislativa.objects.first() - nome_casa = casa_legislativa.nome if casa_legislativa and casa_legislativa.nome else '' + nome_casa = ( + casa_legislativa.nome if casa_legislativa and casa_legislativa.nome else "" + ) return { - 'sapl_as_sapn': sapn_is_enabled(), - 'nome_sistema': verbose_name, - 'nome_casa': nome_casa, - 'base_url': get_base_url(request), + "sapl_as_sapn": sapn_is_enabled(), + "nome_sistema": verbose_name, + "nome_casa": nome_casa, + "base_url": get_base_url(request), } diff --git a/sapl/crispy_layout_mixin.py b/sapl/crispy_layout_mixin.py index 9f003f3f1..3e04dab30 100644 --- a/sapl/crispy_layout_mixin.py +++ b/sapl/crispy_layout_mixin.py @@ -1,5 +1,6 @@ from math import ceil +import yaml from crispy_forms.bootstrap import FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit @@ -9,7 +10,6 @@ from django.urls import reverse, reverse_lazy from django.utils import formats from django.utils.encoding import force_str from django.utils.translation import gettext as _ -import yaml def heads_and_tails(list_of_lists): @@ -19,11 +19,11 @@ def heads_and_tails(list_of_lists): def to_column(name_span): fieldname, span = name_span - return Div(fieldname, css_class='col-md-%d' % span) + return Div(fieldname, css_class="col-md-%d" % span) def to_row(names_spans): - return Div(*map(to_column, names_spans), css_class='row') + return Div(*map(to_column, names_spans), css_class="row") def to_fieldsets(fields): @@ -36,21 +36,28 @@ def to_fieldsets(fields): yield field -def form_actions(more=[Div(css_class='clearfix')], - label=_('Salvar'), name='salvar', - css_class='float-right', disabled=True): - - if disabled and force_str(label) != 'Pesquisar': - doubleclick = 'this.form.submit();this.disabled=true;' +def form_actions( + more=[Div(css_class="clearfix")], + label=_("Salvar"), + name="salvar", + css_class="float-right", + disabled=True, +): + if disabled and force_str(label) != "Pesquisar": + doubleclick = "this.form.submit();this.disabled=true;" else: - doubleclick = 'return true;' + doubleclick = "return true;" return FormActions( *more, - Submit(name, label, css_class=css_class, - # para impedir resubmissão do form - onclick=doubleclick), - css_class='form-group row justify-content-between' + Submit( + name, + label, + css_class=css_class, + # para impedir resubmissão do form + onclick=doubleclick, + ), + css_class="form-group row justify-content-between", ) @@ -85,16 +92,22 @@ class SaplFormHelper(FormHelper): class SaplFormLayout(Layout): - - def __init__(self, *fields, cancel_label=_('Cancelar'), - save_label=_('Salvar'), actions=None): - + def __init__( + self, *fields, cancel_label=_("Cancelar"), save_label=_("Salvar"), actions=None + ): buttons = actions if not buttons: - buttons = form_actions(label=save_label, more=[ - HTML('%s' % cancel_label) - if cancel_label else None]) + buttons = form_actions( + label=save_label, + more=[ + HTML( + '%s' % cancel_label + ) + if cancel_label + else None + ], + ) _fields = list(to_fieldsets(fields)) if buttons: @@ -103,26 +116,25 @@ class SaplFormLayout(Layout): def get_field_display(obj, fieldname): - field = '' + field = "" try: field = obj._meta.get_field(fieldname) except Exception as e: - """ nos casos que o fieldname não é um field_model, - ele pode ser um aggregate, annotate, um property, um manager, - ou mesmo uma método no model. + """nos casos que o fieldname não é um field_model, + ele pode ser um aggregate, annotate, um property, um manager, + ou mesmo uma método no model. """ value = getattr(obj, fieldname) try: verbose_name = value.model._meta.verbose_name except AttributeError: - verbose_name = '' + verbose_name = "" else: - verbose_name = str(field.verbose_name)\ - if hasattr(field, 'verbose_name') else '' + verbose_name = str(field.verbose_name) if hasattr(field, "verbose_name") else "" - if hasattr(field, 'choices') and field.choices: - value = getattr(obj, 'get_%s_display' % fieldname)() + if hasattr(field, "choices") and field.choices: + value = getattr(obj, "get_%s_display" % fieldname)() else: value = getattr(obj, fieldname) @@ -130,95 +142,100 @@ def get_field_display(obj, fieldname): str_type_from_field = str(type(field)) if value is None: - display = '' - elif '.date' in str_type_from_value: + display = "" + elif ".date" in str_type_from_value: display = formats.date_format(value, "SHORT_DATE_FORMAT") - elif 'bool' in str_type_from_value: - display = _('Sim') if value else _('Não') - elif 'ImageFieldFile' in str(type(value)): + elif "bool" in str_type_from_value: + display = _("Sim") if value else _("Não") + elif "ImageFieldFile" in str(type(value)): if value: display = ''.format(value.url) else: - display = '' - elif 'FieldFile' in str_type_from_value: + display = "" + elif "FieldFile" in str_type_from_value: if value: display = '{}'.format( - value.url, - value.name.split('/')[-1:][0]) + value.url, value.name.split("/")[-1:][0] + ) else: - display = '' - elif 'ManyRelatedManager' in str_type_from_value\ - or 'RelatedManager' in str_type_from_value\ - or 'GenericRelatedObjectManager' in str_type_from_value: - display = '
      ' + display = "" + elif ( + "ManyRelatedManager" in str_type_from_value + or "RelatedManager" in str_type_from_value + or "GenericRelatedObjectManager" in str_type_from_value + ): + display = "
        " for v in value.all(): - display += '
      • %s
      • ' % str(v) - display += '
      ' + display += "
    • %s
    • " % str(v) + display += "
    " if not verbose_name: - if hasattr(field, 'related_model'): - verbose_name = str( - field.related_model._meta.verbose_name_plural) - elif hasattr(field, 'model'): + if hasattr(field, "related_model"): + verbose_name = str(field.related_model._meta.verbose_name_plural) + elif hasattr(field, "model"): verbose_name = str(field.model._meta.verbose_name_plural) - elif 'GenericForeignKey' in str_type_from_field: + elif "GenericForeignKey" in str_type_from_field: display = '{}'.format( reverse( - '%s:%s_detail' % ( - value._meta.app_config.name, obj.content_type.model), - args=(value.id,)), - value) - elif 'TextField' in str_type_from_field: - display = value.replace('\n', '
    ') + "%s:%s_detail" % (value._meta.app_config.name, obj.content_type.model), + args=(value.id,), + ), + value, + ) + elif "TextField" in str_type_from_field: + display = value.replace("\n", "
    ") display = '
    {}
    '.format(display) else: display = str(value) - return verbose_name, display or ' ' + return verbose_name, display or " " class CrispyLayoutFormMixin: - @property def layout_key(self): - if hasattr(super(CrispyLayoutFormMixin, self), 'layout_key'): + if hasattr(super(CrispyLayoutFormMixin, self), "layout_key"): return super(CrispyLayoutFormMixin, self).layout_key else: return self.model.__name__ @property def layout_key_set(self): - if hasattr(super(CrispyLayoutFormMixin, self), 'layout_key_set'): + if hasattr(super(CrispyLayoutFormMixin, self), "layout_key_set"): return super(CrispyLayoutFormMixin, self).layout_key_set else: - obj = self.crud if hasattr(self, 'crud') else self - return getattr(obj.model, - obj.model_set).field.model.__name__ + obj = self.crud if hasattr(self, "crud") else self + return getattr(obj.model, obj.model_set).field.model.__name__ def get_layout(self, yaml_layout=None): if not yaml_layout: - yaml_layout = '%s/layouts.yaml' % self.model._meta.app_config.label + yaml_layout = "%s/layouts.yaml" % self.model._meta.app_config.label return read_layout_from_yaml(yaml_layout, self.layout_key) def get_layout_set(self): - obj = self.crud if hasattr(self, 'crud') else self - yaml_layout = '%s/layouts.yaml' % getattr( - obj.model, obj.model_set).field.model._meta.app_config.label + obj = self.crud if hasattr(self, "crud") else self + yaml_layout = ( + "%s/layouts.yaml" + % getattr(obj.model, obj.model_set).field.model._meta.app_config.label + ) return read_layout_from_yaml(yaml_layout, self.layout_key_set) @property def fields(self): - if hasattr(self, 'form_class') and self.form_class: + if hasattr(self, "form_class") and self.form_class: return None else: - '''Returns all fields in the layout''' - return [fieldname for legend_rows in self.get_layout() - for row in legend_rows[1:] - for fieldname, span in row] + """Returns all fields in the layout""" + return [ + fieldname + for legend_rows in self.get_layout() + for row in legend_rows[1:] + for fieldname, span in row + ] def get_form(self, form_class=None): - super_get_form = getattr(super(CrispyLayoutFormMixin, self), 'get_form', None) + super_get_form = getattr(super(CrispyLayoutFormMixin, self), "get_form", None) if super_get_form is None: # Either raise, or (if you want to support non-form views) construct a form when form_class exists. - if getattr(self, 'form_class', None): + if getattr(self, "form_class", None): form_class = self.get_form_class() form = form_class(**self.get_form_kwargs()) else: @@ -236,24 +253,24 @@ class CrispyLayoutFormMixin: @property def list_field_names(self): - '''The list of field names to display on table + """The list of field names to display on table This base implementation returns the field names in the first fieldset of the layout. - ''' - obj = self.crud if hasattr(self, 'crud') else self - if hasattr(obj, 'list_field_names') and obj.list_field_names: + """ + obj = self.crud if hasattr(self, "crud") else self + if hasattr(obj, "list_field_names") and obj.list_field_names: return obj.list_field_names rows = self.get_layout()[0][1:] return [fieldname for row in rows for fieldname, __ in row] @property def list_field_names_set(self): - '''The list of field names to display on table + """The list of field names to display on table This base implementation returns the field names in the first fieldset of the layout. - ''' + """ rows = self.get_layout_set()[0][1:] return [fieldname for row in rows for fieldname, __ in row] @@ -261,65 +278,65 @@ class CrispyLayoutFormMixin: obj = self.get_object() func = None - if '|' in fieldname: - fieldname, func = tuple(fieldname.split('|')) + if "|" in fieldname: + fieldname, func = tuple(fieldname.split("|")) try: verbose_name, field_display = get_field_display(obj, fieldname) except: - verbose_name, field_display = '', '' + verbose_name, field_display = "", "" if func: verbose_name, field_display = getattr(self, func)(obj, fieldname) - hook_fieldname = 'hook_%s' % fieldname + hook_fieldname = "hook_%s" % fieldname if hasattr(self, hook_fieldname): try: - verbose_name, field_display = getattr( - self, hook_fieldname)(obj, verbose_name=verbose_name, field_display=field_display) + verbose_name, field_display = getattr(self, hook_fieldname)( + obj, verbose_name=verbose_name, field_display=field_display + ) except: - verbose_name, field_display = getattr( - self, hook_fieldname)(obj) + verbose_name, field_display = getattr(self, hook_fieldname)(obj) elif not func: verbose_name, field_display = get_field_display(obj, fieldname) return { - 'id': fieldname, - 'span': span, - 'verbose_name': verbose_name, - 'text': field_display, + "id": fieldname, + "span": span, + "verbose_name": verbose_name, + "text": field_display, } def fk_urlify_for_detail(self, obj, fieldname): - field = obj._meta.get_field(fieldname) value = getattr(obj, fieldname) display = '{}'.format( reverse( - '%s:%s_detail' % ( - value._meta.app_config.name, value._meta.model_name), - args=(value.id,)), - value) + "%s:%s_detail" % (value._meta.app_config.name, value._meta.model_name), + args=(value.id,), + ), + value, + ) return field.verbose_name, display def fk_urlify_for_list(self, obj, field): value = getattr(obj, field) - return reverse( - '%s:%s_detail' % ( - value._meta.app_config.name, - value._meta.model_name), - kwargs={'pk': value.id}), + return ( + reverse( + "%s:%s_detail" % (value._meta.app_config.name, value._meta.model_name), + kwargs={"pk": value.id}, + ), + ) def m2m_urlize_for_detail(self, obj, fieldname): - - manager, fieldname = tuple(fieldname.split('__')) + manager, fieldname = tuple(fieldname.split("__")) manager = getattr(obj, manager) verbose_name = manager.model._meta.verbose_name - display = '' + display = "" for item in manager.all(): obj_m2m = getattr(item, fieldname) @@ -330,44 +347,50 @@ class CrispyLayoutFormMixin: display += '
  • {}
  • '.format( reverse( - '%s:%s_detail' % ( - obj_m2m._meta.app_config.name, obj_m2m._meta.model_name), - args=(obj_m2m.id,)), - obj_m2m) + "%s:%s_detail" + % (obj_m2m._meta.app_config.name, obj_m2m._meta.model_name), + args=(obj_m2m.id,), + ), + obj_m2m, + ) - display += '' + display += "" if display: - display = '
      %s
    ' % display + display = "
      %s
    " % display else: - verbose_name = '' + verbose_name = "" return verbose_name, display def widget__signs(self, obj, fieldname): from sapl.base.models import Metadata + try: md = Metadata.objects.get( - content_type=ContentType.objects.get_for_model( - obj._meta.model), - object_id=obj.id,) - autores = md.metadata['signs'][fieldname]['autores'] - t = template.loader.get_template('base/widget__signs.html') - rendered = str(t.render(context={'signs': autores})) + content_type=ContentType.objects.get_for_model(obj._meta.model), + object_id=obj.id, + ) + autores = md.metadata["signs"][fieldname]["autores"] + t = template.loader.get_template("base/widget__signs.html") + rendered = str(t.render(context={"signs": autores})) except Exception as e: - return '', '' + return "", "" - return 'Assinaturas Eletrônicas', rendered + return "Assinaturas Eletrônicas", rendered @property def layout_display(self): - return [ - {'legend': legend, - 'rows': [[self.get_column(fieldname, span) - for fieldname, span in row] - for row in rows] - } for legend, rows in heads_and_tails(self.get_layout())] + { + "legend": legend, + "rows": [ + [self.get_column(fieldname, span) for fieldname, span in row] + for row in rows + ], + } + for legend, rows in heads_and_tails(self.get_layout()) + ] def read_yaml_from_file(yaml_layout): @@ -387,7 +410,7 @@ def read_layout_from_yaml(yaml_layout, key): base = yaml[key] def line_to_namespans(line): - split = [cell.split(':') for cell in line.split()] + split = [cell.split(":") for cell in line.split()] namespans = [[s[0], int(s[1]) if len(s) > 1 else 0] for s in split] remaining = 12 - sum(s for n, s in namespans) nondefined = [ns for ns in namespans if not ns[1]] @@ -398,5 +421,7 @@ def read_layout_from_yaml(yaml_layout, key): remaining = remaining - span return list(map(tuple, namespans)) - return [[legend] + [line_to_namespans(l) for l in lines] - for legend, lines in base.items()] + return [ + [legend] + [line_to_namespans(l) for l in lines] + for legend, lines in base.items() + ] diff --git a/sapl/crud/base.py b/sapl/crud/base.py index 5816c2ec7..6169e3b9c 100644 --- a/sapl/crud/base.py +++ b/sapl/crud/base.py @@ -5,7 +5,6 @@ from crispy_forms.bootstrap import FieldWithButtons, StrictButton from crispy_forms.layout import Field, Layout from django import forms from django.conf import settings -from django.urls import re_path from django.contrib import messages from django.contrib.auth.mixins import PermissionRequiredMixin from django.core.exceptions import ObjectDoesNotExist @@ -13,7 +12,7 @@ from django.db import models from django.db.models.fields.related import ForeignKey, ManyToManyField from django.http.response import Http404 from django.shortcuts import redirect -from django.urls import reverse +from django.urls import re_path, reverse from django.utils.decorators import classonlymethod from django.utils.encoding import force_str from django.utils.translation import gettext_lazy as _ @@ -22,30 +21,40 @@ from django.views.generic import (CreateView, DeleteView, DetailView, ListView, from django.views.generic.base import ContextMixin from django.views.generic.list import MultipleObjectMixin -from sapl.crispy_layout_mixin import CrispyLayoutFormMixin, get_field_display -from sapl.crispy_layout_mixin import SaplFormHelper -from sapl.rules import (RP_ADD, RP_CHANGE, RP_DELETE, RP_DETAIL, - RP_LIST) +from sapl.crispy_layout_mixin import (CrispyLayoutFormMixin, SaplFormHelper, + get_field_display) +from sapl.rules import RP_ADD, RP_CHANGE, RP_DELETE, RP_DETAIL, RP_LIST from sapl.utils import normalize logger = logging.getLogger(settings.BASE_DIR.name) -ACTION_LIST, ACTION_CREATE, ACTION_DETAIL, ACTION_UPDATE, ACTION_DELETE = \ - 'list', 'create', 'detail', 'update', 'delete' +ACTION_LIST, ACTION_CREATE, ACTION_DETAIL, ACTION_UPDATE, ACTION_DELETE = ( + "list", + "create", + "detail", + "update", + "delete", +) def _form_invalid_message(msg): - return '%s %s' % (_('Formulário inválido.'), msg) + return "%s %s" % (_("Formulário inválido."), msg) -FORM_MESSAGES = {ACTION_CREATE: (_('Registro criado com sucesso!'), - _('O registro não foi criado.')), - ACTION_UPDATE: (_('Registro alterado com sucesso!'), - _('Suas alterações não foram salvas.')), - ACTION_DELETE: (_('Registro excluído com sucesso!'), - _('O registro não foi excluído.'))} -FORM_MESSAGES = {k: (a, _form_invalid_message(b)) - for k, (a, b) in FORM_MESSAGES.items()} +FORM_MESSAGES = { + ACTION_CREATE: (_("Registro criado com sucesso!"), _("O registro não foi criado.")), + ACTION_UPDATE: ( + _("Registro alterado com sucesso!"), + _("Suas alterações não foram salvas."), + ), + ACTION_DELETE: ( + _("Registro excluído com sucesso!"), + _("O registro não foi excluído."), + ), +} +FORM_MESSAGES = { + k: (a, _form_invalid_message(b)) for k, (a, b) in FORM_MESSAGES.items() +} def from_to(start, end): @@ -53,14 +62,14 @@ def from_to(start, end): def make_pagination(index, num_pages): - '''Make a list of adjacent page ranges interspersed with "None"s + """Make a list of adjacent page ranges interspersed with "None"s The list starts with [1, 2] and end with [num_pages-1, num_pages]. The list includes [index-1, index, index+1] "None"s separate those ranges and mean ellipsis (...) Example: [1, 2, None, 10, 11, 12, None, 29, 30] - ''' + """ PAGINATION_LENGTH = 10 if num_pages <= PAGINATION_LENGTH: @@ -73,8 +82,7 @@ def make_pagination(index, num_pages): if index + 1 >= num_pages - 3: tail = from_to(index - 1, num_pages) else: - tail = [index - 1, index, index + 1, - None, num_pages - 1, num_pages] + tail = [index - 1, index, index + 1, None, num_pages - 1, num_pages] head = from_to(1, PAGINATION_LENGTH - len(tail) - 1) return head + [None] + tail @@ -101,23 +109,27 @@ variáveis do crud: class SearchMixin(models.Model): - - search = models.TextField(blank=True, default='') + search = models.TextField(blank=True, default="") logger = logging.getLogger(__name__) class Meta: abstract = True - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None, auto_update_search=True): - - if auto_update_search and hasattr(self, 'fields_search'): - search = '' + def save( + self, + force_insert=False, + force_update=False, + using=None, + update_fields=None, + auto_update_search=True, + ): + if auto_update_search and hasattr(self, "fields_search"): + search = "" for str_field in self.fields_search: - fields = str_field.split('__') + fields = str_field.split("__") if len(fields) == 1: try: - search += str(getattr(self, str_field)) + ' ' + search += str(getattr(self, str_field)) + " " except Exception as e: username = self.request.user.username self.logger.error("user=" + username + ". " + str(e)) @@ -125,50 +137,50 @@ class SearchMixin(models.Model): _self = self for field in fields: _self = getattr(_self, field) - search += str(_self) + ' ' + search += str(_self) + " " self.search = search self.search = normalize(self.search) return super(SearchMixin, self).save( - force_insert=force_insert, force_update=force_update, - using=using, update_fields=update_fields) + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) class ListWithSearchForm(forms.Form): - q = forms.CharField(required=False, label='', - widget=forms.TextInput( - attrs={'type': 'search'})) + q = forms.CharField( + required=False, label="", widget=forms.TextInput(attrs={"type": "search"}) + ) - o = forms.CharField(required=False, label='', - widget=forms.HiddenInput()) + o = forms.CharField(required=False, label="", widget=forms.HiddenInput()) class Meta: - fields = ['q', 'o'] + fields = ["q", "o"] def __init__(self, *args, **kwargs): super(ListWithSearchForm, self).__init__(*args, **kwargs) self.helper = SaplFormHelper() - self.form_class = 'form-inline' - self.helper.form_method = 'GET' + self.form_class = "form-inline" + self.helper.form_method = "GET" self.helper.layout = Layout( - Field('o'), + Field("o"), FieldWithButtons( - Field('q', - placeholder=_('Filtrar Lista'), - css_class='form-control-lg'), + Field("q", placeholder=_("Filtrar Lista"), css_class="form-control-lg"), StrictButton( - _('Filtrar'), css_class='btn-outline-primary btn-lg', - type='submit')) + _("Filtrar"), css_class="btn-outline-primary btn-lg", type="submit" + ), + ), ) class PermissionRequiredForAppCrudMixin(PermissionRequiredMixin): - def has_permission(self): apps = self.app_label if isinstance(apps, str): - apps = apps, + apps = (apps,) # app_label vazio dará acesso geral for app in apps: if not self.request.user.has_module_perms(app): @@ -177,7 +189,6 @@ class PermissionRequiredForAppCrudMixin(PermissionRequiredMixin): class PermissionRequiredContainerCrudMixin(PermissionRequiredMixin): - def has_permission(self): perms = self.get_permission_required() # Torna a view pública se não possuir conteudo @@ -196,8 +207,8 @@ class PermissionRequiredContainerCrudMixin(PermissionRequiredMixin): if not self.has_permission(): return self.handle_no_permission() - if 'pk' in kwargs: - params = {'pk': kwargs['pk']} + if "pk" in kwargs: + params = {"pk": kwargs["pk"]} if self.container_field: params[self.container_field] = request.user.pk @@ -206,42 +217,39 @@ class PermissionRequiredContainerCrudMixin(PermissionRequiredMixin): raise Http404() elif self.container_field: - container = self.container_field.split('__') + container = self.container_field.split("__") if len(container) > 1: - container_model = getattr( - self.model, container[0]).field.related_model + container_model = getattr(self.model, container[0]).field.related_model params = {} - params['__'.join( - container[1:])] = request.user.pk + params["__".join(container[1:])] = request.user.pk if not container_model.objects.filter(**params).exists(): messages.error( request, - 'O Usuário (%s) não está registrado como (%s).' % ( - request.user, container_model._meta.verbose_name)) - return redirect('/') + "O Usuário (%s) não está registrado como (%s)." + % (request.user, container_model._meta.verbose_name), + ) + return redirect("/") else: # TODO: implementar caso o user for o próprio o container pass - return super(PermissionRequiredMixin, self).dispatch( - request, *args, **kwargs) + return super(PermissionRequiredMixin, self).dispatch(request, *args, **kwargs) @property def container_field(self): - if hasattr(self, 'crud') and not hasattr(self.crud, 'container_field'): - self.crud.container_field = '' - if hasattr(self, 'crud'): + if hasattr(self, "crud") and not hasattr(self.crud, "container_field"): + self.crud.container_field = "" + if hasattr(self, "crud"): return self.crud.container_field @property def container_field_set(self): - if hasattr(self, 'crud') and\ - not hasattr(self.crud, 'container_field_set'): - self.crud.container_field_set = '' - if hasattr(self, 'crud'): + if hasattr(self, "crud") and not hasattr(self.crud, "container_field_set"): + self.crud.container_field_set = "" + if hasattr(self, "crud"): return self.crud.container_field_set @property @@ -250,62 +258,64 @@ class PermissionRequiredContainerCrudMixin(PermissionRequiredMixin): class CrudBaseMixin(CrispyLayoutFormMixin): - def __init__(self, **kwargs): super(CrudBaseMixin, self).__init__(**kwargs) - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self self.app_label = obj.model._meta.app_label self.model_name = obj.model._meta.model_name - if hasattr(obj, 'model_set') and obj.model_set: + if hasattr(obj, "model_set") and obj.model_set: self.app_label_set = getattr( - obj.model, obj.model_set).field.model._meta.app_label + obj.model, obj.model_set + ).field.model._meta.app_label self.model_name_set = getattr( - obj.model, obj.model_set).field.model._meta.model_name + obj.model, obj.model_set + ).field.model._meta.model_name - if not hasattr(obj, 'public'): + if not hasattr(obj, "public"): obj.public = [] - if hasattr(self, 'permission_required') and self.permission_required: - + if hasattr(self, "permission_required") and self.permission_required: self.permission_required = tuple( ( - self.permission(pr) for pr in ( - set(self.permission_required) - set(obj.public) - ) + self.permission(pr) + for pr in (set(self.permission_required) - set(obj.public)) ) ) @classmethod def url_name(cls, suffix): - return '%s_%s' % (cls.model._meta.model_name, suffix) + return "%s_%s" % (cls.model._meta.model_name, suffix) def url_name_set(self, suffix): - obj = self.crud if hasattr(self, 'crud') else self - return '%s_%s' % (getattr(obj.model, obj.model_set - ).field.model._meta.model_name, suffix) + obj = self.crud if hasattr(self, "crud") else self + return "%s_%s" % ( + getattr(obj.model, obj.model_set).field.model._meta.model_name, + suffix, + ) def permission(self, rad): - return '%s%s%s' % (self.app_label if rad.endswith('_') else '', - rad, - self.model_name if rad.endswith('_') else '') + return "%s%s%s" % ( + self.app_label if rad.endswith("_") else "", + rad, + self.model_name if rad.endswith("_") else "", + ) def permission_set(self, rad): - return '%s%s%s' % (self.app_label_set if rad.endswith('_') else '', - rad, - self.model_name_set if rad.endswith('_') else '') + return "%s%s%s" % ( + self.app_label_set if rad.endswith("_") else "", + rad, + self.model_name_set if rad.endswith("_") else "", + ) def resolve_url(self, suffix, args=None): namespace = self.model._meta.app_config.name - return reverse('%s:%s' % (namespace, self.url_name(suffix)), - args=args) + return reverse("%s:%s" % (namespace, self.url_name(suffix)), args=args) def resolve_url_set(self, suffix, args=None): - obj = self.crud if hasattr(self, 'crud') else self - namespace = getattr( - obj.model, obj.model_set).field.model._meta.app_config.name - return reverse('%s:%s' % (namespace, self.url_name_set(suffix)), - args=args) + obj = self.crud if hasattr(self, "crud") else self + namespace = getattr(obj.model, obj.model_set).field.model._meta.app_config.name + return reverse("%s:%s" % (namespace, self.url_name_set(suffix)), args=args) @property def ordered_list(self): @@ -313,70 +323,79 @@ class CrudBaseMixin(CrispyLayoutFormMixin): @property def list_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.ListView.permission_required: return self.resolve_url(ACTION_LIST) else: - return self.resolve_url( - ACTION_LIST) if self.request.user.has_perm( - self.permission(RP_LIST)) else '' + return ( + self.resolve_url(ACTION_LIST) + if self.request.user.has_perm(self.permission(RP_LIST)) + else "" + ) @property def create_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.CreateView.permission_required: return self.resolve_url(ACTION_CREATE) else: - return self.resolve_url( - ACTION_CREATE) if self.request.user.has_perm( - self.permission(RP_ADD)) else '' + return ( + self.resolve_url(ACTION_CREATE) + if self.request.user.has_perm(self.permission(RP_ADD)) + else "" + ) @property def detail_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.DetailView.permission_required: return self.resolve_url(ACTION_DETAIL, args=(self.object.id,)) else: - return self.resolve_url(ACTION_DETAIL, args=(self.object.id,))\ - if self.request.user.has_perm( - self.permission(RP_DETAIL)) else '' + return ( + self.resolve_url(ACTION_DETAIL, args=(self.object.id,)) + if self.request.user.has_perm(self.permission(RP_DETAIL)) + else "" + ) @property def update_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.UpdateView.permission_required: return self.resolve_url(ACTION_UPDATE, args=(self.object.id,)) else: - return self.resolve_url(ACTION_UPDATE, args=(self.object.id,))\ - if self.request.user.has_perm( - self.permission(RP_CHANGE)) else '' + return ( + self.resolve_url(ACTION_UPDATE, args=(self.object.id,)) + if self.request.user.has_perm(self.permission(RP_CHANGE)) + else "" + ) @property def delete_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.DeleteView.permission_required: return self.resolve_url(ACTION_DELETE, args=(self.object.id,)) else: - return self.resolve_url(ACTION_DELETE, args=(self.object.id,))\ - if self.request.user.has_perm( - self.permission(RP_DELETE)) else '' + return ( + self.resolve_url(ACTION_DELETE, args=(self.object.id,)) + if self.request.user.has_perm(self.permission(RP_DELETE)) + else "" + ) @property def openapi_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self o = self.object - url = f'/api/{o._meta.app_label}/{o._meta.model_name}/{o.id}' + url = f"/api/{o._meta.app_label}/{o._meta.model_name}/{o.id}" return url def get_template_names(self): names = super(CrudBaseMixin, self).get_template_names() - names.append("crud/%s.html" % - self.template_name_suffix.lstrip('_')) + names.append("crud/%s.html" % self.template_name_suffix.lstrip("_")) return names @property def verbose_name_set(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self return getattr(obj.model, obj.model_set).field.model._meta.verbose_name @property @@ -394,10 +413,10 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): @classmethod def get_url_regex(cls): - return r'^$' + return r"^$" paginate_by = 10 - no_entries_msg = _('Nenhum registro encontrado.') + no_entries_msg = _("Nenhum registro encontrado.") def get_rows(self, object_list): return [self._as_row(obj) for obj in object_list] @@ -413,95 +432,104 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): 'composicao__periodo__data_inicio', 'composicao__periodo__data_fim')] """ r = [] - for (fieldname, _) in self._parse_field_names(self.list_field_names): + for fieldname, _ in self._parse_field_names(self.list_field_names): if not isinstance(fieldname, tuple): - fieldname = fieldname, + fieldname = (fieldname,) s = [] for fn in fieldname: m = self.model - fn = fn.split('__') + fn = fn.split("__") for f in fn: if not f: continue try: f = m._meta.get_field(f) - if hasattr(f, 'related_model') and f.related_model: + if hasattr(f, "related_model") and f.related_model: m = f.related_model except: f = None if f: - hook = 'hook_header_{}'.format(''.join(fn)) + hook = "hook_header_{}".format("".join(fn)) if hasattr(self, hook): header = getattr(self, hook)() s.append(force_str(header)) else: s.append(force_str(f.verbose_name)) else: - hook = 'hook_header_{}'.format(''.join(fn)) + hook = "hook_header_{}".format("".join(fn)) if hasattr(self, hook): header = getattr(self, hook)() s.append(header) - s = ' / '.join(filter(lambda x: x, s)) + s = " / ".join(filter(lambda x: x, s)) r.append(s) return r def _parse_field_names(self, field_name_list): parsed_list = [] for field_name in field_name_list: - field_tuple = tuple(field_name.split('|')) \ - if '|' in field_name else (field_name, None) + field_tuple = ( + tuple(field_name.split("|")) + if "|" in field_name + else (field_name, None) + ) parsed_list.append(field_tuple) return parsed_list def _as_row(self, obj): r = [] - for i, (name, func) in enumerate(self._parse_field_names(self.list_field_names)): + for i, (name, func) in enumerate( + self._parse_field_names(self.list_field_names) + ): # URL padrão para primeira coluna da listagem - url = self.resolve_url( - ACTION_DETAIL, args=(obj.id,)) if i == 0 else None + url = self.resolve_url(ACTION_DETAIL, args=(obj.id,)) if i == 0 else None # gera URL para matéria a partir de fk_urlify_for_list em # layouts.yaml if i > 0 and func is not None: url = getattr(self, func)(obj, name)[0] """Caso o crud list seja para uma relação ManyToManyField""" - if url and hasattr(self, 'crud') and \ - hasattr(self.crud, 'is_m2m') and self.crud.is_m2m: - url = url + ('?pkk=' + self.kwargs['pk'] - if 'pk' in self.kwargs else '') + if ( + url + and hasattr(self, "crud") + and hasattr(self.crud, "is_m2m") + and self.crud.is_m2m + ): + url = url + ("?pkk=" + self.kwargs["pk"] if "pk" in self.kwargs else "") if not isinstance(name, tuple): - name = name, + name = (name,) """ se elemento de list_field_name for uma tupla, constrói a informação com ' - ' se os campos forem simples, ou com
    se for m2m """ if isinstance(name, tuple): - s = '' + s = "" for j, n in enumerate(name): if not n: - s += '
    ' + s += "
    " continue m = obj - n = n.split('__') + n = n.split("__") for f in n[:-1]: m = getattr(m, f) if not m: break - ss = '' + ss = "" try: if m: ss = get_field_display(m, n[-1])[1] ss = ( - ('
    ' if '
      ' in ss else ' - ') + ss) \ - if ss and j != 0 and s else ss + (("
      " if "
        " in ss else " - ") + ss) + if ss and j != 0 and s + else ss + ) except: pass finally: - hook = 'hook_{}'.format(''.join(n)) + hook = "hook_{}".format("".join(n)) if hasattr(self, hook): hs, url = getattr(self, hook)(obj, ss, url) s += str(hs) @@ -512,52 +540,48 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): return r def get_context_data(self, **kwargs): - """ Relevante se na implmentação do crud list, for informado + """Relevante se na implmentação do crud list, for informado um formulário de pesquisa herdado ou o próprio ListWithSearchForm. Só pode ser usado se o model relativo herdar de SearchMixin""" - if hasattr(self, 'form_search_class'): - q = str(self.request.GET.get('q'))\ - if 'q' in self.request.GET else '' + if hasattr(self, "form_search_class"): + q = str(self.request.GET.get("q")) if "q" in self.request.GET else "" - o = self.request.GET['o'] if 'o' in self.request.GET else '1' + o = self.request.GET["o"] if "o" in self.request.GET else "1" - if 'form' not in kwargs: - initial = self.get_initial() if hasattr( - self, 'get_initial') else {} - initial.update({'q': q, 'o': o}) - kwargs['form'] = self.form_search_class( - initial=initial) + if "form" not in kwargs: + initial = self.get_initial() if hasattr(self, "get_initial") else {} + initial.update({"q": q, "o": o}) + kwargs["form"] = self.form_search_class(initial=initial) count = self.object_list.count() context = super().get_context_data(**kwargs) - context.setdefault('title', self.verbose_name_plural) - context['count'] = count + context.setdefault("title", self.verbose_name_plural) + context["count"] = count # pagination if self.paginate_by: - page_obj = context['page_obj'] - paginator = context['paginator'] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + page_obj = context["page_obj"] + paginator = context["paginator"] + context["page_range"] = make_pagination( + page_obj.number, paginator.num_pages + ) # rows - object_list = context['object_list'] - context['headers'] = self.get_headers() - context['rows'] = self.get_rows(object_list) + object_list = context["object_list"] + context["headers"] = self.get_headers() + context["rows"] = self.get_rows(object_list) - context['NO_ENTRIES_MSG'] = self.no_entries_msg + context["NO_ENTRIES_MSG"] = self.no_entries_msg qr = self.request.GET.copy() - if 'page' in qr: - del qr['page'] - context['filter_url'] = ( - '&' + qr.urlencode()) if len(qr) > 0 else '' + if "page" in qr: + del qr["page"] + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" if self.ordered_list: - if 'o' in qr: - del qr['o'] - context['ordering_url'] = ( - '&' + qr.urlencode()) if len(qr) > 0 else '' + if "o" in qr: + del qr["o"] + context["ordering_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" return context def get_queryset(self): @@ -565,12 +589,12 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): # form_search_class # só pode ser usado em models que herdam de SearchMixin - if hasattr(self, 'form_search_class'): + if hasattr(self, "form_search_class"): request = self.request - if request.GET.get('q') is not None: - query = normalize(str(request.GET.get('q'))) + if request.GET.get("q") is not None: + query = normalize(str(request.GET.get("q"))) - query = query.split(' ') + query = query.split(" ") if query: q = models.Q() for item in query: @@ -583,45 +607,44 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): if self.ordered_list: list_field_names = self.list_field_names - o = '1' - desc = '' - if 'o' in self.request.GET: - o = self.request.GET['o'] - desc = '-' if o.startswith('-') else '' + o = "1" + desc = "" + if "o" in self.request.GET: + o = self.request.GET["o"] + desc = "-" if o.startswith("-") else "" # Constroi a ordenação da listagem com base no que o usuário # clicar try: fields_for_ordering = list_field_names[ - (abs(int(o)) - 1) % len(list_field_names)] + (abs(int(o)) - 1) % len(list_field_names) + ] if isinstance(fields_for_ordering, str): - fields_for_ordering = [fields_for_ordering, ] + fields_for_ordering = [ + fields_for_ordering, + ] ordering = () model = self.model for fo in fields_for_ordering: - fm = None try: fm = model._meta.get_field(fo) except Exception as e: username = self.request.user.username - self.logger.info( - "user=" + username + ". " + str(e) - ) + self.logger.info("user=" + username + ". " + str(e)) pass - if fm and hasattr(fm, 'related_model')\ - and fm.related_model: + if fm and hasattr(fm, "related_model") and fm.related_model: rmo = fm.related_model._meta.ordering if rmo: rmo = rmo[0] if not isinstance(rmo, str): rmo = rmo[0] - if rmo.startswith('-'): + if rmo.startswith("-"): rmo = rmo[1:] - fo = '%s__%s' % (fo, rmo) + fo = "%s__%s" % (fo, rmo) fo = desc + fo ordering += (fo,) @@ -638,8 +661,7 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): # print(ordering) except Exception as e: - logger.warning( - _(f"ERRO: construção da tupla de ordenação. {e}")) + logger.warning(_(f"ERRO: construção da tupla de ordenação. {e}")) # print(queryset.query) if not self.request.user.is_authenticated: @@ -653,14 +675,15 @@ class CrudListView(PermissionRequiredContainerCrudMixin, ListView): return queryset -class CrudCreateView(PermissionRequiredContainerCrudMixin, - FormMessagesMixin, CreateView): +class CrudCreateView( + PermissionRequiredContainerCrudMixin, FormMessagesMixin, CreateView +): permission_required = (RP_ADD,) logger = logging.getLogger(__name__) @classmethod def get_url_regex(cls): - return r'^create$' + return r"^create$" form_valid_message, form_invalid_message = FORM_MESSAGES[ACTION_CREATE] @@ -672,8 +695,10 @@ class CrudCreateView(PermissionRequiredContainerCrudMixin, return self.detail_url def get_context_data(self, **kwargs): - kwargs.setdefault('title', _('Adicionar %(verbose_name)s') % { - 'verbose_name': self.verbose_name}) + kwargs.setdefault( + "title", + _("Adicionar %(verbose_name)s") % {"verbose_name": self.verbose_name}, + ) return super(CrudCreateView, self).get_context_data(**kwargs) def form_valid(self, form): @@ -687,34 +712,37 @@ class CrudCreateView(PermissionRequiredContainerCrudMixin, pass if self.container_field: - container = self.container_field.split('__') + container = self.container_field.split("__") if len(container) > 1: # TODO: implementar caso o user for próprio o container - container_model = getattr( - self.model, container[0]).field.related_model + container_model = getattr(self.model, container[0]).field.related_model params = {} - params['__'.join( - container[1:])] = self.request.user.pk + params["__".join(container[1:])] = self.request.user.pk - if 'pk' in self.kwargs: - params['pk'] = self.kwargs['pk'] + if "pk" in self.kwargs: + params["pk"] = self.kwargs["pk"] - container_data = container_model.objects.filter( - **params).first() + container_data = container_model.objects.filter(**params).first() if not container_data: raise Exception( - _('Não é permitido adicionar um registro ' - 'sem estar em um Container %s' - ) % container_model._meta.verbose_name) + _( + "Não é permitido adicionar um registro " + "sem estar em um Container %s" + ) + % container_model._meta.verbose_name + ) - if hasattr(self, 'crud') and\ - hasattr(self.crud, 'is_m2m') and self.crud.is_m2m: + if ( + hasattr(self, "crud") + and hasattr(self.crud, "is_m2m") + and self.crud.is_m2m + ): setattr( - self.object, container[1], getattr( - container_data, container[1])) + self.object, container[1], getattr(container_data, container[1]) + ) response = super().form_valid(form) getattr(self.object, container[0]).add(container_data) return response @@ -724,17 +752,17 @@ class CrudCreateView(PermissionRequiredContainerCrudMixin, return super().form_valid(form) -class CrudDetailView(PermissionRequiredContainerCrudMixin, - DetailView, MultipleObjectMixin): - +class CrudDetailView( + PermissionRequiredContainerCrudMixin, DetailView, MultipleObjectMixin +): permission_required = (RP_DETAIL,) - no_entries_msg = _('Nenhum registro Associado.') + no_entries_msg = _("Nenhum registro Associado.") paginate_by = 10 logger = logging.getLogger(__name__) @classmethod def get_url_regex(cls): - return r'^(?P\d+)$' + return r"^(?P\d+)$" def get_rows(self, object_list): return [self._as_row(obj) for obj in object_list] @@ -743,75 +771,83 @@ class CrudDetailView(PermissionRequiredContainerCrudMixin, if not self.object_list: return [] try: - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self return [ - (getattr( - self.object, obj.model_set).model._meta.get_field( - fieldname).verbose_name - if hasattr(self.object, fieldname) else - getattr( - self.object, obj.model_set).model._meta.get_field( - fieldname).related_model._meta.verbose_name_plural) - for fieldname in self.list_field_names_set] + ( + getattr(self.object, obj.model_set) + .model._meta.get_field(fieldname) + .verbose_name + if hasattr(self.object, fieldname) + else getattr(self.object, obj.model_set) + .model._meta.get_field(fieldname) + .related_model._meta.verbose_name_plural + ) + for fieldname in self.list_field_names_set + ] except Exception as e: username = self.request.user.username self.logger.error("user=" + username + ". " + str(e)) - obj = self.crud if hasattr(self, 'crud') else self - return [getattr( - self.object, - obj.model_set).model._meta.verbose_name_plural] + obj = self.crud if hasattr(self, "crud") else self + return [getattr(self.object, obj.model_set).model._meta.verbose_name_plural] def url_model_set_name(self, suffix): - return '%s_%s' % ( - getattr(self.object, - self.crud.model_set).model._meta.model_name, - suffix) + return "%s_%s" % ( + getattr(self.object, self.crud.model_set).model._meta.model_name, + suffix, + ) def resolve_model_set_url(self, suffix, args=None): - obj = self.crud if hasattr(self, 'crud') else self - namespace = getattr( - self.object, obj.model_set).model._meta.app_config.name - return reverse('%s:%s' % ( - namespace, self.url_model_set_name(suffix)), - args=args) + obj = self.crud if hasattr(self, "crud") else self + namespace = getattr(self.object, obj.model_set).model._meta.app_config.name + return reverse( + "%s:%s" % (namespace, self.url_model_set_name(suffix)), args=args + ) def _as_row(self, obj): try: - return [( - get_field_display(obj, name)[1], - self.resolve_model_set_url(ACTION_DETAIL, args=(obj.id,)) - if i == 0 else None) - for i, name in enumerate(self.list_field_names_set)] + return [ + ( + get_field_display(obj, name)[1], + self.resolve_model_set_url(ACTION_DETAIL, args=(obj.id,)) + if i == 0 + else None, + ) + for i, name in enumerate(self.list_field_names_set) + ] except Exception as e: username = self.request.user.username self.logger.error("user=" + username + ". " + str(e)) - return [( - getattr(obj, name), - self.resolve_model_set_url(ACTION_DETAIL, args=(obj.id,)) - if i == 0 else None) - for i, name in enumerate(self.list_field_names_set)] + return [ + ( + getattr(obj, name), + self.resolve_model_set_url(ACTION_DETAIL, args=(obj.id,)) + if i == 0 + else None, + ) + for i, name in enumerate(self.list_field_names_set) + ] def get_object(self, queryset=None): - if hasattr(self, 'object'): + if hasattr(self, "object"): return self.object return DetailView.get_object(self, queryset=queryset) def get(self, request, *args, **kwargs): try: - self.object = self.model.objects.get(pk=kwargs.get('pk')) + self.object = self.model.objects.get(pk=kwargs.get("pk")) except Exception as e: username = request.user.username self.logger.error("user=" + username + ". " + str(e)) raise Http404 - obj = self.crud if hasattr(self, 'crud') else self - if hasattr(obj, 'model_set') and obj.model_set: + obj = self.crud if hasattr(self, "crud") else self + if hasattr(obj, "model_set") and obj.model_set: self.object_list = self.get_queryset() context = self.get_context_data(object=self.object) return self.render_to_response(context) def get_queryset(self): - obj = self.crud if hasattr(self, 'crud') else self - if hasattr(obj, 'model_set') and obj.model_set: + obj = self.crud if hasattr(self, "crud") else self + if hasattr(obj, "model_set") and obj.model_set: queryset = getattr(self.object, obj.model_set).all() else: queryset = super().get_queryset() @@ -827,29 +863,29 @@ class CrudDetailView(PermissionRequiredContainerCrudMixin, return queryset def get_context_data(self, **kwargs): - obj = self.crud if hasattr(self, 'crud') else self - if hasattr(obj, 'model_set') and obj.model_set: + obj = self.crud if hasattr(self, "crud") else self + if hasattr(obj, "model_set") and obj.model_set: count = self.object_list.count() context = MultipleObjectMixin.get_context_data(self, **kwargs) - context['count'] = count + context["count"] = count if self.paginate_by: - page_obj = context['page_obj'] - paginator = context['paginator'] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + page_obj = context["page_obj"] + paginator = context["paginator"] + context["page_range"] = make_pagination( + page_obj.number, paginator.num_pages + ) # rows - object_list = context['object_list'] - context['headers'] = self.get_headers() - context['rows'] = self.get_rows(object_list) + object_list = context["object_list"] + context["headers"] = self.get_headers() + context["rows"] = self.get_rows(object_list) - context['NO_ENTRIES_MSG'] = self.no_entries_msg + context["NO_ENTRIES_MSG"] = self.no_entries_msg else: context = ContextMixin.get_context_data(self, **kwargs) if self.object: - context['object'] = self.object - context_object_name = self.get_context_object_name( - self.object) + context["object"] = self.object + context_object_name = self.get_context_object_name(self.object) if context_object_name: context[context_object_name] = self.object context.update(kwargs) @@ -858,26 +894,22 @@ class CrudDetailView(PermissionRequiredContainerCrudMixin, @property def model_set_verbose_name(self): - obj = self.crud if hasattr(self, 'crud') else self - return getattr( - self.object, - obj.model_set).model._meta.verbose_name + obj = self.crud if hasattr(self, "crud") else self + return getattr(self.object, obj.model_set).model._meta.verbose_name @property def model_set_verbose_name_plural(self): - obj = self.crud if hasattr(self, 'crud') else self - return getattr( - self.object, - obj.model_set).model._meta.verbose_name_plural + obj = self.crud if hasattr(self, "crud") else self + return getattr(self.object, obj.model_set).model._meta.verbose_name_plural -class CrudUpdateView(PermissionRequiredContainerCrudMixin, - FormMessagesMixin, UpdateView): +class CrudUpdateView( + PermissionRequiredContainerCrudMixin, FormMessagesMixin, UpdateView +): permission_required = (RP_CHANGE,) logger = logging.getLogger(__name__) def form_valid(self, form): - self.object = form.instance try: self.object.modifier = self.request.user @@ -890,7 +922,7 @@ class CrudUpdateView(PermissionRequiredContainerCrudMixin, @classmethod def get_url_regex(cls): - return r'^(?P\d+)/edit$' + return r"^(?P\d+)/edit$" form_valid_message, form_invalid_message = FORM_MESSAGES[ACTION_UPDATE] @@ -902,14 +934,15 @@ class CrudUpdateView(PermissionRequiredContainerCrudMixin, return self.detail_url -class CrudDeleteView(PermissionRequiredContainerCrudMixin, - FormMessagesMixin, DeleteView): +class CrudDeleteView( + PermissionRequiredContainerCrudMixin, FormMessagesMixin, DeleteView +): permission_required = (RP_DELETE,) logger = logging.getLogger(__name__) @classmethod def get_url_regex(cls): - return r'^(?P\d+)/delete$' + return r"^(?P\d+)/delete$" form_valid_message, form_invalid_message = FORM_MESSAGES[ACTION_DELETE] @@ -924,26 +957,22 @@ class CrudDeleteView(PermissionRequiredContainerCrudMixin, try: return super(CrudDeleteView, self).delete(request, args, kwargs) except models.ProtectedError as err: - error_msg = 'Registro não pode ser removido, pois\ + error_msg = "Registro não pode ser removido, pois\ é referenciado por outros registros:
        \ -
          ' - error_msg2 = '' +
            " + error_msg2 = "" for i in err.protected_objects: - error_msg += '
          • {} - {}
          • '.format( - i._meta.verbose_name, i - ) - error_msg2 += '{} - {}, '.format( - i._meta.verbose_name, i - ) - error_msg2 = error_msg2[:len(error_msg2) - 2] + '.' - error_msg += '
          ' + error_msg += "
        • {} - {}
        • ".format(i._meta.verbose_name, i) + error_msg2 += "{} - {}, ".format(i._meta.verbose_name, i) + error_msg2 = error_msg2[: len(error_msg2) - 2] + "." + error_msg += "
        " username = request.user.username - self.logger.error("user=" + username + ". Registro não pode ser removido, pois " - "é referenciado por outros registros: " + error_msg2) - messages.add_message(request, - messages.ERROR, - error_msg) + self.logger.error( + "user=" + username + ". Registro não pode ser removido, pois " + "é referenciado por outros registros: " + error_msg2 + ) + messages.add_message(request, messages.ERROR, error_msg) return self.render_to_response(self.get_context_data()) @@ -956,29 +985,31 @@ class Crud: DetailView = CrudDetailView UpdateView = CrudUpdateView DeleteView = CrudDeleteView - help_topic = '' + help_topic = "" @classonlymethod def get_urls(cls): - def _add_base(view): - if not view: return if not cls.__abstract__: return view - pr = set(view.permission_required) if hasattr( - view, 'permission_required') else set() - - if hasattr(view, 'permission_required') and \ - view.permission_required and \ - hasattr(cls, 'public') and \ - cls.public: + pr = ( + set(view.permission_required) + if hasattr(view, "permission_required") + else set() + ) - #print(view.permission_required, view) - #print(cls.public, cls) + if ( + hasattr(view, "permission_required") + and view.permission_required + and hasattr(cls, "public") + and cls.public + ): + # print(view.permission_required, view) + # print(cls.public, cls) pr = pr - set(cls.public) @@ -997,9 +1028,16 @@ class Crud: CrudUpdateView = _add_base(cls.UpdateView) CrudDeleteView = _add_base(cls.DeleteView) - cruds = CrudListView, CrudCreateView, CrudDetailView, CrudUpdateView, CrudDeleteView + cruds = ( + CrudListView, + CrudCreateView, + CrudDetailView, + CrudUpdateView, + CrudDeleteView, + ) if cls.__abstract__: + class CRUD(cls): __abstract__ = False ListView = CrudListView @@ -1013,30 +1051,46 @@ class Crud: c.crud = CRUD cruds_base = [ - (CrudListView.get_url_regex() - if CrudListView else None, CrudListView, ACTION_LIST), - (CrudCreateView.get_url_regex() - if CrudCreateView else None, CrudCreateView, ACTION_CREATE), - (CrudDetailView.get_url_regex() - if CrudDetailView else None, CrudDetailView, ACTION_DETAIL), - (CrudUpdateView.get_url_regex() - if CrudUpdateView else None, CrudUpdateView, ACTION_UPDATE), - (CrudDeleteView.get_url_regex() - if CrudDeleteView else None, CrudDeleteView, ACTION_DELETE)] + ( + CrudListView.get_url_regex() if CrudListView else None, + CrudListView, + ACTION_LIST, + ), + ( + CrudCreateView.get_url_regex() if CrudCreateView else None, + CrudCreateView, + ACTION_CREATE, + ), + ( + CrudDetailView.get_url_regex() if CrudDetailView else None, + CrudDetailView, + ACTION_DETAIL, + ), + ( + CrudUpdateView.get_url_regex() if CrudUpdateView else None, + CrudUpdateView, + ACTION_UPDATE, + ), + ( + CrudDeleteView.get_url_regex() if CrudDeleteView else None, + CrudDeleteView, + ACTION_DELETE, + ), + ] cruds = [] for crud in cruds_base: if crud[0]: cruds.append(crud) - return [re_path(regex, view.as_view(), name=view.url_name(suffix)) - for regex, view, suffix in cruds] + return [ + re_path(regex, view.as_view(), name=view.url_name(suffix)) + for regex, view, suffix in cruds + ] @classonlymethod def build(cls, _model, _help_topic, _model_set=None, list_field_names=[]): - def create_class(_list_field_names): - class ModelCrud(cls): model = _model model_set = _model_set @@ -1046,20 +1100,21 @@ class Crud: return ModelCrud ModelCrud = create_class(list_field_names) - ModelCrud.__name__ = '%sCrud' % _model.__name__ + ModelCrud.__name__ = "%sCrud" % _model.__name__ return ModelCrud class CrudAux(Crud): """ - Checa permissão para ver qualquer dado de tabela auxiliar - a permissão base.view_tabelas_auxiliares está definada class Meta - do model sapl.base.models.AppConfig que, naturalmente é um arquivo - de configuração geral e só pode ser acessado através das Tabelas - Auxiliares... Com isso o script de geração de perfis acaba que por - criar essa permissão apenas para o perfil Operador Geral. + Checa permissão para ver qualquer dado de tabela auxiliar + a permissão base.view_tabelas_auxiliares está definada class Meta + do model sapl.base.models.AppConfig que, naturalmente é um arquivo + de configuração geral e só pode ser acessado através das Tabelas + Auxiliares... Com isso o script de geração de perfis acaba que por + criar essa permissão apenas para o perfil Operador Geral. """ - permission_required = ('base.view_tabelas_auxiliares',) + + permission_required = ("base.view_tabelas_auxiliares",) class ListView(Crud.ListView): template_name = "crud/list_tabaux.html" @@ -1074,15 +1129,13 @@ class CrudAux(Crud): Se o valor de subnav_template_name é nulo faz o filter subnav não abrir o padrão e nem um outro arquivo. """ - if 'subnav_template_name' not in context: - context['subnav_template_name'] = self.subnav_template_name + if "subnav_template_name" not in context: + context["subnav_template_name"] = self.subnav_template_name return context @classonlymethod def build(cls, _model, _help_topic, _model_set=None, list_field_names=[]): - - ModelCrud = Crud.build( - _model, _help_topic, _model_set, list_field_names) + ModelCrud = Crud.build(_model, _help_topic, _model_set, list_field_names) class ModelCrudAux(CrudAux, ModelCrud): pass @@ -1095,59 +1148,70 @@ class MasterDetailCrud(Crud): link_return_to_parent_field = False class BaseMixin(Crud.BaseMixin): - @property def list_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.ListView: - return '' - return self.resolve_url(ACTION_LIST, args=(self.kwargs['pk'],))\ - if self.request.user.has_perm(self.permission(RP_LIST)) else '' + return "" + return ( + self.resolve_url(ACTION_LIST, args=(self.kwargs["pk"],)) + if self.request.user.has_perm(self.permission(RP_LIST)) + else "" + ) @property def create_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.CreateView: - return '' - return self.resolve_url(ACTION_CREATE, args=(self.kwargs['pk'],))\ - if self.request.user.has_perm(self.permission(RP_ADD)) else '' + return "" + return ( + self.resolve_url(ACTION_CREATE, args=(self.kwargs["pk"],)) + if self.request.user.has_perm(self.permission(RP_ADD)) + else "" + ) @property def detail_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.DetailView: - return '' - pkk = self.request.GET['pkk'] if 'pkk' in self.request.GET else '' - return (super().detail_url + (('?pkk=' + pkk) if pkk else ''))\ - if self.request.user.has_perm( - self.permission(RP_DETAIL)) else '' + return "" + pkk = self.request.GET["pkk"] if "pkk" in self.request.GET else "" + return ( + (super().detail_url + (("?pkk=" + pkk) if pkk else "")) + if self.request.user.has_perm(self.permission(RP_DETAIL)) + else "" + ) @property def update_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.UpdateView: - return '' - pkk = self.request.GET['pkk'] if 'pkk' in self.request.GET else '' - return (super().update_url + (('?pkk=' + pkk) if pkk else ''))\ - if self.request.user.has_perm( - self.permission(RP_CHANGE)) else '' + return "" + pkk = self.request.GET["pkk"] if "pkk" in self.request.GET else "" + return ( + (super().update_url + (("?pkk=" + pkk) if pkk else "")) + if self.request.user.has_perm(self.permission(RP_CHANGE)) + else "" + ) @property def delete_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.DeleteView: - return '' - return super().delete_url\ - if self.request.user.has_perm( - self.permission(RP_DELETE)) else '' + return "" + return ( + super().delete_url + if self.request.user.has_perm(self.permission(RP_DELETE)) + else "" + ) def get_context_data(self, **kwargs): - obj = self.crud if hasattr(self, 'crud') else self - self.object = getattr(self, 'object', None) + obj = self.crud if hasattr(self, "crud") else self + self.object = getattr(self, "object", None) parent_object = None if self.object: - if '__' in obj.parent_field: - fields = obj.parent_field.split('__') + if "__" in obj.parent_field: + fields = obj.parent_field.split("__") parent_object = self.object for field in fields: parent_object = getattr(parent_object, field) @@ -1156,9 +1220,9 @@ class MasterDetailCrud(Crud): if not isinstance(parent_object, models.Model): if parent_object.count() > 1: - if 'pkk' not in self.request.GET: + if "pkk" not in self.request.GET: raise Http404() - root_pk = self.request.GET['pkk'] + root_pk = self.request.GET["pkk"] parent_object = parent_object.filter(id=root_pk) parent_object = parent_object.first() @@ -1168,22 +1232,26 @@ class MasterDetailCrud(Crud): root_pk = parent_object.pk else: - root_pk = self.kwargs['pk'] if 'pkk' not in self.request.GET\ - else self.request.GET['pkk'] - kwargs.setdefault('root_pk', root_pk) - - title = '%s (%s)' % ( - self.object, - parent_object - ) if parent_object else '' + root_pk = ( + self.kwargs["pk"] + if "pkk" not in self.request.GET + else self.request.GET["pkk"] + ) + kwargs.setdefault("root_pk", root_pk) + + title = ( + "%s (%s)" % (self.object, parent_object) + if parent_object + else "" + ) context = super(CrudBaseMixin, self).get_context_data(**kwargs) - if 'title' not in context and title: - context['title'] = title + if "title" not in context and title: + context["title"] = title return context class ListView(Crud.ListView): - permission_required = RP_LIST, + permission_required = (RP_LIST,) logger = logging.getLogger(__name__) def get(self, request, *args, **kwargs): @@ -1191,41 +1259,37 @@ class MasterDetailCrud(Crud): @classmethod def get_url_regex(cls): - return r'^(?P\d+)/%s$' % cls.model._meta.model_name + return r"^(?P\d+)/%s$" % cls.model._meta.model_name def get_context_data(self, **kwargs): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self context = CrudListView.get_context_data(self, **kwargs) parent_model = None - if '__' in obj.parent_field: - fields = obj.parent_field.split('__') + if "__" in obj.parent_field: + fields = obj.parent_field.split("__") parent_model = pm = self.model for field in fields: pm = getattr(pm, field) if isinstance(pm.field, ForeignKey): - parent_model = getattr( - parent_model, field).field.related_model + parent_model = getattr(parent_model, field).field.related_model else: - parent_model = getattr( - parent_model, field).rel.related_model + parent_model = getattr(parent_model, field).rel.related_model pm = parent_model else: - parent_model = getattr( - self.model, obj.parent_field) - if isinstance(parent_model.field, ( - ForeignKey, ManyToManyField)): + parent_model = getattr(self.model, obj.parent_field) + if isinstance(parent_model.field, (ForeignKey, ManyToManyField)): parent_model = parent_model.field.related_model else: parent_model = parent_model.rel.related_model - params = {'pk': kwargs['root_pk']} + params = {"pk": kwargs["root_pk"]} if self.container_field: - container = self.container_field.split('__') + container = self.container_field.split("__") if len(container) > 1: - params['__'.join(container[1:])] = self.request.user.pk + params["__".join(container[1:])] = self.request.user.pk try: parent_object = parent_model.objects.get(**params) @@ -1234,16 +1298,17 @@ class MasterDetailCrud(Crud): self.logger.error("user=" + username + ". " + str(e)) raise Http404() - context[ - 'title'] = '%s (%s)' % ( - context['title'], parent_object) + context["title"] = "%s (%s)" % ( + context["title"], + parent_object, + ) return context def get_queryset(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self qs = super().get_queryset() - kwargs = {obj.parent_field: self.kwargs['pk']} + kwargs = {obj.parent_field: self.kwargs["pk"]} """if self.container_field: kwargs[self.container_field] = self.request.user.pk""" @@ -1254,48 +1319,42 @@ class MasterDetailCrud(Crud): return PermissionRequiredMixin.dispatch(self, request, *args, **kwargs) class CreateView(Crud.CreateView): - permission_required = RP_ADD, + permission_required = (RP_ADD,) logger = logging.getLogger(__name__) def dispatch(self, request, *args, **kwargs): - return PermissionRequiredMixin.dispatch( - self, request, *args, **kwargs) + return PermissionRequiredMixin.dispatch(self, request, *args, **kwargs) @classmethod def get_url_regex(cls): - return r'^(?P\d+)/%s/create$' % cls.model._meta.model_name + return r"^(?P\d+)/%s/create$" % cls.model._meta.model_name def get_form(self, form_class=None): - obj = self.crud if hasattr(self, 'crud') else self - form = super(MasterDetailCrud.CreateView, self).get_form( - self.form_class) - parent_field = obj.parent_field.split('__') + obj = self.crud if hasattr(self, "crud") else self + form = super(MasterDetailCrud.CreateView, self).get_form(self.form_class) + parent_field = obj.parent_field.split("__") if not obj.is_m2m or len(parent_field) > 1: field = self.model._meta.get_field(parent_field[0]) try: - parent = field.related_model.objects.get( - pk=self.kwargs['pk']) + parent = field.related_model.objects.get(pk=self.kwargs["pk"]) except ObjectDoesNotExist: raise Http404() setattr(form.instance, parent_field[0], parent) return form def get_context_data(self, **kwargs): + obj = self.crud if hasattr(self, "crud") else self + context = Crud.CreateView.get_context_data(self, **kwargs) - obj = self.crud if hasattr(self, 'crud') else self - context = Crud.CreateView.get_context_data( - self, **kwargs) - - params = {'pk': self.kwargs['pk']} + params = {"pk": self.kwargs["pk"]} if self.container_field: # FIXME refatorar para parent_field com '__' - parent_model = getattr( - self.model, obj.parent_field).field.related_model + parent_model = getattr(self.model, obj.parent_field).field.related_model - container = self.container_field.split('__') + container = self.container_field.split("__") if len(container) > 1: - params['__'.join(container[1:])] = self.request.user.pk + params["__".join(container[1:])] = self.request.user.pk try: parent_object = parent_model.objects.get(**params) @@ -1306,12 +1365,13 @@ class MasterDetailCrud(Crud): else: parent_model = self.model parent_object = None - if '__' in obj.parent_field: - fields = obj.parent_field.split('__') + if "__" in obj.parent_field: + fields = obj.parent_field.split("__") for field in fields: if parent_model == self.model: parent_model = getattr( - parent_model, field).field.related_model + parent_model, field + ).field.related_model parent_object = parent_model.objects.get(**params) else: parent_object = getattr(parent_object, field) @@ -1325,11 +1385,13 @@ class MasterDetailCrud(Crud): parent_object = parent_model.objects.get(**params) - context['root_pk'] = parent_object.pk + context["root_pk"] = parent_object.pk if parent_object: - context['title'] = '%s (%s)' % ( - context['title'], parent_object) + context["title"] = "%s (%s)" % ( + context["title"], + parent_object, + ) return context @@ -1337,18 +1399,17 @@ class MasterDetailCrud(Crud): def cancel_url(self): if self.list_url: return self.list_url - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self - params = {'pk': self.kwargs['pk']} + params = {"pk": self.kwargs["pk"]} parent_model = self.model parent_object = None - if '__' in obj.parent_field: - fields = obj.parent_field.split('__') + if "__" in obj.parent_field: + fields = obj.parent_field.split("__") for field in fields: if parent_model == self.model: - parent_model = getattr( - parent_model, field).field.related_model + parent_model = getattr(parent_model, field).field.related_model parent_object = parent_model.objects.get(**params) else: parent_object = getattr(parent_object, field) @@ -1356,34 +1417,37 @@ class MasterDetailCrud(Crud): else: parent_model = getattr( - parent_model, obj.parent_field).field.related_model + parent_model, obj.parent_field + ).field.related_model parent_object = parent_model.objects.get(**params) return reverse( - '%s:%s' % (parent_model._meta.app_config.name, - '%s_%s' % ( - parent_model._meta.model_name, - ACTION_DETAIL)), - kwargs={'pk': parent_object.pk}) + "%s:%s" + % ( + parent_model._meta.app_config.name, + "%s_%s" % (parent_model._meta.model_name, ACTION_DETAIL), + ), + kwargs={"pk": parent_object.pk}, + ) class UpdateView(Crud.UpdateView): - permission_required = RP_CHANGE, + permission_required = (RP_CHANGE,) @classmethod def get_url_regex(cls): - return r'^%s/(?P\d+)/edit$' % cls.model._meta.model_name + return r"^%s/(?P\d+)/edit$" % cls.model._meta.model_name class DeleteView(Crud.DeleteView): - permission_required = RP_DELETE, + permission_required = (RP_DELETE,) @classmethod def get_url_regex(cls): - return r'^%s/(?P\d+)/delete$' % cls.model._meta.model_name + return r"^%s/(?P\d+)/delete$" % cls.model._meta.model_name def get_success_url(self): - obj = self.crud if hasattr(self, 'crud') else self - if '__' in obj.parent_field: - fields = obj.parent_field.split('__') + obj = self.crud if hasattr(self, "crud") else self + if "__" in obj.parent_field: + fields = obj.parent_field.split("__") parent_object = self.object for field in fields: parent_object = getattr(parent_object, field) @@ -1392,9 +1456,9 @@ class MasterDetailCrud(Crud): parent_object = getattr(self.object, obj.parent_field) if not isinstance(parent_object, models.Model): if parent_object.count() > 1: - if 'pkk' not in self.request.GET: + if "pkk" not in self.request.GET: raise Http404 - root_pk = self.request.GET['pkk'] + root_pk = self.request.GET["pkk"] parent_object = parent_object.filter(id=root_pk) parent_object = parent_object.first() @@ -1407,32 +1471,38 @@ class MasterDetailCrud(Crud): if obj.is_m2m: namespace = parent_object._meta.app_config.name - return reverse('%s:%s' % ( - namespace, - '%s_%s' % (parent_object._meta.model_name, ACTION_DETAIL)), - args=(pk,)) + return reverse( + "%s:%s" + % ( + namespace, + "%s_%s" % (parent_object._meta.model_name, ACTION_DETAIL), + ), + args=(pk,), + ) else: return self.resolve_url(ACTION_LIST, args=(pk,)) class DetailView(Crud.DetailView): - permission_required = RP_DETAIL, - template_name = 'crud/detail_detail.html' + permission_required = (RP_DETAIL,) + template_name = "crud/detail_detail.html" @classmethod def get_url_regex(cls): - return r'^%s/(?P\d+)$' % cls.model._meta.model_name + return r"^%s/(?P\d+)$" % cls.model._meta.model_name @property def detail_list_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.ListView: - return '' - - if obj.ListView.permission_required not in obj.public or\ - self.request.user.has_perm(self.permission(RP_LIST)): - if '__' in obj.parent_field: - fields = obj.parent_field.split('__') + return "" + + if ( + obj.ListView.permission_required not in obj.public + or self.request.user.has_perm(self.permission(RP_LIST)) + ): + if "__" in obj.parent_field: + fields = obj.parent_field.split("__") parent_object = self.object for field in fields: parent_object = getattr(parent_object, field) @@ -1441,9 +1511,9 @@ class MasterDetailCrud(Crud): if not isinstance(parent_object, models.Model): if parent_object.count() > 1: - if 'pkk' not in self.request.GET: + if "pkk" not in self.request.GET: raise Http404 - root_pk = self.request.GET['pkk'] + root_pk = self.request.GET["pkk"] parent_object = parent_object.filter(id=root_pk) parent_object = parent_object.first() @@ -1455,23 +1525,23 @@ class MasterDetailCrud(Crud): pk = root_pk return self.resolve_url(ACTION_LIST, args=(pk,)) else: - return '' + return "" @property def detail_create_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.CreateView: - return '' + return "" if self.request.user.has_perm(self.permission(RP_ADD)): - parent_field = obj.parent_field.split('__')[0] + parent_field = obj.parent_field.split("__")[0] parent_object = getattr(self.object, parent_field) if not isinstance(parent_object, models.Model): if parent_object.count() > 1: - if 'pkk' not in self.request.GET: + if "pkk" not in self.request.GET: raise Http404 - root_pk = self.request.GET['pkk'] + root_pk = self.request.GET["pkk"] parent_object = parent_object.filter(id=root_pk) parent_object = parent_object.first() @@ -1484,24 +1554,26 @@ class MasterDetailCrud(Crud): if not obj.is_m2m: return url else: - if '__' in obj.parent_field: - fields = obj.parent_field.split('__') + if "__" in obj.parent_field: + fields = obj.parent_field.split("__") parent_object = self.object for field in fields: parent_object = getattr(parent_object, field) else: parent_object = getattr(self.object, obj.parent_field) - return url + '?pkk=' + str(parent_object.pk) + return url + "?pkk=" + str(parent_object.pk) else: - return '' + return "" @property def detail_set_create_url(self): - obj = self.crud if hasattr(self, 'crud') else self - if hasattr(obj, 'model_set') and obj.model_set\ - and self.request.user.has_perm( - self.permission_set(RP_ADD)): + obj = self.crud if hasattr(self, "crud") else self + if ( + hasattr(obj, "model_set") + and obj.model_set + and self.request.user.has_perm(self.permission_set(RP_ADD)) + ): root_pk = self.object.pk pk = root_pk @@ -1509,61 +1581,65 @@ class MasterDetailCrud(Crud): if not obj.is_m2m: return url else: - if '__' in obj.parent_field: - fields = obj.parent_field.split('__') + if "__" in obj.parent_field: + fields = obj.parent_field.split("__") parent_object = self.object for field in fields: parent_object = getattr(parent_object, field) else: parent_object = getattr(self.object, obj.parent_field) - return url + '?pkk=' + str(parent_object.pk) + return url + "?pkk=" + str(parent_object.pk) else: - return '' + return "" @property def detail_root_detail_url(self): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self if not obj.link_return_to_parent_field: - return '' - if hasattr(obj, 'parent_field'): - parent_field = obj.parent_field.split('__') + return "" + if hasattr(obj, "parent_field"): + parent_field = obj.parent_field.split("__") if not obj.is_m2m or len(parent_field) > 1: # field = self.model._meta.get_field(parent_field[0]) - if isinstance(getattr( - self.object, parent_field[0]), models.Model): + if isinstance(getattr(self.object, parent_field[0]), models.Model): parent_object = getattr(self.object, parent_field[0]) root_pk = parent_object.pk pk = root_pk namespace = parent_object._meta.app_config.name - return reverse('%s:%s' % ( - namespace, - '%s_%s' % (parent_object._meta.model_name, - ACTION_DETAIL)), - args=(pk,)) - return '' + return reverse( + "%s:%s" + % ( + namespace, + "%s_%s" + % (parent_object._meta.model_name, ACTION_DETAIL), + ), + args=(pk,), + ) + return "" @property def detail_root_detail_verbose_name(self): - obj = self.crud if hasattr(self, 'crud') else self - if hasattr(obj, 'parent_field'): - parent_field = obj.parent_field.split('__') + obj = self.crud if hasattr(self, "crud") else self + if hasattr(obj, "parent_field"): + parent_field = obj.parent_field.split("__") if not obj.is_m2m or len(parent_field) > 1: field = self.model._meta.get_field(parent_field[0]) return field.verbose_name - return '' + return "" @classonlymethod - def build(cls, model, parent_field, help_topic, - _model_set=None, list_field_names=[]): + def build( + cls, model, parent_field, help_topic, _model_set=None, list_field_names=[] + ): crud = super(MasterDetailCrud, cls).build( - model, help_topic, _model_set=_model_set, - list_field_names=list_field_names) + model, help_topic, _model_set=_model_set, list_field_names=list_field_names + ) crud.parent_field = parent_field return crud @@ -1572,12 +1648,10 @@ class CrudBaseForListAndDetailExternalAppView(MasterDetailCrud): CreateView, UpdateView, DeleteView = None, None, None class BaseMixin(MasterDetailCrud.BaseMixin): - def resolve_url(self, suffix, args=None): - obj = self.crud if hasattr(self, 'crud') else self + obj = self.crud if hasattr(self, "crud") else self """ namespace deve ser redirecionado para app local pois o models colocados nos cruds que herdam este Crud são de outras app """ - return reverse('%s:%s' % (obj.namespace, self.url_name(suffix)), - args=args) + return reverse("%s:%s" % (obj.namespace, self.url_name(suffix)), args=args) diff --git a/sapl/crud/tests/settings.py b/sapl/crud/tests/settings.py index d2450045a..d16b37578 100644 --- a/sapl/crud/tests/settings.py +++ b/sapl/crud/tests/settings.py @@ -3,68 +3,72 @@ from os.path import dirname, join BASE_DIR = dirname(dirname(dirname(__file__))) DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': ':memory:', + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": ":memory:", }, } INSTALLED_APPS = ( - 'django.contrib.contenttypes', - 'django.contrib.auth', - 'django.contrib.messages', - 'django.contrib.sessions', - 'crud.tests.stub_app', - 'crispy_forms', + "django.contrib.contenttypes", + "django.contrib.auth", + "django.contrib.messages", + "django.contrib.sessions", + "crud.tests.stub_app", + "crispy_forms", ) -ROOT_URLCONF = 'crud.tests.stub_app.urls' +ROOT_URLCONF = "crud.tests.stub_app.urls" USE_TZ = True -SECRET_KEY = 'zzz...' +SECRET_KEY = "zzz..." -TEMPLATES = [{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [join(BASE_DIR, 'crud/tests/stub_app/templates'), - join(BASE_DIR, 'templates')], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - "django.core.context_processors.media", - "django.core.context_processors.static", - 'django.contrib.messages.context_processors.messages', +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [ + join(BASE_DIR, "crud/tests/stub_app/templates"), + join(BASE_DIR, "templates"), ], - }, -}] + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.core.context_processors.media", + "django.core.context_processors.static", + "django.contrib.messages.context_processors.messages", + ], + }, + } +] -STATIC_URL = '/static/' +STATIC_URL = "/static/" MIDDLEWARE_CLASSES = ( - 'django.contrib.sessions.middleware.SessionMiddleware', + "django.contrib.sessions.middleware.SessionMiddleware", # 'django.middleware.locale.LocaleMiddleware', # 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', + "django.contrib.auth.middleware.AuthenticationMiddleware", # 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', + "django.contrib.messages.middleware.MessageMiddleware", # 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 'django.middleware.security.SecurityMiddleware', ) SILENCED_SYSTEM_CHECKS = [ - '1_7.W001', # Unset MIDDLEWARE_CLASSES warning + "1_7.W001", # Unset MIDDLEWARE_CLASSES warning ] -TIME_ZONE = 'America/Sao_Paulo' +TIME_ZONE = "America/Sao_Paulo" USE_I18N = True USE_L10N = False USE_TZ = True # DATE_FORMAT = 'N j, Y' -DATE_FORMAT = 'd/m/Y' -SHORT_DATE_FORMAT = 'd/m/Y' -DATE_INPUT_FORMATS = ('%d/%m/%Y', '%m-%d-%Y', '%Y-%m-%d') +DATE_FORMAT = "d/m/Y" +SHORT_DATE_FORMAT = "d/m/Y" +DATE_INPUT_FORMATS = ("%d/%m/%Y", "%m-%d-%Y", "%Y-%m-%d") diff --git a/sapl/crud/tests/stub_app/models.py b/sapl/crud/tests/stub_app/models.py index 8608077e6..543b9e20d 100644 --- a/sapl/crud/tests/stub_app/models.py +++ b/sapl/crud/tests/stub_app/models.py @@ -11,13 +11,13 @@ class Continent(models.Model): class Country(models.Model): name = models.CharField(max_length=50) continent = models.ForeignKey(Continent, on_delete=models.CASCADE) - is_cold = models.BooleanField(choices=[(True, 'Yes'), (False, 'No')]) + is_cold = models.BooleanField(choices=[(True, "Yes"), (False, "No")]) population = models.PositiveIntegerField(blank=True, null=True) description = models.TextField(blank=True) class Meta: - verbose_name = 'Country' - verbose_name_plural = 'Countries' + verbose_name = "Country" + verbose_name_plural = "Countries" def __str__(self): return self.name diff --git a/sapl/crud/tests/stub_app/urls.py b/sapl/crud/tests/stub_app/urls.py index 27d15adfe..efeb3aa02 100644 --- a/sapl/crud/tests/stub_app/urls.py +++ b/sapl/crud/tests/stub_app/urls.py @@ -3,6 +3,5 @@ from django.urls import include, path from .views import CityCrud, CountryCrud urlpatterns = [ - path('country/', include( - CountryCrud.get_urls() + CityCrud.get_urls(), 'stub_app')), + path("country/", include(CountryCrud.get_urls() + CityCrud.get_urls(), "stub_app")), ] diff --git a/sapl/crud/tests/stub_app/views.py b/sapl/crud/tests/stub_app/views.py index 11d4e3d9f..a41cd31af 100644 --- a/sapl/crud/tests/stub_app/views.py +++ b/sapl/crud/tests/stub_app/views.py @@ -6,7 +6,7 @@ from .models import City, Country class CountryCrud(Crud): model = Country - help_topic = 'help_topic', + help_topic = ("help_topic",) class ListView(CrudListView): paginate_by = 10 @@ -14,4 +14,4 @@ class CountryCrud(Crud): class CityCrud(MasterDetailCrud): model = City - help_topic = 'help_topic', + help_topic = ("help_topic",) diff --git a/sapl/crud/tests/test_base.py b/sapl/crud/tests/test_base.py index bd5e0d95c..9fa9f122f 100644 --- a/sapl/crud/tests/test_base.py +++ b/sapl/crud/tests/test_base.py @@ -1,7 +1,7 @@ from django.core.urlresolvers import reverse from model_bakery import baker - get_field_display, make_pagination) +from sapl.crud.base import get_field_display, make_pagination from sapl.crud.tests.stub_app.models import Continent, Country from sapl.crud.tests.stub_app.views import CountryCrud @@ -13,10 +13,12 @@ __ = None # for test readability @pytest.mark.parametrize( "index, num_pages, result", - [(i, k, from_to(1, k)) - for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - for k in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] - ] + [ + [ + (i, k, from_to(1, k)) + for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + for k in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + ] + + [ (11, 11, [1, 2, 3, 4, 5, 6, 7, __, 10, (11)]), (10, 11, [1, 2, 3, 4, 5, 6, __, 9, (10), 11]), (9, 11, [1, 2, 3, 4, 5, __, 8, (9), 10, 11]), @@ -28,7 +30,6 @@ __ = None # for test readability (3, 11, [1, 2, (3), 4, 5, 6, 7, __, 10, 11]), (2, 11, [1, (2), 3, 4, 5, 6, 7, __, 10, 11]), (1, 11, [(1), 2, 3, 4, 5, 6, 7, __, 10, 11]), - (12, 12, [1, 2, 3, 4, 5, 6, 7, __, 11, (12)]), (11, 12, [1, 2, 3, 4, 5, 6, __, 10, (11), 12]), (10, 12, [1, 2, 3, 4, 5, __, 9, (10), 11, 12]), @@ -41,12 +42,12 @@ __ = None # for test readability (3, 12, [1, 2, (3), 4, 5, 6, 7, __, 11, 12]), (2, 12, [1, (2), 3, 4, 5, 6, 7, __, 11, 12]), (1, 12, [(1), 2, 3, 4, 5, 6, 7, __, 11, 12]), - # some random entries (8, 22, [1, 2, 3, __, 7, (8), 9, __, 21, 22]), (1, 17, [(1), 2, 3, 4, 5, 6, 7, __, 16, 17]), (22, 25, [1, 2, 3, 4, __, 21, (22), 23, 24, 25]), - ]) + ], +) def test_make_pagination(index, num_pages, result): assert num_pages < 10 or len(result) == 10 assert make_pagination(index, num_pages) == result @@ -54,29 +55,32 @@ def test_make_pagination(index, num_pages, result): def test_get_field_display(): stub = baker.prepare(Country, is_cold=True) - assert get_field_display(stub, 'name')[1] == stub.name - assert get_field_display(stub, 'continent')[1] == str(stub.continent) + assert get_field_display(stub, "name")[1] == stub.name + assert get_field_display(stub, "continent")[1] == str(stub.continent) # must return choice display, not the value assert stub.is_cold is True - assert get_field_display(stub, 'is_cold')[1] == 'Yes' + assert get_field_display(stub, "is_cold")[1] == "Yes" # None is displayed as an empty string assert stub.population is None - assert get_field_display(stub, 'population')[1] == '' + assert get_field_display(stub, "population")[1] == "" -@pytest.mark.parametrize("_layout, result", [ - ([['Dados Complementares']], []), # missing rows definition - - ([['Basic', [('name', 9), ('population', 3)]], - ['More Details', [('description', 12)]], - ], - ['name', 'population']), -]) +@pytest.mark.parametrize( + "_layout, result", + [ + ([["Dados Complementares"]], []), # missing rows definition + ( + [ + ["Basic", [("name", 9), ("population", 3)]], + ["More Details", [("description", 12)]], + ], + ["name", "population"], + ), + ], +) def test_layout_fieldnames(_layout, result): - class StubMixin(CrispyLayoutFormMixin): - def get_layout(self): return _layout @@ -85,21 +89,20 @@ def test_layout_fieldnames(_layout, result): def test_layout_detail_fieldsets(): - - stub = baker.make(Country, - name='Brazil', - continent__name='South America', - is_cold=False) + stub = baker.make( + Country, name="Brazil", continent__name="South America", is_cold=False + ) class StubMixin(CrispyLayoutFormMixin): - def get_layout(self): - return [['Basic Data', - [('name', 9), ('continent', 3)], - [('population', 6), ('is_cold', 6)] - ], - ['More Details', [('description', 12)]], - ] + return [ + [ + "Basic Data", + [("name", 9), ("continent", 3)], + [("population", 6), ("is_cold", 6)], + ], + ["More Details", [("description", 12)]], + ] def get_object(self): return stub @@ -110,154 +113,183 @@ def test_layout_detail_fieldsets(): assert stub.population is None assert view.layout_display == [ - {'legend': 'Basic Data', - 'rows': [[{'id': 'name', - 'span': 9, - 'text': stub.name, - 'verbose_name': 'name'}, - {'id': 'continent', - 'span': 3, - 'text': stub.continent.name, - 'verbose_name': 'continent'} - ], - - [{'id': 'population', - 'span': 6, - 'text': '', - 'verbose_name': 'population'}, - {'id': 'is_cold', - 'span': 6, - 'text': 'No', - 'verbose_name': 'is cold'}]]}, - {'legend': 'More Details', - 'rows': [[{'id': 'description', - 'span': 12, - 'text': '', - 'verbose_name': 'description'}]]}] + { + "legend": "Basic Data", + "rows": [ + [ + { + "id": "name", + "span": 9, + "text": stub.name, + "verbose_name": "name", + }, + { + "id": "continent", + "span": 3, + "text": stub.continent.name, + "verbose_name": "continent", + }, + ], + [ + { + "id": "population", + "span": 6, + "text": "", + "verbose_name": "population", + }, + { + "id": "is_cold", + "span": 6, + "text": "No", + "verbose_name": "is cold", + }, + ], + ], + }, + { + "legend": "More Details", + "rows": [ + [ + { + "id": "description", + "span": 12, + "text": "", + "verbose_name": "description", + } + ] + ], + }, + ] def test_reverse(): - assert '/country/' == reverse('sapl.stub_app:country_list') - assert '/country/create' == reverse('sapl.stub_app:country_create') - assert '/country/2' == reverse('sapl.stub_app:country_detail', args=(2,)) - assert '/country/2/edit' == reverse( - 'sapl.stub_app:country_update', args=(2,)) - assert '/country/2/delete' == reverse( - 'sapl.stub_app:country_delete', args=(2,)) + assert "/country/" == reverse("sapl.stub_app:country_list") + assert "/country/create" == reverse("sapl.stub_app:country_create") + assert "/country/2" == reverse("sapl.stub_app:country_detail", args=(2,)) + assert "/country/2/edit" == reverse("sapl.stub_app:country_update", args=(2,)) + assert "/country/2/delete" == reverse("sapl.stub_app:country_delete", args=(2,)) def assert_h1(res, title): - assert res.html.find('main').find('h1').text.strip() == title + assert res.html.find("main").find("h1").text.strip() == title NO_ENTRIES_MSG = str(CrudListView.no_entries_msg) # "unlazy" def assert_on_list_page(res): - assert_h1(res, 'Countries') - assert 'Adicionar Country' in res - assert res.html.find('table') or NO_ENTRIES_MSG in res + assert_h1(res, "Countries") + assert "Adicionar Country" in res + assert res.html.find("table") or NO_ENTRIES_MSG in res # XXX ... characterize better def assert_on_create_page(res): - assert_h1(res, 'Adicionar Country') + assert_h1(res, "Adicionar Country") form = res.form - assert not any( - form[k].value for k in form.fields if k != 'csrfmiddlewaretoken') + assert not any(form[k].value for k in form.fields if k != "csrfmiddlewaretoken") def assert_on_detail_page(res, stub_name): assert_h1(res, stub_name) assert not res.forms - assert 'Editar' in res - assert 'Excluir' in res - + assert "Editar" in res + assert "Excluir" in res -@pytest.mark.parametrize("num_entries, page_size, ranges, page_list", [ - (0, 6, [], []), - (5, 5, [(0, 5)], []), - (10, 5, [(0, 5), (5, 10)], ['Anterior', '1', '2', 'Próxima']), - (9, 4, [(0, 4), (4, 8), (8, 9)], ['Anterior', '1', '2', '3', 'Próxima']), -]) -def test_flux_list_paginate_detail( - app, num_entries, page_size, ranges, page_list): +@pytest.mark.parametrize( + "num_entries, page_size, ranges, page_list", + [ + (0, 6, [], []), + (5, 5, [(0, 5)], []), + (10, 5, [(0, 5), (5, 10)], ["Anterior", "1", "2", "Próxima"]), + (9, 4, [(0, 4), (4, 8), (8, 9)], ["Anterior", "1", "2", "3", "Próxima"]), + ], +) +def test_flux_list_paginate_detail(app, num_entries, page_size, ranges, page_list): entries_labels = [] for i in range(num_entries): - name, continent = 'name %s' % i, 'continent %s' % i + name, continent = "name %s" % i, "continent %s" % i population, is_cold = i, i % 2 == 0 - entries_labels.append([ - name, continent, str(population), 'Yes' if is_cold else 'No']) - baker.make(Country, - name=name, - continent__name=continent, - population=population, - is_cold=is_cold) + entries_labels.append( + [name, continent, str(population), "Yes" if is_cold else "No"] + ) + baker.make( + Country, + name=name, + continent__name=continent, + population=population, + is_cold=is_cold, + ) CountryCrud.ListView.paginate_by = page_size - res = app.get('/country/') + res = app.get("/country/") if num_entries == 0: assert_on_list_page(res) assert NO_ENTRIES_MSG in res # no table - assert not res.html.find('table') + assert not res.html.find("table") # no pagination - assert not res.html.find('ul', {'class': 'pagination'}) + assert not res.html.find("ul", {"class": "pagination"}) else: + def assert_at_page(res, i): assert_on_list_page(res) - table = res.html.find('table') + table = res.html.find("table") assert table - header_trs = table.findAll('tr') + header_trs = table.findAll("tr") header, trs = header_trs[0], header_trs[1:] - assert [c.text for c in header.findChildren('th')] == [ - 'name', 'continent', 'population', 'is cold'] - rows = [[td.text.strip() for td in tr.findAll('td')] - for tr in trs] + assert [c.text for c in header.findChildren("th")] == [ + "name", + "continent", + "population", + "is cold", + ] + rows = [[td.text.strip() for td in tr.findAll("td")] for tr in trs] start, end = ranges[i - 1] assert entries_labels[start:end] == rows - paginator = res.html.find('ul', {'class': 'pagination'}) + paginator = res.html.find("ul", {"class": "pagination"}) if page_list: assert paginator assert paginator.text.strip().split() == page_list assert_at_page(res, 1) - res_detail = res.click('name 1') - assert_on_detail_page(res_detail, 'name 1') + res_detail = res.click("name 1") + assert_on_detail_page(res_detail, "name 1") if len(ranges) > 1: - res = res.click('2', href='page=2') + res = res.click("2", href="page=2") assert_at_page(res, 2) - fist_entry_on_2nd_page = 'name %s' % page_size + fist_entry_on_2nd_page = "name %s" % page_size res_detail = res.click(fist_entry_on_2nd_page) assert_on_detail_page(res_detail, fist_entry_on_2nd_page) - res = res.click('1', href='page=1') + res = res.click("1", href="page=1") assert_at_page(res, 1) - res_detail = res.click('name 1') - assert_on_detail_page(res_detail, 'name 1') + res_detail = res.click("name 1") + assert_on_detail_page(res_detail, "name 1") -@pytest.mark.parametrize("cancel, make_invalid_submit", [ - (a, b) for a in (True, False) for b in (True, False)]) +@pytest.mark.parametrize( + "cancel, make_invalid_submit", + [(a, b) for a in (True, False) for b in (True, False)], +) def test_flux_list_create_detail(app, cancel, make_invalid_submit): - # to have a couple an option for continent field stub_continent = baker.make(Continent) - res = app.get('/country/') + res = app.get("/country/") # on list page assert_on_list_page(res) - res = res.click('Adicionar Country') + res = res.click("Adicionar Country") previous_objects = set(Country.objects.all()) # on create page @@ -265,7 +297,7 @@ def test_flux_list_create_detail(app, cancel, make_invalid_submit): # test bifurcation ! if cancel: - res = res.click('Cancelar') + res = res.click("Cancelar") # back to list page assert_on_list_page(res) # db has not changed @@ -275,35 +307,35 @@ def test_flux_list_create_detail(app, cancel, make_invalid_submit): if make_invalid_submit: # some fields are required => validation error res = res.form.submit() - 'Formulário inválido. O registro não foi criado.' in res + "Formulário inválido. O registro não foi criado." in res assert_on_create_page(res) # db has not changed assert previous_objects == set(Country.objects.all()) # now fill out some fields form = res.form - stub_name = '### name ###' - form['name'] = stub_name - form['continent'] = stub_continent.id - form['population'] = 23000 - form['is_cold'] = True + stub_name = "### name ###" + form["name"] = stub_name + form["continent"] = stub_continent.id + form["population"] = 23000 + form["is_cold"] = True res = form.submit() # on redirect to detail page created = Country.objects.get(name=stub_name) - assert res.url.endswith('/country/%s' % created.id) + assert res.url.endswith("/country/%s" % created.id) res = res.follow() # on detail page assert_on_detail_page(res, stub_name) - assert 'Registro criado com sucesso!' in res + assert "Registro criado com sucesso!" in res [new_obj] = list(set(Country.objects.all()) - previous_objects) assert new_obj.name == stub_name def get_detail_page(app): - stub = baker.make(Country, name='Country Stub') - res = app.get('/country/%s' % stub.id) + stub = baker.make(Country, name="Country Stub") + res = app.get("/country/%s" % stub.id) # on detail page assert_on_detail_page(res, stub.name) return stub, res @@ -312,46 +344,46 @@ def get_detail_page(app): @pytest.mark.parametrize("cancel", [True, False]) def test_flux_detail_update_detail(app, cancel): stub, res = get_detail_page(app) - res = res.click('Editar') + res = res.click("Editar") # on update page assert_h1(res, stub.name) # test bifurcation ! if cancel: - res = res.click('Cancelar') + res = res.click("Cancelar") # back to detail page assert_on_detail_page(res, stub.name) assert Country.objects.get(pk=stub.pk).name == stub.name else: form = res.form - new_name = '### New Name ###' - form['name'] = new_name + new_name = "### New Name ###" + form["name"] = new_name res = form.submit() # on redirect to detail page - assert res.url.endswith('/country/%s' % stub.id) + assert res.url.endswith("/country/%s" % stub.id) res = res.follow() # back to detail page assert_on_detail_page(res, new_name) - assert 'Registro alterado com sucesso!' in res + assert "Registro alterado com sucesso!" in res assert Country.objects.get(pk=stub.pk).name == new_name @pytest.mark.parametrize("cancel", [True, False]) def test_flux_detail_delete_list(app, cancel): stub, res = get_detail_page(app) - res = res.click('Excluir') + res = res.click("Excluir") # on delete page - assert 'Confirma exclusão de' in res + assert "Confirma exclusão de" in res assert stub.name in res # test bifurcation ! if cancel: - res = res.click('Cancelar') + res = res.click("Cancelar") # back to detail page assert_on_detail_page(res, stub.name) @@ -360,10 +392,10 @@ def test_flux_detail_delete_list(app, cancel): res = res.form.submit() # on redirect to list page - assert res.url.endswith('/country/') + assert res.url.endswith("/country/") res = res.follow() # on list page - assert 'Registro excluído com sucesso!' in res - assert_h1(res, 'Countries') + assert "Registro excluído com sucesso!" in res + assert_h1(res, "Countries") assert not Country.objects.filter(pk=stub.pk) diff --git a/sapl/crud/tests/test_masterdetail.py b/sapl/crud/tests/test_masterdetail.py index 781faea23..7b1e30bc7 100644 --- a/sapl/crud/tests/test_masterdetail.py +++ b/sapl/crud/tests/test_masterdetail.py @@ -2,13 +2,16 @@ import pytest from django.urls import reverse -@pytest.mark.parametrize('path_name', [ - '/country/1/city stub_app:city_list', - '/country/1/city/create stub_app:city_create', - '/country/city/1 stub_app:city_detail', - '/country/city/1/edit stub_app:city_update', - '/country/city/1/delete stub_app:city_delete', -]) +@pytest.mark.parametrize( + "path_name", + [ + "/country/1/city stub_app:city_list", + "/country/1/city/create stub_app:city_create", + "/country/city/1 stub_app:city_detail", + "/country/city/1/edit stub_app:city_update", + "/country/city/1/delete stub_app:city_delete", + ], +) def test_reverse(path_name): path, name = path_name.split() assert path == reverse(name, args=(1,)) diff --git a/sapl/crud/urls.py b/sapl/crud/urls.py index 2154488b6..f16d2b047 100644 --- a/sapl/crud/urls.py +++ b/sapl/crud/urls.py @@ -1,5 +1,5 @@ from django.urls import include, path urlpatterns = [ - path('', include('stub_app.urls')), + path("", include("stub_app.urls")), ] diff --git a/sapl/decorators.py b/sapl/decorators.py index 7f7ca14e6..68e9db518 100644 --- a/sapl/decorators.py +++ b/sapl/decorators.py @@ -18,26 +18,21 @@ def vigencia_atual(decorated_method): def display_atual(self): string_displayed = decorated_method(self) - if hasattr(self, 'data_inicio') and hasattr(self, 'data_fim'): + if hasattr(self, "data_inicio") and hasattr(self, "data_fim"): today = timezone.now().today().date() e_atual = self.data_inicio <= today <= self.data_fim string_displayed = "{} {}".format( - string_displayed, "(Atual)" if e_atual else "") + string_displayed, "(Atual)" if e_atual else "" + ) else: instancia_sem_atributo = "{} [{}, {}].".format( - 'Instância não possui os atributos', - 'data_inicio', - 'data_fim') + "Instância não possui os atributos", "data_inicio", "data_fim" + ) mensagem_decorator = "Decorator @{} foi desabilitado.".format( vigencia_atual.__name__() ) - print(_('{} {}'.format( - _(instancia_sem_atributo), - _(mensagem_decorator) - ) - ) - ) + print(_("{} {}".format(_(instancia_sem_atributo), _(mensagem_decorator)))) return string_displayed @@ -59,13 +54,13 @@ def receiver_multi_senders(signal, **kwargs): """ def _decorator(func): - senders = kwargs.get('senders', []) + senders = kwargs.get("senders", []) if isinstance(signal, (list, tuple)): if not senders: for s in signal: s.connect(func, **kwargs) else: - senders = kwargs.pop('senders') + senders = kwargs.pop("senders") for sender in senders: for s in signal: s.connect(func, sender=sender, **kwargs) @@ -74,7 +69,7 @@ def receiver_multi_senders(signal, **kwargs): if not senders: signal.connect(func, **kwargs) else: - senders = kwargs.pop('senders') + senders = kwargs.pop("senders") for sender in senders: signal.connect(func, sender=sender, **kwargs) diff --git a/sapl/endpoint_restriction_middleware.py b/sapl/endpoint_restriction_middleware.py index b815b4a2e..9b0d45167 100644 --- a/sapl/endpoint_restriction_middleware.py +++ b/sapl/endpoint_restriction_middleware.py @@ -1,24 +1,25 @@ -from django.http import HttpResponseForbidden import logging +from django.http import HttpResponseForbidden + # lista de IPs permitidos (localhost, redes locais, etc) # https://en.wikipedia.org/wiki/Reserved_IP_addresses ALLOWED_IPS = [ - '127.0.0.1', - '::1', - '10.0.0.0/8', - '172.16.0.0/12', - '192.168.0.0/16', - 'fc00::/7', - '::1', - 'fe80::/10', - '192.0.2.0/24', - '2001:db8::/32', - '224.0.0.0/4', - 'ff00::/8' + "127.0.0.1", + "::1", + "10.0.0.0/8", + "172.16.0.0/12", + "192.168.0.0/16", + "fc00::/7", + "::1", + "fe80::/10", + "192.0.2.0/24", + "2001:db8::/32", + "224.0.0.0/4", + "ff00::/8", ] -RESTRICTED_ENDPOINTS = ['/metrics'] +RESTRICTED_ENDPOINTS = ["/metrics"] class EndpointRestrictionMiddleware: @@ -29,10 +30,10 @@ class EndpointRestrictionMiddleware: def __call__(self, request): # IP do cliente - client_ip = request.META.get('REMOTE_ADDR') + client_ip = request.META.get("REMOTE_ADDR") # bloqueia acesso a endpoints restritos para IPs nao permitidos if request.path in RESTRICTED_ENDPOINTS and client_ip not in ALLOWED_IPS: - return HttpResponseForbidden('Acesso proibido') + return HttpResponseForbidden("Acesso proibido") return self.get_response(request) diff --git a/sapl/hashers.py b/sapl/hashers.py index 3e9cf6c5f..f78150450 100644 --- a/sapl/hashers.py +++ b/sapl/hashers.py @@ -6,7 +6,7 @@ from django.utils.encoding import force_bytes def to_base64(source): - return base64.b64encode(source).decode('utf-8') + return base64.b64encode(source).decode("utf-8") class ZopeSHA1PasswordHasher(PBKDF2PasswordHasher): @@ -40,14 +40,14 @@ def get_salt_from_zope_sha1(data): return to_base64(salt) -ZOPE_SHA1_PREFIX = '{SSHA}' +ZOPE_SHA1_PREFIX = "{SSHA}" def zope_encoded_password_to_django(encoded): "Migra um hash de senha do zope para uso com o ZopeSHA1PasswordHasher" if encoded and encoded.startswith(ZOPE_SHA1_PREFIX): - data = encoded[len(ZOPE_SHA1_PREFIX):] + data = encoded[len(ZOPE_SHA1_PREFIX) :] salt = get_salt_from_zope_sha1(data) hasher = ZopeSHA1PasswordHasher() return super(ZopeSHA1PasswordHasher, hasher).encode(data, salt) diff --git a/sapl/lexml/OAIServer.py b/sapl/lexml/OAIServer.py index e23db808e..92d0feb42 100644 --- a/sapl/lexml/OAIServer.py +++ b/sapl/lexml/OAIServer.py @@ -10,79 +10,92 @@ from django.utils import timezone from lxml import etree from lxml.builder import ElementMaker - from sapl.base.models import AppConfig, CasaLegislativa -from sapl.lexml.models import LexmlPublicador, LexmlProvedor +from sapl.lexml.models import LexmlProvedor, LexmlPublicador from sapl.norma.models import NormaJuridica from sapl.utils import LISTA_DE_UFS class OAILEXML: """ - Padrao OAI do LeXML - Esta registrado sobre o nome 'oai_lexml' + Padrao OAI do LeXML + Esta registrado sobre o nome 'oai_lexml' """ def __init__(self, prefix): self.prefix = prefix - self.ns = {'oai_lexml': 'http://www.lexml.gov.br/oai_lexml', } - self.schemas = {'oai_lexml': 'http://projeto.lexml.gov.br/esquemas/oai_lexml.xsd'} + self.ns = { + "oai_lexml": "http://www.lexml.gov.br/oai_lexml", + } + self.schemas = { + "oai_lexml": "http://projeto.lexml.gov.br/esquemas/oai_lexml.xsd" + } def __call__(self, element, metadata): data = metadata.record - if data.get('metadata'): - value = etree.XML(data['metadata']) + if data.get("metadata"): + value = etree.XML(data["metadata"]) element.append(value) class OAIServer: """ - An OAI-2.0 compliant oai server. - Underlying code is based on pyoai's oaipmh.server' + An OAI-2.0 compliant oai server. + Underlying code is based on pyoai's oaipmh.server' """ - XSI_NS = 'http://www.w3.org/2001/XMLSchema-instance' - ns = {'lexml': 'http://www.lexml.gov.br/oai_lexml'} - schema = {'oai_lexml': 'http://projeto.lexml.gov.br/esquemas/oai_lexml.xsd'} + XSI_NS = "http://www.w3.org/2001/XMLSchema-instance" + ns = {"lexml": "http://www.lexml.gov.br/oai_lexml"} + schema = {"oai_lexml": "http://projeto.lexml.gov.br/esquemas/oai_lexml.xsd"} def __init__(self, config={}): self.config = config def identify(self): result = oaipmh.common.Identify( - repositoryName=self.config['titulo'], - baseURL=self.config['base_url'], - protocolVersion='2.0', - adminEmails=self.config['email'], + repositoryName=self.config["titulo"], + baseURL=self.config["base_url"], + protocolVersion="2.0", + adminEmails=self.config["email"], earliestDatestamp=datetime(2001, 1, 1, 10, 00), - deletedRecord='transient', - granularity='YYYY-MM-DDThh:mm:ssZ', - compression=['identity'], - toolkit_description=False) - if self.config.get('descricao'): - result.add_description(self.config['descricao']) + deletedRecord="transient", + granularity="YYYY-MM-DDThh:mm:ssZ", + compression=["identity"], + toolkit_description=False, + ) + if self.config.get("descricao"): + result.add_description(self.config["descricao"]) return result def create_header_and_metadata(self, record): header = self.create_header(record) - metadata = oaipmh.common.Metadata(None, record['metadata']) + metadata = oaipmh.common.Metadata(None, record["metadata"]) metadata.record = record return header, metadata - def list_query(self, from_=None, until=None, offset=0, batch_size=10, identifier=None): + def list_query( + self, from_=None, until=None, offset=0, batch_size=10, identifier=None + ): if identifier: - identifier = int(identifier.split('/')[-1]) # Get internal id + identifier = int(identifier.split("/")[-1]) # Get internal id else: - identifier = '' + identifier = "" until = datetime.now() if not until or until > datetime.now() else until - return self.oai_query(offset=offset, batch_size=batch_size, from_=from_, until=until, - identifier=identifier) + return self.oai_query( + offset=offset, + batch_size=batch_size, + from_=from_, + until=until, + identifier=identifier, + ) def check_metadata_prefix(self, metadata_prefix): - if not metadata_prefix in self.config['metadata_prefixes']: + if not metadata_prefix in self.config["metadata_prefixes"]: raise oaipmh.error.CannotDisseminateFormatError - def listRecords(self, metadataPrefix, from_=None, until=None, cursor=0, batch_size=10): + def listRecords( + self, metadataPrefix, from_=None, until=None, cursor=0, batch_size=10 + ): self.check_metadata_prefix(metadataPrefix) for record in self.list_query(from_, until, cursor, batch_size): header, metadata = self.create_header_and_metadata(record) @@ -92,11 +105,15 @@ class OAIServer: return "oai:{}".format(internal_id) def create_header(self, record): - oai_id = self.get_oai_id(record['record']['id']) - timestamp = record['record']['when_modified'] if record['record']['when_modified'] else datetime.now() + oai_id = self.get_oai_id(record["record"]["id"]) + timestamp = ( + record["record"]["when_modified"] + if record["record"]["when_modified"] + else datetime.now() + ) timestamp = timestamp.replace(tzinfo=None) sets = [] - deleted = record['record']['deleted'] + deleted = record["record"]["deleted"] return oaipmh.common.Header(None, oai_id, timestamp, sets, deleted) def get_esfera_federacao(self): @@ -104,129 +121,179 @@ class OAIServer: return appconfig.esfera_federacao def recupera_norma(self, offset, batch_size, from_, until, identifier, esfera): - kwargs = {'data__isnull': False, - 'esfera_federacao__isnull': False, - 'timestamp__isnull': False, - 'timestamp__lte': until} + kwargs = { + "data__isnull": False, + "esfera_federacao__isnull": False, + "timestamp__isnull": False, + "timestamp__lte": until, + } if from_: - kwargs['timestamp__gte'] = from_ + kwargs["timestamp__gte"] = from_ if identifier: - kwargs['numero'] = identifier + kwargs["numero"] = identifier if esfera: - kwargs['esfera_federacao'] = esfera - return NormaJuridica.objects.select_related('tipo').filter(**kwargs)[offset:offset + batch_size] + kwargs["esfera_federacao"] = esfera + return NormaJuridica.objects.select_related("tipo").filter(**kwargs)[ + offset : offset + batch_size + ] def monta_id(self, norma): if norma: - num = len(casa.endereco_web.split('.')) - dominio = '.'.join(casa.endereco_web.split('.')[1:num]) - prefixo_oai = '{}.{}:sapl/'.format(casa.sigla.lower(), dominio) + num = len(casa.endereco_web.split(".")) + dominio = ".".join(casa.endereco_web.split(".")[1:num]) + prefixo_oai = "{}.{}:sapl/".format(casa.sigla.lower(), dominio) numero_interno = norma.numero tipo_norma = norma.tipo.equivalente_lexml ano_norma = norma.ano - identificador = '{}{};{};{}'.format(prefixo_oai, tipo_norma, ano_norma, numero_interno) + identificador = "{}{};{};{}".format( + prefixo_oai, tipo_norma, ano_norma, numero_interno + ) return identificador else: return None @staticmethod def remove_acentos(linha): - res = unicodedata.normalize('NFKD', linha).encode('ASCII', 'ignore') + res = unicodedata.normalize("NFKD", linha).encode("ASCII", "ignore") res = res.decode("UTF-8") - remove_list = ["\'", "\"", "-"] + remove_list = ["'", '"', "-"] for i in remove_list: res = res.replace(i, "") return res def monta_urn(self, norma, esfera): if norma: - urn = 'urn:lex:br;' - esferas = {'M': 'municipal', 'E': 'estadual'} + urn = "urn:lex:br;" + esferas = {"M": "municipal", "E": "estadual"} municipio = self.remove_acentos(casa.municipio.lower()) uf_map = dict(LISTA_DE_UFS) - uf_desc = uf_map.get(casa.uf.upper(), '').lower() + uf_desc = uf_map.get(casa.uf.upper(), "").lower() uf_desc = self.remove_acentos(uf_desc) - for x in [' ', '.de.', '.da.', '.das.', '.do.', '.dos.']: - municipio = municipio.replace(x, '.') - uf_desc = uf_desc.replace(x, '.') - if esfera == 'M': - urn += '{};{}:'.format(uf_desc, municipio) - if norma.tipo.equivalente_lexml == 'regimento.interno' or norma.tipo.equivalente_lexml == 'resolucao': - urn += 'camara.' - urn += esferas[esfera] + ':' - elif esfera == 'E': - urn += '{}:{}:'.format(uf_desc, esferas[esfera]) + for x in [" ", ".de.", ".da.", ".das.", ".do.", ".dos."]: + municipio = municipio.replace(x, ".") + uf_desc = uf_desc.replace(x, ".") + if esfera == "M": + urn += "{};{}:".format(uf_desc, municipio) + if ( + norma.tipo.equivalente_lexml == "regimento.interno" + or norma.tipo.equivalente_lexml == "resolucao" + ): + urn += "camara." + urn += esferas[esfera] + ":" + elif esfera == "E": + urn += "{}:{}:".format(uf_desc, esferas[esfera]) else: - urn += ':' + urn += ":" if norma.tipo.equivalente_lexml: - urn += '{}:{};'.format(norma.tipo.equivalente_lexml, norma.data.isoformat()) + urn += "{}:{};".format( + norma.tipo.equivalente_lexml, norma.data.isoformat() + ) else: - urn += '{};'.format(norma.data.isoformat()) - if norma.tipo.equivalente_lexml == 'lei.organica' or norma.tipo.equivalente_lexml == 'constituicao': + urn += "{};".format(norma.data.isoformat()) + if ( + norma.tipo.equivalente_lexml == "lei.organica" + or norma.tipo.equivalente_lexml == "constituicao" + ): urn += str(norma.ano) else: urn += str(norma.numero) if norma.data_vigencia and norma.data_publicacao: - urn += '@{};publicacao;{}'.format(norma.data_vigencia.isoformat(), norma.data_publicacao.isoformat()) + urn += "@{};publicacao;{}".format( + norma.data_vigencia.isoformat(), norma.data_publicacao.isoformat() + ) elif norma.data_publicacao: - urn += '@inicio.vigencia;publicacao;{}'.format(norma.data_publicacao.isoformat()) + urn += "@inicio.vigencia;publicacao;{}".format( + norma.data_publicacao.isoformat() + ) return urn else: return None def data_por_extenso(self, data): - data = data.strftime('%d-%m-%Y') - if data != '': - meses = {1: 'Janeiro', 2: 'Fevereiro', 3: 'Março', 4: 'Abril', 5: 'Maio', 6: 'Junho', 7: 'Julho', - 8: 'Agosto', 9: 'Setembro', 10: 'Outubro', 11: 'Novembro', 12: 'Dezembro'} - return '{} de {} de {}'.format(data[0:2], meses[int(data[3:5])], data[6:]) + data = data.strftime("%d-%m-%Y") + if data != "": + meses = { + 1: "Janeiro", + 2: "Fevereiro", + 3: "Março", + 4: "Abril", + 5: "Maio", + 6: "Junho", + 7: "Julho", + 8: "Agosto", + 9: "Setembro", + 10: "Outubro", + 11: "Novembro", + 12: "Dezembro", + } + return "{} de {} de {}".format(data[0:2], meses[int(data[3:5])], data[6:]) else: - return '' + return "" def monta_xml(self, urn, norma): - BASE_URL_SAPL = self.config['base_url'] - BASE_URL_SAPL = BASE_URL_SAPL[:BASE_URL_SAPL.find('/', 8)] + BASE_URL_SAPL = self.config["base_url"] + BASE_URL_SAPL = BASE_URL_SAPL[: BASE_URL_SAPL.find("/", 8)] publicador = LexmlPublicador.objects.first() if norma and publicador: - LEXML = ElementMaker(namespace=self.ns['lexml'], nsmap=self.ns) + LEXML = ElementMaker(namespace=self.ns["lexml"], nsmap=self.ns) oai_lexml = LEXML.LexML() - oai_lexml.attrib['{{{pre}}}schemaLocation'.format(pre=self.XSI_NS)] = '{} {}'.format( - 'http://www.lexml.gov.br/oai_lexml', 'http://projeto.lexml.gov.br/esquemas/oai_lexml.xsd') + oai_lexml.attrib[ + "{{{pre}}}schemaLocation".format(pre=self.XSI_NS) + ] = "{} {}".format( + "http://www.lexml.gov.br/oai_lexml", + "http://projeto.lexml.gov.br/esquemas/oai_lexml.xsd", + ) texto_integral = norma.texto_integral - mime_types = {'doc': 'application/msword', - 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'odt': 'application/vnd.oasis.opendocument.text', - 'pdf': 'application/pdf', - 'rtf': 'application/rtf'} + mime_types = { + "doc": "application/msword", + "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "odt": "application/vnd.oasis.opendocument.text", + "pdf": "application/pdf", + "rtf": "application/rtf", + } if texto_integral: url_conteudo = BASE_URL_SAPL + texto_integral.url - extensao = texto_integral.url.split('.')[-1] - formato = mime_types.get(extensao, 'application/octet-stream') + extensao = texto_integral.url.split(".")[-1] + formato = mime_types.get(extensao, "application/octet-stream") else: - formato = 'text/html' - url_conteudo = BASE_URL_SAPL + reverse('sapl.norma:normajuridica_detail', - kwargs={'pk': norma.pk}) + formato = "text/html" + url_conteudo = BASE_URL_SAPL + reverse( + "sapl.norma:normajuridica_detail", kwargs={"pk": norma.pk} + ) element_maker = ElementMaker() id_publicador = str(publicador.id_publicador) - item_conteudo = element_maker.Item(url_conteudo, formato=formato, idPublicador=id_publicador, - tipo='conteudo') + item_conteudo = element_maker.Item( + url_conteudo, + formato=formato, + idPublicador=id_publicador, + tipo="conteudo", + ) oai_lexml.append(item_conteudo) - url = BASE_URL_SAPL + reverse('sapl.norma:normajuridica_detail', kwargs={'pk': norma.pk}) - item_metadado = element_maker.Item(url, formato='text/html', idPublicador=id_publicador, tipo='metadado') + url = BASE_URL_SAPL + reverse( + "sapl.norma:normajuridica_detail", kwargs={"pk": norma.pk} + ) + item_metadado = element_maker.Item( + url, formato="text/html", idPublicador=id_publicador, tipo="metadado" + ) oai_lexml.append(item_metadado) documento_individual = element_maker.DocumentoIndividual(urn) oai_lexml.append(documento_individual) - if norma.tipo.equivalente_lexml == 'lei.organica': - epigrafe = '{} de {} - {}, de {}'.format(norma.tipo.descricao, casa.municipio, - casa.uf, norma.ano) - elif norma.tipo.equivalente_lexml == 'constituicao': - epigrafe = '{} do Estado de {}, de {}'.format(norma.tipo.descricao, casa.municipio, - norma.ano) + if norma.tipo.equivalente_lexml == "lei.organica": + epigrafe = "{} de {} - {}, de {}".format( + norma.tipo.descricao, casa.municipio, casa.uf, norma.ano + ) + elif norma.tipo.equivalente_lexml == "constituicao": + epigrafe = "{} do Estado de {}, de {}".format( + norma.tipo.descricao, casa.municipio, norma.ano + ) else: - epigrafe = '{} n° {}, de {}'.format(norma.tipo.descricao, norma.numero, - self.data_por_extenso(norma.data)) + epigrafe = "{} n° {}, de {}".format( + norma.tipo.descricao, + norma.numero, + self.data_por_extenso(norma.data), + ) oai_lexml.append(element_maker.Epigrafe(epigrafe)) oai_lexml.append(element_maker.Ementa(norma.ementa)) indexacao = norma.indexacao @@ -236,48 +303,50 @@ class OAIServer: else: return None - def oai_query(self, offset=0, batch_size=10, from_=None, until=None, identifier=None): + def oai_query( + self, offset=0, batch_size=10, from_=None, until=None, identifier=None + ): if from_: - from_ = timezone.make_aware(from_) # convert from naive to timezone aware datetime + from_ = timezone.make_aware( + from_ + ) # convert from naive to timezone aware datetime esfera = self.get_esfera_federacao() offset = 0 if offset < 0 else offset batch_size = 10 if batch_size < 0 else batch_size - until = timezone.make_aware(until) \ - if until and timezone.make_aware(until) < timezone.now() \ + until = ( + timezone.make_aware(until) + if until and timezone.make_aware(until) < timezone.now() else timezone.now() + ) - normas = self.recupera_norma(offset, - batch_size, - from_, - until, - identifier, - esfera) + normas = self.recupera_norma( + offset, batch_size, from_, until, identifier, esfera + ) for norma in normas: resultado = {} identificador = self.monta_id(norma) urn = self.monta_urn(norma, esfera) xml_lexml = self.monta_xml(urn, norma) - resultado['tx_metadado_xml'] = xml_lexml - resultado['cd_status'] = 'N' - resultado['id'] = identificador - resultado['when_modified'] = norma.timestamp - resultado['deleted'] = 0 - yield {'record': resultado, - 'metadata': resultado['tx_metadado_xml']} + resultado["tx_metadado_xml"] = xml_lexml + resultado["cd_status"] = "N" + resultado["id"] = identificador + resultado["when_modified"] = norma.timestamp + resultado["deleted"] = 0 + yield {"record": resultado, "metadata": resultado["tx_metadado_xml"]} def OAIServerFactory(config={}): """ - Create a new OAI batching OAI Server given a config and a database + Create a new OAI batching OAI Server given a config and a database """ - for prefix in config['metadata_prefixes']: + for prefix in config["metadata_prefixes"]: metadata_registry = oaipmh.metadata.MetadataRegistry() metadata_registry.registerWriter(prefix, OAILEXML(prefix)) return oaipmh.server.BatchingServer( OAIServer(config), metadata_registry=metadata_registry, - resumption_batch_size=config['batch_size'] + resumption_batch_size=config["batch_size"], ) @@ -292,40 +361,41 @@ def casa_legislativa(): def get_xml_provedor(): - """ antigo get_descricao_casa() """ - descricao = '' + """antigo get_descricao_casa()""" + descricao = "" provedor = LexmlProvedor.objects.first() if provedor: descricao = provedor.xml if descricao: - descricao = descricao.encode('utf-8') + descricao = descricao.encode("utf-8") return descricao def get_config(url, batch_size): - config = {'content_type': None, - 'delay': 0, - 'base_asset_path': None, - 'metadata_prefixes': ['oai_lexml'], - 'titulo': casa_legislativa().nome, # Inicializa variável global casa - 'email': [casa.email], # lista de e-mails, antigo `def get_email()` - 'base_url': url[:url.find('/', 8)] + reverse('sapl.lexml:lexml_endpoint')[:-4], # remove '/oai' suffix - 'descricao': get_xml_provedor(), - 'batch_size': batch_size - } + config = { + "content_type": None, + "delay": 0, + "base_asset_path": None, + "metadata_prefixes": ["oai_lexml"], + "titulo": casa_legislativa().nome, # Inicializa variável global casa + "email": [casa.email], # lista de e-mails, antigo `def get_email()` + "base_url": url[: url.find("/", 8)] + + reverse("sapl.lexml:lexml_endpoint")[:-4], # remove '/oai' suffix + "descricao": get_xml_provedor(), + "batch_size": batch_size, + } return config -if __name__ == '__main__': +if __name__ == "__main__": """ - Para executar localmente (estando no diretório raiz): - - $ ./manage.py shell_plus - - Executar comando - %run sapl/lexml/OAIServer.py + Para executar localmente (estando no diretório raiz): + + $ ./manage.py shell_plus + + Executar comando + %run sapl/lexml/OAIServer.py """ - oai_server = OAIServerFactory(get_config('http://127.0.0.1:8000/', 10)) - r = oai_server.handleRequest({'verb': 'ListRecords', - 'metadataPrefix': 'oai_lexml'}) - print(r.decode('UTF-8')) + oai_server = OAIServerFactory(get_config("http://127.0.0.1:8000/", 10)) + r = oai_server.handleRequest({"verb": "ListRecords", "metadataPrefix": "oai_lexml"}) + print(r.decode("UTF-8")) diff --git a/sapl/lexml/apps.py b/sapl/lexml/apps.py index 25982c489..026f64b02 100644 --- a/sapl/lexml/apps.py +++ b/sapl/lexml/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.lexml' - label = 'lexml' - verbose_name = _('LexML') + name = "sapl.lexml" + label = "lexml" + verbose_name = _("LexML") diff --git a/sapl/lexml/forms.py b/sapl/lexml/forms.py index fcec0d1ee..f2001d4a4 100644 --- a/sapl/lexml/forms.py +++ b/sapl/lexml/forms.py @@ -1,13 +1,14 @@ +import os +import re +import xml.dom.minidom as dom +from io import StringIO + from django.core.exceptions import ValidationError from django.forms import ModelForm -from sapl.settings import PROJECT_DIR from django.utils.translation import gettext_lazy as _ - -from io import StringIO from lxml import etree -import os -import re -import xml.dom.minidom as dom + +from sapl.settings import PROJECT_DIR from .models import LexmlProvedor @@ -21,7 +22,7 @@ class LexmlProvedorForm(ModelForm): "id_responsavel", "nome_responsavel", "email_responsavel", - "xml" + "xml", ] def clean(self): @@ -44,14 +45,17 @@ def validar_xml(xml): try: dom.parse(xml) except Exception as e: - raise ValidationError(_(F"XML mal formatado. Error: {e}")) + raise ValidationError(_(f"XML mal formatado. Error: {e}")) + def validar_schema(xml): - xml_schema = open(os.path.join(PROJECT_DIR, 'sapl/templates/lexml/schema.xsd'), 'rb').read() + xml_schema = open( + os.path.join(PROJECT_DIR, "sapl/templates/lexml/schema.xsd"), "rb" + ).read() schema_root = etree.XML(xml_schema) schema = etree.XMLSchema(schema_root) parser = etree.XMLParser(schema=schema) try: root = etree.fromstring(xml.encode(), parser) except Exception as e: - raise ValidationError(_(F"XML mal formatado. Error: {e}")) + raise ValidationError(_(f"XML mal formatado. Error: {e}")) diff --git a/sapl/lexml/models.py b/sapl/lexml/models.py index 1abc67b3a..935572ac4 100644 --- a/sapl/lexml/models.py +++ b/sapl/lexml/models.py @@ -3,64 +3,58 @@ from django.utils.translation import gettext_lazy as _ 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')) + id_provedor = models.PositiveIntegerField(verbose_name=_("Id do provedor")) + nome = models.CharField(max_length=255, verbose_name=_("Nome do provedor")) sigla = models.CharField(max_length=15) email_responsavel = models.EmailField( - max_length=50, - blank=True, - verbose_name=_('E-mail do responsável')) + max_length=50, blank=True, verbose_name=_("E-mail do responsável") + ) nome_responsavel = models.CharField( - max_length=255, - blank=True, - verbose_name=_('Nome do responsável')) + max_length=255, blank=True, verbose_name=_("Nome do responsável") + ) tipo = models.CharField(max_length=50) id_responsavel = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Id do responsável')) + blank=True, null=True, verbose_name=_("Id do responsável") + ) xml = models.TextField( - blank=True, - verbose_name=_('XML fornecido pela equipe do LexML:')) + blank=True, verbose_name=_("XML fornecido pela equipe do LexML:") + ) @property def pretty_xml(self): import html + safe_xml = html.escape(self.xml) - return safe_xml.replace('\\n', '
        ').replace(' ', ' ') + return safe_xml.replace("\\n", "
        ").replace(" ", " ") class Meta: - verbose_name = _('Provedor Lexml') - verbose_name_plural = _('Provedores Lexml') - ordering = ('id',) + verbose_name = _("Provedor Lexml") + verbose_name_plural = _("Provedores Lexml") + ordering = ("id",) def __str__(self): return self.nome class LexmlPublicador(models.Model): - id_publicador = models.PositiveIntegerField( - verbose_name=_('Id do publicador')) - nome = models.CharField( - max_length=255, verbose_name=_('Nome do publicador')) + id_publicador = models.PositiveIntegerField(verbose_name=_("Id do publicador")) + nome = models.CharField(max_length=255, verbose_name=_("Nome do publicador")) email_responsavel = models.EmailField( - max_length=50, - blank=True, - verbose_name=_('E-mail do responsável')) + max_length=50, blank=True, verbose_name=_("E-mail do responsável") + ) sigla = models.CharField( - max_length=255, - blank=True, - verbose_name=_('Sigla do Publicador')) + max_length=255, blank=True, verbose_name=_("Sigla do Publicador") + ) nome_responsavel = models.CharField( - max_length=255, - blank=True, - verbose_name=_('Nome do responsável')) + max_length=255, blank=True, verbose_name=_("Nome do responsável") + ) tipo = models.CharField(max_length=50) - id_responsavel = models.PositiveIntegerField( - verbose_name=_('Id do responsável')) + id_responsavel = models.PositiveIntegerField(verbose_name=_("Id do responsável")) class Meta: - verbose_name = _('Publicador Lexml') - verbose_name_plural = _('Publicadores Lexml') - ordering = ('id',) + verbose_name = _("Publicador Lexml") + verbose_name_plural = _("Publicadores Lexml") + ordering = ("id",) def __str__(self): return self.nome diff --git a/sapl/lexml/urls.py b/sapl/lexml/urls.py index f5954ad85..4001ad7fb 100644 --- a/sapl/lexml/urls.py +++ b/sapl/lexml/urls.py @@ -1,17 +1,19 @@ from django.urls import include, path, re_path -from sapl.lexml.views import LexmlProvedorCrud, LexmlPublicadorCrud, lexml_request, request_search +from sapl.lexml.views import (LexmlProvedorCrud, LexmlPublicadorCrud, + lexml_request, request_search) from .apps import AppConfig app_name = AppConfig.name urlpatterns = [ - path('sistema/lexml/provedor/', - include(LexmlProvedorCrud.get_urls())), - path('sistema/lexml/publicador/', - include(LexmlPublicadorCrud.get_urls())), - re_path(r'^sistema/lexml/request_search/(?P[\w\-]+)/', request_search, name='lexml_search'), - re_path(r'^sistema/lexml/oai', lexml_request, name='lexml_endpoint'), - + path("sistema/lexml/provedor/", include(LexmlProvedorCrud.get_urls())), + path("sistema/lexml/publicador/", include(LexmlPublicadorCrud.get_urls())), + re_path( + r"^sistema/lexml/request_search/(?P[\w\-]+)/", + request_search, + name="lexml_search", + ), + re_path(r"^sistema/lexml/oai", lexml_request, name="lexml_endpoint"), ] diff --git a/sapl/lexml/views.py b/sapl/lexml/views.py index e9b53a177..d0bab9255 100644 --- a/sapl/lexml/views.py +++ b/sapl/lexml/views.py @@ -1,20 +1,19 @@ from django.http import HttpResponse from django.shortcuts import render -from sapl.crud.base import CrudAux, Crud +from sapl.crud.base import Crud, CrudAux from sapl.lexml.OAIServer import OAIServerFactory, get_config from sapl.rules import RP_DETAIL, RP_LIST -from .models import LexmlProvedor, LexmlPublicador - from .forms import LexmlProvedorForm +from .models import LexmlProvedor, LexmlPublicador -LexmlPublicadorCrud = CrudAux.build(LexmlPublicador, 'lexml_publicador') +LexmlPublicadorCrud = CrudAux.build(LexmlPublicador, "lexml_publicador") class LexmlProvedorCrud(Crud): model = LexmlProvedor - help_topic = 'lexml_provedor' + help_topic = "lexml_provedor" public = [RP_LIST, RP_DETAIL] class CreateView(Crud.CreateView): @@ -24,19 +23,19 @@ class LexmlProvedorCrud(Crud): form_class = LexmlProvedorForm class DetailView(Crud.DetailView): - layout_key = 'LexmlProvedorDetail' + layout_key = "LexmlProvedorDetail" def lexml_request(request): request_dict = request.GET.copy() - if request_dict.get('batch_size'): - del request_dict['batch_size'] + if request_dict.get("batch_size"): + del request_dict["batch_size"] - config = get_config(request.get_raw_uri(), int(request.GET.get('batch_size', '10'))) + config = get_config(request.get_raw_uri(), int(request.GET.get("batch_size", "10"))) oai_server = OAIServerFactory(config) r = oai_server.handleRequest(request_dict) - response = r.decode('UTF-8') - return HttpResponse(response, content_type='text/xml') + response = r.decode("UTF-8") + return HttpResponse(response, content_type="text/xml") def request_search(request, keyword): diff --git a/sapl/materia/admin.py b/sapl/materia/admin.py index 6fb649296..20c03de69 100644 --- a/sapl/materia/admin.py +++ b/sapl/materia/admin.py @@ -13,7 +13,6 @@ register_all_models_in_admin(__name__) if not settings.DEBUG: class RestricaoAdmin(admin.ModelAdmin): - def has_add_permission(self, request, obj=None): return False @@ -29,7 +28,7 @@ if not settings.DEBUG: TipoComissao, TipoAfastamento, SituacaoMilitar, - TipoDependente + TipoDependente, ) for model in models: diff --git a/sapl/materia/apps.py b/sapl/materia/apps.py index a8ee2425d..7ecd86867 100644 --- a/sapl/materia/apps.py +++ b/sapl/materia/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.materia' - label = 'materia' - verbose_name = _('Matéria') + name = "sapl.materia" + label = "materia" + verbose_name = _("Matéria") diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index 0ad391a71..f0eb48f5d 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1,8 +1,9 @@ import logging import os +import django_filters from crispy_forms.bootstrap import Alert, InlineRadios -from crispy_forms.layout import (Button, Field, Fieldset, HTML, Layout, Row, Div) +from crispy_forms.layout import HTML, Button, Div, Field, Fieldset, Layout, Row from django import forms from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist, ValidationError @@ -16,78 +17,70 @@ from django.forms.widgets import CheckboxSelectMultiple, HiddenInput, Select from django.urls import reverse from django.utils import timezone from django.utils.translation import gettext_lazy as _ -import django_filters -from sapl.base.models import AppConfig as BaseAppConfig, Autor, TipoAutor +from sapl.base.models import AppConfig as BaseAppConfig +from sapl.base.models import Autor, TipoAutor from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC, STATUS_TA_PRIVATE) -from sapl.crispy_layout_mixin import (form_actions, SaplFormHelper, - SaplFormLayout, to_column, to_row) -from sapl.materia.models import (AssuntoMateria, MateriaAssunto, - MateriaLegislativa, Orgao, - RegimeTramitacao, StatusTramitacao, - TipoDocumento, TipoProposicao, - ConfigEtiquetaMateriaLegislativa, HistoricoProposicao) +from sapl.crispy_layout_mixin import (SaplFormHelper, SaplFormLayout, + form_actions, to_column, to_row) +from sapl.materia.models import (AssuntoMateria, + ConfigEtiquetaMateriaLegislativa, + HistoricoProposicao, MateriaAssunto, + MateriaLegislativa, Orgao, RegimeTramitacao, + StatusTramitacao, TipoDocumento, + TipoProposicao) from sapl.norma.models import (LegislacaoCitada, NormaJuridica, TipoNormaJuridica) from sapl.parlamentares.models import Legislatura, Partido -from sapl.protocoloadm.models import (DocumentoAdministrativo, - Protocolo) -from sapl.utils import (autor_label, autor_modal, timing, - ChoiceWithoutValidationField, - choice_anos_com_materias, FileFieldCheckMixin, - FilterOverridesMetaMixin, gerar_hash_arquivo, - lista_anexados, MateriaPesquisaOrderingFilter, +from sapl.protocoloadm.models import DocumentoAdministrativo, Protocolo +from sapl.utils import (SEPARADOR_HASH_PROPOSICAO, YES_NO_CHOICES, + ChoiceWithoutValidationField, FileFieldCheckMixin, + FilterOverridesMetaMixin, GoogleRecapthaMixin, + MateriaPesquisaOrderingFilter, autor_label, + autor_modal, choice_anos_com_materias, + gerar_hash_arquivo, get_client_ip, lista_anexados, models_with_gr_for_model, qs_override_django_filter, - SEPARADOR_HASH_PROPOSICAO, - validar_arquivo, YES_NO_CHOICES, - GoogleRecapthaMixin, get_client_ip) + timing, validar_arquivo) -from .models import (AcompanhamentoMateria, Anexada, Autoria, - DespachoInicial, DocumentoAcessorio, Numeracao, - Proposicao, Relatoria, TipoMateriaLegislativa, - Tramitacao, UnidadeTramitacao) +from .models import (AcompanhamentoMateria, Anexada, Autoria, DespachoInicial, + DocumentoAcessorio, Numeracao, Proposicao, Relatoria, + TipoMateriaLegislativa, Tramitacao, UnidadeTramitacao) def CHOICE_TRAMITACAO(): - return [('', 'Tanto Faz'), - (1, 'Sim'), - (0, 'Não')] + return [("", "Tanto Faz"), (1, "Sim"), (0, "Não")] def CHOICE_TIPO_LISTAGEM(): return [ - (1, _('Detalhada')), - (2, _('Simplificada')), + (1, _("Detalhada")), + (2, _("Simplificada")), ] class AdicionarVariasAutoriasFilterSet(django_filters.FilterSet): - class Meta: model = Autor - fields = ['nome'] + fields = ["nome"] def __init__(self, *args, **kwargs): super(AdicionarVariasAutoriasFilterSet, self).__init__(*args, **kwargs) - row1 = to_row([('nome', 12)]) + row1 = to_row([("nome", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Filtrar Autores'), - row1, form_actions(label='Filtrar')) + Fieldset(_("Filtrar Autores"), row1, form_actions(label="Filtrar")) ) class OrgaoForm(ModelForm): - class Meta: model = Orgao - fields = ['nome', 'sigla', 'unidade_deliberativa', - 'endereco', 'telefone'] + fields = ["nome", "sigla", "unidade_deliberativa", "endereco", "telefone"] @transaction.atomic def save(self, commit=True): @@ -95,101 +88,123 @@ class OrgaoForm(ModelForm): content_type = ContentType.objects.get_for_model(Orgao) object_id = orgao.pk tipo = TipoAutor.objects.get(content_type=content_type) - nome = orgao.nome + ' - ' + orgao.sigla + nome = orgao.nome + " - " + orgao.sigla Autor.objects.create( - content_type=content_type, - object_id=object_id, - tipo=tipo, - nome=nome + content_type=content_type, object_id=object_id, tipo=tipo, nome=nome ) return orgao class ReceberProposicaoForm(Form): - cod_hash = forms.CharField(label='Código do Documento', required=True) + cod_hash = forms.CharField(label="Código do Documento", required=True) def __init__(self, *args, **kwargs): - row1 = to_row([('cod_hash', 12)]) + row1 = to_row([("cod_hash", 12)]) self.helper = SaplFormHelper() self.helper.layout = Layout( Fieldset( - _('Incorporar Proposição'), row1, - form_actions(label='Recuperar Proposição') + _("Incorporar Proposição"), + row1, + form_actions(label="Recuperar Proposição"), ) ) super(ReceberProposicaoForm, self).__init__(*args, **kwargs) class MateriaSimplificadaForm(FileFieldCheckMixin, ModelForm): - logger = logging.getLogger(__name__) class Meta: model = MateriaLegislativa - fields = ['tipo', 'numero', 'ano', 'data_apresentacao', - 'numero_protocolo', 'regime_tramitacao', - 'em_tramitacao', 'ementa', 'tipo_apresentacao', - 'texto_original'] + fields = [ + "tipo", + "numero", + "ano", + "data_apresentacao", + "numero_protocolo", + "regime_tramitacao", + "em_tramitacao", + "ementa", + "tipo_apresentacao", + "texto_original", + ] widgets = { - 'numero_protocolo': forms.TextInput(attrs={'readonly': True}), + "numero_protocolo": forms.TextInput(attrs={"readonly": True}), } def __init__(self, *args, **kwargs): - - row1 = to_row([('tipo', 6), ('numero', 3), ('ano', 3)]) - row2 = to_row([('data_apresentacao', 6), ('numero_protocolo', 6)]) - row3 = to_row([('regime_tramitacao', 6), - ('em_tramitacao', 3), ('tipo_apresentacao', 3)]) - row4 = to_row([('ementa', 12)]) - row5 = to_row([('texto_original', 12)]) + row1 = to_row([("tipo", 6), ("numero", 3), ("ano", 3)]) + row2 = to_row([("data_apresentacao", 6), ("numero_protocolo", 6)]) + row3 = to_row( + [("regime_tramitacao", 6), ("em_tramitacao", 3), ("tipo_apresentacao", 3)] + ) + row4 = to_row([("ementa", 12)]) + row5 = to_row([("texto_original", 12)]) self.helper = SaplFormHelper() self.helper.layout = Layout( Fieldset( - _('Formulário Simplificado'), - row1, row2, row3, row4, row5, - form_actions(label='Salvar') + _("Formulário Simplificado"), + row1, + row2, + row3, + row4, + row5, + form_actions(label="Salvar"), ) ) super(MateriaSimplificadaForm, self).__init__(*args, **kwargs) class MateriaLegislativaForm(FileFieldCheckMixin, ModelForm): - logger = logging.getLogger(__name__) - tipo_autor = ModelChoiceField(label=_('Tipo Autor'), - required=False, - queryset=TipoAutor.objects.all(), - empty_label=_('------'), ) + tipo_autor = ModelChoiceField( + label=_("Tipo Autor"), + required=False, + queryset=TipoAutor.objects.all(), + empty_label=_("------"), + ) - autor = forms.ModelChoiceField(required=False, - empty_label='------', - queryset=Autor.objects.all() - ) + autor = forms.ModelChoiceField( + required=False, empty_label="------", queryset=Autor.objects.all() + ) class Meta: model = MateriaLegislativa - exclude = ['texto_articulado', 'autores', 'proposicao', - 'anexadas', 'data_ultima_atualizacao'] + exclude = [ + "texto_articulado", + "autores", + "proposicao", + "anexadas", + "data_ultima_atualizacao", + ] widgets = { - 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput() + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), } def __init__(self, *args, **kwargs): super(MateriaLegislativaForm, self).__init__(*args, **kwargs) - self.fields['ementa'].widget.attrs['maxlength'] = 1000 + self.fields["ementa"].widget.attrs["maxlength"] = 1000 if self.instance and self.instance.pk: - self.fields['tipo_autor'] = forms.CharField(required=False, - widget=forms.HiddenInput()) - self.fields['autor'] = forms.CharField(required=False, - widget=forms.HiddenInput()) - if kwargs['instance'].numero_protocolo and Protocolo.objects.filter(numero=kwargs['instance'].numero_protocolo, ano=kwargs['instance'].ano).exists(): - self.fields['numero_protocolo'].widget.attrs['readonly'] = True + self.fields["tipo_autor"] = forms.CharField( + required=False, widget=forms.HiddenInput() + ) + self.fields["autor"] = forms.CharField( + required=False, widget=forms.HiddenInput() + ) + if ( + kwargs["instance"].numero_protocolo + and Protocolo.objects.filter( + numero=kwargs["instance"].numero_protocolo, + ano=kwargs["instance"].ano, + ).exists() + ): + self.fields["numero_protocolo"].widget.attrs["readonly"] = True def clean(self): super(MateriaLegislativaForm, self).clean() @@ -199,55 +214,73 @@ class MateriaLegislativaForm(FileFieldCheckMixin, ModelForm): cleaned_data = self.cleaned_data - data_apresentacao = cleaned_data['data_apresentacao'] - ano = cleaned_data['ano'] - protocolo = cleaned_data['numero_protocolo'] + data_apresentacao = cleaned_data["data_apresentacao"] + ano = cleaned_data["ano"] + protocolo = cleaned_data["numero_protocolo"] protocolo_antigo = self.instance.numero_protocolo if protocolo: if not Protocolo.objects.filter(numero=protocolo, ano=ano).exists(): - self.logger.warning( - "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))) + _("Protocolo %s/%s não existe" % (protocolo, ano)) + ) if protocolo_antigo != protocolo: exist_materia = MateriaLegislativa.objects.filter( - numero_protocolo=protocolo, - ano=ano).exists() + numero_protocolo=protocolo, ano=ano + ).exists() exist_doc = DocumentoAdministrativo.objects.filter( - protocolo_id=protocolo, - ano=ano).exists() + protocolo_id=protocolo, ano=ano + ).exists() if exist_materia or exist_doc: - self.logger.error("Protocolo %s/%s ja possui" - " documento vinculado" - % (protocolo, ano)) - raise ValidationError(_('Protocolo %s/%s ja possui' - ' documento vinculado' - % (protocolo, ano))) + self.logger.error( + "Protocolo %s/%s ja possui" + " documento vinculado" % (protocolo, ano) + ) + raise ValidationError( + _( + "Protocolo %s/%s ja possui" + " documento vinculado" % (protocolo, ano) + ) + ) p = Protocolo.objects.get(numero=protocolo, ano=ano) - if p.tipo_materia != cleaned_data['tipo']: - self.logger.error("Tipo do Protocolo ({}) deve ser o mesmo do Tipo Matéria ({})." - .format(cleaned_data['tipo'], p.tipo_materia)) + if p.tipo_materia != cleaned_data["tipo"]: + self.logger.error( + "Tipo do Protocolo ({}) deve ser o mesmo do Tipo Matéria ({}).".format( + cleaned_data["tipo"], p.tipo_materia + ) + ) raise ValidationError( - _('Tipo do Protocolo deve ser o mesmo do Tipo Matéria')) + _("Tipo do Protocolo deve ser o mesmo do Tipo Matéria") + ) - ano_origem_externa = cleaned_data['ano_origem_externa'] - data_origem_externa = cleaned_data['data_origem_externa'] + ano_origem_externa = cleaned_data["ano_origem_externa"] + data_origem_externa = cleaned_data["data_origem_externa"] - if ano_origem_externa and data_origem_externa and \ - ano_origem_externa != data_origem_externa.year: - self.logger.error("O ano de origem externa da matéria ({}) é " - " diferente do ano na data de origem externa ({})." - .format(ano_origem_externa, data_origem_externa)) - raise ValidationError(_("O ano de origem externa da matéria não " - "pode ser diferente do ano na data de " - "origem externa")) + if ( + ano_origem_externa + and data_origem_externa + and ano_origem_externa != data_origem_externa.year + ): + self.logger.error( + "O ano de origem externa da matéria ({}) é " + " diferente do ano na data de origem externa ({}).".format( + ano_origem_externa, data_origem_externa + ) + ) + raise ValidationError( + _( + "O ano de origem externa da matéria não " + "pode ser diferente do ano na data de " + "origem externa" + ) + ) - texto_original = self.cleaned_data.get('texto_original', False) + texto_original = self.cleaned_data.get("texto_original", False) if texto_original: validar_arquivo(texto_original, "Texto Original") @@ -263,23 +296,22 @@ class MateriaLegislativaForm(FileFieldCheckMixin, ModelForm): materia = super(MateriaLegislativaForm, self).save(commit) materia.save() - if self.cleaned_data['autor']: + if self.cleaned_data["autor"]: autoria = Autoria() autoria.primeiro_autor = primeiro_autor autoria.materia = materia - autoria.autor = self.cleaned_data['autor'] + autoria.autor = self.cleaned_data["autor"] autoria.save() return materia class UnidadeTramitacaoForm(ModelForm): - logger = logging.getLogger(__name__) class Meta: model = UnidadeTramitacao - fields = ['comissao', 'orgao', 'parlamentar'] + fields = ["comissao", "orgao", "parlamentar"] def clean(self): super(UnidadeTramitacaoForm, self).clean() @@ -294,7 +326,7 @@ class UnidadeTramitacaoForm(ModelForm): del cleaned_data[key] if len(cleaned_data) != 1: - msg = _('Somente um campo deve ser preenchido!') + msg = _("Somente um campo deve ser preenchido!") self.logger.error("Somente um campo deve ser preenchido!") raise ValidationError(msg) return cleaned_data @@ -303,11 +335,11 @@ class UnidadeTramitacaoForm(ModelForm): unidade = super(UnidadeTramitacaoForm, self).save(commit) cd = self.cleaned_data - if not cd.get('orgao'): + if not cd.get("orgao"): unidade.orgao = None - if not cd.get('parlamentar'): + if not cd.get("parlamentar"): unidade.parlamentar = None - if not cd.get('comissao'): + if not cd.get("comissao"): unidade.comissao = None unidade.save() @@ -315,15 +347,13 @@ class UnidadeTramitacaoForm(ModelForm): class AcompanhamentoMateriaForm(GoogleRecapthaMixin, ModelForm): - class Meta: model = AcompanhamentoMateria - fields = ['email'] + fields = ["email"] def __init__(self, *args, **kwargs): - - kwargs['title_label'] = _('Acompanhamento de Matéria por e-mail') - kwargs['action_label'] = _('Cadastrar') + kwargs["title_label"] = _("Acompanhamento de Matéria por e-mail") + kwargs["action_label"] = _("Cadastrar") super().__init__(*args, **kwargs) @@ -333,8 +363,7 @@ class DocumentoAcessorioForm(FileFieldCheckMixin, ModelForm): class Meta: model = DocumentoAcessorio - fields = ['tipo', 'nome', 'data', 'autor', - 'ementa', 'indexacao', 'arquivo'] + fields = ["tipo", "nome", "data", "autor", "ementa", "indexacao", "arquivo"] def clean(self): super(DocumentoAcessorioForm, self).clean() @@ -342,7 +371,7 @@ class DocumentoAcessorioForm(FileFieldCheckMixin, ModelForm): if not self.is_valid(): return self.cleaned_data - arquivo = self.cleaned_data.get('arquivo') + arquivo = self.cleaned_data.get("arquivo") if arquivo: validar_arquivo(arquivo, "Texto Integral") @@ -350,8 +379,8 @@ class DocumentoAcessorioForm(FileFieldCheckMixin, ModelForm): # TODO: definir arquivo no form e preservar o nome do campo # que gerou a mensagem de erro. ## arquivo = forms.FileField(required=True, label="Texto Integral") - nome_arquivo = self.fields['arquivo'].label - raise ValidationError(f'Favor anexar arquivo em {nome_arquivo}') + nome_arquivo = self.fields["arquivo"].label + raise ValidationError(f"Favor anexar arquivo em {nome_arquivo}") return self.cleaned_data @@ -361,9 +390,9 @@ class RelatoriaForm(ModelForm): composicao = forms.ModelChoiceField( required=True, - empty_label='---------', + empty_label="---------", queryset=Composicao.objects.all(), - label=_('Composição') + label=_("Composição"), ) tipo_unidade_tramitacao_destino = forms.CharField(required=False) @@ -373,49 +402,55 @@ class RelatoriaForm(ModelForm): class Meta: model = Relatoria fields = [ - 'comissao', - 'data_designacao_relator', - 'data_destituicao_relator', - 'tipo_fim_relatoria', - 'composicao', - 'parlamentar' + "comissao", + "data_designacao_relator", + "data_destituicao_relator", + "tipo_fim_relatoria", + "composicao", + "parlamentar", ] widgets = { - 'comissao': forms.Select(attrs={'disabled': 'disabled'}), - 'tipo_unidade_tramitacao_destino': forms.HiddenInput(), - 'unidade_tramitacao_destino': forms.HiddenInput(), + "comissao": forms.Select(attrs={"disabled": "disabled"}), + "tipo_unidade_tramitacao_destino": forms.HiddenInput(), + "unidade_tramitacao_destino": forms.HiddenInput(), } def __init__(self, *args, **kwargs): - row1 = to_row([('comissao', 12)]) - row2 = to_row([('data_designacao_relator', 4), - ('data_destituicao_relator', 4), - ('tipo_fim_relatoria', 4)]) - row3 = to_row([('composicao', 4), - ('parlamentar', 8)]) + row1 = to_row([("comissao", 12)]) + row2 = to_row( + [ + ("data_designacao_relator", 4), + ("data_destituicao_relator", 4), + ("tipo_fim_relatoria", 4), + ] + ) + row3 = to_row([("composicao", 4), ("parlamentar", 8)]) self.helper = SaplFormHelper() - self.helper.layout = SaplFormLayout( - Fieldset(_('Relatoria'), row1, row2, row3)) + self.helper.layout = SaplFormLayout(Fieldset(_("Relatoria"), row1, row2, row3)) super().__init__(*args, **kwargs) - comissao_pk = kwargs['initial']['comissao'] + comissao_pk = kwargs["initial"]["comissao"] composicoes = Composicao.objects.filter(comissao_id=comissao_pk) - self.fields['composicao'].choices = [('', '---------')] + \ - [(c.pk, c) for c in composicoes] + self.fields["composicao"].choices = [("", "---------")] + [ + (c.pk, c) for c in composicoes + ] # UPDATE - if self.initial.get('composicao') and self.initial.get('parlamentar'): - parlamentares = [(p.parlamentar.id, p.parlamentar) for p in - Participacao.objects.filter(composicao__comissao_id=comissao_pk, - composicao_id=self.initial['composicao'])] + if self.initial.get("composicao") and self.initial.get("parlamentar"): + parlamentares = [ + (p.parlamentar.id, p.parlamentar) + for p in Participacao.objects.filter( + composicao__comissao_id=comissao_pk, + composicao_id=self.initial["composicao"], + ) + ] - self.fields['parlamentar'].choices = [ - ('', '---------')] + parlamentares + self.fields["parlamentar"].choices = [("", "---------")] + parlamentares # INSERT else: - self.fields['parlamentar'].choices = [('', '---------')] + self.fields["parlamentar"].choices = [("", "---------")] def clean(self): super().clean() @@ -427,63 +462,72 @@ class RelatoriaForm(ModelForm): try: self.logger.debug("Tentando obter objeto Comissao.") - comissao = Comissao.objects.get(id=self.initial['comissao']) + comissao = Comissao.objects.get(id=self.initial["comissao"]) except ObjectDoesNotExist as e: self.logger.error( "Objeto Comissao não encontrado com id={}. A localização atual deve ser uma comissão. ".format( - self.initial['comissao']) + str(e)) - msg = _('A localização atual deve ser uma comissão.') + self.initial["comissao"] + ) + + str(e) + ) + msg = _("A localização atual deve ser uma comissão.") raise ValidationError(msg) else: - cleaned_data['comissao'] = comissao - - if cleaned_data['data_designacao_relator'] < cleaned_data['composicao'].periodo.data_inicio \ - or cleaned_data['data_designacao_relator'] > cleaned_data['composicao'].periodo.data_fim: + cleaned_data["comissao"] = comissao + + if ( + cleaned_data["data_designacao_relator"] + < cleaned_data["composicao"].periodo.data_inicio + or cleaned_data["data_designacao_relator"] + > cleaned_data["composicao"].periodo.data_fim + ): raise ValidationError( - _('Data de designação deve estar dentro do período da composição.')) + _("Data de designação deve estar dentro do período da composição.") + ) return cleaned_data class TramitacaoForm(ModelForm): - - urgente = forms.ChoiceField(required=True, - choices=YES_NO_CHOICES, - initial=False, - label=_("Urgente?")) + urgente = forms.ChoiceField( + required=True, choices=YES_NO_CHOICES, initial=False, label=_("Urgente?") + ) logger = logging.getLogger(__name__) class Meta: model = Tramitacao - fields = ['data_tramitacao', - 'unidade_tramitacao_local', - 'status', - 'turno', - 'urgente', - 'unidade_tramitacao_destino', - 'data_encaminhamento', - 'data_fim_prazo', - 'texto', - 'user', - 'ip', - 'ultima_edicao'] - - widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput()} + fields = [ + "data_tramitacao", + "unidade_tramitacao_local", + "status", + "turno", + "urgente", + "unidade_tramitacao_destino", + "data_encaminhamento", + "data_fim_prazo", + "texto", + "user", + "ip", + "ultima_edicao", + ] + + widgets = { + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), + } def __init__(self, *args, **kwargs): super(TramitacaoForm, self).__init__(*args, **kwargs) - self.fields['data_tramitacao'].initial = timezone.now().date() + self.fields["data_tramitacao"].initial = timezone.now().date() ust = UnidadeTramitacao.objects.select_related().all() - unidade_tramitacao_destino = [('', '---------')] + [(ut.pk, ut) - for ut in ust if ut.comissao and ut.comissao.ativa] - unidade_tramitacao_destino.extend( - [(ut.pk, ut) for ut in ust if ut.orgao]) - unidade_tramitacao_destino.extend( - [(ut.pk, ut) for ut in ust if ut.parlamentar]) - self.fields['unidade_tramitacao_destino'].choices = unidade_tramitacao_destino + unidade_tramitacao_destino = [("", "---------")] + [ + (ut.pk, ut) for ut in ust if ut.comissao and ut.comissao.ativa + ] + unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.orgao]) + unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.parlamentar]) + self.fields["unidade_tramitacao_destino"].choices = unidade_tramitacao_destino def clean(self): super(TramitacaoForm, self).clean() @@ -493,62 +537,81 @@ class TramitacaoForm(ModelForm): cleaned_data = self.cleaned_data - if 'data_encaminhamento' in cleaned_data: - data_enc_form = cleaned_data['data_encaminhamento'] - if 'data_fim_prazo' in cleaned_data: - data_prazo_form = cleaned_data['data_fim_prazo'] - if 'data_tramitacao' in cleaned_data: - data_tram_form = cleaned_data['data_tramitacao'] - - ultima_tramitacao = Tramitacao.objects.filter( - materia_id=self.instance.materia_id).exclude( - id=self.instance.id).order_by( - '-data_tramitacao', - '-id').first() + if "data_encaminhamento" in cleaned_data: + data_enc_form = cleaned_data["data_encaminhamento"] + if "data_fim_prazo" in cleaned_data: + data_prazo_form = cleaned_data["data_fim_prazo"] + if "data_tramitacao" in cleaned_data: + data_tram_form = cleaned_data["data_tramitacao"] + + ultima_tramitacao = ( + Tramitacao.objects.filter(materia_id=self.instance.materia_id) + .exclude(id=self.instance.id) + .order_by("-data_tramitacao", "-id") + .first() + ) if not self.instance.data_tramitacao: - - if ultima_tramitacao and BaseAppConfig.attr('tramitacao_origem_fixa'): + if ultima_tramitacao and BaseAppConfig.attr("tramitacao_origem_fixa"): destino = ultima_tramitacao.unidade_tramitacao_destino - if (destino != self.cleaned_data['unidade_tramitacao_local']): - self.logger.error("A origem da nova tramitação ({}) não é igual ao " - "destino da última adicionada ({})!" - .format(self.cleaned_data['unidade_tramitacao_local'], destino)) - msg = _('A origem da nova tramitação deve ser igual ao ' - 'destino da última adicionada!') + if destino != self.cleaned_data["unidade_tramitacao_local"]: + self.logger.error( + "A origem da nova tramitação ({}) não é igual ao " + "destino da última adicionada ({})!".format( + self.cleaned_data["unidade_tramitacao_local"], destino + ) + ) + msg = _( + "A origem da nova tramitação deve ser igual ao " + "destino da última adicionada!" + ) raise ValidationError(msg) - if cleaned_data['data_tramitacao'] > timezone.now().date(): - 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!') + if cleaned_data["data_tramitacao"] > timezone.now().date(): + 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 - data_tram_form < ultima_tramitacao.data_tramitacao): - msg = _('A data da nova tramitação deve ser ' + - 'maior que a data da última tramitação!') - self.logger.error("A data da nova tramitação ({}) deve ser " - "maior que a data da última tramitação ({})!" - .format(data_tram_form, ultima_tramitacao.data_tramitacao)) + if ultima_tramitacao and data_tram_form < ultima_tramitacao.data_tramitacao: + msg = _( + "A data da nova tramitação deve ser " + + "maior que a data da última tramitação!" + ) + self.logger.error( + "A data da nova tramitação ({}) deve ser " + "maior que a data da última tramitação ({})!".format( + data_tram_form, ultima_tramitacao.data_tramitacao + ) + ) raise ValidationError(msg) 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.warning("A data de encaminhamento ({}) deve ser maior que a data de tramitação! ({})" - .format(data_enc_form, data_tram_form)) + "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) if data_prazo_form: if data_prazo_form < data_tram_form: - msg = _('A data fim de prazo deve ser ' + - 'maior que a data de tramitação!') - self.logger.error("A data fim de prazo ({}) deve ser " + - "maior que a data de tramitação ({})!" - .format(data_prazo_form, data_tram_form)) + msg = _( + "A data fim de prazo deve ser " + "maior que a data de tramitação!" + ) + self.logger.error( + "A data fim de prazo ({}) deve ser " + + "maior que a data de tramitação ({})!".format( + data_prazo_form, data_tram_form + ) + ) raise ValidationError(msg) return cleaned_data @@ -561,40 +624,45 @@ class TramitacaoForm(ModelForm): materia.em_tramitacao = False if tramitacao.status.indicador == "F" else True materia.save() - tramitar_anexadas = BaseAppConfig.attr( - 'tramitacao_materia') + tramitar_anexadas = BaseAppConfig.attr("tramitacao_materia") if tramitar_anexadas: lista_tramitacao = [] materias_anexadas = lista_anexados(materia) for mat in materias_anexadas: - ultima_tramitacao = mat.tramitacao_set.\ - select_related('unidade_tramitacao_destino').\ - order_by('-data_tramitacao', '-id').first() - if not ultima_tramitacao or \ - ultima_tramitacao.unidade_tramitacao_destino \ - == tramitacao.unidade_tramitacao_local: - mat.em_tramitacao = False if \ - tramitacao.status.indicador == "F" else True - lista_tramitacao.append(Tramitacao( - status=tramitacao.status, - materia=mat, - data_tramitacao=tramitacao.data_tramitacao, - unidade_tramitacao_local=tramitacao.unidade_tramitacao_local, - data_encaminhamento=tramitacao.data_encaminhamento, - unidade_tramitacao_destino=tramitacao.unidade_tramitacao_destino, - urgente=tramitacao.urgente, - turno=tramitacao.turno, - texto=tramitacao.texto, - data_fim_prazo=tramitacao.data_fim_prazo, - user=tramitacao.user, - ip=tramitacao.ip, - ultima_edicao=tramitacao.ultima_edicao - )) + ultima_tramitacao = ( + mat.tramitacao_set.select_related("unidade_tramitacao_destino") + .order_by("-data_tramitacao", "-id") + .first() + ) + if ( + not ultima_tramitacao + or ultima_tramitacao.unidade_tramitacao_destino + == tramitacao.unidade_tramitacao_local + ): + mat.em_tramitacao = ( + False if tramitacao.status.indicador == "F" else True + ) + lista_tramitacao.append( + Tramitacao( + status=tramitacao.status, + materia=mat, + data_tramitacao=tramitacao.data_tramitacao, + unidade_tramitacao_local=tramitacao.unidade_tramitacao_local, + data_encaminhamento=tramitacao.data_encaminhamento, + unidade_tramitacao_destino=tramitacao.unidade_tramitacao_destino, + urgente=tramitacao.urgente, + turno=tramitacao.turno, + texto=tramitacao.texto, + data_fim_prazo=tramitacao.data_fim_prazo, + user=tramitacao.user, + ip=tramitacao.ip, + ultima_edicao=tramitacao.ultima_edicao, + ) + ) # TODO: BULK UPDATE não envia Signal para Tramitacao Tramitacao.objects.bulk_create(lista_tramitacao) # Atualiza status 'em_tramitacao' - MateriaLegislativa.objects.bulk_update( - materias_anexadas, ['em_tramitacao']) + MateriaLegislativa.objects.bulk_update(materias_anexadas, ["em_tramitacao"]) return tramitacao @@ -604,18 +672,24 @@ def compara_tramitacoes_mat(tramitacao1, tramitacao2): if not tramitacao1 or not tramitacao2: return False - lst_items = ['id', 'materia_id', 'timestamp'] - values = [(k, v) for k, v in tramitacao1.__dict__.items() - if ((k not in lst_items) and (k[0] != '_'))] - other_values = [(k, v) for k, v in tramitacao2.__dict__.items() - if (k not in lst_items and k[0] != '_')] + lst_items = ["id", "materia_id", "timestamp"] + values = [ + (k, v) + for k, v in tramitacao1.__dict__.items() + if ((k not in lst_items) and (k[0] != "_")) + ] + other_values = [ + (k, v) + for k, v in tramitacao2.__dict__.items() + if (k not in lst_items and k[0] != "_") + ] return values == other_values class TramitacaoUpdateForm(TramitacaoForm): unidade_tramitacao_local = forms.ModelChoiceField( - queryset=UnidadeTramitacao.objects.all(), - widget=forms.HiddenInput()) + queryset=UnidadeTramitacao.objects.all(), widget=forms.HiddenInput() + ) data_tramitacao = forms.DateField(widget=forms.HiddenInput()) @@ -623,26 +697,27 @@ class TramitacaoUpdateForm(TramitacaoForm): class Meta: model = Tramitacao - fields = ['data_tramitacao', - 'unidade_tramitacao_local', - 'status', - 'turno', - 'urgente', - 'unidade_tramitacao_destino', - 'data_encaminhamento', - 'data_fim_prazo', - 'texto', - 'user', - 'ip', - 'ultima_edicao' - ] + fields = [ + "data_tramitacao", + "unidade_tramitacao_local", + "status", + "turno", + "urgente", + "unidade_tramitacao_destino", + "data_encaminhamento", + "data_fim_prazo", + "texto", + "user", + "ip", + "ultima_edicao", + ] widgets = { - 'data_encaminhamento': forms.DateInput(format='%d/%m/%Y'), - 'data_fim_prazo': forms.DateInput(format='%d/%m/%Y'), - 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput() + "data_encaminhamento": forms.DateInput(format="%d/%m/%Y"), + "data_fim_prazo": forms.DateInput(format="%d/%m/%Y"), + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), } def clean(self): @@ -654,40 +729,51 @@ class TramitacaoUpdateForm(TramitacaoForm): cd = self.cleaned_data obj = self.instance - ultima_tramitacao = Tramitacao.objects.filter( - materia_id=obj.materia_id).order_by( - '-data_tramitacao', - '-id').first() + ultima_tramitacao = ( + Tramitacao.objects.filter(materia_id=obj.materia_id) + .order_by("-data_tramitacao", "-id") + .first() + ) # Se a Tramitação que está sendo editada não for a mais recente, # ela não pode ter seu destino alterado. if ultima_tramitacao != obj: - if cd['unidade_tramitacao_destino'] != \ - obj.unidade_tramitacao_destino and BaseAppConfig.attr('tramitacao_origem_fixa'): - self.logger.error("Você não pode mudar a Unidade de Destino desta " - "tramitação para {}, pois irá conflitar com a Unidade " - "Local da tramitação seguinte ({})." - .format(cd['unidade_tramitacao_destino'], - obj.unidade_tramitacao_destino)) + if cd[ + "unidade_tramitacao_destino" + ] != obj.unidade_tramitacao_destino and BaseAppConfig.attr( + "tramitacao_origem_fixa" + ): + self.logger.error( + "Você não pode mudar a Unidade de Destino desta " + "tramitação para {}, pois irá conflitar com a Unidade " + "Local da tramitação seguinte ({}).".format( + cd["unidade_tramitacao_destino"], obj.unidade_tramitacao_destino + ) + ) raise ValidationError( - 'Você não pode mudar a Unidade de Destino desta ' - 'tramitação, pois irá conflitar com a Unidade ' - 'Local da tramitação seguinte') - - if not (cd['data_tramitacao'] != obj.data_tramitacao or - cd['unidade_tramitacao_destino'] != obj.unidade_tramitacao_destino or - cd['status'] != obj.status or cd['texto'] != obj.texto or - cd['data_encaminhamento'] != obj.data_encaminhamento or - cd['data_fim_prazo'] != obj.data_fim_prazo or cd['urgente'] != str(obj.urgente) or - cd['turno'] != obj.turno): + "Você não pode mudar a Unidade de Destino desta " + "tramitação, pois irá conflitar com a Unidade " + "Local da tramitação seguinte" + ) + + if not ( + cd["data_tramitacao"] != obj.data_tramitacao + or cd["unidade_tramitacao_destino"] != obj.unidade_tramitacao_destino + or cd["status"] != obj.status + or cd["texto"] != obj.texto + or cd["data_encaminhamento"] != obj.data_encaminhamento + or cd["data_fim_prazo"] != obj.data_fim_prazo + or cd["urgente"] != str(obj.urgente) + or cd["turno"] != obj.turno + ): # Se não ocorreram alterações, o usuário, ip, data e hora da última # edição (real) são mantidos - cd['user'] = obj.user - cd['ip'] = obj.ip - cd['ultima_edicao'] = obj.ultima_edicao + cd["user"] = obj.user + cd["ip"] = obj.ip + cd["ultima_edicao"] = obj.ultima_edicao - cd['data_tramitacao'] = obj.data_tramitacao - cd['unidade_tramitacao_local'] = obj.unidade_tramitacao_local + cd["data_tramitacao"] = obj.data_tramitacao + cd["unidade_tramitacao_local"] = obj.unidade_tramitacao_local return cd @@ -697,22 +783,30 @@ class TramitacaoUpdateForm(TramitacaoForm): ant_tram_principal = Tramitacao.objects.get(id=self.instance.id) nova_tram_principal = super(TramitacaoUpdateForm, self).save(commit) materia = nova_tram_principal.materia - materia.em_tramitacao = False if nova_tram_principal.status.indicador == "F" else True + materia.em_tramitacao = ( + False if nova_tram_principal.status.indicador == "F" else True + ) materia.save() - tramitar_anexadas = BaseAppConfig.attr( - 'tramitacao_materia') + tramitar_anexadas = BaseAppConfig.attr("tramitacao_materia") if tramitar_anexadas: anexadas_list = lista_anexados(materia) for ma in anexadas_list: tram_anexada = ma.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() if compara_tramitacoes_mat(ant_tram_principal, tram_anexada): tram_anexada.status = nova_tram_principal.status tram_anexada.data_tramitacao = nova_tram_principal.data_tramitacao - tram_anexada.unidade_tramitacao_local = nova_tram_principal.unidade_tramitacao_local - tram_anexada.data_encaminhamento = nova_tram_principal.data_encaminhamento - tram_anexada.unidade_tramitacao_destino = nova_tram_principal.unidade_tramitacao_destino + tram_anexada.unidade_tramitacao_local = ( + nova_tram_principal.unidade_tramitacao_local + ) + tram_anexada.data_encaminhamento = ( + nova_tram_principal.data_encaminhamento + ) + tram_anexada.unidade_tramitacao_destino = ( + nova_tram_principal.unidade_tramitacao_destino + ) tram_anexada.urgente = nova_tram_principal.urgente tram_anexada.turno = nova_tram_principal.turno tram_anexada.texto = nova_tram_principal.texto @@ -722,44 +816,47 @@ class TramitacaoUpdateForm(TramitacaoForm): tram_anexada.ultima_edicao = nova_tram_principal.ultima_edicao tram_anexada.save() - ma.em_tramitacao = False if nova_tram_principal.status.indicador == "F" else True + ma.em_tramitacao = ( + False if nova_tram_principal.status.indicador == "F" else True + ) ma.save() # TODO: refatorar? return nova_tram_principal class LegislacaoCitadaForm(ModelForm): - tipo = forms.ModelChoiceField( - label=_('Tipo Norma'), + label=_("Tipo Norma"), required=True, queryset=TipoNormaJuridica.objects.all(), - empty_label='Selecione', + empty_label="Selecione", ) - numero = forms.CharField(label='Número', required=True) + numero = forms.CharField(label="Número", required=True) - ano = forms.CharField(label='Ano', required=True) + ano = forms.CharField(label="Ano", required=True) logger = logging.getLogger(__name__) class Meta: model = LegislacaoCitada - fields = ['tipo', - 'numero', - 'ano', - 'disposicoes', - 'parte', - 'livro', - 'titulo', - 'capitulo', - 'secao', - 'subsecao', - 'artigo', - 'paragrafo', - 'inciso', - 'alinea', - 'item'] + fields = [ + "tipo", + "numero", + "ano", + "disposicoes", + "parte", + "livro", + "titulo", + "capitulo", + "secao", + "subsecao", + "artigo", + "paragrafo", + "inciso", + "alinea", + "item", + ] def clean(self): super(LegislacaoCitadaForm, self).clean() @@ -770,46 +867,53 @@ class LegislacaoCitadaForm(ModelForm): cleaned_data = self.cleaned_data try: - self.logger.debug("Tentando obter objeto NormalJuridica (numero={}, ano={}, tipo={})." - .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) + self.logger.debug( + "Tentando obter objeto NormalJuridica (numero={}, ano={}, tipo={}).".format( + cleaned_data["numero"], cleaned_data["ano"], cleaned_data["tipo"] + ) + ) norma = NormaJuridica.objects.get( - numero=cleaned_data['numero'], - ano=cleaned_data['ano'], - tipo=cleaned_data['tipo']) + numero=cleaned_data["numero"], + ano=cleaned_data["ano"], + tipo=cleaned_data["tipo"], + ) except ObjectDoesNotExist: - self.logger.error("A norma a ser inclusa (numero={}, ano={}, tipo={}) " - "não existe no cadastro de Normas." - .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) - msg = _('A norma a ser inclusa não existe no cadastro' - ' de Normas.') + self.logger.error( + "A norma a ser inclusa (numero={}, ano={}, tipo={}) " + "não existe no cadastro de Normas.".format( + cleaned_data["numero"], cleaned_data["ano"], cleaned_data["tipo"] + ) + ) + msg = _("A norma a ser inclusa não existe no cadastro" " de Normas.") raise ValidationError(msg) else: - cleaned_data['norma'] = norma + cleaned_data["norma"] = norma filtro_base = LegislacaoCitada.objects.filter( materia=self.instance.materia, - norma=self.cleaned_data['norma'], - disposicoes=self.cleaned_data['disposicoes'], - parte=self.cleaned_data['parte'], - livro=self.cleaned_data['livro'], - titulo=self.cleaned_data['titulo'], - capitulo=self.cleaned_data['capitulo'], - secao=self.cleaned_data['secao'], - subsecao=self.cleaned_data['subsecao'], - artigo=self.cleaned_data['artigo'], - paragrafo=self.cleaned_data['paragrafo'], - inciso=self.cleaned_data['inciso'], - alinea=self.cleaned_data['alinea'], - item=self.cleaned_data['item']) + norma=self.cleaned_data["norma"], + disposicoes=self.cleaned_data["disposicoes"], + parte=self.cleaned_data["parte"], + livro=self.cleaned_data["livro"], + titulo=self.cleaned_data["titulo"], + capitulo=self.cleaned_data["capitulo"], + secao=self.cleaned_data["secao"], + subsecao=self.cleaned_data["subsecao"], + artigo=self.cleaned_data["artigo"], + paragrafo=self.cleaned_data["paragrafo"], + inciso=self.cleaned_data["inciso"], + alinea=self.cleaned_data["alinea"], + item=self.cleaned_data["item"], + ) if not self.instance.id: if filtro_base.exists(): - msg = _('Essa Legislação já foi cadastrada.') + msg = _("Essa Legislação já foi cadastrada.") self.logger.error("Essa Legislação já foi cadastrada.") raise ValidationError(msg) else: if filtro_base.exclude(id=self.instance.id).exists(): - msg = _('Essa Legislação já foi cadastrada.') + msg = _("Essa Legislação já foi cadastrada.") self.logger.error("Essa Legislação já foi cadastrada.") raise ValidationError(msg) return cleaned_data @@ -817,21 +921,17 @@ class LegislacaoCitadaForm(ModelForm): def save(self, commit=False): legislacao = super(LegislacaoCitadaForm, self).save(commit) - legislacao.norma = self.cleaned_data['norma'] + legislacao.norma = self.cleaned_data["norma"] legislacao.save() return legislacao class NumeracaoForm(ModelForm): - logger = logging.getLogger(__name__) class Meta: model = Numeracao - fields = ['tipo_materia', - 'numero_materia', - 'ano_materia', - 'data_materia'] + fields = ["tipo_materia", "numero_materia", "ano_materia", "data_materia"] def clean(self): super(NumeracaoForm, self).clean() @@ -840,53 +940,68 @@ class NumeracaoForm(ModelForm): return self.cleaned_data try: - self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}. tipo={})." - .format(self.cleaned_data['numero_materia'], - self.cleaned_data['ano_materia'], self.cleaned_data['tipo_materia'])) + self.logger.info( + "Tentando obter objeto MateriaLegislativa (numero={}, ano={}. tipo={}).".format( + self.cleaned_data["numero_materia"], + self.cleaned_data["ano_materia"], + self.cleaned_data["tipo_materia"], + ) + ) MateriaLegislativa.objects.get( - numero=self.cleaned_data['numero_materia'], - ano=self.cleaned_data['ano_materia'], - tipo=self.cleaned_data['tipo_materia']) + numero=self.cleaned_data["numero_materia"], + ano=self.cleaned_data["ano_materia"], + tipo=self.cleaned_data["tipo_materia"], + ) except ObjectDoesNotExist: - msg = _('A matéria a ser inclusa não existe no cadastro' - ' de matérias legislativas.') - self.logger.error("A MateriaLegislativa a ser inclusa (numero={}, ano={}. tipo={}) não existe no cadastro de matérias legislativas." - .format(self.cleaned_data['numero_materia'], - self.cleaned_data['ano_materia'], self.cleaned_data['tipo_materia'])) + msg = _( + "A matéria a ser inclusa não existe no cadastro" + " de matérias legislativas." + ) + self.logger.error( + "A MateriaLegislativa a ser inclusa (numero={}, ano={}. tipo={}) não existe no cadastro de matérias legislativas.".format( + self.cleaned_data["numero_materia"], + self.cleaned_data["ano_materia"], + self.cleaned_data["tipo_materia"], + ) + ) raise ValidationError(msg) if Numeracao.objects.filter( materia=self.instance.materia, - tipo_materia=self.cleaned_data['tipo_materia'], - ano_materia=self.cleaned_data['ano_materia'], - numero_materia=self.cleaned_data['numero_materia'] + tipo_materia=self.cleaned_data["tipo_materia"], + ano_materia=self.cleaned_data["ano_materia"], + numero_materia=self.cleaned_data["numero_materia"], ).exists(): - msg = _('Essa numeração já foi cadastrada.') - self.logger.error("Essa numeração (materia={}, tipo_materia={}, ano_materia={}, numero_materia={}) " - "já foi cadastrada.".format(self.instance.materia, self.cleaned_data['tipo_materia'], - self.cleaned_data['ano_materia'], self.cleaned_data['numero_materia'])) + msg = _("Essa numeração já foi cadastrada.") + self.logger.error( + "Essa numeração (materia={}, tipo_materia={}, ano_materia={}, numero_materia={}) " + "já foi cadastrada.".format( + self.instance.materia, + self.cleaned_data["tipo_materia"], + self.cleaned_data["ano_materia"], + self.cleaned_data["numero_materia"], + ) + ) raise ValidationError(msg) return self.cleaned_data class AnexadaForm(ModelForm): - logger = logging.getLogger(__name__) tipo = forms.ModelChoiceField( - label='Tipo', + label="Tipo", required=True, queryset=TipoMateriaLegislativa.objects.all(), - empty_label='Selecione', + empty_label="Selecione", ) - numero = forms.IntegerField(label='Número', required=True) + numero = forms.IntegerField(label="Número", required=True) - ano = forms.CharField(label='Ano', required=True) + ano = forms.CharField(label="Ano", required=True) def __init__(self, *args, **kwargs): - return super(AnexadaForm, self).__init__(*args, **kwargs) def clean(self): @@ -897,58 +1012,73 @@ class AnexadaForm(ModelForm): cleaned_data = self.cleaned_data - data_anexacao = cleaned_data['data_anexacao'] - data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao + data_anexacao = cleaned_data["data_anexacao"] + data_desanexacao = ( + cleaned_data["data_desanexacao"] + if cleaned_data["data_desanexacao"] + else data_anexacao + ) if data_anexacao > data_desanexacao: - self.logger.error( - "Data de anexação posterior à data de desanexação.") + self.logger.error("Data de anexação posterior à data de desanexação.") raise ValidationError( - _("Data de anexação posterior à data de desanexação.")) + _("Data de anexação posterior à data de desanexação.") + ) try: - self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={})." - .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) + self.logger.info( + "Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={}).".format( + cleaned_data["numero"], cleaned_data["ano"], cleaned_data["tipo"] + ) + ) materia_anexada = MateriaLegislativa.objects.get( - numero=cleaned_data['numero'], - ano=cleaned_data['ano'], - tipo=cleaned_data['tipo']) + numero=cleaned_data["numero"], + ano=cleaned_data["ano"], + tipo=cleaned_data["tipo"], + ) except ObjectDoesNotExist: - msg = _('A {} {}/{} não existe no cadastro de matérias legislativas.' - .format(cleaned_data['tipo'], cleaned_data['numero'], cleaned_data['ano'])) + msg = _( + "A {} {}/{} não existe no cadastro de matérias legislativas.".format( + cleaned_data["tipo"], cleaned_data["numero"], cleaned_data["ano"] + ) + ) self.logger.warning( - "A matéria a ser anexada não existe no cadastro de matérias legislativas.") + "A matéria a ser anexada não existe no cadastro de matérias legislativas." + ) raise ValidationError(msg) materia_principal = self.instance.materia_principal if materia_principal == materia_anexada: self.logger.error("Matéria não pode ser anexada a si mesma.") - raise ValidationError(_('Matéria não pode ser anexada a si mesma')) + raise ValidationError(_("Matéria não pode ser anexada a si mesma")) - is_anexada = Anexada.objects.filter( - materia_principal=materia_principal, - materia_anexada=materia_anexada - ).exclude(pk=self.instance.pk).exists() + is_anexada = ( + Anexada.objects.filter( + materia_principal=materia_principal, materia_anexada=materia_anexada + ) + .exclude(pk=self.instance.pk) + .exists() + ) if is_anexada: self.logger.error("Matéria já se encontra anexada.") - raise ValidationError(_('Matéria já se encontra anexada')) + raise ValidationError(_("Matéria já se encontra anexada")) ciclico = False - anexadas_anexada = Anexada.objects.filter( - materia_principal=materia_anexada) + anexadas_anexada = Anexada.objects.filter(materia_principal=materia_anexada) anexadas_visitadas = [materia_principal] while anexadas_anexada: anexadas = [] for anexa in anexadas_anexada: - if anexa.materia_anexada in anexadas_visitadas: ciclico = True break else: anexadas_visitadas.append(anexa.materia_anexada) - for a in Anexada.objects.filter(materia_principal=anexa.materia_anexada): + for a in Anexada.objects.filter( + materia_principal=anexa.materia_anexada + ): anexadas.append(a) if ciclico: break @@ -956,91 +1086,94 @@ class AnexadaForm(ModelForm): if ciclico: self.logger.error( - "A matéria não pode ser anexada por uma de suas anexadas.") + "A matéria não pode ser anexada por uma de suas anexadas." + ) raise ValidationError( - _("A matéria não pode ser anexada por uma de suas anexadas.")) + _("A matéria não pode ser anexada por uma de suas anexadas.") + ) - cleaned_data['materia_anexada'] = materia_anexada + cleaned_data["materia_anexada"] = materia_anexada return cleaned_data def save(self, commit=False): anexada = super(AnexadaForm, self).save(commit) - anexada.materia_anexada = self.cleaned_data['materia_anexada'] + anexada.materia_anexada = self.cleaned_data["materia_anexada"] anexada.save() return anexada class Meta: model = Anexada - fields = ['tipo', 'numero', 'ano', 'data_anexacao', 'data_desanexacao'] + fields = ["tipo", "numero", "ano", "data_anexacao", "data_desanexacao"] class MateriaLegislativaFilterSet(django_filters.FilterSet): - - ano = django_filters.ChoiceFilter(required=False, - label='Ano da Matéria', - choices=choice_anos_com_materias) + ano = django_filters.ChoiceFilter( + required=False, label="Ano da Matéria", choices=choice_anos_com_materias + ) autoria__autor = django_filters.CharFilter(widget=forms.HiddenInput()) autoria__primeiro_autor = django_filters.BooleanFilter( - required=False, - label=_('Primeiro Autor')) + required=False, label=_("Primeiro Autor") + ) - autoria__autor__parlamentar_set__filiacao__partido = django_filters.ModelChoiceFilter( - queryset=Partido.objects.all(), - label=_('Matérias por Partido')) + autoria__autor__parlamentar_set__filiacao__partido = ( + django_filters.ModelChoiceFilter( + queryset=Partido.objects.all(), label=_("Matérias por Partido") + ) + ) ementa = django_filters.CharFilter( - label=_('Pesquisar expressões na ementa'), - method='filter_ementa' + label=_("Pesquisar expressões na ementa"), method="filter_ementa" ) - indexacao = django_filters.CharFilter(lookup_expr='icontains', - label=_('Indexação')) + indexacao = django_filters.CharFilter(lookup_expr="icontains", label=_("Indexação")) - em_tramitacao = django_filters.ChoiceFilter(required=False, - label='Em tramitação', - choices=CHOICE_TRAMITACAO) + em_tramitacao = django_filters.ChoiceFilter( + required=False, label="Em tramitação", choices=CHOICE_TRAMITACAO + ) materiaassunto__assunto = django_filters.ModelChoiceFilter( - queryset=AssuntoMateria.objects.all(), - label=_('Assunto')) + queryset=AssuntoMateria.objects.all(), label=_("Assunto") + ) numeracao__numero_materia = django_filters.NumberFilter( - required=False, - label=_('Número do processo')) + required=False, label=_("Número do processo") + ) - o = MateriaPesquisaOrderingFilter(help_text='') + o = MateriaPesquisaOrderingFilter(help_text="") tipo_listagem = forms.ChoiceField( required=False, choices=CHOICE_TIPO_LISTAGEM, - label=_('Tipo da Listagem do Resultado da Pesquisa')) + label=_("Tipo da Listagem do Resultado da Pesquisa"), + ) class Meta(FilterOverridesMetaMixin): model = MateriaLegislativa - fields = ['numero', - 'numero_protocolo', - 'numeracao__numero_materia', - 'ano', - 'tipo', - 'data_apresentacao', - 'data_publicacao', - 'autoria__autor__tipo', - 'autoria__primeiro_autor', - 'autoria__autor__parlamentar_set__filiacao__partido', - 'relatoria__parlamentar_id', - 'tramitacao__unidade_tramitacao_destino', - 'tramitacao__status', - 'materiaassunto__assunto', - 'em_tramitacao', - 'tipo_origem_externa', - 'numero_origem_externa', - 'ano_origem_externa', - 'data_origem_externa', - 'local_origem_externa', - 'regime_tramitacao', - ] + fields = [ + "numero", + "numero_protocolo", + "numeracao__numero_materia", + "ano", + "tipo", + "data_apresentacao", + "data_publicacao", + "autoria__autor__tipo", + "autoria__primeiro_autor", + "autoria__autor__parlamentar_set__filiacao__partido", + "relatoria__parlamentar_id", + "tramitacao__unidade_tramitacao_destino", + "tramitacao__status", + "materiaassunto__assunto", + "em_tramitacao", + "tipo_origem_externa", + "numero_origem_externa", + "ano_origem_externa", + "data_origem_externa", + "local_origem_externa", + "regime_tramitacao", + ] def filter_ementa(self, queryset, name, value): texto = value.split() @@ -1055,182 +1188,213 @@ class MateriaLegislativaFilterSet(django_filters.FilterSet): # self.filters['tipo'].label = 'Tipo de Matéria' self.filters[ - 'autoria__autor__parlamentar_set__filiacao__partido' - ].label = 'Partido do Autor' + "autoria__autor__parlamentar_set__filiacao__partido" + ].label = "Partido do Autor" - self.filters['autoria__autor__tipo'].label = _('Tipo de Autor') - self.filters['relatoria__parlamentar_id'].label = _('Relatoria') - self.filters['tramitacao__unidade_tramitacao_destino'].label = _( - 'Unidade de tramitação atual') - self.filters['tramitacao__status'].label = _( - 'Status da tramitação atual') - self.filters['tramitacao__status'].label = _( - 'Status da tramitação atual') + self.filters["autoria__autor__tipo"].label = _("Tipo de Autor") + self.filters["relatoria__parlamentar_id"].label = _("Relatoria") + self.filters["tramitacao__unidade_tramitacao_destino"].label = _( + "Unidade de tramitação atual" + ) + self.filters["tramitacao__status"].label = _("Status da tramitação atual") + self.filters["tramitacao__status"].label = _("Status da tramitação atual") - self.filters['o'].label = _('Ordenação') - self.form.fields['tipo_listagem'] = self.tipo_listagem + self.filters["o"].label = _("Ordenação") + self.form.fields["tipo_listagem"] = self.tipo_listagem - row1 = to_row( - [('tipo', 5), ('ementa', 7)]) + row1 = to_row([("tipo", 5), ("ementa", 7)]) row2 = to_row( - [('numero', 3), - ('numeracao__numero_materia', 3), - ('numero_protocolo', 3), - ('ano', 3)]) - row3 = to_row( - [('data_apresentacao', 6), - ('data_publicacao', 6)]) - row4 = to_row([ - ('autoria__autor', 0), - (Button('pesquisar', - 'Pesquisar Autor', - css_class='btn btn-primary btn-sm'), 2), - (Button('limpar', - 'Limpar Autor', - css_class='btn btn-primary btn-sm'), 2), - ('autoria__primeiro_autor', 2), - ('autoria__autor__tipo', 3), - ('autoria__autor__parlamentar_set__filiacao__partido', 3) - ]) - row6 = to_row( - [('relatoria__parlamentar_id', 6), - ('em_tramitacao', 6)]) + [ + ("numero", 3), + ("numeracao__numero_materia", 3), + ("numero_protocolo", 3), + ("ano", 3), + ] + ) + row3 = to_row([("data_apresentacao", 6), ("data_publicacao", 6)]) + row4 = to_row( + [ + ("autoria__autor", 0), + ( + Button( + "pesquisar", + "Pesquisar Autor", + css_class="btn btn-primary btn-sm", + ), + 2, + ), + ( + Button( + "limpar", "Limpar Autor", css_class="btn btn-primary btn-sm" + ), + 2, + ), + ("autoria__primeiro_autor", 2), + ("autoria__autor__tipo", 3), + ("autoria__autor__parlamentar_set__filiacao__partido", 3), + ] + ) + row6 = to_row([("relatoria__parlamentar_id", 6), ("em_tramitacao", 6)]) row7 = to_row( - [('tramitacao__unidade_tramitacao_destino', 6), - ('tramitacao__status', 6), - ]) + [ + ("tramitacao__unidade_tramitacao_destino", 6), + ("tramitacao__status", 6), + ] + ) row9 = to_row( - [('materiaassunto__assunto', 4), ('indexacao', 4), ('regime_tramitacao', 4)]) + [("materiaassunto__assunto", 4), ("indexacao", 4), ("regime_tramitacao", 4)] + ) + + row8 = to_row([("o", 8), ("tipo_listagem", 4)]) - row8 = to_row( + row10 = to_row( [ - ('o', 8), - ('tipo_listagem', 4) - ]) - - row10 = to_row([ - ('tipo_origem_externa', 4), - ('numero_origem_externa', 4), - ('ano_origem_externa', 4), - ]) - row11 = to_row([ - ('data_origem_externa', 8), - ('local_origem_externa', 4) - ]) + ("tipo_origem_externa", 4), + ("numero_origem_externa", 4), + ("ano_origem_externa", 4), + ] + ) + row11 = to_row([("data_origem_externa", 8), ("local_origem_externa", 4)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( Div( - Fieldset(_('Pesquisa Básica'), - row1, row2, - HTML(autor_label), - HTML(autor_modal), - row4, - ), - Button('btn_pesquisa_avancada', 'Pesquisa Avançada >>>', - css_id='btn_pesquisa_avancada_id', - css_class='btn btn-dark', - onClick="pesquisaAvancada()", - style='margin-bottom: 2vh;font-weight: bold' - ), - Fieldset(_('Como listar os resultados da pesquisa'), - row8, - css_class='pesquisa_avancada', - style='display: none;', - ), - Fieldset(_('Origem externa'), - row10, row11, - css_class='pesquisa_avancada', - style='display: none;', - ), - Fieldset(_('Mais Opções de Pesquisa...'), - row3, - row6, row7, row9, - css_class='pesquisa_avancada', - style='display: none;' - ), - form_actions(label=_('Pesquisar')), - ) - ) + Fieldset( + _("Pesquisa Básica"), + row1, + row2, + HTML(autor_label), + HTML(autor_modal), + row4, + ), + Button( + "btn_pesquisa_avancada", + "Pesquisa Avançada >>>", + css_id="btn_pesquisa_avancada_id", + css_class="btn btn-dark", + onClick="pesquisaAvancada()", + style="margin-bottom: 2vh;font-weight: bold", + ), + Fieldset( + _("Como listar os resultados da pesquisa"), + row8, + css_class="pesquisa_avancada", + style="display: none;", + ), + Fieldset( + _("Origem externa"), + row10, + row11, + css_class="pesquisa_avancada", + style="display: none;", + ), + Fieldset( + _("Mais Opções de Pesquisa..."), + row3, + row6, + row7, + row9, + css_class="pesquisa_avancada", + style="display: none;", + ), + form_actions(label=_("Pesquisar")), + ) + ) @property def qs(self): qs = qs_override_django_filter(self) - if hasattr(self.form, 'cleaned_data') and self.form.cleaned_data[ - 'autoria__autor__parlamentar_set__filiacao__partido']: - - q_data_inicio_e_fim = Q(data_apresentacao__gte=F( - 'autoria__autor__parlamentar_set__filiacao__data'), + if ( + hasattr(self.form, "cleaned_data") + and self.form.cleaned_data[ + "autoria__autor__parlamentar_set__filiacao__partido" + ] + ): + q_data_inicio_e_fim = Q( + data_apresentacao__gte=F( + "autoria__autor__parlamentar_set__filiacao__data" + ), data_apresentacao__lte=F( - 'autoria__autor__parlamentar_set__filiacao__data_desfiliacao')) + "autoria__autor__parlamentar_set__filiacao__data_desfiliacao" + ), + ) q_data_inicio = Q( data_apresentacao__gte=F( - 'autoria__autor__parlamentar_set__filiacao__data'), - autoria__autor__parlamentar_set__filiacao__data_desfiliacao__isnull=True + "autoria__autor__parlamentar_set__filiacao__data" + ), + autoria__autor__parlamentar_set__filiacao__data_desfiliacao__isnull=True, ) - qs = qs.filter( - q_data_inicio_e_fim | q_data_inicio - ) + qs = qs.filter(q_data_inicio_e_fim | q_data_inicio) return qs def pega_ultima_tramitacao(): - return Tramitacao.objects.values( - 'materia_id').annotate(data_encaminhamento=Max( - 'data_encaminhamento'), - id=Max('id')).values_list('id', flat=True) + return ( + Tramitacao.objects.values("materia_id") + .annotate(data_encaminhamento=Max("data_encaminhamento"), id=Max("id")) + .values_list("id", flat=True) + ) def filtra_tramitacao_status(status): lista = pega_ultima_tramitacao() - return Tramitacao.objects.filter( - id__in=lista, - status=status).distinct().values_list('materia_id', flat=True) + return ( + Tramitacao.objects.filter(id__in=lista, status=status) + .distinct() + .values_list("materia_id", flat=True) + ) def filtra_tramitacao_destino(destino): lista = pega_ultima_tramitacao() - return Tramitacao.objects.filter( - id__in=lista, - unidade_tramitacao_destino=destino).distinct().values_list( - 'materia_id', flat=True) + return ( + Tramitacao.objects.filter(id__in=lista, unidade_tramitacao_destino=destino) + .distinct() + .values_list("materia_id", flat=True) + ) def filtra_tramitacao_destino_and_status(status, destino): lista = pega_ultima_tramitacao() - return Tramitacao.objects.filter( - id__in=lista, - status=status, - unidade_tramitacao_destino=destino).distinct().values_list( - 'materia_id', flat=True) + return ( + Tramitacao.objects.filter( + id__in=lista, status=status, unidade_tramitacao_destino=destino + ) + .distinct() + .values_list("materia_id", flat=True) + ) class DespachoInicialCreateForm(forms.Form): comissao = forms.ModelMultipleChoiceField( queryset=Comissao.objects.filter(ativa=True), widget=forms.CheckboxSelectMultiple(), - label=Comissao._meta.verbose_name_plural) + label=Comissao._meta.verbose_name_plural, + ) def __init__(self, *args, **kwargs): row1 = to_row( - [('comissao', 12), ]) + [ + ("comissao", 12), + ] + ) self.helper = SaplFormHelper() - self.helper.form_method = 'POST' + self.helper.form_method = "POST" self.helper.layout = SaplFormLayout(row1) super().__init__(*args, **kwargs) def clean(self): super().clean() - comissoes = self.cleaned_data.get('comissao') + comissoes = self.cleaned_data.get("comissao") if not comissoes: - msg = _('Você deve escolher pelo menos uma comissão.') + msg = _("Você deve escolher pelo menos uma comissão.") raise ValidationError(msg) if not self.is_valid(): @@ -1239,11 +1403,10 @@ class DespachoInicialCreateForm(forms.Form): errors = [] for comissao in comissoes: if DespachoInicial.objects.filter( - materia=self.initial['materia'], + materia=self.initial["materia"], comissao=comissao, ).exists(): - msg = _('Já existe um Despacho cadastrado para %s' % - comissao) + msg = _("Já existe um Despacho cadastrado para %s" % comissao) errors.append(msg) if errors: raise ValidationError(errors) @@ -1253,11 +1416,12 @@ class DespachoInicialCreateForm(forms.Form): class DespachoInicialForm(ModelForm): comissao = forms.ModelChoiceField( - queryset=Comissao.objects.filter(ativa=True), label=_('Comissão')) + queryset=Comissao.objects.filter(ativa=True), label=_("Comissão") + ) class Meta: model = DespachoInicial - fields = ['comissao'] + fields = ["comissao"] def clean(self): super(DespachoInicialForm, self).clean() @@ -1265,54 +1429,59 @@ class DespachoInicialForm(ModelForm): if not self.is_valid(): return self.cleaned_data - if DespachoInicial.objects.filter( - materia=self.instance.materia, - comissao=self.cleaned_data['comissao'], - ).exclude(pk=self.instance.pk).exists(): - msg = _('Já existe um Despacho cadastrado para %s' % - self.cleaned_data['comissao']) + if ( + DespachoInicial.objects.filter( + materia=self.instance.materia, + comissao=self.cleaned_data["comissao"], + ) + .exclude(pk=self.instance.pk) + .exists() + ): + msg = _( + "Já existe um Despacho cadastrado para %s" + % self.cleaned_data["comissao"] + ) raise ValidationError(msg) return self.cleaned_data class AutoriaForm(ModelForm): + tipo_autor = ModelChoiceField( + label=_("Tipo Autor"), + required=True, + queryset=TipoAutor.objects.all(), + empty_label=_("Selecione"), + ) - tipo_autor = ModelChoiceField(label=_('Tipo Autor'), - required=True, - queryset=TipoAutor.objects.all(), - empty_label=_('Selecione'),) - - data_relativa = forms.DateField( - widget=forms.HiddenInput(), required=False) + data_relativa = forms.DateField(widget=forms.HiddenInput(), required=False) logger = logging.getLogger(__name__) def __init__(self, *args, **kwargs): super(AutoriaForm, self).__init__(*args, **kwargs) - self.fields['primeiro_autor'].required = True + self.fields["primeiro_autor"].required = True - if 'initial' in kwargs and 'materia' in kwargs['initial']: - materia = kwargs['initial']['materia'] - self.fields['primeiro_autor'].initial = Autoria.objects.filter( - materia=materia).count() == 0 + if "initial" in kwargs and "materia" in kwargs["initial"]: + materia = kwargs["initial"]["materia"] + self.fields["primeiro_autor"].initial = ( + Autoria.objects.filter(materia=materia).count() == 0 + ) - row1 = to_row([('tipo_autor', 4), - ('autor', 4), - ('primeiro_autor', 4)]) + row1 = to_row([("tipo_autor", 4), ("autor", 4), ("primeiro_autor", 4)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset(_('Autoria'), - row1, 'data_relativa', form_actions(label='Salvar'))) + Fieldset(_("Autoria"), row1, "data_relativa", form_actions(label="Salvar")) + ) - if not kwargs['instance']: - self.fields['autor'].choices = [] + if not kwargs["instance"]: + self.fields["autor"].choices = [] class Meta: model = Autoria - fields = ['tipo_autor', 'autor', 'primeiro_autor', 'data_relativa'] + fields = ["tipo_autor", "autor", "primeiro_autor", "data_relativa"] def clean(self): cd = super(AutoriaForm, self).clean() @@ -1321,198 +1490,214 @@ class AutoriaForm(ModelForm): return self.cleaned_data autorias = Autoria.objects.filter( - materia=self.instance.materia, autor=cd['autor']) + materia=self.instance.materia, autor=cd["autor"] + ) pk = self.instance.pk - if ((not pk and autorias.exists()) or - (pk and autorias.exclude(pk=pk).exists())): - self.logger.error( - "Esse Autor (pk={}) já foi cadastrado.".format(pk)) - raise ValidationError(_('Esse Autor já foi cadastrado.')) + if (not pk and autorias.exists()) or (pk and autorias.exclude(pk=pk).exists()): + self.logger.error("Esse Autor (pk={}) já foi cadastrado.".format(pk)) + raise ValidationError(_("Esse Autor já foi cadastrado.")) return cd class AutoriaMultiCreateForm(Form): - logger = logging.getLogger(__name__) - tipo_autor = ModelChoiceField(label=_('Tipo Autor'), - required=True, - queryset=TipoAutor.objects.all(), - empty_label=_('Selecione'),) + tipo_autor = ModelChoiceField( + label=_("Tipo Autor"), + required=True, + queryset=TipoAutor.objects.all(), + empty_label=_("Selecione"), + ) - data_relativa = forms.DateField( - widget=forms.HiddenInput(), required=False) + data_relativa = forms.DateField(widget=forms.HiddenInput(), required=False) autor = ModelMultipleChoiceField( queryset=Autor.objects.all(), - label=_('Possiveis Autores'), + label=_("Possiveis Autores"), required=True, - widget=CheckboxSelectMultiple) + widget=CheckboxSelectMultiple, + ) autores = ModelMultipleChoiceField( - queryset=Autor.objects.all(), - required=False, - widget=HiddenInput) + queryset=Autor.objects.all(), required=False, widget=HiddenInput + ) primeiro_autor = forms.ChoiceField( - required=True, - choices=YES_NO_CHOICES, - label="Primeiro Autor?" + required=True, choices=YES_NO_CHOICES, label="Primeiro Autor?" ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if 'initial' in kwargs and 'autores' in kwargs['initial']: - self.fields['primeiro_autor'].initial = kwargs['initial']['autores'].count( - ) == 0 + if "initial" in kwargs and "autores" in kwargs["initial"]: + self.fields["primeiro_autor"].initial = ( + kwargs["initial"]["autores"].count() == 0 + ) - row1 = to_row([('tipo_autor', 10), ('primeiro_autor', 2)]) + row1 = to_row([("tipo_autor", 10), ("primeiro_autor", 2)]) - row2 = to_row([('autor', 12), ]) + row2 = to_row( + [ + ("autor", 12), + ] + ) self.helper = SaplFormHelper() self.helper.layout = Layout( Fieldset( - _('Autorias'), row1, row2, 'data_relativa', 'autores', - form_actions(label='Incluir Autores Selecionados'))) + _("Autorias"), + row1, + row2, + "data_relativa", + "autores", + form_actions(label="Incluir Autores Selecionados"), + ) + ) - self.fields['autor'].choices = [] + self.fields["autor"].choices = [] def clean(self): cd = super().clean() - if 'autores' in self.errors: - del self.errors['autores'] + if "autores" in self.errors: + del self.errors["autores"] - if 'autor' not in cd or not cd['autor'].exists(): - self.logger.error( - "Ao menos um autor deve ser selecionado para inclusão") + if "autor" not in cd or not cd["autor"].exists(): + self.logger.error("Ao menos um autor deve ser selecionado para inclusão") raise ValidationError( - _('Ao menos um autor deve ser selecionado para inclusão')) + _("Ao menos um autor deve ser selecionado para inclusão") + ) return cd class AcessorioEmLoteFilterSet(django_filters.FilterSet): - class Meta(FilterOverridesMetaMixin): model = MateriaLegislativa - fields = ['tipo', 'data_apresentacao'] + fields = ["tipo", "data_apresentacao"] def __init__(self, *args, **kwargs): super(AcessorioEmLoteFilterSet, self).__init__(*args, **kwargs) - self.filters['tipo'].label = 'Tipo de Matéria' - self.filters['data_apresentacao'].label = 'Data (Inicial - Final)' - self.form.fields['tipo'].required = True - self.form.fields['data_apresentacao'].required = True + self.filters["tipo"].label = "Tipo de Matéria" + self.filters["data_apresentacao"].label = "Data (Inicial - Final)" + self.form.fields["tipo"].required = True + self.form.fields["data_apresentacao"].required = True - row1 = to_row([('tipo', 12)]) - row2 = to_row([('data_apresentacao', 12)]) + row1 = to_row([("tipo", 12)]) + row2 = to_row([("data_apresentacao", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Documentos Acessórios em Lote'), - row1, row2, form_actions(label='Pesquisar'))) + Fieldset( + _("Documentos Acessórios em Lote"), + row1, + row2, + form_actions(label="Pesquisar"), + ) + ) class AnexadaEmLoteFilterSet(django_filters.FilterSet): - class Meta(FilterOverridesMetaMixin): model = MateriaLegislativa - fields = ['tipo', 'data_apresentacao'] + fields = ["tipo", "data_apresentacao"] def __init__(self, *args, **kwargs): super(AnexadaEmLoteFilterSet, self).__init__(*args, **kwargs) - self.filters['tipo'].label = 'Tipo de Matéria' - self.filters['data_apresentacao'].label = 'Data (Inicial - Final)' + self.filters["tipo"].label = "Tipo de Matéria" + self.filters["data_apresentacao"].label = "Data (Inicial - Final)" - self.form.fields['tipo'].required = True - self.form.fields['data_apresentacao'].required = True + self.form.fields["tipo"].required = True + self.form.fields["data_apresentacao"].required = True - row1 = to_row([('tipo', 12)]) - row2 = to_row([('data_apresentacao', 12)]) + row1 = to_row([("tipo", 12)]) + row2 = to_row([("data_apresentacao", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Matérias'), - row1, row2, form_actions(label='Pesquisar'))) + Fieldset( + _("Pesquisa de Matérias"), row1, row2, form_actions(label="Pesquisar") + ) + ) class PrimeiraTramitacaoEmLoteFilterSet(django_filters.FilterSet): - class Meta(FilterOverridesMetaMixin): model = MateriaLegislativa - fields = ['tipo', 'data_apresentacao'] + fields = ["tipo", "data_apresentacao"] def __init__(self, *args, **kwargs): - super(PrimeiraTramitacaoEmLoteFilterSet, self).__init__( - *args, **kwargs) + super(PrimeiraTramitacaoEmLoteFilterSet, self).__init__(*args, **kwargs) - self.filters['tipo'].label = 'Tipo de Matéria' - self.filters['data_apresentacao'].label = 'Data (Inicial - Final)' - self.form.fields['tipo'].required = True - self.form.fields['data_apresentacao'].required = False + self.filters["tipo"].label = "Tipo de Matéria" + self.filters["data_apresentacao"].label = "Data (Inicial - Final)" + self.form.fields["tipo"].required = True + self.form.fields["data_apresentacao"].required = False - row1 = to_row([('tipo', 12)]) - row2 = to_row([('data_apresentacao', 12)]) + row1 = to_row([("tipo", 12)]) + row2 = to_row([("data_apresentacao", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Primeira Tramitação'), - row1, row2, form_actions(label='Pesquisar'))) + Fieldset( + _("Primeira Tramitação"), row1, row2, form_actions(label="Pesquisar") + ) + ) class TramitacaoEmLoteFilterSet(django_filters.FilterSet): - class Meta(FilterOverridesMetaMixin): model = MateriaLegislativa - fields = ['tipo', 'data_apresentacao', 'tramitacao__status', - 'tramitacao__unidade_tramitacao_destino'] + fields = [ + "tipo", + "data_apresentacao", + "tramitacao__status", + "tramitacao__unidade_tramitacao_destino", + ] def __init__(self, *args, **kwargs): - super(TramitacaoEmLoteFilterSet, self).__init__( - *args, **kwargs) - - self.filters['tipo'].label = _('Tipo de Matéria') - self.filters['data_apresentacao'].label = _('Data (Inicial - Final)') - self.filters['tramitacao__unidade_tramitacao_destino' - ].label = _('Unidade Destino (Último Destino)') - self.filters['tramitacao__status'].label = _('Status') - self.form.fields['tipo'].required = True - self.form.fields['data_apresentacao'].required = False - self.form.fields['tramitacao__status'].required = True - self.form.fields[ - 'tramitacao__unidade_tramitacao_destino'].required = True - - row1 = to_row([ - ('tipo', 4), - ('tramitacao__unidade_tramitacao_destino', 4), - ('tramitacao__status', 4)]) - row2 = to_row([('data_apresentacao', 12)]) + super(TramitacaoEmLoteFilterSet, self).__init__(*args, **kwargs) + + self.filters["tipo"].label = _("Tipo de Matéria") + self.filters["data_apresentacao"].label = _("Data (Inicial - Final)") + self.filters["tramitacao__unidade_tramitacao_destino"].label = _( + "Unidade Destino (Último Destino)" + ) + self.filters["tramitacao__status"].label = _("Status") + self.form.fields["tipo"].required = True + self.form.fields["data_apresentacao"].required = False + self.form.fields["tramitacao__status"].required = True + self.form.fields["tramitacao__unidade_tramitacao_destino"].required = True + + row1 = to_row( + [ + ("tipo", 4), + ("tramitacao__unidade_tramitacao_destino", 4), + ("tramitacao__status", 4), + ] + ) + row2 = to_row([("data_apresentacao", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Tramitação em Lote'), - row1, row2, form_actions(label=_('Pesquisar')))) + Fieldset( + _("Tramitação em Lote"), row1, row2, form_actions(label=_("Pesquisar")) + ) + ) class TipoProposicaoForm(ModelForm): - try: content_types_choices = [ - ( - f'{ct.app_label}/{ct.model}', - ct - ) + (f"{ct.app_label}/{ct.model}", ct) for k, ct in ContentType.objects.get_for_models( *models_with_gr_for_model(TipoProposicao) ).items() @@ -1524,55 +1709,58 @@ class TipoProposicaoForm(ModelForm): content_type = forms.ChoiceField( choices=content_types_choices, - label=TipoProposicao._meta.get_field('content_type').verbose_name, + label=TipoProposicao._meta.get_field("content_type").verbose_name, required=True, - help_text=TipoProposicao._meta.get_field('content_type').help_text) + help_text=TipoProposicao._meta.get_field("content_type").help_text, + ) tipo_conteudo_related_radio = ChoiceWithoutValidationField( - label="Seleção de Tipo", - required=False, - widget=forms.RadioSelect()) + label="Seleção de Tipo", required=False, widget=forms.RadioSelect() + ) tipo_conteudo_related = forms.IntegerField( - widget=forms.HiddenInput(), - required=True) + widget=forms.HiddenInput(), required=True + ) class Meta: model = TipoProposicao - fields = ['descricao', - 'content_type', - 'tipo_conteudo_related_radio', - 'tipo_conteudo_related', - 'perfis'] + fields = [ + "descricao", + "content_type", + "tipo_conteudo_related_radio", + "tipo_conteudo_related", + "perfis", + ] - widgets = {'tipo_conteudo_related': forms.HiddenInput(), - 'perfis': widgets.CheckboxSelectMultiple()} + widgets = { + "tipo_conteudo_related": forms.HiddenInput(), + "perfis": widgets.CheckboxSelectMultiple(), + } def __init__(self, *args, **kwargs): - tipo_select = Fieldset( TipoProposicao._meta.verbose_name, Row( to_column( ( Row( - to_column(('descricao', 12)), - to_column(('perfis', 12)), + to_column(("descricao", 12)), + to_column(("perfis", 12)), ), - 5 + 5, ) ), to_column( ( Row( - to_column(('content_type', 12)), - to_column(('tipo_conteudo_related_radio', 12)), - to_column(('tipo_conteudo_related', 12)), + to_column(("content_type", 12)), + to_column(("tipo_conteudo_related_radio", 12)), + to_column(("tipo_conteudo_related", 12)), ), - 7 + 7, ) ), - ) + ), ) self.helper = SaplFormHelper() @@ -1588,30 +1776,33 @@ class TipoProposicaoForm(ModelForm): cd = self.cleaned_data - content_type = cd['content_type'].split('/') + content_type = cd["content_type"].split("/") content_type = ContentType.objects.filter( - app_label=content_type[0], - model=content_type[1]).first() - cd['content_type'] = content_type + app_label=content_type[0], model=content_type[1] + ).first() + cd["content_type"] = content_type if not content_type: self.logger.error("Meta Tipo Inexistente") - raise ValidationError( - _('Meta Tipo Inexistente.')) + raise ValidationError(_("Meta Tipo Inexistente.")) - if 'tipo_conteudo_related' not in cd or not cd[ - 'tipo_conteudo_related']: + if "tipo_conteudo_related" not in cd or not cd["tipo_conteudo_related"]: self.logger.error("Seleção de Tipo não definida.") - raise ValidationError( - _('Seleção de Tipo não definida.')) + raise ValidationError(_("Seleção de Tipo não definida.")) - if not content_type.model_class().objects.filter( - pk=cd['tipo_conteudo_related']).exists(): - self.logger.error("O Registro definido (%s) não está na base de %s." - % (cd['tipo_conteudo_related'], content_type)) + if ( + not content_type.model_class() + .objects.filter(pk=cd["tipo_conteudo_related"]) + .exists() + ): + self.logger.error( + "O Registro definido (%s) não está na base de %s." + % (cd["tipo_conteudo_related"], content_type) + ) raise ValidationError( - _('O Registro definido (%s) não está na base de %s.' - ) % (cd['tipo_conteudo_related'], content_type)) + _("O Registro definido (%s) não está na base de %s.") + % (cd["tipo_conteudo_related"], content_type) + ) """ A unicidade de tipo proposição para tipo de conteudo @@ -1639,26 +1830,29 @@ class TipoProposicaoForm(ModelForm): @transaction.atomic def save(self, commit=False): - tipo_proposicao = self.instance assert tipo_proposicao.content_type - tipo_proposicao.tipo_conteudo_related = \ - tipo_proposicao.content_type.model_class( - ).objects.get(pk=self.cleaned_data['tipo_conteudo_related']) + tipo_proposicao.tipo_conteudo_related = ( + tipo_proposicao.content_type.model_class().objects.get( + pk=self.cleaned_data["tipo_conteudo_related"] + ) + ) return super().save(True) class TipoProposicaoSelect(Select): - - def create_option(self, name, value, label, selected, index, subindex=None, attrs=None): - option = super().create_option(name, value, label, selected, - index, subindex=subindex, attrs=attrs) + def create_option( + self, name, value, label, selected, index, subindex=None, attrs=None + ): + option = super().create_option( + name, value, label, selected, index, subindex=subindex, attrs=attrs + ) if value: tipo = TipoProposicao.objects.get(id=value) - option['attrs']['data-has-perfil'] = str(tipo.perfis.exists()) + option["attrs"]["data-has-perfil"] = str(tipo.perfis.exists()) return option @@ -1668,55 +1862,52 @@ class TramitacaoEmLoteForm(ModelForm): class Meta: model = Tramitacao - fields = ['data_tramitacao', - 'unidade_tramitacao_local', - 'status', - 'urgente', - 'turno', - 'unidade_tramitacao_destino', - 'data_encaminhamento', - 'data_fim_prazo', - 'texto', - 'user', - 'ip', - 'ultima_edicao'] - - widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput()} + fields = [ + "data_tramitacao", + "unidade_tramitacao_local", + "status", + "urgente", + "turno", + "unidade_tramitacao_destino", + "data_encaminhamento", + "data_fim_prazo", + "texto", + "user", + "ip", + "ultima_edicao", + ] + + widgets = { + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), + } def __init__(self, *args, **kwargs): super(TramitacaoEmLoteForm, self).__init__(*args, **kwargs) - self.fields['data_tramitacao'].initial = timezone.now().date() + self.fields["data_tramitacao"].initial = timezone.now().date() ust = UnidadeTramitacao.objects.select_related().all() - unidade_tramitacao_destino = [('', '---------')] + [(ut.pk, ut) - for ut in ust if ut.comissao and ut.comissao.ativa] - unidade_tramitacao_destino.extend( - [(ut.pk, ut) for ut in ust if ut.orgao]) - unidade_tramitacao_destino.extend( - [(ut.pk, ut) for ut in ust if ut.parlamentar]) - self.fields['unidade_tramitacao_destino'].choices = unidade_tramitacao_destino - self.fields['urgente'].label = "Urgente? *" - - row1 = to_row([ - ('data_tramitacao', 4), - ('data_encaminhamento', 4), - ('data_fim_prazo', 4) - ]) - row2 = to_row([ - ('unidade_tramitacao_local', 6), - ('unidade_tramitacao_destino', 6), - ]) - row3 = to_row([ - ('status', 4), - ('urgente', 4), - ('turno', 4) - ]) - row4 = to_row([ - ('texto', 12) - ]) - - documentos_checkbox_HTML = r''' + unidade_tramitacao_destino = [("", "---------")] + [ + (ut.pk, ut) for ut in ust if ut.comissao and ut.comissao.ativa + ] + unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.orgao]) + unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.parlamentar]) + self.fields["unidade_tramitacao_destino"].choices = unidade_tramitacao_destino + self.fields["urgente"].label = "Urgente? *" + + row1 = to_row( + [("data_tramitacao", 4), ("data_encaminhamento", 4), ("data_fim_prazo", 4)] + ) + row2 = to_row( + [ + ("unidade_tramitacao_local", 6), + ("unidade_tramitacao_destino", 6), + ] + ) + row3 = to_row([("status", 4), ("urgente", 4), ("turno", 4)]) + row4 = to_row([("texto", 12)]) + + documentos_checkbox_HTML = r"""
        Selecione as matérias para tramitação: @@ -1745,15 +1936,18 @@ class TramitacaoEmLoteForm(ModelForm):
        - ''' + """ self.helper = SaplFormHelper() self.helper.layout = Layout( Fieldset( - 'Detalhes da tramitação:', - row1, row2, row3, row4, + "Detalhes da tramitação:", + row1, + row2, + row3, + row4, HTML(documentos_checkbox_HTML), - form_actions(label='Salvar') + form_actions(label="Salvar"), ) ) @@ -1763,39 +1957,49 @@ class TramitacaoEmLoteForm(ModelForm): if not self.is_valid(): return self.cleaned_data - if 'data_encaminhamento' in cleaned_data: - data_enc_form = cleaned_data['data_encaminhamento'] - if 'data_fim_prazo' in cleaned_data: - data_prazo_form = cleaned_data['data_fim_prazo'] - if 'data_tramitacao' in cleaned_data: - data_tram_form = cleaned_data['data_tramitacao'] + if "data_encaminhamento" in cleaned_data: + data_enc_form = cleaned_data["data_encaminhamento"] + if "data_fim_prazo" in cleaned_data: + data_prazo_form = cleaned_data["data_fim_prazo"] + if "data_tramitacao" in cleaned_data: + data_tram_form = cleaned_data["data_tramitacao"] if not self.instance.data_tramitacao: - - if cleaned_data['data_tramitacao'] > timezone.now().date(): - self.logger.error('A data de tramitação ({}) deve ser ' - 'menor ou igual a data de hoje ({})!' - .format(cleaned_data['data_tramitacao'], timezone.now().date())) + if cleaned_data["data_tramitacao"] > timezone.now().date(): + self.logger.error( + "A data de tramitação ({}) deve ser " + "menor ou igual a data de hoje ({})!".format( + cleaned_data["data_tramitacao"], timezone.now().date() + ) + ) msg = _( - 'A data de tramitação deve ser ' + - 'menor ou igual a data de hoje!') + "A data de tramitação deve ser " + "menor ou igual a data de hoje!" + ) raise ValidationError(msg) if data_enc_form: if data_enc_form < data_tram_form: - self.logger.warning('A data de encaminhamento ({}) deve ser maior que a data de tramitação ({})!' - .format(data_enc_form, data_tram_form)) + 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!') + "A data de encaminhamento deve ser maior que a data de tramitação!" + ) raise ValidationError(msg) if data_prazo_form: if data_prazo_form < data_tram_form: - self.logger.error('A data fim de prazo ({}) deve ser ' - 'maior que a data de tramitação ({})!' - .format(data_prazo_form, data_tram_form)) - msg = _('A data fim de prazo deve ser ' + - 'maior que a data de tramitação!') + self.logger.error( + "A data fim de prazo ({}) deve ser " + "maior que a data de tramitação ({})!".format( + data_prazo_form, data_tram_form + ) + ) + msg = _( + "A data fim de prazo deve ser " + "maior que a data de tramitação!" + ) raise ValidationError(msg) return cleaned_data @@ -1804,28 +2008,30 @@ class TramitacaoEmLoteForm(ModelForm): def save(self, commit=True): cd = self.cleaned_data - materias = self.initial['materias'] - user = self.initial['user'] if 'user' in self.initial else None - ip = self.initial['ip'] if 'ip' in self.initial else '' - ultima_edicao = self.initial['ultima_edicao'] if 'ultima_edicao' in self.initial else '' + materias = self.initial["materias"] + user = self.initial["user"] if "user" in self.initial else None + ip = self.initial["ip"] if "ip" in self.initial else "" + ultima_edicao = ( + self.initial["ultima_edicao"] if "ultima_edicao" in self.initial else "" + ) - tramitar_anexadas = BaseAppConfig.attr('tramitacao_materia') + tramitar_anexadas = BaseAppConfig.attr("tramitacao_materia") for mat_id in materias: mat = MateriaLegislativa.objects.get(id=mat_id) tramitacao = Tramitacao.objects.create( - status=cd['status'], + status=cd["status"], materia=mat, - data_tramitacao=cd['data_tramitacao'], - unidade_tramitacao_local=cd['unidade_tramitacao_local'], - unidade_tramitacao_destino=cd['unidade_tramitacao_destino'], - data_encaminhamento=cd['data_encaminhamento'], - urgente=cd['urgente'], - turno=cd['turno'], - texto=cd['texto'], - data_fim_prazo=cd['data_fim_prazo'], + data_tramitacao=cd["data_tramitacao"], + unidade_tramitacao_local=cd["unidade_tramitacao_local"], + unidade_tramitacao_destino=cd["unidade_tramitacao_destino"], + data_encaminhamento=cd["data_encaminhamento"], + urgente=cd["urgente"], + turno=cd["turno"], + texto=cd["texto"], + data_fim_prazo=cd["data_fim_prazo"], user=user, ip=ip, - ultima_edicao=ultima_edicao + ultima_edicao=ultima_edicao, ) mat.em_tramitacao = False if tramitacao.status.indicador == "F" else True mat.save() @@ -1834,26 +2040,34 @@ class TramitacaoEmLoteForm(ModelForm): lista_tramitacao = [] anexadas = lista_anexados(mat) for ml in anexadas: - if not ml.tramitacao_set.order_by('-data_tramitacao', '-id').all() or \ - ml.tramitacao_set.order_by('-data_tramitacao', '-id').first().unidade_tramitacao_destino \ - == tramitacao.unidade_tramitacao_local: - ml.em_tramitacao = False if tramitacao.status.indicador == "F" else True + if ( + not ml.tramitacao_set.order_by("-data_tramitacao", "-id").all() + or ml.tramitacao_set.order_by("-data_tramitacao", "-id") + .first() + .unidade_tramitacao_destino + == tramitacao.unidade_tramitacao_local + ): + ml.em_tramitacao = ( + False if tramitacao.status.indicador == "F" else True + ) ml.save() - lista_tramitacao.append(Tramitacao( - status=tramitacao.status, - materia=ml, - data_tramitacao=tramitacao.data_tramitacao, - unidade_tramitacao_local=tramitacao.unidade_tramitacao_local, - data_encaminhamento=tramitacao.data_encaminhamento, - unidade_tramitacao_destino=tramitacao.unidade_tramitacao_destino, - urgente=tramitacao.urgente, - turno=tramitacao.turno, - texto=tramitacao.texto, - data_fim_prazo=tramitacao.data_fim_prazo, - user=tramitacao.user, - ip=tramitacao.ip, - ultima_edicao=tramitacao.ultima_edicao - )) + lista_tramitacao.append( + Tramitacao( + status=tramitacao.status, + materia=ml, + data_tramitacao=tramitacao.data_tramitacao, + unidade_tramitacao_local=tramitacao.unidade_tramitacao_local, + data_encaminhamento=tramitacao.data_encaminhamento, + unidade_tramitacao_destino=tramitacao.unidade_tramitacao_destino, + urgente=tramitacao.urgente, + turno=tramitacao.turno, + texto=tramitacao.texto, + data_fim_prazo=tramitacao.data_fim_prazo, + user=tramitacao.user, + ip=tramitacao.ip, + ultima_edicao=tramitacao.ultima_edicao, + ) + ) # TODO: BULK UPDATE não envia Signal para Tramitacao Tramitacao.objects.bulk_create(lista_tramitacao) @@ -1861,120 +2075,135 @@ class TramitacaoEmLoteForm(ModelForm): class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm): - logger = logging.getLogger(__name__) - TIPO_TEXTO_CHOICE = [ - ('D', _('Arquivo Digital')), - ('T', _('Texto Articulado')) - ] + TIPO_TEXTO_CHOICE = [("D", _("Arquivo Digital")), ("T", _("Texto Articulado"))] tipo_materia = forms.ModelChoiceField( label=TipoMateriaLegislativa._meta.verbose_name, required=False, queryset=TipoMateriaLegislativa.objects.all(), - empty_label='Selecione') + empty_label="Selecione", + ) - numero_materia = forms.CharField( - label='Número', required=False) + numero_materia = forms.CharField(label="Número", required=False) - ano_materia = forms.CharField( - label='Ano', required=False) + ano_materia = forms.CharField(label="Ano", required=False) tipo_texto = forms.ChoiceField( - label=_('Tipo do Texto da Proposição'), + label=_("Tipo do Texto da Proposição"), required=False, choices=TIPO_TEXTO_CHOICE, - widget=widgets.RadioSelect()) + widget=widgets.RadioSelect(), + ) materia_de_vinculo = forms.ModelChoiceField( queryset=MateriaLegislativa.objects.all(), widget=widgets.HiddenInput(), - required=False) + required=False, + ) receber_recibo = forms.TypedChoiceField( - choices=YES_NO_CHOICES, - widget=widgets.HiddenInput(), - required=False) + choices=YES_NO_CHOICES, widget=widgets.HiddenInput(), required=False + ) numero_materia_futuro = forms.IntegerField( - label='Número (Opcional)', required=False) + label="Número (Opcional)", required=False + ) class Meta: model = Proposicao - fields = ['tipo', - 'receber_recibo', - 'descricao', - 'observacao', - 'texto_original', - 'materia_de_vinculo', - 'tipo_materia', - 'numero_materia', - 'ano_materia', - 'tipo_texto', - 'hash_code', - 'numero_materia_futuro', - 'user', - 'ip', - 'ultima_edicao'] + fields = [ + "tipo", + "receber_recibo", + "descricao", + "observacao", + "texto_original", + "materia_de_vinculo", + "tipo_materia", + "numero_materia", + "ano_materia", + "tipo_texto", + "hash_code", + "numero_materia_futuro", + "user", + "ip", + "ultima_edicao", + ] widgets = { - 'descricao': widgets.Textarea(attrs={'rows': 4}), - 'tipo': TipoProposicaoSelect(), - 'hash_code': forms.HiddenInput(), - 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput() + "descricao": widgets.Textarea(attrs={"rows": 4}), + "tipo": TipoProposicaoSelect(), + "hash_code": forms.HiddenInput(), + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), } def __init__(self, *args, **kwargs): self.texto_articulado_proposicao = BaseAppConfig.attr( - 'texto_articulado_proposicao') + "texto_articulado_proposicao" + ) - self.receber_recibo = BaseAppConfig.attr( - 'receber_recibo_proposicao') + self.receber_recibo = BaseAppConfig.attr("receber_recibo_proposicao") if not self.texto_articulado_proposicao: - if 'tipo_texto' in self._meta.fields: - self._meta.fields.remove('tipo_texto') + if "tipo_texto" in self._meta.fields: + self._meta.fields.remove("tipo_texto") else: - if 'tipo_texto' not in self._meta.fields: - self._meta.fields.append('tipo_texto') + if "tipo_texto" not in self._meta.fields: + self._meta.fields.append("tipo_texto") fields = [ - to_column((Fieldset( - TipoProposicao._meta.verbose_name, Field('tipo')), 12)), + to_column((Fieldset(TipoProposicao._meta.verbose_name, Field("tipo")), 12)), to_column( - (Alert('teste', - css_class="ementa_materia hidden alert-info", - dismiss=False), 12)), - to_column(('descricao', 12)), - to_column(('observacao', 12)), - + ( + Alert( + "teste", + css_class="ementa_materia hidden alert-info", + dismiss=False, + ), + 12, + ) + ), + to_column(("descricao", 12)), + to_column(("observacao", 12)), ] if BaseAppConfig.objects.last().escolher_numero_materia_proposicao: - fields.append(to_column(('numero_materia_futuro', 12)),) + fields.append( + to_column(("numero_materia_futuro", 12)), + ) else: - if 'numero_materia_futuro' in self._meta.fields: - self._meta.fields.remove('numero_materia_futuro') + if "numero_materia_futuro" in self._meta.fields: + self._meta.fields.remove("numero_materia_futuro") if self.texto_articulado_proposicao: fields.append( - to_column((InlineRadios('tipo_texto'), 5)),) + to_column((InlineRadios("tipo_texto"), 5)), + ) - fields.append(to_column(( - 'texto_original', 7 if self.texto_articulado_proposicao else 12))) + fields.append( + to_column(("texto_original", 7 if self.texto_articulado_proposicao else 12)) + ) fields.append( to_column( ( Fieldset( - _('Outras informações - Vincular a Matéria Legislativa Existente'), - to_row([('tipo_materia', 12), ]), - to_row([('numero_materia', 6), - ('ano_materia', 6)]), - ), 12)), + _( + "Outras informações - Vincular a Matéria Legislativa Existente" + ), + to_row( + [ + ("tipo_materia", 12), + ] + ), + to_row([("numero_materia", 6), ("ano_materia", 6)]), + ), + 12, + ) + ), ) self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout(*fields) @@ -1982,26 +2211,26 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm): super(ProposicaoForm, self).__init__(*args, **kwargs) if self.instance.pk: - self.fields['tipo_texto'].initial = '' + self.fields["tipo_texto"].initial = "" if self.instance.texto_original: - self.fields['tipo_texto'].initial = 'D' + self.fields["tipo_texto"].initial = "D" if self.texto_articulado_proposicao: if self.instance.texto_articulado.exists(): - self.fields['tipo_texto'].initial = 'T' + self.fields["tipo_texto"].initial = "T" if self.instance.materia_de_vinculo: self.fields[ - 'tipo_materia' + "tipo_materia" ].initial = self.instance.materia_de_vinculo.tipo self.fields[ - 'numero_materia' + "numero_materia" ].initial = self.instance.materia_de_vinculo.numero self.fields[ - 'ano_materia' + "ano_materia" ].initial = self.instance.materia_de_vinculo.ano def clean_texto_original(self): - texto_original = self.cleaned_data.get('texto_original', False) + texto_original = self.cleaned_data.get("texto_original", False) if texto_original: validar_arquivo(texto_original, "Texto Original") @@ -2009,17 +2238,19 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm): return texto_original def gerar_hash(self, inst, receber_recibo): - inst.save() if receber_recibo == True: - inst.hash_code = '' + inst.hash_code = "" else: if inst.texto_original: inst.hash_code = gerar_hash_arquivo( - inst.texto_original.path, str(inst.pk)) + inst.texto_original.path, str(inst.pk) + ) elif inst.texto_articulado.exists(): ta = inst.texto_articulado.first() - inst.hash_code = 'P' + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(inst.pk) + inst.hash_code = ( + "P" + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(inst.pk) + ) def clean(self): super(ProposicaoForm, self).clean() @@ -2029,40 +2260,59 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm): cd = self.cleaned_data - texto_original = cd.get('texto_original', False) + texto_original = cd.get("texto_original", False) if texto_original: - validar_arquivo(texto_original, 'Texto Original') + validar_arquivo(texto_original, "Texto Original") - tm, am, nm = (cd.get('tipo_materia', ''), - cd.get('ano_materia', ''), - cd.get('numero_materia', '')) + tm, am, nm = ( + cd.get("tipo_materia", ""), + cd.get("ano_materia", ""), + cd.get("numero_materia", ""), + ) - if cd['numero_materia_futuro'] and \ - 'tipo' in cd and \ - MateriaLegislativa.objects.filter(tipo=cd['tipo'].tipo_conteudo_related, - ano=timezone.now().year, - numero=cd['numero_materia_futuro']): - raise ValidationError(_("A matéria {} {}/{} já existe.".format(cd['tipo'].tipo_conteudo_related.descricao, - cd['numero_materia_futuro'], - timezone.now().year))) + if ( + cd["numero_materia_futuro"] + and "tipo" in cd + and MateriaLegislativa.objects.filter( + tipo=cd["tipo"].tipo_conteudo_related, + ano=timezone.now().year, + numero=cd["numero_materia_futuro"], + ) + ): + raise ValidationError( + _( + "A matéria {} {}/{} já existe.".format( + cd["tipo"].tipo_conteudo_related.descricao, + cd["numero_materia_futuro"], + timezone.now().year, + ) + ) + ) if tm and am and nm: try: - self.logger.debug("Tentando obter objeto MateriaLegislativa (tipo_id={}, ano={}, numero={})." - .format(tm, am, nm)) + self.logger.debug( + "Tentando obter objeto MateriaLegislativa (tipo_id={}, ano={}, numero={}).".format( + tm, am, nm + ) + ) materia_de_vinculo = MateriaLegislativa.objects.get( - tipo_id=tm, - ano=am, - numero=nm + tipo_id=tm, ano=am, numero=nm ) except ObjectDoesNotExist: - self.logger.error("Objeto MateriaLegislativa vinculada (tipo_id={}, ano={}, numero={}) não existe!" - .format(tm, am, nm)) - raise ValidationError(_('Matéria Vinculada não existe!')) + self.logger.error( + "Objeto MateriaLegislativa vinculada (tipo_id={}, ano={}, numero={}) não existe!".format( + tm, am, nm + ) + ) + raise ValidationError(_("Matéria Vinculada não existe!")) else: - self.logger.info("MateriaLegislativa vinculada (tipo_id={}, ano={}, numero={}) com sucesso." - .format(tm, am, nm)) - cd['materia_de_vinculo'] = materia_de_vinculo + self.logger.info( + "MateriaLegislativa vinculada (tipo_id={}, ano={}, numero={}) com sucesso.".format( + tm, am, nm + ) + ) + cd["materia_de_vinculo"] = materia_de_vinculo return cd @@ -2072,35 +2322,35 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm): receber_recibo = BaseAppConfig.objects.last().receber_recibo_proposicao if inst.pk: - if 'tipo_texto' in cd: - - if cd['tipo_texto'] == 'T' and inst.texto_original: + if "tipo_texto" in cd: + if cd["tipo_texto"] == "T" and inst.texto_original: inst.texto_original.delete() - elif cd['tipo_texto'] != 'T': + elif cd["tipo_texto"] != "T": inst.texto_articulado.all().delete() - if 'texto_original' in cd and\ - not cd['texto_original'] and \ - inst.texto_original: + if ( + "texto_original" in cd + and not cd["texto_original"] + and inst.texto_original + ): inst.texto_original.delete() self.gerar_hash(inst, receber_recibo) return super().save(commit) inst.ano = timezone.now().year - sequencia_numeracao = BaseAppConfig.attr( - 'sequencia_numeracao_proposicao') - if sequencia_numeracao == 'A': - numero__max = Proposicao.objects.filter( - autor=inst.autor, - ano=timezone.now().year).aggregate(Max('numero_proposicao')) - elif sequencia_numeracao == 'B': + sequencia_numeracao = BaseAppConfig.attr("sequencia_numeracao_proposicao") + if sequencia_numeracao == "A": numero__max = Proposicao.objects.filter( - ano=timezone.now().year).aggregate(Max('numero_proposicao')) - numero__max = numero__max['numero_proposicao__max'] - inst.numero_proposicao = ( - numero__max + 1) if numero__max else 1 + autor=inst.autor, ano=timezone.now().year + ).aggregate(Max("numero_proposicao")) + elif sequencia_numeracao == "B": + numero__max = Proposicao.objects.filter(ano=timezone.now().year).aggregate( + Max("numero_proposicao") + ) + numero__max = numero__max["numero_proposicao__max"] + inst.numero_proposicao = (numero__max + 1) if numero__max else 1 self.gerar_hash(inst, receber_recibo) @@ -2110,41 +2360,40 @@ class ProposicaoForm(FileFieldCheckMixin, forms.ModelForm): class DevolverProposicaoForm(forms.ModelForm): - justificativa_devolucao = forms.CharField( - required=False, widget=widgets.Textarea(attrs={'rows': 5})) + required=False, widget=widgets.Textarea(attrs={"rows": 5}) + ) logger = logging.getLogger(__name__) class Meta: model = Proposicao - fields = [ - 'justificativa_devolucao', - 'observacao', - 'user', - 'ip' - ] + fields = ["justificativa_devolucao", "observacao", "user", "ip"] widgets = { - 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), } def __init__(self, *args, **kwargs): - # esta chamada isola o __init__ de ProposicaoForm super(DevolverProposicaoForm, self).__init__(*args, **kwargs) fields = [] fields.append( Fieldset( - _('Registro de Devolução'), - to_column(('justificativa_devolucao', 12)), - to_column(('observacao', 12)), + _("Registro de Devolução"), + to_column(("justificativa_devolucao", 12)), + to_column(("observacao", 12)), to_column( - (form_actions(label=_('Devolver'), - name='devolver', - css_class='btn-danger float-right'), 12) - ) + ( + form_actions( + label=_("Devolver"), + name="devolver", + css_class="btn-danger float-right", + ), + 12, + ) + ), ) ) @@ -2159,12 +2408,10 @@ class DevolverProposicaoForm(forms.ModelForm): cd = self.cleaned_data - if 'justificativa_devolucao' not in cd or\ - not cd['justificativa_devolucao']: + if "justificativa_devolucao" not in cd or not cd["justificativa_devolucao"]: # TODO Implementar notificação ao autor por email self.logger.error("Adicione uma Justificativa para devolução.") - raise ValidationError( - _('Adicione uma Justificativa para devolução.')) + raise ValidationError(_("Adicione uma Justificativa para devolução.")) return cd @transaction.atomic @@ -2183,195 +2430,211 @@ class DevolverProposicaoForm(forms.ModelForm): ta.save() observacao = self.instance.justificativa_devolucao - HistoricoProposicao.objects.create(proposicao=self.instance, - status='D', - user=self.initial['user'], - ip=self.initial['ip'], - observacao=observacao) + HistoricoProposicao.objects.create( + proposicao=self.instance, + status="D", + user=self.initial["user"], + ip=self.initial["ip"], + observacao=observacao, + ) self.instance.results = { - 'messages': { - 'success': [_('Devolução efetuada com sucesso.'), ] + "messages": { + "success": [ + _("Devolução efetuada com sucesso."), + ] }, - 'url': reverse('sapl.materia:receber-proposicao') + "url": reverse("sapl.materia:receber-proposicao"), } return self.instance class ConfirmarProposicaoForm(ProposicaoForm): - tipo_readonly = forms.CharField( label=TipoProposicao._meta.verbose_name, - required=False, widget=widgets.TextInput( - attrs={'readonly': 'readonly'})) + required=False, + widget=widgets.TextInput(attrs={"readonly": "readonly"}), + ) autor_readonly = forms.CharField( label=Autor._meta.verbose_name, - required=False, widget=widgets.TextInput( - attrs={'readonly': 'readonly'})) + required=False, + widget=widgets.TextInput(attrs={"readonly": "readonly"}), + ) - regime_tramitacao = forms.ModelChoiceField(label="Regime de tramitação", - required=False, queryset=RegimeTramitacao.objects.all()) + regime_tramitacao = forms.ModelChoiceField( + label="Regime de tramitação", + required=False, + queryset=RegimeTramitacao.objects.all(), + ) gerar_protocolo = forms.ChoiceField( required=False, - label=_( - 'Gerar Protocolo na incorporação?'), + label=_("Gerar Protocolo na incorporação?"), choices=YES_NO_CHOICES, - widget=widgets.RadioSelect()) + widget=widgets.RadioSelect(), + ) - numero_de_paginas = forms.IntegerField(required=False, min_value=0, - label=_('Número de Páginas'),) + numero_de_paginas = forms.IntegerField( + required=False, + min_value=0, + label=_("Número de Páginas"), + ) class Meta: model = Proposicao fields = [ - 'data_envio', - 'descricao', - 'observacao', - 'gerar_protocolo', - 'numero_de_paginas', - 'numero_materia_futuro', - 'user', - 'ip' + "data_envio", + "descricao", + "observacao", + "gerar_protocolo", + "numero_de_paginas", + "numero_materia_futuro", + "user", + "ip", ] widgets = { - 'descricao': widgets.Textarea( - attrs={'readonly': 'readonly', 'rows': 4}), - 'data_envio': widgets.DateTimeInput( - attrs={'readonly': 'readonly'}), - 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), + "descricao": widgets.Textarea(attrs={"readonly": "readonly", "rows": 4}), + "data_envio": widgets.DateTimeInput(attrs={"readonly": "readonly"}), + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), } def __init__(self, *args, **kwargs): + self.proposicao_incorporacao_obrigatoria = BaseAppConfig.attr( + "proposicao_incorporacao_obrigatoria" + ) - self.proposicao_incorporacao_obrigatoria = \ - BaseAppConfig.attr('proposicao_incorporacao_obrigatoria') - - if self.proposicao_incorporacao_obrigatoria != 'C': - if 'gerar_protocolo' in self._meta.fields: - self._meta.fields.remove('gerar_protocolo') + if self.proposicao_incorporacao_obrigatoria != "C": + if "gerar_protocolo" in self._meta.fields: + self._meta.fields.remove("gerar_protocolo") else: - if 'gerar_protocolo' not in self._meta.fields: - self._meta.fields.append('gerar_protocolo') + if "gerar_protocolo" not in self._meta.fields: + self._meta.fields.append("gerar_protocolo") - if self.proposicao_incorporacao_obrigatoria == 'N': - if 'numero_de_paginas' in self._meta.fields: - self._meta.fields.remove('numero_de_paginas') + if self.proposicao_incorporacao_obrigatoria == "N": + if "numero_de_paginas" in self._meta.fields: + self._meta.fields.remove("numero_de_paginas") else: - if 'numero_de_paginas' not in self._meta.fields: - self._meta.fields.append('numero_de_paginas') + if "numero_de_paginas" not in self._meta.fields: + self._meta.fields.append("numero_de_paginas") - self.instance = kwargs.get('instance', None) + self.instance = kwargs.get("instance", None) if not self.instance: self.logger.error("Erro na Busca por proposição a incorporar") - raise ValueError(_('Erro na Busca por proposição a incorporar')) + raise ValueError(_("Erro na Busca por proposição a incorporar")) if self.instance.tipo.content_type.model_class() == TipoDocumento: - if 'numero_de_paginas' in self._meta.fields: - self._meta.fields.remove('numero_de_paginas') - if 'gerar_protocolo' in self._meta.fields: - self._meta.fields.remove('gerar_protocolo') - if 'regime_tramitacao' in self._meta.fields: - self._meta.fields.remove('regime_tramitacao') + if "numero_de_paginas" in self._meta.fields: + self._meta.fields.remove("numero_de_paginas") + if "gerar_protocolo" in self._meta.fields: + self._meta.fields.remove("gerar_protocolo") + if "regime_tramitacao" in self._meta.fields: + self._meta.fields.remove("regime_tramitacao") # esta chamada isola o __init__ de ProposicaoForm super(ProposicaoForm, self).__init__(*args, **kwargs) - if self.instance.tipo.content_type.model_class() ==\ - TipoMateriaLegislativa: - self.fields['regime_tramitacao'].required = True + if self.instance.tipo.content_type.model_class() == TipoMateriaLegislativa: + self.fields["regime_tramitacao"].required = True fields = [ Fieldset( - _('Dados Básicos'), + _("Dados Básicos"), to_row( [ - ('tipo_readonly', 3), - ('data_envio', 3), - ('autor_readonly', 3), - ('numero_materia_futuro', 3), - ('descricao', 12), - ('observacao', 12) + ("tipo_readonly", 3), + ("data_envio", 3), + ("autor_readonly", 3), + ("numero_materia_futuro", 3), + ("descricao", 12), + ("observacao", 12), ] - ) + ), ) ] - if not BaseAppConfig.objects.last().escolher_numero_materia_proposicao or \ - not self.instance.numero_materia_futuro: - if 'numero_materia_futuro' in self._meta.fields: + if ( + not BaseAppConfig.objects.last().escolher_numero_materia_proposicao + or not self.instance.numero_materia_futuro + ): + if "numero_materia_futuro" in self._meta.fields: del fields[0][0][3] fields.append( Fieldset( - _('Vinculado a Matéria Legislativa'), + _("Vinculado a Matéria Legislativa"), to_row( [ - ('tipo_materia', 3), - ('numero_materia', 2), - ('ano_materia', 2), - (Alert(_('O responsável pela incorporação pode ' - 'alterar a anexação. Limpar os campos ' - 'de Vinculação gera um %s independente ' - 'sem anexação se for possível para esta ' - 'Proposição. Não sendo, a rotina de incorporação ' - 'não permitirá estes campos serem vazios.' - ) % self.instance.tipo.content_type, - css_class="alert-info", - dismiss=False), 5), - (Alert('', - css_class="ementa_materia hidden alert-info", - dismiss=False), 12), + ("tipo_materia", 3), + ("numero_materia", 2), + ("ano_materia", 2), + ( + Alert( + _( + "O responsável pela incorporação pode " + "alterar a anexação. Limpar os campos " + "de Vinculação gera um %s independente " + "sem anexação se for possível para esta " + "Proposição. Não sendo, a rotina de incorporação " + "não permitirá estes campos serem vazios." + ) + % self.instance.tipo.content_type, + css_class="alert-info", + dismiss=False, + ), + 5, + ), + ( + Alert( + "", + css_class="ementa_materia hidden alert-info", + dismiss=False, + ), + 12, + ), ] - ) + ), ) ) itens_incorporacao = [] - if self.instance.tipo.content_type.model_class() == \ - TipoMateriaLegislativa: - itens_incorporacao = [to_column(('regime_tramitacao', 4))] + if self.instance.tipo.content_type.model_class() == TipoMateriaLegislativa: + itens_incorporacao = [to_column(("regime_tramitacao", 4))] - if self.proposicao_incorporacao_obrigatoria == 'C': - itens_incorporacao.append(to_column((InlineRadios( - 'gerar_protocolo'), 4))) + if self.proposicao_incorporacao_obrigatoria == "C": + itens_incorporacao.append( + to_column((InlineRadios("gerar_protocolo"), 4)) + ) - if self.proposicao_incorporacao_obrigatoria != 'N': - itens_incorporacao.append(to_column(('numero_de_paginas', 4))) + if self.proposicao_incorporacao_obrigatoria != "N": + itens_incorporacao.append(to_column(("numero_de_paginas", 4))) itens_incorporacao.append( - to_column( - (form_actions(label=_('Incorporar'), - name='incorporar'), 12) - ) + to_column((form_actions(label=_("Incorporar"), name="incorporar"), 12)) ) - fields.append( - Fieldset(_('Registro de Incorporação'), Row(*itens_incorporacao))) + fields.append(Fieldset(_("Registro de Incorporação"), Row(*itens_incorporacao))) self.helper = SaplFormHelper() self.helper.layout = Layout(*fields) - self.fields['tipo_readonly'].initial = self.instance.tipo.descricao - self.fields['autor_readonly'].initial = str(self.instance.autor) + self.fields["tipo_readonly"].initial = self.instance.tipo.descricao + self.fields["autor_readonly"].initial = str(self.instance.autor) if self.instance.numero_materia_futuro: - self.fields['numero_materia_futuro'].initial = self.instance.numero_materia_futuro + self.fields[ + "numero_materia_futuro" + ].initial = self.instance.numero_materia_futuro if self.instance.materia_de_vinculo: + self.fields["tipo_materia"].initial = self.instance.materia_de_vinculo.tipo self.fields[ - 'tipo_materia' - ].initial = self.instance.materia_de_vinculo.tipo - self.fields[ - 'numero_materia' + "numero_materia" ].initial = self.instance.materia_de_vinculo.numero - self.fields[ - 'ano_materia' - ].initial = self.instance.materia_de_vinculo.ano + self.fields["ano_materia"].initial = self.instance.materia_de_vinculo.ano - if self.proposicao_incorporacao_obrigatoria == 'C': - self.fields['gerar_protocolo'].initial = True + if self.proposicao_incorporacao_obrigatoria == "C": + self.fields["gerar_protocolo"].initial = True def clean(self): super(ConfirmarProposicaoForm, self).clean() @@ -2379,33 +2642,41 @@ class ConfirmarProposicaoForm(ProposicaoForm): if not self.is_valid(): return self.cleaned_data - numeracao = BaseAppConfig.attr('sequencia_numeracao_proposicao') + numeracao = BaseAppConfig.attr("sequencia_numeracao_proposicao") if not numeracao: - self.logger.error("A sequência de numeração (por ano ou geral)" - " não foi configurada para a aplicação em " - "tabelas auxiliares") - raise ValidationError("A sequência de numeração (por ano ou geral)" - " não foi configurada para a aplicação em " - "tabelas auxiliares") + self.logger.error( + "A sequência de numeração (por ano ou geral)" + " não foi configurada para a aplicação em " + "tabelas auxiliares" + ) + raise ValidationError( + "A sequência de numeração (por ano ou geral)" + " não foi configurada para a aplicação em " + "tabelas auxiliares" + ) cd = ProposicaoForm.clean(self) - if self.instance.tipo.content_type.model_class() ==\ - TipoMateriaLegislativa: - if 'regime_tramitacao' not in cd or\ - not cd['regime_tramitacao']: + if self.instance.tipo.content_type.model_class() == TipoMateriaLegislativa: + if "regime_tramitacao" not in cd or not cd["regime_tramitacao"]: self.logger.error("Regime de Tramitação deve ser informado.") - raise ValidationError( - _('Regime de Tramitação deve ser informado.')) + raise ValidationError(_("Regime de Tramitação deve ser informado.")) - elif self.instance.tipo.content_type.model_class( - ) == TipoDocumento and not cd['materia_de_vinculo']: - self.logger.error("Documentos não podem ser incorporados sem definir " - "para qual Matéria Legislativa ele se destina.") + elif ( + self.instance.tipo.content_type.model_class() == TipoDocumento + and not cd["materia_de_vinculo"] + ): + self.logger.error( + "Documentos não podem ser incorporados sem definir " + "para qual Matéria Legislativa ele se destina." + ) raise ValidationError( - _('Documentos não podem ser incorporados sem definir ' - 'para qual Matéria Legislativa ele se destina.')) + _( + "Documentos não podem ser incorporados sem definir " + "para qual Matéria Legislativa ele se destina." + ) + ) return cd @@ -2414,10 +2685,10 @@ class ConfirmarProposicaoForm(ProposicaoForm): # TODO Implementar workflow entre protocolo e autores cd = self.cleaned_data - self.instance.justificativa_devolucao = '' + self.instance.justificativa_devolucao = "" self.instance.data_devolucao = None self.instance.data_recebimento = timezone.now() - self.instance.materia_de_vinculo = cd['materia_de_vinculo'] + self.instance.materia_de_vinculo = cd["materia_de_vinculo"] if self.instance.texto_articulado.exists(): ta = self.instance.texto_articulado.first() @@ -2441,29 +2712,28 @@ class ConfirmarProposicaoForm(ProposicaoForm): abaixo. """ self.instance.results = { - 'messages': { - 'success': [_('Proposição incorporada com sucesso'), ] + "messages": { + "success": [ + _("Proposição incorporada com sucesso"), + ] }, - 'url': reverse('sapl.materia:receber-proposicao') + "url": reverse("sapl.materia:receber-proposicao"), } proposicao = self.instance conteudo_gerado = None - HistoricoProposicao.objects.create(proposicao=proposicao, - status='R', - user=self.initial['user'], - ip=self.initial['ip'], - ) - - if self.instance.tipo.content_type.model_class( - ) == TipoMateriaLegislativa: + HistoricoProposicao.objects.create( + proposicao=proposicao, + status="R", + user=self.initial["user"], + ip=self.initial["ip"], + ) + if self.instance.tipo.content_type.model_class() == TipoMateriaLegislativa: numeracao = None try: - self.logger.debug( - "Tentando obter modelo de sequência de numeração.") - numeracao = BaseAppConfig.objects.last( - ).sequencia_numeracao_protocolo + self.logger.debug("Tentando obter modelo de sequência de numeração.") + numeracao = BaseAppConfig.objects.last().sequencia_numeracao_protocolo except AttributeError as e: self.logger.error("Erro ao obter modelo. " + str(e)) pass @@ -2472,33 +2742,34 @@ class ConfirmarProposicaoForm(ProposicaoForm): if tipo.sequencia_numeracao: numeracao = tipo.sequencia_numeracao ano = timezone.now().year - if numeracao == 'A': + if numeracao == "A": numero = MateriaLegislativa.objects.filter( - ano=ano, tipo=tipo).aggregate(Max('numero')) - elif numeracao == 'L': + ano=ano, tipo=tipo + ).aggregate(Max("numero")) + elif numeracao == "L": legislatura = Legislatura.objects.filter( - data_inicio__year__lte=ano, - data_fim__year__gte=ano).first() + data_inicio__year__lte=ano, data_fim__year__gte=ano + ).first() data_inicio = legislatura.data_inicio data_fim = legislatura.data_fim numero = MateriaLegislativa.objects.filter( data_apresentacao__gte=data_inicio, data_apresentacao__lte=data_fim, - tipo=tipo).aggregate( - Max('numero')) - elif numeracao == 'U': - numero = MateriaLegislativa.objects.filter( - tipo=tipo).aggregate(Max('numero')) + tipo=tipo, + ).aggregate(Max("numero")) + elif numeracao == "U": + numero = MateriaLegislativa.objects.filter(tipo=tipo).aggregate( + Max("numero") + ) if numeracao is None: - numero['numero__max'] = 0 + numero["numero__max"] = 0 - if cd['numero_materia_futuro'] and not MateriaLegislativa.objects.filter(tipo=tipo, - ano=ano, - numero=cd['numero_materia_futuro']): - max_numero = cd['numero_materia_futuro'] + if cd["numero_materia_futuro"] and not MateriaLegislativa.objects.filter( + tipo=tipo, ano=ano, numero=cd["numero_materia_futuro"] + ): + max_numero = cd["numero_materia_futuro"] else: - max_numero = numero['numero__max'] + \ - 1 if numero['numero__max'] else 1 + max_numero = numero["numero__max"] + 1 if numero["numero__max"] else 1 # dados básicos materia = MateriaLegislativa() @@ -2508,12 +2779,13 @@ class ConfirmarProposicaoForm(ProposicaoForm): materia.ano = ano materia.data_apresentacao = timezone.now() materia.em_tramitacao = True - materia.regime_tramitacao = cd['regime_tramitacao'] + materia.regime_tramitacao = cd["regime_tramitacao"] if proposicao.texto_original: materia.texto_original = File( proposicao.texto_original, - os.path.basename(proposicao.texto_original.path)) + os.path.basename(proposicao.texto_original.path), + ) materia.save() conteudo_gerado = materia @@ -2525,9 +2797,9 @@ class ConfirmarProposicaoForm(ProposicaoForm): ta_materia.privacidade = STATUS_TA_IMMUTABLE_PUBLIC ta_materia.save() - self.instance.results['messages']['success'].append(_( - 'Matéria Legislativa registrada com sucesso (%s)' - ) % str(materia)) + self.instance.results["messages"]["success"].append( + _("Matéria Legislativa registrada com sucesso (%s)") % str(materia) + ) # autoria autoria = Autoria() @@ -2536,9 +2808,9 @@ class ConfirmarProposicaoForm(ProposicaoForm): autoria.primeiro_autor = True autoria.save() - self.instance.results['messages']['success'].append(_( - 'Autoria registrada para (%s)' - ) % str(autoria.autor)) + self.instance.results["messages"]["success"].append( + _("Autoria registrada para (%s)") % str(autoria.autor) + ) # Matéria de vinlculo if proposicao.materia_de_vinculo: @@ -2548,16 +2820,15 @@ class ConfirmarProposicaoForm(ProposicaoForm): anexada.data_anexacao = timezone.now() anexada.save() - self.instance.results['messages']['success'].append(_( - 'Matéria anexada a (%s)' - ) % str(anexada.materia_principal)) + self.instance.results["messages"]["success"].append( + _("Matéria anexada a (%s)") % str(anexada.materia_principal) + ) - self.instance.results['url'] = reverse( - 'sapl.materia:materialegislativa_detail', - kwargs={'pk': materia.pk}) + self.instance.results["url"] = reverse( + "sapl.materia:materialegislativa_detail", kwargs={"pk": materia.pk} + ) elif self.instance.tipo.content_type.model_class() == TipoDocumento: - # dados básicos doc = DocumentoAcessorio() doc.materia = proposicao.materia_de_vinculo @@ -2574,17 +2845,19 @@ class ConfirmarProposicaoForm(ProposicaoForm): doc.arquivo = proposicao.texto_original = File( proposicao.texto_original, - os.path.basename(proposicao.texto_original.path)) + os.path.basename(proposicao.texto_original.path), + ) doc.save() conteudo_gerado = doc - self.instance.results['messages']['success'].append(_( - 'Documento Acessório registrado com sucesso e anexado (%s)' - ) % str(doc.materia)) + self.instance.results["messages"]["success"].append( + _("Documento Acessório registrado com sucesso e anexado (%s)") + % str(doc.materia) + ) - self.instance.results['url'] = reverse( - 'sapl.materia:documentoacessorio_detail', - kwargs={'pk': doc.pk}) + self.instance.results["url"] = reverse( + "sapl.materia:documentoacessorio_detail", kwargs={"pk": doc.pk} + ) proposicao.conteudo_gerado_related = conteudo_gerado proposicao.save() @@ -2593,12 +2866,12 @@ class ConfirmarProposicaoForm(ProposicaoForm): return self.instance # Nunca gerar protocolo - if self.proposicao_incorporacao_obrigatoria == 'N': + if self.proposicao_incorporacao_obrigatoria == "N": return self.instance # ocorre se proposicao_incorporacao_obrigatoria == 'C' (condicional) # and gerar_protocolo == False - if 'gerar_protocolo' not in cd or cd['gerar_protocolo'] == 'False': + if "gerar_protocolo" not in cd or cd["gerar_protocolo"] == "False": return self.instance # resta a opção proposicao_incorporacao_obrigatoria == 'C' @@ -2614,56 +2887,60 @@ class ConfirmarProposicaoForm(ProposicaoForm): GenericForeignKey """ - numeracao = BaseAppConfig.attr('sequencia_numeracao_protocolo') - if numeracao == 'A': - nm = Protocolo.objects.filter( - ano=timezone.now().year).aggregate(Max('numero')) - elif numeracao == 'L': + numeracao = BaseAppConfig.attr("sequencia_numeracao_protocolo") + if numeracao == "A": + nm = Protocolo.objects.filter(ano=timezone.now().year).aggregate( + Max("numero") + ) + elif numeracao == "L": legislatura = Legislatura.objects.filter( data_inicio__year__lte=timezone.now().year, - data_fim__year__gte=timezone.now().year).first() + data_fim__year__gte=timezone.now().year, + ).first() ano_inicio = legislatura.data_inicio.year ano_fim = legislatura.data_fim.year nm = Protocolo.objects.filter( - ano__gte=ano_inicio, ano__lte=ano_fim).aggregate(Max('numero')) + ano__gte=ano_inicio, ano__lte=ano_fim + ).aggregate(Max("numero")) else: # numeracao == 'U' ou não informada - nm = Protocolo.objects.all().aggregate(Max('numero')) + nm = Protocolo.objects.all().aggregate(Max("numero")) protocolo = Protocolo() - protocolo.numero = (nm['numero__max'] + 1) if nm['numero__max'] else 1 + protocolo.numero = (nm["numero__max"] + 1) if nm["numero__max"] else 1 protocolo.ano = timezone.now().year - protocolo.tipo_protocolo = '1' + protocolo.tipo_protocolo = "1" protocolo.user = proposicao.user protocolo.de_proposicao = True - protocolo.interessado = str(proposicao.autor)[ - :200] # tamanho máximo 200 + protocolo.interessado = str(proposicao.autor)[:200] # tamanho máximo 200 protocolo.autor = proposicao.autor protocolo.assunto_ementa = proposicao.descricao - protocolo.numero_paginas = cd['numero_de_paginas'] + protocolo.numero_paginas = cd["numero_de_paginas"] protocolo.anulado = False - if self.instance.tipo.content_type.model_class( - ) == TipoMateriaLegislativa: + if self.instance.tipo.content_type.model_class() == TipoMateriaLegislativa: protocolo.tipo_materia = proposicao.tipo.tipo_conteudo_related - protocolo.tipo_processo = '1' + protocolo.tipo_processo = "1" elif self.instance.tipo.content_type.model_class() == TipoDocumento: protocolo.tipo_documento = proposicao.tipo.tipo_conteudo_related - protocolo.tipo_processo = '0' + protocolo.tipo_processo = "0" protocolo.save() - HistoricoProposicao.objects.create(proposicao=proposicao, - status='E', - user=self.initial['user'], - ip=self.initial['ip']) + HistoricoProposicao.objects.create( + proposicao=proposicao, + status="E", + user=self.initial["user"], + ip=self.initial["ip"], + ) - self.instance.results['messages']['success'].append(_( - 'Protocolo realizado com sucesso')) + self.instance.results["messages"]["success"].append( + _("Protocolo realizado com sucesso") + ) - self.instance.results['url'] = reverse( - 'sapl.protocoloadm:protocolo_mostrar', - kwargs={'pk': protocolo.pk}) + self.instance.results["url"] = reverse( + "sapl.protocoloadm:protocolo_mostrar", kwargs={"pk": protocolo.pk} + ) conteudo_gerado.numero_protocolo = protocolo.numero conteudo_gerado.save() @@ -2672,62 +2949,46 @@ class ConfirmarProposicaoForm(ProposicaoForm): class MateriaAssuntoForm(ModelForm): - class Meta: model = MateriaAssunto - fields = ['materia', 'assunto'] + fields = ["materia", "assunto"] - widgets = {'materia': forms.HiddenInput()} + widgets = {"materia": forms.HiddenInput()} class EtiquetaPesquisaForm(forms.Form): - logger = logging.getLogger(__name__) tipo_materia = forms.ModelChoiceField( label=TipoMateriaLegislativa._meta.verbose_name, queryset=TipoMateriaLegislativa.objects.all(), required=False, - empty_label='Selecione') + empty_label="Selecione", + ) data_inicial = forms.DateField( - label='Data Inicial', - required=False, - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Inicial", required=False, widget=forms.DateInput(format="%d/%m/%Y") ) data_final = forms.DateField( - label='Data Final', - required=False, - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Final", required=False, widget=forms.DateInput(format="%d/%m/%Y") ) - processo_inicial = forms.IntegerField( - label='Processo Inicial', - required=False) + processo_inicial = forms.IntegerField(label="Processo Inicial", required=False) - processo_final = forms.IntegerField( - label='Processo Final', - required=False) + processo_final = forms.IntegerField(label="Processo Final", required=False) def __init__(self, *args, **kwargs): super(EtiquetaPesquisaForm, self).__init__(*args, **kwargs) - row1 = to_row( - [('tipo_materia', 6), - ('data_inicial', 3), - ('data_final', 3)]) + row1 = to_row([("tipo_materia", 6), ("data_inicial", 3), ("data_final", 3)]) - row2 = to_row( - [('processo_inicial', 6), - ('processo_final', 6)]) + row2 = to_row([("processo_inicial", 6), ("processo_final", 6)]) self.helper = SaplFormHelper() self.helper.layout = Layout( Fieldset( - ('Formulário de Etiqueta'), - row1, row2, - form_actions(label='Pesquisar') + ("Formulário de Etiqueta"), row1, row2, form_actions(label="Pesquisar") ) ) @@ -2740,80 +3001,88 @@ class EtiquetaPesquisaForm(forms.Form): cleaned_data = self.cleaned_data # Verifica se algum campo de data foi preenchido - if cleaned_data['data_inicial'] or cleaned_data['data_final']: + if cleaned_data["data_inicial"] or cleaned_data["data_final"]: # Então verifica se o usuário preencheu o Incial e mas não # preencheu o Final, ou vice-versa - if (not cleaned_data['data_inicial'] or - not cleaned_data['data_final']): - self.logger.error("Caso pesquise por data, os campos de Data Incial e " - "Data Final devem ser preenchidos obrigatoriamente") - raise ValidationError(_( - 'Caso pesquise por data, os campos de Data Incial e ' + - 'Data Final devem ser preenchidos obrigatoriamente')) + if not cleaned_data["data_inicial"] or not cleaned_data["data_final"]: + self.logger.error( + "Caso pesquise por data, os campos de Data Incial e " + "Data Final devem ser preenchidos obrigatoriamente" + ) + raise ValidationError( + _( + "Caso pesquise por data, os campos de Data Incial e " + + "Data Final devem ser preenchidos obrigatoriamente" + ) + ) # Caso tenha preenchido, verifica se a data final é maior que # a inicial - elif cleaned_data['data_final'] < cleaned_data['data_inicial']: - self.logger.error("A Data Final ({}) não pode ser menor que a Data Inicial({})." - .format(cleaned_data['data_final'], cleaned_data['data_inicial'])) - raise ValidationError(_( - 'A Data Final não pode ser menor que a Data Inicial')) + elif cleaned_data["data_final"] < cleaned_data["data_inicial"]: + self.logger.error( + "A Data Final ({}) não pode ser menor que a Data Inicial({}).".format( + cleaned_data["data_final"], cleaned_data["data_inicial"] + ) + ) + raise ValidationError( + _("A Data Final não pode ser menor que a Data Inicial") + ) # O mesmo processo anterior é feito com o processo - if (cleaned_data['processo_inicial'] or - cleaned_data['processo_final']): - if (not cleaned_data['processo_inicial'] or - not cleaned_data['processo_final']): - self.logger.error("Caso pesquise por número de processo, os campos de " - "Processo Inicial e Processo Final " - "devem ser preenchidos obrigatoriamente") - raise ValidationError(_( - 'Caso pesquise por número de processo, os campos de ' + - 'Processo Inicial e Processo Final ' + - 'devem ser preenchidos obrigatoriamente')) - elif (cleaned_data['processo_final'] < - cleaned_data['processo_inicial']): - self.logger.error("O processo final ({}) não pode ser menor que o inicial ({})." - .format(cleaned_data['processo_final'], cleaned_data['processo_inicial'])) - raise ValidationError(_( - 'O processo final não pode ser menor que o inicial')) + if cleaned_data["processo_inicial"] or cleaned_data["processo_final"]: + if ( + not cleaned_data["processo_inicial"] + or not cleaned_data["processo_final"] + ): + self.logger.error( + "Caso pesquise por número de processo, os campos de " + "Processo Inicial e Processo Final " + "devem ser preenchidos obrigatoriamente" + ) + raise ValidationError( + _( + "Caso pesquise por número de processo, os campos de " + + "Processo Inicial e Processo Final " + + "devem ser preenchidos obrigatoriamente" + ) + ) + elif cleaned_data["processo_final"] < cleaned_data["processo_inicial"]: + self.logger.error( + "O processo final ({}) não pode ser menor que o inicial ({}).".format( + cleaned_data["processo_final"], cleaned_data["processo_inicial"] + ) + ) + raise ValidationError( + _("O processo final não pode ser menor que o inicial") + ) return cleaned_data class FichaPesquisaForm(forms.Form): - logger = logging.getLogger(__name__) tipo_materia = forms.ModelChoiceField( label=TipoMateriaLegislativa._meta.verbose_name, queryset=TipoMateriaLegislativa.objects.all(), - empty_label='Selecione') + empty_label="Selecione", + ) data_inicial = forms.DateField( - label='Data Inicial', - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Inicial", widget=forms.DateInput(format="%d/%m/%Y") ) data_final = forms.DateField( - label='Data Final', - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Final", widget=forms.DateInput(format="%d/%m/%Y") ) def __init__(self, *args, **kwargs): super(FichaPesquisaForm, self).__init__(*args, **kwargs) - row1 = to_row( - [('tipo_materia', 6), - ('data_inicial', 3), - ('data_final', 3)]) + row1 = to_row([("tipo_materia", 6), ("data_inicial", 3), ("data_final", 3)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset( - ('Formulário de Ficha'), - row1, - form_actions(label='Pesquisar') - ) + Fieldset(("Formulário de Ficha"), row1, form_actions(label="Pesquisar")) ) def clean(self): @@ -2827,47 +3096,52 @@ class FichaPesquisaForm(forms.Form): if not self.is_valid(): return cleaned_data - if cleaned_data['data_final'] < cleaned_data['data_inicial']: - self.logger.error("A Data Final ({}) não pode ser menor que a Data Inicial ({})." - .format(cleaned_data['data_final'], cleaned_data['data_inicial'])) - raise ValidationError(_( - 'A Data Final não pode ser menor que a Data Inicial')) + if cleaned_data["data_final"] < cleaned_data["data_inicial"]: + self.logger.error( + "A Data Final ({}) não pode ser menor que a Data Inicial ({}).".format( + cleaned_data["data_final"], cleaned_data["data_inicial"] + ) + ) + raise ValidationError( + _("A Data Final não pode ser menor que a Data Inicial") + ) return cleaned_data class FichaSelecionaForm(forms.Form): materia = forms.ModelChoiceField( - widget=forms.RadioSelect, - queryset=MateriaLegislativa.objects.all(), - label='') + widget=forms.RadioSelect, queryset=MateriaLegislativa.objects.all(), label="" + ) def __init__(self, *args, **kwargs): super(FichaSelecionaForm, self).__init__(*args, **kwargs) - row1 = to_row( - [('materia', 12)]) + row1 = to_row([("materia", 12)]) self.helper = SaplFormHelper() self.helper.layout = Layout( Fieldset( - ('Selecione a ficha que deseja imprimir'), + ("Selecione a ficha que deseja imprimir"), row1, - form_actions(label='Gerar Impresso') + form_actions(label="Gerar Impresso"), ) ) class StatusTramitacaoFilterSet(django_filters.FilterSet): descricao = django_filters.CharFilter( - label=_("Descrição do Status"), method='multifield_filter') + label=_("Descrição do Status"), method="multifield_filter" + ) class Meta: model = StatusTramitacao fields = ["descricao"] def multifield_filter(self, queryset, name, value): - return queryset.filter(Q(sigla__icontains=value) | Q(descricao__icontains=value)) + return queryset.filter( + Q(sigla__icontains=value) | Q(descricao__icontains=value) + ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -2877,32 +3151,39 @@ class StatusTramitacaoFilterSet(django_filters.FilterSet): self.form.helper = SaplFormHelper() self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_("Pesquisa de Status de Tramitacao"), - row0, form_actions(label="Pesquisar")) + Fieldset( + _("Pesquisa de Status de Tramitacao"), + row0, + form_actions(label="Pesquisar"), + ) ) class ExcluirTramitacaoEmLote(forms.Form): - logger = logging.getLogger(__name__) - data_tramitacao = forms.DateField(required=True, - label=_('Data da Tramitação')) + data_tramitacao = forms.DateField(required=True, label=_("Data da Tramitação")) - unidade_tramitacao_local = forms.ModelChoiceField(label=_('Unidade Local'), - required=True, - queryset=UnidadeTramitacao.objects.all(), - empty_label='------') + unidade_tramitacao_local = forms.ModelChoiceField( + label=_("Unidade Local"), + required=True, + queryset=UnidadeTramitacao.objects.all(), + empty_label="------", + ) - unidade_tramitacao_destino = forms.ModelChoiceField(label=_('Unidade Destino'), - required=True, - queryset=UnidadeTramitacao.objects.all(), - empty_label='------') + unidade_tramitacao_destino = forms.ModelChoiceField( + label=_("Unidade Destino"), + required=True, + queryset=UnidadeTramitacao.objects.all(), + empty_label="------", + ) - status = forms.ModelChoiceField(label=_('Status'), - required=True, - queryset=StatusTramitacao.objects.all(), - empty_label='------') + status = forms.ModelChoiceField( + label=_("Status"), + required=True, + queryset=StatusTramitacao.objects.all(), + empty_label="------", + ) def clean(self): super(ExcluirTramitacaoEmLote, self).clean() @@ -2912,23 +3193,31 @@ class ExcluirTramitacaoEmLote(forms.Form): if not self.is_valid(): return cleaned_data - data_tramitacao = cleaned_data['data_tramitacao'] - unidade_tramitacao_local = cleaned_data['unidade_tramitacao_local'] - unidade_tramitacao_destino = cleaned_data['unidade_tramitacao_destino'] - status = cleaned_data['status'] + data_tramitacao = cleaned_data["data_tramitacao"] + unidade_tramitacao_local = cleaned_data["unidade_tramitacao_local"] + unidade_tramitacao_destino = cleaned_data["unidade_tramitacao_destino"] + status = cleaned_data["status"] - tramitacao_set = Tramitacao.objects.filter(data_tramitacao=data_tramitacao, - unidade_tramitacao_local=unidade_tramitacao_local, - unidade_tramitacao_destino=unidade_tramitacao_destino, - status=status) + tramitacao_set = Tramitacao.objects.filter( + data_tramitacao=data_tramitacao, + unidade_tramitacao_local=unidade_tramitacao_local, + unidade_tramitacao_destino=unidade_tramitacao_destino, + status=status, + ) if not tramitacao_set.exists(): - self.logger.error("Não existem tramitações com os dados informados " - " (data_tramitacao={}, unidade_tramitacao_local={})." - "unidade_tramitacao_destino={}, status={})." - .format(data_tramitacao, unidade_tramitacao_local, - unidade_tramitacao_destino, status)) + self.logger.error( + "Não existem tramitações com os dados informados " + " (data_tramitacao={}, unidade_tramitacao_local={})." + "unidade_tramitacao_destino={}, status={}).".format( + data_tramitacao, + unidade_tramitacao_local, + unidade_tramitacao_destino, + status, + ) + ) raise forms.ValidationError( - _("Não existem tramitações com os dados informados.")) + _("Não existem tramitações com os dados informados.") + ) return cleaned_data @@ -2936,20 +3225,24 @@ class ExcluirTramitacaoEmLote(forms.Form): super(ExcluirTramitacaoEmLote, self).__init__(*args, **kwargs) row1 = to_row( - [('data_tramitacao', 6), - ('status', 6), ]) + [ + ("data_tramitacao", 6), + ("status", 6), + ] + ) row2 = to_row( - [('unidade_tramitacao_local', 6), - ('unidade_tramitacao_destino', 6)]) + [("unidade_tramitacao_local", 6), ("unidade_tramitacao_destino", 6)] + ) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset(_('Dados das Tramitações'), - row1, - row2, - HTML(" "), - form_actions(label='Excluir') - ) + Fieldset( + _("Dados das Tramitações"), + row1, + row2, + HTML(" "), + form_actions(label="Excluir"), + ) ) @@ -2958,45 +3251,33 @@ class MateriaPesquisaSimplesForm(forms.Form): label=TipoMateriaLegislativa._meta.verbose_name, queryset=TipoMateriaLegislativa.objects.all(), required=False, - empty_label='Selecione') + empty_label="Selecione", + ) data_inicial = forms.DateField( - label='Data Inicial', - required=False, - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Inicial", required=False, widget=forms.DateInput(format="%d/%m/%Y") ) data_final = forms.DateField( - label='Data Final', - required=False, - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Final", required=False, widget=forms.DateInput(format="%d/%m/%Y") ) titulo = forms.CharField( - label='Título do Relatório', - required=False, - max_length=150) + label="Título do Relatório", required=False, max_length=150 + ) logger = logging.getLogger(__name__) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - row1 = to_row( - [('tipo_materia', 6), - ('data_inicial', 3), - ('data_final', 3)]) + row1 = to_row([("tipo_materia", 6), ("data_inicial", 3), ("data_final", 3)]) - row2 = to_row( - [('titulo', 12)]) + row2 = to_row([("titulo", 12)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset( - 'Índice de Materias', - row1, row2, - form_actions(label='Pesquisar') - ) + Fieldset("Índice de Materias", row1, row2, form_actions(label="Pesquisar")) ) def clean(self): @@ -3006,20 +3287,30 @@ class MateriaPesquisaSimplesForm(forms.Form): return self.cleaned_data cleaned_data = self.cleaned_data - data_inicial = cleaned_data['data_inicial'] - data_final = cleaned_data['data_final'] + data_inicial = cleaned_data["data_inicial"] + data_final = cleaned_data["data_final"] if data_inicial or data_final: if not (data_inicial and data_final): - self.logger.error("Caso pesquise por data, os campos de Data Inicial e " - "Data Final devem ser preenchidos obrigatoriamente") - raise ValidationError(_('Caso pesquise por data, os campos de Data Inicial e ' - 'Data Final devem ser preenchidos obrigatoriamente')) + self.logger.error( + "Caso pesquise por data, os campos de Data Inicial e " + "Data Final devem ser preenchidos obrigatoriamente" + ) + raise ValidationError( + _( + "Caso pesquise por data, os campos de Data Inicial e " + "Data Final devem ser preenchidos obrigatoriamente" + ) + ) elif data_inicial > data_final: - self.logger.error("Data Final ({}) menor que a Data Inicial ({}).".format( - data_final, data_inicial)) + self.logger.error( + "Data Final ({}) menor que a Data Inicial ({}).".format( + data_final, data_inicial + ) + ) raise ValidationError( - _('A Data Final não pode ser menor que a Data Inicial')) + _("A Data Final não pode ser menor que a Data Inicial") + ) return cleaned_data @@ -3027,4 +3318,4 @@ class MateriaPesquisaSimplesForm(forms.Form): class ConfigEtiquetaMateriaLegislativaForms(ModelForm): class Meta: model = ConfigEtiquetaMateriaLegislativa - fields = '__all__' + fields = "__all__" diff --git a/sapl/materia/models.py b/sapl/materia/models.py index a66dba6db..28c94cd64 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -15,19 +15,18 @@ from sapl.comissoes.models import Comissao, Reuniao from sapl.compilacao.models import (PerfilEstruturalTextoArticulado, TextoArticulado) from sapl.parlamentares.models import Parlamentar -from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, SaplGenericForeignKey, - SaplGenericRelation, restringe_tipos_de_arquivo_txt, - texto_upload_path, get_settings_auth_user_model, - OverwriteStorage) +from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, OverwriteStorage, + SaplGenericForeignKey, SaplGenericRelation, + get_settings_auth_user_model, + restringe_tipos_de_arquivo_txt, texto_upload_path) # from sapl.protocoloadm.models import Protocolo -EM_TRAMITACAO = [(1, 'Sim'), - (0, 'Não')] +EM_TRAMITACAO = [(1, "Sim"), (0, "Não")] def grupo_autor(): try: - grupo = Group.objects.get(name='Autor') + grupo = Group.objects.get(name="Autor") except Group.DoesNotExist: return None return grupo.id @@ -36,50 +35,57 @@ def grupo_autor(): class TipoProposicao(models.Model): descricao = models.CharField( max_length=50, - verbose_name=_('Descrição'), + verbose_name=_("Descrição"), unique=True, error_messages={ - 'unique': _('Já existe um Tipo de Proposição com esta descrição.') - }) + "unique": _("Já existe um Tipo de Proposição com esta descrição.") + }, + ) content_type = models.ForeignKey( - ContentType, default=None, + ContentType, + default=None, on_delete=models.PROTECT, - verbose_name=_('Conversão de Meta-Tipos'), - help_text=_(""" + verbose_name=_("Conversão de Meta-Tipos"), + help_text=_( + """ Quando uma proposição é incorporada, ela é convertida de proposição para outro elemento dentro do Sapl. Existem alguns elementos que uma proposição pode se tornar. Defina este meta-tipo e em seguida escolha um Tipo Correspondente! - """) + """ + ), ) - object_id = models.PositiveIntegerField( - blank=True, null=True, default=None) + object_id = models.PositiveIntegerField(blank=True, null=True, default=None) tipo_conteudo_related = SaplGenericForeignKey( - 'content_type', 'object_id', verbose_name=_('Tipo Correspondente')) + "content_type", "object_id", verbose_name=_("Tipo Correspondente") + ) perfis = models.ManyToManyField( PerfilEstruturalTextoArticulado, - blank=True, verbose_name=_('Perfis Estruturais de Textos Articulados'), - help_text=_(""" + blank=True, + verbose_name=_("Perfis Estruturais de Textos Articulados"), + help_text=_( + """ Mesmo que em Configurações da Aplicação nas Tabelas Auxiliares esteja definido que Proposições possam utilizar Textos Articulados, ao gerar uma proposição, a solução de Textos Articulados será disponibilizada se o Tipo escolhido para a Proposição estiver associado a ao menos um Perfil Estrutural de Texto Articulado. - """)) + """ + ), + ) class Meta: - verbose_name = _('Tipo de Proposição') - verbose_name_plural = _('Tipos de Proposições') - ordering = ('id',) + verbose_name = _("Tipo de Proposição") + verbose_name_plural = _("Tipos de Proposições") + ordering = ("id",) def __str__(self): return self.descricao class TipoMateriaManager(models.Manager): - def reordene(self, exclude_pk=None): tipos = self.get_queryset() if exclude_pk: @@ -91,25 +97,17 @@ class TipoMateriaManager(models.Manager): def reposicione(self, pk, idx): tipos = self.reordene(exclude_pk=pk) - self.get_queryset( - ).filter( - sequencia_regimental__gte=idx - ).update( - sequencia_regimental=models.F('sequencia_regimental') + 1 + self.get_queryset().filter(sequencia_regimental__gte=idx).update( + sequencia_regimental=models.F("sequencia_regimental") + 1 ) - self.get_queryset( - ).filter( - pk=pk - ).update( - sequencia_regimental=idx - ) + self.get_queryset().filter(pk=pk).update(sequencia_regimental=idx) class TipoMateriaLegislativa(models.Model): objects = TipoMateriaManager() - sigla = models.CharField(max_length=5, verbose_name=_('Sigla')) - descricao = models.CharField(max_length=50, verbose_name=_('Descrição ')) + sigla = models.CharField(max_length=5, verbose_name=_("Sigla")) + descricao = models.CharField(max_length=50, verbose_name=_("Descrição ")) # XXX o que é isso ? num_automatica = models.BooleanField(default=False) # XXX o que é isso ? @@ -117,61 +115,64 @@ class TipoMateriaLegislativa(models.Model): tipo_proposicao = SaplGenericRelation( TipoProposicao, - related_query_name='tipomaterialegislativa_set', - fields_search=( - ('descricao', '__icontains'), - ('sigla', '__icontains') - )) + related_query_name="tipomaterialegislativa_set", + fields_search=(("descricao", "__icontains"), ("sigla", "__icontains")), + ) sequencia_numeracao = models.CharField( max_length=1, blank=True, - verbose_name=_('Sequência de numeração'), - choices=SEQUENCIA_NUMERACAO_PROTOCOLO) + verbose_name=_("Sequência de numeração"), + choices=SEQUENCIA_NUMERACAO_PROTOCOLO, + ) sequencia_regimental = models.PositiveIntegerField( default=0, - verbose_name=_('Sequência Regimental'), - help_text=_('A sequência regimental diz respeito ao que define ' - 'o regimento da Casa Legislativa sobre qual a ordem ' - 'de entrada das proposições nas Sessões Plenárias.')) + verbose_name=_("Sequência Regimental"), + help_text=_( + "A sequência regimental diz respeito ao que define " + "o regimento da Casa Legislativa sobre qual a ordem " + "de entrada das proposições nas Sessões Plenárias." + ), + ) class Meta: - verbose_name = _('Tipo de Matéria Legislativa') - verbose_name_plural = _('Tipos de Matérias Legislativas') - ordering = ['sequencia_regimental', 'descricao'] + verbose_name = _("Tipo de Matéria Legislativa") + verbose_name_plural = _("Tipos de Matérias Legislativas") + ordering = ["sequencia_regimental", "descricao"] def __str__(self): return self.descricao class RegimeTramitacao(models.Model): - descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) + descricao = models.CharField(max_length=50, verbose_name=_("Descrição")) class Meta: - verbose_name = _('Regime de Tramitação') - verbose_name_plural = _('Regimes de Tramitação') - ordering = ('id',) + verbose_name = _("Regime de Tramitação") + verbose_name_plural = _("Regimes de Tramitação") + ordering = ("id",) def __str__(self): return self.descricao class Origem(models.Model): - sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) + sigla = models.CharField(max_length=10, verbose_name=_("Sigla")) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) class Meta: - verbose_name = _('Origem') - verbose_name_plural = _('Origens') - ordering = ('id',) + verbose_name = _("Origem") + verbose_name_plural = _("Origens") + ordering = ("id",) def __str__(self): return self.nome -TIPO_APRESENTACAO_CHOICES = Choices(('O', 'oral', _('Oral')), - ('E', 'escrita', _('Escrita'))) +TIPO_APRESENTACAO_CHOICES = Choices( + ("O", "oral", _("Oral")), ("E", "escrita", _("Escrita")) +) def materia_upload_path(instance, filename): @@ -186,155 +187,152 @@ class MateriaLegislativa(models.Model): tipo = models.ForeignKey( TipoMateriaLegislativa, on_delete=models.PROTECT, - verbose_name=TipoMateriaLegislativa._meta.verbose_name) - numero = models.PositiveIntegerField(verbose_name=_('Número')) - ano = models.PositiveSmallIntegerField(verbose_name=_('Ano'), - choices=RANGE_ANOS) + verbose_name=TipoMateriaLegislativa._meta.verbose_name, + ) + numero = models.PositiveIntegerField(verbose_name=_("Número")) + ano = models.PositiveSmallIntegerField(verbose_name=_("Ano"), choices=RANGE_ANOS) numero_protocolo = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Número do Protocolo')) - data_apresentacao = models.DateField( - verbose_name=_('Data de Apresentação')) + blank=True, null=True, verbose_name=_("Número do Protocolo") + ) + data_apresentacao = models.DateField(verbose_name=_("Data de Apresentação")) tipo_apresentacao = models.CharField( - max_length=1, blank=True, - verbose_name=_('Tipo de Apresentação'), - choices=TIPO_APRESENTACAO_CHOICES) + max_length=1, + blank=True, + verbose_name=_("Tipo de Apresentação"), + choices=TIPO_APRESENTACAO_CHOICES, + ) regime_tramitacao = models.ForeignKey( - RegimeTramitacao, - on_delete=models.PROTECT, - verbose_name=_('Regime Tramitação')) + RegimeTramitacao, on_delete=models.PROTECT, verbose_name=_("Regime Tramitação") + ) data_publicacao = models.DateField( - blank=True, null=True, verbose_name=_('Data de Publicação')) + blank=True, null=True, verbose_name=_("Data de Publicação") + ) tipo_origem_externa = models.ForeignKey( TipoMateriaLegislativa, blank=True, null=True, - related_name='tipo_origem_externa_set', + related_name="tipo_origem_externa_set", on_delete=models.PROTECT, - verbose_name=_('Tipo')) + verbose_name=_("Tipo"), + ) numero_origem_externa = models.CharField( - max_length=10, blank=True, verbose_name=_('Número')) + max_length=10, blank=True, verbose_name=_("Número") + ) ano_origem_externa = models.PositiveSmallIntegerField( - blank=True, null=True, verbose_name=_('Ano'), choices=RANGE_ANOS) + blank=True, null=True, verbose_name=_("Ano"), choices=RANGE_ANOS + ) data_origem_externa = models.DateField( - blank=True, null=True, verbose_name=_('Data')) + blank=True, null=True, verbose_name=_("Data") + ) local_origem_externa = models.ForeignKey( - Origem, blank=True, null=True, - on_delete=models.PROTECT, verbose_name=_('Local de Origem')) - apelido = models.CharField( - max_length=50, blank=True, verbose_name=_('Apelido')) + Origem, + blank=True, + null=True, + on_delete=models.PROTECT, + verbose_name=_("Local de Origem"), + ) + apelido = models.CharField(max_length=50, blank=True, verbose_name=_("Apelido")) dias_prazo = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Dias Prazo')) + blank=True, null=True, verbose_name=_("Dias Prazo") + ) data_fim_prazo = models.DateField( - blank=True, null=True, verbose_name=_('Data Fim Prazo')) + blank=True, null=True, verbose_name=_("Data Fim Prazo") + ) em_tramitacao = models.BooleanField( - verbose_name=_('Em Tramitação?'), - default=False, - choices=YES_NO_CHOICES) + verbose_name=_("Em Tramitação?"), default=False, choices=YES_NO_CHOICES + ) polemica = models.BooleanField( - null=True, - blank=True, - default=False, - verbose_name=_('Matéria Polêmica?') + null=True, blank=True, default=False, verbose_name=_("Matéria Polêmica?") ) - objeto = models.CharField( - max_length=150, blank=True, verbose_name=_('Objeto')) + objeto = models.CharField(max_length=150, blank=True, verbose_name=_("Objeto")) complementar = models.BooleanField( - null=True, - blank=True, - default=False, - verbose_name=_('É Complementar?') - ) - ementa = models.TextField(verbose_name=_('Ementa')) - indexacao = models.TextField( - blank=True, verbose_name=_('Indexação')) - observacao = models.TextField( - blank=True, verbose_name=_('Observação')) + null=True, blank=True, default=False, verbose_name=_("É Complementar?") + ) + ementa = models.TextField(verbose_name=_("Ementa")) + indexacao = models.TextField(blank=True, verbose_name=_("Indexação")) + observacao = models.TextField(blank=True, verbose_name=_("Observação")) resultado = models.TextField(blank=True) # XXX novo anexadas = models.ManyToManyField( - 'self', + "self", blank=True, - through='Anexada', + through="Anexada", symmetrical=False, - related_name='anexo_de', - through_fields=( - 'materia_principal', - 'materia_anexada')) + related_name="anexo_de", + through_fields=("materia_principal", "materia_anexada"), + ) texto_original = models.FileField( max_length=300, blank=True, null=True, upload_to=materia_upload_path, - verbose_name=_('Texto Original'), + verbose_name=_("Texto Original"), storage=OverwriteStorage(), - validators=[restringe_tipos_de_arquivo_txt]) + validators=[restringe_tipos_de_arquivo_txt], + ) texto_articulado = GenericRelation( - TextoArticulado, related_query_name='texto_articulado') + TextoArticulado, related_query_name="texto_articulado" + ) - proposicao = GenericRelation( - 'Proposicao', related_query_name='proposicao') + proposicao = GenericRelation("Proposicao", related_query_name="proposicao") autores = models.ManyToManyField( Autor, - through='Autoria', - through_fields=('materia', 'autor'), - symmetrical=False, ) + through="Autoria", + through_fields=("materia", "autor"), + symmetrical=False, + ) data_ultima_atualizacao = models.DateTimeField( - blank=True, null=True, - auto_now=True, - verbose_name=_('Data')) + blank=True, null=True, auto_now=True, verbose_name=_("Data") + ) user = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Usuário'), + verbose_name=_("Usuário"), on_delete=models.PROTECT, null=True, - blank=True - ) - ip = models.CharField( - verbose_name=_('IP'), - max_length=60, blank=True, - default='' ) + ip = models.CharField(verbose_name=_("IP"), max_length=60, blank=True, default="") ultima_edicao = models.DateTimeField( - verbose_name=_('Data e Hora da Edição'), - blank=True, null=True + verbose_name=_("Data e Hora da Edição"), blank=True, null=True ) class Meta: - verbose_name = _('Matéria Legislativa') - verbose_name_plural = _('Matérias Legislativas') + verbose_name = _("Matéria Legislativa") + verbose_name_plural = _("Matérias Legislativas") unique_together = (("tipo", "numero", "ano"),) - ordering = ['-ano', 'tipo', 'numero'] + ordering = ["-ano", "tipo", "numero"] permissions = (("can_access_impressos", "Can access impressos"),) def __str__(self): - return _('%(tipo)s nº %(numero)s de %(ano)s') % { - 'tipo': self.tipo, 'numero': self.numero, 'ano': self.ano} + return _("%(tipo)s nº %(numero)s de %(ano)s") % { + "tipo": self.tipo, + "numero": self.numero, + "ano": self.ano, + } @property def epigrafe(self): - return _('%(tipo)s nº %(numero)s de %(data)s') % { - 'tipo': self.tipo, - 'numero': self.numero, - 'data': defaultfilters.date( - self.data_apresentacao, - r"d \d\e F \d\e Y" - )} + return _("%(tipo)s nº %(numero)s de %(data)s") % { + "tipo": self.tipo, + "numero": self.numero, + "data": defaultfilters.date(self.data_apresentacao, r"d \d\e F \d\e Y"), + } def data_entrada_protocolo(self): - ''' - hack: recuperar a data de entrada do protocolo sem gerar - dependência circular - ''' + """ + hack: recuperar a data de entrada do protocolo sem gerar + dependência circular + """ from sapl.protocoloadm.models import Protocolo + if self.ano and self.numero_protocolo: protocolo = Protocolo.objects.filter( - ano=self.ano, - numero=self.numero_protocolo).first() + ano=self.ano, numero=self.numero_protocolo + ).first() if protocolo: if protocolo.timestamp: return protocolo.timestamp @@ -346,7 +344,7 @@ class MateriaLegislativa(models.Model): elif protocolo.data: return protocolo.data - return '' + return "" def delete(self, using=None, keep_parents=False): texto_original = self.texto_original @@ -362,137 +360,149 @@ class MateriaLegislativa(models.Model): return result - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): - + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): if not self.pk and self.texto_original: texto_original = self.texto_original self.texto_original = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.texto_original = texto_original - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) class Autoria(models.Model): - autor = models.ForeignKey(Autor, - verbose_name=_('Autor'), - on_delete=models.PROTECT) + autor = models.ForeignKey(Autor, verbose_name=_("Autor"), on_delete=models.PROTECT) materia = models.ForeignKey( - MateriaLegislativa, on_delete=models.CASCADE, - verbose_name=_('Matéria Legislativa')) - primeiro_autor = models.BooleanField(verbose_name=_('Primeiro Autor'), - choices=YES_NO_CHOICES, - default=False) + MateriaLegislativa, + on_delete=models.CASCADE, + verbose_name=_("Matéria Legislativa"), + ) + primeiro_autor = models.BooleanField( + verbose_name=_("Primeiro Autor"), choices=YES_NO_CHOICES, default=False + ) class Meta: - verbose_name = _('Autoria') - verbose_name_plural = _('Autorias') - unique_together = (('autor', 'materia'),) - ordering = ('-primeiro_autor', 'autor__nome') + verbose_name = _("Autoria") + verbose_name_plural = _("Autorias") + unique_together = (("autor", "materia"),) + ordering = ("-primeiro_autor", "autor__nome") def __str__(self): - return _('Autoria: %(autor)s - %(materia)s') % { - 'autor': self.autor, 'materia': self.materia} + return _("Autoria: %(autor)s - %(materia)s") % { + "autor": self.autor, + "materia": self.materia, + } class AcompanhamentoMateria(models.Model): usuario = models.CharField(max_length=50) materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) - email = models.EmailField( - max_length=100, verbose_name=_('E-mail')) + email = models.EmailField(max_length=100, verbose_name=_("E-mail")) data_cadastro = models.DateField(auto_now_add=True) hash = models.CharField(max_length=8) confirmado = models.BooleanField(default=False) class Meta: - verbose_name = _('Acompanhamento de Matéria') - verbose_name_plural = _('Acompanhamentos de Matéria') - ordering = ('id',) + verbose_name = _("Acompanhamento de Matéria") + verbose_name_plural = _("Acompanhamentos de Matéria") + ordering = ("id",) def __str__(self): if self.data_cadastro is None: - return _('%(materia)s - %(email)s') % { - 'materia': self.materia, - 'email': self.email + return _("%(materia)s - %(email)s") % { + "materia": self.materia, + "email": self.email, } else: - return _('%(materia)s - %(email)s - Registrado em: %(data)s') % { - 'materia': self.materia, - 'email': self.email, - 'data': str(self.data_cadastro.strftime('%d/%m/%Y')) + return _("%(materia)s - %(email)s - Registrado em: %(data)s") % { + "materia": self.materia, + "email": self.email, + "data": str(self.data_cadastro.strftime("%d/%m/%Y")), } class PautaReuniao(models.Model): reuniao = models.ForeignKey( - Reuniao, related_name='reuniao_set', + Reuniao, + related_name="reuniao_set", on_delete=models.CASCADE, - verbose_name=_('Reunião') + verbose_name=_("Reunião"), ) materia = models.ForeignKey( - MateriaLegislativa, related_name='materia_set', + MateriaLegislativa, + related_name="materia_set", on_delete=models.PROTECT, - verbose_name=_('Matéria') + verbose_name=_("Matéria"), ) class Meta: - verbose_name = _('Matéria da Pauta') - verbose_name_plural = ('Matérias da Pauta') - ordering = ('id',) + verbose_name = _("Matéria da Pauta") + verbose_name_plural = "Matérias da Pauta" + ordering = ("id",) def __str__(self): - return _('Reunião: %(reuniao)s' - ' - Matéria: %(materia)s') % { - 'reuniao': self.reuniao, - 'materia': self.materia - } + return _("Reunião: %(reuniao)s" " - Matéria: %(materia)s") % { + "reuniao": self.reuniao, + "materia": self.materia, + } class Anexada(models.Model): materia_principal = models.ForeignKey( - MateriaLegislativa, related_name='materia_principal_set', + MateriaLegislativa, + related_name="materia_principal_set", on_delete=models.CASCADE, - verbose_name=_('Matéria Principal')) + verbose_name=_("Matéria Principal"), + ) materia_anexada = models.ForeignKey( - MateriaLegislativa, related_name='materia_anexada_set', + MateriaLegislativa, + related_name="materia_anexada_set", on_delete=models.CASCADE, - verbose_name=_('Matéria Anexada')) - data_anexacao = models.DateField(verbose_name=_('Data Anexação')) + verbose_name=_("Matéria Anexada"), + ) + data_anexacao = models.DateField(verbose_name=_("Data Anexação")) data_desanexacao = models.DateField( - blank=True, null=True, verbose_name=_('Data Desanexação')) + blank=True, null=True, verbose_name=_("Data Desanexação") + ) class Meta: - verbose_name = _('Anexada') - verbose_name_plural = _('Anexadas') - ordering = ('id',) + verbose_name = _("Anexada") + verbose_name_plural = _("Anexadas") + ordering = ("id",) def __str__(self): - return _('Principal: %(materia_principal)s' - ' - Anexada: %(materia_anexada)s') % { - 'materia_principal': self.materia_principal, - 'materia_anexada': self.materia_anexada} + return _( + "Principal: %(materia_principal)s" " - Anexada: %(materia_anexada)s" + ) % { + "materia_principal": self.materia_principal, + "materia_anexada": self.materia_anexada, + } class AssuntoMateria(models.Model): - assunto = models.CharField( - max_length=50, - verbose_name=_('Assunto')) + assunto = models.CharField(max_length=50, verbose_name=_("Assunto")) dispositivo = models.CharField( - max_length=200, - blank=True, - verbose_name=_('Descrição do Dispositivo Legal')) + max_length=200, blank=True, verbose_name=_("Descrição do Dispositivo Legal") + ) class Meta: - verbose_name = _('Assunto de Matéria') - verbose_name_plural = _('Assuntos de Matéria') - ordering = ('assunto', 'dispositivo') + verbose_name = _("Assunto de Matéria") + verbose_name_plural = _("Assuntos de Matéria") + ordering = ("assunto", "dispositivo") def __str__(self): return self.assunto @@ -501,34 +511,34 @@ class AssuntoMateria(models.Model): class DespachoInicial(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) comissao = models.ForeignKey( - Comissao, on_delete=models.CASCADE, verbose_name="Comissão") + Comissao, on_delete=models.CASCADE, verbose_name="Comissão" + ) class Meta: - verbose_name = _('Despacho Inicial') - verbose_name_plural = _('Despachos Iniciais') - ordering = ('id',) + verbose_name = _("Despacho Inicial") + verbose_name_plural = _("Despachos Iniciais") + ordering = ("id",) def __str__(self): - return _('%(materia)s - %(comissao)s') % { - 'materia': self.materia, - 'comissao': self.comissao} + return _("%(materia)s - %(comissao)s") % { + "materia": self.materia, + "comissao": self.comissao, + } class TipoDocumento(models.Model): - descricao = models.CharField( - max_length=50, verbose_name=_('Tipo Documento')) + descricao = models.CharField(max_length=50, verbose_name=_("Tipo Documento")) tipo_proposicao = SaplGenericRelation( TipoProposicao, - related_query_name='tipodocumento_set', - fields_search=( - ('descricao', '__icontains'), - )) + related_query_name="tipodocumento_set", + fields_search=(("descricao", "__icontains"),), + ) class Meta: - verbose_name = _('Tipo de Documento') - verbose_name_plural = _('Tipos de Documento') - ordering = ['descricao'] + verbose_name = _("Tipo de Documento") + verbose_name_plural = _("Tipos de Documento") + ordering = ["descricao"] def __str__(self): return self.descricao @@ -537,38 +547,41 @@ class TipoDocumento(models.Model): class DocumentoAcessorio(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) tipo = models.ForeignKey( - TipoDocumento, on_delete=models.PROTECT, verbose_name=_('Tipo')) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) - data = models.DateField(blank=True, null=True, - default=None, verbose_name=_('Data')) - autor = models.CharField( - max_length=200, blank=True, verbose_name=_('Autor')) - ementa = models.TextField(blank=True, verbose_name=_('Ementa')) - indexacao = models.TextField(blank=True, verbose_name=_('Indexação')) + TipoDocumento, on_delete=models.PROTECT, verbose_name=_("Tipo") + ) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) + data = models.DateField(blank=True, null=True, default=None, verbose_name=_("Data")) + autor = models.CharField(max_length=200, blank=True, verbose_name=_("Autor")) + ementa = models.TextField(blank=True, verbose_name=_("Ementa")) + indexacao = models.TextField(blank=True, verbose_name=_("Indexação")) arquivo = models.FileField( blank=True, null=True, max_length=300, upload_to=anexo_upload_path, - verbose_name=_('Texto Integral'), + verbose_name=_("Texto Integral"), storage=OverwriteStorage(), - validators=[restringe_tipos_de_arquivo_txt]) - proposicao = GenericRelation('Proposicao', related_query_name='proposicao') + validators=[restringe_tipos_de_arquivo_txt], + ) + proposicao = GenericRelation("Proposicao", related_query_name="proposicao") data_ultima_atualizacao = models.DateTimeField( - blank=True, null=True, auto_now=True, verbose_name=_('Data')) + blank=True, null=True, auto_now=True, verbose_name=_("Data") + ) class Meta: - verbose_name = _('Documento Acessório') - verbose_name_plural = _('Documentos Acessórios') - ordering = ('data', 'id') + verbose_name = _("Documento Acessório") + verbose_name_plural = _("Documentos Acessórios") + ordering = ("data", "id") def __str__(self): - return _('%(tipo)s - %(nome)s de %(data)s por %(autor)s') % { - 'tipo': self.tipo, - 'nome': self.nome, - 'data': formats.date_format( - self.data, "SHORT_DATE_FORMAT") if self.data else '', - 'autor': self.autor} + return _("%(tipo)s - %(nome)s de %(data)s por %(autor)s") % { + "tipo": self.tipo, + "nome": self.nome, + "data": formats.date_format(self.data, "SHORT_DATE_FORMAT") + if self.data + else "", + "autor": self.autor, + } def delete(self, using=None, keep_parents=False): arquivo = self.arquivo @@ -583,43 +596,49 @@ class DocumentoAcessorio(models.Model): return result - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): - + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): if not self.pk and self.arquivo: arquivo = self.arquivo self.arquivo = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.arquivo = arquivo - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) class MateriaAssunto(models.Model): # TODO M2M ?? assunto = models.ForeignKey( - AssuntoMateria, - on_delete=models.CASCADE, - verbose_name=_('Assunto')) + AssuntoMateria, on_delete=models.CASCADE, verbose_name=_("Assunto") + ) materia = models.ForeignKey( - MateriaLegislativa, - on_delete=models.CASCADE, - verbose_name=_('Matéria')) + MateriaLegislativa, on_delete=models.CASCADE, verbose_name=_("Matéria") + ) class Meta: - verbose_name = _('Relação Matéria - Assunto') - verbose_name_plural = _('Relações Matéria - Assunto') - ordering = ('assunto__assunto', '-materia') + verbose_name = _("Relação Matéria - Assunto") + verbose_name_plural = _("Relações Matéria - Assunto") + ordering = ("assunto__assunto", "-materia") def __str__(self): - return _('%(materia)s - %(assunto)s') % { - 'materia': self.materia, 'assunto': self.assunto} + return _("%(materia)s - %(assunto)s") % { + "materia": self.materia, + "assunto": self.assunto, + } class Numeracao(models.Model): @@ -627,106 +646,111 @@ class Numeracao(models.Model): tipo_materia = models.ForeignKey( TipoMateriaLegislativa, on_delete=models.CASCADE, - verbose_name=_('Tipo de Matéria')) - numero_materia = models.CharField(max_length=5, - verbose_name=_('Número')) - ano_materia = models.PositiveSmallIntegerField(verbose_name=_('Ano'), - choices=RANGE_ANOS) - data_materia = models.DateField(verbose_name=_('Data'), null=True) + verbose_name=_("Tipo de Matéria"), + ) + numero_materia = models.CharField(max_length=5, verbose_name=_("Número")) + ano_materia = models.PositiveSmallIntegerField( + verbose_name=_("Ano"), choices=RANGE_ANOS + ) + data_materia = models.DateField(verbose_name=_("Data"), null=True) class Meta: - verbose_name = _('Numeração') - verbose_name_plural = _('Numerações') - ordering = ('materia', - 'tipo_materia', - 'numero_materia', - 'ano_materia', - 'data_materia',) + verbose_name = _("Numeração") + verbose_name_plural = _("Numerações") + ordering = ( + "materia", + "tipo_materia", + "numero_materia", + "ano_materia", + "data_materia", + ) def __str__(self): - return _('%(numero)s/%(ano)s') % { - 'numero': self.numero_materia, - 'ano': self.ano_materia} + return _("%(numero)s/%(ano)s") % { + "numero": self.numero_materia, + "ano": self.ano_materia, + } class Orgao(models.Model): - nome = models.CharField(max_length=256, verbose_name=_('Nome')) - sigla = models.CharField(max_length=15, verbose_name=_('Sigla')) + nome = models.CharField(max_length=256, verbose_name=_("Nome")) + sigla = models.CharField(max_length=15, verbose_name=_("Sigla")) unidade_deliberativa = models.BooleanField( - choices=YES_NO_CHOICES, - verbose_name=(_('Unidade Deliberativa')), - default=False) - endereco = models.CharField( - max_length=100, blank=True, verbose_name=_('Endereço')) - telefone = models.CharField( - max_length=50, blank=True, verbose_name=_('Telefone')) - - autor = SaplGenericRelation(Autor, - related_query_name='orgao_set', - fields_search=( - ('nome', '__icontains'), - ('sigla', '__icontains') - )) + choices=YES_NO_CHOICES, verbose_name=(_("Unidade Deliberativa")), default=False + ) + endereco = models.CharField(max_length=100, blank=True, verbose_name=_("Endereço")) + telefone = models.CharField(max_length=50, blank=True, verbose_name=_("Telefone")) + + autor = SaplGenericRelation( + Autor, + related_query_name="orgao_set", + fields_search=(("nome", "__icontains"), ("sigla", "__icontains")), + ) class Meta: - verbose_name = _('Órgão') - verbose_name_plural = _('Órgãos') - ordering = ['nome'] + verbose_name = _("Órgão") + verbose_name_plural = _("Órgãos") + ordering = ["nome"] def __str__(self): - return _( - '%(nome)s - %(sigla)s') % {'nome': self.nome, 'sigla': self.sigla} + return _("%(nome)s - %(sigla)s") % {"nome": self.nome, "sigla": self.sigla} class TipoFimRelatoria(models.Model): - descricao = models.CharField( - max_length=50, verbose_name=_('Tipo Fim Relatoria')) + descricao = models.CharField(max_length=50, verbose_name=_("Tipo Fim Relatoria")) class Meta: - verbose_name = _('Tipo Fim de Relatoria') - verbose_name_plural = _('Tipos Fim de Relatoria') - ordering = ('id',) + verbose_name = _("Tipo Fim de Relatoria") + verbose_name_plural = _("Tipos Fim de Relatoria") + ordering = ("id",) def __str__(self): return self.descricao class Relatoria(models.Model): - materia = models.ForeignKey(MateriaLegislativa, - on_delete=models.CASCADE, - verbose_name=_('Matéria')) - parlamentar = models.ForeignKey(Parlamentar, - on_delete=models.CASCADE, - verbose_name=_('Parlamentar')) + materia = models.ForeignKey( + MateriaLegislativa, on_delete=models.CASCADE, verbose_name=_("Matéria") + ) + parlamentar = models.ForeignKey( + Parlamentar, on_delete=models.CASCADE, verbose_name=_("Parlamentar") + ) tipo_fim_relatoria = models.ForeignKey( TipoFimRelatoria, blank=True, null=True, on_delete=models.PROTECT, - verbose_name=_('Motivo Fim Relatoria')) + verbose_name=_("Motivo Fim Relatoria"), + ) comissao = models.ForeignKey( - Comissao, blank=True, null=True, - on_delete=models.CASCADE, verbose_name=_('Comissão')) - data_designacao_relator = models.DateField( - verbose_name=_('Data Designação')) + Comissao, + blank=True, + null=True, + on_delete=models.CASCADE, + verbose_name=_("Comissão"), + ) + data_designacao_relator = models.DateField(verbose_name=_("Data Designação")) data_destituicao_relator = models.DateField( - blank=True, null=True, verbose_name=_('Data Destituição')) + blank=True, null=True, verbose_name=_("Data Destituição") + ) class Meta: - verbose_name = _('Relatoria') - verbose_name_plural = _('Relatorias') - ordering = ('id',) + verbose_name = _("Relatoria") + verbose_name_plural = _("Relatorias") + ordering = ("id",) def __str__(self): if self.tipo_fim_relatoria: - return _('%(materia)s - %(tipo)s - %(data)s') % { - 'materia': self.materia, - 'tipo': self.tipo_fim_relatoria, - 'data': self.data_designacao_relator.strftime("%d/%m/%Y")} + return _("%(materia)s - %(tipo)s - %(data)s") % { + "materia": self.materia, + "tipo": self.tipo_fim_relatoria, + "data": self.data_designacao_relator.strftime("%d/%m/%Y"), + } else: - return _('%(materia)s - %(data)s') % { - 'materia': self.materia, - 'data': self.data_designacao_relator.strftime("%d/%m/%Y")} + return _("%(materia)s - %(data)s") % { + "materia": self.materia, + "data": self.data_designacao_relator.strftime("%d/%m/%Y"), + } class Parecer(models.Model): @@ -734,114 +758,93 @@ class Parecer(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) tipo_conclusao = models.CharField(max_length=3, blank=True) tipo_apresentacao = models.CharField( - max_length=1, choices=TIPO_APRESENTACAO_CHOICES) + max_length=1, choices=TIPO_APRESENTACAO_CHOICES + ) parecer = models.TextField(blank=True) class Meta: - verbose_name = _('Parecer') - verbose_name_plural = _('Pareceres') - ordering = ('id',) + verbose_name = _("Parecer") + verbose_name_plural = _("Pareceres") + ordering = ("id",) def __str__(self): - return _('%(relatoria)s - %(tipo)s') % { - 'relatoria': self.relatoria, 'tipo': self.tipo_apresentacao + return _("%(relatoria)s - %(tipo)s") % { + "relatoria": self.relatoria, + "tipo": self.tipo_apresentacao, } class Proposicao(models.Model): - autor = models.ForeignKey( - Autor, - null=True, - blank=True, - on_delete=models.PROTECT - ) + autor = models.ForeignKey(Autor, null=True, blank=True, on_delete=models.PROTECT) tipo = models.ForeignKey( TipoProposicao, on_delete=models.PROTECT, blank=False, null=True, - verbose_name=_('Tipo') + verbose_name=_("Tipo"), ) # XXX data_envio was not null, but actual data said otherwise!!! data_envio = models.DateTimeField( - blank=False, - null=True, - verbose_name=_('Data de Envio') + blank=False, null=True, verbose_name=_("Data de Envio") ) data_recebimento = models.DateTimeField( - blank=True, - null=True, - verbose_name=_('Data de Recebimento') + blank=True, null=True, verbose_name=_("Data de Recebimento") ) data_devolucao = models.DateTimeField( - blank=True, - null=True, - verbose_name=_('Data de Devolução') + blank=True, null=True, verbose_name=_("Data de Devolução") ) usuario_envio = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Usuário Responsável pelo Envio'), + verbose_name=_("Usuário Responsável pelo Envio"), on_delete=models.PROTECT, - related_name='proposicoes_enviadas', + related_name="proposicoes_enviadas", blank=True, - null=True + null=True, ) usuario_recebimento = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Usuário Responsável pelo Recebimento'), + verbose_name=_("Usuário Responsável pelo Recebimento"), on_delete=models.PROTECT, - related_name='proposicoes_recebidas', + related_name="proposicoes_recebidas", blank=True, - null=True + null=True, ) usuario_devolucao = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Usuário Responsável pela Devolução'), + verbose_name=_("Usuário Responsável pela Devolução"), on_delete=models.PROTECT, - related_name='proposicoes_devolvidas', + related_name="proposicoes_devolvidas", blank=True, - null=True + null=True, ) - descricao = models.TextField(verbose_name=_('Ementa')) + descricao = models.TextField(verbose_name=_("Ementa")) justificativa_devolucao = models.CharField( - max_length=200, - blank=True, - verbose_name=_('Justificativa da Devolução') + max_length=200, blank=True, verbose_name=_("Justificativa da Devolução") ) ano = models.PositiveSmallIntegerField( - verbose_name=_('Ano'), - default=None, - blank=True, - null=True, - choices=RANGE_ANOS + verbose_name=_("Ano"), default=None, blank=True, null=True, choices=RANGE_ANOS ) numero_proposicao = models.PositiveIntegerField( - blank=True, - null=True, - verbose_name=_('Número') + blank=True, null=True, verbose_name=_("Número") ) numero_materia_futuro = models.PositiveIntegerField( - blank=True, - null=True, - verbose_name=_('Número Matéria') + blank=True, null=True, verbose_name=_("Número Matéria") ) hash_code = models.CharField( - verbose_name=_('Código do Documento'), - max_length=200, - blank=True + verbose_name=_("Código do Documento"), max_length=200, blank=True ) """ @@ -863,10 +866,8 @@ class Proposicao(models.Model): status = models.CharField( blank=True, max_length=1, - choices=(('E', 'Enviada'), - ('R', 'Recebida'), - ('I', 'Incorporada')), - verbose_name=_('Status Proposição') + choices=(("E", "Enviada"), ("R", "Recebida"), ("I", "Incorporada")), + verbose_name=_("Status Proposição"), ) texto_original = models.FileField( @@ -874,14 +875,13 @@ class Proposicao(models.Model): upload_to=materia_upload_path, blank=True, null=True, - verbose_name=_('Texto Original'), + verbose_name=_("Texto Original"), storage=OverwriteStorage(), - validators=[restringe_tipos_de_arquivo_txt] + validators=[restringe_tipos_de_arquivo_txt], ) texto_articulado = GenericRelation( - TextoArticulado, - related_query_name='texto_articulado' + TextoArticulado, related_query_name="texto_articulado" ) materia_de_vinculo = models.ForeignKey( @@ -889,8 +889,8 @@ class Proposicao(models.Model): blank=True, null=True, on_delete=models.CASCADE, - verbose_name=_('Matéria anexadora'), - related_name=_('proposicao_set') + verbose_name=_("Matéria anexadora"), + related_name=_("proposicao_set"), ) content_type = models.ForeignKey( @@ -898,31 +898,20 @@ class Proposicao(models.Model): default=None, blank=True, null=True, - verbose_name=_('Tipo de Material Gerado'), - on_delete=models.PROTECT + verbose_name=_("Tipo de Material Gerado"), + on_delete=models.PROTECT, ) - object_id = models.PositiveIntegerField( - blank=True, - null=True, - default=None - ) + object_id = models.PositiveIntegerField(blank=True, null=True, default=None) conteudo_gerado_related = SaplGenericForeignKey( - 'content_type', - 'object_id', - verbose_name=_('Conteúdo Gerado') + "content_type", "object_id", verbose_name=_("Conteúdo Gerado") ) - observacao = models.TextField( - blank=True, - verbose_name=_('Observação') - ) + observacao = models.TextField(blank=True, verbose_name=_("Observação")) cancelado = models.BooleanField( - verbose_name=_('Cancelada ?'), - choices=YES_NO_CHOICES, - default=False + verbose_name=_("Cancelada ?"), choices=YES_NO_CHOICES, default=False ) """ @@ -943,23 +932,16 @@ class Proposicao(models.Model): user = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Usuário'), + verbose_name=_("Usuário"), on_delete=models.PROTECT, null=True, - blank=True - ) - - ip = models.CharField( - verbose_name=_('IP'), - max_length=60, blank=True, - default='' ) + ip = models.CharField(verbose_name=_("IP"), max_length=60, blank=True, default="") + ultima_edicao = models.DateTimeField( - verbose_name=_('Data e Hora da Edição'), - blank=True, - null=True + verbose_name=_("Data e Hora da Edição"), blank=True, null=True ) @property @@ -968,49 +950,59 @@ class Proposicao(models.Model): @property def title_type(self): - return '%s nº _____ %s' % ( - self.tipo, formats.date_format( + return "%s nº _____ %s" % ( + self.tipo, + formats.date_format( self.data_envio if self.data_envio else timezone.now(), - r"\d\e d \d\e F \d\e Y")) + r"\d\e d \d\e F \d\e Y", + ), + ) class Meta: - ordering = ['-data_recebimento'] - verbose_name = _('Proposição') - verbose_name_plural = _('Proposições') - unique_together = (('content_type', 'object_id'),) + ordering = ["-data_recebimento"] + verbose_name = _("Proposição") + verbose_name_plural = _("Proposições") + unique_together = (("content_type", "object_id"),) permissions = ( - ('detail_proposicao_enviada', - _('Pode acessar detalhes de uma proposição enviada.')), - ('detail_proposicao_devolvida', - _('Pode acessar detalhes de uma proposição devolvida.')), - ('detail_proposicao_incorporada', - _('Pode acessar detalhes de uma proposição incorporada.')), + ( + "detail_proposicao_enviada", + _("Pode acessar detalhes de uma proposição enviada."), + ), + ( + "detail_proposicao_devolvida", + _("Pode acessar detalhes de uma proposição devolvida."), + ), + ( + "detail_proposicao_incorporada", + _("Pode acessar detalhes de uma proposição incorporada."), + ), ) def __str__(self): if self.ano and self.numero_proposicao: - return '%s %s/%s' % (Proposicao._meta.verbose_name, - self.numero_proposicao, - self.ano) + return "%s %s/%s" % ( + Proposicao._meta.verbose_name, + self.numero_proposicao, + self.ano, + ) else: if len(self.descricao) < 30: - descricao = self.descricao[:28] + ' ...' + descricao = self.descricao[:28] + " ..." else: descricao = self.descricao - return '%s %s/%s' % (Proposicao._meta.verbose_name, - self.id, - descricao) + return "%s %s/%s" % (Proposicao._meta.verbose_name, self.id, descricao) @property def epigrafe(self): - return _('%(tipo)s nº %(numero)s de %(data)s') % { - 'tipo': self.tipo, - 'numero': self.numero_proposicao, - 'data': defaultfilters.date( + return _("%(tipo)s nº %(numero)s de %(data)s") % { + "tipo": self.tipo, + "numero": self.numero_proposicao, + "data": defaultfilters.date( self.data_envio if self.data_envio else timezone.now(), - r"d \d\e F \d\e Y" - )} + r"d \d\e F \d\e Y", + ), + } def delete(self, using=None, keep_parents=False): texto_original = self.texto_original @@ -1021,8 +1013,9 @@ class Proposicao(models.Model): return result - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): # atualiza o usuario baseado no status da proposição (que esta sendo # calculado pela data) if self.data_envio is not None and not self.usuario_envio: @@ -1035,244 +1028,280 @@ class Proposicao(models.Model): if not self.pk and self.texto_original: texto_original = self.texto_original self.texto_original = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.texto_original = texto_original - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) class HistoricoProposicao(models.Model): - STATUS_PROPOSICAO = Choices(('E', 'ENVIADA', _('Enviada')), - ('R', 'RECEBIDA', _('Recebida')), - ('T', 'RETORNADA', _('Retornada')), - ('D', 'DEVOLVIDA', _('Devolvida'))) - - proposicao = models.ForeignKey(Proposicao, - verbose_name=_('Proposição'), - db_index=True, - on_delete=models.CASCADE) - status = models.CharField(max_length=1, - verbose_name=_('Status de Proposição'), - db_index=True, - choices=STATUS_PROPOSICAO) - data_hora = models.DateTimeField(null=True, - blank=True, - default=timezone.now, - db_index=True, - verbose_name=_('Data/Hora')) - observacao = models.CharField(max_length=200, - blank=True, - verbose_name=_('Observação')) - user = models.ForeignKey(get_settings_auth_user_model(), - verbose_name=_('Usuário'), - on_delete=models.PROTECT, - null=True, - blank=True) - ip = models.CharField(verbose_name=_('IP'), - max_length=60, - blank=True, - default='') + STATUS_PROPOSICAO = Choices( + ("E", "ENVIADA", _("Enviada")), + ("R", "RECEBIDA", _("Recebida")), + ("T", "RETORNADA", _("Retornada")), + ("D", "DEVOLVIDA", _("Devolvida")), + ) + + proposicao = models.ForeignKey( + Proposicao, + verbose_name=_("Proposição"), + db_index=True, + on_delete=models.CASCADE, + ) + status = models.CharField( + max_length=1, + verbose_name=_("Status de Proposição"), + db_index=True, + choices=STATUS_PROPOSICAO, + ) + data_hora = models.DateTimeField( + null=True, + blank=True, + default=timezone.now, + db_index=True, + verbose_name=_("Data/Hora"), + ) + observacao = models.CharField( + max_length=200, blank=True, verbose_name=_("Observação") + ) + user = models.ForeignKey( + get_settings_auth_user_model(), + verbose_name=_("Usuário"), + on_delete=models.PROTECT, + null=True, + blank=True, + ) + ip = models.CharField(verbose_name=_("IP"), max_length=60, blank=True, default="") @property def status_descricao(self): return self.STATUS_PROPOSICAO[self.status] class Meta: - verbose_name = _('Histórico de Proposição') - verbose_name_plural = _('Histórico de Proposições') - ordering = ('-data_hora', '-proposicao') + verbose_name = _("Histórico de Proposição") + verbose_name_plural = _("Histórico de Proposições") + ordering = ("-data_hora", "-proposicao") def __str__(self): - return f'{self.data_hora} - {self.STATUS_PROPOSICAO[self.status]} - {str(self.proposicao)}' + return f"{self.data_hora} - {self.STATUS_PROPOSICAO[self.status]} - {str(self.proposicao)}" class StatusTramitacao(models.Model): - INDICADOR_CHOICES = Choices(('F', 'fim', _('Fim')), - ('R', 'retorno', _('Retorno'))) + INDICADOR_CHOICES = Choices(("F", "fim", _("Fim")), ("R", "retorno", _("Retorno"))) - sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) - descricao = models.CharField(max_length=60, verbose_name=_('Descrição')) + sigla = models.CharField(max_length=10, verbose_name=_("Sigla")) + descricao = models.CharField(max_length=60, verbose_name=_("Descrição")) indicador = models.CharField( blank=True, - max_length=1, verbose_name=_('Indicador da Tramitação'), - choices=INDICADOR_CHOICES) + max_length=1, + verbose_name=_("Indicador da Tramitação"), + choices=INDICADOR_CHOICES, + ) class Meta: - verbose_name = _('Status de Tramitação') - verbose_name_plural = _('Status de Tramitação') - ordering = ['descricao'] + verbose_name = _("Status de Tramitação") + verbose_name_plural = _("Status de Tramitação") + ordering = ["descricao"] def __str__(self): - return _('%(descricao)s') % { - 'descricao': self.descricao} + return _("%(descricao)s") % {"descricao": self.descricao} class UnidadeTramitacaoManager(models.Manager): """ - Esta classe permite ordenar alfabeticamente a unidade de tramitacao - através da concatenação de 3 fields + Esta classe permite ordenar alfabeticamente a unidade de tramitacao + através da concatenação de 3 fields """ def get_queryset(self): - return super(UnidadeTramitacaoManager, self).get_queryset().annotate( - nome_composto=Concat('orgao__nome', - 'comissao__sigla', - 'parlamentar__nome_parlamentar') - ).order_by('nome_composto') + return ( + super(UnidadeTramitacaoManager, self) + .get_queryset() + .annotate( + nome_composto=Concat( + "orgao__nome", "comissao__sigla", "parlamentar__nome_parlamentar" + ) + ) + .order_by("nome_composto") + ) class UnidadeTramitacao(models.Model): comissao = models.ForeignKey( - Comissao, blank=True, null=True, - on_delete=models.PROTECT, verbose_name=_('Comissão')) + Comissao, + blank=True, + null=True, + on_delete=models.PROTECT, + verbose_name=_("Comissão"), + ) orgao = models.ForeignKey( - Orgao, blank=True, null=True, - on_delete=models.PROTECT, verbose_name=_('Órgão')) + Orgao, blank=True, null=True, on_delete=models.PROTECT, verbose_name=_("Órgão") + ) parlamentar = models.ForeignKey( - Parlamentar, blank=True, null=True, - on_delete=models.PROTECT, verbose_name=_('Parlamentar')) + Parlamentar, + blank=True, + null=True, + on_delete=models.PROTECT, + verbose_name=_("Parlamentar"), + ) objects = UnidadeTramitacaoManager() class Meta: - verbose_name = _('Unidade de Tramitação') - verbose_name_plural = _('Unidades de Tramitação') - ordering = ('orgao__nome', 'comissao__sigla', - 'parlamentar__nome_parlamentar') + verbose_name = _("Unidade de Tramitação") + verbose_name_plural = _("Unidades de Tramitação") + ordering = ("orgao__nome", "comissao__sigla", "parlamentar__nome_parlamentar") def __str__(self): if self.orgao and self.comissao and self.parlamentar: - return _('%(comissao)s - %(orgao)s - %(parlamentar)s') % { - 'comissao': self.comissao, 'orgao': self.orgao, - 'parlamentar': self.parlamentar + return _("%(comissao)s - %(orgao)s - %(parlamentar)s") % { + "comissao": self.comissao, + "orgao": self.orgao, + "parlamentar": self.parlamentar, } elif self.orgao and self.comissao and not self.parlamentar: - return _('%(comissao)s - %(orgao)s') % { - 'comissao': self.comissao, 'orgao': self.orgao + return _("%(comissao)s - %(orgao)s") % { + "comissao": self.comissao, + "orgao": self.orgao, } elif self.orgao and not self.comissao and self.parlamentar: - return _('%(orgao)s - %(parlamentar)s') % { - 'orgao': self.orgao, 'parlamentar': self.parlamentar + return _("%(orgao)s - %(parlamentar)s") % { + "orgao": self.orgao, + "parlamentar": self.parlamentar, } elif not self.orgao and self.comissao and self.parlamentar: - return _('%(comissao)s - %(parlamentar)s') % { - 'comissao': self.comissao, 'parlamentar': self.parlamentar + return _("%(comissao)s - %(parlamentar)s") % { + "comissao": self.comissao, + "parlamentar": self.parlamentar, } elif not self.orgao and self.comissao and not self.parlamentar: - return _('%(comissao)s') % {'comissao': self.comissao} + return _("%(comissao)s") % {"comissao": self.comissao} elif self.orgao and not self.comissao and not self.parlamentar: - return _('%(orgao)s') % {'orgao': self.orgao} + return _("%(orgao)s") % {"orgao": self.orgao} else: - return _('%(parlamentar)s') % {'parlamentar': self.parlamentar} + return _("%(parlamentar)s") % {"parlamentar": self.parlamentar} class Tramitacao(models.Model): TURNO_CHOICES = Choices( - ('P', 'primeiro', _('Primeiro')), - ('S', 'segundo', _('Segundo')), - ('U', 'unico', _('Único')), - ('L', 'suplementar', _('Suplementar')), - ('F', 'final', _('Final')), - ('A', 'votacao_unica', _('Votação Única em Regime de Urgência')), - ('B', 'primeira_votacao', _('1ª Votação')), - ('C', 'segunda_terceira_votacao', _('2ª e 3ª Votações')), - ('D', 'deliberacao', _('Deliberação')), - ('G', 'primeria_segunda_votacoes', _('1ª e 2ª Votações')), - ('E', 'primeira_segunda_votacao_urgencia', _( - '1ª e 2ª Votações em Regime de Urgência')), - - ) - - status = models.ForeignKey(StatusTramitacao, on_delete=models.PROTECT, - # TODO PÓS MIGRACAO INICIAL (vide #1381) - # não nulo quando todas as - # bases tiverem sido corrigidas - null=True, - verbose_name=_('Status')) + ("P", "primeiro", _("Primeiro")), + ("S", "segundo", _("Segundo")), + ("U", "unico", _("Único")), + ("L", "suplementar", _("Suplementar")), + ("F", "final", _("Final")), + ("A", "votacao_unica", _("Votação Única em Regime de Urgência")), + ("B", "primeira_votacao", _("1ª Votação")), + ("C", "segunda_terceira_votacao", _("2ª e 3ª Votações")), + ("D", "deliberacao", _("Deliberação")), + ("G", "primeria_segunda_votacoes", _("1ª e 2ª Votações")), + ( + "E", + "primeira_segunda_votacao_urgencia", + _("1ª e 2ª Votações em Regime de Urgência"), + ), + ) + + status = models.ForeignKey( + StatusTramitacao, + on_delete=models.PROTECT, + # TODO PÓS MIGRACAO INICIAL (vide #1381) + # não nulo quando todas as + # bases tiverem sido corrigidas + null=True, + verbose_name=_("Status"), + ) materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) # TODO: Remover os campos de data # TODO: pois timestamp supre a necessidade timestamp = models.DateTimeField(default=timezone.now) - data_tramitacao = models.DateField(verbose_name=_('Data Tramitação')) + data_tramitacao = models.DateField(verbose_name=_("Data Tramitação")) unidade_tramitacao_local = models.ForeignKey( UnidadeTramitacao, - related_name='tramitacoes_origem', + related_name="tramitacoes_origem", on_delete=models.PROTECT, - verbose_name=_('Unidade Local')) + verbose_name=_("Unidade Local"), + ) data_encaminhamento = models.DateField( - blank=True, null=True, verbose_name=_('Data Encaminhamento')) + blank=True, null=True, verbose_name=_("Data Encaminhamento") + ) unidade_tramitacao_destino = models.ForeignKey( UnidadeTramitacao, # TODO PÓS MIGRACAO INICIAL (vide #1381) # não nulo quando todas as # bases tiverem sido corrigidas null=True, - related_name='tramitacoes_destino', + related_name="tramitacoes_destino", on_delete=models.PROTECT, - verbose_name=_('Unidade Destino')) - urgente = models.BooleanField(verbose_name=_('Urgente ?'), - choices=YES_NO_CHOICES, - default=False) + verbose_name=_("Unidade Destino"), + ) + urgente = models.BooleanField( + verbose_name=_("Urgente ?"), choices=YES_NO_CHOICES, default=False + ) turno = models.CharField( - max_length=1, blank=True, verbose_name=_('Turno'), - choices=TURNO_CHOICES) - texto = models.TextField(verbose_name=_('Texto da Ação'), blank=True) + max_length=1, blank=True, verbose_name=_("Turno"), choices=TURNO_CHOICES + ) + texto = models.TextField(verbose_name=_("Texto da Ação"), blank=True) data_fim_prazo = models.DateField( - blank=True, null=True, verbose_name=_('Data Fim Prazo')) - user = models.ForeignKey(get_settings_auth_user_model(), - verbose_name=_('Usuário'), - on_delete=models.PROTECT, - null=True, - blank=True) - ip = models.CharField(verbose_name=_('IP'), - max_length=60, - blank=True, - default='') + blank=True, null=True, verbose_name=_("Data Fim Prazo") + ) + user = models.ForeignKey( + get_settings_auth_user_model(), + verbose_name=_("Usuário"), + on_delete=models.PROTECT, + null=True, + blank=True, + ) + ip = models.CharField(verbose_name=_("IP"), max_length=60, blank=True, default="") ultima_edicao = models.DateTimeField( - verbose_name=_('Data e Hora da Edição'), - blank=True, null=True + verbose_name=_("Data e Hora da Edição"), blank=True, null=True ) class Meta: - verbose_name = _('Tramitação') - verbose_name_plural = _('Tramitações') - ordering = ('-data_tramitacao', '-id') + verbose_name = _("Tramitação") + verbose_name_plural = _("Tramitações") + ordering = ("-data_tramitacao", "-id") def __str__(self): - return _('%(materia)s | %(status)s | %(data)s') % { - 'materia': self.materia, - 'status': self.status, - 'data': self.data_tramitacao.strftime("%d/%m/%Y")} + return _("%(materia)s | %(status)s | %(data)s") % { + "materia": self.materia, + "status": self.status, + "data": self.data_tramitacao.strftime("%d/%m/%Y"), + } class MateriaEmTramitacao(models.Model): - materia = models.ForeignKey( - MateriaLegislativa, on_delete=models.DO_NOTHING) + materia = models.ForeignKey(MateriaLegislativa, on_delete=models.DO_NOTHING) tramitacao = models.ForeignKey(Tramitacao, on_delete=models.DO_NOTHING) unidade_tramitacao_atual = models.ForeignKey( UnidadeTramitacao, - related_name='materiaemtramitacao_set', + related_name="materiaemtramitacao_set", on_delete=models.DO_NOTHING, - verbose_name=_('Unidade de Tramitação Atual'), - db_column='unidade_tramitacao_atual_id', + verbose_name=_("Unidade de Tramitação Atual"), + db_column="unidade_tramitacao_atual_id", null=True, - blank=True + blank=True, ) class Meta: managed = False db_table = "materia_materiaemtramitacao" - ordering = ('-id',) + ordering = ("-id",) def __str__(self): - return '{}/{}'.format(self.materia, self.tramitacao) + return "{}/{}".format(self.materia, self.tramitacao) class ConfigEtiquetaMateriaLegislativa(models.Model): @@ -1280,7 +1309,7 @@ class ConfigEtiquetaMateriaLegislativa(models.Model): altura = models.FloatField(default=3) class Meta: - ordering = ('id',) + ordering = ("id",) def save(self, *args, **kwargs): self.id = 1 diff --git a/sapl/materia/tests/test_email_templates.py b/sapl/materia/tests/test_email_templates.py index 32b2f7ec8..3f62b979c 100644 --- a/sapl/materia/tests/test_email_templates.py +++ b/sapl/materia/tests/test_email_templates.py @@ -5,62 +5,71 @@ from sapl.base.email_utils import enviar_emails, load_email_templates def test_email_template_loading(): expected = "Hello Django" - emails = load_email_templates(['email/test_tramitacao.html'], - context={"name": "Django"}) + emails = load_email_templates( + ["email/test_tramitacao.html"], context={"name": "Django"} + ) # strip \n and \r to compare with expected - actual = emails[0].replace('\n', '').replace('\r', '') + actual = emails[0].replace("\n", "").replace("\r", "") assert actual == expected def test_html_email_body_with_materia(): - templates = load_email_templates(['email/tramitacao.txt', - 'email/tramitacao.html'], - {"image": 'img/logo.png', - "casa_legislativa": - "Assembléia Parlamentar", - "data_registro": "25/02/2016", - "cod_materia": "1", - "descricao_materia": "Ementa de teste", - "autoria": ["Autor1", "Autor2"], - "data": "25/02/2016", - "status": "Arquivado", - "texto_acao": "Deliberado", - "hash_txt": "abc01f", - "materia_id": "794", - "base_url": "http://localhost:8000", - "materia_url": - "/materia/764/acompanhar-materia", - "excluir_url": - "/materia/764/acompanhar-excluir"}) + templates = load_email_templates( + ["email/tramitacao.txt", "email/tramitacao.html"], + { + "image": "img/logo.png", + "casa_legislativa": "Assembléia Parlamentar", + "data_registro": "25/02/2016", + "cod_materia": "1", + "descricao_materia": "Ementa de teste", + "autoria": ["Autor1", "Autor2"], + "data": "25/02/2016", + "status": "Arquivado", + "texto_acao": "Deliberado", + "hash_txt": "abc01f", + "materia_id": "794", + "base_url": "http://localhost:8000", + "materia_url": "/materia/764/acompanhar-materia", + "excluir_url": "/materia/764/acompanhar-excluir", + }, + ) assert len(templates) == 2 def test_enviar_email_distintos(): NUM_MESSAGES = 10 - messages = [{'recipient': 'user-' + str(i) + '@test.com', - 'subject': 'subject: ' + str(i), - 'txt_message': 'txt: ' + str(i), - 'html_message': '', - } for i in range(NUM_MESSAGES)] - - recipients = [m['recipient'] for m in messages] - - enviar_emails('test@sapl.com', recipients, messages) + messages = [ + { + "recipient": "user-" + str(i) + "@test.com", + "subject": "subject: " + str(i), + "txt_message": "txt: " + str(i), + "html_message": "", + } + for i in range(NUM_MESSAGES) + ] + + recipients = [m["recipient"] for m in messages] + + enviar_emails("test@sapl.com", recipients, messages) assert len(mail.outbox) == NUM_MESSAGES def test_enviar_same_email(): NUM_MESSAGES = 10 - messages = [{'recipient': 'user-' + str(i) + '@test.com', - 'subject': 'subject: ' + str(i), - 'txt_message': 'txt: ' + str(i), - 'html_message': '', - } for i in range(NUM_MESSAGES)] - - recipients = [m['recipient'] for m in messages] - - enviar_emails('test@sapl.com', recipients, [messages[0]]) + messages = [ + { + "recipient": "user-" + str(i) + "@test.com", + "subject": "subject: " + str(i), + "txt_message": "txt: " + str(i), + "html_message": "", + } + for i in range(NUM_MESSAGES) + ] + + recipients = [m["recipient"] for m in messages] + + enviar_emails("test@sapl.com", recipients, [messages[0]]) assert len(mail.outbox) == 1 diff --git a/sapl/materia/tests/test_materia.py b/sapl/materia/tests/test_materia.py index fab1742e0..04d9efa54 100644 --- a/sapl/materia/tests/test_materia.py +++ b/sapl/materia/tests/test_materia.py @@ -1,17 +1,17 @@ from datetime import date +import pytest from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType from django.core.files.uploadedfile import SimpleUploadedFile from django.db.models import Max from django.urls import reverse from model_bakery import baker -import pytest -from sapl.base.models import Autor, TipoAutor, AppConfig +from sapl.base.models import AppConfig, Autor, TipoAutor from sapl.comissoes.models import Comissao, TipoComissao -from sapl.materia.forms import (TramitacaoForm, compara_tramitacoes_mat, - TramitacaoUpdateForm) +from sapl.materia.forms import (TramitacaoForm, TramitacaoUpdateForm, + compara_tramitacoes_mat) from sapl.materia.models import (Anexada, Autoria, DespachoInicial, DocumentoAcessorio, MateriaLegislativa, Numeracao, Proposicao, RegimeTramitacao, @@ -21,26 +21,20 @@ from sapl.materia.models import (Anexada, Autoria, DespachoInicial, from sapl.norma.models import (LegislacaoCitada, NormaJuridica, TipoNormaJuridica) from sapl.parlamentares.models import Legislatura -from sapl.utils import models_with_gr_for_model, lista_anexados +from sapl.utils import lista_anexados, models_with_gr_for_model @pytest.mark.django_db(transaction=False) def test_lista_materias_anexadas(): - tipo_materia = baker.make( - TipoMateriaLegislativa, - descricao="Tipo_Teste" - ) - regime_tramitacao = baker.make( - RegimeTramitacao, - descricao="Regime_Teste" - ) + tipo_materia = baker.make(TipoMateriaLegislativa, descricao="Tipo_Teste") + regime_tramitacao = baker.make(RegimeTramitacao, descricao="Regime_Teste") materia_principal = baker.make( MateriaLegislativa, numero=20, ano=2018, data_apresentacao="2018-01-04", regime_tramitacao=regime_tramitacao, - tipo=tipo_materia + tipo=tipo_materia, ) materia_anexada = baker.make( MateriaLegislativa, @@ -48,7 +42,7 @@ def test_lista_materias_anexadas(): ano=2019, data_apresentacao="2019-05-04", regime_tramitacao=regime_tramitacao, - tipo=tipo_materia + tipo=tipo_materia, ) materia_anexada_anexada = baker.make( MateriaLegislativa, @@ -56,20 +50,20 @@ def test_lista_materias_anexadas(): ano=2020, data_apresentacao="2020-01-05", regime_tramitacao=regime_tramitacao, - tipo=tipo_materia + tipo=tipo_materia, ) baker.make( Anexada, materia_principal=materia_principal, materia_anexada=materia_anexada, - data_anexacao="2019-05-11" + data_anexacao="2019-05-11", ) baker.make( Anexada, materia_principal=materia_anexada, materia_anexada=materia_anexada_anexada, - data_anexacao="2020-11-05" + data_anexacao="2020-11-05", ) lista = lista_anexados(materia_principal) @@ -81,21 +75,15 @@ def test_lista_materias_anexadas(): @pytest.mark.django_db(transaction=False) def test_lista_materias_anexadas_ciclo(): - tipo_materia = baker.make( - TipoMateriaLegislativa, - descricao="Tipo_Teste" - ) - regime_tramitacao = baker.make( - RegimeTramitacao, - descricao="Regime_Teste" - ) + tipo_materia = baker.make(TipoMateriaLegislativa, descricao="Tipo_Teste") + regime_tramitacao = baker.make(RegimeTramitacao, descricao="Regime_Teste") materia_principal = baker.make( MateriaLegislativa, numero=20, ano=2018, data_apresentacao="2018-01-04", regime_tramitacao=regime_tramitacao, - tipo=tipo_materia + tipo=tipo_materia, ) materia_anexada = baker.make( MateriaLegislativa, @@ -103,20 +91,20 @@ def test_lista_materias_anexadas_ciclo(): ano=2019, data_apresentacao="2019-05-04", regime_tramitacao=regime_tramitacao, - tipo=tipo_materia + tipo=tipo_materia, ) baker.make( Anexada, materia_principal=materia_principal, materia_anexada=materia_anexada, - data_anexacao="2019-05-11" + data_anexacao="2019-05-11", ) baker.make( Anexada, materia_principal=materia_anexada, materia_anexada=materia_principal, - data_anexacao="2020-11-05" + data_anexacao="2020-11-05", ) lista = lista_anexados(materia_principal) @@ -129,11 +117,13 @@ def test_lista_materias_anexadas_ciclo(): def make_unidade_tramitacao(descricao): # Cria uma comissão para ser a unidade de tramitação tipo_comissao = baker.make(TipoComissao) - comissao = baker.make(Comissao, - tipo=tipo_comissao, - nome=descricao, - sigla='T', - data_criacao='2016-03-21') + comissao = baker.make( + Comissao, + tipo=tipo_comissao, + nome=descricao, + sigla="T", + data_criacao="2016-03-21", + ) # Testa a comissão assert comissao.tipo == tipo_comissao @@ -149,21 +139,21 @@ def make_unidade_tramitacao(descricao): @pytest.mark.django_db(transaction=False) def make_norma(): # Cria um novo tipo de Norma - tipo = baker.make(TipoNormaJuridica, - sigla='T1', - descricao='Teste_Tipo_Norma') - baker.make(NormaJuridica, - tipo=tipo, - numero=1, - ano=2016, - data='2016-03-21', - esfera_federacao='E', - ementa='Teste_Ementa') + tipo = baker.make(TipoNormaJuridica, sigla="T1", descricao="Teste_Tipo_Norma") + baker.make( + NormaJuridica, + tipo=tipo, + numero=1, + ano=2016, + data="2016-03-21", + esfera_federacao="E", + ementa="Teste_Ementa", + ) # Testa se a Norma foi criada norma = NormaJuridica.objects.first() assert norma.tipo == tipo - assert norma.numero == '1' + assert norma.numero == "1" assert norma.ano == 2016 return norma @@ -171,18 +161,20 @@ def make_norma(): @pytest.mark.django_db(transaction=False) def make_materia_principal(): - regime_tramitacao = baker.make(RegimeTramitacao, descricao='Teste_Regime') + regime_tramitacao = baker.make(RegimeTramitacao, descricao="Teste_Regime") # Cria a matéria principal - tipo = baker.make(TipoMateriaLegislativa, - sigla='T1', - descricao='Teste_MateriaLegislativa') - baker.make(MateriaLegislativa, - tipo=tipo, - numero='165', - ano='2002', - data_apresentacao='2003-01-01', - regime_tramitacao=regime_tramitacao) + tipo = baker.make( + TipoMateriaLegislativa, sigla="T1", descricao="Teste_MateriaLegislativa" + ) + baker.make( + MateriaLegislativa, + tipo=tipo, + numero="165", + ano="2002", + data_apresentacao="2003-01-01", + regime_tramitacao=regime_tramitacao, + ) # Testa matéria materia = MateriaLegislativa.objects.first() @@ -197,29 +189,32 @@ def test_materia_anexada_submit(admin_client): materia_principal = make_materia_principal() # Cria a matéria que será anexada - tipo_anexada = baker.make(TipoMateriaLegislativa, - sigla='T2', - descricao='Teste_2') - regime_tramitacao = baker.make(RegimeTramitacao, descricao='Teste_Regime') - baker.make(MateriaLegislativa, - tipo=tipo_anexada, - numero='32', - ano='2004', - data_apresentacao='2005-11-10', - regime_tramitacao=regime_tramitacao) + tipo_anexada = baker.make(TipoMateriaLegislativa, sigla="T2", descricao="Teste_2") + regime_tramitacao = baker.make(RegimeTramitacao, descricao="Teste_Regime") + baker.make( + MateriaLegislativa, + tipo=tipo_anexada, + numero="32", + ano="2004", + data_apresentacao="2005-11-10", + regime_tramitacao=regime_tramitacao, + ) # Testa se a matéria que será anexada foi criada materia_anexada = MateriaLegislativa.objects.get(numero=32, ano=2004) # Testa POST - response = admin_client.post(reverse('sapl.materia:anexada_create', - kwargs={'pk': materia_principal.pk}), - {'tipo': materia_anexada.tipo.pk, - 'numero': materia_anexada.numero, - 'ano': materia_anexada.ano, - 'data_anexacao': '2016-03-18', - 'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse("sapl.materia:anexada_create", kwargs={"pk": materia_principal.pk}), + { + "tipo": materia_anexada.tipo.pk, + "numero": materia_anexada.numero, + "ano": materia_anexada.ano, + "data_anexacao": "2016-03-18", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 # Verifica se a matéria foi anexada corretamente @@ -232,23 +227,22 @@ def test_materia_anexada_submit(admin_client): def test_autoria_submit(admin_client): materia_principal = make_materia_principal() # Cria um tipo de Autor - tipo_autor = baker.make(TipoAutor, descricao='Teste Tipo_Autor') + tipo_autor = baker.make(TipoAutor, descricao="Teste Tipo_Autor") # Cria um Autor - autor = baker.make( - Autor, - tipo=tipo_autor, - nome='Autor Teste') + autor = baker.make(Autor, tipo=tipo_autor, nome="Autor Teste") # Testa POST response = admin_client.post( - reverse('sapl.materia:autoria_create', - kwargs={'pk': materia_principal.pk}), - {'autor': autor.pk, - 'tipo_autor': tipo_autor.pk, - 'primeiro_autor': True, - 'materia_id': materia_principal.pk, }, - follow=True) + reverse("sapl.materia:autoria_create", kwargs={"pk": materia_principal.pk}), + { + "autor": autor.pk, + "tipo_autor": tipo_autor.pk, + "primeiro_autor": True, + "materia_id": materia_principal.pk, + }, + follow=True, + ) assert response.status_code == 200 # Verifica se o autor foi realmente criado @@ -264,19 +258,23 @@ def test_despacho_inicial_submit(admin_client): # Cria uma comissão tipo_comissao = baker.make(TipoComissao) - comissao = baker.make(Comissao, - tipo=tipo_comissao, - nome='Teste', - ativa=True, - sigla='T', - data_criacao='2016-03-18') + comissao = baker.make( + Comissao, + tipo=tipo_comissao, + nome="Teste", + ativa=True, + sigla="T", + data_criacao="2016-03-18", + ) # Testa POST - response = admin_client.post(reverse('sapl.materia:despachoinicial_create', - kwargs={'pk': materia_principal.pk}), - {'comissao': comissao.pk, - 'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse( + "sapl.materia:despachoinicial_create", kwargs={"pk": materia_principal.pk} + ), + {"comissao": comissao.pk, "salvar": "salvar"}, + follow=True, + ) assert response.status_code == 200 # Verifica se o despacho foi criado @@ -292,14 +290,17 @@ def test_numeracao_submit(admin_client): materia = make_materia_principal() # Testa POST - response = admin_client.post(reverse('sapl.materia:numeracao_create', - kwargs={'pk': materia_principal.pk}), - {'tipo_materia': materia.tipo.pk, - 'numero_materia': materia.numero, - 'ano_materia': materia.ano, - 'data_materia': '2016-03-21', - 'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse("sapl.materia:numeracao_create", kwargs={"pk": materia_principal.pk}), + { + "tipo_materia": materia.tipo.pk, + "numero_materia": materia.numero, + "ano_materia": materia.ano, + "data_materia": "2016-03-21", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 @@ -314,42 +315,43 @@ def test_documento_acessorio_submit(admin_client): materia_principal = make_materia_principal() # Cria um tipo de Autor - tipo_autor = baker.make(TipoAutor, descricao='Teste Tipo_Autor') + tipo_autor = baker.make(TipoAutor, descricao="Teste Tipo_Autor") # Cria um Autor - autor = baker.make( - Autor, - tipo=tipo_autor, - nome='Autor Teste') + autor = baker.make(Autor, tipo=tipo_autor, nome="Autor Teste") # Cria um tipo de documento - tipo = baker.make(TipoDocumento, - descricao='Teste') + tipo = baker.make(TipoDocumento, descricao="Teste") - arquivo = SimpleUploadedFile("file.pdf", - b'conteudo do arquivo', - content_type="application/pdf") + arquivo = SimpleUploadedFile( + "file.pdf", b"conteudo do arquivo", content_type="application/pdf" + ) # Testa POST - response = admin_client.post(reverse( - 'sapl.materia:documentoacessorio_create', - kwargs={'pk': materia_principal.pk}), - {'tipo': tipo.pk, - 'nome': 'teste_nome', - 'data_materia': '2016-03-21', - 'autor': autor, - 'arquivo': arquivo, - 'ementa': 'teste_ementa', - 'data': '2016-03-21', - 'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse( + "sapl.materia:documentoacessorio_create", + kwargs={"pk": materia_principal.pk}, + ), + { + "tipo": tipo.pk, + "nome": "teste_nome", + "data_materia": "2016-03-21", + "autor": autor, + "arquivo": arquivo, + "ementa": "teste_ementa", + "data": "2016-03-21", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 # Verifica se o documento foi criado doc = DocumentoAcessorio.objects.first() assert doc.tipo == tipo - assert doc.nome == 'teste_nome' + assert doc.nome == "teste_nome" assert doc.autor == str(autor) @@ -360,14 +362,18 @@ def test_legislacao_citada_submit(admin_client): # Testa POST response = admin_client.post( - reverse('sapl.materia:legislacaocitada_create', - kwargs={'pk': materia_principal.pk}), - {'tipo': norma.tipo.pk, - 'numero': norma.numero, - 'ano': norma.ano, - 'disposicao': 'disposicao', - 'salvar': 'salvar'}, - follow=True) + reverse( + "sapl.materia:legislacaocitada_create", kwargs={"pk": materia_principal.pk} + ), + { + "tipo": norma.tipo.pk, + "numero": norma.numero, + "ano": norma.ano, + "disposicao": "disposicao", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 @@ -380,81 +386,87 @@ def test_legislacao_citada_submit(admin_client): def test_tramitacao_submit(admin_client): materia_principal = make_materia_principal() # Cria status para tramitação - status_tramitacao = baker.make(StatusTramitacao, - indicador='F', - sigla='ST', - descricao='Status_Teste') + status_tramitacao = baker.make( + StatusTramitacao, indicador="F", sigla="ST", descricao="Status_Teste" + ) # Testa POST response = admin_client.post( - reverse('sapl.materia:tramitacao_create', - kwargs={'pk': materia_principal.pk}), - {'unidade_tramitacao_local': make_unidade_tramitacao( - 'Unidade Local').pk, - 'unidade_tramitacao_destino': make_unidade_tramitacao( - 'Unidade Destino').pk, - 'urgente': True, - 'status': status_tramitacao.pk, - 'data_tramitacao': '2016-03-21', - 'data_fim_prazo': '2016-03-22', - 'data_encaminhamento': '2016-03-22', - 'texto': 'Texto_Teste', - 'salvar': 'salvar'}, - follow=True) + reverse("sapl.materia:tramitacao_create", kwargs={"pk": materia_principal.pk}), + { + "unidade_tramitacao_local": make_unidade_tramitacao("Unidade Local").pk, + "unidade_tramitacao_destino": make_unidade_tramitacao("Unidade Destino").pk, + "urgente": True, + "status": status_tramitacao.pk, + "data_tramitacao": "2016-03-21", + "data_fim_prazo": "2016-03-22", + "data_encaminhamento": "2016-03-22", + "texto": "Texto_Teste", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 # Testa se a tramitacao foi criada tramitacao = Tramitacao.objects.first() - assert (tramitacao.unidade_tramitacao_local.comissao.nome == - 'Unidade Local') - assert (tramitacao.unidade_tramitacao_destino.comissao.nome == - 'Unidade Destino') + assert tramitacao.unidade_tramitacao_local.comissao.nome == "Unidade Local" + assert tramitacao.unidade_tramitacao_destino.comissao.nome == "Unidade Destino" assert tramitacao.urgente is True @pytest.mark.django_db(transaction=False) def test_form_errors_anexada(admin_client): materia_principal = make_materia_principal() - response = admin_client.post(reverse('sapl.materia:anexada_create', - kwargs={'pk': materia_principal.pk}), - {'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse("sapl.materia:anexada_create", kwargs={"pk": materia_principal.pk}), + {"salvar": "salvar"}, + follow=True, + ) - assert (response.context_data['form'].errors['tipo'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['numero'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['ano'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['data_anexacao'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["tipo"] == ["Este campo é obrigatório."] + assert response.context_data["form"].errors["numero"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["ano"] == ["Este campo é obrigatório."] + assert response.context_data["form"].errors["data_anexacao"] == [ + "Este campo é obrigatório." + ] @pytest.mark.django_db(transaction=False) def test_form_errors_autoria(admin_client): materia_principal = make_materia_principal() - response = admin_client.post(reverse('sapl.materia:autoria_create', - kwargs={'pk': materia_principal.pk}), - {'materia_id': materia_principal.pk, - 'autor_id': '', }, - follow=True) + response = admin_client.post( + reverse("sapl.materia:autoria_create", kwargs={"pk": materia_principal.pk}), + { + "materia_id": materia_principal.pk, + "autor_id": "", + }, + follow=True, + ) - assert (response.context_data['form'].errors['autor'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["autor"] == [ + "Este campo é obrigatório." + ] @pytest.mark.django_db(transaction=False) def test_form_errors_despacho_inicial(admin_client): materia_principal = make_materia_principal() - response = admin_client.post(reverse('sapl.materia:despachoinicial_create', - kwargs={'pk': materia_principal.pk}), - {'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse( + "sapl.materia:despachoinicial_create", kwargs={"pk": materia_principal.pk} + ), + {"salvar": "salvar"}, + follow=True, + ) - assert (response.context_data['form'].errors['comissao'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["comissao"] == [ + "Este campo é obrigatório." + ] @pytest.mark.django_db(transaction=False) @@ -462,15 +474,16 @@ def test_form_errors_documento_acessorio(admin_client): materia_principal = make_materia_principal() response = admin_client.post( - reverse('sapl.materia:documentoacessorio_create', - kwargs={'pk': materia_principal.pk}), - {'salvar': 'salvar'}, - follow=True) + reverse( + "sapl.materia:documentoacessorio_create", + kwargs={"pk": materia_principal.pk}, + ), + {"salvar": "salvar"}, + follow=True, + ) - assert (response.context_data['form'].errors['tipo'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['nome'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["tipo"] == ["Este campo é obrigatório."] + assert response.context_data["form"].errors["nome"] == ["Este campo é obrigatório."] @pytest.mark.django_db(transaction=False) @@ -478,36 +491,42 @@ def test_form_errors_legislacao_citada(admin_client): materia_principal = make_materia_principal() response = admin_client.post( - reverse('sapl.materia:legislacaocitada_create', - kwargs={'pk': materia_principal.pk}), - {'salvar': 'salvar'}, - follow=True) + reverse( + "sapl.materia:legislacaocitada_create", kwargs={"pk": materia_principal.pk} + ), + {"salvar": "salvar"}, + follow=True, + ) - assert (response.context_data['form'].errors['tipo'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['numero'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['ano'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["tipo"] == ["Este campo é obrigatório."] + assert response.context_data["form"].errors["numero"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["ano"] == ["Este campo é obrigatório."] @pytest.mark.django_db(transaction=False) def test_form_errors_numeracao(admin_client): materia_principal = make_materia_principal() - response = admin_client.post(reverse('sapl.materia:numeracao_create', - kwargs={'pk': materia_principal.pk}), - {'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse("sapl.materia:numeracao_create", kwargs={"pk": materia_principal.pk}), + {"salvar": "salvar"}, + follow=True, + ) - assert (response.context_data['form'].errors['tipo_materia'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['numero_materia'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['ano_materia'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['data_materia'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["tipo_materia"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["numero_materia"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["ano_materia"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["data_materia"] == [ + "Este campo é obrigatório." + ] @pytest.mark.django_db(transaction=False) @@ -515,19 +534,23 @@ def test_form_errors_tramitacao(admin_client): materia_principal = make_materia_principal() response = admin_client.post( - reverse('sapl.materia:tramitacao_create', - kwargs={'pk': materia_principal.pk}), - {'salvar': 'salvar'}, - follow=True) + reverse("sapl.materia:tramitacao_create", kwargs={"pk": materia_principal.pk}), + {"salvar": "salvar"}, + follow=True, + ) - assert (response.context_data['form'].errors['data_tramitacao'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors[ - 'unidade_tramitacao_local'] == ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['status'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors[ - 'unidade_tramitacao_destino'] == ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["data_tramitacao"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["unidade_tramitacao_local"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["status"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["unidade_tramitacao_destino"] == [ + "Este campo é obrigatório." + ] @pytest.mark.django_db(transaction=False) @@ -535,330 +558,345 @@ def test_form_errors_relatoria(admin_client): materia_principal = make_materia_principal() response = admin_client.post( - reverse('sapl.materia:relatoria_create', - kwargs={'pk': materia_principal.pk}), - {'salvar': 'salvar'}, - follow=True) + reverse("sapl.materia:relatoria_create", kwargs={"pk": materia_principal.pk}), + {"salvar": "salvar"}, + follow=True, + ) - assert (response.context_data['form'].errors['data_designacao_relator'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['parlamentar'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["data_designacao_relator"] == [ + "Este campo é obrigatório." + ] + assert response.context_data["form"].errors["parlamentar"] == [ + "Este campo é obrigatório." + ] @pytest.mark.django_db(transaction=False) def test_proposicao_submit(admin_client): - tipo_autor = baker.make(TipoAutor, descricao='Teste Tipo_Autor') + tipo_autor = baker.make(TipoAutor, descricao="Teste Tipo_Autor") user = get_user_model().objects.filter(is_active=True)[0] - autor = baker.make( - Autor, - tipo=tipo_autor, - nome='Autor Teste') + autor = baker.make(Autor, tipo=tipo_autor, nome="Autor Teste") autor.operadores.add(user) - file_content = 'file_content' - texto = SimpleUploadedFile("file.txt", file_content.encode('UTF-8')) + file_content = "file_content" + texto = SimpleUploadedFile("file.txt", file_content.encode("UTF-8")) - mcts = ContentType.objects.get_for_models( - *models_with_gr_for_model(TipoProposicao)) + mcts = ContentType.objects.get_for_models(*models_with_gr_for_model(TipoProposicao)) for pk, mct in enumerate(mcts): tipo_conteudo_related = baker.make(mct, pk=pk + 1) response = admin_client.post( - reverse('sapl.materia:proposicao_create'), - {'tipo': baker.make( - TipoProposicao, pk=3, - tipo_conteudo_related=tipo_conteudo_related).pk, - 'descricao': 'Teste proposição', - 'justificativa_devolucao': ' ', - 'status': 'E', - 'autor': autor.pk, - 'texto_original': texto, - 'salvar': 'salvar', - 'receber_recibo': 'True', - }, - follow=True) + reverse("sapl.materia:proposicao_create"), + { + "tipo": baker.make( + TipoProposicao, pk=3, tipo_conteudo_related=tipo_conteudo_related + ).pk, + "descricao": "Teste proposição", + "justificativa_devolucao": " ", + "status": "E", + "autor": autor.pk, + "texto_original": texto, + "salvar": "salvar", + "receber_recibo": "True", + }, + follow=True, + ) assert response.status_code == 200 proposicao = Proposicao.objects.first() assert proposicao is not None - assert proposicao.descricao == 'Teste proposição' + assert proposicao.descricao == "Teste proposição" assert proposicao.tipo.pk == 3 assert proposicao.tipo.tipo_conteudo_related.pk == pk + 1 @pytest.mark.django_db(transaction=False) def test_form_errors_proposicao(admin_client): - tipo_autor = baker.make(TipoAutor, descricao='Teste Tipo_Autor') + tipo_autor = baker.make(TipoAutor, descricao="Teste Tipo_Autor") user = get_user_model().objects.filter(is_active=True)[0] - autor = baker.make( - Autor, - tipo=tipo_autor, - nome='Autor Teste') + autor = baker.make(Autor, tipo=tipo_autor, nome="Autor Teste") autor.operadores.add(user) - file_content = 'file_content' - texto = SimpleUploadedFile("file.txt", file_content.encode('UTF-8')) + file_content = "file_content" + texto = SimpleUploadedFile("file.txt", file_content.encode("UTF-8")) - response = admin_client.post(reverse('sapl.materia:proposicao_create'), - {'autor': autor.pk, - 'justificativa_devolucao': ' ', - 'texto_original': texto, - 'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse("sapl.materia:proposicao_create"), + { + "autor": autor.pk, + "justificativa_devolucao": " ", + "texto_original": texto, + "salvar": "salvar", + }, + follow=True, + ) - assert (response.context_data['form'].errors['tipo'] == - ['Este campo é obrigatório.']) - assert (response.context_data['form'].errors['descricao'] == - ['Este campo é obrigatório.']) + assert response.context_data["form"].errors["tipo"] == ["Este campo é obrigatório."] + assert response.context_data["form"].errors["descricao"] == [ + "Este campo é obrigatório." + ] @pytest.mark.django_db(transaction=False) def test_numeracao_materia_legislativa_por_legislatura(admin_client): - # Criar Legislaturas - legislatura1 = baker.make(Legislatura, - data_inicio='2014-01-01', - data_fim='2018-12-31', - numero=20, - data_eleicao='2013-10-15' - ) - legislatura2 = baker.make(Legislatura, - data_inicio='2009-01-01', - data_fim='2013-12-31', - numero=21, - data_eleicao='2018-10-15' - ) + legislatura1 = baker.make( + Legislatura, + data_inicio="2014-01-01", + data_fim="2018-12-31", + numero=20, + data_eleicao="2013-10-15", + ) + legislatura2 = baker.make( + Legislatura, + data_inicio="2009-01-01", + data_fim="2013-12-31", + numero=21, + data_eleicao="2018-10-15", + ) # Cria uma materia na legislatura1 - tipo_materia = baker.make(TipoMateriaLegislativa, - id=1, sequencia_numeracao='L') - materia = baker.make(MateriaLegislativa, - tipo=tipo_materia, - ano=2017, - numero=1, - data_apresentacao='2017-03-05' - ) + tipo_materia = baker.make(TipoMateriaLegislativa, id=1, sequencia_numeracao="L") + materia = baker.make( + MateriaLegislativa, + tipo=tipo_materia, + ano=2017, + numero=1, + data_apresentacao="2017-03-05", + ) - url = reverse('sapl.materia:recuperar_materia') + url = reverse("sapl.materia:recuperar_materia") # Testa numeração do Materia Legislativa na Legislatura1 - query_params = '?tipo={}&ano={}'.format(materia.tipo.id, materia.ano) + query_params = "?tipo={}&ano={}".format(materia.tipo.id, materia.ano) response = admin_client.get(url + query_params, follow=True) - response_content = eval(response.content.decode('ascii')) + response_content = eval(response.content.decode("ascii")) esperado_legislatura1 = eval('{"numero": 2, "ano": "2017"}') - assert response_content['numero'] == esperado_legislatura1['numero'] + assert response_content["numero"] == esperado_legislatura1["numero"] # Testa numeração do Materia Legislativa na Legislatura2 - query_params = '?tipo={}&ano={}'.format(1, '2010') + query_params = "?tipo={}&ano={}".format(1, "2010") response = admin_client.get(url + query_params, follow=True) - response_content = eval(response.content.decode('ascii')) + response_content = eval(response.content.decode("ascii")) esperado_legislatura2 = eval('{"ano": "2010", "numero": 1}') - assert response_content['numero'] == esperado_legislatura2['numero'] + assert response_content["numero"] == esperado_legislatura2["numero"] @pytest.mark.django_db(transaction=False) def test_numeracao_materia_legislativa_por_ano(admin_client): - # Cria uma materia - tipo_materia = baker.make(TipoMateriaLegislativa, - id=1, sequencia_numeracao='A') - materia = baker.make(MateriaLegislativa, - tipo=tipo_materia, - ano=2017, - numero=1 - ) + tipo_materia = baker.make(TipoMateriaLegislativa, id=1, sequencia_numeracao="A") + materia = baker.make(MateriaLegislativa, tipo=tipo_materia, ano=2017, numero=1) - url = reverse('sapl.materia:recuperar_materia') + url = reverse("sapl.materia:recuperar_materia") # Testa numeração da Materia Legislativa no ano da materia criada - query_params = '?tipo={}&ano={}'.format(materia.tipo.id, materia.ano) + query_params = "?tipo={}&ano={}".format(materia.tipo.id, materia.ano) response = admin_client.get(url + query_params, follow=True) - response_content = eval(response.content.decode('ascii')) + response_content = eval(response.content.decode("ascii")) esperado_ano = eval('{"numero": 2, "ano": "2017"}') - assert response_content['numero'] == esperado_ano['numero'] + assert response_content["numero"] == esperado_ano["numero"] # Testa numeração da Materia Legislativa de outro ano - query_params = '?tipo={}&ano={}'.format(1, '2010') + query_params = "?tipo={}&ano={}".format(1, "2010") response = admin_client.get(url + query_params, follow=True) - response_content = eval(response.content.decode('ascii')) + response_content = eval(response.content.decode("ascii")) esperado_outro_ano = eval('{"ano": "2010", "numero": 1}') - assert response_content['numero'] == esperado_outro_ano['numero'] + assert response_content["numero"] == esperado_outro_ano["numero"] @pytest.mark.django_db(transaction=False) def test_tramitacoes_materias_anexadas(admin_client): config = baker.make(AppConfig, tramitacao_materia=True) - tipo_materia = baker.make( - TipoMateriaLegislativa, - descricao="Tipo_Teste" - ) + tipo_materia = baker.make(TipoMateriaLegislativa, descricao="Tipo_Teste") materia_principal = baker.make( - MateriaLegislativa, - ano=2018, - data_apresentacao="2018-01-04", - tipo=tipo_materia + MateriaLegislativa, ano=2018, data_apresentacao="2018-01-04", tipo=tipo_materia ) materia_anexada = baker.make( - MateriaLegislativa, - ano=2019, - data_apresentacao="2019-05-04", - tipo=tipo_materia + MateriaLegislativa, ano=2019, data_apresentacao="2019-05-04", tipo=tipo_materia ) materia_anexada_anexada = baker.make( - MateriaLegislativa, - ano=2020, - data_apresentacao="2020-01-05", - tipo=tipo_materia + MateriaLegislativa, ano=2020, data_apresentacao="2020-01-05", tipo=tipo_materia ) baker.make( Anexada, materia_principal=materia_principal, materia_anexada=materia_anexada, - data_anexacao="2019-05-11" + data_anexacao="2019-05-11", ) baker.make( Anexada, materia_principal=materia_anexada, materia_anexada=materia_anexada_anexada, - data_anexacao="2020-11-05" + data_anexacao="2020-11-05", ) unidade_tramitacao_local_1 = make_unidade_tramitacao(descricao="Teste 1") unidade_tramitacao_destino_1 = make_unidade_tramitacao(descricao="Teste 2") unidade_tramitacao_destino_2 = make_unidade_tramitacao(descricao="Teste 3") - status = baker.make( - StatusTramitacao, - indicador='R') + status = baker.make(StatusTramitacao, indicador="R") # Teste criação de Tramitacao form = TramitacaoForm(data={}) - form.data = {'data_tramitacao': date(2019, 5, 6), - 'unidade_tramitacao_local': unidade_tramitacao_local_1.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.pk, - 'status': status.pk, - 'urgente': False, - 'texto': "Texto de teste"} + form.data = { + "data_tramitacao": date(2019, 5, 6), + "unidade_tramitacao_local": unidade_tramitacao_local_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.pk, + "status": status.pk, + "urgente": False, + "texto": "Texto de teste", + } form.instance.materia_id = materia_principal.pk assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = materia_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() tramitacao_anexada_anexada = materia_anexada_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() # Verifica se foram criadas as tramitações para as matérias anexadas e # anexadas às anexadas - assert materia_principal.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() == tramitacao_principal + assert ( + materia_principal.tramitacao_set.order_by("-data_tramitacao", "-id").first() + == tramitacao_principal + ) assert tramitacao_principal.materia.em_tramitacao == ( - tramitacao_principal.status.indicador != "F") + tramitacao_principal.status.indicador != "F" + ) assert compara_tramitacoes_mat(tramitacao_principal, tramitacao_anexada) - assert MateriaLegislativa.objects.get(id=materia_anexada.pk).em_tramitacao \ - == (tramitacao_anexada.status.indicador != "F") - assert compara_tramitacoes_mat( - tramitacao_anexada_anexada, tramitacao_principal) - assert MateriaLegislativa.objects.get(id=materia_anexada_anexada.pk).em_tramitacao \ - == (tramitacao_anexada_anexada.status.indicador != "F") + assert MateriaLegislativa.objects.get(id=materia_anexada.pk).em_tramitacao == ( + tramitacao_anexada.status.indicador != "F" + ) + assert compara_tramitacoes_mat(tramitacao_anexada_anexada, tramitacao_principal) + assert MateriaLegislativa.objects.get( + id=materia_anexada_anexada.pk + ).em_tramitacao == (tramitacao_anexada_anexada.status.indicador != "F") # Teste Edição de Tramitacao form = TramitacaoUpdateForm(data={}) # Alterando unidade_tramitacao_destino - form.data = {'data_tramitacao': tramitacao_principal.data_tramitacao, - 'unidade_tramitacao_local': tramitacao_principal.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.pk, - 'status': tramitacao_principal.status.pk, - 'urgente': tramitacao_principal.urgente, - 'texto': tramitacao_principal.texto} + form.data = { + "data_tramitacao": tramitacao_principal.data_tramitacao, + "unidade_tramitacao_local": tramitacao_principal.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "status": tramitacao_principal.status.pk, + "urgente": tramitacao_principal.urgente, + "texto": tramitacao_principal.texto, + } form.instance = tramitacao_principal assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = materia_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() tramitacao_anexada_anexada = materia_anexada_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() - assert tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + assert ( + tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + ) assert tramitacao_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 - assert tramitacao_anexada_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + assert ( + tramitacao_anexada_anexada.unidade_tramitacao_destino + == unidade_tramitacao_destino_2 + ) # Teste Remoção de Tramitacao - url = reverse('sapl.materia:tramitacao_delete', - kwargs={'pk': tramitacao_principal.pk}) - response = admin_client.post(url, {'confirmar': 'confirmar'}, follow=True) + url = reverse( + "sapl.materia:tramitacao_delete", kwargs={"pk": tramitacao_principal.pk} + ) + response = admin_client.post(url, {"confirmar": "confirmar"}, follow=True) assert Tramitacao.objects.filter(id=tramitacao_principal.pk).count() == 0 assert Tramitacao.objects.filter(id=tramitacao_anexada.pk).count() == 0 - assert Tramitacao.objects.filter( - id=tramitacao_anexada_anexada.pk).count() == 0 + assert Tramitacao.objects.filter(id=tramitacao_anexada_anexada.pk).count() == 0 # Testes para quando as tramitações das anexadas divergem form = TramitacaoForm(data={}) - form.data = {'data_tramitacao': date(2019, 5, 6), - 'unidade_tramitacao_local': unidade_tramitacao_local_1.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.pk, - 'status': status.pk, - 'urgente': False, - 'texto': "Texto de teste"} + form.data = { + "data_tramitacao": date(2019, 5, 6), + "unidade_tramitacao_local": unidade_tramitacao_local_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.pk, + "status": status.pk, + "urgente": False, + "texto": "Texto de teste", + } form.instance.materia_id = materia_principal.pk assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = materia_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() tramitacao_anexada_anexada = materia_anexada_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() form = TramitacaoUpdateForm(data={}) # Alterando unidade_tramitacao_destino - form.data = {'data_tramitacao': tramitacao_anexada.data_tramitacao, - 'unidade_tramitacao_local': tramitacao_anexada.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.pk, - 'status': tramitacao_anexada.status.pk, - 'urgente': tramitacao_anexada.urgente, - 'texto': tramitacao_anexada.texto} + form.data = { + "data_tramitacao": tramitacao_anexada.data_tramitacao, + "unidade_tramitacao_local": tramitacao_anexada.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "status": tramitacao_anexada.status.pk, + "urgente": tramitacao_anexada.urgente, + "texto": tramitacao_anexada.texto, + } form.instance = tramitacao_anexada assert form.is_valid() tramitacao_anexada = form.save() tramitacao_anexada_anexada = materia_anexada_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() - assert tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_1 + assert ( + tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_1 + ) assert tramitacao_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 - assert tramitacao_anexada_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + assert ( + tramitacao_anexada_anexada.unidade_tramitacao_destino + == unidade_tramitacao_destino_2 + ) # Editando a tramitação principal, as tramitações anexadas não devem ser # editadas form = TramitacaoUpdateForm(data={}) # Alterando o texto - form.data = {'data_tramitacao': tramitacao_principal.data_tramitacao, - 'unidade_tramitacao_local': tramitacao_principal.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino': tramitacao_principal.unidade_tramitacao_destino.pk, - 'status': tramitacao_principal.status.pk, - 'urgente': tramitacao_principal.urgente, - 'texto': "Testando a alteração"} + form.data = { + "data_tramitacao": tramitacao_principal.data_tramitacao, + "unidade_tramitacao_local": tramitacao_principal.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": tramitacao_principal.unidade_tramitacao_destino.pk, + "status": tramitacao_principal.status.pk, + "urgente": tramitacao_principal.urgente, + "texto": "Testando a alteração", + } form.instance = tramitacao_principal assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = materia_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() tramitacao_anexada_anexada = materia_anexada_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() assert tramitacao_principal.texto == "Testando a alteração" assert not tramitacao_anexada.texto == "Testando a alteração" @@ -866,22 +904,22 @@ def test_tramitacoes_materias_anexadas(admin_client): # Removendo a tramitação pricipal, as tramitações anexadas não devem ser # removidas, pois divergiram - url = reverse('sapl.materia:tramitacao_delete', - kwargs={'pk': tramitacao_principal.pk}) - response = admin_client.post(url, {'confirmar': 'confirmar'}, follow=True) + url = reverse( + "sapl.materia:tramitacao_delete", kwargs={"pk": tramitacao_principal.pk} + ) + response = admin_client.post(url, {"confirmar": "confirmar"}, follow=True) assert Tramitacao.objects.filter(id=tramitacao_principal.pk).count() == 0 assert Tramitacao.objects.filter(id=tramitacao_anexada.pk).count() == 1 - assert Tramitacao.objects.filter( - id=tramitacao_anexada_anexada.pk).count() == 1 + assert Tramitacao.objects.filter(id=tramitacao_anexada_anexada.pk).count() == 1 # Removendo a tramitação anexada, a tramitação anexada à anexada deve ser # removida - url = reverse('sapl.materia:tramitacao_delete', - kwargs={'pk': tramitacao_anexada.pk}) - response = admin_client.post(url, {'confirmar': 'confirmar'}, follow=True) + url = reverse( + "sapl.materia:tramitacao_delete", kwargs={"pk": tramitacao_anexada.pk} + ) + response = admin_client.post(url, {"confirmar": "confirmar"}, follow=True) assert Tramitacao.objects.filter(id=tramitacao_anexada.pk).count() == 0 - assert Tramitacao.objects.filter( - id=tramitacao_anexada_anexada.pk).count() == 0 + assert Tramitacao.objects.filter(id=tramitacao_anexada_anexada.pk).count() == 0 # Agora testando para caso não seja desejado tramitar as matérias anexadas # junto com as matérias principais @@ -893,95 +931,123 @@ def test_tramitacoes_materias_anexadas(admin_client): # Teste criação de Tramitacao form = TramitacaoForm(data={}) - form.data = {'data_tramitacao': date(2019, 5, 6), - 'unidade_tramitacao_local': unidade_tramitacao_local_1.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.pk, - 'status': status.pk, - 'urgente': False, - 'texto': "Texto de teste"} + form.data = { + "data_tramitacao": date(2019, 5, 6), + "unidade_tramitacao_local": unidade_tramitacao_local_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.pk, + "status": status.pk, + "urgente": False, + "texto": "Texto de teste", + } form.instance.materia_id = materia_principal.pk assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = materia_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() tramitacao_anexada_anexada = materia_anexada_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() # Deve ser criada tramitação apenas para a matéria principal - assert materia_principal.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() == tramitacao_principal + assert ( + materia_principal.tramitacao_set.order_by("-data_tramitacao", "-id").first() + == tramitacao_principal + ) assert not tramitacao_anexada assert not tramitacao_anexada_anexada # Criação de uma tramitação igual para a anexada à principal para testar a # edição form = TramitacaoForm(data={}) - form.data = {'data_tramitacao': date(2019, 5, 6), - 'unidade_tramitacao_local': unidade_tramitacao_local_1.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.pk, - 'status': status.pk, - 'urgente': False, - 'texto': "Texto de teste"} + form.data = { + "data_tramitacao": date(2019, 5, 6), + "unidade_tramitacao_local": unidade_tramitacao_local_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.pk, + "status": status.pk, + "urgente": False, + "texto": "Texto de teste", + } form.instance.materia_id = materia_anexada.pk assert form.is_valid() tramitacao_anexada = form.save() tramitacao_principal = materia_principal.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() tramitacao_anexada_anexada = materia_anexada_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() - assert materia_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() == tramitacao_anexada - assert materia_principal.tramitacao_set.order_by( - '-data_tramitacao', '-id').all().count() == 1 + assert ( + materia_anexada.tramitacao_set.order_by("-data_tramitacao", "-id").first() + == tramitacao_anexada + ) + assert ( + materia_principal.tramitacao_set.order_by("-data_tramitacao", "-id") + .all() + .count() + == 1 + ) assert compara_tramitacoes_mat(tramitacao_principal, tramitacao_anexada) assert not tramitacao_anexada_anexada # Teste Edição de Tramitacao form = TramitacaoUpdateForm(data={}) # Alterando unidade_tramitacao_destino - form.data = {'data_tramitacao': tramitacao_principal.data_tramitacao, - 'unidade_tramitacao_local': tramitacao_principal.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.pk, - 'status': tramitacao_principal.status.pk, - 'urgente': tramitacao_principal.urgente, - 'texto': tramitacao_principal.texto} + form.data = { + "data_tramitacao": tramitacao_principal.data_tramitacao, + "unidade_tramitacao_local": tramitacao_principal.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "status": tramitacao_principal.status.pk, + "urgente": tramitacao_principal.urgente, + "texto": tramitacao_principal.texto, + } form.instance = tramitacao_principal assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = materia_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() tramitacao_anexada_anexada = materia_anexada_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() - assert tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + assert ( + tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + ) assert tramitacao_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_1 assert not tramitacao_anexada_anexada # Alterando a tramitação anexada para testar a remoção de tramitações # Alterando unidade_tramitacao_destino form = TramitacaoUpdateForm(data={}) - form.data = {'data_tramitacao': tramitacao_principal.data_tramitacao, - 'unidade_tramitacao_local': tramitacao_principal.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.pk, - 'status': tramitacao_principal.status.pk, - 'urgente': tramitacao_principal.urgente, - 'texto': tramitacao_principal.texto} + form.data = { + "data_tramitacao": tramitacao_principal.data_tramitacao, + "unidade_tramitacao_local": tramitacao_principal.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "status": tramitacao_principal.status.pk, + "urgente": tramitacao_principal.urgente, + "texto": tramitacao_principal.texto, + } form.instance = tramitacao_anexada assert form.is_valid() tramitacao_anexada = form.save() tramitacao_principal = materia_principal.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() tramitacao_anexada_anexada = materia_anexada_anexada.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() - assert tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + assert ( + tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + ) assert tramitacao_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 assert not tramitacao_anexada_anexada assert compara_tramitacoes_mat(tramitacao_principal, tramitacao_anexada) @@ -989,8 +1055,9 @@ def test_tramitacoes_materias_anexadas(admin_client): # Testando a remoção # Removendo a tramitação pricipal, as tramitações anexadas não devem ser # removidas - url = reverse('sapl.materia:tramitacao_delete', - kwargs={'pk': tramitacao_principal.pk}) - response = admin_client.post(url, {'confirmar': 'confirmar'}, follow=True) + url = reverse( + "sapl.materia:tramitacao_delete", kwargs={"pk": tramitacao_principal.pk} + ) + response = admin_client.post(url, {"confirmar": "confirmar"}, follow=True) assert Tramitacao.objects.filter(id=tramitacao_principal.pk).count() == 0 assert Tramitacao.objects.filter(id=tramitacao_anexada.pk).count() == 1 diff --git a/sapl/materia/tests/test_materia_form.py b/sapl/materia/tests/test_materia_form.py index 9501dac83..99386868b 100644 --- a/sapl/materia/tests/test_materia_form.py +++ b/sapl/materia/tests/test_materia_form.py @@ -15,9 +15,9 @@ def test_valida_campos_obrigatorios_ficha_pesquisa_form(): errors = form.errors - assert errors['tipo_materia'] == [_('Este campo é obrigatório.')] - assert errors['data_inicial'] == [_('Este campo é obrigatório.')] - assert errors['data_final'] == [_('Este campo é obrigatório.')] + assert errors["tipo_materia"] == [_("Este campo é obrigatório.")] + assert errors["data_inicial"] == [_("Este campo é obrigatório.")] + assert errors["data_final"] == [_("Este campo é obrigatório.")] assert len(errors) == 3 @@ -26,23 +26,30 @@ def test_valida_campos_obrigatorios_ficha_pesquisa_form(): def test_ficha_pesquisa_form_datas_invalidas(): tipo = baker.make(TipoMateriaLegislativa) - form = forms.FichaPesquisaForm(data={'tipo_materia': str(tipo.pk), - 'data_inicial': '10/11/2017', - 'data_final': '09/11/2017' - }) + form = forms.FichaPesquisaForm( + data={ + "tipo_materia": str(tipo.pk), + "data_inicial": "10/11/2017", + "data_final": "09/11/2017", + } + ) assert not form.is_valid() - assert form.errors['__all__'] == [_('A Data Final não pode ser menor que ' - 'a Data Inicial')] + assert form.errors["__all__"] == [ + _("A Data Final não pode ser menor que " "a Data Inicial") + ] @pytest.mark.django_db(transaction=False) def test_ficha_pesquisa_form_invalido(): tipo = baker.make(TipoMateriaLegislativa) - form = forms.FichaPesquisaForm(data={'tipo_materia': str(tipo.pk), - 'data_inicial': '10/11/2017', - 'data_final': '09/11/2017' - }) + form = forms.FichaPesquisaForm( + data={ + "tipo_materia": str(tipo.pk), + "data_inicial": "10/11/2017", + "data_final": "09/11/2017", + } + ) assert not form.is_valid() @@ -55,7 +62,7 @@ def test_valida_campos_obrigatorios_ficha_seleciona_form(): errors = form.errors - assert errors['materia'] == [_('Este campo é obrigatório.')] + assert errors["materia"] == [_("Este campo é obrigatório.")] assert len(errors) == 1 @@ -64,7 +71,7 @@ def test_valida_campos_obrigatorios_ficha_seleciona_form(): def test_ficha_seleciona_form_valido(): materia = baker.make(MateriaLegislativa) - form = forms.FichaSelecionaForm(data={'materia': str(materia.pk)}) + form = forms.FichaSelecionaForm(data={"materia": str(materia.pk)}) assert form.is_valid() @@ -76,13 +83,13 @@ def test_valida_campos_obrigatorios_materialegislativa_form(): assert not form.is_valid() errors = form.errors - assert errors['tipo'] == [_('Este campo é obrigatório.')] - assert errors['ano'] == [_('Este campo é obrigatório.')] - assert errors['data_apresentacao'] == [_('Este campo é obrigatório.')] - assert errors['numero'] == [_('Este campo é obrigatório.')] - assert errors['ementa'] == [_('Este campo é obrigatório.')] - assert errors['regime_tramitacao'] == [_('Este campo é obrigatório.')] - assert errors['em_tramitacao'] == [_('Este campo é obrigatório.')] + assert errors["tipo"] == [_("Este campo é obrigatório.")] + assert errors["ano"] == [_("Este campo é obrigatório.")] + assert errors["data_apresentacao"] == [_("Este campo é obrigatório.")] + assert errors["numero"] == [_("Este campo é obrigatório.")] + assert errors["ementa"] == [_("Este campo é obrigatório.")] + assert errors["regime_tramitacao"] == [_("Este campo é obrigatório.")] + assert errors["em_tramitacao"] == [_("Este campo é obrigatório.")] assert len(errors) == 7 @@ -93,7 +100,8 @@ def test_valida_campos_obrigatorios_unidade_tramitacao_form(): assert not form.is_valid() errors = form.errors - assert errors['__all__'] == [_('Somente um campo deve ser preenchido!')] + assert errors["__all__"] == [_("Somente um campo deve ser preenchido!")] + @pytest.mark.django_db(transaction=False) def test_valida_campos_obrigatorios_orgao_form(): @@ -102,9 +110,9 @@ def test_valida_campos_obrigatorios_orgao_form(): assert not form.is_valid() errors = form.errors - assert errors['nome'] == [_('Este campo é obrigatório.')] - assert errors['sigla'] == [_('Este campo é obrigatório.')] - assert errors['unidade_deliberativa'] == [_('Este campo é obrigatório.')] + assert errors["nome"] == [_("Este campo é obrigatório.")] + assert errors["sigla"] == [_("Este campo é obrigatório.")] + assert errors["unidade_deliberativa"] == [_("Este campo é obrigatório.")] assert len(errors) == 3 @@ -116,14 +124,15 @@ def test_valida_campos_obrigatorios_materia_assunto_form(): errors = form.errors - assert errors['assunto'] == [_('Este campo é obrigatório.')] - assert errors['materia'] == [_('Este campo é obrigatório.')] + assert errors["assunto"] == [_("Este campo é obrigatório.")] + assert errors["materia"] == [_("Este campo é obrigatório.")] assert len(errors) == 2 + @pytest.mark.django_db(transaction=False) def test_valida_campos_obrigatorios_autoria_form(): - form = forms.AutoriaForm(data={},instance=None) + form = forms.AutoriaForm(data={}, instance=None) assert not form.is_valid() @@ -131,9 +140,9 @@ def test_valida_campos_obrigatorios_autoria_form(): assert len(errors) == 3 - assert errors['tipo_autor'] == [_('Este campo é obrigatório.')] - assert errors['autor'] == [_('Este campo é obrigatório.')] - assert errors['primeiro_autor'] == [_('Este campo é obrigatório.')] + assert errors["tipo_autor"] == [_("Este campo é obrigatório.")] + assert errors["autor"] == [_("Este campo é obrigatório.")] + assert errors["primeiro_autor"] == [_("Este campo é obrigatório.")] @pytest.mark.django_db(transaction=False) @@ -146,10 +155,12 @@ def test_valida_campos_obrigatorios_autoria_multicreate_form(): assert len(errors) == 4 - assert errors['__all__'] == [_('Ao menos um autor deve ser selecionado para inclusão')] - assert errors['tipo_autor'] == [_('Este campo é obrigatório.')] - assert errors['autor'] == [_('Este campo é obrigatório.')] - assert errors['primeiro_autor'] == [_('Este campo é obrigatório.')] + assert errors["__all__"] == [ + _("Ao menos um autor deve ser selecionado para inclusão") + ] + assert errors["tipo_autor"] == [_("Este campo é obrigatório.")] + assert errors["autor"] == [_("Este campo é obrigatório.")] + assert errors["primeiro_autor"] == [_("Este campo é obrigatório.")] @pytest.mark.django_db(transaction=False) @@ -159,12 +170,13 @@ def test_valida_campos_obrigatorios_tipo_proposicao_form(): assert not form.is_valid() errors = form.errors - assert errors['tipo_conteudo_related'] == [_('Este campo é obrigatório.')] - assert errors['descricao'] == [_('Este campo é obrigatório.')] - assert errors['content_type'] == [_('Este campo é obrigatório.')] + assert errors["tipo_conteudo_related"] == [_("Este campo é obrigatório.")] + assert errors["descricao"] == [_("Este campo é obrigatório.")] + assert errors["content_type"] == [_("Este campo é obrigatório.")] assert len(errors) == 3 + @pytest.mark.django_db(transaction=False) def test_valida_campos_obrigatorios_devolver_proposicao_form(): form = forms.DevolverProposicaoForm(data={}) @@ -172,27 +184,30 @@ def test_valida_campos_obrigatorios_devolver_proposicao_form(): assert not form.is_valid() errors = form.errors - assert errors['__all__'] == [_('Adicione uma Justificativa para devolução.')] + assert errors["__all__"] == [_("Adicione uma Justificativa para devolução.")] assert len(errors) == 1 + @pytest.mark.django_db(transaction=False) def test_valida_campos_obrigatorios_relatoria_form(): tipo_comissao = baker.make(TipoComissao) - comissao = baker.make(Comissao, - tipo=tipo_comissao, - nome='Comissao Teste', - sigla='T', - data_criacao='2016-03-21') - form = forms.RelatoriaForm(initial={'comissao':comissao}, data={}) + comissao = baker.make( + Comissao, + tipo=tipo_comissao, + nome="Comissao Teste", + sigla="T", + data_criacao="2016-03-21", + ) + form = forms.RelatoriaForm(initial={"comissao": comissao}, data={}) assert not form.is_valid() errors = form.errors - assert errors['parlamentar'] == [_('Este campo é obrigatório.')] - assert errors['data_designacao_relator'] == [_('Este campo é obrigatório.')] - assert errors['composicao'] == [_('Este campo é obrigatório.')] + assert errors["parlamentar"] == [_("Este campo é obrigatório.")] + assert errors["data_designacao_relator"] == [_("Este campo é obrigatório.")] + assert errors["composicao"] == [_("Este campo é obrigatório.")] assert len(errors) == 3 @@ -205,11 +220,11 @@ def test_valida_campos_obrigatorios_tramitacao_form(): errors = form.errors - assert errors['unidade_tramitacao_local'] == [_('Este campo é obrigatório.')] - assert errors['status'] == [_('Este campo é obrigatório.')] - assert errors['data_tramitacao'] == [_('Este campo é obrigatório.')] - assert errors['unidade_tramitacao_destino'] == [_('Este campo é obrigatório.')] - assert errors['urgente'] == [_('Este campo é obrigatório.')] + assert errors["unidade_tramitacao_local"] == [_("Este campo é obrigatório.")] + assert errors["status"] == [_("Este campo é obrigatório.")] + assert errors["data_tramitacao"] == [_("Este campo é obrigatório.")] + assert errors["unidade_tramitacao_destino"] == [_("Este campo é obrigatório.")] + assert errors["urgente"] == [_("Este campo é obrigatório.")] assert len(errors) == 5 @@ -222,11 +237,11 @@ def test_valida_campos_obrigatorios_tramitacao_update_form(): errors = form.errors - assert errors['unidade_tramitacao_local'] == [_('Este campo é obrigatório.')] - assert errors['status'] == [_('Este campo é obrigatório.')] - assert errors['data_tramitacao'] == [_('Este campo é obrigatório.')] - assert errors['unidade_tramitacao_destino'] == [_('Este campo é obrigatório.')] - assert errors['urgente'] == [_('Este campo é obrigatório.')] + assert errors["unidade_tramitacao_local"] == [_("Este campo é obrigatório.")] + assert errors["status"] == [_("Este campo é obrigatório.")] + assert errors["data_tramitacao"] == [_("Este campo é obrigatório.")] + assert errors["unidade_tramitacao_destino"] == [_("Este campo é obrigatório.")] + assert errors["urgente"] == [_("Este campo é obrigatório.")] assert len(errors) == 5 @@ -238,9 +253,9 @@ def test_valida_campos_obrigatorios_legislacao_citada_form(): assert not form.is_valid() errors = form.errors - assert errors['tipo'] == [_('Este campo é obrigatório.')] - assert errors['ano'] == [_('Este campo é obrigatório.')] - assert errors['numero'] == [_('Este campo é obrigatório.')] + assert errors["tipo"] == [_("Este campo é obrigatório.")] + assert errors["ano"] == [_("Este campo é obrigatório.")] + assert errors["numero"] == [_("Este campo é obrigatório.")] assert len(errors) == 3 @@ -253,10 +268,10 @@ def test_valida_campos_obrigatorios_numeracao_form(): errors = form.errors - assert errors['tipo_materia'] == [_('Este campo é obrigatório.')] - assert errors['ano_materia'] == [_('Este campo é obrigatório.')] - assert errors['numero_materia'] == [_('Este campo é obrigatório.')] - assert errors['data_materia'] == [_('Este campo é obrigatório.')] + assert errors["tipo_materia"] == [_("Este campo é obrigatório.")] + assert errors["ano_materia"] == [_("Este campo é obrigatório.")] + assert errors["numero_materia"] == [_("Este campo é obrigatório.")] + assert errors["data_materia"] == [_("Este campo é obrigatório.")] assert len(errors) == 4 @@ -269,9 +284,9 @@ def test_valida_campos_obrigatorios_anexada_form(): errors = form.errors - assert errors['tipo'] == [_('Este campo é obrigatório.')] - assert errors['ano'] == [_('Este campo é obrigatório.')] - assert errors['numero'] == [_('Este campo é obrigatório.')] - assert errors['data_anexacao'] == [_('Este campo é obrigatório.')] + assert errors["tipo"] == [_("Este campo é obrigatório.")] + assert errors["ano"] == [_("Este campo é obrigatório.")] + assert errors["numero"] == [_("Este campo é obrigatório.")] + assert errors["data_anexacao"] == [_("Este campo é obrigatório.")] assert len(errors) == 4 diff --git a/sapl/materia/tests/test_materia_urls.py b/sapl/materia/tests/test_materia_urls.py index 84a421e1b..197eea712 100644 --- a/sapl/materia/tests/test_materia_urls.py +++ b/sapl/materia/tests/test_materia_urls.py @@ -2,18 +2,15 @@ import pytest from django.urls import reverse -@pytest.mark.parametrize("test_input,kwargs,expected", [ - ('sapl.materia:relatoria_update', - {'pk': '11'}, - '/materia/relatoria/11/edit'), - ('sapl.materia:tramitacao_update', - {'pk': '8'}, - '/materia/tramitacao/8/edit'), - ('sapl.materia:proposicao_create', {}, '/proposicao/create'), - ('sapl.materia:proposicao_update', - {'pk': '3'}, - '/proposicao/3/edit'), - ('sapl.materia:proposicao_list', {}, '/proposicao/'), -]) +@pytest.mark.parametrize( + "test_input,kwargs,expected", + [ + ("sapl.materia:relatoria_update", {"pk": "11"}, "/materia/relatoria/11/edit"), + ("sapl.materia:tramitacao_update", {"pk": "8"}, "/materia/tramitacao/8/edit"), + ("sapl.materia:proposicao_create", {}, "/proposicao/create"), + ("sapl.materia:proposicao_update", {"pk": "3"}, "/proposicao/3/edit"), + ("sapl.materia:proposicao_list", {}, "/proposicao/"), + ], +) def test_reverse(test_input, kwargs, expected): assert reverse(test_input, kwargs=kwargs) == expected diff --git a/sapl/materia/urls.py b/sapl/materia/urls.py index bab4d11fe..625647a53 100644 --- a/sapl/materia/urls.py +++ b/sapl/materia/urls.py @@ -6,188 +6,250 @@ from sapl.materia.views import (AcompanhamentoConfirmarView, AssuntoMateriaCrud, AutoriaCrud, AutoriaMultiCreateView, ConfirmarProposicao, CriarProtocoloMateriaView, DespachoInicialCrud, + DespachoInicialMultiCreateView, DocumentoAcessorioCrud, DocumentoAcessorioEmLoteView, - MateriaAnexadaEmLoteView, - EtiquetaPesquisaView, FichaPesquisaView, - FichaSelecionaView, ImpressosView, - LegislacaoCitadaCrud, MateriaAssuntoCrud, + EtiquetaPesquisaView, + ExcluirTramitacaoEmLoteView, FichaPesquisaView, + FichaSelecionaView, HistoricoProposicaoView, + ImpressosView, LegislacaoCitadaCrud, + MateriaAnexadaEmLoteView, MateriaAssuntoCrud, MateriaLegislativaCrud, - MateriaLegislativaPesquisaView, MateriaTaView, + MateriaLegislativaPesquisaView, + MateriaPesquisaSimplesView, MateriaTaView, NumeracaoCrud, OrgaoCrud, OrigemCrud, + PesquisarStatusTramitacaoView, PrimeiraTramitacaoEmLoteView, ProposicaoCrud, ProposicaoDevolvida, ProposicaoPendente, ProposicaoRecebida, ProposicaoTaView, ReceberProposicao, ReciboProposicaoView, RegimeTramitacaoCrud, RelatoriaCrud, - StatusTramitacaoCrud, TipoDocumentoCrud, - TipoFimRelatoriaCrud, TipoMateriaCrud, - TipoProposicaoCrud, TramitacaoCrud, - TramitacaoEmLoteView, UnidadeTramitacaoCrud, - proposicao_texto, recuperar_materia, - ExcluirTramitacaoEmLoteView, - RetornarProposicao, - MateriaPesquisaSimplesView, - DespachoInicialMultiCreateView, - get_zip_docacessorios, get_pdf_docacessorios, + RetornarProposicao, StatusTramitacaoCrud, + TipoDocumentoCrud, TipoFimRelatoriaCrud, + TipoMateriaCrud, TipoProposicaoCrud, + TramitacaoCrud, TramitacaoEmLoteView, + UnidadeTramitacaoCrud, configEtiquetaMateriaLegislativaCrud, - PesquisarStatusTramitacaoView, HistoricoProposicaoView) + get_pdf_docacessorios, get_zip_docacessorios, + proposicao_texto, recuperar_materia) from sapl.norma.views import NormaPesquisaSimplesView -from sapl.protocoloadm.views import ( - FichaPesquisaAdmView, FichaSelecionaAdmView -) +from sapl.protocoloadm.views import FichaPesquisaAdmView, FichaSelecionaAdmView from .apps import AppConfig app_name = AppConfig.name urlpatterns_impressos = [ - path('materia/impressos/', - ImpressosView.as_view(), - name='impressos'), - path('materia/impressos/etiqueta-pesquisa/', + path("materia/impressos/", ImpressosView.as_view(), name="impressos"), + path( + "materia/impressos/etiqueta-pesquisa/", EtiquetaPesquisaView.as_view(), - name='impressos_etiqueta'), - path('materia/impressos/ficha-pesquisa/', + name="impressos_etiqueta", + ), + path( + "materia/impressos/ficha-pesquisa/", FichaPesquisaView.as_view(), - name='impressos_ficha_pesquisa'), - path('materia/impressos/ficha-seleciona/', + name="impressos_ficha_pesquisa", + ), + path( + "materia/impressos/ficha-seleciona/", FichaSelecionaView.as_view(), - name='impressos_ficha_seleciona'), - path('materia/impressos/norma-pesquisa/', + name="impressos_ficha_seleciona", + ), + path( + "materia/impressos/norma-pesquisa/", NormaPesquisaSimplesView.as_view(), - name='impressos_norma_pesquisa'), - path('materia/impressos/materia-pesquisa/', + name="impressos_norma_pesquisa", + ), + path( + "materia/impressos/materia-pesquisa/", MateriaPesquisaSimplesView.as_view(), - name='impressos_materia_pesquisa'), - path('materia/impressos/ficha-pesquisa-adm/', + name="impressos_materia_pesquisa", + ), + path( + "materia/impressos/ficha-pesquisa-adm/", FichaPesquisaAdmView.as_view(), - name='impressos_ficha_pesquisa_adm'), - path('materia/impressos/ficha-seleciona-adm/', + name="impressos_ficha_pesquisa_adm", + ), + path( + "materia/impressos/ficha-seleciona-adm/", FichaSelecionaAdmView.as_view(), - name='impressos_ficha_seleciona_adm'), + name="impressos_ficha_seleciona_adm", + ), ] urlpatterns_materia = [ - # Esta customização substitui a url do crud desque que ela permaneça antes # da inclusão das urls de DespachoInicialCrud - re_path(r'^materia/(?P\d+)/despachoinicial/create', + re_path( + r"^materia/(?P\d+)/despachoinicial/create", DespachoInicialMultiCreateView.as_view(), - name='despacho-inicial-multi'), - - path('materia/', include(MateriaLegislativaCrud.get_urls() + - AnexadaCrud.get_urls() + - AutoriaCrud.get_urls() + - DespachoInicialCrud.get_urls() + - MateriaAssuntoCrud.get_urls() + - NumeracaoCrud.get_urls() + - LegislacaoCitadaCrud.get_urls() + - TramitacaoCrud.get_urls() + - RelatoriaCrud.get_urls() + - DocumentoAcessorioCrud.get_urls())), - - path('materia//create_simplificado', + name="despacho-inicial-multi", + ), + path( + "materia/", + include( + MateriaLegislativaCrud.get_urls() + + AnexadaCrud.get_urls() + + AutoriaCrud.get_urls() + + DespachoInicialCrud.get_urls() + + MateriaAssuntoCrud.get_urls() + + NumeracaoCrud.get_urls() + + LegislacaoCitadaCrud.get_urls() + + TramitacaoCrud.get_urls() + + RelatoriaCrud.get_urls() + + DocumentoAcessorioCrud.get_urls() + ), + ), + path( + "materia//create_simplificado", CriarProtocoloMateriaView.as_view(), - name='materia_create_simplificado'), - re_path(r'^materia/recuperar-materia', - recuperar_materia, name='recuperar_materia'), - path('materia//ta', - MateriaTaView.as_view(), name='materia_ta'), - - - path('materia/pesquisar-materia', - MateriaLegislativaPesquisaView.as_view(), name='pesquisar_materia'), - path('materia//acompanhar-materia/', - AcompanhamentoMateriaView.as_view(), name='acompanhar_materia'), - path('materia//acompanhar-confirmar', + name="materia_create_simplificado", + ), + re_path(r"^materia/recuperar-materia", recuperar_materia, name="recuperar_materia"), + path("materia//ta", MateriaTaView.as_view(), name="materia_ta"), + path( + "materia/pesquisar-materia", + MateriaLegislativaPesquisaView.as_view(), + name="pesquisar_materia", + ), + path( + "materia//acompanhar-materia/", + AcompanhamentoMateriaView.as_view(), + name="acompanhar_materia", + ), + path( + "materia//acompanhar-confirmar", AcompanhamentoConfirmarView.as_view(), - name='acompanhar_confirmar'), - path('materia//acompanhar-excluir', + name="acompanhar_confirmar", + ), + path( + "materia//acompanhar-excluir", AcompanhamentoExcluirView.as_view(), - name='acompanhar_excluir'), - - re_path(r'^materia/(?P\d+)/autoria/multicreate', + name="acompanhar_excluir", + ), + re_path( + r"^materia/(?P\d+)/autoria/multicreate", AutoriaMultiCreateView.as_view(), - name='autoria_multicreate'), - - - re_path(r'^materia/acessorio-em-lote', DocumentoAcessorioEmLoteView.as_view(), - name='acessorio_em_lote'), - re_path(r'^materia/(?P\d+)/anexada-em-lote', MateriaAnexadaEmLoteView.as_view(), - name='anexada_em_lote'), - re_path(r'^materia/primeira-tramitacao-em-lote', + name="autoria_multicreate", + ), + re_path( + r"^materia/acessorio-em-lote", + DocumentoAcessorioEmLoteView.as_view(), + name="acessorio_em_lote", + ), + re_path( + r"^materia/(?P\d+)/anexada-em-lote", + MateriaAnexadaEmLoteView.as_view(), + name="anexada_em_lote", + ), + re_path( + r"^materia/primeira-tramitacao-em-lote", PrimeiraTramitacaoEmLoteView.as_view(), - name='primeira_tramitacao_em_lote'), - re_path(r'^materia/tramitacao-em-lote', TramitacaoEmLoteView.as_view(), - name='tramitacao_em_lote'), - re_path(r'^materia/excluir-tramitacao-em-lote', ExcluirTramitacaoEmLoteView.as_view(), - name='excluir_tramitacao_em_lote'), - path('materia/docacessorio/zip/', get_zip_docacessorios, - name='compress_docacessorios'), - path('materia/docacessorio/pdf/', get_pdf_docacessorios, - name='merge_docacessorios') + name="primeira_tramitacao_em_lote", + ), + re_path( + r"^materia/tramitacao-em-lote", + TramitacaoEmLoteView.as_view(), + name="tramitacao_em_lote", + ), + re_path( + r"^materia/excluir-tramitacao-em-lote", + ExcluirTramitacaoEmLoteView.as_view(), + name="excluir_tramitacao_em_lote", + ), + path( + "materia/docacessorio/zip/", + get_zip_docacessorios, + name="compress_docacessorios", + ), + path( + "materia/docacessorio/pdf/", + get_pdf_docacessorios, + name="merge_docacessorios", + ), ] urlpatterns_proposicao = [ - path('proposicao/', include(ProposicaoCrud.get_urls())), - re_path(r'^proposicao/recibo/(?P\d+)', ReciboProposicaoView.as_view(), - name='recibo-proposicao'), - re_path(r'^proposicao/receber/', ReceberProposicao.as_view(), - name='receber-proposicao'), - re_path(r'^proposicao/pendente/', ProposicaoPendente.as_view(), - name='proposicao-pendente'), - re_path(r'^proposicao/recebida/', ProposicaoRecebida.as_view(), - name='proposicao-recebida'), - re_path(r'^proposicao/devolvida/', ProposicaoDevolvida.as_view(), - name='proposicao-devolvida'), - re_path(r'^proposicao/confirmar/P(?P[0-9A-Fa-f]+)/(?P\d+)', ConfirmarProposicao.as_view(), - name='proposicao-confirmar'), - path('sistema/proposicao/tipo/', - include(TipoProposicaoCrud.get_urls())), - - path('proposicao//ta', - ProposicaoTaView.as_view(), name='proposicao_ta'), - - - path('proposicao/texto/', proposicao_texto, - name='proposicao_texto'), - re_path(r'^proposicao/(?P\d+)/retornar', RetornarProposicao.as_view(), - name='retornar-proposicao'), - re_path(r'^proposicao/historico', HistoricoProposicaoView.as_view(), - name='historico-proposicao'), - + path("proposicao/", include(ProposicaoCrud.get_urls())), + re_path( + r"^proposicao/recibo/(?P\d+)", + ReciboProposicaoView.as_view(), + name="recibo-proposicao", + ), + re_path( + r"^proposicao/receber/", ReceberProposicao.as_view(), name="receber-proposicao" + ), + re_path( + r"^proposicao/pendente/", + ProposicaoPendente.as_view(), + name="proposicao-pendente", + ), + re_path( + r"^proposicao/recebida/", + ProposicaoRecebida.as_view(), + name="proposicao-recebida", + ), + re_path( + r"^proposicao/devolvida/", + ProposicaoDevolvida.as_view(), + name="proposicao-devolvida", + ), + re_path( + r"^proposicao/confirmar/P(?P[0-9A-Fa-f]+)/(?P\d+)", + ConfirmarProposicao.as_view(), + name="proposicao-confirmar", + ), + path("sistema/proposicao/tipo/", include(TipoProposicaoCrud.get_urls())), + path("proposicao//ta", ProposicaoTaView.as_view(), name="proposicao_ta"), + path("proposicao/texto/", proposicao_texto, name="proposicao_texto"), + re_path( + r"^proposicao/(?P\d+)/retornar", + RetornarProposicao.as_view(), + name="retornar-proposicao", + ), + re_path( + r"^proposicao/historico", + HistoricoProposicaoView.as_view(), + name="historico-proposicao", + ), ] urlpatterns_sistema = [ - path('sistema/assunto-materia/', - include(AssuntoMateriaCrud.get_urls())), - path('sistema/proposicao/tipo/', - include(TipoProposicaoCrud.get_urls())), - path('sistema/materia/tipo/', include(TipoMateriaCrud.get_urls())), - path('sistema/materia/regime-tramitacao/', - include(RegimeTramitacaoCrud.get_urls())), - path('sistema/materia/tipo-documento/', - include(TipoDocumentoCrud.get_urls())), - path('sistema/materia/tipo-fim-relatoria/', - include(TipoFimRelatoriaCrud.get_urls())), - path('sistema/materia/unidade-tramitacao/', - include(UnidadeTramitacaoCrud.get_urls())), - path('sistema/materia/origem/', include(OrigemCrud.get_urls())), - - path('sistema/materia/status-tramitacao/', include( - StatusTramitacaoCrud.get_urls() - )), + path("sistema/assunto-materia/", include(AssuntoMateriaCrud.get_urls())), + path("sistema/proposicao/tipo/", include(TipoProposicaoCrud.get_urls())), + path("sistema/materia/tipo/", include(TipoMateriaCrud.get_urls())), + path( + "sistema/materia/regime-tramitacao/", include(RegimeTramitacaoCrud.get_urls()) + ), + path("sistema/materia/tipo-documento/", include(TipoDocumentoCrud.get_urls())), + path( + "sistema/materia/tipo-fim-relatoria/", include(TipoFimRelatoriaCrud.get_urls()) + ), + path( + "sistema/materia/unidade-tramitacao/", include(UnidadeTramitacaoCrud.get_urls()) + ), + path("sistema/materia/origem/", include(OrigemCrud.get_urls())), + path( + "sistema/materia/status-tramitacao/", include(StatusTramitacaoCrud.get_urls()) + ), re_path( - r'^sistema/materia/pesquisar-status-tramitacao/', + r"^sistema/materia/pesquisar-status-tramitacao/", PesquisarStatusTramitacaoView.as_view(), - name="pesquisar_statustramitacao" + name="pesquisar_statustramitacao", + ), + path("sistema/materia/orgao/", include(OrgaoCrud.get_urls())), + re_path( + r"^sistema/materia/config-etiqueta-materia-legislativas/", + configEtiquetaMateriaLegislativaCrud, + name="configEtiquetaMateriaLegislativaCrud", ), - - path('sistema/materia/orgao/', include(OrgaoCrud.get_urls())), - re_path(r'^sistema/materia/config-etiqueta-materia-legislativas/',configEtiquetaMateriaLegislativaCrud, name="configEtiquetaMateriaLegislativaCrud"), ] -urlpatterns = urlpatterns_impressos + urlpatterns_materia + \ - urlpatterns_proposicao + urlpatterns_sistema +urlpatterns = ( + urlpatterns_impressos + + urlpatterns_materia + + urlpatterns_proposicao + + urlpatterns_sistema +) diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 0f7a71f3b..ea00f1b67 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -1,26 +1,25 @@ - -from datetime import datetime -from io import BytesIO import logging import os -from random import choice import shutil -from string import ascii_letters, digits import time import zipfile +from datetime import datetime +from io import BytesIO +from random import choice +from string import ascii_letters, digits -from PyPDF4 import PdfFileReader, PdfFileMerger +import weasyprint from crispy_forms.layout import HTML from django.conf import settings from django.contrib import messages from django.contrib.auth.decorators import permission_required from django.contrib.auth.mixins import PermissionRequiredMixin -from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, ValidationError +from django.core.exceptions import (MultipleObjectsReturned, + ObjectDoesNotExist, ValidationError) from django.db.models import Max, Q from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect -from django.shortcuts import get_object_or_404, redirect -from django.shortcuts import render +from django.shortcuts import get_object_or_404, redirect, render from django.template import loader from django.urls import reverse from django.utils import formats, timezone @@ -30,203 +29,230 @@ 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_filters.views import FilterView -import weasyprint +from PyPDF4 import PdfFileMerger, PdfFileReader import sapl from sapl.base.email_utils import do_envia_email_confirmacao -from sapl.base.models import Autor, CasaLegislativa, AppConfig as BaseAppConfig +from sapl.base.models import AppConfig as BaseAppConfig +from sapl.base.models import Autor, CasaLegislativa from sapl.comissoes.models import Participacao -from sapl.compilacao.models import STATUS_TA_IMMUTABLE_RESTRICT, STATUS_TA_PRIVATE +from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_RESTRICT, + STATUS_TA_PRIVATE) from sapl.compilacao.views import IntegracaoTaView -from sapl.crispy_layout_mixin import form_actions, SaplFormHelper, SaplFormLayout -from sapl.crud.base import (Crud, CrudAux, make_pagination, MasterDetailCrud, - PermissionRequiredForAppCrudMixin, RP_DETAIL, RP_LIST,) -from sapl.materia.forms import (AnexadaForm, AutoriaForm, AutoriaMultiCreateForm, - ConfirmarProposicaoForm, DevolverProposicaoForm, - DespachoInicialCreateForm, LegislacaoCitadaForm, - MateriaPesquisaSimplesForm, OrgaoForm, ProposicaoForm, - TipoProposicaoForm, TramitacaoForm, TramitacaoUpdateForm, ConfigEtiquetaMateriaLegislativaForms) +from sapl.crispy_layout_mixin import (SaplFormHelper, SaplFormLayout, + form_actions) +from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, + MasterDetailCrud, + PermissionRequiredForAppCrudMixin, make_pagination) +from sapl.materia.forms import (AnexadaForm, AutoriaForm, + AutoriaMultiCreateForm, + ConfigEtiquetaMateriaLegislativaForms, + ConfirmarProposicaoForm, + DespachoInicialCreateForm, + DevolverProposicaoForm, LegislacaoCitadaForm, + MateriaPesquisaSimplesForm, OrgaoForm, + ProposicaoForm, TipoProposicaoForm, + TramitacaoForm, TramitacaoUpdateForm) from sapl.norma.models import LegislacaoCitada from sapl.parlamentares.models import Legislatura from sapl.protocoloadm.models import Protocolo from sapl.settings import MAX_DOC_UPLOAD_SIZE, MEDIA_ROOT -from sapl.utils import (autor_label, autor_modal, gerar_hash_arquivo, get_base_url, - get_client_ip, get_mime_type_from_file_extension, lista_anexados, - mail_service_configured, montar_row_autor, SEPARADOR_HASH_PROPOSICAO, - show_results_filter_set, get_tempfile_dir, - google_recaptcha_configured, MultiFormatOutputMixin) +from sapl.utils import (SEPARADOR_HASH_PROPOSICAO, MultiFormatOutputMixin, + autor_label, autor_modal, gerar_hash_arquivo, + get_base_url, get_client_ip, + get_mime_type_from_file_extension, get_tempfile_dir, + google_recaptcha_configured, lista_anexados, + mail_service_configured, montar_row_autor, + show_results_filter_set) from .forms import (AcessorioEmLoteFilterSet, AcompanhamentoMateriaForm, - AnexadaEmLoteFilterSet, AdicionarVariasAutoriasFilterSet, - compara_tramitacoes_mat, DespachoInicialForm, - DocumentoAcessorioForm, EtiquetaPesquisaForm, - ExcluirTramitacaoEmLote, FichaPesquisaForm, - FichaSelecionaForm, filtra_tramitacao_destino, - filtra_tramitacao_destino_and_status, - filtra_tramitacao_status, MateriaAssuntoForm, + AdicionarVariasAutoriasFilterSet, AnexadaEmLoteFilterSet, + DespachoInicialForm, DocumentoAcessorioForm, + EtiquetaPesquisaForm, ExcluirTramitacaoEmLote, + FichaPesquisaForm, FichaSelecionaForm, MateriaAssuntoForm, MateriaLegislativaFilterSet, MateriaLegislativaForm, MateriaSimplificadaForm, PrimeiraTramitacaoEmLoteFilterSet, ReceberProposicaoForm, RelatoriaForm, - TramitacaoEmLoteFilterSet, TramitacaoEmLoteForm, - UnidadeTramitacaoForm, StatusTramitacaoFilterSet) -from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, DespachoInicial, - DocumentoAcessorio, MateriaAssunto, MateriaLegislativa, Numeracao, Orgao, - Origem, Proposicao, RegimeTramitacao, Relatoria, StatusTramitacao, - TipoDocumento, TipoFimRelatoria, TipoMateriaLegislativa, TipoProposicao, - Tramitacao, UnidadeTramitacao, ConfigEtiquetaMateriaLegislativa, HistoricoProposicao) - + StatusTramitacaoFilterSet, TramitacaoEmLoteFilterSet, + TramitacaoEmLoteForm, UnidadeTramitacaoForm, + compara_tramitacoes_mat, filtra_tramitacao_destino, + filtra_tramitacao_destino_and_status, + filtra_tramitacao_status) +from .models import (AcompanhamentoMateria, Anexada, AssuntoMateria, Autoria, + ConfigEtiquetaMateriaLegislativa, DespachoInicial, + DocumentoAcessorio, HistoricoProposicao, MateriaAssunto, + MateriaLegislativa, Numeracao, Orgao, Origem, Proposicao, + RegimeTramitacao, Relatoria, StatusTramitacao, + TipoDocumento, TipoFimRelatoria, TipoMateriaLegislativa, + TipoProposicao, Tramitacao, UnidadeTramitacao) -AssuntoMateriaCrud = CrudAux.build(AssuntoMateria, 'assunto_materia') +AssuntoMateriaCrud = CrudAux.build(AssuntoMateria, "assunto_materia") -OrigemCrud = CrudAux.build(Origem, '') +OrigemCrud = CrudAux.build(Origem, "") -RegimeTramitacaoCrud = CrudAux.build( - RegimeTramitacao, 'regime_tramitacao') +RegimeTramitacaoCrud = CrudAux.build(RegimeTramitacao, "regime_tramitacao") -TipoDocumentoCrud = CrudAux.build( - TipoDocumento, 'tipo_documento') +TipoDocumentoCrud = CrudAux.build(TipoDocumento, "tipo_documento") -TipoFimRelatoriaCrud = CrudAux.build( - TipoFimRelatoria, 'fim_relatoria') +TipoFimRelatoriaCrud = CrudAux.build(TipoFimRelatoria, "fim_relatoria") def autores_ja_adicionados(materia_pk): autorias = Autoria.objects.filter(materia_id=materia_pk).values_list( - 'autor_id', flat=True) + "autor_id", flat=True + ) return autorias def proposicao_texto(request, pk): logger = logging.getLogger(__name__) username = request.user.username - logger.debug('user=' + username + - '. Tentando obter objeto Proposicao com pk = {}.'.format(pk)) + logger.debug( + "user=" + + username + + ". Tentando obter objeto Proposicao com pk = {}.".format(pk) + ) proposicao = Proposicao.objects.get(pk=pk) if proposicao.texto_original: - if (not proposicao.data_recebimento and - not proposicao.autor.operadores.filter( - id=request.user.id - ).exists() - ): - logger.error("user=" + username + ". Usuário ({}) não tem permissão para acessar o texto original." - .format(request.user.id)) - messages.error(request, _( - 'Você não tem permissão para acessar o texto original.')) - return redirect(reverse('sapl.materia:proposicao_detail', - kwargs={'pk': pk})) + if ( + not proposicao.data_recebimento + and not proposicao.autor.operadores.filter(id=request.user.id).exists() + ): + logger.error( + "user=" + + username + + ". Usuário ({}) não tem permissão para acessar o texto original.".format( + request.user.id + ) + ) + messages.error( + request, _("Você não tem permissão para acessar o texto original.") + ) + return redirect( + reverse("sapl.materia:proposicao_detail", kwargs={"pk": pk}) + ) arquivo = proposicao.texto_original mime = get_mime_type_from_file_extension(arquivo.name) - with open(arquivo.path, 'rb') as f: + with open(arquivo.path, "rb") as f: data = f.read() - response = HttpResponse(data, content_type='%s' % mime) - response['Content-Disposition'] = ( - 'inline; filename="%s"' % arquivo.name.split('/')[-1]) + response = HttpResponse(data, content_type="%s" % mime) + response["Content-Disposition"] = ( + 'inline; filename="%s"' % arquivo.name.split("/")[-1] + ) return response - logger.error('user=' + username + - '. Objeto Proposicao com pk={} não encontrado.'.format(pk)) + logger.error( + "user=" + username + ". Objeto Proposicao com pk={} não encontrado.".format(pk) + ) raise Http404 class AdicionarVariasAutorias(PermissionRequiredForAppCrudMixin, FilterView): app_label = sapl.materia.apps.AppConfig.label filterset_class = AdicionarVariasAutoriasFilterSet - template_name = 'materia/adicionar_varias_autorias.html' + template_name = "materia/adicionar_varias_autorias.html" model = Autor def get_filterset_kwargs(self, filterset_class): - super(AdicionarVariasAutorias, self).get_filterset_kwargs( - filterset_class) - kwargs = {'data': self.request.GET or None} + super(AdicionarVariasAutorias, self).get_filterset_kwargs(filterset_class) + kwargs = {"data": self.request.GET or None} qs = self.get_queryset() - qs = qs.exclude( - id__in=autores_ja_adicionados(self.kwargs['pk'])).distinct() + qs = qs.exclude(id__in=autores_ja_adicionados(self.kwargs["pk"])).distinct() - kwargs.update({'queryset': qs}) + kwargs.update({"queryset": qs}) return kwargs def get_context_data(self, **kwargs): - context = super(AdicionarVariasAutorias, self).get_context_data( - **kwargs) + context = super(AdicionarVariasAutorias, self).get_context_data(**kwargs) - context['title'] = _('Pesquisar Autores') + context["title"] = _("Pesquisar Autores") qr = self.request.GET.copy() - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" - context['show_results'] = show_results_filter_set(qr) + context["show_results"] = show_results_filter_set(qr) - context['pk_materia'] = self.kwargs['pk'] + context["pk_materia"] = self.kwargs["pk"] return context def post(self, request, *args, **kwargs): - marcados = request.POST.getlist('autor_id') + marcados = request.POST.getlist("autor_id") for m in marcados: - Autoria.objects.create( - materia_id=self.kwargs['pk'], - autor_id=m - ) + Autoria.objects.create(materia_id=self.kwargs["pk"], autor_id=m) return HttpResponseRedirect( - reverse('sapl.materia:autoria_list', - kwargs={'pk': self.kwargs['pk']})) + reverse("sapl.materia:autoria_list", kwargs={"pk": self.kwargs["pk"]}) + ) class CriarProtocoloMateriaView(CreateView): template_name = "crud/form.html" form_class = MateriaSimplificadaForm - form_valid_message = _('Matéria cadastrada com sucesso!') + form_valid_message = _("Matéria cadastrada com sucesso!") logger = logging.getLogger(__name__) def get_success_url(self, materia): - return reverse('sapl.materia:materialegislativa_detail', kwargs={ - 'pk': materia.pk}) + return reverse( + "sapl.materia:materialegislativa_detail", kwargs={"pk": materia.pk} + ) def get_context_data(self, **kwargs): - context = super( - CriarProtocoloMateriaView, self).get_context_data(**kwargs) + context = super(CriarProtocoloMateriaView, self).get_context_data(**kwargs) username = self.request.user.username try: - self.logger.debug("user=" + username + - ". Tentando obter objeto Protocolo.") - protocolo = Protocolo.objects.get(pk=self.kwargs['pk']) + self.logger.debug("user=" + username + ". Tentando obter objeto Protocolo.") + protocolo = Protocolo.objects.get(pk=self.kwargs["pk"]) except ObjectDoesNotExist as e: self.logger.error( - "user=" + username + ". Objeto Protocolo com pk={} não encontrado. ".format(self.kwargs['pk']) + str(e)) + "user=" + + username + + ". Objeto Protocolo com pk={} não encontrado. ".format( + self.kwargs["pk"] + ) + + str(e) + ) raise Http404() numero = 1 try: - self.logger.debug("user=" + username + - ". Tentando obter materias do último ano.") + self.logger.debug( + "user=" + username + ". Tentando obter materias do último ano." + ) materias_ano = MateriaLegislativa.objects.filter( - ano=protocolo.ano, - tipo=protocolo.tipo_materia).latest('numero') + ano=protocolo.ano, tipo=protocolo.tipo_materia + ).latest("numero") numero = materias_ano.numero + 1 except ObjectDoesNotExist: - self.logger.error("user=" + username + ". Não foram encontradas matérias no último ano ({}). " - "Definido 1 como padrão.".format(protocolo.ano)) + self.logger.error( + "user=" + + username + + ". Não foram encontradas matérias no último ano ({}). " + "Definido 1 como padrão.".format(protocolo.ano) + ) pass # numero ficou com o valor padrão 1 acima - context['form'].fields['tipo'].initial = protocolo.tipo_materia - context['form'].fields['numero'].initial = numero - context['form'].fields['ano'].initial = protocolo.ano + context["form"].fields["tipo"].initial = protocolo.tipo_materia + context["form"].fields["numero"].initial = numero + context["form"].fields["ano"].initial = protocolo.ano if protocolo: if protocolo.timestamp: - context['form'].fields['data_apresentacao'].initial = protocolo.timestamp.date( - ) + context["form"].fields[ + "data_apresentacao" + ].initial = protocolo.timestamp.date() elif protocolo.timestamp_data_hora_manual: - context['form'].fields['data_apresentacao'].initial = protocolo.timestamp_data_hora_manual.date() + context["form"].fields[ + "data_apresentacao" + ].initial = protocolo.timestamp_data_hora_manual.date() elif protocolo.data: - context['form'].fields['data_apresentacao'].initial = protocolo.data - context['form'].fields['numero_protocolo'].initial = protocolo.numero - context['form'].fields['ementa'].initial = protocolo.assunto_ementa + context["form"].fields["data_apresentacao"].initial = protocolo.data + context["form"].fields["numero_protocolo"].initial = protocolo.numero + context["form"].fields["ementa"].initial = protocolo.assunto_ementa return context @@ -244,18 +270,25 @@ class CriarProtocoloMateriaView(CreateView): try: self.logger.info( - "user=" + username + ". Tentando obter objeto Procolo com pk={}.".format(self.kwargs['pk'])) - protocolo = Protocolo.objects.get(pk=self.kwargs['pk']) + "user=" + + username + + ". Tentando obter objeto Procolo com pk={}.".format(self.kwargs["pk"]) + ) + protocolo = Protocolo.objects.get(pk=self.kwargs["pk"]) except ObjectDoesNotExist: self.logger.error( - 'user=' + username + '. Objeto Protocolo com pk={} não encontrado.'.format(self.kwargs['pk'])) + "user=" + + username + + ". Objeto Protocolo com pk={} não encontrado.".format( + self.kwargs["pk"] + ) + ) raise Http404() if protocolo.autor: Autoria.objects.create( - materia=materia, - autor=protocolo.autor, - primeiro_autor=True) + materia=materia, autor=protocolo.autor, primeiro_autor=True + ) return redirect(self.get_success_url(materia)) @@ -264,19 +297,19 @@ class MateriaTaView(IntegracaoTaView): model = MateriaLegislativa model_type_foreignkey = TipoMateriaLegislativa map_fields = { - 'data': 'data_apresentacao', - 'ementa': 'ementa', - 'observacao': None, - 'numero': 'numero', - 'ano': 'ano', - 'tipo': 'tipo', + "data": "data_apresentacao", + "ementa": "ementa", + "observacao": None, + "numero": "numero", + "ano": "ano", + "tipo": "tipo", } map_funcs = { - 'publicacao_func': False, + "publicacao_func": False, } ta_values = { - 'editable_only_by_owners': False, - 'editing_locked': False, + "editable_only_by_owners": False, + "editing_locked": False, } def get(self, request, *args, **kwargs): @@ -285,7 +318,7 @@ class MateriaTaView(IntegracaoTaView): este get foi implementado para tratar uma prerrogativa externa de usuário. """ - if sapl.base.models.AppConfig.attr('texto_articulado_materia'): + if sapl.base.models.AppConfig.attr("texto_articulado_materia"): return IntegracaoTaView.get(self, request, *args, **kwargs) else: return self.get_redirect_deactivated() @@ -295,20 +328,18 @@ class ProposicaoTaView(IntegracaoTaView): model = Proposicao model_type_foreignkey = TipoProposicao map_fields = { - 'data': 'data_envio', - 'ementa': 'descricao', - 'observacao': None, - 'numero': 'numero_proposicao', - 'ano': 'ano', - 'tipo': 'tipo', - } - map_funcs = { - 'publicacao_func': False + "data": "data_envio", + "ementa": "descricao", + "observacao": None, + "numero": "numero_proposicao", + "ano": "ano", + "tipo": "tipo", } + map_funcs = {"publicacao_func": False} ta_values = { - 'editable_only_by_owners': True, - 'editing_locked': False, - 'privacidade': STATUS_TA_PRIVATE + "editable_only_by_owners": True, + "editing_locked": False, + "privacidade": STATUS_TA_PRIVATE, } def get(self, request, *args, **kwargs): @@ -317,13 +348,13 @@ class ProposicaoTaView(IntegracaoTaView): este get foi implementado para tratar uma prerrogativa externa de usuário. """ - if sapl.base.models.AppConfig.attr('texto_articulado_proposicao'): - - proposicao = get_object_or_404(self.model, pk=kwargs['pk']) + if sapl.base.models.AppConfig.attr("texto_articulado_proposicao"): + proposicao = get_object_or_404(self.model, pk=kwargs["pk"]) - if not proposicao.data_envio and \ - not proposicao.autor.operadores.filter( - id=request.user.id).exists(): + if ( + not proposicao.data_envio + and not proposicao.autor.operadores.filter(id=request.user.id).exists() + ): raise Http404() return IntegracaoTaView.get(self, request, *args, **kwargs) @@ -331,54 +362,59 @@ class ProposicaoTaView(IntegracaoTaView): return self.get_redirect_deactivated() -@permission_required('materia.detail_materialegislativa') +@permission_required("materia.detail_materialegislativa") def recuperar_materia(request): logger = logging.getLogger(__name__) username = request.user.username - tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo']) - ano = request.GET.get('ano', '') + tipo = TipoMateriaLegislativa.objects.get(pk=request.GET["tipo"]) + ano = request.GET.get("ano", "") if not (tipo and ano): - return JsonResponse({'numero': '', 'ano': ''}) + return JsonResponse({"numero": "", "ano": ""}) numeracao = None try: - logger.debug("user=" + username + - ". Tentando obter numeração da matéria.") - numeracao = sapl.base.models.AppConfig.objects.last( - ).sequencia_numeracao_protocolo + logger.debug("user=" + username + ". Tentando obter numeração da matéria.") + numeracao = ( + sapl.base.models.AppConfig.objects.last().sequencia_numeracao_protocolo + ) except AttributeError as e: - logger.error("user=" + username + ". " + str(e) + - " Numeracao da matéria definida como None.") + logger.error( + "user=" + + username + + ". " + + str(e) + + " Numeracao da matéria definida como None." + ) pass if tipo.sequencia_numeracao: numeracao = tipo.sequencia_numeracao - if numeracao == 'A': - numero = MateriaLegislativa.objects.filter( - ano=ano, tipo=tipo).aggregate(Max('numero')) - elif numeracao == 'L': + if numeracao == "A": + numero = MateriaLegislativa.objects.filter(ano=ano, tipo=tipo).aggregate( + Max("numero") + ) + elif numeracao == "L": legislatura = Legislatura.objects.filter( - data_inicio__year__lte=ano, - data_fim__year__gte=ano).first() + data_inicio__year__lte=ano, data_fim__year__gte=ano + ).first() data_inicio = legislatura.data_inicio data_fim = legislatura.data_fim numero = MateriaLegislativa.objects.filter( data_apresentacao__gte=data_inicio, data_apresentacao__lte=data_fim, - tipo=tipo).aggregate( - Max('numero')) - elif numeracao == 'U': - numero = MateriaLegislativa.objects.filter( - tipo=tipo).aggregate(Max('numero')) + tipo=tipo, + ).aggregate(Max("numero")) + elif numeracao == "U": + numero = MateriaLegislativa.objects.filter(tipo=tipo).aggregate(Max("numero")) if numeracao is None: - numero['numero__max'] = 0 + numero["numero__max"] = 0 - max_numero = numero['numero__max'] + 1 if numero['numero__max'] else 1 + max_numero = numero["numero__max"] + 1 if numero["numero__max"] else 1 - response = JsonResponse({'numero': max_numero, 'ano': ano}) + response = JsonResponse({"numero": max_numero, "ano": ano}) return response @@ -388,7 +424,7 @@ class StatusTramitacaoCrud(CrudAux): class DeleteView(CrudAux.DeleteView): def get_success_url(self): - return reverse('sapl.materia:pesquisar_statustramitacao') + return reverse("sapl.materia:pesquisar_statustramitacao") class PesquisarStatusTramitacaoView(FilterView): @@ -397,30 +433,26 @@ class PesquisarStatusTramitacaoView(FilterView): paginate_by = 20 def get_filterset_kwargs(self, filterset_class): - super(PesquisarStatusTramitacaoView, self).get_filterset_kwargs( - filterset_class - ) + super(PesquisarStatusTramitacaoView, self).get_filterset_kwargs(filterset_class) - return ({ + return { "data": self.request.GET or None, - "queryset": self.get_queryset().order_by("sigla").distinct() - }) + "queryset": self.get_queryset().order_by("sigla").distinct(), + } def get_context_data(self, **kwargs): - context = super(PesquisarStatusTramitacaoView, self).get_context_data( - **kwargs - ) + context = super(PesquisarStatusTramitacaoView, self).get_context_data(**kwargs) paginator = context["paginator"] page_obj = context["page_obj"] - context.update({ - "page_range": make_pagination( - page_obj.number, paginator.num_pages - ), - "NO_ENTRIES_MSG": "Nenhum status de tramitacao encontrado!", - "title": _("Status de Tramitação") - }) + context.update( + { + "page_range": make_pagination(page_obj.number, paginator.num_pages), + "NO_ENTRIES_MSG": "Nenhum status de tramitacao encontrado!", + "title": _("Status de Tramitação"), + } + ) return context @@ -429,27 +461,29 @@ class PesquisarStatusTramitacaoView(FilterView): data = self.filterset.data - url = '' + url = "" if data: - url = '&' + str(self.request.META["QUERY_STRING"]) + url = "&" + str(self.request.META["QUERY_STRING"]) if url.startswith("&page"): - url = '' + url = "" - if 'descricao' in self.request.META['QUERY_STRING'] or\ - 'page' in self.request.META['QUERY_STRING']: + if ( + "descricao" in self.request.META["QUERY_STRING"] + or "page" in self.request.META["QUERY_STRING"] + ): resultados = self.object_list else: resultados = [] - context = self.get_context_data(filter=self.filterset, - object_list=resultados, - filter_url=url, - numero_res=len(resultados) - ) + context = self.get_context_data( + filter=self.filterset, + object_list=resultados, + filter_url=url, + numero_res=len(resultados), + ) - context['show_results'] = show_results_filter_set( - self.request.GET.copy()) + context["show_results"] = show_results_filter_set(self.request.GET.copy()) return self.render_to_response(context) @@ -463,11 +497,10 @@ class OrgaoCrud(CrudAux): class TipoProposicaoCrud(CrudAux): model = TipoProposicao - help_text = 'tipo_proposicao' + help_text = "tipo_proposicao" class BaseMixin(CrudAux.BaseMixin): - list_field_names = [ - "descricao", "content_type", 'tipo_conteudo_related'] + list_field_names = ["descricao", "content_type", "tipo_conteudo_related"] class CreateView(CrudAux.CreateView): form_class = TipoProposicaoForm @@ -480,17 +513,23 @@ class TipoProposicaoCrud(CrudAux): def get_initial(self): initial = CrudAux.UpdateView.get_initial(self) ct = self.object.content_type - initial['content_type'] = f'{ct.app_label}/{ct.model}' - initial['tipo_conteudo_related'] = self.object.object_id + initial["content_type"] = f"{ct.app_label}/{ct.model}" + initial["tipo_conteudo_related"] = self.object.object_id return initial def criar_materia_proposicao(proposicao): tipo_materia = TipoMateriaLegislativa.objects.get( - descricao=proposicao.tipo.descricao) - numero = MateriaLegislativa.objects.filter( - ano=timezone.now().year).order_by('numero').last().numero + 1 - regime = RegimeTramitacao.objects.get(descricao='Normal') + descricao=proposicao.tipo.descricao + ) + numero = ( + MateriaLegislativa.objects.filter(ano=timezone.now().year) + .order_by("numero") + .last() + .numero + + 1 + ) + regime = RegimeTramitacao.objects.get(descricao="Normal") return MateriaLegislativa.objects.create( tipo=tipo_materia, @@ -500,15 +539,14 @@ def criar_materia_proposicao(proposicao): regime_tramitacao=regime, em_tramitacao=True, ementa=proposicao.descricao, - texto_original=proposicao.texto_original + texto_original=proposicao.texto_original, ) def criar_doc_proposicao(proposicao): - tipo_doc = TipoDocumento.objects.get( - descricao=proposicao.tipo.descricao) + tipo_doc = TipoDocumento.objects.get(descricao=proposicao.tipo.descricao) if proposicao.autor is None: - autor = 'Desconhecido' + autor = "Desconhecido" else: autor = proposicao.autor @@ -518,88 +556,89 @@ def criar_doc_proposicao(proposicao): arquivo=proposicao.texto_original, nome=proposicao.descricao, data=proposicao.data_envio, - autor=autor + autor=autor, ) class ProposicaoDevolvida(PermissionRequiredMixin, ListView): - template_name = 'materia/prop_devolvidas_list.html' + template_name = "materia/prop_devolvidas_list.html" model = Proposicao - ordering = ['data_envio'] + ordering = ["data_envio"] paginate_by = 10 - permission_required = ('materia.detail_proposicao_devolvida', ) + permission_required = ("materia.detail_proposicao_devolvida",) def get_queryset(self): return Proposicao.objects.filter( data_envio__isnull=True, data_recebimento__isnull=True, - data_devolucao__isnull=False) + data_devolucao__isnull=False, + ) def get_context_data(self, **kwargs): context = super(ProposicaoDevolvida, self).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'] = 'Nenhuma proposição devolvida.' - context['subnav_template_name'] = 'materia/subnav_prop.yaml' + paginator = context["paginator"] + page_obj = context["page_obj"] + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) + context["NO_ENTRIES_MSG"] = "Nenhuma proposição devolvida." + context["subnav_template_name"] = "materia/subnav_prop.yaml" return context class ProposicaoPendente(PermissionRequiredMixin, ListView): - template_name = 'materia/prop_pendentes_list.html' + template_name = "materia/prop_pendentes_list.html" model = Proposicao - ordering = ['data_envio', 'autor', 'tipo', 'descricao'] + ordering = ["data_envio", "autor", "tipo", "descricao"] paginate_by = 10 - permission_required = ('materia.detail_proposicao_enviada', ) + permission_required = ("materia.detail_proposicao_enviada",) def get_queryset(self): return Proposicao.objects.filter( data_envio__isnull=False, data_recebimento__isnull=True, - data_devolucao__isnull=True) + data_devolucao__isnull=True, + ) def get_context_data(self, **kwargs): context = super(ProposicaoPendente, self).get_context_data(**kwargs) - context['object_list'] = Proposicao.objects.filter( + context["object_list"] = Proposicao.objects.filter( data_envio__isnull=False, data_recebimento__isnull=True, - data_devolucao__isnull=True) - paginator = context['paginator'] - page_obj = context['page_obj'] - context['AppConfig'] = sapl.base.models.AppConfig.objects.all().last() - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) - context['NO_ENTRIES_MSG'] = 'Nenhuma proposição pendente.' - - context['subnav_template_name'] = 'materia/subnav_prop.yaml' + data_devolucao__isnull=True, + ) + paginator = context["paginator"] + page_obj = context["page_obj"] + context["AppConfig"] = sapl.base.models.AppConfig.objects.all().last() + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) + context["NO_ENTRIES_MSG"] = "Nenhuma proposição pendente." + + context["subnav_template_name"] = "materia/subnav_prop.yaml" qr = self.request.GET.copy() - context['filter_url'] = ('&o=' + qr['o']) if 'o' in qr.keys() else '' + context["filter_url"] = ("&o=" + qr["o"]) if "o" in qr.keys() else "" return context class ProposicaoRecebida(PermissionRequiredMixin, ListView): - template_name = 'materia/prop_recebidas_list.html' + template_name = "materia/prop_recebidas_list.html" model = Proposicao paginate_by = 10 - permission_required = 'materia.detail_proposicao_incorporada' + permission_required = "materia.detail_proposicao_incorporada" def get_queryset(self): return Proposicao.objects.filter( data_envio__isnull=False, data_recebimento__isnull=False, - data_devolucao__isnull=True) + data_devolucao__isnull=True, + ) def get_context_data(self, **kwargs): context = super(ProposicaoRecebida, self).get_context_data(**kwargs) - paginator = context['paginator'] - page_obj = context['page_obj'] - context['AppConfig'] = sapl.base.models.AppConfig.objects.all().last() - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) - context['NO_ENTRIES_MSG'] = 'Nenhuma proposição recebida.' - context['subnav_template_name'] = 'materia/subnav_prop.yaml' + paginator = context["paginator"] + page_obj = context["page_obj"] + context["AppConfig"] = sapl.base.models.AppConfig.objects.all().last() + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) + context["NO_ENTRIES_MSG"] = "Nenhuma proposição recebida." + context["subnav_template_name"] = "materia/subnav_prop.yaml" return context @@ -609,49 +648,57 @@ class ReceberProposicao(PermissionRequiredForAppCrudMixin, FormView): form_class = ReceberProposicaoForm def post(self, request, *args, **kwargs): - form = ReceberProposicaoForm(request.POST) if form.is_valid(): try: # A ultima parte do código deve ser a pk da Proposicao - cod_hash = form.cleaned_data["cod_hash"]. \ - replace('/', SEPARADOR_HASH_PROPOSICAO) + cod_hash = form.cleaned_data["cod_hash"].replace( + "/", SEPARADOR_HASH_PROPOSICAO + ) id = cod_hash.split(SEPARADOR_HASH_PROPOSICAO)[1] - proposicao = Proposicao.objects.get(id=id, - data_envio__isnull=False, - data_recebimento__isnull=True) + proposicao = Proposicao.objects.get( + id=id, data_envio__isnull=False, data_recebimento__isnull=True + ) if proposicao.texto_articulado.exists(): ta = proposicao.texto_articulado.first() # FIXME hash para textos articulados - hasher = 'P' + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(proposicao.id) + hasher = ( + "P" + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(proposicao.id) + ) else: - hasher = gerar_hash_arquivo( - proposicao.texto_original.path, - str(proposicao.id)) \ - if proposicao.texto_original else None + hasher = ( + gerar_hash_arquivo( + proposicao.texto_original.path, str(proposicao.id) + ) + if proposicao.texto_original + else None + ) if hasher == cod_hash: return HttpResponseRedirect( - reverse('sapl.materia:proposicao-confirmar', - kwargs={ - 'hash': hasher.split(SEPARADOR_HASH_PROPOSICAO)[0][1:], - 'pk': proposicao.pk})) + reverse( + "sapl.materia:proposicao-confirmar", + kwargs={ + "hash": hasher.split(SEPARADOR_HASH_PROPOSICAO)[0][1:], + "pk": proposicao.pk, + }, + ) + ) except ObjectDoesNotExist: - messages.error(request, _('Proposição não encontrada!')) + messages.error(request, _("Proposição não encontrada!")) except IndexError: - messages.error(request, _('Código de recibo mal formado!')) + messages.error(request, _("Código de recibo mal formado!")) except IOError: - messages.error(request, _( - 'Erro abrindo texto original de proposição')) + messages.error(request, _("Erro abrindo texto original de proposição")) return self.form_invalid(form) def get_success_url(self): - return reverse('sapl.materia:receber-proposicao') + return reverse("sapl.materia:receber-proposicao") def get_context_data(self, **kwargs): context = super(ReceberProposicao, self).get_context_data(**kwargs) - context['subnav_template_name'] = 'materia/subnav_prop.yaml' + context["subnav_template_name"] = "materia/subnav_prop.yaml" return context @@ -659,32 +706,37 @@ class RetornarProposicao(UpdateView): app_label = sapl.protocoloadm.apps.AppConfig.label template_name = "materia/proposicao_confirm_return.html" model = Proposicao - fields = ['data_envio', 'descricao'] - permission_required = ('materia.detail_proposicao_enviada', ) + fields = ["data_envio", "descricao"] + permission_required = ("materia.detail_proposicao_enviada",) logger = logging.getLogger(__name__) def dispatch(self, request, *args, **kwargs): username = request.user.username try: self.logger.info( - "user=" + username + ". Tentando obter objeto Proposicao com id={}.".format(kwargs['pk'])) - p = Proposicao.objects.get(id=kwargs['pk']) + "user=" + + username + + ". Tentando obter objeto Proposicao com id={}.".format(kwargs["pk"]) + ) + p = Proposicao.objects.get(id=kwargs["pk"]) except: self.logger.error( - "user=" + username + ". Objeto Proposicao com id={} não encontrado.".format(kwargs['pk'])) + "user=" + + username + + ". Objeto Proposicao com id={} não encontrado.".format(kwargs["pk"]) + ) raise Http404() if not p.autor.operadores.filter(id=request.user.id).exists(): self.logger.error( - "user=" + username + ". Usuário ({}) sem acesso a esta opção.".format(request.user)) - messages.error( - request, - 'Usuário sem acesso a esta opção.' % - request.user) - return redirect('/') + "user=" + + username + + ". Usuário ({}) sem acesso a esta opção.".format(request.user) + ) + messages.error(request, "Usuário sem acesso a esta opção." % request.user) + return redirect("/") - return super(RetornarProposicao, self).dispatch( - request, *args, **kwargs) + return super(RetornarProposicao, self).dispatch(request, *args, **kwargs) class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): @@ -696,18 +748,18 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): def get_initial(self): initial = super().get_initial() - initial['ip'] = get_client_ip(self.request) - initial['user'] = self.request.user + initial["ip"] = get_client_ip(self.request) + initial["user"] = self.request.user return initial def get_success_url(self): - msgs = self.object.results['messages'] + msgs = self.object.results["messages"] for key, value in msgs.items(): for item in value: getattr(messages, key)(self.request, item) - return self.object.results['url'] + return self.object.results["url"] def get_object(self, queryset=None): username = self.request.user.username @@ -718,26 +770,44 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): já recebidas -> data_recebimento != None não enviadas -> data_envio == None """ - self.logger.debug("user=" + username + - ". Tentando obter objeto Proposicao.") - proposicao = Proposicao.objects.get(pk=self.kwargs['pk'], - data_envio__isnull=False, - data_recebimento__isnull=True) + self.logger.debug( + "user=" + username + ". Tentando obter objeto Proposicao." + ) + proposicao = Proposicao.objects.get( + pk=self.kwargs["pk"], + data_envio__isnull=False, + data_recebimento__isnull=True, + ) self.object = None if proposicao.texto_articulado.exists(): ta = proposicao.texto_articulado.first() - hasher = 'P' + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(proposicao.id) + hasher = ( + "P" + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(proposicao.id) + ) else: - hasher = gerar_hash_arquivo( - proposicao.texto_original.path, - str(proposicao.pk)) if proposicao.texto_original else None + hasher = ( + gerar_hash_arquivo( + proposicao.texto_original.path, str(proposicao.pk) + ) + if proposicao.texto_original + else None + ) - if hasher == 'P%s%s%s' % (self.kwargs['hash'], SEPARADOR_HASH_PROPOSICAO, proposicao.pk): + if hasher == "P%s%s%s" % ( + self.kwargs["hash"], + SEPARADOR_HASH_PROPOSICAO, + proposicao.pk, + ): self.object = proposicao except Exception as e: - self.logger.error("user=" + username + ". Objeto Proposicao com atributos (pk={}, data_envio=Not Null, " - "data_recebimento=Null) não encontrado. ".format(self.kwargs['pk']) + str(e)) + self.logger.error( + "user=" + + username + + ". Objeto Proposicao com atributos (pk={}, data_envio=Not Null, " + "data_recebimento=Null) não encontrado. ".format(self.kwargs["pk"]) + + str(e) + ) raise Http404() if not self.object: @@ -748,7 +818,7 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context def get_form(self, form_class=None): @@ -756,7 +826,7 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): form_class = self.get_form_class() if self.request.POST: - if 'justificativa_devolucao' in self.request.POST: + if "justificativa_devolucao" in self.request.POST: return form_class[1](**self.get_form_kwargs()) else: return form_class[0](**self.get_form_kwargs()) @@ -775,9 +845,9 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): # renderização do template_name definido nesta classe kwargs = { - 'initial': self.get_initial(), - 'prefix': self.get_prefix(), - 'instance': form.instance + "initial": self.get_initial(), + "prefix": self.get_prefix(), + "instance": form.instance, } if isinstance(form, self.form_class[0]): @@ -790,32 +860,31 @@ class ConfirmarProposicao(PermissionRequiredForAppCrudMixin, UpdateView): class UnidadeTramitacaoCrud(CrudAux): model = UnidadeTramitacao - help_topic = 'unidade_tramitacao' + help_topic = "unidade_tramitacao" class BaseMixin(CrudAux.BaseMixin): - list_field_names = ['comissao', 'orgao', 'parlamentar'] + list_field_names = ["comissao", "orgao", "parlamentar"] class ListView(CrudAux.ListView): - def get_headers(self): - return [_('Unidade de Tramitação')] + return [_("Unidade de Tramitação")] def is_not_empty(self, value): if value is None: return False - value = value.strip().replace(' ', '') - return value != '' + value = value.strip().replace(" ", "") + return value != "" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - for row in context['rows']: + for row in context["rows"]: if self.is_not_empty(row[0][0]): # Comissão pass elif self.is_not_empty(row[1][0]): # Órgão row[0] = (row[1][0], row[0][1]) elif self.is_not_empty(row[2][0]): # Parlamentar row[0] = (row[2][0], row[0][1]) - row[1], row[2] = ('', ''), ('', '') + row[1], row[2] = ("", ""), ("", "") return context class UpdateView(Crud.UpdateView): @@ -827,17 +896,17 @@ class UnidadeTramitacaoCrud(CrudAux): class ProposicaoCrud(Crud): model = Proposicao - help_topic = 'proposicao' - container_field = 'autor__operadores' + help_topic = "proposicao" + container_field = "autor__operadores" class BaseMixin(Crud.BaseMixin): list_field_names = [ - 'data_envio', - 'data_recebimento', - 'descricao', - 'tipo', - 'conteudo_gerado_related', - 'cancelado' + "data_envio", + "data_recebimento", + "descricao", + "tipo", + "conteudo_gerado_related", + "cancelado", ] class BaseLocalMixin: @@ -846,66 +915,73 @@ class ProposicaoCrud(Crud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context 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' + layout_key = "Proposicao" permission_required = ( RP_DETAIL, - 'materia.detail_proposicao_enviada', - 'materia.detail_proposicao_devolvida', - 'materia.detail_proposicao_incorporada' + "materia.detail_proposicao_enviada", + "materia.detail_proposicao_devolvida", + "materia.detail_proposicao_incorporada", ) logger = logging.getLogger(__name__) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' - context['AppConfig'] = sapl.base.models.AppConfig.objects.all().last() - - context['title'] = '%s (%s)' % ( - self.object, self.object.autor) + context["subnav_template_name"] = "" + context["AppConfig"] = sapl.base.models.AppConfig.objects.all().last() - context['user'] = self.request.user - context['proposicao'] = Proposicao.objects.get( - pk=self.kwargs['pk'] + context["title"] = "%s (%s)" % ( + self.object, + self.object.autor, ) + + context["user"] = self.request.user + context["proposicao"] = Proposicao.objects.get(pk=self.kwargs["pk"]) return context def get(self, request, *args, **kwargs): - action = request.GET.get('action', '') + action = request.GET.get("action", "") user = request.user username = user.username if not action: return Crud.DetailView.get(self, request, *args, **kwargs) - p = Proposicao.objects.get(id=kwargs['pk']) + p = Proposicao.objects.get(id=kwargs["pk"]) - msg_error = '' + msg_error = "" if p and p.autor.operadores.filter(id=request.user.id).exists(): - if action == 'send': + if action == "send": if p.data_envio and p.data_recebimento: - msg_error = _('Proposição já foi enviada e recebida.') + msg_error = _("Proposição já foi enviada e recebida.") elif p.data_envio: - msg_error = _('Proposição já foi enviada.') + 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.') + "Proposição não possui nenhum tipo de Texto associado." + ) else: if p.texto_articulado.exists(): ta = p.texto_articulado.first() @@ -914,93 +990,133 @@ class ProposicaoCrud(Crud): ta.save() receber_recibo = BaseAppConfig.attr( - 'receber_recibo_proposicao') + "receber_recibo_proposicao" + ) if not receber_recibo: ta = p.texto_articulado.first() - p.hash_code = 'P' + ta.hash() + SEPARADOR_HASH_PROPOSICAO + str(p.pk) + p.hash_code = ( + "P" + + ta.hash() + + SEPARADOR_HASH_PROPOSICAO + + str(p.pk) + ) p.data_devolucao = None p.data_envio = timezone.now() p.save() HistoricoProposicao.objects.create( proposicao=p, - status='E', + status="E", ip=get_client_ip(self.request), - user=self.request.user) + user=self.request.user, + ) - messages.success(request, _( - 'Proposição enviada com sucesso.')) + messages.success(request, _("Proposição enviada com sucesso.")) try: - 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)) + 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).order_by('numero').last().numero + 1 - 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))) + numero = ( + MateriaLegislativa.objects.filter( + tipo=p.tipo.tipo_conteudo_related, ano=p.ano + ) + .order_by("numero") + .last() + .numero + + 1 + ) + 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.warning( - "User=" + username + ". " + str(e)) + self.logger.warning("User=" + username + ". " + str(e)) pass except AttributeError as e: - self.logger.warning( - "User=" + username + ". " + str(e)) + self.logger.warning("User=" + username + ". " + str(e)) pass except TypeError as e: - self.logger.warning( - "User=" + username + ". " + str(e)) + self.logger.warning("User=" + username + ". " + str(e)) pass - elif action == 'return': + elif action == "return": if not p.data_envio: - 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.') + 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.warning("User={}. Proposição (numero={}) já foi recebida, " - "não é possível retorná-la.".format(username, p.numero_proposicao)) + 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.') + "Proposição já foi recebida, não é possível retorná-la." + ) else: p.data_envio = None p.save() HistoricoProposicao.objects.create( proposicao=p, - status='T', + status="T", ip=get_client_ip(self.request), - user=self.request.user) + user=self.request.user, + ) if p.texto_articulado.exists(): ta = p.texto_articulado.first() ta.privacidade = STATUS_TA_PRIVATE ta.editing_locked = False ta.save() - self.logger.info("User={}. Proposição (numero={}) Retornada com sucesso." - .format(username, 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={}. Tentando obter objeto Proposicao com pk={}".format( - username, kwargs['pk'])) - p = Proposicao.objects.get(id=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.warning("User={}. Erro ao obter proposicao com pk={}. Retornando 404. {}" - .format(username, 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(): @@ -1010,41 +1126,63 @@ 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: - msg = '' + msg = "" if proposicao[0][0] and proposicao[0][1]: - self.logger.warning("User={}. Proposição (id={}) já foi enviada e recebida." - "Não pode mais ser excluida.".format(username, kwargs['pk'])) + 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.') + "Proposição já foi enviada e recebida. Não pode mais ser excluida." + ) elif proposicao[0][0] and not proposicao[0][1]: - self.logger.warning("""\ + 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.") + 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) @@ -1058,15 +1196,20 @@ class ProposicaoCrud(Crud): 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(): + 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() + ): self.object.user = self.request.user self.object.ip = get_client_ip(self.request) from django.utils import timezone + self.object.ultima_edicao = timezone.now() self.object.save() @@ -1074,11 +1217,11 @@ class ProposicaoCrud(Crud): dict_objeto_novo = self.object.__dict__ atributos = [ - 'tipo_id', - 'descricao', - 'observacao', - 'texto_original', - 'materia_de_vinculo_id' + "tipo_id", + "descricao", + "observacao", + "texto_original", + "materia_de_vinculo_id", ] for atributo in atributos: @@ -1086,6 +1229,7 @@ class ProposicaoCrud(Crud): self.object.user = self.request.user self.object.ip = get_client_ip(self.request) from django.utils import timezone + self.object.ultima_edicao = timezone.now() self.object.save() break @@ -1093,24 +1237,34 @@ 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 = '' + msg = "" if proposicao[0][0] and proposicao[0][1]: - self.logger.warning('User={}. Proposição (id={}) já foi enviada e recebida. ' - 'Não pode mais ser editada'.format(username, kwargs['pk'])) + 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') + "Proposição já foi enviada e recebida. Não pode mais ser editada" + ) elif proposicao[0][0] and not proposicao[0][1]: - self.logger.warning("""\ + 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.") + 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) @@ -1118,17 +1272,28 @@ class ProposicaoCrud(Crud): return True def get_success_url(self): - tipo_texto = self.request.POST.get('tipo_texto', '') + tipo_texto = self.request.POST.get("tipo_texto", "") username = self.request.user.username - if tipo_texto == 'T': - messages.info(self.request, _("""\ + 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("""\ + 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}) + 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) @@ -1140,60 +1305,69 @@ class ProposicaoCrud(Crud): def get_initial(self): initial = super().get_initial() - initial['user'] = self.request.user - initial['ip'] = get_client_ip(self.request) + initial["user"] = self.request.user + initial["ip"] = get_client_ip(self.request) from django.utils import timezone - initial['ultima_edicao'] = timezone.now() + + initial["ultima_edicao"] = timezone.now() return initial def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context def get_success_url(self): - - tipo_texto = self.request.POST.get('tipo_texto', '') + tipo_texto = self.request.POST.get("tipo_texto", "") username = self.request.user.username - if tipo_texto == 'T': - messages.info(self.request, _("""\ + 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("""\ + 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}) + 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 = timezone.localtime(obj.data_recebimento) obj.data_recebimento = formats.date_format( - obj.data_recebimento, "DATETIME_FORMAT") + obj.data_recebimento, "DATETIME_FORMAT" + ) if obj.data_envio is None: - obj.data_envio = 'Em elaboração...' + 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, "DATETIME_FORMAT" + ) return [self._as_row(obj) for obj in object_list] @@ -1201,107 +1375,116 @@ class ProposicaoCrud(Crud): class ReciboProposicaoView(TemplateView): logger = logging.getLogger(__name__) template_name = "materia/recibo_proposicao.html" - permission_required = ('materia.detail_proposicao', ) + permission_required = ("materia.detail_proposicao",) def has_permission(self): perms = self.get_permission_required() if not self.request.user.has_perms(perms): return False - return (Proposicao.objects.filter( - id=self.kwargs['pk'], - autor__operadores=self.request.user).exists()) + return Proposicao.objects.filter( + id=self.kwargs["pk"], autor__operadores=self.request.user + ).exists() def get_context_data(self, **kwargs): - context = super(ReciboProposicaoView, self).get_context_data( - **kwargs) - proposicao = Proposicao.objects.get(pk=self.kwargs['pk']) + context = super(ReciboProposicaoView, self).get_context_data(**kwargs) + proposicao = Proposicao.objects.get(pk=self.kwargs["pk"]) if proposicao.texto_original: _hash = gerar_hash_arquivo( - proposicao.texto_original.path, - self.kwargs['pk']) + proposicao.texto_original.path, self.kwargs["pk"] + ) elif proposicao.texto_articulado.exists(): ta = proposicao.texto_articulado.first() # FIXME hash para textos articulados - _hash = 'P' + ta.hash() + '/' + str(proposicao.id) + _hash = "P" + ta.hash() + "/" + str(proposicao.id) from sapl.utils import create_barcode + base64_data = create_barcode(_hash, 100, 500) - barcode = 'data:image/png;base64,{0}'.format(base64_data) + barcode = "data:image/png;base64,{0}".format(base64_data) - context.update({'proposicao': proposicao, - 'hash': _hash, - 'barcode': barcode}) + context.update({"proposicao": proposicao, "hash": _hash, "barcode": barcode}) return context def get(self, request, *args, **kwargs): - proposicao = Proposicao.objects.get(pk=self.kwargs['pk']) + proposicao = Proposicao.objects.get(pk=self.kwargs["pk"]) username = request.user.username if proposicao.data_envio: return TemplateView.get(self, request, *args, **kwargs) if not proposicao.data_envio and not proposicao.data_devolucao: - self.logger.error('user=' + username + '. Não é possível gerar recibo para uma ' - 'Proposição (pk={}) ainda não enviada.'.format(self.kwargs['pk'])) - messages.error(request, _('Não é possível gerar recibo para uma ' - 'Proposição ainda não enviada.')) + self.logger.error( + "user=" + username + ". Não é possível gerar recibo para uma " + "Proposição (pk={}) ainda não enviada.".format(self.kwargs["pk"]) + ) + messages.error( + request, + _( + "Não é possível gerar recibo para uma " + "Proposição ainda não enviada." + ), + ) elif proposicao.data_devolucao: self.logger.error( - "user=" + username + ". Não é possível gerar recibo para proposicao de pk={}.".format(self.kwargs['pk'])) - messages.error(request, _('Não é possível gerar recibo.')) + "user=" + + username + + ". Não é possível gerar recibo para proposicao de pk={}.".format( + self.kwargs["pk"] + ) + ) + messages.error(request, _("Não é possível gerar recibo.")) - return redirect(reverse('sapl.materia:proposicao_detail', - kwargs={'pk': proposicao.pk})) + return redirect( + reverse("sapl.materia:proposicao_detail", kwargs={"pk": proposicao.pk}) + ) class HistoricoProposicaoView(PermissionRequiredMixin, ListView): logger = logging.getLogger(__name__) template_name = "materia/historico_proposicao.html" - ordering = ['-data_hora'] + ordering = ["-data_hora"] paginate_by = 10 model = HistoricoProposicao permission_required = ( - 'materia.list_historicoproposicao', - 'materia.add_historicoproposicao', - 'materia.change_historicoproposicao', - 'materia.delete_historicoproposicao', - 'materia.detail_historicoproposicao', + "materia.list_historicoproposicao", + "materia.add_historicoproposicao", + "materia.change_historicoproposicao", + "materia.delete_historicoproposicao", + "materia.detail_historicoproposicao", ) def get_queryset(self): qs = super().get_queryset() - from sapl.rules import SAPL_GROUP_AUTOR from django.contrib.auth.models import Group + from sapl.rules import SAPL_GROUP_AUTOR + user = self.request.user grupo_autor = Group.objects.get(name=SAPL_GROUP_AUTOR) - if not user.is_superuser and grupo_autor.user_set.filter( - id=user.id).exists(): + if not user.is_superuser and grupo_autor.user_set.filter(id=user.id).exists(): autores = Autor.objects.filter(operadores=user) qs = qs.filter(proposicao__autor__in=autores) return qs def get_context_data(self, **kwargs): - context = super(HistoricoProposicaoView, - self).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'] = 'Nenhuma proposição' + context = super(HistoricoProposicaoView, self).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"] = "Nenhuma proposição" if self.request.user.is_superuser: - context['subnav_template_name'] = 'materia/subnav_prop.yaml' + context["subnav_template_name"] = "materia/subnav_prop.yaml" return context class RelatoriaCrud(MasterDetailCrud): model = Relatoria - parent_field = 'materia' - help_topic = 'tramitacao_relatoria' + parent_field = "materia" + help_topic = "tramitacao_relatoria" public = [RP_LIST, RP_DETAIL] class CreateView(MasterDetailCrud.CreateView): @@ -1310,11 +1493,13 @@ class RelatoriaCrud(MasterDetailCrud): logger = logging.getLogger(__name__) def get_initial(self): - materia = MateriaLegislativa.objects.get(id=self.kwargs['pk']) + materia = MateriaLegislativa.objects.get(id=self.kwargs["pk"]) - loc_atual = Tramitacao.objects.\ - filter(materia=materia).order_by( - '-data_tramitacao', '-id').first() + loc_atual = ( + Tramitacao.objects.filter(materia=materia) + .order_by("-data_tramitacao", "-id") + .first() + ) if loc_atual is None: localizacao = -1 @@ -1333,14 +1518,15 @@ class RelatoriaCrud(MasterDetailCrud): unidade_tramitacao_destino = loc_atual.unidade_tramitacao_destino return { - 'comissao': localizacao, 'tipo_unidade_tramitacao_destino': tipo_unidade_tramitacao_destino, - 'unidade_tramitacao_destino': unidade_tramitacao_destino + "comissao": localizacao, + "tipo_unidade_tramitacao_destino": tipo_unidade_tramitacao_destino, + "unidade_tramitacao_destino": unidade_tramitacao_destino, } - return {'comissao': localizacao} + return {"comissao": localizacao} class ListView(MasterDetailCrud.ListView): - layout_key = 'RelatoriaList' + layout_key = "RelatoriaList" class UpdateView(MasterDetailCrud.UpdateView): form_class = RelatoriaForm @@ -1348,62 +1534,78 @@ class RelatoriaCrud(MasterDetailCrud): logger = logging.getLogger(__name__) def get_initial(self): - relatoria = Relatoria.objects.get(id=self.kwargs['pk']) + relatoria = Relatoria.objects.get(id=self.kwargs["pk"]) parlamentar = relatoria.parlamentar comissao = relatoria.comissao - composicoes = [p.composicao for p in - Participacao.objects.filter( - parlamentar=parlamentar, - composicao__comissao=comissao)] + composicoes = [ + p.composicao + for p in Participacao.objects.filter( + parlamentar=parlamentar, composicao__comissao=comissao + ) + ] data_designacao = relatoria.data_designacao_relator - composicao = '' + composicao = "" for c in composicoes: data_inicial = c.periodo.data_inicio - data_fim = c.periodo.data_fim if c.periodo.data_fim else timezone.now().date() + data_fim = ( + c.periodo.data_fim if c.periodo.data_fim else timezone.now().date() + ) if data_inicial <= data_designacao <= data_fim: composicao = c.id break - return {'comissao': relatoria.comissao.id, - 'parlamentar': relatoria.parlamentar.id, - 'composicao': composicao} + return { + "comissao": relatoria.comissao.id, + "parlamentar": relatoria.parlamentar.id, + "composicao": composicao, + } class TramitacaoCrud(MasterDetailCrud): model = Tramitacao - parent_field = 'materia' - help_topic = 'tramitacao_relatoria' + parent_field = "materia" + help_topic = "tramitacao_relatoria" public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['data_tramitacao', 'unidade_tramitacao_local', - 'unidade_tramitacao_destino', 'status'] + list_field_names = [ + "data_tramitacao", + "unidade_tramitacao_local", + "unidade_tramitacao_destino", + "status", + ] ordered_list = False - ordering = '-data_tramitacao', + ordering = ("-data_tramitacao",) class CreateView(MasterDetailCrud.CreateView): form_class = TramitacaoForm logger = logging.getLogger(__name__) def get_success_url(self): - return reverse('sapl.materia:tramitacao_list', kwargs={ - 'pk': self.kwargs['pk']}) + return reverse( + "sapl.materia:tramitacao_list", kwargs={"pk": self.kwargs["pk"]} + ) def get_initial(self): initial = super(CreateView, self).get_initial() - local = MateriaLegislativa.objects.get(pk=self.kwargs['pk'])\ - .tramitacao_set.order_by('-data_tramitacao', '-id').first() + local = ( + MateriaLegislativa.objects.get(pk=self.kwargs["pk"]) + .tramitacao_set.order_by("-data_tramitacao", "-id") + .first() + ) if local: - initial['unidade_tramitacao_local' - ] = local.unidade_tramitacao_destino.pk + initial[ + "unidade_tramitacao_local" + ] = local.unidade_tramitacao_destino.pk else: - initial['unidade_tramitacao_local'] = '' - initial['data_tramitacao'] = timezone.now().date() - initial['ip'] = get_client_ip(self.request) - initial['user'] = self.request.user + initial["unidade_tramitacao_local"] = "" + initial["data_tramitacao"] = timezone.now().date() + initial["ip"] = get_client_ip(self.request) + initial["user"] = self.request.user from django.utils import timezone - initial['ultima_edicao'] = timezone.now() + + initial["ultima_edicao"] = timezone.now() return initial @@ -1411,35 +1613,44 @@ class TramitacaoCrud(MasterDetailCrud): context = super().get_context_data(**kwargs) username = self.request.user.username - ultima_tramitacao = Tramitacao.objects.filter( - materia_id=self.kwargs['pk']).order_by( - '-data_tramitacao', - '-id').first() + ultima_tramitacao = ( + Tramitacao.objects.filter(materia_id=self.kwargs["pk"]) + .order_by("-data_tramitacao", "-id") + .first() + ) # TODO: Esta checagem foi inserida na issue #2027, mas é mesmo # necessária? if ultima_tramitacao: if ultima_tramitacao.unidade_tramitacao_destino: - if BaseAppConfig.attr('tramitacao_origem_fixa'): - context['form'].fields[ - 'unidade_tramitacao_local'].choices = [ - (ultima_tramitacao.unidade_tramitacao_destino.pk, - ultima_tramitacao.unidade_tramitacao_destino)] + if BaseAppConfig.attr("tramitacao_origem_fixa"): + context["form"].fields["unidade_tramitacao_local"].choices = [ + ( + ultima_tramitacao.unidade_tramitacao_destino.pk, + ultima_tramitacao.unidade_tramitacao_destino, + ) + ] else: - self.logger.error('user=' + username + '. Unidade de tramitação destino ' - 'da última tramitação não pode ser vazia!') - msg = _('Unidade de tramitação destino ' - ' da última tramitação não pode ser vazia!') + self.logger.error( + "user=" + username + ". Unidade de tramitação destino " + "da última tramitação não pode ser vazia!" + ) + msg = _( + "Unidade de tramitação destino " + " da última tramitação não pode ser vazia!" + ) messages.add_message(self.request, messages.ERROR, msg) - primeira_tramitacao = not(Tramitacao.objects.filter( - materia_id=int(kwargs['root_pk'])).exists()) + primeira_tramitacao = not ( + Tramitacao.objects.filter(materia_id=int(kwargs["root_pk"])).exists() + ) # Se não for a primeira tramitação daquela matéria, o campo # não pode ser modificado - if not primeira_tramitacao and BaseAppConfig.attr('tramitacao_origem_fixa'): - context['form'].fields[ - 'unidade_tramitacao_local'].widget.attrs['readonly'] = True + if not primeira_tramitacao and BaseAppConfig.attr("tramitacao_origem_fixa"): + context["form"].fields["unidade_tramitacao_local"].widget.attrs[ + "readonly" + ] = True return context @@ -1447,58 +1658,64 @@ class TramitacaoCrud(MasterDetailCrud): form_class = TramitacaoUpdateForm logger = logging.getLogger(__name__) - layout_key = 'TramitacaoUpdate' + layout_key = "TramitacaoUpdate" def get_initial(self): initial = super(UpdateView, self).get_initial() - initial['ip'] = get_client_ip(self.request) - initial['user'] = self.request.user + initial["ip"] = get_client_ip(self.request) + initial["user"] = self.request.user from django.utils import timezone - initial['ultima_edicao'] = timezone.now() + + initial["ultima_edicao"] = timezone.now() return initial class ListView(MasterDetailCrud.ListView): - def get_queryset(self): qs = super(MasterDetailCrud.ListView, self).get_queryset() - kwargs = {self.crud.parent_field: self.kwargs['pk']} - return qs.filter(**kwargs).order_by('-data_tramitacao', - '-timestamp', - '-id') + kwargs = {self.crud.parent_field: self.kwargs["pk"]} + return qs.filter(**kwargs).order_by("-data_tramitacao", "-timestamp", "-id") class DeleteView(MasterDetailCrud.DeleteView): - logger = logging.getLogger(__name__) def delete(self, request, *args, **kwargs): - tramitacao = Tramitacao.objects.select_related( - 'materia').get(id=self.kwargs['pk']) + tramitacao = Tramitacao.objects.select_related("materia").get( + id=self.kwargs["pk"] + ) materia = tramitacao.materia - url = reverse('sapl.materia:tramitacao_list', - kwargs={'pk': materia.id}) + url = reverse("sapl.materia:tramitacao_list", kwargs={"pk": materia.id}) ultima_tramitacao = materia.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() + "-data_tramitacao", "-id" + ).first() 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)) - msg = _('Somente a última tramitação pode ser deletada!') + 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 + ) + ) + msg = _("Somente a última tramitação pode ser deletada!") messages.add_message(request, messages.ERROR, msg) return HttpResponseRedirect(url) else: - # recupera últimas duas tramitacoes - penultima_tramitacao = materia.tramitacao_set.order_by( - '-data_tramitacao', '-id').exclude( - id=ultima_tramitacao.id).first() - if not penultima_tramitacao or \ - penultima_tramitacao.status.indicador == "F": + penultima_tramitacao = ( + materia.tramitacao_set.order_by("-data_tramitacao", "-id") + .exclude(id=ultima_tramitacao.id) + .first() + ) + if ( + not penultima_tramitacao + or penultima_tramitacao.status.indicador == "F" + ): materia.em_tramitacao = False else: materia.em_tramitacao = True @@ -1507,33 +1724,40 @@ class TramitacaoCrud(MasterDetailCrud): tramitacoes_deletar = [tramitacao.id] tramitar_anexadas = sapl.base.models.AppConfig.attr( - 'tramitacao_materia') + "tramitacao_materia" + ) if tramitar_anexadas: materias_anexadas = lista_anexados(materia) for materia in materias_anexadas: ultima_tramitacao = materia.tramitacao_set.order_by( - '-data_tramitacao', '-id').first() - if compara_tramitacoes_mat(ultima_tramitacao, - tramitacao): + "-data_tramitacao", "-id" + ).first() + if compara_tramitacoes_mat(ultima_tramitacao, tramitacao): tramitacoes_deletar.append(ultima_tramitacao.id) # recupera últimas duas tramitacoes - penultima_tramitacao = materia.tramitacao_set.order_by( - '-data_tramitacao', '-id').exclude( - id=ultima_tramitacao.id).first() - if not penultima_tramitacao or \ - penultima_tramitacao.status.indicador == "F": + penultima_tramitacao = ( + materia.tramitacao_set.order_by( + "-data_tramitacao", "-id" + ) + .exclude(id=ultima_tramitacao.id) + .first() + ) + if ( + not penultima_tramitacao + or penultima_tramitacao.status.indicador == "F" + ): materia.em_tramitacao = False else: materia.em_tramitacao = True # Atualiza status 'em_tramitacao' - MateriaLegislativa.objects.\ - bulk_update(materias_anexadas, ['em_tramitacao']) + MateriaLegislativa.objects.bulk_update( + materias_anexadas, ["em_tramitacao"] + ) Tramitacao.objects.filter(id__in=tramitacoes_deletar).delete() return HttpResponseRedirect(url) class DetailView(MasterDetailCrud.DetailView): - template_name = "materia/tramitacao_detail.html" def get_context_data(self, **kwargs): @@ -1542,7 +1766,7 @@ class TramitacaoCrud(MasterDetailCrud): def montar_helper_documento_acessorio(self): - autor_row = montar_row_autor('autor') + autor_row = montar_row_autor("autor") self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout(*self.get_layout()) @@ -1555,19 +1779,27 @@ def montar_helper_documento_acessorio(self): self.helper.layout[1].pop() # Adiciona novos botões dentro do form - self.helper.layout[0][3][0].insert(1, form_actions(more=[ - HTML('Cancelar')])) + self.helper.layout[0][3][0].insert( + 1, + form_actions( + more=[ + HTML( + 'Cancelar' + ) + ] + ), + ) class DocumentoAcessorioCrud(MasterDetailCrud): model = DocumentoAcessorio - parent_field = 'materia' - help_topic = 'despacho_autoria' + parent_field = "materia" + help_topic = "despacho_autoria" public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['nome', 'tipo', 'data', 'autor', 'arquivo'] + list_field_names = ["nome", "tipo", "data", "autor", "arquivo"] class CreateView(MasterDetailCrud.CreateView): form_class = DocumentoAcessorioForm @@ -1577,13 +1809,14 @@ class DocumentoAcessorioCrud(MasterDetailCrud): def get_initial(self): initial = super(CreateView, self).get_initial() - initial['data'] = timezone.now().date() + initial["data"] = timezone.now().date() return initial def get_context_data(self, **kwargs): - context = super( - MasterDetailCrud.CreateView, self).get_context_data(**kwargs) + context = super(MasterDetailCrud.CreateView, self).get_context_data( + **kwargs + ) return context class UpdateView(MasterDetailCrud.UpdateView): @@ -1599,12 +1832,12 @@ class DocumentoAcessorioCrud(MasterDetailCrud): class AutoriaCrud(MasterDetailCrud): model = Autoria - parent_field = 'materia' - help_topic = 'despacho_autoria' + parent_field = "materia" + help_topic = "despacho_autoria" public = [RP_LIST, RP_DETAIL] - list_field_names = ['autor', 'autor__tipo__descricao', 'primeiro_autor'] + list_field_names = ["autor", "autor__tipo__descricao", "primeiro_autor"] - class LocalBaseMixin(): + class LocalBaseMixin: form_class = AutoriaForm @property @@ -1612,35 +1845,35 @@ class AutoriaCrud(MasterDetailCrud): return None class CreateView(LocalBaseMixin, MasterDetailCrud.CreateView): - def get_initial(self): initial = super().get_initial() - materia = MateriaLegislativa.objects.get(id=self.kwargs['pk']) - initial['data_relativa'] = materia.data_apresentacao - initial['autor'] = [] - initial['materia'] = materia + materia = MateriaLegislativa.objects.get(id=self.kwargs["pk"]) + initial["data_relativa"] = materia.data_apresentacao + initial["autor"] = [] + initial["materia"] = materia return initial class UpdateView(LocalBaseMixin, MasterDetailCrud.UpdateView): - def get_initial(self): initial = super().get_initial() - initial.update({ - 'data_relativa': self.object.materia.data_apresentacao, - 'tipo_autor': self.object.autor.tipo.id, - 'materia': self.object.materia - }) + initial.update( + { + "data_relativa": self.object.materia.data_apresentacao, + "tipo_autor": self.object.autor.tipo.id, + "materia": self.object.materia, + } + ) return initial class AutoriaMultiCreateView(PermissionRequiredForAppCrudMixin, FormView): app_label = sapl.materia.apps.AppConfig.label form_class = AutoriaMultiCreateForm - template_name = 'materia/autoria_multicreate_form.html' + template_name = "materia/autoria_multicreate_form.html" @classmethod def get_url_regex(cls): - return r'^(?P\d+)/%s/multicreate' % cls.model._meta.model_name + return r"^(?P\d+)/%s/multicreate" % cls.model._meta.model_name @property def layout_key(self): @@ -1648,30 +1881,32 @@ class AutoriaMultiCreateView(PermissionRequiredForAppCrudMixin, FormView): def get_initial(self): initial = super().get_initial() - self.materia = MateriaLegislativa.objects.get(id=self.kwargs['pk']) - initial['data_relativa'] = self.materia.data_apresentacao - initial['autores'] = self.materia.autores.all() + self.materia = MateriaLegislativa.objects.get(id=self.kwargs["pk"]) + initial["data_relativa"] = self.materia.data_apresentacao + initial["autores"] = self.materia.autores.all() return initial def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['title'] = '%s (%s)' % ( - _('Adicionar Várias Autorias'), self.materia) + context["title"] = "%s (%s)" % ( + _("Adicionar Várias Autorias"), + self.materia, + ) return context def get_success_url(self): messages.add_message( - self.request, messages.SUCCESS, - _('Autorias adicionadas com sucesso.')) - return reverse( - 'sapl.materia:autoria_list', kwargs={'pk': self.materia.pk}) + self.request, messages.SUCCESS, _("Autorias adicionadas com sucesso.") + ) + return reverse("sapl.materia:autoria_list", kwargs={"pk": self.materia.pk}) def form_valid(self, form): - autores_selecionados = form.cleaned_data['autor'] - primeiro_autor = form.cleaned_data['primeiro_autor'] + autores_selecionados = form.cleaned_data["autor"] + primeiro_autor = form.cleaned_data["primeiro_autor"] for autor in autores_selecionados: - Autoria.objects.create(materia=self.materia, - autor=autor, primeiro_autor=primeiro_autor) + Autoria.objects.create( + materia=self.materia, autor=autor, primeiro_autor=primeiro_autor + ) return FormView.form_valid(self, form) @@ -1679,47 +1914,50 @@ class AutoriaMultiCreateView(PermissionRequiredForAppCrudMixin, FormView): class DespachoInicialMultiCreateView(PermissionRequiredForAppCrudMixin, FormView): app_label = sapl.materia.apps.AppConfig.label form_class = DespachoInicialCreateForm - template_name = 'materia/despachoinicial_multicreate_form.html' + template_name = "materia/despachoinicial_multicreate_form.html" def get_initial(self): initial = super().get_initial() - self.materia = MateriaLegislativa.objects.get(id=self.kwargs['pk']) - initial['materia'] = self.materia + self.materia = MateriaLegislativa.objects.get(id=self.kwargs["pk"]) + initial["materia"] = self.materia return initial def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['title'] = '%s (%s)' % ( - _('Adicionar Vários Despachos'), self.materia) - context['root_pk'] = self.kwargs['pk'] - context['subnav_template_name'] = 'materia/subnav.yaml' + context["title"] = "%s (%s)" % ( + _("Adicionar Vários Despachos"), + self.materia, + ) + context["root_pk"] = self.kwargs["pk"] + context["subnav_template_name"] = "materia/subnav.yaml" return context def get_success_url(self): messages.add_message( - self.request, messages.SUCCESS, - _('Despachos adicionados com sucesso.')) + self.request, messages.SUCCESS, _("Despachos adicionados com sucesso.") + ) return reverse( - 'sapl.materia:despachoinicial_list', kwargs={'pk': self.materia.pk}) + "sapl.materia:despachoinicial_list", kwargs={"pk": self.materia.pk} + ) def form_valid(self, form): - comissoes_selecionadas = form.cleaned_data['comissao'] + comissoes_selecionadas = form.cleaned_data["comissao"] for comissao in comissoes_selecionadas: - DespachoInicial.objects.create( - materia=self.materia, comissao=comissao) + DespachoInicial.objects.create(materia=self.materia, comissao=comissao) return FormView.form_valid(self, form) @property def cancel_url(self): return reverse( - 'sapl.materia:despachoinicial_list', kwargs={'pk': self.materia.pk}) + "sapl.materia:despachoinicial_list", kwargs={"pk": self.materia.pk} + ) class DespachoInicialCrud(MasterDetailCrud): model = DespachoInicial - parent_field = 'materia' - help_topic = 'despacho_autoria' + parent_field = "materia" + help_topic = "despacho_autoria" public = [RP_LIST, RP_DETAIL] class UpdateView(MasterDetailCrud.UpdateView): @@ -1728,17 +1966,16 @@ class DespachoInicialCrud(MasterDetailCrud): class LegislacaoCitadaCrud(MasterDetailCrud): model = LegislacaoCitada - parent_field = 'materia' - help_topic = 'legislacao_cita_matanexada' + parent_field = "materia" + help_topic = "legislacao_cita_matanexada" public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['norma', 'disposicoes'] + list_field_names = ["norma", "disposicoes"] def resolve_url(self, suffix, args=None): - namespace = 'sapl.materia' - return reverse('%s:%s' % (namespace, self.url_name(suffix)), - args=args) + namespace = "sapl.materia" + return reverse("%s:%s" % (namespace, self.url_name(suffix)), args=args) class CreateView(MasterDetailCrud.CreateView): form_class = LegislacaoCitadaForm @@ -1748,14 +1985,13 @@ class LegislacaoCitadaCrud(MasterDetailCrud): def get_initial(self): initial = super(UpdateView, self).get_initial() - initial['tipo'] = self.object.norma.tipo.id - initial['numero'] = self.object.norma.numero - initial['ano'] = self.object.norma.ano + initial["tipo"] = self.object.norma.tipo.id + initial["numero"] = self.object.norma.numero + initial["ano"] = self.object.norma.ano return initial class DetailView(MasterDetailCrud.DetailView): - - layout_key = 'LegislacaoCitadaDetail' + layout_key = "LegislacaoCitadaDetail" class DeleteView(MasterDetailCrud.DeleteView): pass @@ -1763,19 +1999,19 @@ class LegislacaoCitadaCrud(MasterDetailCrud): class NumeracaoCrud(MasterDetailCrud): model = Numeracao - parent_field = 'materia' - help_topic = 'numeracao_docsacess' + parent_field = "materia" + help_topic = "numeracao_docsacess" public = [RP_LIST, RP_DETAIL] class AnexadaCrud(MasterDetailCrud): model = Anexada - parent_field = 'materia_principal' - help_topic = 'materia_anexada' + parent_field = "materia_principal" + help_topic = "materia_anexada" public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['materia_anexada', 'data_anexacao'] + list_field_names = ["materia_anexada", "data_anexacao"] class CreateView(MasterDetailCrud.CreateView): form_class = AnexadaForm @@ -1785,33 +2021,32 @@ class AnexadaCrud(MasterDetailCrud): def get_initial(self): initial = super(UpdateView, self).get_initial() - initial['tipo'] = self.object.materia_anexada.tipo.id - initial['numero'] = self.object.materia_anexada.numero - initial['ano'] = self.object.materia_anexada.ano + initial["tipo"] = self.object.materia_anexada.tipo.id + initial["numero"] = self.object.materia_anexada.numero + initial["ano"] = self.object.materia_anexada.ano return initial class DetailView(MasterDetailCrud.DetailView): - @property def layout_key(self): - return 'AnexadaDetail' + return "AnexadaDetail" class MateriaAssuntoCrud(MasterDetailCrud): model = MateriaAssunto - parent_field = 'materia' - help_topic = '' + parent_field = "materia" + help_topic = "" public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['assunto', 'materia'] + list_field_names = ["assunto", "materia"] class CreateView(MasterDetailCrud.CreateView): form_class = MateriaAssuntoForm def get_initial(self): initial = super(CreateView, self).get_initial() - initial['materia'] = self.kwargs['pk'] + initial["materia"] = self.kwargs["pk"] return initial class UpdateView(MasterDetailCrud.UpdateView): @@ -1819,38 +2054,38 @@ class MateriaAssuntoCrud(MasterDetailCrud): def get_initial(self): initial = super(UpdateView, self).get_initial() - initial['materia'] = self.get_object().materia - initial['assunto'] = self.get_object().assunto + initial["materia"] = self.get_object().materia + initial["assunto"] = self.get_object().assunto return initial class MateriaLegislativaCrud(Crud): model = MateriaLegislativa - help_topic = 'materia_legislativa' + help_topic = "materia_legislativa" public = [RP_LIST, RP_DETAIL] class BaseMixin(Crud.BaseMixin): - list_field_names = ['tipo', 'numero', 'ano', 'data_apresentacao'] + list_field_names = ["tipo", "numero", "ano", "data_apresentacao"] - list_url = '' + list_url = "" @property def search_url(self): namespace = self.model._meta.app_config.name - return reverse('%s:%s' % (namespace, 'pesquisar_materia')) + return reverse("%s:%s" % (namespace, "pesquisar_materia")) class CreateView(Crud.CreateView): - form_class = MateriaLegislativaForm def get_initial(self): initial = super().get_initial() - initial['user'] = self.request.user - initial['ip'] = get_client_ip(self.request) + initial["user"] = self.request.user + initial["ip"] = get_client_ip(self.request) from django.utils import timezone - initial['ultima_edicao'] = timezone.now() + + initial["ultima_edicao"] = timezone.now() return initial @@ -1859,24 +2094,41 @@ class MateriaLegislativaCrud(Crud): return self.search_url class UpdateView(Crud.UpdateView): - form_class = MateriaLegislativaForm def form_valid(self, form): dict_objeto_antigo = MateriaLegislativa.objects.get( - pk=self.kwargs['pk'] + pk=self.kwargs["pk"] ).__dict__ self.object = form.save() dict_objeto_novo = self.object.__dict__ atributos = [ - 'tipo_id', 'ano', 'numero', 'data_apresentacao', 'numero_protocolo', - 'tipo_apresentacao', 'texto_original', 'apelido', 'dias_prazo', 'polemica', - 'objeto', 'regime_tramitacao_id', 'em_tramitacao', 'data_fim_prazo', - 'data_publicacao', 'complementar', 'tipo_origem_externa_id', - 'numero_origem_externa', 'ano_origem_externa', 'local_origem_externa_id', - 'data_origem_externa', 'ementa', 'indexacao', 'observacao' + "tipo_id", + "ano", + "numero", + "data_apresentacao", + "numero_protocolo", + "tipo_apresentacao", + "texto_original", + "apelido", + "dias_prazo", + "polemica", + "objeto", + "regime_tramitacao_id", + "em_tramitacao", + "data_fim_prazo", + "data_publicacao", + "complementar", + "tipo_origem_externa_id", + "numero_origem_externa", + "ano_origem_externa", + "local_origem_externa_id", + "data_origem_externa", + "ementa", + "indexacao", + "observacao", ] for atributo in atributos: @@ -1885,17 +2137,20 @@ class MateriaLegislativaCrud(Crud): self.object.ip = get_client_ip(self.request) from django.utils import timezone + self.object.ultima_edicao = timezone.now() self.object.save() break - if Anexada.objects.filter(materia_principal=self.kwargs['pk']).exists(): - materia = MateriaLegislativa.objects.get(pk=self.kwargs['pk']) + if Anexada.objects.filter(materia_principal=self.kwargs["pk"]).exists(): + materia = MateriaLegislativa.objects.get(pk=self.kwargs["pk"]) anexadas = lista_anexados(materia) for anexada in anexadas: - anexada.em_tramitacao = True if form.instance.em_tramitacao else False + anexada.em_tramitacao = ( + True if form.instance.em_tramitacao else False + ) anexada.save() return super().form_valid(form) @@ -1905,27 +2160,23 @@ class MateriaLegislativaCrud(Crud): return self.search_url class DeleteView(Crud.DeleteView): - def get_success_url(self): return self.search_url class DetailView(Crud.DetailView): - - layout_key = 'MateriaLegislativaDetail' + layout_key = "MateriaLegislativaDetail" template_name = "materia/materialegislativa_detail.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['user'] = self.request.user - context['materia'] = MateriaLegislativa.objects.get( - pk=self.kwargs['pk']) + context["user"] = self.request.user + context["materia"] = MateriaLegislativa.objects.get(pk=self.kwargs["pk"]) return context class ListView(Crud.ListView, RedirectView): - def get_redirect_url(self, *args, **kwargs): namespace = self.model._meta.app_config.name - return reverse('%s:%s' % (namespace, 'pesquisar_materia')) + return reverse("%s:%s" % (namespace, "pesquisar_materia")) def get(self, request, *args, **kwargs): return RedirectView.get(self, request, *args, **kwargs) @@ -1935,24 +2186,21 @@ class MateriaLegislativaCrud(Crud): class DocumentoAcessorioView(PermissionRequiredMixin, CreateView): template_name = "materia/documento_acessorio.html" form_class = DocumentoAcessorioForm - permission_required = ('materia.add_documentoacessorio', ) + permission_required = ("materia.add_documentoacessorio",) def get(self, request, *args, **kwargs): - materia = MateriaLegislativa.objects.get(id=kwargs['pk']) - docs = DocumentoAcessorio.objects.filter( - materia_id=kwargs['pk']).order_by('data') + materia = MateriaLegislativa.objects.get(id=kwargs["pk"]) + docs = DocumentoAcessorio.objects.filter(materia_id=kwargs["pk"]).order_by( + "data" + ) form = DocumentoAcessorioForm() - return self.render_to_response( - {'object': materia, - 'form': form, - 'docs': docs}) + return self.render_to_response({"object": materia, "form": form, "docs": docs}) def post(self, request, *args, **kwargs): form = self.get_form() - materia = MateriaLegislativa.objects.get(id=kwargs['pk']) - docs_list = DocumentoAcessorio.objects.filter( - materia_id=kwargs['pk']) + materia = MateriaLegislativa.objects.get(id=kwargs["pk"]) + docs_list = DocumentoAcessorio.objects.filter(materia_id=kwargs["pk"]) if form.is_valid(): documento_acessorio = form.save(commit=False) @@ -1960,49 +2208,61 @@ class DocumentoAcessorioView(PermissionRequiredMixin, CreateView): documento_acessorio.save() return self.form_valid(form) else: - return self.render_to_response({'form': form, - 'object': materia, - 'docs': docs_list}) + return self.render_to_response( + {"form": form, "object": materia, "docs": docs_list} + ) def get_success_url(self): - pk = self.kwargs['pk'] - return reverse('sapl.materia:documento_acessorio', kwargs={'pk': pk}) + pk = self.kwargs["pk"] + return reverse("sapl.materia:documento_acessorio", kwargs={"pk": pk}) class AcompanhamentoConfirmarView(TemplateView): - logger = logging.getLogger(__name__) def get_redirect_url(self, email): username = self.request.user.username self.logger.debug( - 'user=' + username + '. Esta matéria está sendo acompanhada pelo e-mail: %s' % (email)) - msg = _('Esta matéria está sendo acompanhada pelo e-mail: %s') % ( - email) + "user=" + + username + + ". Esta matéria está sendo acompanhada pelo e-mail: %s" % (email) + ) + msg = _("Esta matéria está sendo acompanhada pelo e-mail: %s") % (email) messages.add_message(self.request, messages.SUCCESS, msg) - return reverse('sapl.materia:materialegislativa_detail', - kwargs={'pk': self.kwargs['pk']}) + return reverse( + "sapl.materia:materialegislativa_detail", kwargs={"pk": self.kwargs["pk"]} + ) def get(self, request, *args, **kwargs): - materia_id = kwargs['pk'] - hash_txt = request.GET.get('hash_txt', '') + materia_id = kwargs["pk"] + hash_txt = request.GET.get("hash_txt", "") username = self.request.user.username try: - self.logger.info("user=" + username + ". Tentando obter objeto AcompanhamentoMateria (materia_id={}, hash={})." - .format(materia_id, hash_txt)) + self.logger.info( + "user=" + + username + + ". Tentando obter objeto AcompanhamentoMateria (materia_id={}, hash={}).".format( + materia_id, hash_txt + ) + ) acompanhar = AcompanhamentoMateria.objects.get( - materia_id=materia_id, - hash=hash_txt) + materia_id=materia_id, hash=hash_txt + ) except ObjectDoesNotExist: - self.logger.error("user=" + username + ". Objeto AcompanhamentoMateria(materia_id={}, hash={}) não encontrado." - .format(materia_id, hash_txt)) + self.logger.error( + "user=" + + username + + ". Objeto AcompanhamentoMateria(materia_id={}, hash={}) não encontrado.".format( + materia_id, hash_txt + ) + ) raise Http404() except MultipleObjectsReturned as e: # A melhor solução deve ser permitir que a exceção # (MultipleObjectsReturned) seja lançada e vá para o log, # pois só poderá ser causada por um erro de desenvolvimente - self.logger.error('user=' + username + '.' + str(e)) + self.logger.error("user=" + username + "." + str(e)) pass acompanhar.confirmado = True acompanhar.save() @@ -2011,31 +2271,43 @@ class AcompanhamentoConfirmarView(TemplateView): class AcompanhamentoExcluirView(TemplateView): - logger = logging.getLogger(__name__) def get_success_url(self): username = self.request.user.username - self.logger.debug("user=" + username + - ". Você parou de acompanhar esta matéria.") - msg = _('Você parou de acompanhar esta matéria.') + self.logger.debug( + "user=" + username + ". Você parou de acompanhar esta matéria." + ) + msg = _("Você parou de acompanhar esta matéria.") messages.add_message(self.request, messages.INFO, msg) - return reverse('sapl.materia:materialegislativa_detail', - kwargs={'pk': self.kwargs['pk']}) + return reverse( + "sapl.materia:materialegislativa_detail", kwargs={"pk": self.kwargs["pk"]} + ) def get(self, request, *args, **kwargs): - materia_id = kwargs['pk'] - hash_txt = request.GET.get('hash_txt', '') + materia_id = kwargs["pk"] + hash_txt = request.GET.get("hash_txt", "") username = self.request.user.username try: - self.logger.info("user=" + username + ". Tentando deletar objeto AcompanhamentoMateria (materia_id={}, hash={})." - .format(materia_id, hash_txt)) - AcompanhamentoMateria.objects.get(materia_id=materia_id, - hash=hash_txt).delete() + self.logger.info( + "user=" + + username + + ". Tentando deletar objeto AcompanhamentoMateria (materia_id={}, hash={}).".format( + materia_id, hash_txt + ) + ) + AcompanhamentoMateria.objects.get( + materia_id=materia_id, hash=hash_txt + ).delete() except ObjectDoesNotExist: - self.logger.error("user=" + username + ". Objeto AcompanhamentoMateria (materia_id={}, hash={}) não encontrado." - .format(materia_id, hash_txt)) + self.logger.error( + "user=" + + username + + ". Objeto AcompanhamentoMateria (materia_id={}, hash={}) não encontrado.".format( + materia_id, hash_txt + ) + ) pass return HttpResponseRedirect(self.get_success_url()) @@ -2047,39 +2319,48 @@ class MateriaLegislativaPesquisaView(MultiFormatOutputMixin, FilterView): paginate_by = 50 fields_base_report = [ - 'id', 'ano', 'numero', 'tipo__sigla', 'tipo__descricao', 'autoria__autor__nome', 'texto_original', 'ementa' + "id", + "ano", + "numero", + "tipo__sigla", + "tipo__descricao", + "autoria__autor__nome", + "texto_original", + "ementa", ] fields_report = { - 'csv': fields_base_report, - 'xlsx': fields_base_report, - 'json': fields_base_report, + "csv": fields_base_report, + "xlsx": fields_base_report, + "json": fields_base_report, } def hook_texto_original(self, obj): - url = self.request.build_absolute_uri('/')[:-1] - texto_original = obj.texto_original if not isinstance( - obj, dict) else obj["texto_original"] + url = self.request.build_absolute_uri("/")[:-1] + texto_original = ( + obj.texto_original if not isinstance(obj, dict) else obj["texto_original"] + ) - return f'{url}/media/{texto_original}' + return f"{url}/media/{texto_original}" def get_filterset_kwargs(self, filterset_class): super().get_filterset_kwargs(filterset_class) - kwargs = {'data': self.request.GET or None} + kwargs = {"data": self.request.GET or None} - tipo_listagem = self.request.GET.get('tipo_listagem', '1') - tipo_listagem = '1' if not tipo_listagem else tipo_listagem + tipo_listagem = self.request.GET.get("tipo_listagem", "1") + tipo_listagem = "1" if not tipo_listagem else tipo_listagem qs = self.get_queryset().distinct() - if tipo_listagem == '1': - - status_tramitacao = self.request.GET.get('tramitacao__status') + if tipo_listagem == "1": + status_tramitacao = self.request.GET.get("tramitacao__status") unidade_destino = self.request.GET.get( - 'tramitacao__unidade_tramitacao_destino') + "tramitacao__unidade_tramitacao_destino" + ) if status_tramitacao and unidade_destino: - lista = filtra_tramitacao_destino_and_status(status_tramitacao, - unidade_destino) + lista = filtra_tramitacao_destino_and_status( + status_tramitacao, unidade_destino + ) qs = qs.filter(id__in=lista).distinct() elif status_tramitacao: @@ -2090,69 +2371,75 @@ class MateriaLegislativaPesquisaView(MultiFormatOutputMixin, FilterView): lista = filtra_tramitacao_destino(unidade_destino) qs = qs.filter(id__in=lista).distinct() - qs = qs.prefetch_related("autoria_set", - "autoria_set__autor", - "numeracao_set", - "anexadas", - "tipo", - "texto_articulado", - "relatoria_set", - "relatoria_set__comissao", - "relatoria_set__parlamentar", - "tramitacao_set", - "tramitacao_set__status", - "tramitacao_set__unidade_tramitacao_local", - "tramitacao_set__unidade_tramitacao_destino", - "normajuridica_set", - "registrovotacao_set", - "documentoacessorio_set") + qs = qs.prefetch_related( + "autoria_set", + "autoria_set__autor", + "numeracao_set", + "anexadas", + "tipo", + "texto_articulado", + "relatoria_set", + "relatoria_set__comissao", + "relatoria_set__parlamentar", + "tramitacao_set", + "tramitacao_set__status", + "tramitacao_set__unidade_tramitacao_local", + "tramitacao_set__unidade_tramitacao_destino", + "normajuridica_set", + "registrovotacao_set", + "documentoacessorio_set", + ) else: - - qs = qs.prefetch_related("autoria_set", - "numeracao_set", - "autoria_set__autor", - "tipo",) + qs = qs.prefetch_related( + "autoria_set", + "numeracao_set", + "autoria_set__autor", + "tipo", + ) # retorna somente MateriaLegislativa sem MateriaAssunto se True - materia_assunto_null = self.request.GET.get( - "materiaassunto_null", False) + materia_assunto_null = self.request.GET.get("materiaassunto_null", False) if materia_assunto_null: qs = qs.filter(materiaassunto__isnull=True) - if 'o' in self.request.GET and not self.request.GET['o']: - args = ['-ano', 'tipo__sequencia_regimental', '-numero'] if BaseAppConfig.attr( - 'ordenacao_pesquisa_materia') == 'R' else ['-ano', 'tipo__sigla', '-numero'] + if "o" in self.request.GET and not self.request.GET["o"]: + args = ( + ["-ano", "tipo__sequencia_regimental", "-numero"] + if BaseAppConfig.attr("ordenacao_pesquisa_materia") == "R" + else ["-ano", "tipo__sigla", "-numero"] + ) qs = qs.order_by(*args) - kwargs.update({ - 'queryset': qs, - }) + kwargs.update( + { + "queryset": qs, + } + ) return kwargs def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['title'] = _('Pesquisar Matéria Legislativa') + context["title"] = _("Pesquisar Matéria Legislativa") - tipo_listagem = self.request.GET.get('tipo_listagem', '1') - tipo_listagem = '1' if not tipo_listagem else tipo_listagem + tipo_listagem = self.request.GET.get("tipo_listagem", "1") + tipo_listagem = "1" if not tipo_listagem else tipo_listagem - context['tipo_listagem'] = tipo_listagem + context["tipo_listagem"] = tipo_listagem qr = self.request.GET.copy() - if 'page' in qr: - del qr['page'] + if "page" in qr: + del qr["page"] - paginator = context['paginator'] - page_obj = context['page_obj'] + paginator = context["paginator"] + page_obj = context["page_obj"] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" - context['show_results'] = show_results_filter_set(qr) + context["show_results"] = show_results_filter_set(qr) return context @@ -2163,52 +2450,55 @@ class AcompanhamentoMateriaView(CreateView): def get_random_chars(self): s = ascii_letters + digits - return ''.join(choice(s) for i in range(choice([6, 7]))) + return "".join(choice(s) for i in range(choice([6, 7]))) def get(self, request, *args, **kwargs): if not mail_service_configured(): - self.logger.warning(_('Servidor de email não configurado.')) - messages.error(request, _('Serviço de Acompanhamento de ' - 'Matérias não foi configurado')) - return redirect('/') + self.logger.warning(_("Servidor de email não configurado.")) + messages.error( + request, + _("Serviço de Acompanhamento de " "Matérias não foi configurado"), + ) + return redirect("/") if not google_recaptcha_configured(): - self.logger.warning(_('Google Recaptcha não configurado!')) - messages.error(request, _('Google Recaptcha não configurado!')) - return redirect(request.headers.get('referer', '/')) + self.logger.warning(_("Google Recaptcha não configurado!")) + messages.error(request, _("Google Recaptcha não configurado!")) + return redirect(request.headers.get("referer", "/")) - pk = self.kwargs['pk'] + pk = self.kwargs["pk"] materia = MateriaLegislativa.objects.get(id=pk) return self.render_to_response( - {'form': AcompanhamentoMateriaForm(), - 'materia': materia}) + {"form": AcompanhamentoMateriaForm(), "materia": materia} + ) def post(self, request, *args, **kwargs): - if not settings.EMAIL_HOST: - self.logger.warning(_('Servidor de email não configurado.')) - messages.error(request, _('Serviço de Acompanhamento de ' - 'Matérias não foi configurado')) - return redirect('/') + self.logger.warning(_("Servidor de email não configurado.")) + messages.error( + request, + _("Serviço de Acompanhamento de " "Matérias não foi configurado"), + ) + return redirect("/") if not google_recaptcha_configured(): - self.logger.warning(_('Google Recaptcha não configurado!')) - messages.error(request, _('Google Recaptcha não configurado!')) - return redirect(request.headers.get('referer', '/')) + self.logger.warning(_("Google Recaptcha não configurado!")) + messages.error(request, _("Google Recaptcha não configurado!")) + return redirect(request.headers.get("referer", "/")) form = AcompanhamentoMateriaForm(request.POST) - pk = self.kwargs['pk'] + pk = self.kwargs["pk"] materia = MateriaLegislativa.objects.get(id=pk) if form.is_valid(): - email = form.cleaned_data['email'] + email = form.cleaned_data["email"] usuario = request.user hash_txt = self.get_random_chars() acompanhar = AcompanhamentoMateria.objects.get_or_create( - materia=materia, - email=form.data['email']) + materia=materia, email=form.data["email"] + ) # Se o segundo elemento do retorno do get_or_create for True # quer dizer que o elemento não existia @@ -2222,22 +2512,25 @@ class AcompanhamentoMateriaView(CreateView): base_url = get_base_url(request) destinatario = AcompanhamentoMateria.objects.get( - materia=materia, - email=email, - confirmado=False) + materia=materia, email=email, confirmado=False + ) casa = CasaLegislativa.objects.first() - do_envia_email_confirmacao(base_url, - casa, - "materia", - materia, - destinatario) - self.logger.debug('user=' + usuario.username + '. Foi enviado um e-mail de confirmação. Confira sua caixa \ + do_envia_email_confirmacao( + base_url, casa, "materia", materia, destinatario + ) + self.logger.debug( + "user=" + + usuario.username + + ". Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ - confirmar o acompanhamento desta matéria.') - msg = _('Foi enviado um e-mail de confirmação. Confira sua caixa \ + confirmar o acompanhamento desta matéria." + ) + msg = _( + "Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ - confirmar o acompanhamento desta matéria.') + confirmar o acompanhamento desta matéria." + ) messages.add_message(request, messages.SUCCESS, msg) # Se o elemento existir e o email não foi confirmado: @@ -2250,121 +2543,128 @@ class AcompanhamentoMateriaView(CreateView): base_url = get_base_url(request) destinatario = AcompanhamentoMateria.objects.get( - materia=materia, - email=email, - confirmado=False + materia=materia, email=email, confirmado=False ) casa = CasaLegislativa.objects.first() - do_envia_email_confirmacao(base_url, - casa, - "materia", - materia, - destinatario) + do_envia_email_confirmacao( + base_url, casa, "materia", materia, destinatario + ) - self.logger.debug('user=' + usuario.username + '. Foi enviado um e-mail de confirmação. Confira sua caixa \ + self.logger.debug( + "user=" + + usuario.username + + ". Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ - confirmar o acompanhamento desta matéria.') + confirmar o acompanhamento desta matéria." + ) - msg = _('Foi enviado um e-mail de confirmação. Confira sua caixa \ + msg = _( + "Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ - confirmar o acompanhamento desta matéria.') + confirmar o acompanhamento desta matéria." + ) messages.add_message(request, messages.SUCCESS, msg) # Caso esse Acompanhamento já exista # avisa ao usuário que essa matéria já está sendo acompanhada else: - self.logger.debug("user=" + usuario.username + - ". Este e-mail já está acompanhando essa matéria.") - msg = _('Este e-mail já está acompanhando essa matéria.') + self.logger.debug( + "user=" + + usuario.username + + ". Este e-mail já está acompanhando essa matéria." + ) + msg = _("Este e-mail já está acompanhando essa matéria.") messages.add_message(request, messages.ERROR, msg) - return self.render_to_response( - {'form': form, - 'materia': materia - }) + return self.render_to_response({"form": form, "materia": materia}) return HttpResponseRedirect(self.get_success_url()) else: - return self.render_to_response( - {'form': form, - 'materia': materia}) + return self.render_to_response({"form": form, "materia": materia}) def get_success_url(self): - return reverse('sapl.materia:materialegislativa_detail', - kwargs={'pk': self.kwargs['pk']}) + return reverse( + "sapl.materia:materialegislativa_detail", kwargs={"pk": self.kwargs["pk"]} + ) class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView): filterset_class = AcessorioEmLoteFilterSet - template_name = 'materia/em_lote/acessorio.html' - permission_required = ('materia.add_documentoacessorio',) + template_name = "materia/em_lote/acessorio.html" + permission_required = ("materia.add_documentoacessorio",) logger = logging.getLogger(__name__) def get_context_data(self, **kwargs): - context = super(DocumentoAcessorioEmLoteView, - self).get_context_data(**kwargs) + context = super(DocumentoAcessorioEmLoteView, self).get_context_data(**kwargs) - context['title'] = _('Documentos Acessórios em Lote') + context["title"] = _("Documentos Acessórios em Lote") # Verifica se os campos foram preenchidos if not self.filterset.form.is_valid(): return context qr = self.request.GET.copy() - context['tipos_docs'] = TipoDocumento.objects.all() + context["tipos_docs"] = TipoDocumento.objects.all() if not len(qr): - context['object_list'] = [] + context["object_list"] = [] else: - context['object_list'] = context['object_list'].order_by( - 'ano', 'numero') + context["object_list"] = context["object_list"].order_by("ano", "numero") - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" - context['show_results'] = show_results_filter_set(qr) + context["show_results"] = show_results_filter_set(qr) return context def post(self, request, *args, **kwargs): username = request.user.username - marcadas = request.POST.getlist('materia_id') + marcadas = request.POST.getlist("materia_id") if len(marcadas) == 0: - msg = _('Nenhuma máteria foi selecionada.') + msg = _("Nenhuma máteria foi selecionada.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) - tipo = TipoDocumento.objects.get(descricao=request.POST['tipo']) + tipo = TipoDocumento.objects.get(descricao=request.POST["tipo"]) tz = timezone.get_current_timezone() - if len(request.POST['autor']) > 50: - msg = _('Autor tem que ter menos do que 50 caracteres.') + if len(request.POST["autor"]) > 50: + msg = _("Autor tem que ter menos do que 50 caracteres.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) - if request.FILES['arquivo'].size > MAX_DOC_UPLOAD_SIZE: - msg = _("O arquivo Anexo de Texto Integral deve ser menor que {0:.1f} MB, \ - o tamanho atual desse arquivo é {1:.1f} MB" - .format((MAX_DOC_UPLOAD_SIZE / 1024) / 1024, (request.FILES['arquivo'].size / 1024) / 1024)) + if request.FILES["arquivo"].size > MAX_DOC_UPLOAD_SIZE: + msg = _( + "O arquivo Anexo de Texto Integral deve ser menor que {0:.1f} MB, \ + o tamanho atual desse arquivo é {1:.1f} MB".format( + (MAX_DOC_UPLOAD_SIZE / 1024) / 1024, + (request.FILES["arquivo"].size / 1024) / 1024, + ) + ) messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) - tmp_name = os.path.join(MEDIA_ROOT, request.FILES['arquivo'].name) - with open(tmp_name, 'wb') as destination: - for chunk in request.FILES['arquivo'].chunks(): + tmp_name = os.path.join(MEDIA_ROOT, request.FILES["arquivo"].name) + with open(tmp_name, "wb") as destination: + for chunk in request.FILES["arquivo"].chunks(): destination.write(chunk) try: - dt = datetime.strptime(request.POST['data'], "%d/%m/%Y") + dt = datetime.strptime(request.POST["data"], "%d/%m/%Y") if timezone.is_naive(dt): dt = timezone.make_aware(dt, timezone.get_current_timezone()) return dt except Exception as e: msg = _( - 'Formato da data incorreto. O formato deve ser da forma dd/mm/aaaa.') + "Formato da data incorreto. O formato deve ser da forma dd/mm/aaaa." + ) messages.add_message(request, messages.ERROR, msg) - self.logger.error("User={}. {}. Data inserida: {}".format( - username, str(msg), request.POST['data'])) + self.logger.error( + "User={}. {}. Data inserida: {}".format( + username, str(msg), request.POST["data"] + ) + ) os.remove(tmp_name) return self.get(request, self.kwargs) @@ -2372,90 +2672,105 @@ class DocumentoAcessorioEmLoteView(PermissionRequiredMixin, FilterView): doc = DocumentoAcessorio() doc.materia_id = materia_id doc.tipo = tipo - doc.nome = request.POST['nome'] + doc.nome = request.POST["nome"] doc.data = doc_data - doc.autor = request.POST['autor'] - doc.ementa = request.POST['ementa'] + doc.autor = request.POST["autor"] + doc.ementa = request.POST["ementa"] doc.arquivo.name = tmp_name try: doc.clean_fields() except ValidationError as e: - for m in ['%s: %s' % (DocumentoAcessorio()._meta.get_field(k).verbose_name, '
        '.join(v)) - for k, v in e.message_dict.items()]: + for m in [ + "%s: %s" + % ( + DocumentoAcessorio()._meta.get_field(k).verbose_name, + "
        ".join(v), + ) + for k, v in e.message_dict.items() + ]: # Insere as mensagens de erro no formato: # 'verbose_name do nome do campo': 'mensagem de erro' messages.add_message(request, messages.ERROR, m) - self.logger.error("User={}. {}. Nome do arquivo: {}.".format( - username, str(msg), request.FILES['arquivo'].name)) + self.logger.error( + "User={}. {}. Nome do arquivo: {}.".format( + username, str(msg), request.FILES["arquivo"].name + ) + ) os.remove(tmp_name) return self.get(request, self.kwargs) doc.save() - diretorio = os.path.join(MEDIA_ROOT, - 'sapl/public/documentoacessorio', - str(doc_data.year), - str(doc.id)) + diretorio = os.path.join( + MEDIA_ROOT, + "sapl/public/documentoacessorio", + str(doc_data.year), + str(doc.id), + ) if not os.path.exists(diretorio): os.makedirs(diretorio) - file_path = os.path.join(diretorio, - request.FILES['arquivo'].name) + file_path = os.path.join(diretorio, request.FILES["arquivo"].name) shutil.copy2(tmp_name, file_path) - doc.arquivo.name = file_path.split( - MEDIA_ROOT + "/")[1] # Retira MEDIA_ROOT do nome + doc.arquivo.name = file_path.split(MEDIA_ROOT + "/")[ + 1 + ] # Retira MEDIA_ROOT do nome doc.save() os.remove(tmp_name) - msg = _('Documento(s) criado(s).') + msg = _("Documento(s) criado(s).") messages.add_message(request, messages.SUCCESS, msg) return self.get(request, self.kwargs) class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView): filterset_class = AnexadaEmLoteFilterSet - template_name = 'materia/em_lote/anexada.html' - permission_required = ('materia.add_documentoacessorio',) + template_name = "materia/em_lote/anexada.html" + permission_required = ("materia.add_documentoacessorio",) def get_context_data(self, **kwargs): - context = super(MateriaAnexadaEmLoteView, - self).get_context_data(**kwargs) + context = super(MateriaAnexadaEmLoteView, self).get_context_data(**kwargs) - context['root_pk'] = self.kwargs['pk'] + context["root_pk"] = self.kwargs["pk"] - context['subnav_template_name'] = 'materia/subnav.yaml' + context["subnav_template_name"] = "materia/subnav.yaml" - context['title'] = _('Matérias Anexadas em Lote') + context["title"] = _("Matérias Anexadas em Lote") # Verifica se os campos foram preenchidos - if not self.request.GET.get('tipo', " "): - msg = _('Por favor, selecione um tipo de matéria.') + if not self.request.GET.get("tipo", " "): + msg = _("Por favor, selecione um tipo de matéria.") messages.add_message(self.request, messages.ERROR, msg) - if not self.request.GET.get('data_apresentacao_0', " ") or not self.request.GET.get('data_apresentacao_1', " "): - msg = _('Por favor, preencha as datas.') + if not self.request.GET.get( + "data_apresentacao_0", " " + ) or not self.request.GET.get("data_apresentacao_1", " "): + msg = _("Por favor, preencha as datas.") messages.add_message(self.request, messages.ERROR, msg) return context - if not self.request.GET.get('data_apresentacao_0', " ") or not self.request.GET.get('data_apresentacao_1', " "): - msg = _('Por favor, preencha as datas.') + if not self.request.GET.get( + "data_apresentacao_0", " " + ) or not self.request.GET.get("data_apresentacao_1", " "): + msg = _("Por favor, preencha as datas.") messages.add_message(self.request, messages.ERROR, msg) return context qr = self.request.GET.copy() if not len(qr): - context['object_list'] = [] + context["object_list"] = [] else: - context['object_list'] = context['object_list'].order_by( - 'numero', '-ano') - principal = MateriaLegislativa.objects.get(pk=self.kwargs['pk']) - not_list = [self.kwargs['pk']] + \ - [m for m in principal.materia_principal_set.all( - ).values_list('materia_anexada_id', flat=True)] - context['object_list'] = context['object_list'].exclude( - pk__in=not_list) - - context['temp_object_list'] = context['object_list'] - context['object_list'] = [] - for obj in context['temp_object_list']: + context["object_list"] = context["object_list"].order_by("numero", "-ano") + principal = MateriaLegislativa.objects.get(pk=self.kwargs["pk"]) + not_list = [self.kwargs["pk"]] + [ + m + for m in principal.materia_principal_set.all().values_list( + "materia_anexada_id", flat=True + ) + ] + context["object_list"] = context["object_list"].exclude(pk__in=not_list) + + context["temp_object_list"] = context["object_list"] + context["object_list"] = [] + for obj in context["temp_object_list"]: materia_anexada = obj ciclico = False anexadas_anexada = Anexada.objects.filter( @@ -2466,58 +2781,60 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView): anexadas = [] for anexa in anexadas_anexada: - if principal == anexa.materia_anexada: ciclico = True else: - for a in Anexada.objects.filter(materia_principal=anexa.materia_anexada): + for a in Anexada.objects.filter( + materia_principal=anexa.materia_anexada + ): anexadas.append(a) anexadas_anexada = anexadas if not ciclico: - context['object_list'].append(obj) + context["object_list"].append(obj) - context['numero_res'] = len(context['object_list']) + context["numero_res"] = len(context["object_list"]) - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" - context['show_results'] = show_results_filter_set(qr) + context["show_results"] = show_results_filter_set(qr) return context def post(self, request, *args, **kwargs): - marcadas = request.POST.getlist('materia_id') + marcadas = request.POST.getlist("materia_id") data_anexacao = datetime.strptime( - request.POST['data_anexacao'], "%d/%m/%Y").date() + request.POST["data_anexacao"], "%d/%m/%Y" + ).date() - if request.POST['data_desanexacao'] == '': + if request.POST["data_desanexacao"] == "": data_desanexacao = None v_data_desanexacao = data_anexacao else: data_desanexacao = datetime.strptime( - request.POST['data_desanexacao'], "%d/%m/%Y").date() + request.POST["data_desanexacao"], "%d/%m/%Y" + ).date() v_data_desanexacao = data_desanexacao if len(marcadas) == 0: - msg = _('Nenhuma máteria foi selecionada.') + msg = _("Nenhuma máteria foi selecionada.") messages.add_message(request, messages.ERROR, msg) if data_anexacao > v_data_desanexacao: - msg = _('Data de anexação posterior à data de desanexação.') + msg = _("Data de anexação posterior à data de desanexação.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) if data_anexacao > v_data_desanexacao: - msg = _('Data de anexação posterior à data de desanexação.') + msg = _("Data de anexação posterior à data de desanexação.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) - principal = MateriaLegislativa.objects.get(pk=kwargs['pk']) + principal = MateriaLegislativa.objects.get(pk=kwargs["pk"]) for materia in MateriaLegislativa.objects.filter(id__in=marcadas): - anexada = Anexada() anexada.materia_principal = principal anexada.materia_anexada = materia @@ -2525,54 +2842,58 @@ class MateriaAnexadaEmLoteView(PermissionRequiredMixin, FilterView): anexada.data_desanexacao = data_desanexacao anexada.save() - msg = _('Matéria(s) anexada(s).') + msg = _("Matéria(s) anexada(s).") messages.add_message(request, messages.SUCCESS, msg) - success_url = reverse('sapl.materia:anexada_list', - kwargs={'pk': kwargs['pk']}) + success_url = reverse("sapl.materia:anexada_list", kwargs={"pk": kwargs["pk"]}) return HttpResponseRedirect(success_url) class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): filterset_class = PrimeiraTramitacaoEmLoteFilterSet - template_name = 'materia/em_lote/tramitacao.html' - permission_required = ('materia.add_tramitacao', ) + template_name = "materia/em_lote/tramitacao.html" + permission_required = ("materia.add_tramitacao",) primeira_tramitacao = True logger = logging.getLogger(__name__) def get_context_data(self, **kwargs): - context = super(PrimeiraTramitacaoEmLoteView, - self).get_context_data(**kwargs) + context = super(PrimeiraTramitacaoEmLoteView, self).get_context_data(**kwargs) - context['subnav_template_name'] = 'materia/em_lote/subnav_em_lote.yaml' - context['primeira_tramitacao'] = self.primeira_tramitacao + context["subnav_template_name"] = "materia/em_lote/subnav_em_lote.yaml" + context["primeira_tramitacao"] = self.primeira_tramitacao # Verifica se os campos foram preenchidos if not self.filterset.form.is_valid(): return context - context['object_list'] = context['object_list'].order_by( - 'ano', 'numero') + context["object_list"] = context["object_list"].order_by("ano", "numero") qr = self.request.GET.copy() form = TramitacaoEmLoteForm() - context['form'] = form + context["form"] = form if self.primeira_tramitacao: - context['title'] = _('Primeira Tramitação em Lote') + context["title"] = _("Primeira Tramitação em Lote") # Pega somente documentos que não possuem tramitação - context['object_list'] = [obj for obj in context['object_list'] - if obj.tramitacao_set.order_by('-data_tramitacao', '-id').all().count() == 0] + context["object_list"] = [ + obj + for obj in context["object_list"] + if obj.tramitacao_set.order_by("-data_tramitacao", "-id").all().count() + == 0 + ] else: - context['title'] = _('Tramitação em Lote') - context['form'].fields['unidade_tramitacao_local'].initial = UnidadeTramitacao.objects.get( - id=qr['tramitacao__unidade_tramitacao_destino']) + context["title"] = _("Tramitação em Lote") + context["form"].fields[ + "unidade_tramitacao_local" + ].initial = UnidadeTramitacao.objects.get( + id=qr["tramitacao__unidade_tramitacao_destino"] + ) - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" - context['show_results'] = show_results_filter_set(qr) + context["show_results"] = show_results_filter_set(qr) return context @@ -2581,42 +2902,50 @@ class PrimeiraTramitacaoEmLoteView(PermissionRequiredMixin, FilterView): ip = get_client_ip(request) from django.utils import timezone + ultima_edicao = timezone.now() - materias_ids = request.POST.getlist('materias') + materias_ids = request.POST.getlist("materias") if not materias_ids: msg = _("Escolha alguma matéria para ser tramitada.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) - form = TramitacaoEmLoteForm(request.POST, - initial={'materias': materias_ids, - 'user': user, 'ip': ip, - 'ultima_edicao': ultima_edicao}) + form = TramitacaoEmLoteForm( + request.POST, + initial={ + "materias": materias_ids, + "user": user, + "ip": ip, + "ultima_edicao": ultima_edicao, + }, + ) if form.is_valid(): form.save() - msg = _('Tramitação completa.') - self.logger.info('user=' + user.username + - '. Tramitação completa.') + msg = _("Tramitação completa.") + self.logger.info("user=" + user.username + ". Tramitação completa.") messages.add_message(request, messages.SUCCESS, msg) return self.get_success_url() return self.form_invalid(form) def get_success_url(self): - return HttpResponseRedirect(reverse('sapl.materia:primeira_tramitacao_em_lote')) + return HttpResponseRedirect(reverse("sapl.materia:primeira_tramitacao_em_lote")) def form_invalid(self, form, *args, **kwargs): for key, erros in form.errors.items(): - if not key == '__all__': - [messages.add_message( - self.request, messages.ERROR, form.fields[key].label + ": " + e) for e in erros] + if not key == "__all__": + [ + messages.add_message( + self.request, messages.ERROR, form.fields[key].label + ": " + e + ) + for e in erros + ] else: - [messages.add_message(self.request, messages.ERROR, e) - for e in erros] - return self.get(self.request, kwargs, {'form': form}) + [messages.add_message(self.request, messages.ERROR, e) for e in erros] + return self.get(self.request, kwargs, {"form": form}) class TramitacaoEmLoteView(PrimeiraTramitacaoEmLoteView): @@ -2625,98 +2954,104 @@ class TramitacaoEmLoteView(PrimeiraTramitacaoEmLoteView): primeira_tramitacao = False def get_context_data(self, **kwargs): - context = super(TramitacaoEmLoteView, - self).get_context_data(**kwargs) + context = super(TramitacaoEmLoteView, self).get_context_data(**kwargs) qr = self.request.GET.copy() - context['primeira_tramitacao'] = self.primeira_tramitacao + context["primeira_tramitacao"] = self.primeira_tramitacao - if ('tramitacao__status' in qr and - 'tramitacao__unidade_tramitacao_destino' in qr and - qr['tramitacao__status'] and - qr['tramitacao__unidade_tramitacao_destino']): + if ( + "tramitacao__status" in qr + and "tramitacao__unidade_tramitacao_destino" in qr + and qr["tramitacao__status"] + and qr["tramitacao__unidade_tramitacao_destino"] + ): lista = filtra_tramitacao_destino_and_status( - qr['tramitacao__status'], - qr['tramitacao__unidade_tramitacao_destino']) - context['object_list'] = context['object_list'].filter( - id__in=lista).distinct() + qr["tramitacao__status"], qr["tramitacao__unidade_tramitacao_destino"] + ) + context["object_list"] = ( + context["object_list"].filter(id__in=lista).distinct() + ) return context class ImpressosView(PermissionRequiredMixin, TemplateView): - template_name = 'materia/impressos/impressos.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos.html" + permission_required = ("materia.can_access_impressos",) def gerar_pdf_impressos(request, context, template_name): template = loader.get_template(template_name) html = template.render(context, request) pdf = weasyprint.HTML( - string=html, base_url=request.build_absolute_uri()).write_pdf() + string=html, base_url=request.build_absolute_uri() + ).write_pdf() - response = HttpResponse(pdf, content_type='application/pdf') - response['Content-Disposition'] = 'inline; filename="relatorio_impressos.pdf"' - response['Content-Transfer-Encoding'] = 'binary' + response = HttpResponse(pdf, content_type="application/pdf") + response["Content-Disposition"] = 'inline; filename="relatorio_impressos.pdf"' + response["Content-Transfer-Encoding"] = "binary" return response class EtiquetaPesquisaView(PermissionRequiredMixin, FormView): form_class = EtiquetaPesquisaForm - template_name = 'materia/impressos/impressos_form.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos_form.html" + permission_required = ("materia.can_access_impressos",) def form_valid(self, form): context = {} - materias = MateriaLegislativa.objects.all().order_by( - '-data_apresentacao') + materias = MateriaLegislativa.objects.all().order_by("-data_apresentacao") - if form.cleaned_data['tipo_materia']: - materias = materias.filter(tipo=form.cleaned_data['tipo_materia']) + if form.cleaned_data["tipo_materia"]: + materias = materias.filter(tipo=form.cleaned_data["tipo_materia"]) - if form.cleaned_data['data_inicial']: + if form.cleaned_data["data_inicial"]: materias = materias.filter( - data_apresentacao__gte=form.cleaned_data['data_inicial'], - data_apresentacao__lte=form.cleaned_data['data_final']) + data_apresentacao__gte=form.cleaned_data["data_inicial"], + data_apresentacao__lte=form.cleaned_data["data_final"], + ) - if form.cleaned_data['processo_inicial']: + if form.cleaned_data["processo_inicial"]: materias = materias.filter( - numero__gte=form.cleaned_data[ - 'processo_inicial'], - numero__lte=form.cleaned_data[ - 'processo_final']) + numero__gte=form.cleaned_data["processo_inicial"], + numero__lte=form.cleaned_data["processo_final"], + ) - context['quantidade'] = len(materias) + context["quantidade"] = len(materias) - if context['quantidade'] > 20: + if context["quantidade"] > 20: materias = materias[:20] for m in materias: if len(m.ementa) > 100: m.ementa = m.ementa[0:99] + "[...]" - context['materias'] = materias + context["materias"] = materias - return gerar_pdf_impressos(self.request, context, - 'materia/impressos/etiqueta_pdf.html') + return gerar_pdf_impressos( + self.request, context, "materia/impressos/etiqueta_pdf.html" + ) class FichaPesquisaView(PermissionRequiredMixin, FormView): form_class = FichaPesquisaForm - template_name = 'materia/impressos/impressos_form.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos_form.html" + permission_required = ("materia.can_access_impressos",) def form_valid(self, form): - tipo_materia = form.data['tipo_materia'] - data_inicial = form.data['data_inicial'] - data_final = form.data['data_final'] - - url = reverse('sapl.materia:impressos_ficha_seleciona') - url = url + '?tipo=%s&data_inicial=%s&data_final=%s' % ( - tipo_materia, data_inicial, data_final) + tipo_materia = form.data["tipo_materia"] + data_inicial = form.data["data_inicial"] + data_final = form.data["data_final"] + + url = reverse("sapl.materia:impressos_ficha_seleciona") + url = url + "?tipo=%s&data_inicial=%s&data_final=%s" % ( + tipo_materia, + data_inicial, + data_final, + ) return HttpResponseRedirect(url) @@ -2724,49 +3059,63 @@ class FichaPesquisaView(PermissionRequiredMixin, FormView): class FichaSelecionaView(PermissionRequiredMixin, FormView): logger = logging.getLogger(__name__) form_class = FichaSelecionaForm - template_name = 'materia/impressos/impressos_form.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos_form.html" + permission_required = ("materia.can_access_impressos",) def get_context_data(self, **kwargs): - if ('tipo' not in self.request.GET or - 'data_inicial' not in self.request.GET or - 'data_final' not in self.request.GET): - return HttpResponseRedirect(reverse( - 'sapl.materia:impressos_ficha_pesquisa')) + if ( + "tipo" not in self.request.GET + or "data_inicial" not in self.request.GET + or "data_final" not in self.request.GET + ): + return HttpResponseRedirect( + reverse("sapl.materia:impressos_ficha_pesquisa") + ) - context = super(FichaSelecionaView, self).get_context_data( - **kwargs) + context = super(FichaSelecionaView, self).get_context_data(**kwargs) - tipo = self.request.GET['tipo'] + tipo = self.request.GET["tipo"] data_inicial = datetime.strptime( - self.request.GET['data_inicial'], "%d/%m/%Y").date() + self.request.GET["data_inicial"], "%d/%m/%Y" + ).date() data_final = datetime.strptime( - self.request.GET['data_final'], "%d/%m/%Y").date() + self.request.GET["data_final"], "%d/%m/%Y" + ).date() materia_list = MateriaLegislativa.objects.filter( - tipo=tipo, - data_apresentacao__range=(data_inicial, data_final)) - context['quantidade'] = len(materia_list) + tipo=tipo, data_apresentacao__range=(data_inicial, data_final) + ) + context["quantidade"] = len(materia_list) materia_list = materia_list[:100] - context['form'].fields['materia'].choices = [ - (m.id, str(m)) for m in materia_list] + context["form"].fields["materia"].choices = [ + (m.id, str(m)) for m in materia_list + ] username = self.request.user.username - if context['quantidade'] > 100: - self.logger.info('user=' + username + '. Sua pesquisa (tipo={}, data_inicial={}, data_final={}) retornou mais do que ' - '100 impressos. Por questões de ' - 'performance, foram retornados ' - 'apenas os 100 primeiros. Caso ' - 'queira outros, tente fazer uma ' - 'pesquisa mais específica'.format(tipo, data_inicial, data_final)) - messages.info(self.request, _('Sua pesquisa retornou mais do que ' - '100 impressos. Por questões de ' - 'performance, foram retornados ' - 'apenas os 100 primeiros. Caso ' - 'queira outros, tente fazer uma ' - 'pesquisa mais específica')) + if context["quantidade"] > 100: + self.logger.info( + "user=" + + username + + ". Sua pesquisa (tipo={}, data_inicial={}, data_final={}) retornou mais do que " + "100 impressos. Por questões de " + "performance, foram retornados " + "apenas os 100 primeiros. Caso " + "queira outros, tente fazer uma " + "pesquisa mais específica".format(tipo, data_inicial, data_final) + ) + messages.info( + self.request, + _( + "Sua pesquisa retornou mais do que " + "100 impressos. Por questões de " + "performance, foram retornados " + "apenas os 100 primeiros. Caso " + "queira outros, tente fazer uma " + "pesquisa mais específica" + ), + ) return context @@ -2776,48 +3125,59 @@ class FichaSelecionaView(PermissionRequiredMixin, FormView): try: self.logger.debug( - "user=" + username + ". Tentando obter objeto MateriaLegislativa com id={}".format(form.data['materia'])) - materia = MateriaLegislativa.objects.get( - id=form.data['materia']) + "user=" + + username + + ". Tentando obter objeto MateriaLegislativa com id={}".format( + form.data["materia"] + ) + ) + materia = MateriaLegislativa.objects.get(id=form.data["materia"]) except ObjectDoesNotExist: self.logger.error( - "user=" + username + ". Esta MáteriaLegislativa não existe (id={}).".format(form.data['materia'])) - mensagem = _('Esta Máteria não existe!') + "user=" + + username + + ". Esta MáteriaLegislativa não existe (id={}).".format( + form.data["materia"] + ) + ) + mensagem = _("Esta Máteria não existe!") self.messages.add_message(self.request, messages.INFO, mensagem) return self.render_to_response(context) if len(materia.ementa) > 301: - materia.ementa = materia.ementa[0:300] + '[...]' - context['materia'] = materia - context['despachos'] = materia.despachoinicial_set.all().values_list( - 'comissao__nome', flat=True) + materia.ementa = materia.ementa[0:300] + "[...]" + context["materia"] = materia + context["despachos"] = materia.despachoinicial_set.all().values_list( + "comissao__nome", flat=True + ) - return gerar_pdf_impressos(self.request, context, - 'materia/impressos/ficha_pdf.html') + return gerar_pdf_impressos( + self.request, context, "materia/impressos/ficha_pdf.html" + ) class ExcluirTramitacaoEmLoteView(PermissionRequiredMixin, FormView): - - template_name = 'materia/em_lote/excluir_tramitacao.html' - permission_required = ('materia.add_tramitacao',) + template_name = "materia/em_lote/excluir_tramitacao.html" + permission_required = ("materia.add_tramitacao",) form_class = ExcluirTramitacaoEmLote - form_valid_message = _('Tramitações excluídas com sucesso!') + form_valid_message = _("Tramitações excluídas com sucesso!") def get_success_url(self): - return reverse('sapl.materia:excluir_tramitacao_em_lote') + return reverse("sapl.materia:excluir_tramitacao_em_lote") def form_valid(self, form): - tramitacao_set = Tramitacao.objects.filter( - data_tramitacao=form.cleaned_data['data_tramitacao'], - unidade_tramitacao_local=form.cleaned_data[ - 'unidade_tramitacao_local'], - unidade_tramitacao_destino=form.cleaned_data[ - 'unidade_tramitacao_destino'], - status=form.cleaned_data['status']) + data_tramitacao=form.cleaned_data["data_tramitacao"], + unidade_tramitacao_local=form.cleaned_data["unidade_tramitacao_local"], + unidade_tramitacao_destino=form.cleaned_data["unidade_tramitacao_destino"], + status=form.cleaned_data["status"], + ) for tramitacao in tramitacao_set: materia = tramitacao.materia - if tramitacao == materia.tramitacao_set.order_by('-data_tramitacao', '-id').first(): + if ( + tramitacao + == materia.tramitacao_set.order_by("-data_tramitacao", "-id").first() + ): tramitacao.delete() return redirect(self.get_success_url()) @@ -2825,29 +3185,36 @@ class ExcluirTramitacaoEmLoteView(PermissionRequiredMixin, FormView): class MateriaPesquisaSimplesView(PermissionRequiredMixin, FormView): form_class = MateriaPesquisaSimplesForm - template_name = 'materia/impressos/impressos_form.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos_form.html" + permission_required = ("materia.can_access_impressos",) def form_valid(self, form): - template_materia = 'materia/impressos/materias_pdf.html' + template_materia = "materia/impressos/materias_pdf.html" kwargs = {} - if form.cleaned_data.get('tipo_materia'): - kwargs.update({'tipo': form.cleaned_data['tipo_materia']}) - - if form.cleaned_data.get('data_inicial'): - kwargs.update({'data_apresentacao__gte': form.cleaned_data['data_inicial'], - 'data_apresentacao__lte': form.cleaned_data['data_final']}) + if form.cleaned_data.get("tipo_materia"): + kwargs.update({"tipo": form.cleaned_data["tipo_materia"]}) + + if form.cleaned_data.get("data_inicial"): + kwargs.update( + { + "data_apresentacao__gte": form.cleaned_data["data_inicial"], + "data_apresentacao__lte": form.cleaned_data["data_final"], + } + ) - materias = MateriaLegislativa.objects.filter( - **kwargs).order_by('-numero', 'ano') + materias = MateriaLegislativa.objects.filter(**kwargs).order_by( + "-numero", "ano" + ) quantidade_materias = materias.count() materias = materias[:2000] if quantidade_materias > 2000 else materias - context = {'quantidade': quantidade_materias, - 'titulo': form.cleaned_data['titulo'], - 'materias': materias} + context = { + "quantidade": quantidade_materias, + "titulo": form.cleaned_data["titulo"], + "materias": materias, + } return gerar_pdf_impressos(self.request, context, template_materia) @@ -2856,7 +3223,7 @@ class TipoMateriaCrud(CrudAux): model = TipoMateriaLegislativa class DetailView(CrudAux.DetailView): - layout_key = 'TipoMateriaLegislativaDetail' + layout_key = "TipoMateriaLegislativaDetail" class DeleteView(CrudAux.DeleteView): def delete(self, request, *args, **kwargs): @@ -2866,31 +3233,32 @@ class TipoMateriaCrud(CrudAux): class ListView(CrudAux.ListView): paginate_by = None - layout_key = 'TipoMateriaLegislativaDetail' + layout_key = "TipoMateriaLegislativaDetail" template_name = "materia/tipomaterialegislativa_list.html" def hook_sigla(self, obj, default, url): - return '{}'.format( - url, obj.id, obj.sigla), '' + return '{}'.format(url, obj.id, obj.sigla), "" def get(self, request, *args, **kwargs): - if TipoMateriaLegislativa.objects.filter( - sequencia_regimental=0).exists(): + if TipoMateriaLegislativa.objects.filter(sequencia_regimental=0).exists(): TipoMateriaLegislativa.objects.reordene() return CrudAux.ListView.get(self, request, *args, **kwargs) class CreateView(CrudAux.CreateView): - def form_valid(self, form): fv = super().form_valid(form) if not TipoMateriaLegislativa.objects.exclude( - sequencia_regimental=0).exists(): + sequencia_regimental=0 + ).exists(): TipoMateriaLegislativa.objects.reordene() else: sr__max = TipoMateriaLegislativa.objects.all().aggregate( - Max('sequencia_regimental')) - self.object.sequencia_regimental = sr__max['sequencia_regimental__max'] + 1 + Max("sequencia_regimental") + ) + self.object.sequencia_regimental = ( + sr__max["sequencia_regimental__max"] + 1 + ) self.object.save() return fv @@ -2898,11 +3266,10 @@ class TipoMateriaCrud(CrudAux): def create_zip_docacessorios(materia): """ - Creates in memory zip files + Creates in memory zip files """ logger = logging.getLogger(__name__) - docs = materia.documentoacessorio_set. \ - all().values_list('arquivo', flat=True) + docs = materia.documentoacessorio_set.all().values_list("arquivo", flat=True) if not docs: return None, None @@ -2910,83 +3277,93 @@ def create_zip_docacessorios(materia): if not docs_path: raise FileNotFoundError( - "Não há arquivos PDF cadastrados em documentos acessorios.") + "Não há arquivos PDF cadastrados em documentos acessorios." + ) logger.info( - "Gerando compilado PDF de documentos acessorios com {} documentos".format(docs_path)) + "Gerando compilado PDF de documentos acessorios com {} documentos".format( + docs_path + ) + ) _zipfile = BytesIO() try: - with zipfile.ZipFile(_zipfile, 'w', zipfile.ZIP_DEFLATED) as zipf: + with zipfile.ZipFile(_zipfile, "w", zipfile.ZIP_DEFLATED) as zipf: for f in docs_path: zipf.write(f, f.split(os.sep)[-1]) except Exception as e: logger.error(e) raise e - external_name = "mat_{}_{}_docacessorios.zip".format( - materia.numero, materia.ano) + external_name = "mat_{}_{}_docacessorios.zip".format(materia.numero, materia.ano) return external_name, _zipfile.getvalue() def get_zip_docacessorios(request, pk): logger = logging.getLogger(__name__) - username = 'Usuário anônimo' if request.user.is_anonymous else 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) data = None try: external_name, data = create_zip_docacessorios(materia) logger.info( - "user= {}. Gerou o zip compilado de documento acessorios".format(username)) + "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.') + msg = _("Não há arquivos cadastrados nesses documentos acessórios.") messages.add_message(request, messages.ERROR, msg) - return redirect(reverse('sapl.materia:documentoacessorio_list', - kwargs={'pk': pk})) + return redirect( + reverse("sapl.materia:documentoacessorio_list", kwargs={"pk": pk}) + ) except Exception as e: - logger.error("user={}. Um erro inesperado ocorreu na criação do pdf de documentos acessorios: {}" - .format(username, str(e))) - msg = _('Um erro inesperado ocorreu. Entre em contato com o suporte do SAPL.') + logger.error( + "user={}. Um erro inesperado ocorreu na criação do pdf de documentos acessorios: {}".format( + username, str(e) + ) + ) + msg = _("Um erro inesperado ocorreu. Entre em contato com o suporte do SAPL.") messages.add_message(request, messages.ERROR, msg) - return redirect(reverse('sapl.materia:documentoacessorio_list', - kwargs={'pk': pk})) + return redirect( + reverse("sapl.materia:documentoacessorio_list", kwargs={"pk": pk}) + ) if not data: - msg = _('Não há nenhum documento acessório cadastrado.') + msg = _("Não há nenhum documento acessório cadastrado.") messages.add_message(request, messages.ERROR, msg) - return redirect(reverse('sapl.materia:documentoacessorio_list', - kwargs={'pk': pk})) + return redirect( + reverse("sapl.materia:documentoacessorio_list", kwargs={"pk": pk}) + ) - response = HttpResponse(data, content_type='application/zip') - response['Content-Disposition'] = ('attachment; filename="%s"' - % external_name) + response = HttpResponse(data, content_type="application/zip") + response["Content-Disposition"] = 'attachment; filename="%s"' % external_name return response def create_pdf_docacessorios(materia): """ - Creates a unified in memory PDF file + Creates a unified in memory PDF file """ logger = logging.getLogger(__name__) - docs = materia.documentoacessorio_set. \ - all().values_list('arquivo', flat=True) + docs = materia.documentoacessorio_set.all().values_list("arquivo", flat=True) if not docs: return None, None # TODO: o for-comprehension abaixo filtra os arquivos não PDF. # TODO: o que fazer com os arquivos não PDF? converter? ignorar? - docs_path = [os.path.join(MEDIA_ROOT, i) - for i in docs if i.lower().endswith('pdf')] + docs_path = [os.path.join(MEDIA_ROOT, i) for i in docs if i.lower().endswith("pdf")] if not docs_path: raise FileNotFoundError( - "Não há arquivos PDF cadastrados em documentos acessorios.") - logger.info("Gerando compilado PDF de documentos acessorios com {} documentos" - .format(docs_path)) - merged_pdf = '{}/mat_{}_{}_docacessorios.pdf'.format( - get_tempfile_dir(), - materia.pk, - time.mktime(datetime.now().timetuple())) + "Não há arquivos PDF cadastrados em documentos acessorios." + ) + logger.info( + "Gerando compilado PDF de documentos acessorios com {} documentos".format( + docs_path + ) + ) + merged_pdf = "{}/mat_{}_{}_docacessorios.pdf".format( + get_tempfile_dir(), materia.pk, time.mktime(datetime.now().timetuple()) + ) merger = PdfFileMerger(strict=False) for f in docs_path: @@ -2996,55 +3373,59 @@ def create_pdf_docacessorios(materia): merger.write(data) merger.close() - external_name = "mat_{}_{}_docacessorios.pdf".format( - materia.numero, materia.ano) + external_name = "mat_{}_{}_docacessorios.pdf".format(materia.numero, materia.ano) return external_name, data.getvalue() def get_pdf_docacessorios(request, pk): materia = get_object_or_404(MateriaLegislativa, pk=pk) logger = logging.getLogger(__name__) - username = 'Usuário anônimo' if request.user.is_anonymous else request.user.username + username = "Usuário anônimo" if request.user.is_anonymous else request.user.username try: external_name, data = create_pdf_docacessorios(materia) logger.info( - "user= {}. Gerou o pdf compilado de documento acessorios".format(username)) + "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.') + msg = _("Não há arquivos cadastrados nesses documentos acessórios.") messages.add_message(request, messages.ERROR, msg) - return redirect(reverse('sapl.materia:documentoacessorio_list', - kwargs={'pk': pk})) + return redirect( + reverse("sapl.materia:documentoacessorio_list", kwargs={"pk": pk}) + ) except Exception as e: - logger.error("user= {}.Um erro inesperado ocorreu na criação do pdf de documentos acessorios: {}" - .format(username, str(e))) - msg = _('Um erro inesperado ocorreu. Entre em contato com o suporte do SAPL.') + logger.error( + "user= {}.Um erro inesperado ocorreu na criação do pdf de documentos acessorios: {}".format( + username, str(e) + ) + ) + msg = _("Um erro inesperado ocorreu. Entre em contato com o suporte do SAPL.") messages.add_message(request, messages.ERROR, msg) - return redirect(reverse('sapl.materia:documentoacessorio_list', - kwargs={'pk': pk})) + return redirect( + reverse("sapl.materia:documentoacessorio_list", kwargs={"pk": pk}) + ) if not data: - msg = _('Não há nenhum documento acessório PDF cadastrado.') + msg = _("Não há nenhum documento acessório PDF cadastrado.") messages.add_message(request, messages.ERROR, msg) - return redirect(reverse('sapl.materia:documentoacessorio_list', - kwargs={'pk': pk})) + return redirect( + reverse("sapl.materia:documentoacessorio_list", kwargs={"pk": pk}) + ) - response = HttpResponse(data, content_type='application/pdf') - response['Content-Disposition'] = ('attachment; filename="%s"' - % external_name) + response = HttpResponse(data, content_type="application/pdf") + response["Content-Disposition"] = 'attachment; filename="%s"' % external_name return response def configEtiquetaMateriaLegislativaCrud(request): config = ConfigEtiquetaMateriaLegislativa.objects.last() if request.method == "POST": - form = ConfigEtiquetaMateriaLegislativaForms( - request.POST, instance=config) + 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}) + return redirect("materia/config_etiqueta_materia.html", {"form": form}) else: form = ConfigEtiquetaMateriaLegislativaForms(instance=config) - return render(request, 'materia/config_etiqueta_materia.html', {'form': form}) + return render(request, "materia/config_etiqueta_materia.html", {"form": form}) diff --git a/sapl/middleware.py b/sapl/middleware.py index 7a8d4ff65..bb62d73fe 100644 --- a/sapl/middleware.py +++ b/sapl/middleware.py @@ -11,11 +11,13 @@ class CheckWeakPasswordMiddleware: self.get_response = get_response def __call__(self, request): - if request.user.is_authenticated and \ - request.session.get('weak_password', False) and \ - request.path != reverse('sapl.base:alterar_senha') and \ - request.path != reverse('sapl.base:logout'): + if ( + request.user.is_authenticated + and request.session.get("weak_password", False) + and request.path != reverse("sapl.base:alterar_senha") + and request.path != reverse("sapl.base:logout") + ): logging.warning(f"Usuário {request.user.username} possui senha fraca.") - return redirect('sapl.base:alterar_senha') + return redirect("sapl.base:alterar_senha") return self.get_response(request) diff --git a/sapl/norma/apps.py b/sapl/norma/apps.py index 593a172fa..f89a9a6bd 100644 --- a/sapl/norma/apps.py +++ b/sapl/norma/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.norma' - label = 'norma' - verbose_name = _('Norma Jurídica') + name = "sapl.norma" + label = "norma" + verbose_name = _("Norma Jurídica") diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index c958beb58..e336f8cfe 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -1,54 +1,54 @@ import logging import re -from crispy_forms.layout import (Button, Fieldset, HTML, Layout) +import django_filters +from crispy_forms.layout import HTML, Button, Fieldset, Layout from django import forms from django.contrib.postgres.search import SearchVector from django.core.exceptions import ObjectDoesNotExist, ValidationError -from django.db.models import Q, F, Func, Value +from django.db.models import F, Func, Q, Value from django.forms import ModelChoiceField, ModelForm, widgets from django.utils import timezone from django.utils.translation import gettext_lazy as _ -import django_filters from sapl.base.models import TipoAutor -from sapl.crispy_layout_mixin import form_actions, SaplFormHelper, to_row -from sapl.materia.models import (MateriaLegislativa, - TipoMateriaLegislativa, Orgao) +from sapl.crispy_layout_mixin import SaplFormHelper, form_actions, to_row +from sapl.materia.models import (MateriaLegislativa, Orgao, + TipoMateriaLegislativa) from sapl.parlamentares.models import Partido -from sapl.utils import (autor_label, autor_modal, ANO_CHOICES, choice_anos_com_normas, - FileFieldCheckMixin, FilterOverridesMetaMixin, - NormaPesquisaOrderingFilter, validar_arquivo) +from sapl.utils import (ANO_CHOICES, FileFieldCheckMixin, + FilterOverridesMetaMixin, NormaPesquisaOrderingFilter, + autor_label, autor_modal, choice_anos_com_normas, + validar_arquivo) from .models import (AnexoNormaJuridica, AssuntoNorma, AutoriaNorma, NormaJuridica, NormaRelacionada, TipoNormaJuridica) def get_esferas(): - return [('E', 'Estadual'), - ('F', 'Federal'), - ('M', 'Municipal')] + return [("E", "Estadual"), ("F", "Federal"), ("M", "Municipal")] -YES_NO_CHOICES = [('', '---------'), - (True, _('Sim')), - (False, _('Não'))] +YES_NO_CHOICES = [("", "---------"), (True, _("Sim")), (False, _("Não"))] -ORDENACAO_CHOICES = [('', '---------'), - ('tipo,ano,numero', _('Tipo/Ano/Número')), - ('data,tipo,ano,numero', _('Data/Tipo/Ano/Número'))] +ORDENACAO_CHOICES = [ + ("", "---------"), + ("tipo,ano,numero", _("Tipo/Ano/Número")), + ("data,tipo,ano,numero", _("Data/Tipo/Ano/Número")), +] class AssuntoNormaFilterSet(django_filters.FilterSet): - assunto = django_filters.CharFilter(label=_("Assunto"), - method='multifield_filter') + assunto = django_filters.CharFilter(label=_("Assunto"), method="multifield_filter") class Meta: model = AssuntoNorma fields = ["assunto"] def multifield_filter(self, queryset, name, value): - return queryset.filter(Q(assunto__icontains=value) | Q(descricao__icontains=value)) + return queryset.filter( + Q(assunto__icontains=value) | Q(descricao__icontains=value) + ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -60,226 +60,292 @@ class AssuntoNormaFilterSet(django_filters.FilterSet): self.form.helper.layout = Layout( Fieldset( _("Pesquisa de Assunto de Norma Jurídica"), - row0, form_actions(label="Pesquisar")) + row0, + form_actions(label="Pesquisar"), + ) ) class NormaFilterSet(django_filters.FilterSet): + ano = django_filters.ChoiceFilter( + required=False, label="Ano", choices=choice_anos_com_normas + ) - ano = django_filters.ChoiceFilter(required=False, - label='Ano', - choices=choice_anos_com_normas) - - numero = django_filters.CharFilter( - method='filter_numero', - label=_('Número')) + numero = django_filters.CharFilter(method="filter_numero", label=_("Número")) ementa = django_filters.CharFilter( - method='filter_ementa', - label=_('Pesquisar expressões na ementa da norma')) + method="filter_ementa", label=_("Pesquisar expressões na ementa da norma") + ) - indexacao = django_filters.CharFilter(method='filter_indexacao', - label=_('Indexação')) + indexacao = django_filters.CharFilter( + method="filter_indexacao", label=_("Indexação") + ) - assuntos = django_filters.ModelChoiceFilter( - queryset=AssuntoNorma.objects.all()) + assuntos = django_filters.ModelChoiceFilter(queryset=AssuntoNorma.objects.all()) autorianorma__autor = django_filters.CharFilter(widget=forms.HiddenInput()) autorianorma__primeiro_autor = django_filters.BooleanFilter( - required=False, - label=_('Primeiro Autor')) - autorianorma__autor__parlamentar_set__filiacao__partido = django_filters.ModelChoiceFilter( - queryset=Partido.objects.all(), - label=_('Normas por Partido')) + required=False, label=_("Primeiro Autor") + ) + autorianorma__autor__parlamentar_set__filiacao__partido = ( + django_filters.ModelChoiceFilter( + queryset=Partido.objects.all(), label=_("Normas por Partido") + ) + ) - o = NormaPesquisaOrderingFilter(help_text='') + o = NormaPesquisaOrderingFilter(help_text="") class Meta(FilterOverridesMetaMixin): model = NormaJuridica - fields = ['orgao', 'tipo', 'numero', 'ano', 'data', - 'data_vigencia', 'data_publicacao', 'ementa', 'assuntos', - 'autorianorma__autor', 'autorianorma__primeiro_autor', 'autorianorma__autor__tipo'] + fields = [ + "orgao", + "tipo", + "numero", + "ano", + "data", + "data_vigencia", + "data_publicacao", + "ementa", + "assuntos", + "autorianorma__autor", + "autorianorma__primeiro_autor", + "autorianorma__autor__tipo", + ] def __init__(self, *args, **kwargs): super(NormaFilterSet, self).__init__(*args, **kwargs) - self.filters['autorianorma__autor__tipo'].label = _('Tipo de Autor') - - row1 = to_row([('tipo', 4), ('numero', 4), ('ano', 4)]) - row2 = to_row([('data', 6), ('data_publicacao', 6)]) - row3 = to_row([('ementa', 6), ('assuntos', 6)]) - row4 = to_row([('data_vigencia', 6), ('orgao', 6), ]) - row5 = to_row([('o', 6), ('indexacao', 6)]) - row6 = to_row([ - ('autorianorma__autor', 0), - (Button('pesquisar', - 'Pesquisar Autor', - css_class='btn btn-primary btn-sm'), 2), - (Button('limpar', - 'Limpar Autor', - css_class='btn btn-primary btn-sm'), 2), - ('autorianorma__primeiro_autor', 2), - ('autorianorma__autor__tipo', 3), - ('autorianorma__autor__parlamentar_set__filiacao__partido', 3) - ]) + self.filters["autorianorma__autor__tipo"].label = _("Tipo de Autor") + + row1 = to_row([("tipo", 4), ("numero", 4), ("ano", 4)]) + row2 = to_row([("data", 6), ("data_publicacao", 6)]) + row3 = to_row([("ementa", 6), ("assuntos", 6)]) + row4 = to_row( + [ + ("data_vigencia", 6), + ("orgao", 6), + ] + ) + row5 = to_row([("o", 6), ("indexacao", 6)]) + row6 = to_row( + [ + ("autorianorma__autor", 0), + ( + Button( + "pesquisar", + "Pesquisar Autor", + css_class="btn btn-primary btn-sm", + ), + 2, + ), + ( + Button( + "limpar", "Limpar Autor", css_class="btn btn-primary btn-sm" + ), + 2, + ), + ("autorianorma__primeiro_autor", 2), + ("autorianorma__autor__tipo", 3), + ("autorianorma__autor__parlamentar_set__filiacao__partido", 3), + ] + ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Norma'), - row1, row2, row3, row4, row5, - Fieldset(_('Pesquisa Avançada'), - row6, - HTML(autor_label), - HTML(autor_modal)), - form_actions(label='Pesquisar')) + Fieldset( + _("Pesquisa de Norma"), + row1, + row2, + row3, + row4, + row5, + Fieldset( + _("Pesquisa Avançada"), row6, HTML(autor_label), HTML(autor_modal) + ), + form_actions(label="Pesquisar"), + ) ) def filter_numero(self, queryset, name, value): - p = r'(\W|_)' - value = re.sub(p, '', value, flags=re.IGNORECASE) + p = r"(\W|_)" + value = re.sub(p, "", value, flags=re.IGNORECASE) return queryset.annotate( numero_clean=Func( - F('numero'), - Value(p), - Value(''), - Value('g'), - function='REGEXP_REPLACE' + F("numero"), Value(p), Value(""), Value("g"), function="REGEXP_REPLACE" ) ).filter(numero_clean=value) def filter_ementa(self, queryset, name, value): - return queryset.annotate(search=SearchVector('ementa', - config='portuguese')).filter(search=value) + return queryset.annotate( + search=SearchVector("ementa", config="portuguese") + ).filter(search=value) def filter_indexacao(self, queryset, name, value): - return queryset.annotate(search=SearchVector('indexacao', - config='portuguese')).filter(search=value) + return queryset.annotate( + search=SearchVector("indexacao", config="portuguese") + ).filter(search=value) def filter_autoria(self, queryset, name, value): - return queryset.filter(**{ - name: value, - }) + return queryset.filter( + **{ + name: value, + } + ) class NormaJuridicaForm(FileFieldCheckMixin, ModelForm): - # Campos de MateriaLegislativa tipo_materia = forms.ModelChoiceField( - label='Matéria', + label="Matéria", required=False, queryset=TipoMateriaLegislativa.objects.all(), - empty_label='Selecione', - widget=forms.Select(attrs={'autocomplete': 'off'}) + empty_label="Selecione", + widget=forms.Select(attrs={"autocomplete": "off"}), ) numero_materia = forms.CharField( - label='Número Matéria', + label="Número Matéria", required=False, - widget=forms.TextInput(attrs={'autocomplete': 'off'}) + widget=forms.TextInput(attrs={"autocomplete": "off"}), ) ano_materia = forms.ChoiceField( - label='Ano Matéria', + label="Ano Matéria", required=False, choices=ANO_CHOICES, - widget=forms.Select(attrs={'autocomplete': 'off'}) + widget=forms.Select(attrs={"autocomplete": "off"}), ) logger = logging.getLogger(__name__) class Meta: model = NormaJuridica - fields = ['tipo', - 'numero', - 'ano', - 'orgao', - 'data', - 'esfera_federacao', - 'complemento', - 'tipo_materia', - 'numero_materia', - 'ano_materia', - 'data_publicacao', - 'data_vigencia', - 'veiculo_publicacao', - 'pagina_inicio_publicacao', - 'pagina_fim_publicacao', - 'ementa', - 'indexacao', - 'observacao', - 'texto_integral', - 'assuntos', - 'user', - 'ip', - 'ultima_edicao'] - - widgets = {'assuntos': widgets.CheckboxSelectMultiple, - 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput()} + fields = [ + "tipo", + "numero", + "ano", + "orgao", + "data", + "esfera_federacao", + "complemento", + "tipo_materia", + "numero_materia", + "ano_materia", + "data_publicacao", + "data_vigencia", + "veiculo_publicacao", + "pagina_inicio_publicacao", + "pagina_fim_publicacao", + "ementa", + "indexacao", + "observacao", + "texto_integral", + "assuntos", + "user", + "ip", + "ultima_edicao", + ] - def clean(self): + widgets = { + "assuntos": widgets.CheckboxSelectMultiple, + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), + } + def clean(self): cleaned_data = super(NormaJuridicaForm, self).clean() if not self.is_valid(): return cleaned_data import re - has_digits = re.sub(r'[^0-9]', '', cleaned_data['numero']) + + has_digits = re.sub(r"[^0-9]", "", cleaned_data["numero"]) if not has_digits: - self.logger.error("Número de norma ({}) não pode conter somente letras.".format( - cleaned_data['numero'])) - raise ValidationError( - 'Número de norma não pode conter somente letras') + self.logger.error( + "Número de norma ({}) não pode conter somente letras.".format( + cleaned_data["numero"] + ) + ) + raise ValidationError("Número de norma não pode conter somente letras") - if self.instance.numero != cleaned_data['numero']: + if self.instance.numero != cleaned_data["numero"]: params = { - 'ano': cleaned_data['ano'], - 'numero': cleaned_data['numero'], - 'tipo': cleaned_data['tipo'], + "ano": cleaned_data["ano"], + "numero": cleaned_data["numero"], + "tipo": cleaned_data["tipo"], } - params['orgao'] = cleaned_data['orgao'] + params["orgao"] = cleaned_data["orgao"] norma = NormaJuridica.objects.filter(**params).exists() if norma: - 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, Órgão " - "e Número no sistema") - if (cleaned_data['tipo_materia'] and - cleaned_data['numero_materia'] and - cleaned_data['ano_materia']): + 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, Órgão " + "e Número no sistema" + ) + if ( + cleaned_data["tipo_materia"] + and cleaned_data["numero_materia"] + and cleaned_data["ano_materia"] + ): try: - self.logger.debug("Tentando obter objeto MateriaLegislativa com tipo={}, numero={}, ano={}." - .format(cleaned_data['tipo_materia'], cleaned_data['numero_materia'], cleaned_data['ano_materia'])) + self.logger.debug( + "Tentando obter objeto MateriaLegislativa com tipo={}, numero={}, ano={}.".format( + cleaned_data["tipo_materia"], + cleaned_data["numero_materia"], + cleaned_data["ano_materia"], + ) + ) materia = MateriaLegislativa.objects.get( - tipo_id=cleaned_data['tipo_materia'], - numero=cleaned_data['numero_materia'], - ano=cleaned_data['ano_materia']) + tipo_id=cleaned_data["tipo_materia"], + numero=cleaned_data["numero_materia"], + ano=cleaned_data["ano_materia"], + ) except ObjectDoesNotExist: - self.logger.error("Matéria Legislativa %s/%s (%s) é inexistente." % ( - self.cleaned_data['numero_materia'], - self.cleaned_data['ano_materia'], - cleaned_data['tipo_materia'].descricao)) + self.logger.error( + "Matéria Legislativa %s/%s (%s) é inexistente." + % ( + self.cleaned_data["numero_materia"], + self.cleaned_data["ano_materia"], + cleaned_data["tipo_materia"].descricao, + ) + ) raise forms.ValidationError( - _("Matéria Legislativa %s/%s (%s) é inexistente." % ( - self.cleaned_data['numero_materia'], - self.cleaned_data['ano_materia'], - cleaned_data['tipo_materia'].descricao))) + _( + "Matéria Legislativa %s/%s (%s) é inexistente." + % ( + self.cleaned_data["numero_materia"], + self.cleaned_data["ano_materia"], + cleaned_data["tipo_materia"].descricao, + ) + ) + ) else: - self.logger.info("MateriaLegislativa com tipo={}, numero={}, ano={} obtida com sucesso." - .format(cleaned_data['tipo_materia'], cleaned_data['numero_materia'], cleaned_data['ano_materia'])) - cleaned_data['materia'] = materia + self.logger.info( + "MateriaLegislativa com tipo={}, numero={}, ano={} obtida com sucesso.".format( + cleaned_data["tipo_materia"], + cleaned_data["numero_materia"], + cleaned_data["ano_materia"], + ) + ) + cleaned_data["materia"] = materia else: - cleaned_data['materia'] = None + cleaned_data["materia"] = None return cleaned_data def clean_texto_integral(self): super(NormaJuridicaForm, self).clean() - texto_integral = self.cleaned_data.get('texto_integral', False) + texto_integral = self.cleaned_data.get("texto_integral", False) if texto_integral: validar_arquivo(texto_integral, "Texto Original") @@ -289,49 +355,56 @@ class NormaJuridicaForm(FileFieldCheckMixin, ModelForm): def save(self, commit=False): norma = self.instance norma.timestamp = timezone.now() - norma.materia = self.cleaned_data['materia'] + norma.materia = self.cleaned_data["materia"] norma = super(NormaJuridicaForm, self).save(commit=True) return norma class AutoriaNormaForm(ModelForm): + tipo_autor = ModelChoiceField( + label=_("Tipo Autor"), + required=False, + queryset=TipoAutor.objects.all(), + empty_label=_("Selecione"), + ) - tipo_autor = ModelChoiceField(label=_('Tipo Autor'), - required=False, - queryset=TipoAutor.objects.all(), - empty_label=_('Selecione'),) - - data_relativa = forms.DateField( - widget=forms.HiddenInput(), required=False) + data_relativa = forms.DateField(widget=forms.HiddenInput(), required=False) - legislatura_anterior = forms.BooleanField(label=_('Legislatura Anterior'), - required=False) + legislatura_anterior = forms.BooleanField( + label=_("Legislatura Anterior"), required=False + ) logger = logging.getLogger(__name__) def __init__(self, *args, **kwargs): super(AutoriaNormaForm, self).__init__(*args, **kwargs) - row1 = to_row([('tipo_autor', 4), - ('autor', 4), - ('primeiro_autor', 4)]) + row1 = to_row([("tipo_autor", 4), ("autor", 4), ("primeiro_autor", 4)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset(_('Autoria'), - row1, 'data_relativa', - form_actions(label='Salvar'), - to_row([('legislatura_anterior', 12)]))) + Fieldset( + _("Autoria"), + row1, + "data_relativa", + form_actions(label="Salvar"), + to_row([("legislatura_anterior", 12)]), + ) + ) if not self.instance: - self.fields['autor'].choices = [] + self.fields["autor"].choices = [] class Meta: model = AutoriaNorma - fields = ['tipo_autor', 'autor', - 'primeiro_autor', 'data_relativa', - 'legislatura_anterior'] + fields = [ + "tipo_autor", + "autor", + "primeiro_autor", + "data_relativa", + "legislatura_anterior", + ] def clean(self): cd = super(AutoriaNormaForm, self).clean() @@ -340,32 +413,27 @@ class AutoriaNormaForm(ModelForm): return self.cleaned_data autorias = AutoriaNorma.objects.filter( - norma=self.instance.norma, autor=cd['autor']) + norma=self.instance.norma, autor=cd["autor"] + ) pk = self.instance.pk - if ((not pk and autorias.exists()) or - (pk and autorias.exclude(pk=pk).exists())): - self.logger.error( - "Autor ({}) já foi cadastrado.".format(cd['autor'])) - raise ValidationError(_('Esse Autor já foi cadastrado.')) + if (not pk and autorias.exists()) or (pk and autorias.exclude(pk=pk).exists()): + self.logger.error("Autor ({}) já foi cadastrado.".format(cd["autor"])) + raise ValidationError(_("Esse Autor já foi cadastrado.")) return cd class AnexoNormaJuridicaForm(FileFieldCheckMixin, ModelForm): - logger = logging.getLogger(__name__) - anexo_arquivo = forms.FileField( - required=True, - label="Arquivo Anexo" - ) + anexo_arquivo = forms.FileField(required=True, label="Arquivo Anexo") class Meta: model = AnexoNormaJuridica - fields = ['norma', 'anexo_arquivo', 'assunto_anexo'] + fields = ["norma", "anexo_arquivo", "assunto_anexo"] widgets = { - 'norma': forms.HiddenInput(), + "norma": forms.HiddenInput(), } def clean(self): @@ -374,7 +442,7 @@ class AnexoNormaJuridicaForm(FileFieldCheckMixin, ModelForm): if not self.is_valid(): return cleaned_data - anexo_arquivo = self.cleaned_data.get('anexo_arquivo', False) + anexo_arquivo = self.cleaned_data.get("anexo_arquivo", False) if anexo_arquivo: validar_arquivo(anexo_arquivo, "Arquivo Anexo") @@ -383,44 +451,40 @@ class AnexoNormaJuridicaForm(FileFieldCheckMixin, ModelForm): def save(self, commit=False): anexo = self.instance - anexo.ano = self.cleaned_data['norma'].ano - anexo.norma = self.cleaned_data['norma'] - anexo.assunto_anexo = self.cleaned_data['assunto_anexo'] - anexo.anexo_arquivo = self.cleaned_data['anexo_arquivo'] + anexo.ano = self.cleaned_data["norma"].ano + anexo.norma = self.cleaned_data["norma"] + anexo.assunto_anexo = self.cleaned_data["assunto_anexo"] + anexo.anexo_arquivo = self.cleaned_data["anexo_arquivo"] anexo = super(AnexoNormaJuridicaForm, self).save(commit=True) return anexo class NormaRelacionadaForm(ModelForm): - orgao = forms.ModelChoiceField( - label='Órgão', + label="Órgão", required=False, queryset=Orgao.objects.all(), - empty_label='----------', + empty_label="----------", ) tipo = forms.ModelChoiceField( - label='Tipo', + label="Tipo", required=True, queryset=TipoNormaJuridica.objects.all(), - empty_label='----------', + empty_label="----------", ) - numero = forms.CharField(label='Número', required=True) - ano = forms.CharField(label='Ano', required=True) + numero = forms.CharField(label="Número", required=True) + ano = forms.CharField(label="Ano", required=True) ementa = forms.CharField( - required=False, - widget=forms.Textarea(attrs={'disabled': 'disabled'})) + required=False, widget=forms.Textarea(attrs={"disabled": "disabled"}) + ) logger = logging.getLogger(__name__) class Meta: model = NormaRelacionada - fields = ['orgao', 'tipo', 'numero', 'ano', - 'resumo', 'ementa', 'tipo_vinculo'] + fields = ["orgao", "tipo", "numero", "ano", "resumo", "ementa", "tipo_vinculo"] - widgets = { - 'resumo': forms.Textarea( - attrs={'id': 'texto-rico'})} + widgets = {"resumo": forms.Textarea(attrs={"id": "texto-rico"})} def __init__(self, *args, **kwargs): super(NormaRelacionadaForm, self).__init__(*args, **kwargs) @@ -433,30 +497,51 @@ class NormaRelacionadaForm(ModelForm): cleaned_data = self.cleaned_data try: - self.logger.debug("Tentando obter objeto NormaJuridica com numero={}, ano={}, tipo={}, orgao={}.".format( - cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'], cleaned_data['orgao'])) + self.logger.debug( + "Tentando obter objeto NormaJuridica com numero={}, ano={}, tipo={}, orgao={}.".format( + cleaned_data["numero"], + cleaned_data["ano"], + cleaned_data["tipo"], + cleaned_data["orgao"], + ) + ) norma_relacionada = NormaJuridica.objects.get( - numero=cleaned_data['numero'], - ano=cleaned_data['ano'], - tipo=cleaned_data['tipo'], - orgao=cleaned_data['orgao']) + numero=cleaned_data["numero"], + ano=cleaned_data["ano"], + tipo=cleaned_data["tipo"], + orgao=cleaned_data["orgao"], + ) except ObjectDoesNotExist: - self.logger.info("NormaJuridica com numero={}, ano={}, tipo={}, orgao={} não existe.".format( - cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'], cleaned_data['orgao'])) - msg = _('A norma a ser relacionada não existe.') + self.logger.info( + "NormaJuridica com numero={}, ano={}, tipo={}, orgao={} não existe.".format( + cleaned_data["numero"], + cleaned_data["ano"], + cleaned_data["tipo"], + cleaned_data["orgao"], + ) + ) + msg = _("A norma a ser relacionada não existe.") raise ValidationError(msg) else: - self.logger.info("NormaJuridica com numero={}, ano={}, tipo={} , orgao={} obtida com sucesso.".format( - cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'], cleaned_data['orgao'])) - cleaned_data['norma_relacionada'] = norma_relacionada + self.logger.info( + "NormaJuridica com numero={}, ano={}, tipo={} , orgao={} obtida com sucesso.".format( + cleaned_data["numero"], + cleaned_data["ano"], + cleaned_data["tipo"], + cleaned_data["orgao"], + ) + ) + cleaned_data["norma_relacionada"] = norma_relacionada return cleaned_data def save(self, commit=False): relacionada = super(NormaRelacionadaForm, self).save(commit) - relacionada.norma_relacionada = self.cleaned_data['norma_relacionada'] + relacionada.norma_relacionada = self.cleaned_data["norma_relacionada"] if relacionada.tipo_vinculo.revoga_integralmente: - relacionada.norma_relacionada.data_vigencia = relacionada.norma_principal.data + relacionada.norma_relacionada.data_vigencia = ( + relacionada.norma_principal.data + ) relacionada.norma_relacionada.save() relacionada.save() return relacionada @@ -467,45 +552,33 @@ class NormaPesquisaSimplesForm(forms.Form): label=TipoNormaJuridica._meta.verbose_name, queryset=TipoNormaJuridica.objects.all(), required=False, - empty_label='Selecione') + empty_label="Selecione", + ) data_inicial = forms.DateField( - label='Data Inicial', - required=False, - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Inicial", required=False, widget=forms.DateInput(format="%d/%m/%Y") ) data_final = forms.DateField( - label='Data Final', - required=False, - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Final", required=False, widget=forms.DateInput(format="%d/%m/%Y") ) titulo = forms.CharField( - label='Título do Relatório', - required=False, - max_length=150) + label="Título do Relatório", required=False, max_length=150 + ) logger = logging.getLogger(__name__) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - row1 = to_row( - [('tipo_norma', 6), - ('data_inicial', 3), - ('data_final', 3)]) + row1 = to_row([("tipo_norma", 6), ("data_inicial", 3), ("data_final", 3)]) - row2 = to_row( - [('titulo', 12)]) + row2 = to_row([("titulo", 12)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset( - 'Índice de Normas', - row1, row2, - form_actions(label='Pesquisar') - ) + Fieldset("Índice de Normas", row1, row2, form_actions(label="Pesquisar")) ) def clean(self): @@ -515,19 +588,29 @@ class NormaPesquisaSimplesForm(forms.Form): return self.cleaned_data cleaned_data = self.cleaned_data - data_inicial = cleaned_data['data_inicial'] - data_final = cleaned_data['data_final'] + data_inicial = cleaned_data["data_inicial"] + data_final = cleaned_data["data_final"] if data_inicial or data_final: - if not(data_inicial and data_final): - self.logger.error("Caso pesquise por data, os campos de Data Inicial e " - "Data Final devem ser preenchidos obrigatoriamente") - raise ValidationError(_('Caso pesquise por data, os campos de Data Inicial e ' - 'Data Final devem ser preenchidos obrigatoriamente')) + if not (data_inicial and data_final): + self.logger.error( + "Caso pesquise por data, os campos de Data Inicial e " + "Data Final devem ser preenchidos obrigatoriamente" + ) + raise ValidationError( + _( + "Caso pesquise por data, os campos de Data Inicial e " + "Data Final devem ser preenchidos obrigatoriamente" + ) + ) elif data_inicial > data_final: - self.logger.error("Data Final ({}) menor que a Data Inicial ({}).".format( - data_final, data_inicial)) + self.logger.error( + "Data Final ({}) menor que a Data Inicial ({}).".format( + data_final, data_inicial + ) + ) raise ValidationError( - _('A Data Final não pode ser menor que a Data Inicial')) + _("A Data Final não pode ser menor que a Data Inicial") + ) return cleaned_data diff --git a/sapl/norma/models.py b/sapl/norma/models.py index 6b63b94fc..f7377190f 100644 --- a/sapl/norma/models.py +++ b/sapl/norma/models.py @@ -8,22 +8,21 @@ from model_utils import Choices from sapl.base.models import Autor from sapl.compilacao.models import TextoArticulado from sapl.materia.models import MateriaLegislativa, Orgao -from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, - restringe_tipos_de_arquivo_txt, - texto_upload_path, +from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, OverwriteStorage, get_settings_auth_user_model, - OverwriteStorage) + restringe_tipos_de_arquivo_txt, texto_upload_path) class AssuntoNorma(models.Model): - assunto = models.CharField(max_length=50, verbose_name=_('Assunto')) + assunto = models.CharField(max_length=50, verbose_name=_("Assunto")) descricao = models.CharField( - max_length=250, blank=True, verbose_name=_('Descrição')) + max_length=250, blank=True, verbose_name=_("Descrição") + ) class Meta: - verbose_name = _('Assunto de Norma Jurídica') - verbose_name_plural = _('Assuntos de Normas Jurídicas') - ordering = ['assunto'] + verbose_name = _("Assunto de Norma Jurídica") + verbose_name_plural = _("Assuntos de Normas Jurídicas") + ordering = ["assunto"] def __str__(self): return self.assunto @@ -31,33 +30,37 @@ class AssuntoNorma(models.Model): class TipoNormaJuridica(models.Model): # TODO transform into Domain Model and use an FK for the field - EQUIVALENTE_LEXML_CHOICES = ((name, name) for name in - ('constituicao', - 'ementa.constitucional', - 'lei.complementar', - 'lei.delegada', - 'lei', - 'decreto.lei', - 'medida.provisoria', - 'decreto', - 'lei.organica', - 'emenda.lei.organica', - 'decreto.legislativo', - 'resolucao', - 'regimento.interno', - )) + EQUIVALENTE_LEXML_CHOICES = ( + (name, name) + for name in ( + "constituicao", + "ementa.constitucional", + "lei.complementar", + "lei.delegada", + "lei", + "decreto.lei", + "medida.provisoria", + "decreto", + "lei.organica", + "emenda.lei.organica", + "decreto.legislativo", + "resolucao", + "regimento.interno", + ) + ) equivalente_lexml = models.CharField( max_length=50, blank=True, - verbose_name=_('Equivalente LexML'), - choices=EQUIVALENTE_LEXML_CHOICES) - sigla = models.CharField(max_length=3, verbose_name=_('Sigla')) - descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) + verbose_name=_("Equivalente LexML"), + choices=EQUIVALENTE_LEXML_CHOICES, + ) + sigla = models.CharField(max_length=3, verbose_name=_("Sigla")) + descricao = models.CharField(max_length=50, verbose_name=_("Descrição")) class Meta: - verbose_name = _('Tipo de Norma Jurídica') - verbose_name_plural = _('Tipos de Norma Jurídica') - ordering = ['descricao'] + verbose_name = _("Tipo de Norma Jurídica") + verbose_name_plural = _("Tipos de Norma Jurídica") + ordering = ["descricao"] def __str__(self): return self.descricao @@ -68,7 +71,6 @@ def norma_upload_path(instance, filename): class NormaJuridicaManager(models.Manager): - use_for_related_fields = True def normas_sem_textos_articulados(self): @@ -81,19 +83,16 @@ class NormaJuridicaManager(models.Manager): qs = qs.filter( texto_articulado__editable_only_by_owners=False, texto_articulado__privacidade=0, - texto_articulado__isnull=False + texto_articulado__isnull=False, ) return qs def normas_com_textos_articulados_pendentes(self): qs = self.get_queryset() - qs = qs.filter( - texto_articulado__editable_only_by_owners=False) + qs = qs.filter(texto_articulado__editable_only_by_owners=False) - q = models.Q( - texto_articulado__privacidade=0 - ) | models.Q( + q = models.Q(texto_articulado__privacidade=0) | models.Q( texto_articulado__isnull=True ) qs = qs.exclude(q) @@ -109,14 +108,15 @@ class NormaJuridicaManager(models.Manager): count = 0 elif count == 3: ds = ta.dispositivos_set.all() - if ds[1].auto_inserido and \ - not d[2].dispositivo_pai and\ - d[2].tipo_dispositivo.dispositivo_de_articulacao: + if ( + ds[1].auto_inserido + and not d[2].dispositivo_pai + and d[2].tipo_dispositivo.dispositivo_de_articulacao + ): count = 0 if not count: - ta.dispositivos_set.filter( - dispositivo_pai__isnull=False).delete() + ta.dispositivos_set.filter(dispositivo_pai__isnull=False).delete() ta.publicacao_set.all().delete() ta.delete() @@ -124,13 +124,12 @@ class NormaJuridicaManager(models.Manager): class NormaJuridica(models.Model): - objects = NormaJuridicaManager() ESFERA_FEDERACAO_CHOICES = Choices( - ('M', 'municipal', _('Municipal')), - ('E', 'estadual', _('Estadual')), - ('F', 'federal', _('Federal')), + ("M", "municipal", _("Municipal")), + ("E", "estadual", _("Estadual")), + ("F", "federal", _("Federal")), ) texto_integral = models.FileField( @@ -138,132 +137,137 @@ class NormaJuridica(models.Model): blank=True, null=True, upload_to=norma_upload_path, - verbose_name=_('Texto Original'), + verbose_name=_("Texto Original"), storage=OverwriteStorage(), - validators=[restringe_tipos_de_arquivo_txt]) + validators=[restringe_tipos_de_arquivo_txt], + ) tipo = models.ForeignKey( TipoNormaJuridica, on_delete=models.PROTECT, - verbose_name=_('Tipo da Norma Jurídica')) + verbose_name=_("Tipo da Norma Jurídica"), + ) materia = models.ForeignKey( - MateriaLegislativa, blank=True, null=True, + MateriaLegislativa, + blank=True, + null=True, on_delete=models.PROTECT, - verbose_name=_('Matéria'), - related_name='normajuridica_set') + verbose_name=_("Matéria"), + related_name="normajuridica_set", + ) orgao = models.ForeignKey( - Orgao, blank=True, null=True, - on_delete=models.PROTECT, verbose_name=_('Órgão')) - numero = models.CharField( - max_length=8, - verbose_name=_('Número')) - ano = models.PositiveSmallIntegerField(verbose_name=_('Ano'), - choices=RANGE_ANOS) + Orgao, blank=True, null=True, on_delete=models.PROTECT, verbose_name=_("Órgão") + ) + numero = models.CharField(max_length=8, verbose_name=_("Número")) + ano = models.PositiveSmallIntegerField(verbose_name=_("Ano"), choices=RANGE_ANOS) esfera_federacao = models.CharField( max_length=1, - verbose_name=_('Esfera Federação'), - choices=ESFERA_FEDERACAO_CHOICES) - data = models.DateField(blank=False, null=True, verbose_name=_('Data')) + verbose_name=_("Esfera Federação"), + choices=ESFERA_FEDERACAO_CHOICES, + ) + data = models.DateField(blank=False, null=True, verbose_name=_("Data")) data_publicacao = models.DateField( - blank=True, null=True, verbose_name=_('Data de Publicação')) + blank=True, null=True, verbose_name=_("Data de Publicação") + ) veiculo_publicacao = models.CharField( - max_length=200, - blank=True, - verbose_name=_('Veículo de Publicação')) + max_length=200, blank=True, verbose_name=_("Veículo de Publicação") + ) pagina_inicio_publicacao = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Pg. Início')) + blank=True, null=True, verbose_name=_("Pg. Início") + ) pagina_fim_publicacao = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Pg. Fim')) - ementa = models.TextField(verbose_name=_('Ementa')) - indexacao = models.TextField( - blank=True, verbose_name=_('Indexação')) - observacao = models.TextField( - blank=True, verbose_name=_('Observação')) + blank=True, null=True, verbose_name=_("Pg. Fim") + ) + ementa = models.TextField(verbose_name=_("Ementa")) + indexacao = models.TextField(blank=True, verbose_name=_("Indexação")) + observacao = models.TextField(blank=True, verbose_name=_("Observação")) complemento = models.BooleanField( null=True, blank=True, default=False, - verbose_name=_('Complementar ?'), - choices=YES_NO_CHOICES + verbose_name=_("Complementar ?"), + choices=YES_NO_CHOICES, ) # XXX was a CharField (attention on migrate) assuntos = models.ManyToManyField( - AssuntoNorma, blank=True, - verbose_name=_('Assuntos')) + AssuntoNorma, blank=True, verbose_name=_("Assuntos") + ) data_vigencia = models.DateField( - blank=True, null=True, verbose_name=_('Data Fim Vigência')) + blank=True, null=True, verbose_name=_("Data Fim Vigência") + ) timestamp = models.DateTimeField(null=True) texto_articulado = GenericRelation( - TextoArticulado, related_query_name='texto_articulado') + TextoArticulado, related_query_name="texto_articulado" + ) data_ultima_atualizacao = models.DateTimeField( - blank=True, null=True, - auto_now=True, - verbose_name=_('Data')) + blank=True, null=True, auto_now=True, verbose_name=_("Data") + ) autores = models.ManyToManyField( Autor, - through='AutoriaNorma', - through_fields=('norma', 'autor'), - symmetrical=False) + through="AutoriaNorma", + through_fields=("norma", "autor"), + symmetrical=False, + ) user = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Usuário'), + verbose_name=_("Usuário"), on_delete=models.PROTECT, null=True, - blank=True - ) - ip = models.CharField( - verbose_name=_('IP'), - max_length=60, blank=True, - default='' ) + ip = models.CharField(verbose_name=_("IP"), max_length=60, blank=True, default="") ultima_edicao = models.DateTimeField( - verbose_name=_('Data e Hora da Edição'), - blank=True, null=True + verbose_name=_("Data e Hora da Edição"), blank=True, null=True ) class Meta: - verbose_name = _('Norma Jurídica') - verbose_name_plural = _('Normas Jurídicas') - ordering = ['-data', '-numero'] + verbose_name = _("Norma Jurídica") + verbose_name_plural = _("Normas Jurídicas") + ordering = ["-data", "-numero"] def get_normas_relacionadas(self): - principais = NormaRelacionada.objects.\ - select_related('tipo_vinculo', - 'norma_principal', - 'norma_relacionada', - 'norma_principal__tipo', - 'norma_relacionada__tipo').\ - filter(norma_principal=self.id).order_by('norma_principal__data', - 'norma_relacionada__data') - relacionadas = NormaRelacionada.objects.\ - select_related('tipo_vinculo', - 'norma_principal', - 'norma_relacionada', - 'norma_principal__tipo', - 'norma_relacionada__tipo').\ - filter(norma_relacionada=self.id).order_by('norma_principal__data', - 'norma_relacionada__data') + principais = ( + NormaRelacionada.objects.select_related( + "tipo_vinculo", + "norma_principal", + "norma_relacionada", + "norma_principal__tipo", + "norma_relacionada__tipo", + ) + .filter(norma_principal=self.id) + .order_by("norma_principal__data", "norma_relacionada__data") + ) + relacionadas = ( + NormaRelacionada.objects.select_related( + "tipo_vinculo", + "norma_principal", + "norma_relacionada", + "norma_principal__tipo", + "norma_relacionada__tipo", + ) + .filter(norma_relacionada=self.id) + .order_by("norma_principal__data", "norma_relacionada__data") + ) return (principais, relacionadas) def get_anexos_norma_juridica(self): - anexos = AnexoNormaJuridica.objects.filter( - norma=self.id) + anexos = AnexoNormaJuridica.objects.filter(norma=self.id) return anexos def __str__(self): numero_norma = self.numero if numero_norma.isnumeric(): - numero_norma = '{0:,}'.format(int(self.numero)).replace(',', '.') + numero_norma = "{0:,}".format(int(self.numero)).replace(",", ".") - return _('%(tipo)s%(orgao_sigla)s nº %(numero)s, de %(data)s') % { - 'tipo': self.tipo, - 'orgao_sigla': f'-{self.orgao.sigla}' if self.orgao else '', - 'numero': numero_norma, - 'data': defaultfilters.date(self.data, r"d \d\e F \d\e Y").lower()} + return _("%(tipo)s%(orgao_sigla)s nº %(numero)s, de %(data)s") % { + "tipo": self.tipo, + "orgao_sigla": f"-{self.orgao.sigla}" if self.orgao else "", + "numero": numero_norma, + "data": defaultfilters.date(self.data, r"d \d\e F \d\e Y").lower(), + } @property def epigrafe(self): @@ -273,12 +277,13 @@ class NormaJuridica(models.Model): def epigrafe_simplificada(self): numero_norma = self.numero if numero_norma.isnumeric(): - numero_norma = '{0:,}'.format(int(self.numero)).replace(',', '.') + numero_norma = "{0:,}".format(int(self.numero)).replace(",", ".") - return _('%(tipo)s nº %(numero)s, de %(data)s') % { - 'tipo': self.tipo, - 'numero': numero_norma, - 'data': defaultfilters.date(self.data, r"d \d\e F \d\e Y").lower()} + return _("%(tipo)s nº %(numero)s, de %(data)s") % { + "tipo": self.tipo, + "numero": numero_norma, + "data": defaultfilters.date(self.data, r"d \d\e F \d\e Y").lower(), + } def delete(self, using=None, keep_parents=False): texto_integral = self.texto_integral @@ -289,22 +294,28 @@ class NormaJuridica(models.Model): return result - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): - + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): if not self.pk and self.texto_integral: texto_integral = self.texto_integral self.texto_integral = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.texto_integral = texto_integral - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) def get_ano_atual(): @@ -313,50 +324,51 @@ def get_ano_atual(): class NormaEstatisticas(models.Model): usuario = models.CharField(max_length=50) - horario_acesso = models.DateTimeField( - blank=True, null=True) - ano = models.PositiveSmallIntegerField(verbose_name=_('Ano'), - choices=RANGE_ANOS, default=get_ano_atual) - norma = models.ForeignKey(NormaJuridica, - on_delete=models.CASCADE) + horario_acesso = models.DateTimeField(blank=True, null=True) + ano = models.PositiveSmallIntegerField( + verbose_name=_("Ano"), choices=RANGE_ANOS, default=get_ano_atual + ) + norma = models.ForeignKey(NormaJuridica, on_delete=models.CASCADE) class Meta: - ordering = ('id',) + ordering = ("id",) def __str__(self): - return _('Usuário: %(usuario)s, Norma: %(norma)s') % { - 'usuario': self.usuario, 'norma': self.norma} + return _("Usuário: %(usuario)s, Norma: %(norma)s") % { + "usuario": self.usuario, + "norma": self.norma, + } class ViewNormasEstatisticas(models.Model): - mais_acessadas = models.PositiveSmallIntegerField( - verbose_name=_('Mais Acessadas')) + mais_acessadas = models.PositiveSmallIntegerField(verbose_name=_("Mais Acessadas")) ano_est = models.PositiveSmallIntegerField( - verbose_name=_('Ano do Registro de Acesso')) + verbose_name=_("Ano do Registro de Acesso") + ) mes_est = models.PositiveSmallIntegerField( - verbose_name=_('Mês do Registro de Acesso')) + verbose_name=_("Mês do Registro de Acesso") + ) - norma_id = models.BigIntegerField(verbose_name=_('Id da Norma')) + norma_id = models.BigIntegerField(verbose_name=_("Id da Norma")) norma_count = models.PositiveSmallIntegerField( - verbose_name=_('Mês do Registro de Acesso')) + verbose_name=_("Mês do Registro de Acesso") + ) - norma_numero = models.CharField( - max_length=8, verbose_name=_('Número da Norma')) + norma_numero = models.CharField(max_length=8, verbose_name=_("Número da Norma")) - norma_ano = models.PositiveSmallIntegerField( - verbose_name=_('Ano da Norma')) - norma_ementa = models.TextField(verbose_name=_('Ementa')) - norma_observacao = models.TextField( - blank=True, verbose_name=_('Observação')) + norma_ano = models.PositiveSmallIntegerField(verbose_name=_("Ano da Norma")) + norma_ementa = models.TextField(verbose_name=_("Ementa")) + norma_observacao = models.TextField(blank=True, verbose_name=_("Observação")) norma_tipo_sigla = models.CharField( - max_length=3, - verbose_name=_('Sigla do Tipo da Norma')) + max_length=3, verbose_name=_("Sigla do Tipo da Norma") + ) norma_tipo_descricao = models.CharField( - max_length=50, verbose_name=_('Descrição do Tipo da Norma')) + max_length=50, verbose_name=_("Descrição do Tipo da Norma") + ) - norma_data = models.DateField(verbose_name=_('Data da Norma')) + norma_data = models.DateField(verbose_name=_("Data da Norma")) class Meta: managed = False @@ -364,79 +376,70 @@ class ViewNormasEstatisticas(models.Model): class AutoriaNorma(models.Model): - autor = models.ForeignKey(Autor, - verbose_name=_('Autor'), - on_delete=models.CASCADE) + autor = models.ForeignKey(Autor, verbose_name=_("Autor"), on_delete=models.CASCADE) norma = models.ForeignKey( - NormaJuridica, on_delete=models.CASCADE, - verbose_name=_('Matéria Legislativa')) - primeiro_autor = models.BooleanField(verbose_name=_('Primeiro Autor'), - choices=YES_NO_CHOICES, - default=False) + NormaJuridica, on_delete=models.CASCADE, verbose_name=_("Matéria Legislativa") + ) + primeiro_autor = models.BooleanField( + verbose_name=_("Primeiro Autor"), choices=YES_NO_CHOICES, default=False + ) class Meta: - verbose_name = _('Autoria') - verbose_name_plural = _('Autorias') - unique_together = (('autor', 'norma'), ) - ordering = ('-primeiro_autor', 'autor__nome') + verbose_name = _("Autoria") + verbose_name_plural = _("Autorias") + unique_together = (("autor", "norma"),) + ordering = ("-primeiro_autor", "autor__nome") def __str__(self): - return _('Autoria: %(autor)s - %(norma)s') % { - 'autor': self.autor, 'norma': self.norma} + return _("Autoria: %(autor)s - %(norma)s") % { + "autor": self.autor, + "norma": self.norma, + } class LegislacaoCitada(models.Model): materia = models.ForeignKey(MateriaLegislativa, on_delete=models.CASCADE) norma = models.ForeignKey(NormaJuridica, on_delete=models.CASCADE) disposicoes = models.CharField( - max_length=15, blank=True, verbose_name=_('Disposição')) - parte = models.CharField( - max_length=8, blank=True, verbose_name=_('Parte')) - livro = models.CharField( - max_length=7, blank=True, verbose_name=_('Livro')) - titulo = models.CharField( - max_length=7, blank=True, verbose_name=_('Título')) - capitulo = models.CharField( - max_length=7, blank=True, verbose_name=_('Capítulo')) - secao = models.CharField( - max_length=7, blank=True, verbose_name=_('Seção')) - subsecao = models.CharField( - max_length=7, blank=True, verbose_name=_('Subseção')) - artigo = models.CharField( - max_length=4, blank=True, verbose_name=_('Artigo')) - paragrafo = models.CharField( - max_length=3, blank=True, verbose_name=_('Parágrafo')) - inciso = models.CharField( - max_length=10, blank=True, verbose_name=_('Inciso')) - alinea = models.CharField( - max_length=3, blank=True, verbose_name=_('Alínea')) - item = models.CharField( - max_length=3, blank=True, verbose_name=_('Item')) + max_length=15, blank=True, verbose_name=_("Disposição") + ) + parte = models.CharField(max_length=8, blank=True, verbose_name=_("Parte")) + livro = models.CharField(max_length=7, blank=True, verbose_name=_("Livro")) + titulo = models.CharField(max_length=7, blank=True, verbose_name=_("Título")) + capitulo = models.CharField(max_length=7, blank=True, verbose_name=_("Capítulo")) + secao = models.CharField(max_length=7, blank=True, verbose_name=_("Seção")) + subsecao = models.CharField(max_length=7, blank=True, verbose_name=_("Subseção")) + artigo = models.CharField(max_length=4, blank=True, verbose_name=_("Artigo")) + paragrafo = models.CharField(max_length=3, blank=True, verbose_name=_("Parágrafo")) + inciso = models.CharField(max_length=10, blank=True, verbose_name=_("Inciso")) + alinea = models.CharField(max_length=3, blank=True, verbose_name=_("Alínea")) + item = models.CharField(max_length=3, blank=True, verbose_name=_("Item")) class Meta: - verbose_name = _('Legislação') - verbose_name_plural = _('Legislações') - ordering = ('id',) + verbose_name = _("Legislação") + verbose_name_plural = _("Legislações") + ordering = ("id",) def __str__(self): return str(self.norma) class TipoVinculoNormaJuridica(models.Model): - sigla = models.CharField( - max_length=1, blank=True, verbose_name=_('Sigla')) + sigla = models.CharField(max_length=1, blank=True, verbose_name=_("Sigla")) descricao_ativa = models.CharField( - max_length=50, blank=True, verbose_name=_('Descrição Ativa')) + max_length=50, blank=True, verbose_name=_("Descrição Ativa") + ) descricao_passiva = models.CharField( - max_length=50, blank=True, verbose_name=_('Descrição Passiva')) - revoga_integralmente = models.BooleanField(verbose_name=_('Revoga Integralmente?'), - choices=YES_NO_CHOICES, - default=False) + max_length=50, blank=True, verbose_name=_("Descrição Passiva") + ) + revoga_integralmente = models.BooleanField( + verbose_name=_("Revoga Integralmente?"), choices=YES_NO_CHOICES, default=False + ) class Meta: - verbose_name = _('Tipo de Vínculo entre Normas Jurídicas') - verbose_name_plural = _('Tipos de Vínculos entre Normas Jurídicas') - ordering = ('id',) + verbose_name = _("Tipo de Vínculo entre Normas Jurídicas") + verbose_name_plural = _("Tipos de Vínculos entre Normas Jurídicas") + ordering = ("id",) def __str__(self): return self.descricao_ativa @@ -445,84 +448,95 @@ class TipoVinculoNormaJuridica(models.Model): class NormaRelacionada(models.Model): norma_principal = models.ForeignKey( NormaJuridica, - related_name='norma_principal', + related_name="norma_principal", on_delete=models.PROTECT, - verbose_name=_('Norma Principal')) + verbose_name=_("Norma Principal"), + ) norma_relacionada = models.ForeignKey( NormaJuridica, - related_name='norma_relacionada', + related_name="norma_relacionada", on_delete=models.PROTECT, - verbose_name=_('Norma Relacionada')) + verbose_name=_("Norma Relacionada"), + ) tipo_vinculo = models.ForeignKey( TipoVinculoNormaJuridica, on_delete=models.PROTECT, - verbose_name=_('Tipo de Vínculo')) + verbose_name=_("Tipo de Vínculo"), + ) resumo = models.TextField( blank=True, default="", - verbose_name=_('Resumo'), + verbose_name=_("Resumo"), ) class Meta: - verbose_name = _('Norma Relacionada') - verbose_name_plural = _('Normas Relacionadas') - ordering = ('norma_principal__data', 'norma_relacionada__data') + verbose_name = _("Norma Relacionada") + verbose_name_plural = _("Normas Relacionadas") + ordering = ("norma_principal__data", "norma_relacionada__data") def __str__(self): - return _('Principal: %(norma_principal)s' - ' - Relacionada: %(norma_relacionada)s') % { - 'norma_principal': str(self.norma_principal), - 'norma_relacionada': str(self.norma_relacionada)} + return _( + "Principal: %(norma_principal)s" " - Relacionada: %(norma_relacionada)s" + ) % { + "norma_principal": str(self.norma_principal), + "norma_relacionada": str(self.norma_relacionada), + } class AnexoNormaJuridica(models.Model): norma = models.ForeignKey( NormaJuridica, - related_name='norma', + related_name="norma", on_delete=models.PROTECT, - verbose_name=_('Norma Juridica')) + verbose_name=_("Norma Juridica"), + ) assunto_anexo = models.TextField( - blank=True, - default="", - verbose_name=_('Assunto do Anexo'), - max_length=250 + blank=True, default="", verbose_name=_("Assunto do Anexo"), max_length=250 ) anexo_arquivo = models.FileField( max_length=300, blank=True, null=True, upload_to=norma_upload_path, - verbose_name=_('Arquivo Anexo'), + verbose_name=_("Arquivo Anexo"), storage=OverwriteStorage(), - validators=[restringe_tipos_de_arquivo_txt]) - ano = models.PositiveSmallIntegerField(verbose_name=_('Ano'), - choices=RANGE_ANOS) + validators=[restringe_tipos_de_arquivo_txt], + ) + ano = models.PositiveSmallIntegerField(verbose_name=_("Ano"), choices=RANGE_ANOS) class Meta: - verbose_name = _('Anexo da Norma Juridica') - verbose_name_plural = _('Anexos da Norma Juridica') - ordering = ('id',) + verbose_name = _("Anexo da Norma Juridica") + verbose_name_plural = _("Anexos da Norma Juridica") + ordering = ("id",) def __str__(self): - return _('Anexo: %(anexo)s da norma %(norma)s') % { - 'anexo': self.anexo_arquivo, 'norma': self.norma} - - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): - + return _("Anexo: %(anexo)s da norma %(norma)s") % { + "anexo": self.anexo_arquivo, + "norma": self.norma, + } + + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): if not self.pk and self.anexo_arquivo: anexo_arquivo = self.anexo_arquivo self.anexo_arquivo = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.anexo_arquivo = anexo_arquivo - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) def delete(self, using=None, keep_parents=False): anexo_arquivo = self.anexo_arquivo diff --git a/sapl/norma/tests/test_norma.py b/sapl/norma/tests/test_norma.py index 2b8cdfa3c..993e1d220 100644 --- a/sapl/norma/tests/test_norma.py +++ b/sapl/norma/tests/test_norma.py @@ -1,7 +1,7 @@ +import pytest from django.urls import reverse from django.utils.translation import gettext_lazy as _ from model_bakery import baker -import pytest from sapl.base.models import AppConfig from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa @@ -13,48 +13,55 @@ from sapl.norma.models import NormaJuridica, TipoNormaJuridica @pytest.mark.django_db(transaction=False) def test_incluir_norma_submit(admin_client): # Cria um tipo de norma - tipo = baker.make(TipoNormaJuridica, - sigla='T', - descricao='Teste') + tipo = baker.make(TipoNormaJuridica, sigla="T", descricao="Teste") config = baker.make(AppConfig) # Testa POST - response = admin_client.post(reverse('sapl.norma:normajuridica_create'), - {'tipo': tipo.pk, - 'numero': '1', - 'ano': '2016', - 'data': '2016-03-22', - 'esfera_federacao': 'E', - 'ementa': 'Teste_Ementa', - 'salvar': 'salvar'}, - follow=True) + response = admin_client.post( + reverse("sapl.norma:normajuridica_create"), + { + "tipo": tipo.pk, + "numero": "1", + "ano": "2016", + "data": "2016-03-22", + "esfera_federacao": "E", + "ementa": "Teste_Ementa", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 norma = NormaJuridica.objects.first() - assert norma.numero == '1' + assert norma.numero == "1" assert norma.ano == 2016 assert norma.tipo == tipo @pytest.mark.django_db(transaction=False) def test_incluir_norma_errors(admin_client): - - response = admin_client.post(reverse('sapl.norma:normajuridica_create'), - {'salvar': 'salvar'}, - follow=True) - - assert (response.context_data['form'].errors['tipo'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['numero'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['ano'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['data'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['esfera_federacao'] == - [_('Este campo é obrigatório.')]) - assert (response.context_data['form'].errors['ementa'] == - [_('Este campo é obrigatório.')]) + response = admin_client.post( + reverse("sapl.norma:normajuridica_create"), {"salvar": "salvar"}, follow=True + ) + + assert response.context_data["form"].errors["tipo"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["numero"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["ano"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["data"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["esfera_federacao"] == [ + _("Este campo é obrigatório.") + ] + assert response.context_data["form"].errors["ementa"] == [ + _("Este campo é obrigatório.") + ] # TODO esse teste repete o teste acima (test_incluir_norma_errors) @@ -67,65 +74,69 @@ def test_norma_form_invalida(): errors = form.errors - assert errors['tipo'] == [_('Este campo é obrigatório.')] - assert errors['numero'] == [_('Este campo é obrigatório.')] - assert errors['ano'] == [_('Este campo é obrigatório.')] - assert errors['data'] == [_('Este campo é obrigatório.')] - assert errors['esfera_federacao'] == [_('Este campo é obrigatório.')] - assert errors['ementa'] == [_('Este campo é obrigatório.')] + assert errors["tipo"] == [_("Este campo é obrigatório.")] + assert errors["numero"] == [_("Este campo é obrigatório.")] + assert errors["ano"] == [_("Este campo é obrigatório.")] + assert errors["data"] == [_("Este campo é obrigatório.")] + assert errors["esfera_federacao"] == [_("Este campo é obrigatório.")] + assert errors["ementa"] == [_("Este campo é obrigatório.")] @pytest.mark.django_db(transaction=False) def test_norma_juridica_materia_inexistente(): - tipo = baker.make(TipoNormaJuridica) - tipo_materia = baker.make(TipoMateriaLegislativa, descricao='VETO') + tipo_materia = baker.make(TipoMateriaLegislativa, descricao="VETO") # cria uma matéria qualquer em 2017 pois, no teste, o campo ano_materia # está vazio - materia = baker.make(MateriaLegislativa, - tipo=tipo_materia, - ano=2017, - numero=1, - data_apresentacao='2017-03-05' - ) - - form = NormaJuridicaForm(data={'tipo': str(tipo.pk), - 'numero': '1', - 'ano': '2017', - 'data': '2017-12-12', - 'esfera_federacao': 'F', - 'ementa': 'teste norma', - 'tipo_materia': str(tipo_materia.pk), - 'numero_materia': '2', - 'ano_materia': '2017' - }) + materia = baker.make( + MateriaLegislativa, + tipo=tipo_materia, + ano=2017, + numero=1, + data_apresentacao="2017-03-05", + ) + + form = NormaJuridicaForm( + data={ + "tipo": str(tipo.pk), + "numero": "1", + "ano": "2017", + "data": "2017-12-12", + "esfera_federacao": "F", + "ementa": "teste norma", + "tipo_materia": str(tipo_materia.pk), + "numero_materia": "2", + "ano_materia": "2017", + } + ) assert not form.is_valid() - assert form.errors['__all__'] == [ - _("Matéria Legislativa 2/2017 (VETO) é inexistente.")] + assert form.errors["__all__"] == [ + _("Matéria Legislativa 2/2017 (VETO) é inexistente.") + ] @pytest.mark.django_db(transaction=False) def test_norma_juridica_materia_existente(): tipo = baker.make(TipoNormaJuridica) tipo_materia = baker.make(TipoMateriaLegislativa) - baker.make(MateriaLegislativa, - numero=2, - ano=2017, - tipo=tipo_materia) - - form = NormaJuridicaForm(data={'tipo': str(tipo.pk), - 'numero': '1', - 'ano': '2017', - 'data': '2017-12-12', - 'esfera_federacao': 'F', - 'ementa': 'teste norma', - 'tipo_materia': str(tipo_materia.pk), - 'numero_materia': '2', - 'ano_materia': '2017' - }) + baker.make(MateriaLegislativa, numero=2, ano=2017, tipo=tipo_materia) + + form = NormaJuridicaForm( + data={ + "tipo": str(tipo.pk), + "numero": "1", + "ano": "2017", + "data": "2017-12-12", + "esfera_federacao": "F", + "ementa": "teste norma", + "tipo_materia": str(tipo_materia.pk), + "numero_materia": "2", + "ano_materia": "2017", + } + ) assert form.is_valid() @@ -137,10 +148,10 @@ def test_norma_relacionada_form_campos_obrigatorios(): errors = form.errors - assert errors['tipo'] == [_('Este campo é obrigatório.')] - assert errors['numero'] == [_('Este campo é obrigatório.')] - assert errors['ano'] == [_('Este campo é obrigatório.')] - assert errors['tipo_vinculo'] == [_('Este campo é obrigatório.')] + assert errors["tipo"] == [_("Este campo é obrigatório.")] + assert errors["numero"] == [_("Este campo é obrigatório.")] + assert errors["ano"] == [_("Este campo é obrigatório.")] + assert errors["tipo_vinculo"] == [_("Este campo é obrigatório.")] assert len(errors) == 4 @@ -149,10 +160,14 @@ def test_norma_relacionada_form_campos_obrigatorios(): def test_norma_pesquisa_form_datas_invalidas(): tipo = baker.make(TipoNormaJuridica) - form = NormaPesquisaSimplesForm(data={'tipo_norma': str(tipo.pk), - 'data_inicial': '10/11/2017', - 'data_final': '09/11/2017' - }) + form = NormaPesquisaSimplesForm( + data={ + "tipo_norma": str(tipo.pk), + "data_inicial": "10/11/2017", + "data_final": "09/11/2017", + } + ) assert not form.is_valid() - assert form.errors['__all__'] == [_('A Data Final não pode ser menor que ' - 'a Data Inicial')] + assert form.errors["__all__"] == [ + _("A Data Final não pode ser menor que " "a Data Inicial") + ] diff --git a/sapl/norma/urls.py b/sapl/norma/urls.py index 1d59016da..cd8eeaec4 100644 --- a/sapl/norma/urls.py +++ b/sapl/norma/urls.py @@ -2,42 +2,42 @@ from django.conf import settings from django.urls import include, path, re_path from sapl.norma.views import (AnexoNormaJuridicaCrud, AssuntoNormaCrud, - NormaCrud, NormaPesquisaView, - NormaRelacionadaCrud, NormaTaView, TipoNormaCrud, + AutoriaNormaCrud, NormaCrud, NormaPesquisaView, + NormaRelacionadaCrud, NormaTaView, + PesquisarAssuntoNormaView, TipoNormaCrud, TipoVinculoNormaJuridicaCrud, recuperar_norma, - recuperar_numero_norma, AutoriaNormaCrud, - PesquisarAssuntoNormaView) - + recuperar_numero_norma) from .apps import AppConfig - app_name = AppConfig.name urlpatterns = [ - path('norma/', include(NormaCrud.get_urls() + - NormaRelacionadaCrud.get_urls() + - AnexoNormaJuridicaCrud.get_urls() + - AutoriaNormaCrud.get_urls())), - + path( + "norma/", + include( + NormaCrud.get_urls() + + NormaRelacionadaCrud.get_urls() + + AnexoNormaJuridicaCrud.get_urls() + + AutoriaNormaCrud.get_urls() + ), + ), # Integração com Compilação - path('norma//ta', NormaTaView.as_view(), name='norma_ta'), - path('sistema/norma/tipo/', include(TipoNormaCrud.get_urls())), - - path('sistema/norma/assunto/', include(AssuntoNormaCrud.get_urls())), + path("norma//ta", NormaTaView.as_view(), name="norma_ta"), + path("sistema/norma/tipo/", include(TipoNormaCrud.get_urls())), + path("sistema/norma/assunto/", include(AssuntoNormaCrud.get_urls())), re_path( - r'^sistema/norma/pesquisar-assunto-norma/', - PesquisarAssuntoNormaView.as_view(), name="pesquisar_assuntonorma" + r"^sistema/norma/pesquisar-assunto-norma/", + PesquisarAssuntoNormaView.as_view(), + name="pesquisar_assuntonorma", + ), + path("sistema/norma/vinculo/", include(TipoVinculoNormaJuridicaCrud.get_urls())), + path("norma/pesquisar", NormaPesquisaView.as_view(), name="norma_pesquisa"), + path("norma/recuperar-norma", recuperar_norma, name="recuperar_norma"), + path( + "norma/recuperar-numero-norma", + recuperar_numero_norma, + name="recuperar_numero_norma", ), - - path('sistema/norma/vinculo/', include( - TipoVinculoNormaJuridicaCrud.get_urls())), - - path('norma/pesquisar', - NormaPesquisaView.as_view(), name='norma_pesquisa'), - - path('norma/recuperar-norma', recuperar_norma, name="recuperar_norma"), - path('norma/recuperar-numero-norma', recuperar_numero_norma, - name="recuperar_numero_norma"), ] diff --git a/sapl/norma/views.py b/sapl/norma/views.py index 8df5b570c..73a1f146c 100644 --- a/sapl/norma/views.py +++ b/sapl/norma/views.py @@ -1,7 +1,8 @@ -from datetime import datetime import logging import re +from datetime import datetime +import weasyprint from django.contrib.auth.mixins import PermissionRequiredMixin from django.core.exceptions import ObjectDoesNotExist from django.db.models import Q @@ -17,33 +18,41 @@ from django.utils.translation import gettext_lazy as _ from django.views.generic import TemplateView, UpdateView from django.views.generic.edit import FormView from django_filters.views import FilterView -import weasyprint -from sapl import settings import sapl +from sapl import settings from sapl.base.models import AppConfig from sapl.compilacao.models import STATUS_TA_PUBLIC from sapl.compilacao.views import IntegracaoTaView from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, MasterDetailCrud, make_pagination) from sapl.materia.models import Orgao -from sapl.utils import show_results_filter_set, get_client_ip,\ - sapn_is_enabled, MultiFormatOutputMixin - -from .forms import (AnexoNormaJuridicaForm, NormaFilterSet, NormaJuridicaForm, - NormaPesquisaSimplesForm, NormaRelacionadaForm, - AutoriaNormaForm, AssuntoNormaFilterSet) -from .models import (AnexoNormaJuridica, AssuntoNorma, NormaJuridica, NormaRelacionada, - TipoNormaJuridica, TipoVinculoNormaJuridica, AutoriaNorma, NormaEstatisticas) +from sapl.utils import (MultiFormatOutputMixin, get_client_ip, sapn_is_enabled, + show_results_filter_set) +from .forms import (AnexoNormaJuridicaForm, AssuntoNormaFilterSet, + AutoriaNormaForm, NormaFilterSet, NormaJuridicaForm, + NormaPesquisaSimplesForm, NormaRelacionadaForm) +from .models import (AnexoNormaJuridica, AssuntoNorma, AutoriaNorma, + NormaEstatisticas, NormaJuridica, NormaRelacionada, + TipoNormaJuridica, TipoVinculoNormaJuridica) # LegislacaoCitadaCrud = Crud.build(LegislacaoCitada, '') TipoNormaCrud = CrudAux.build( - TipoNormaJuridica, 'tipo_norma_juridica', - list_field_names=['sigla', 'descricao', 'equivalente_lexml']) + TipoNormaJuridica, + "tipo_norma_juridica", + list_field_names=["sigla", "descricao", "equivalente_lexml"], +) TipoVinculoNormaJuridicaCrud = CrudAux.build( - TipoVinculoNormaJuridica, '', - list_field_names=['sigla', 'descricao_ativa', 'descricao_passiva', 'revoga_integralmente']) + TipoVinculoNormaJuridica, + "", + list_field_names=[ + "sigla", + "descricao_ativa", + "descricao_passiva", + "revoga_integralmente", + ], +) class AssuntoNormaCrud(CrudAux): @@ -54,7 +63,7 @@ class AssuntoNormaCrud(CrudAux): class DeleteView(CrudAux.DeleteView): def get_success_url(self): - return reverse('sapl.norma:pesquisar_assuntonorma') + return reverse("sapl.norma:pesquisar_assuntonorma") class PesquisarAssuntoNormaView(FilterView): @@ -63,30 +72,26 @@ class PesquisarAssuntoNormaView(FilterView): paginate_by = 20 def get_filterset_kwargs(self, filterset_class): - super(PesquisarAssuntoNormaView, self).get_filterset_kwargs( - filterset_class - ) + super(PesquisarAssuntoNormaView, self).get_filterset_kwargs(filterset_class) - return ({ + return { "data": self.request.GET or None, - "queryset": self.get_queryset().order_by("assunto").distinct() - }) + "queryset": self.get_queryset().order_by("assunto").distinct(), + } def get_context_data(self, **kwargs): - context = super(PesquisarAssuntoNormaView, self).get_context_data( - **kwargs - ) + context = super(PesquisarAssuntoNormaView, self).get_context_data(**kwargs) paginator = context["paginator"] page_obj = context["page_obj"] - context.update({ - "page_range": make_pagination( - page_obj.number, paginator.num_pages - ), - "NO_ENTRIES_MSG": "Nenhum assunto de norma jurídica encontrado!", - "title": _("Assunto de Norma Jurídica") - }) + context.update( + { + "page_range": make_pagination(page_obj.number, paginator.num_pages), + "NO_ENTRIES_MSG": "Nenhum assunto de norma jurídica encontrado!", + "title": _("Assunto de Norma Jurídica"), + } + ) return context @@ -95,38 +100,40 @@ class PesquisarAssuntoNormaView(FilterView): data = self.filterset.data - url = '' + url = "" if data: - url = '&' + str(self.request.META["QUERY_STRING"]) + url = "&" + str(self.request.META["QUERY_STRING"]) if url.startswith("&page"): - url = '' + url = "" - if 'assunto' in self.request.META['QUERY_STRING'] or\ - 'page' in self.request.META['QUERY_STRING']: + if ( + "assunto" in self.request.META["QUERY_STRING"] + or "page" in self.request.META["QUERY_STRING"] + ): resultados = self.object_list else: resultados = [] - context = self.get_context_data(filter=self.filterset, - object_list=resultados, - filter_url=url, - numero_res=len(resultados) - ) + context = self.get_context_data( + filter=self.filterset, + object_list=resultados, + filter_url=url, + numero_res=len(resultados), + ) - context['show_results'] = show_results_filter_set( - self.request.GET.copy()) + context["show_results"] = show_results_filter_set(self.request.GET.copy()) return self.render_to_response(context) class NormaRelacionadaCrud(MasterDetailCrud): model = NormaRelacionada - parent_field = 'norma_principal' - help_topic = 'norma_juridica' + parent_field = "norma_principal" + help_topic = "norma_juridica" class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['norma_relacionada', 'tipo_vinculo', 'resujmo'] + list_field_names = ["norma_relacionada", "tipo_vinculo", "resujmo"] class CreateView(MasterDetailCrud.CreateView): form_class = NormaRelacionadaForm @@ -136,15 +143,14 @@ class NormaRelacionadaCrud(MasterDetailCrud): def get_initial(self): initial = super(UpdateView, self).get_initial() - initial['tipo'] = self.object.norma_relacionada.tipo.id - initial['numero'] = self.object.norma_relacionada.numero - initial['ano'] = self.object.norma_relacionada.ano - initial['ementa'] = self.object.norma_relacionada.ementa + initial["tipo"] = self.object.norma_relacionada.tipo.id + initial["numero"] = self.object.norma_relacionada.numero + initial["ano"] = self.object.norma_relacionada.ano + initial["ementa"] = self.object.norma_relacionada.ementa return initial class DetailView(MasterDetailCrud.DetailView): - - layout_key = 'NormaRelacionadaDetail' + layout_key = "NormaRelacionadaDetail" class NormaPesquisaView(MultiFormatOutputMixin, FilterView): @@ -153,110 +159,116 @@ class NormaPesquisaView(MultiFormatOutputMixin, FilterView): paginate_by = 50 fields_base_report = [ - 'id', 'ano', 'numero', 'tipo__sigla', 'tipo__descricao', 'texto_integral', 'ementa' + "id", + "ano", + "numero", + "tipo__sigla", + "tipo__descricao", + "texto_integral", + "ementa", ] fields_report = { - 'csv': fields_base_report, - 'xlsx': fields_base_report, - 'json': fields_base_report, + "csv": fields_base_report, + "xlsx": fields_base_report, + "json": fields_base_report, } def hook_texto_integral(self, obj): - url = self.request.build_absolute_uri('/')[:-1] - texto_integral = obj.texto_integral if not isinstance( - obj, dict) else obj["texto_integral"] + url = self.request.build_absolute_uri("/")[:-1] + texto_integral = ( + obj.texto_integral if not isinstance(obj, dict) else obj["texto_integral"] + ) - return f'{url}/media/{texto_integral}' + return f"{url}/media/{texto_integral}" def get_queryset(self): qs = super().get_queryset() - qs = qs.extra({ - 'nm_i': "CAST(regexp_replace(numero,'[^0-9]','', 'g') AS INTEGER)", - 'norma_letra': "regexp_replace(numero,'[^a-zA-Z]','', 'g')" - }).order_by('-data', '-nm_i', 'norma_letra') + qs = qs.extra( + { + "nm_i": "CAST(regexp_replace(numero,'[^0-9]','', 'g') AS INTEGER)", + "norma_letra": "regexp_replace(numero,'[^a-zA-Z]','', 'g')", + } + ).order_by("-data", "-nm_i", "norma_letra") return qs def get_context_data(self, **kwargs): context = super(NormaPesquisaView, self).get_context_data(**kwargs) - context['title'] = _('Pesquisar Norma Jurídica') + context["title"] = _("Pesquisar Norma Jurídica") - self.filterset.form.fields['o'].label = _('Ordenação') + self.filterset.form.fields["o"].label = _("Ordenação") qs = self.object_list - if 'o' in self.request.GET and not self.request.GET['o']: - qs = qs.order_by('-ano', 'tipo', '-numero') + if "o" in self.request.GET and not self.request.GET["o"]: + qs = qs.order_by("-ano", "tipo", "-numero") qr = self.request.GET.copy() - if 'page' in qr: - del qr['page'] + if "page" in qr: + del qr["page"] - paginator = context['paginator'] - page_obj = context['page_obj'] + paginator = context["paginator"] + page_obj = context["page_obj"] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" - context['show_results'] = show_results_filter_set(qr) + context["show_results"] = show_results_filter_set(qr) return context class AnexoNormaJuridicaCrud(MasterDetailCrud): model = AnexoNormaJuridica - parent_field = 'norma' - help_topic = 'anexonormajuridica' + parent_field = "norma" + help_topic = "anexonormajuridica" public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['id', 'anexo_arquivo', 'assunto_anexo'] + list_field_names = ["id", "anexo_arquivo", "assunto_anexo"] class CreateView(MasterDetailCrud.CreateView): form_class = AnexoNormaJuridicaForm - layout_key = 'AnexoNormaJuridica' + layout_key = "AnexoNormaJuridica" def get_initial(self): initial = super(MasterDetailCrud.CreateView, self).get_initial() - initial['norma'] = NormaJuridica.objects.get(id=self.kwargs['pk']) + initial["norma"] = NormaJuridica.objects.get(id=self.kwargs["pk"]) return initial class UpdateView(MasterDetailCrud.UpdateView): form_class = AnexoNormaJuridicaForm - layout_key = 'AnexoNormaJuridica' + layout_key = "AnexoNormaJuridica" def get_initial(self): initial = super(UpdateView, self).get_initial() - initial['norma'] = self.object.norma - initial['anexo_arquivo'] = self.object.anexo_arquivo - initial['assunto_anexo'] = self.object.assunto_anexo - initial['ano'] = self.object.ano + initial["norma"] = self.object.norma + initial["anexo_arquivo"] = self.object.anexo_arquivo + initial["assunto_anexo"] = self.object.assunto_anexo + initial["ano"] = self.object.ano return initial class DetailView(MasterDetailCrud.DetailView): form_class = AnexoNormaJuridicaForm - layout_key = 'AnexoNormaJuridica' + layout_key = "AnexoNormaJuridica" class NormaTaView(IntegracaoTaView): model = NormaJuridica model_type_foreignkey = TipoNormaJuridica map_fields = { - 'data': 'data', - 'ementa': 'ementa', - 'observacao': 'observacao', - 'numero': 'numero', - 'ano': 'ano', - 'tipo': 'tipo', + "data": "data", + "ementa": "ementa", + "observacao": "observacao", + "numero": "numero", + "ano": "ano", + "tipo": "tipo", } - map_funcs = { - 'publicacao_func': True - } + map_funcs = {"publicacao_func": True} def get(self, request, *args, **kwargs): """ @@ -264,7 +276,7 @@ class NormaTaView(IntegracaoTaView): este get foi implementado para tratar uma prerrogativa externa de usuário. """ - if AppConfig.attr('texto_articulado_norma'): + if AppConfig.attr("texto_articulado_norma"): return IntegracaoTaView.get(self, request, *args, **kwargs) else: return self.get_redirect_deactivated() @@ -272,39 +284,46 @@ class NormaTaView(IntegracaoTaView): class NormaCrud(Crud): model = NormaJuridica - help_topic = 'norma_juridica' + help_topic = "norma_juridica" public = [RP_LIST, RP_DETAIL] class BaseMixin(Crud.BaseMixin): - list_field_names = ['epigrafe', 'ementa'] + list_field_names = ["epigrafe", "ementa"] - list_url = '' + list_url = "" @property def search_url(self): namespace = self.model._meta.app_config.name - return reverse('%s:%s' % (namespace, 'norma_pesquisa')) + return reverse("%s:%s" % (namespace, "norma_pesquisa")) class DetailView(Crud.DetailView): def get(self, request, *args, **kwargs): - estatisticas_acesso_normas = AppConfig.objects.first().estatisticas_acesso_normas - if estatisticas_acesso_normas == 'S' and \ - NormaJuridica.objects.filter(id=kwargs['pk']).exists(): - NormaEstatisticas.objects.create(usuario=str(self.request.user), - norma_id=kwargs['pk'], - ano=timezone.now().year, - horario_acesso=timezone.now()) - - if 'display' not in request.GET and \ - not request.user.has_perm('norma.change_normajuridica'): + estatisticas_acesso_normas = ( + AppConfig.objects.first().estatisticas_acesso_normas + ) + if ( + estatisticas_acesso_normas == "S" + and NormaJuridica.objects.filter(id=kwargs["pk"]).exists() + ): + NormaEstatisticas.objects.create( + usuario=str(self.request.user), + norma_id=kwargs["pk"], + ano=timezone.now().year, + horario_acesso=timezone.now(), + ) + + if "display" not in request.GET and not request.user.has_perm( + "norma.change_normajuridica" + ): ta = self.get_object().texto_articulado.first() if ta and ta.privacidade == STATUS_TA_PUBLIC: - return redirect(reverse('sapl.norma:norma_ta', - kwargs={'pk': self.kwargs['pk']})) + return redirect( + reverse("sapl.norma:norma_ta", kwargs={"pk": self.kwargs["pk"]}) + ) return super().get(request, *args, **kwargs) class DeleteView(Crud.DeleteView): - def get_success_url(self): return self.search_url @@ -320,95 +339,102 @@ class NormaCrud(Crud): def get_initial(self): initial = super().get_initial() - initial['user'] = self.request.user - initial['ip'] = get_client_ip(self.request) + initial["user"] = self.request.user + initial["ip"] = get_client_ip(self.request) from django.utils import timezone - initial['ultima_edicao'] = timezone.now() + + initial["ultima_edicao"] = timezone.now() username = self.request.user.username try: self.logger.debug( - 'user=' + username + '. Tentando obter objeto de modelo da esfera da federação.') - esfera = sapl.base.models.AppConfig.objects.last( - ).esfera_federacao - initial['esfera_federacao'] = esfera + "user=" + + username + + ". Tentando obter objeto de modelo da esfera da federação." + ) + esfera = sapl.base.models.AppConfig.objects.last().esfera_federacao + initial["esfera_federacao"] = esfera except: self.logger.error( - 'user=' + username + '. Erro ao obter objeto de modelo da esfera da federação.') + "user=" + + username + + ". Erro ao obter objeto de modelo da esfera da federação." + ) pass - initial['complemento'] = False + initial["complemento"] = False return initial - layout_key = 'NormaJuridicaCreate' + layout_key = "NormaJuridicaCreate" class ListView(Crud.ListView): - def get(self, request, *args, **kwargs): - if AppConfig.attr('texto_articulado_norma'): - self.status = self.request.GET.get('status', '') + if AppConfig.attr("texto_articulado_norma"): + self.status = self.request.GET.get("status", "") return Crud.ListView.get(self, request, *args, **kwargs) else: url = self.get_redirect_url(*args, **kwargs) return HttpResponseRedirect(url) def hook_header_epigrafe(self, *args, **kwargs): - return force_str(_('Epigrafe')) + return force_str(_("Epigrafe")) def hook_epigrafe(self, obj, ss, url): - return obj.epigrafe, reverse_lazy( - 'sapl.norma:norma_ta', - kwargs={'pk': obj.id}) + "sapl.norma:norma_ta", kwargs={"pk": obj.id} + ) def get_redirect_url(self, *args, **kwargs): namespace = self.model._meta.app_config.name - return reverse('%s:%s' % (namespace, 'norma_pesquisa')) + return reverse("%s:%s" % (namespace, "norma_pesquisa")) def get_queryset(self): - if self.status == 'pendente': + if self.status == "pendente": qs = NormaJuridica.objects.normas_com_textos_articulados_pendentes() - elif self.status == 'publico': + elif self.status == "publico": qs = NormaJuridica.objects.normas_com_textos_articulados_publicados() else: qs = NormaJuridica.objects.normas_sem_textos_articulados() - return qs.order_by('-texto_articulado__privacidade', '-ano', '-numero') + return qs.order_by("-texto_articulado__privacidade", "-ano", "-numero") def get_context_data(self, **kwargs): context = Crud.ListView.get_context_data(self, **kwargs) - if self.status == 'pendente': - context['title'] = 'Normas Jurídicas com Textos Articulados não publicados' - elif self.status == 'publico': - context['title'] = 'Normas Jurídicas com Textos Articulados publicados' + if self.status == "pendente": + context[ + "title" + ] = "Normas Jurídicas com Textos Articulados não publicados" + elif self.status == "publico": + context["title"] = "Normas Jurídicas com Textos Articulados publicados" else: - context['title'] = 'Normas Jurídicas sem Textos Articulados' + context["title"] = "Normas Jurídicas sem Textos Articulados" return context @classmethod def get_url_regex(cls): - return r'^check_compilacao$' + return r"^check_compilacao$" class UpdateView(Crud.UpdateView): form_class = NormaJuridicaForm - layout_key = 'NormaJuridicaCreate' + layout_key = "NormaJuridicaCreate" def get_initial(self): initial = super().get_initial() - norma = NormaJuridica.objects.select_related( - "materia").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 - initial['numero_materia'] = norma.materia.numero - initial['esfera_federacao'] = norma.esfera_federacao + initial["tipo_materia"] = norma.materia.tipo + initial["ano_materia"] = norma.materia.ano + initial["numero_materia"] = norma.materia.numero + initial["esfera_federacao"] = norma.esfera_federacao 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 @@ -418,12 +444,25 @@ class NormaCrud(Crud): self.object = form.save() dict_objeto_novo = self.object.__dict__ - atributos = ['tipo_id', 'numero', 'ano', 'data', 'esfera_federacao', - 'complemento', 'materia_id', 'numero', - 'data_publicacao', 'data_vigencia', - 'veiculo_publicacao', 'pagina_inicio_publicacao', - 'pagina_fim_publicacao', 'ementa', 'indexacao', - 'observacao', 'texto_integral'] + atributos = [ + "tipo_id", + "numero", + "ano", + "data", + "esfera_federacao", + "complemento", + "materia_id", + "numero", + "data_publicacao", + "data_vigencia", + "veiculo_publicacao", + "pagina_inicio_publicacao", + "pagina_fim_publicacao", + "ementa", + "indexacao", + "observacao", + "texto_integral", + ] for atributo in atributos: if dict_objeto_antigo[atributo] != dict_objeto_novo[atributo]: @@ -431,6 +470,7 @@ class NormaCrud(Crud): self.object.ip = get_client_ip(self.request) from django.utils import timezone + self.object.ultima_edicao = timezone.now() self.object.save() break @@ -443,6 +483,7 @@ class NormaCrud(Crud): self.object.ip = get_client_ip(self.request) from django.utils import timezone + self.object.ultima_edicao = timezone.now() self.object.save() @@ -455,61 +496,70 @@ def recuperar_norma(request): username = request.user.username orgao = None - if 'orgao' in request.GET and request.GET['orgao']: - orgao = Orgao.objects.get(pk=request.GET['orgao']) + if "orgao" in request.GET and request.GET["orgao"]: + orgao = Orgao.objects.get(pk=request.GET["orgao"]) - tipo = TipoNormaJuridica.objects.get(pk=request.GET['tipo']) - numero = request.GET['numero'] - ano = request.GET['ano'] + tipo = TipoNormaJuridica.objects.get(pk=request.GET["tipo"]) + numero = request.GET["numero"] + ano = request.GET["ano"] try: - logger.info('user=' + username + '. Tentando obter NormaJuridica (tipo={}, ano={}, numero={}).' - .format(tipo, ano, numero)) - norma = NormaJuridica.objects.get(tipo=tipo, - ano=ano, - numero=numero, - orgao=orgao) - response = JsonResponse({'ementa': norma.ementa, - 'id': norma.id}) + logger.info( + "user=" + + username + + ". Tentando obter NormaJuridica (tipo={}, ano={}, numero={}).".format( + tipo, ano, numero + ) + ) + norma = NormaJuridica.objects.get( + tipo=tipo, ano=ano, numero=numero, orgao=orgao + ) + response = JsonResponse({"ementa": norma.ementa, "id": norma.id}) except ObjectDoesNotExist: - 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}) + 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}) return response def recuperar_numero_norma(request): - tipo = TipoNormaJuridica.objects.get(pk=request.GET['tipo']) - ano = request.GET.get('ano', '') - orgao = request.GET.get('orgao', '') + tipo = TipoNormaJuridica.objects.get(pk=request.GET["tipo"]) + ano = request.GET.get("ano", "") + orgao = request.GET.get("orgao", "") - param = {'tipo': tipo, - 'ano': ano if ano else timezone.now().year, - } + param = { + "tipo": tipo, + "ano": ano if ano else timezone.now().year, + } if orgao: - param['orgao'] = Orgao.objects.get(pk=orgao) + param["orgao"] = Orgao.objects.get(pk=orgao) - norma = NormaJuridica.objects.filter(**param).order_by( - 'tipo', 'ano', 'numero').values_list('numero', flat=True) + norma = ( + NormaJuridica.objects.filter(**param) + .order_by("tipo", "ano", "numero") + .values_list("numero", flat=True) + ) if norma: - numeros = sorted([int(re.sub(r"[^0-9].*", '', n)) for n in norma]) + numeros = sorted([int(re.sub(r"[^0-9].*", "", n)) for n in norma]) next_num = numeros.pop() + 1 - response = JsonResponse({'numero': next_num, - 'ano': param['ano']}) + response = JsonResponse({"numero": next_num, "ano": param["ano"]}) else: - response = JsonResponse( - {'numero': 1, 'ano': param['ano']}) + response = JsonResponse({"numero": 1, "ano": param["ano"]}) return response class AutoriaNormaCrud(MasterDetailCrud): model = AutoriaNorma - parent_field = 'norma' - help_topic = 'despacho_autoria' + parent_field = "norma" + help_topic = "despacho_autoria" public = [RP_LIST, RP_DETAIL] - list_field_names = ['autor', 'autor__tipo__descricao', 'primeiro_autor'] + list_field_names = ["autor", "autor__tipo__descricao", "primeiro_autor"] class LocalBaseMixin: form_class = AutoriaNormaForm @@ -519,69 +569,71 @@ class AutoriaNormaCrud(MasterDetailCrud): return None class CreateView(LocalBaseMixin, MasterDetailCrud.CreateView): - def get_initial(self): initial = super().get_initial() - norma = NormaJuridica.objects.get(id=self.kwargs['pk']) - initial['data_relativa'] = norma.data - initial['autor'] = [] + norma = NormaJuridica.objects.get(id=self.kwargs["pk"]) + initial["data_relativa"] = norma.data + initial["autor"] = [] return initial class UpdateView(LocalBaseMixin, MasterDetailCrud.UpdateView): - def get_initial(self): initial = super().get_initial() - initial.update({ - 'data_relativa': self.object.norma.data, - 'tipo_autor': self.object.autor.tipo.id, - }) + initial.update( + { + "data_relativa": self.object.norma.data, + "tipo_autor": self.object.autor.tipo.id, + } + ) return initial class ImpressosView(PermissionRequiredMixin, TemplateView): - template_name = 'materia/impressos/impressos.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos.html" + permission_required = ("materia.can_access_impressos",) def gerar_pdf_impressos(request, context, template_name): template = loader.get_template(template_name) html = template.render(context, request) pdf = weasyprint.HTML( - string=html, base_url=request.build_absolute_uri()).write_pdf() + string=html, base_url=request.build_absolute_uri() + ).write_pdf() - response = HttpResponse(pdf, content_type='application/pdf') - response['Content-Disposition'] = 'inline; filename="relatorio_impressos.pdf"' - response['Content-Transfer-Encoding'] = 'binary' + response = HttpResponse(pdf, content_type="application/pdf") + response["Content-Disposition"] = 'inline; filename="relatorio_impressos.pdf"' + response["Content-Transfer-Encoding"] = "binary" return response class NormaPesquisaSimplesView(PermissionRequiredMixin, FormView): form_class = NormaPesquisaSimplesForm - template_name = 'materia/impressos/impressos_form.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos_form.html" + permission_required = ("materia.can_access_impressos",) def form_valid(self, form): - template_norma = 'materia/impressos/normas_pdf.html' + template_norma = "materia/impressos/normas_pdf.html" - titulo = form.cleaned_data['titulo'] + titulo = form.cleaned_data["titulo"] kwargs = {} - if form.cleaned_data.get('tipo_norma'): - kwargs.update({'tipo': form.cleaned_data['tipo_norma']}) + if form.cleaned_data.get("tipo_norma"): + kwargs.update({"tipo": form.cleaned_data["tipo_norma"]}) - if form.cleaned_data.get('data_inicial'): - kwargs.update({'data__gte': form.cleaned_data['data_inicial'], - 'data__lte': form.cleaned_data['data_final']}) + if form.cleaned_data.get("data_inicial"): + kwargs.update( + { + "data__gte": form.cleaned_data["data_inicial"], + "data__lte": form.cleaned_data["data_final"], + } + ) - normas = NormaJuridica.objects.filter( - **kwargs).order_by('-numero', 'ano') + normas = NormaJuridica.objects.filter(**kwargs).order_by("-numero", "ano") quantidade_normas = normas.count() normas = normas[:2000] if quantidade_normas > 2000 else normas - context = {'quantidade': quantidade_normas, - 'titulo': titulo, - 'normas': normas} + context = {"quantidade": quantidade_normas, "titulo": titulo, "normas": normas} return gerar_pdf_impressos(self.request, context, template_norma) diff --git a/sapl/painel/apps.py b/sapl/painel/apps.py index e44c55f55..8b4498976 100644 --- a/sapl/painel/apps.py +++ b/sapl/painel/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.painel' - label = 'painel' - verbose_name = _('Painel Eletrônico') + name = "sapl.painel" + label = "painel" + verbose_name = _("Painel Eletrônico") diff --git a/sapl/painel/models.py b/sapl/painel/models.py index fb3de6a2b..b36f8f0c9 100644 --- a/sapl/painel/models.py +++ b/sapl/painel/models.py @@ -4,19 +4,18 @@ from django.utils.translation import gettext_lazy as _ class Painel(models.Model): PAINEL_TYPES = ( - ('C', 'Completo'), - ('P', 'Parlamentares'), - ('V', 'Votação'), - ('M', 'Mensagem'), + ("C", "Completo"), + ("P", "Parlamentares"), + ("V", "Votação"), + ("M", "Mensagem"), ) - aberto = models.BooleanField(verbose_name=_('Abrir painel'), default=False) - data_painel = models.DateField(verbose_name=_('Data painel')) - mostrar = models.CharField(max_length=1, - choices=PAINEL_TYPES, default='C') + aberto = models.BooleanField(verbose_name=_("Abrir painel"), default=False) + data_painel = models.DateField(verbose_name=_("Data painel")) + mostrar = models.CharField(max_length=1, choices=PAINEL_TYPES, default="C") class Meta: - ordering = ('-data_painel',) + ordering = ("-data_painel",) def __str__(self): return str(self.aberto) + ":" + self.data_painel.strftime("%d/%m/%Y") @@ -24,27 +23,28 @@ class Painel(models.Model): class Cronometro(models.Model): CRONOMETRO_TYPES = ( - ('A', _('Aparte')), - ('D', _('Discurso')), - ('O', _('Ordem do dia')), - ('C', _('Considerações finais')) + ("A", _("Aparte")), + ("D", _("Discurso")), + ("O", _("Ordem do dia")), + ("C", _("Considerações finais")), ) CRONOMETRO_STATUS = ( - ('I', 'Start'), - ('R', 'Reset'), - ('S', 'Stop'), + ("I", "Start"), + ("R", "Reset"), + ("S", "Stop"), ) status = models.CharField( max_length=1, - verbose_name=_('Status do cronômetro'), + verbose_name=_("Status do cronômetro"), choices=CRONOMETRO_STATUS, - default='S') - data_cronometro = models.DateField(verbose_name=_('Data do cronômetro')) + default="S", + ) + data_cronometro = models.DateField(verbose_name=_("Data do cronômetro")) tipo = models.CharField( - max_length=1, choices=CRONOMETRO_TYPES, - verbose_name=_('Tipo Cronômetro')) + max_length=1, choices=CRONOMETRO_TYPES, verbose_name=_("Tipo Cronômetro") + ) class Meta: - ordering = ('-data_cronometro',) \ No newline at end of file + ordering = ("-data_cronometro",) diff --git a/sapl/painel/urls.py b/sapl/painel/urls.py index 37a706489..e838f8703 100644 --- a/sapl/painel/urls.py +++ b/sapl/painel/urls.py @@ -8,20 +8,14 @@ from .views import (cronometro_painel, get_dados_painel, painel_mensagem_view, app_name = AppConfig.name urlpatterns = [ - path('painel-principal/', painel_view, - name="painel_principal"), - path('painel//dados', get_dados_painel, name='dados_painel'), - path('painel/mensagem', painel_mensagem_view, name="painel_mensagem"), - path('painel/parlamentar', painel_parlamentar_view, - name='painel_parlamentar'), - path('painel/switch-painel', switch_painel, - name="switch_painel"), - path('painel/votacao', painel_votacao_view, name='painel_votacao'), - path('painel/verifica-painel', verifica_painel, - name="verifica_painel"), - path('painel/cronometro', cronometro_painel, name='cronometro_painel'), + path("painel-principal/", painel_view, name="painel_principal"), + path("painel//dados", get_dados_painel, name="dados_painel"), + path("painel/mensagem", painel_mensagem_view, name="painel_mensagem"), + path("painel/parlamentar", painel_parlamentar_view, name="painel_parlamentar"), + path("painel/switch-painel", switch_painel, name="switch_painel"), + path("painel/votacao", painel_votacao_view, name="painel_votacao"), + path("painel/verifica-painel", verifica_painel, name="verifica_painel"), + path("painel/cronometro", cronometro_painel, name="cronometro_painel"), # url(r'^painel/cronometro$', include(CronometroPainelCrud.get_urls())), - - path('voto-individual/', votante_view, - name='voto_individual'), + path("voto-individual/", votante_view, name="voto_individual"), ] diff --git a/sapl/painel/views.py b/sapl/painel/views.py index 2345175a5..0c0eb2e80 100644 --- a/sapl/painel/views.py +++ b/sapl/painel/views.py @@ -5,11 +5,11 @@ import logging from django.contrib import messages from django.contrib.auth.decorators import user_passes_test from django.core.exceptions import ObjectDoesNotExist -from django.urls import reverse from django.db.models import Q from django.http import HttpResponse, JsonResponse from django.http.response import Http404, HttpResponseRedirect from django.shortcuts import render +from django.urls import reverse from django.utils import timezone from django.utils.translation import gettext_lazy as _ @@ -19,16 +19,16 @@ from sapl.crud.base import Crud from sapl.painel.apps import AppConfig from sapl.parlamentares.models import Legislatura, Parlamentar, Votante from sapl.sessao.models import (ExpedienteMateria, OradorExpediente, OrdemDia, - PresencaOrdemDia, RegistroVotacao, - SessaoPlenaria, SessaoPlenariaPresenca, - VotoParlamentar, RegistroLeitura) + PresencaOrdemDia, RegistroLeitura, + RegistroVotacao, SessaoPlenaria, + SessaoPlenariaPresenca, VotoParlamentar) from sapl.utils import filiacao_data, get_client_ip, sort_lista_chave from .models import Cronometro VOTACAO_NOMINAL = 2 -CronometroPainelCrud = Crud.build(Cronometro, '') +CronometroPainelCrud = Crud.build(Cronometro, "") # FIXME mudar lógica @@ -38,253 +38,352 @@ def check_permission(user): def votacao_aberta(request): - ''' + """ Função que verifica se há somente 1 uma matéria aberta ou nenhuma. É utilizada como uma função auxiliar para a view votante_view. - ''' + """ logger = logging.getLogger(__name__) username = request.user.username votacoes_abertas = SessaoPlenaria.objects.filter( - Q(ordemdia__votacao_aberta=True) | - Q(expedientemateria__votacao_aberta=True)).distinct() + Q(ordemdia__votacao_aberta=True) | Q(expedientemateria__votacao_aberta=True) + ).distinct() if len(votacoes_abertas) > 1: msg_abertas = [] for v in votacoes_abertas: - msg_abertas.append('''
      • %s
      • ''' % ( - reverse('sapl.sessao:sessaoplenaria_detail', - kwargs={'pk': v.id}), - v.__str__())) - logger.info('user=' + username + '. Existe mais de uma votações aberta. Elas se encontram ' - 'nas seguintes Sessões: ' + ', '.join(msg_abertas) + '. ' - 'Para votar, peça para que o Operador feche-as.') - msg = _('Existe mais de uma votações aberta. Elas se encontram ' - 'nas seguintes Sessões: ' + ', '.join(msg_abertas) + '. ' - 'Para votar, peça para que o Operador feche-as.') + msg_abertas.append( + """
      • %s
      • """ + % ( + reverse("sapl.sessao:sessaoplenaria_detail", kwargs={"pk": v.id}), + v.__str__(), + ) + ) + logger.info( + "user=" + + username + + ". Existe mais de uma votações aberta. Elas se encontram " + "nas seguintes Sessões: " + ", ".join(msg_abertas) + ". " + "Para votar, peça para que o Operador feche-as." + ) + msg = _( + "Existe mais de uma votações aberta. Elas se encontram " + "nas seguintes Sessões: " + ", ".join(msg_abertas) + ". " + "Para votar, peça para que o Operador feche-as." + ) messages.add_message(request, messages.INFO, msg) return None, msg elif len(votacoes_abertas) == 1: ordens = OrdemDia.objects.filter( - sessao_plenaria=votacoes_abertas.first(), - votacao_aberta=True) + sessao_plenaria=votacoes_abertas.first(), votacao_aberta=True + ) expedientes = ExpedienteMateria.objects.filter( - sessao_plenaria=votacoes_abertas.first(), - votacao_aberta=True) + sessao_plenaria=votacoes_abertas.first(), votacao_aberta=True + ) numero_materias_abertas = len(ordens) + len(expedientes) if numero_materias_abertas > 1: - logger.info('user=' + username + '. Existe mais de uma votação aberta na Sessão: ' + - ('''
      • %s
      • ''' % ( - reverse('sapl.sessao:sessaoplenaria_detail', - kwargs={'pk': votacoes_abertas.first().id}), - votacoes_abertas.first().__str__()))) - msg = _('Existe mais de uma votação aberta na Sessão: ' + - ('''
      • %s
      • ''' % ( - reverse('sapl.sessao:sessaoplenaria_detail', - kwargs={'pk': votacoes_abertas.first().id}), - votacoes_abertas.first().__str__())) + - 'Para votar, peça para que o Operador as feche.') + logger.info( + "user=" + + username + + ". Existe mais de uma votação aberta na Sessão: " + + ( + """
      • %s
      • """ + % ( + reverse( + "sapl.sessao:sessaoplenaria_detail", + kwargs={"pk": votacoes_abertas.first().id}, + ), + votacoes_abertas.first().__str__(), + ) + ) + ) + msg = _( + "Existe mais de uma votação aberta na Sessão: " + + ( + """
      • %s
      • """ + % ( + reverse( + "sapl.sessao:sessaoplenaria_detail", + kwargs={"pk": votacoes_abertas.first().id}, + ), + votacoes_abertas.first().__str__(), + ) + ) + + "Para votar, peça para que o Operador as feche." + ) messages.add_message(request, messages.INFO, msg) return None, msg return votacoes_abertas.first(), None -def votacao(context,context_vars): +def votacao(context, context_vars): logger = logging.getLogger(__name__) - parlamentar = context_vars['votante'].parlamentar + parlamentar = context_vars["votante"].parlamentar parlamentar_presente = False - if parlamentar.id in context_vars['presentes']: + if parlamentar.id in context_vars["presentes"]: parlamentar_presente = True - context_vars.update({'parlamentar': parlamentar}) + context_vars.update({"parlamentar": parlamentar}) else: - context.update({'error_message': - 'Não há presentes na Sessão com a ' - 'matéria em votação.'}) + context.update( + {"error_message": "Não há presentes na Sessão com a " "matéria em votação."} + ) if parlamentar_presente: voto = [] - if context_vars['ordem_dia']: - voto = VotoParlamentar.objects.filter( - ordem=context_vars['ordem_dia']) - elif context_vars['expediente']: - voto = VotoParlamentar.objects.filter( - expediente=context_vars['expediente']) + if context_vars["ordem_dia"]: + voto = VotoParlamentar.objects.filter(ordem=context_vars["ordem_dia"]) + elif context_vars["expediente"]: + voto = VotoParlamentar.objects.filter(expediente=context_vars["expediente"]) if voto: try: - logger.debug("Tentando obter objeto VotoParlamentar com parlamentar={}.".format(context_vars['parlamentar'])) - voto = voto.get(parlamentar=context_vars['parlamentar']) - context.update({'voto_parlamentar': voto.voto}) + logger.debug( + "Tentando obter objeto VotoParlamentar com parlamentar={}.".format( + context_vars["parlamentar"] + ) + ) + voto = voto.get(parlamentar=context_vars["parlamentar"]) + context.update({"voto_parlamentar": voto.voto}) except ObjectDoesNotExist: - logger.error("Voto do parlamentar {} não computado.".format(context_vars['parlamentar'])) - context.update( - {'voto_parlamentar': 'Voto não ' - 'computado.'}) + logger.error( + "Voto do parlamentar {} não computado.".format( + context_vars["parlamentar"] + ) + ) + context.update({"voto_parlamentar": "Voto não " "computado."}) else: - logger.error("Parlamentar com id={} não está presente na " - "Ordem do Dia/Expediente em votação.".format(parlamentar.id)) - context.update({'error_message': - 'Você não está presente na ' - 'Ordem do Dia/Expediente em votação.'}) + logger.error( + "Parlamentar com id={} não está presente na " + "Ordem do Dia/Expediente em votação.".format(parlamentar.id) + ) + context.update( + { + "error_message": "Você não está presente na " + "Ordem do Dia/Expediente em votação." + } + ) return context, context_vars -def sessao_votacao(context,context_vars): - pk = context_vars['sessao'].pk - context.update({'sessao_id': pk}) - context.update({'sessao': context_vars['sessao'], - 'data': context_vars['sessao'].data_inicio, - 'hora': context_vars['sessao'].hora_inicio}) + +def sessao_votacao(context, context_vars): + pk = context_vars["sessao"].pk + context.update({"sessao_id": pk}) + context.update( + { + "sessao": context_vars["sessao"], + "data": context_vars["sessao"].data_inicio, + "hora": context_vars["sessao"].hora_inicio, + } + ) # Inicializa presentes presentes = [] ordem_dia = get_materia_aberta(pk) expediente = get_materia_expediente_aberta(pk) - errors_msgs = {'materia':'Não há nenhuma matéria aberta.', - 'registro':'A votação para esta matéria já encerrou.', - 'tipo':'A matéria aberta não é do tipo votação nominal.'} + errors_msgs = { + "materia": "Não há nenhuma matéria aberta.", + "registro": "A votação para esta matéria já encerrou.", + "tipo": "A matéria aberta não é do tipo votação nominal.", + } materia_aberta = None if ordem_dia: materia_aberta = ordem_dia - presentes = PresencaOrdemDia.objects.filter( - sessao_plenaria_id=pk).values_list( - 'parlamentar_id', flat=True).distinct() + presentes = ( + PresencaOrdemDia.objects.filter(sessao_plenaria_id=pk) + .values_list("parlamentar_id", flat=True) + .distinct() + ) elif expediente: materia_aberta = expediente - presentes = SessaoPlenariaPresenca.objects.filter( - sessao_plenaria_id=pk).values_list( - 'parlamentar_id', flat=True).distinct() + presentes = ( + SessaoPlenariaPresenca.objects.filter(sessao_plenaria_id=pk) + .values_list("parlamentar_id", flat=True) + .distinct() + ) - context_vars.update({'ordem_dia': ordem_dia, - 'expediente':expediente, - 'presentes': presentes}) + context_vars.update( + {"ordem_dia": ordem_dia, "expediente": expediente, "presentes": presentes} + ) # Verifica votação aberta # Se aberta, verifica se é nominal. ID nominal == 2 erro = None if not materia_aberta: - erro = 'materia' + erro = "materia" elif materia_aberta.registro_aberto: - erro = 'registro' + erro = "registro" elif materia_aberta.tipo_votacao != VOTACAO_NOMINAL: - erro = 'tipo' + erro = "tipo" if not erro: - context.update({'materia': materia_aberta.materia, - 'ementa': materia_aberta.materia.ementa}) + context.update( + {"materia": materia_aberta.materia, "ementa": materia_aberta.materia.ementa} + ) context, context_vars = votacao(context, context_vars) else: - context.update({'error_message': errors_msgs[erro]}) + context.update({"error_message": errors_msgs[erro]}) return context, context_vars def can_vote(context, context_vars, request): - context.update({'permissao': True}) + context.update({"permissao": True}) # Pega sessão sessao, msg = votacao_aberta(request) - context_vars.update({'sessao':sessao}) + context_vars.update({"sessao": sessao}) if sessao and not msg: context, context_vars = sessao_votacao(context, context_vars) elif not sessao and msg: - return HttpResponseRedirect('/') + return HttpResponseRedirect("/") else: - context.update( - {'error_message': 'Não há nenhuma sessão com matéria aberta.'}) + context.update({"error_message": "Não há nenhuma sessão com matéria aberta."}) return context, context_vars def votante_view(request): logger = logging.getLogger(__name__) - username = request.user.username if request.user.is_authenticated else 'AnonymousUser' - + username = ( + request.user.username if request.user.is_authenticated else "AnonymousUser" + ) + # Pega o votante relacionado ao usuário - template_name = 'painel/voto_nominal.html' + template_name = "painel/voto_nominal.html" context = {} context_vars = {} try: - logger.debug(f'user={username}. Tentando obter objeto Votante com user={request.user}.') + logger.debug( + f"user={username}. Tentando obter objeto Votante com user={request.user}." + ) if not request.user.is_anonymous and request.user.is_authenticated: votante = Votante.objects.get(user=request.user) else: raise ObjectDoesNotExist except ObjectDoesNotExist: - logger.error(f"user={username}. Usuário (user={request.user}) não cadastrado como votante na tela de parlamentares. " - "Contate a administração de sua Casa Legislativa!") - msg = _("Usuário não cadastrado como votante na tela de parlamentares. Contate a administração de sua Casa Legislativa!") - context.update({'error_message': msg}) + logger.error( + f"user={username}. Usuário (user={request.user}) não cadastrado como votante na tela de parlamentares. " + "Contate a administração de sua Casa Legislativa!" + ) + msg = _( + "Usuário não cadastrado como votante na tela de parlamentares. Contate a administração de sua Casa Legislativa!" + ) + context.update({"error_message": msg}) return render(request, template_name, context) - context_vars = {'votante': votante} - context = {'head_title': str(_('Votação Individual'))} + context_vars = {"votante": votante} + context = {"head_title": str(_("Votação Individual"))} # Verifica se usuário possui permissão para votar - if 'parlamentares.can_vote' in request.user.get_all_permissions(): + if "parlamentares.can_vote" in request.user.get_all_permissions(): context, context_vars = can_vote(context, context_vars, request) - logger.debug("user=" + username + ". Verificando se usuário {} possui permissão para votar.".format(request.user)) + logger.debug( + "user=" + + username + + ". Verificando se usuário {} possui permissão para votar.".format( + request.user + ) + ) else: - logger.error("user=" + username + ". Usuário {} sem permissão para votar.".format(request.user)) - context.update({'permissao': False, - 'error_message': 'Usuário sem permissão para votar.'}) + logger.error( + "user=" + + username + + ". Usuário {} sem permissão para votar.".format(request.user) + ) + context.update( + {"permissao": False, "error_message": "Usuário sem permissão para votar."} + ) # Salva o voto - if request.method == 'POST': - if context_vars['ordem_dia']: + if request.method == "POST": + if context_vars["ordem_dia"]: try: - logger.info("user=" + username + ". Tentando obter objeto VotoParlamentar para parlamentar={} e ordem={}." - .format(context_vars['parlamentar'], context_vars['ordem_dia'])) + logger.info( + "user=" + + username + + ". Tentando obter objeto VotoParlamentar para parlamentar={} e ordem={}.".format( + context_vars["parlamentar"], context_vars["ordem_dia"] + ) + ) voto = VotoParlamentar.objects.get( - parlamentar=context_vars['parlamentar'], - ordem=context_vars['ordem_dia']) + parlamentar=context_vars["parlamentar"], + ordem=context_vars["ordem_dia"], + ) except ObjectDoesNotExist: - logger.error("user=" + username + ". Erro ao obter VotoParlamentar para parlamentar={} e ordem={}. Criando objeto." - .format(context_vars['parlamentar'], context_vars['ordem_dia'])) + logger.error( + "user=" + + username + + ". Erro ao obter VotoParlamentar para parlamentar={} e ordem={}. Criando objeto.".format( + context_vars["parlamentar"], context_vars["ordem_dia"] + ) + ) voto = VotoParlamentar.objects.create( - parlamentar=context_vars['parlamentar'], - voto=request.POST['voto'], + parlamentar=context_vars["parlamentar"], + voto=request.POST["voto"], user=request.user, ip=get_client_ip(request), - ordem=context_vars['ordem_dia']) + ordem=context_vars["ordem_dia"], + ) else: - logger.info("user=" + username + ". VotoParlamentar para parlamentar={} e ordem={} obtido com sucesso." - .format(context_vars['parlamentar'], context_vars['ordem_dia'])) - voto.voto = request.POST['voto'] + logger.info( + "user=" + + username + + ". VotoParlamentar para parlamentar={} e ordem={} obtido com sucesso.".format( + context_vars["parlamentar"], context_vars["ordem_dia"] + ) + ) + voto.voto = request.POST["voto"] voto.ip = get_client_ip(request) voto.user = request.user voto.save() - elif context_vars['expediente']: + elif context_vars["expediente"]: try: - logger.info("user=" + username + ". Tentando obter objeto VotoParlamentar para parlamentar={} e expediente={}." - .format(context_vars['parlamentar'], context_vars['expediente'])) + logger.info( + "user=" + + username + + ". Tentando obter objeto VotoParlamentar para parlamentar={} e expediente={}.".format( + context_vars["parlamentar"], context_vars["expediente"] + ) + ) voto = VotoParlamentar.objects.get( - parlamentar=context_vars['parlamentar'], - expediente=context_vars['expediente']) + parlamentar=context_vars["parlamentar"], + expediente=context_vars["expediente"], + ) except ObjectDoesNotExist: - logger.error("user=" + username + ". Erro ao obter VotoParlamentar para parlamentar={} e expediente={}. Criando objeto." - .format(context_vars['parlamentar'], context_vars['expediente'])) + logger.error( + "user=" + + username + + ". Erro ao obter VotoParlamentar para parlamentar={} e expediente={}. Criando objeto.".format( + context_vars["parlamentar"], context_vars["expediente"] + ) + ) voto = VotoParlamentar.objects.create( - parlamentar=context_vars['parlamentar'], - voto=request.POST['voto'], + parlamentar=context_vars["parlamentar"], + voto=request.POST["voto"], user=request.user, ip=get_client_ip(request), - expediente=context_vars['expediente']) + expediente=context_vars["expediente"], + ) else: - logger.info("user=" + username + ". VotoParlamentar para parlamentar={} e expediente={} obtido com sucesso." - .format(context_vars['parlamentar'], context_vars['expediente'])) - voto.voto = request.POST['voto'] + logger.info( + "user=" + + username + + ". VotoParlamentar para parlamentar={} e expediente={} obtido com sucesso.".format( + context_vars["parlamentar"], context_vars["expediente"] + ) + ) + voto.voto = request.POST["voto"] voto.ip = get_client_ip(request) voto.user = request.user voto.save() - return HttpResponseRedirect( - reverse('sapl.painel:voto_individual')) + return HttpResponseRedirect(reverse("sapl.painel:voto_individual")) return render(request, template_name, context) @@ -294,14 +393,18 @@ def painel_view(request, pk): now = timezone.localtime(timezone.now()) utc_offset = now.utcoffset().total_seconds() / 60 - context = {'head_title': str(_('Painel Plenário')), 'sessao_id': pk, 'utc_offset': utc_offset } - return render(request, 'painel/index.html', context) + context = { + "head_title": str(_("Painel Plenário")), + "sessao_id": pk, + "utc_offset": utc_offset, + } + return render(request, "painel/index.html", context) @user_passes_test(check_permission) def switch_painel(request): - sessao = SessaoPlenaria.objects.get(id=request.POST['pk_sessao']) - switch = json.loads(request.POST['aberto']) + sessao = SessaoPlenaria.objects.get(id=request.POST["pk_sessao"]) + switch = json.loads(request.POST["aberto"]) if switch: sessao.painel_aberto = True @@ -314,7 +417,7 @@ def switch_painel(request): @user_passes_test(check_permission) def verifica_painel(request): - sessao = SessaoPlenaria.objects.get(id=request.GET['pk_sessao']) + sessao = SessaoPlenaria.objects.get(id=request.GET["pk_sessao"]) status = sessao.painel_aberto resposta = JsonResponse(dict(status=status)) return resposta @@ -322,22 +425,22 @@ def verifica_painel(request): @user_passes_test(check_permission) def painel_mensagem_view(request): - return render(request, 'painel/mensagem.html') + return render(request, "painel/mensagem.html") @user_passes_test(check_permission) def painel_parlamentar_view(request): - return render(request, 'painel/parlamentares.html') + return render(request, "painel/parlamentares.html") @user_passes_test(check_permission) def painel_votacao_view(request): - return render(request, 'painel/votacao.html') + return render(request, "painel/votacao.html") @user_passes_test(check_permission) def cronometro_painel(request): - request.session[request.GET['tipo']] = request.GET['action'] + request.session[request.GET["tipo"]] = request.GET["action"] return HttpResponse({}) @@ -348,38 +451,38 @@ def get_cronometro_status(request, name): logger.debug("user=" + username + ". Tentando obter cronometro.") cronometro = request.session[name] except KeyError as e: - logger.error("user=" + username + ". Erro ao obter cronometro. Retornado como vazio. " + str(e)) - cronometro = '' + logger.error( + "user=" + + username + + ". Erro ao obter cronometro. Retornado como vazio. " + + str(e) + ) + cronometro = "" return cronometro def get_materia_aberta(pk): - return OrdemDia.objects.filter( - sessao_plenaria_id=pk, votacao_aberta=True).last() + return OrdemDia.objects.filter(sessao_plenaria_id=pk, votacao_aberta=True).last() def get_presentes(pk, response, materia): if type(materia) == OrdemDia: - presentes = PresencaOrdemDia.objects.filter( - sessao_plenaria_id=pk) + presentes = PresencaOrdemDia.objects.filter(sessao_plenaria_id=pk) else: - presentes = SessaoPlenariaPresenca.objects.filter( - sessao_plenaria_id=pk) - + presentes = SessaoPlenariaPresenca.objects.filter(sessao_plenaria_id=pk) + sessao = SessaoPlenaria.objects.get(id=pk) num_presentes = len(presentes) data_sessao = sessao.data_inicio - oradores = OradorExpediente.objects.filter( - sessao_plenaria_id=pk).order_by('numero_ordem') + oradores = OradorExpediente.objects.filter(sessao_plenaria_id=pk).order_by( + "numero_ordem" + ) oradores_list = [] for o in oradores: - oradores_list.append( - { - 'nome': o.parlamentar.nome_parlamentar, - 'numero': o.numero_ordem - }) + {"nome": o.parlamentar.nome_parlamentar, "numero": o.numero_ordem} + ) presentes_list = [] for p in presentes: @@ -390,59 +493,65 @@ def get_presentes(pk, response, materia): if p.parlamentar.ativo and mandatos: filiacao = filiacao_data(p.parlamentar, data_sessao, data_sessao) if not filiacao: - partido = 'Sem Registro' + partido = "Sem Registro" else: partido = filiacao presentes_list.append( - {'id': p.id, - 'parlamentar_id': p.parlamentar.id, - 'nome': p.parlamentar.nome_parlamentar, - 'partido': partido, - 'voto': '' - }) + { + "id": p.id, + "parlamentar_id": p.parlamentar.id, + "nome": p.parlamentar.nome_parlamentar, + "partido": partido, + "voto": "", + } + ) elif not p.parlamentar.ativo or not mandatos: num_presentes += -1 if materia: if materia.tipo_votacao == 1: - tipo_votacao = 'Simbólica' + tipo_votacao = "Simbólica" elif materia.tipo_votacao == 2: - tipo_votacao = 'Nominal' + tipo_votacao = "Nominal" elif materia.tipo_votacao == 3: - tipo_votacao = 'Secreta' + tipo_votacao = "Secreta" elif materia.tipo_votacao == 4: - tipo_votacao = 'Leitura' + tipo_votacao = "Leitura" - response.update({ - 'tipo_resultado': materia.resultado, - 'observacao_materia': html.unescape(materia.observacao), - 'tipo_votacao': tipo_votacao, - 'materia_legislativa_texto': str(materia.materia), - 'materia_legislativa_ementa': str(materia.materia.ementa) - }) - - presentes_list = sort_lista_chave(presentes_list, 'nome') - - response.update({ - 'presentes': presentes_list, - 'num_presentes': num_presentes, - 'oradores': oradores_list, - 'msg_painel': str(_('Votação aberta!')), - }) + response.update( + { + "tipo_resultado": materia.resultado, + "observacao_materia": html.unescape(materia.observacao), + "tipo_votacao": tipo_votacao, + "materia_legislativa_texto": str(materia.materia), + "materia_legislativa_ementa": str(materia.materia.ementa), + } + ) + + presentes_list = sort_lista_chave(presentes_list, "nome") + + response.update( + { + "presentes": presentes_list, + "num_presentes": num_presentes, + "oradores": oradores_list, + "msg_painel": str(_("Votação aberta!")), + } + ) return response def get_materia_expediente_aberta(pk): return ExpedienteMateria.objects.filter( - sessao_plenaria_id=pk, votacao_aberta=True).last() + sessao_plenaria_id=pk, votacao_aberta=True + ).last() def response_nenhuma_materia(response): - response.update({ - 'msg_painel': str(_('Nenhuma matéria disponivel para votação.'))}) + response.update({"msg_painel": str(_("Nenhuma matéria disponivel para votação."))}) return JsonResponse(response) @@ -450,95 +559,134 @@ def get_votos(response, materia, mostrar_voto): logger = logging.getLogger(__name__) if type(materia) == OrdemDia: if materia.tipo_votacao != 4: - registro = RegistroVotacao.objects.filter( - ordem=materia, materia=materia.materia).order_by('data_hora').last() + registro = ( + RegistroVotacao.objects.filter(ordem=materia, materia=materia.materia) + .order_by("data_hora") + .last() + ) leitura = None else: - leitura = RegistroLeitura.objects.filter( - ordem=materia, materia=materia.materia).order_by('data_hora').last() + leitura = ( + RegistroLeitura.objects.filter(ordem=materia, materia=materia.materia) + .order_by("data_hora") + .last() + ) registro = None - tipo = 'ordem' + tipo = "ordem" elif type(materia) == ExpedienteMateria: if materia.tipo_votacao != 4: - registro = RegistroVotacao.objects.filter( - expediente=materia, materia=materia.materia).order_by('data_hora').last() + registro = ( + RegistroVotacao.objects.filter( + expediente=materia, materia=materia.materia + ) + .order_by("data_hora") + .last() + ) leitura = None else: - leitura = RegistroLeitura.objects.filter( - expediente=materia, materia=materia.materia).order_by('data_hora').last() + leitura = ( + RegistroLeitura.objects.filter( + expediente=materia, materia=materia.materia + ) + .order_by("data_hora") + .last() + ) registro = None - tipo = 'expediente' + tipo = "expediente" if not registro and not leitura: - response.update({ - 'numero_votos_sim': 0, - 'numero_votos_nao': 0, - 'numero_abstencoes': 0, - 'registro': None, - 'total_votos': 0, - 'tipo_resultado': 'Ainda não foi votada.', - }) + response.update( + { + "numero_votos_sim": 0, + "numero_votos_nao": 0, + "numero_abstencoes": 0, + "registro": None, + "total_votos": 0, + "tipo_resultado": "Ainda não foi votada.", + } + ) if materia.tipo_votacao == 2: - if tipo == 'ordem': + if tipo == "ordem": votos_parlamentares = VotoParlamentar.objects.filter( - ordem_id=materia.id).order_by( - 'parlamentar__nome_parlamentar') + ordem_id=materia.id + ).order_by("parlamentar__nome_parlamentar") else: votos_parlamentares = VotoParlamentar.objects.filter( - expediente_id=materia.id).order_by( - 'parlamentar__nome_parlamentar') + expediente_id=materia.id + ).order_by("parlamentar__nome_parlamentar") - for i, p in enumerate(response['presentes']): + for i, p in enumerate(response["presentes"]): try: - logger.info("Tentando obter votos do parlamentar (id={}).".format(p['parlamentar_id'])) - voto = votos_parlamentares.get(parlamentar_id=p['parlamentar_id']).voto + logger.info( + "Tentando obter votos do parlamentar (id={}).".format( + p["parlamentar_id"] + ) + ) + voto = votos_parlamentares.get( + parlamentar_id=p["parlamentar_id"] + ).voto if voto: if mostrar_voto: - response['presentes'][i]['voto'] = voto + response["presentes"][i]["voto"] = voto else: - response['presentes'][i]['voto'] = 'Voto Informado' + response["presentes"][i]["voto"] = "Voto Informado" except ObjectDoesNotExist: # logger.error("Votos do parlamentar (id={}) não encontrados. Retornado vazio." # .format(p['parlamentar_id'])) - response['presentes'][i]['voto'] = '' + response["presentes"][i]["voto"] = "" elif leitura: - response.update({ - 'numero_votos_sim': 0, - 'numero_votos_nao': 0, - 'numero_abstencoes': 0, - 'registro': True, - 'total_votos': 0, - 'tipo_resultado': 'Matéria lida.', - }) + response.update( + { + "numero_votos_sim": 0, + "numero_votos_nao": 0, + "numero_abstencoes": 0, + "registro": True, + "total_votos": 0, + "tipo_resultado": "Matéria lida.", + } + ) else: - total = (registro.numero_votos_sim + - registro.numero_votos_nao + - registro.numero_abstencoes) + total = ( + registro.numero_votos_sim + + registro.numero_votos_nao + + registro.numero_abstencoes + ) if materia.tipo_votacao == 2: votos_parlamentares = VotoParlamentar.objects.filter( - votacao_id=registro.id).order_by( - 'parlamentar__nome_parlamentar') + votacao_id=registro.id + ).order_by("parlamentar__nome_parlamentar") - for i, p in enumerate(response['presentes']): + for i, p in enumerate(response["presentes"]): try: - logger.debug("Tentando obter votos do parlamentar (id={}).".format(p['parlamentar_id'])) - response['presentes'][i]['voto'] = votos_parlamentares.get( - parlamentar_id=p['parlamentar_id']).voto + logger.debug( + "Tentando obter votos do parlamentar (id={}).".format( + p["parlamentar_id"] + ) + ) + response["presentes"][i]["voto"] = votos_parlamentares.get( + parlamentar_id=p["parlamentar_id"] + ).voto except ObjectDoesNotExist: - logger.error("Votos do parlamentar (id={}) não encontrados. Retornado None.".format(p['parlamentar_id'])) - response['presentes'][i]['voto'] = None - - response.update({ - 'numero_votos_sim': registro.numero_votos_sim, - 'numero_votos_nao': registro.numero_votos_nao, - 'numero_abstencoes': registro.numero_abstencoes, - 'registro': True, - 'total_votos': total, - 'tipo_resultado': registro.tipo_resultado_votacao.nome, - }) + logger.error( + "Votos do parlamentar (id={}) não encontrados. Retornado None.".format( + p["parlamentar_id"] + ) + ) + response["presentes"][i]["voto"] = None + + response.update( + { + "numero_votos_sim": registro.numero_votos_sim, + "numero_votos_nao": registro.numero_votos_nao, + "numero_abstencoes": registro.numero_abstencoes, + "registro": True, + "total_votos": total, + "tipo_resultado": registro.tipo_resultado_votacao.nome, + } + ) return response @@ -553,23 +701,22 @@ def get_dados_painel(request, pk): brasao = None if casa and app_config and (bool(casa.logotipo)): - brasao = casa.logotipo.url \ - if app_config.mostrar_brasao_painel else None - + brasao = casa.logotipo.url if app_config.mostrar_brasao_painel else None + response = { - 'sessao_plenaria': str(sessao), - 'sessao_plenaria_data': sessao.data_inicio.strftime('%d/%m/%Y'), - 'sessao_plenaria_hora_inicio': sessao.hora_inicio, - 'sessao_solene': sessao.tipo.nome == "Solene", - 'sessao_finalizada': sessao.finalizada, - 'tema_solene': sessao.tema_solene, - 'cronometro_aparte': get_cronometro_status(request, 'aparte'), - 'cronometro_discurso': get_cronometro_status(request, 'discurso'), - 'cronometro_ordem': get_cronometro_status(request, 'ordem'), - 'cronometro_consideracoes': get_cronometro_status(request, 'consideracoes'), - 'status_painel': sessao.painel_aberto, - 'brasao': brasao, - 'mostrar_voto': app_config.mostrar_voto + "sessao_plenaria": str(sessao), + "sessao_plenaria_data": sessao.data_inicio.strftime("%d/%m/%Y"), + "sessao_plenaria_hora_inicio": sessao.hora_inicio, + "sessao_solene": sessao.tipo.nome == "Solene", + "sessao_finalizada": sessao.finalizada, + "tema_solene": sessao.tema_solene, + "cronometro_aparte": get_cronometro_status(request, "aparte"), + "cronometro_discurso": get_cronometro_status(request, "discurso"), + "cronometro_ordem": get_cronometro_status(request, "ordem"), + "cronometro_consideracoes": get_cronometro_status(request, "consideracoes"), + "status_painel": sessao.painel_aberto, + "brasao": brasao, + "mostrar_voto": app_config.mostrar_voto, } ordem_dia = get_materia_aberta(pk) @@ -578,25 +725,45 @@ def get_dados_painel(request, pk): # Caso tenha alguma matéria com votação aberta, ela é mostrada no painel # com prioridade para Ordem do Dia. if ordem_dia: - return JsonResponse(get_votos( - get_presentes(pk, response, ordem_dia), - ordem_dia, app_config.mostrar_voto)) + return JsonResponse( + get_votos( + get_presentes(pk, response, ordem_dia), + ordem_dia, + app_config.mostrar_voto, + ) + ) elif expediente: - return JsonResponse(get_votos( - get_presentes(pk, response, expediente), - expediente, app_config.mostrar_voto)) + return JsonResponse( + get_votos( + get_presentes(pk, response, expediente), + expediente, + app_config.mostrar_voto, + ) + ) # Caso não tenha nenhuma aberta, # a matéria a ser mostrada no Painel deve ser a última votada - last_ordem_voto = RegistroVotacao.objects.filter( - ordem__sessao_plenaria=sessao).order_by('data_hora').last() - last_expediente_voto = RegistroVotacao.objects.filter( - expediente__sessao_plenaria=sessao).order_by('data_hora').last() - - last_ordem_leitura = RegistroLeitura.objects.filter( - ordem__sessao_plenaria=sessao).order_by('data_hora').last() - last_expediente_leitura = RegistroLeitura.objects.filter( - expediente__sessao_plenaria=sessao).order_by('data_hora').last() + last_ordem_voto = ( + RegistroVotacao.objects.filter(ordem__sessao_plenaria=sessao) + .order_by("data_hora") + .last() + ) + last_expediente_voto = ( + RegistroVotacao.objects.filter(expediente__sessao_plenaria=sessao) + .order_by("data_hora") + .last() + ) + + last_ordem_leitura = ( + RegistroLeitura.objects.filter(ordem__sessao_plenaria=sessao) + .order_by("data_hora") + .last() + ) + last_expediente_leitura = ( + RegistroLeitura.objects.filter(expediente__sessao_plenaria=sessao) + .order_by("data_hora") + .last() + ) # Obtém última matéria que foi votada, através do timestamp mais recente ordem_expediente = None @@ -604,23 +771,36 @@ def get_dados_painel(request, pk): if last_ordem_voto: ordem_expediente = last_ordem_voto.ordem ultimo_timestamp = last_ordem_voto.data_hora - if (last_expediente_voto and ultimo_timestamp and last_expediente_voto.data_hora > ultimo_timestamp) or \ - (not ultimo_timestamp and last_expediente_voto): + if ( + last_expediente_voto + and ultimo_timestamp + and last_expediente_voto.data_hora > ultimo_timestamp + ) or (not ultimo_timestamp and last_expediente_voto): ordem_expediente = last_expediente_voto.expediente ultimo_timestamp = last_expediente_voto.data_hora - if (last_ordem_leitura and ultimo_timestamp and last_ordem_leitura.data_hora > ultimo_timestamp) or \ - (not ultimo_timestamp and last_ordem_leitura): + if ( + last_ordem_leitura + and ultimo_timestamp + and last_ordem_leitura.data_hora > ultimo_timestamp + ) or (not ultimo_timestamp and last_ordem_leitura): ordem_expediente = last_ordem_leitura.ordem ultimo_timestamp = last_ordem_leitura.data_hora - if (last_expediente_leitura and ultimo_timestamp and last_expediente_leitura.data_hora > ultimo_timestamp) or \ - (not ultimo_timestamp and last_expediente_leitura): + if ( + last_expediente_leitura + and ultimo_timestamp + and last_expediente_leitura.data_hora > ultimo_timestamp + ) or (not ultimo_timestamp and last_expediente_leitura): ordem_expediente = last_expediente_leitura.expediente ultimo_timestamp = last_expediente_leitura.data_hora - + if ordem_expediente: - return JsonResponse(get_votos( - get_presentes(pk, response, ordem_expediente), - ordem_expediente, app_config.mostrar_voto)) + return JsonResponse( + get_votos( + get_presentes(pk, response, ordem_expediente), + ordem_expediente, + app_config.mostrar_voto, + ) + ) # Retorna que não há nenhuma matéria já votada ou aberta return response_nenhuma_materia(get_presentes(pk, response, None)) diff --git a/sapl/parlamentares/apps.py b/sapl/parlamentares/apps.py index bb357afce..3520eff12 100644 --- a/sapl/parlamentares/apps.py +++ b/sapl/parlamentares/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.parlamentares' - label = 'parlamentares' - verbose_name = _('Parlamentares') + name = "sapl.parlamentares" + label = "parlamentares" + verbose_name = _("Parlamentares") diff --git a/sapl/parlamentares/forms.py b/sapl/parlamentares/forms.py index 0aa0479b3..1f75b22ef 100755 --- a/sapl/parlamentares/forms.py +++ b/sapl/parlamentares/forms.py @@ -1,6 +1,7 @@ -from datetime import timedelta import logging +from datetime import timedelta +import django_filters from crispy_forms.layout import Fieldset, Layout from django import forms from django.contrib.auth import get_user_model @@ -12,17 +13,16 @@ from django.db.models import Q from django.forms import ModelForm from django.utils import timezone from django.utils.translation import gettext_lazy as _ -import django_filters from image_cropping.widgets import CropWidget, ImageCropWidget from sapl.base.models import Autor, TipoAutor -from sapl.crispy_layout_mixin import SaplFormHelper -from sapl.crispy_layout_mixin import form_actions, to_row +from sapl.crispy_layout_mixin import SaplFormHelper, form_actions, to_row from sapl.rules import SAPL_GROUP_VOTANTE from sapl.utils import FileFieldCheckMixin -from .models import (Coligacao, ComposicaoColigacao, Filiacao, Frente, Legislatura, - Mandato, Parlamentar, Partido, Votante, Bloco, FrenteParlamentar, BlocoMembro) +from .models import (Bloco, BlocoMembro, Coligacao, ComposicaoColigacao, + Filiacao, Frente, FrenteParlamentar, Legislatura, Mandato, + Parlamentar, Partido, Votante) class CustomImageCropWidget(ImageCropWidget): @@ -31,9 +31,10 @@ class CustomImageCropWidget(ImageCropWidget): We use this trick, and place it right under the CropWidget so that it looks like the user is seeing the image and clearing the image. """ + template_with_initial = ( # '%(initial_text)s: %(initial)s ' - '%(clear_template)s
        %(input_text)s: %(input)s' + "%(clear_template)s
        %(input_text)s: %(input)s" ) @@ -41,30 +42,37 @@ def validar_datas_legislatura(eleicao, inicio, fim, pk=None): logger = logging.getLogger(__name__) # Verifica se data de eleição < inicio < fim if inicio >= fim or eleicao >= inicio: - logger.error('A data início ({}) deve ser menor que a ' + - 'data fim ({}) e a data eleição ({}) deve ser ' + - 'menor que a data início ({})'.format(inicio, fim, eleicao, inicio)) - msg_error = _('A data início deve ser menor que a ' + - 'data fim e a data eleição deve ser ' + - 'menor que a data início') + logger.error( + "A data início ({}) deve ser menor que a " + + "data fim ({}) e a data eleição ({}) deve ser " + + "menor que a data início ({})".format(inicio, fim, eleicao, inicio) + ) + msg_error = _( + "A data início deve ser menor que a " + + "data fim e a data eleição deve ser " + + "menor que a data início" + ) return (False, msg_error) # Verifica se há alguma data cadastrada no intervalo de tempo desejado - intersecao_legislatura = Legislatura.objects.filter( - data_inicio__lte=fim, data_fim__gte=inicio - ).exclude(pk=pk).exists() + intersecao_legislatura = ( + Legislatura.objects.filter(data_inicio__lte=fim, data_fim__gte=inicio) + .exclude(pk=pk) + .exists() + ) if intersecao_legislatura: - logger.error("Já existe uma legislatura neste intervalo de datas (data_inicio<={} e data_fim>={})." - .format(fim, inicio)) - msg_error = _('Já existe uma legislatura neste intervalo de datas') + logger.error( + "Já existe uma legislatura neste intervalo de datas (data_inicio<={} e data_fim>={}).".format( + fim, inicio + ) + ) + msg_error = _("Já existe uma legislatura neste intervalo de datas") return (False, msg_error) # Verifica se há alguma outra data de eleição cadastrada - if Legislatura.objects.filter( - data_eleicao=eleicao).exclude(pk=pk).exists(): - logger.error( - "Esta data de eleição ({}) já foi cadastrada.".format(eleicao)) - msg_error = _('Esta data de eleição já foi cadastrada') + if Legislatura.objects.filter(data_eleicao=eleicao).exclude(pk=pk).exists(): + logger.error("Esta data de eleição ({}) já foi cadastrada.".format(eleicao)) + msg_error = _("Esta data de eleição já foi cadastrada") return (False, msg_error) return (True, None) @@ -73,15 +81,23 @@ def validar_datas_legislatura(eleicao, inicio, fim, pk=None): class MandatoForm(ModelForm): logger = logging.getLogger(__name__) - data_fim_mandato = forms.DateField(label=_('Fim do Mandato')) + data_fim_mandato = forms.DateField(label=_("Fim do Mandato")) class Meta: model = Mandato - fields = ['legislatura', 'coligacao', 'votos_recebidos', - 'data_inicio_mandato', 'data_fim_mandato', - 'data_expedicao_diploma', 'titular', - 'tipo_afastamento', 'observacao', 'parlamentar'] - widgets = {'parlamentar': forms.HiddenInput()} + fields = [ + "legislatura", + "coligacao", + "votos_recebidos", + "data_inicio_mandato", + "data_fim_mandato", + "data_expedicao_diploma", + "titular", + "tipo_afastamento", + "observacao", + "parlamentar", + ] + widgets = {"parlamentar": forms.HiddenInput()} def clean(self): super(MandatoForm, self).clean() @@ -91,74 +107,105 @@ class MandatoForm(ModelForm): data = self.cleaned_data - legislatura = data['legislatura'] + legislatura = data["legislatura"] - data_inicio_mandato = data['data_inicio_mandato'] + data_inicio_mandato = data["data_inicio_mandato"] if data_inicio_mandato: - if (data_inicio_mandato < legislatura.data_inicio or - data_inicio_mandato > legislatura.data_fim): - self.logger.error("Data início mandato ({}) fora do intervalo" - " de legislatura informada ({} a {})." - .format(data_inicio_mandato, legislatura.data_inicio, legislatura.data_fim)) - raise ValidationError(_("Data início mandato fora do intervalo" - " de legislatura informada")) - - data_fim_mandato = data['data_fim_mandato'] + if ( + data_inicio_mandato < legislatura.data_inicio + or data_inicio_mandato > legislatura.data_fim + ): + self.logger.error( + "Data início mandato ({}) fora do intervalo" + " de legislatura informada ({} a {}).".format( + data_inicio_mandato, + legislatura.data_inicio, + legislatura.data_fim, + ) + ) + raise ValidationError( + _( + "Data início mandato fora do intervalo" + " de legislatura informada" + ) + ) + + data_fim_mandato = data["data_fim_mandato"] if data_fim_mandato: - if (data_fim_mandato < legislatura.data_inicio or - data_fim_mandato > legislatura.data_fim): - self.logger.error("Data fim mandato ({}) fora do intervalo" - " de legislatura informada ({} a {})." - .format(data_fim_mandato, legislatura.data_inicio, legislatura.data_fim)) - raise ValidationError(_("Data fim mandato fora do intervalo de" - " legislatura informada")) - - data_expedicao_diploma = data['data_expedicao_diploma'] - if (data_expedicao_diploma and - data_expedicao_diploma > data_inicio_mandato): - self.logger.error("A data da expedição do diploma ({}) deve ser anterior " - "a data de início do mandato ({}).".format(data_expedicao_diploma, data_inicio_mandato)) - raise ValidationError(_("A data da expedição do diploma deve ser anterior " - "a data de início do mandato")) - - coligacao = data['coligacao'] + if ( + data_fim_mandato < legislatura.data_inicio + or data_fim_mandato > legislatura.data_fim + ): + self.logger.error( + "Data fim mandato ({}) fora do intervalo" + " de legislatura informada ({} a {}).".format( + data_fim_mandato, legislatura.data_inicio, legislatura.data_fim + ) + ) + raise ValidationError( + _("Data fim mandato fora do intervalo de" " legislatura informada") + ) + + data_expedicao_diploma = data["data_expedicao_diploma"] + if data_expedicao_diploma and data_expedicao_diploma > data_inicio_mandato: + self.logger.error( + "A data da expedição do diploma ({}) deve ser anterior " + "a data de início do mandato ({}).".format( + data_expedicao_diploma, data_inicio_mandato + ) + ) + raise ValidationError( + _( + "A data da expedição do diploma deve ser anterior " + "a data de início do mandato" + ) + ) + + coligacao = data["coligacao"] if coligacao and not coligacao.legislatura == legislatura: - self.logger.error("A coligação selecionada ({}) não está cadastrada " - "na mesma legislatura ({}) que o presente mandato ({}), " - "favor verificar a coligação ou fazer o cadastro " - "de uma nova coligação na legislatura correspondente" - .format(coligacao, coligacao.legislatura, legislatura)) - raise ValidationError(_("A coligação selecionada não está cadastrada " - "na mesma legislatura que o presente mandato, " - "favor verificar a coligação ou fazer o cadastro " - "de uma nova coligação na legislatura correspondente")) + self.logger.error( + "A coligação selecionada ({}) não está cadastrada " + "na mesma legislatura ({}) que o presente mandato ({}), " + "favor verificar a coligação ou fazer o cadastro " + "de uma nova coligação na legislatura correspondente".format( + coligacao, coligacao.legislatura, legislatura + ) + ) + raise ValidationError( + _( + "A coligação selecionada não está cadastrada " + "na mesma legislatura que o presente mandato, " + "favor verificar a coligação ou fazer o cadastro " + "de uma nova coligação na legislatura correspondente" + ) + ) existe_mandato = Mandato.objects.filter( - parlamentar=data['parlamentar'], - legislatura=data['legislatura']) + parlamentar=data["parlamentar"], legislatura=data["legislatura"] + ) if self.instance.pk: existe_mandato = existe_mandato.exclude(id=self.instance.pk) - if existe_mandato.exists() and data['titular']: - self.logger.error("Mandato nesta legislatura (parlamentar={}, legislatura={}) já existe." - .format(data['parlamentar'], data['legislatura'])) - raise ValidationError(_('Mandato nesta legislatura já existe.')) + if existe_mandato.exists() and data["titular"]: + self.logger.error( + "Mandato nesta legislatura (parlamentar={}, legislatura={}) já existe.".format( + data["parlamentar"], data["legislatura"] + ) + ) + raise ValidationError(_("Mandato nesta legislatura já existe.")) return self.cleaned_data class LegislaturaForm(ModelForm): - logger = logging.getLogger(__name__) class Meta: model = Legislatura exclude = [] - widgets = { - 'observacao': forms.Textarea( - attrs={'id': 'texto-rico'})} + widgets = {"observacao": forms.Textarea(attrs={"id": "texto-rico"})} def clean(self): data = super(LegislaturaForm, self).clean() @@ -166,37 +213,54 @@ class LegislaturaForm(ModelForm): if not self.is_valid(): return self.cleaned_data - numero = data['numero'] - data_inicio = data['data_inicio'] - data_fim = data['data_fim'] - data_eleicao = data['data_eleicao'] + numero = data["numero"] + data_inicio = data["data_inicio"] + data_fim = data["data_fim"] + data_eleicao = data["data_eleicao"] pk = self.instance.pk - ultima_legislatura = Legislatura.objects.filter(data_inicio__lt=data_inicio - ).order_by('-data_inicio').exclude(id=pk).first() - proxima_legislatura = Legislatura.objects.filter(data_fim__gt=data_fim - ).order_by('data_fim').exclude(id=pk).first() + ultima_legislatura = ( + Legislatura.objects.filter(data_inicio__lt=data_inicio) + .order_by("-data_inicio") + .exclude(id=pk) + .first() + ) + proxima_legislatura = ( + Legislatura.objects.filter(data_fim__gt=data_fim) + .order_by("data_fim") + .exclude(id=pk) + .first() + ) if ultima_legislatura and ultima_legislatura.numero >= numero: - self.logger.error("Número ({}) deve ser maior que o da legislatura anterior ({})." - .format(numero, ultima_legislatura.numero)) - raise ValidationError(_("Número deve ser maior que o da legislatura anterior ({})." - .format(numero))) + self.logger.error( + "Número ({}) deve ser maior que o da legislatura anterior ({}).".format( + numero, ultima_legislatura.numero + ) + ) + raise ValidationError( + _( + "Número deve ser maior que o da legislatura anterior ({}).".format( + numero + ) + ) + ) elif proxima_legislatura and proxima_legislatura.numero <= numero: - self.logger.error("O Número ({}) deve ser menor que {}, pois existe uma " - "legislatura cronologicamente à frente desta que está sendo criada!" - .format(numero, proxima_legislatura.numero)) - msg_erro = "O Número deve ser menor que {}, pois existe uma " \ - + self.logger.error( + "O Número ({}) deve ser menor que {}, pois existe uma " + "legislatura cronologicamente à frente desta que está sendo criada!".format( + numero, proxima_legislatura.numero + ) + ) + msg_erro = "O Número deve ser menor que {}, pois existe uma " "legislatura cronologicamente à frente desta que está sendo criada!" msg_erro = msg_erro.format(proxima_legislatura.numero) raise ValidationError(_(msg_erro)) - valida_datas = validar_datas_legislatura(data_eleicao, - data_inicio, - data_fim, - pk=pk) + valida_datas = validar_datas_legislatura( + data_eleicao, data_inicio, data_fim, pk=pk + ) if not valida_datas[0]: raise ValidationError(valida_datas[1]) @@ -204,16 +268,15 @@ class LegislaturaForm(ModelForm): class ParlamentarForm(FileFieldCheckMixin, ModelForm): - class Meta: model = Parlamentar exclude = [] widgets = { - 'fotografia': CustomImageCropWidget(), - 'cropping': CropWidget(), - 'biografia': forms.Textarea( - attrs={'id': 'texto-rico'})} + "fotografia": CustomImageCropWidget(), + "cropping": CropWidget(), + "biografia": forms.Textarea(attrs={"id": "texto-rico"}), + } def save(self, commit=True): parlamentar = super().save() @@ -230,83 +293,79 @@ class ParlamentarForm(FileFieldCheckMixin, ModelForm): class ParlamentarFilterSet(django_filters.FilterSet): nome_parlamentar = django_filters.CharFilter( - label=_('Nome do Parlamentar'), - lookup_expr='icontains') + label=_("Nome do Parlamentar"), lookup_expr="icontains" + ) class Meta: model = Parlamentar - fields = ['nome_parlamentar'] + fields = ["nome_parlamentar"] def __init__(self, *args, **kwargs): super(ParlamentarFilterSet, self).__init__(*args, **kwargs) - row0 = to_row([('nome_parlamentar', 12)]) + row0 = to_row([("nome_parlamentar", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Parlamentar'), - row0, - form_actions(label='Pesquisar')) + Fieldset( + _("Pesquisa de Parlamentar"), row0, form_actions(label="Pesquisar") + ) ) class ColigacaoFilterSet(django_filters.FilterSet): nome = django_filters.CharFilter( - label=_('Nome da Coligação'), lookup_expr='icontains') + label=_("Nome da Coligação"), lookup_expr="icontains" + ) class Meta: model = Coligacao - fields = ['nome'] + fields = ["nome"] def __init__(self, *args, **kwargs): super(ColigacaoFilterSet, self).__init__(*args, **kwargs) - row0 = to_row([('nome', 12)]) + row0 = to_row([("nome", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Coligação'), - row0, - form_actions(label='Pesquisar'))) + Fieldset(_("Pesquisa de Coligação"), row0, form_actions(label="Pesquisar")) + ) class PartidoFilterSet(django_filters.FilterSet): - nome = django_filters.CharFilter(label=_('Nome do Partido'), - method='multifield_filter') + nome = django_filters.CharFilter( + label=_("Nome do Partido"), method="multifield_filter" + ) class Meta: model = Partido - fields = ['nome'] + fields = ["nome"] def multifield_filter(self, queryset, name, value): - return queryset.filter( - Q(sigla__icontains=value) | Q(nome__icontains=value)) + return queryset.filter(Q(sigla__icontains=value) | Q(nome__icontains=value)) def __init__(self, *args, **kwargs): super(PartidoFilterSet, self).__init__(*args, **kwargs) - row0 = to_row([('nome', 12)]) + row0 = to_row([("nome", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Partido'), - row0, - form_actions(label='Pesquisar')) + Fieldset(_("Pesquisa de Partido"), row0, form_actions(label="Pesquisar")) ) class ParlamentarCreateForm(ParlamentarForm): - logger = logging.getLogger(__name__) class Meta(ParlamentarForm.Meta): widgets = { - 'fotografia': forms.ClearableFileInput(), - 'biografia': forms.Textarea( - attrs={'id': 'texto-rico'}) + "fotografia": forms.ClearableFileInput(), + "biografia": forms.Textarea(attrs={"id": "texto-rico"}), } def clean(self): @@ -317,11 +376,12 @@ class ParlamentarCreateForm(ParlamentarForm): cleaned_data = self.cleaned_data parlamentar = Parlamentar.objects.filter( - nome_parlamentar=cleaned_data['nome_parlamentar']).exists() + nome_parlamentar=cleaned_data["nome_parlamentar"] + ).exists() if parlamentar: - self.logger.error('Parlamentar já cadastrado.') - raise ValidationError('Parlamentar já cadastrado.') + self.logger.error("Parlamentar já cadastrado.") + raise ValidationError("Parlamentar já cadastrado.") return cleaned_data @@ -338,7 +398,7 @@ class ParlamentarCreateForm(ParlamentarForm): content_type=content_type, object_id=object_id, tipo=tipo, - nome=parlamentar.nome_parlamentar + nome=parlamentar.nome_parlamentar, ) else: parlamentar.save() @@ -346,20 +406,24 @@ class ParlamentarCreateForm(ParlamentarForm): def validar_datas(data_filiacao, data_desfiliacao, parlamentar, filiacao): - logger = logging.getLogger(__name__) # Verifica se data de desfiliacao é anterior a data de filiacao if data_desfiliacao and data_desfiliacao < data_filiacao: - logger.error("A data de desfiliação ({}) é anterior à data de filiação ({})." - .format(data_desfiliacao, data_filiacao)) - error_msg = _("A data de desfiliação não pode anterior \ - à data de filiação") + logger.error( + "A data de desfiliação ({}) é anterior à data de filiação ({}).".format( + data_desfiliacao, data_filiacao + ) + ) + error_msg = _( + "A data de desfiliação não pode anterior \ + à data de filiação" + ) return [False, error_msg] - filiacoes = parlamentar.filiacao_set.order_by('data') + filiacoes = parlamentar.filiacao_set.order_by("data") if not filiacoes.exists(): - return [True, ''] + return [True, ""] # data ficticia de desfiliacao today = timezone.now() @@ -368,29 +432,49 @@ def validar_datas(data_filiacao, data_desfiliacao, parlamentar, filiacao): # se não puder haver filiação no mesmo dia de desfiliação, basta # retirar os timedelta abaixo range_livre_exigido = Q( - data__range=[data_filiacao + timedelta(days=1), - df_desfiliacao - timedelta(days=1)]) | Q( - data_desfiliacao__range=[data_filiacao + timedelta(days=1), - df_desfiliacao - timedelta(days=1)]) + data__range=[ + data_filiacao + timedelta(days=1), + df_desfiliacao - timedelta(days=1), + ] + ) | Q( + data_desfiliacao__range=[ + data_filiacao + timedelta(days=1), + df_desfiliacao - timedelta(days=1), + ] + ) filiacao_em_edicao_id = filiacao.pk error_msg = None # filiação em edição não é a última e está sem data de desfiliação - if not data_desfiliacao and filiacao_em_edicao_id and\ - filiacao_em_edicao_id != filiacoes.last().pk: - logger.error("Data de desfiliação do parlamentar não pode ser " - "ausente, se existirem datas de filiação posteriores.") - error_msg = _("Data de desfiliação do parlamentar não pode ser\ - ausente, se existirem datas de filiação posteriores.") + if ( + not data_desfiliacao + and filiacao_em_edicao_id + and filiacao_em_edicao_id != filiacoes.last().pk + ): + logger.error( + "Data de desfiliação do parlamentar não pode ser " + "ausente, se existirem datas de filiação posteriores." + ) + error_msg = _( + "Data de desfiliação do parlamentar não pode ser\ + ausente, se existirem datas de filiação posteriores." + ) # a filiação que está sendo inclusa não tem data de desfiliação mas # já existe outra sem data de desfiliação - elif not data_desfiliacao and not filiacao_em_edicao_id and\ - not filiacoes.last().data_desfiliacao: - logger.error("O parlamentar não pode se filiar a novo partido sem" - " antes se desfiliar do partido anterior.") - error_msg = _("O parlamentar não pode se filiar a novo partido sem\ - antes se desfiliar do partido anterior.") + elif ( + not data_desfiliacao + and not filiacao_em_edicao_id + and not filiacoes.last().data_desfiliacao + ): + logger.error( + "O parlamentar não pode se filiar a novo partido sem" + " antes se desfiliar do partido anterior." + ) + error_msg = _( + "O parlamentar não pode se filiar a novo partido sem\ + antes se desfiliar do partido anterior." + ) if not error_msg: # se a filiação é uma edição, a exclui das possibilidades @@ -399,38 +483,49 @@ def validar_datas(data_filiacao, data_desfiliacao, parlamentar, filiacao): # testa a intercessão de intervalo com outra filiação if filiacoes.filter(range_livre_exigido).exists(): - logger.error("A data de filiação e desfiliação não podem estar" - " no intervalo de outro período de filiação.") - error_msg = _("A data de filiação e desfiliação (intervalo de {} a {}) " - "não podem estar no intervalo de outro período de filiação." - .format(data_filiacao, df_desfiliacao, )) + logger.error( + "A data de filiação e desfiliação não podem estar" + " no intervalo de outro período de filiação." + ) + error_msg = _( + "A data de filiação e desfiliação (intervalo de {} a {}) " + "não podem estar no intervalo de outro período de filiação.".format( + data_filiacao, + df_desfiliacao, + ) + ) if not error_msg: # passou pelo teste de intervalo mas a data de filiação é maior que # a ultima que está em aberto - if filiacoes.filter(data_desfiliacao__isnull=True, - data__lte=data_filiacao).exists(): - logger.error("Não pode haver um registro de filiação com data de " - "filiação igual ou superior a data de filiação em aberto ({})." - .format(data_filiacao)) - error_msg = _("Não pode haver um registro de filiação com data de \ - filiação igual ou superior a data de filiação em aberto.") + if filiacoes.filter( + data_desfiliacao__isnull=True, data__lte=data_filiacao + ).exists(): + logger.error( + "Não pode haver um registro de filiação com data de " + "filiação igual ou superior a data de filiação em aberto ({}).".format( + data_filiacao + ) + ) + error_msg = _( + "Não pode haver um registro de filiação com data de \ + filiação igual ou superior a data de filiação em aberto." + ) if error_msg: return [False, error_msg] - return [True, ''] + return [True, ""] class FiliacaoForm(ModelForm): - class Meta: model = Filiacao - fields = ['partido', - 'data', - 'data_desfiliacao'] - widgets = {'data': forms.DateInput(attrs={'autocomplete': 'off'}), - 'data_desfiliacao': forms.DateInput(attrs={'autocomplete': 'off'})} + fields = ["partido", "data", "data_desfiliacao"] + widgets = { + "data": forms.DateInput(attrs={"autocomplete": "off"}), + "data_desfiliacao": forms.DateInput(attrs={"autocomplete": "off"}), + } def clean(self): super(FiliacaoForm, self).clean() @@ -439,10 +534,12 @@ class FiliacaoForm(ModelForm): return self.cleaned_data filiacao = super(FiliacaoForm, self).save(commit=False) - validacao = validar_datas(self.cleaned_data['data'], - self.cleaned_data['data_desfiliacao'], - filiacao.parlamentar, - filiacao) + validacao = validar_datas( + self.cleaned_data["data"], + self.cleaned_data["data_desfiliacao"], + filiacao.parlamentar, + filiacao, + ) if not validacao[0]: raise ValidationError(validacao[1]) @@ -451,12 +548,11 @@ class FiliacaoForm(ModelForm): class ComposicaoColigacaoForm(ModelForm): - logger = logging.getLogger(__name__) class Meta: model = ComposicaoColigacao - fields = ['partido'] + fields = ["partido"] def clean(self): super(ComposicaoColigacaoForm, self).clean() @@ -465,13 +561,15 @@ class ComposicaoColigacaoForm(ModelForm): return self.cleaned_data cleaned_data = self.cleaned_data - pk = self.initial['coligacao_id'] - if (ComposicaoColigacao.objects.filter( - coligacao_id=pk, - partido=cleaned_data.get('partido')).exists()): - self.logger.error("Esse partido (coligacao_id={} e partido={}) já foi cadastrado " - "nesta coligação.".format(pk, cleaned_data.get('partido'))) - msg = _('Esse partido já foi cadastrado nesta coligação.') + pk = self.initial["coligacao_id"] + if ComposicaoColigacao.objects.filter( + coligacao_id=pk, partido=cleaned_data.get("partido") + ).exists(): + self.logger.error( + "Esse partido (coligacao_id={} e partido={}) já foi cadastrado " + "nesta coligação.".format(pk, cleaned_data.get("partido")) + ) + msg = _("Esse partido já foi cadastrado nesta coligação.") raise ValidationError(msg) return self.cleaned_data @@ -485,7 +583,7 @@ class FrenteForm(ModelForm): class Meta: model = Frente - fields = '__all__' + fields = "__all__" def clean(self): super(FrenteForm, self).clean() @@ -493,11 +591,15 @@ class FrenteForm(ModelForm): if not self.is_valid(): return self.cleaned_data - if cd['data_extincao'] and cd['data_criacao'] > cd['data_extincao']: - self.logger.error("Data Dissolução ({}) não pode ser anterior a Data Criação ({})." - .format(cd['data_extincao'], cd['data_criacao'])) + if cd["data_extincao"] and cd["data_criacao"] > cd["data_extincao"]: + self.logger.error( + "Data Dissolução ({}) não pode ser anterior a Data Criação ({}).".format( + cd["data_extincao"], cd["data_criacao"] + ) + ) raise ValidationError( - _("Data Dissolução não pode ser anterior a Data Criação")) + _("Data Dissolução não pode ser anterior a Data Criação") + ) return cd @@ -509,12 +611,12 @@ class FrenteForm(ModelForm): frente.save() content_type = ContentType.objects.get_for_model(Frente) object_id = frente.pk - tipo = TipoAutor.objects.get(descricao__icontains='Frente') + tipo = TipoAutor.objects.get(descricao__icontains="Frente") Autor.objects.create( content_type=content_type, object_id=object_id, tipo=tipo, - nome=frente.nome + nome=frente.nome, ) else: frente.save() @@ -526,47 +628,47 @@ class FrenteParlamentarForm(ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['frente'].widget = forms.HiddenInput() + self.fields["frente"].widget = forms.HiddenInput() class Meta: model = FrenteParlamentar - fields = '__all__' + fields = "__all__" def clean(self): cd = super().clean() if not self.is_valid(): return self.cleaned_data - if cd['cargo'].cargo_unico: + if cd["cargo"].cargo_unico: frente_parlamentar = FrenteParlamentar.objects.filter( - frente=cd['frente'], cargo=cd['cargo']) - if frente_parlamentar and not frente_parlamentar[0].parlamentar == cd['parlamentar']: + frente=cd["frente"], cargo=cd["cargo"] + ) + if ( + frente_parlamentar + and not frente_parlamentar[0].parlamentar == cd["parlamentar"] + ): raise ValidationError( - _("Cargo único já ocupado por outro parlamentar.")) + _("Cargo único já ocupado por outro parlamentar.") + ) return cd class VotanteForm(ModelForm): - - username = forms.CharField( - label=_('Usuário'), - required=True, - max_length=30) + username = forms.CharField(label=_("Usuário"), required=True, max_length=30) logger = logging.getLogger(__name__) class Meta: model = Votante - fields = ['username'] + fields = ["username"] def __init__(self, *args, **kwargs): - row1 = to_row([('username', 4)]) + row1 = to_row([("username", 4)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset(_('Votante'), - row1, form_actions(label='Salvar')) + Fieldset(_("Votante"), row1, form_actions(label="Salvar")) ) super(VotanteForm, self).__init__(*args, **kwargs) @@ -583,24 +685,37 @@ class VotanteForm(ModelForm): cd = self.cleaned_data - username = cd['username'] + username = cd["username"] user = get_user_model().objects.filter(username=username) if not user.exists(): self.logger.error( - "Não foi possível vincular usuário. Usuário {} não existe.".format(username)) - raise ValidationError(_( - "{} [{}] {}".format( - 'Não foi possível vincular usuário. Usuário', - username, - 'não existe'))) + "Não foi possível vincular usuário. Usuário {} não existe.".format( + username + ) + ) + raise ValidationError( + _( + "{} [{}] {}".format( + "Não foi possível vincular usuário. Usuário", + username, + "não existe", + ) + ) + ) if Votante.objects.filter(user=user[0].pk).exists(): - self.logger.error("Não foi possível vincular usuário. Usuário {} já está " - "vinculado à outro parlamentar.".format(username)) - raise ValidationError(_( - "{} [{}] {}".format( - 'Não foi possível vincular usuário. Usuário', - username, - 'já esta vinculado à outro parlamentar'))) + self.logger.error( + "Não foi possível vincular usuário. Usuário {} já está " + "vinculado à outro parlamentar.".format(username) + ) + raise ValidationError( + _( + "{} [{}] {}".format( + "Não foi possível vincular usuário. Usuário", + username, + "já esta vinculado à outro parlamentar", + ) + ) + ) return self.cleaned_data @@ -609,7 +724,7 @@ class VotanteForm(ModelForm): votante = super(VotanteForm, self).save(commit) # Cria user - u = User.objects.get(username=self.cleaned_data['username']) + u = User.objects.get(username=self.cleaned_data["username"]) # Adiciona user ao grupo g = Group.objects.filter(name=SAPL_GROUP_VOTANTE)[0] u.groups.add(g) @@ -626,38 +741,32 @@ class VincularParlamentarForm(forms.Form): label=Parlamentar._meta.verbose_name, queryset=Parlamentar.objects.filter(ativo=True), required=True, - empty_label='Selecione' + empty_label="Selecione", ) legislatura = forms.ModelChoiceField( label=Legislatura._meta.verbose_name, queryset=Legislatura.objects.all(), required=True, - empty_label='Selecione' + empty_label="Selecione", ) data_expedicao_diploma = forms.DateField( - label='Data de Expedição do Diploma', + label="Data de Expedição do Diploma", required=False, - widget=forms.DateInput(format='%d/%m/%Y') + widget=forms.DateInput(format="%d/%m/%Y"), ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - row1 = to_row([ - ('parlamentar', 6), - ('legislatura', 3), - ('data_expedicao_diploma', 3) - ]) + row1 = to_row( + [("parlamentar", 6), ("legislatura", 3), ("data_expedicao_diploma", 3)] + ) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset( - 'Vincular Parlamentar', - row1, - form_actions(label='Vincular') - ) + Fieldset("Vincular Parlamentar", row1, form_actions(label="Vincular")) ) def clean(self): @@ -667,30 +776,34 @@ class VincularParlamentarForm(forms.Form): return self.cleaned_data cleaned_data = self.cleaned_data - parlamentar = cleaned_data['parlamentar'] - legislatura = cleaned_data['legislatura'] - data_expedicao_diploma = cleaned_data['data_expedicao_diploma'] + parlamentar = cleaned_data["parlamentar"] + legislatura = cleaned_data["legislatura"] + data_expedicao_diploma = cleaned_data["data_expedicao_diploma"] if parlamentar.mandato_set.filter(legislatura=legislatura): - self.logger.error( - 'Parlamentar já está vinculado a legislatura informada.') + self.logger.error("Parlamentar já está vinculado a legislatura informada.") raise ValidationError( - _('Parlamentar já está vinculado a legislatura informada.')) - elif data_expedicao_diploma and legislatura.data_inicio <= data_expedicao_diploma: + _("Parlamentar já está vinculado a legislatura informada.") + ) + elif ( + data_expedicao_diploma and legislatura.data_inicio <= data_expedicao_diploma + ): self.logger.error( - 'Data da Expedição do Diploma deve ser anterior a data de início da Legislatura.') + "Data da Expedição do Diploma deve ser anterior a data de início da Legislatura." + ) raise ValidationError( - _('Data da Expedição do Diploma deve ser anterior a data de início da Legislatura.')) + _( + "Data da Expedição do Diploma deve ser anterior a data de início da Legislatura." + ) + ) return cleaned_data class BlocoForm(ModelForm): - class Meta: model = Bloco - fields = ['nome', 'partidos', 'data_criacao', - 'data_extincao', 'descricao'] + fields = ["nome", "partidos", "data_criacao", "data_extincao", "descricao"] def clean(self): super(BlocoForm, self).clean() @@ -698,10 +811,9 @@ class BlocoForm(ModelForm): if not self.is_valid(): return self.cleaned_data - if self.cleaned_data['data_extincao']: - if (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') + if self.cleaned_data["data_extincao"]: + if 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") raise ValidationError(msg) return self.cleaned_data @@ -717,12 +829,12 @@ class BlocoForm(ModelForm): content_type=content_type, object_id=object_id, tipo=tipo, - nome=bloco.nome + nome=bloco.nome, ) else: bloco.save() - bloco.partidos.set(self.cleaned_data['partidos']) + bloco.partidos.set(self.cleaned_data["partidos"]) return bloco @@ -731,24 +843,32 @@ class BlocoMembroForm(ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['bloco'].widget = forms.HiddenInput() + self.fields["bloco"].widget = forms.HiddenInput() class Meta: model = BlocoMembro - fields = '__all__' + fields = "__all__" def clean(self): cd = super().clean() if not self.is_valid(): return self.cleaned_data - if cd['cargo'].cargo_unico \ - and BlocoMembro.objects.filter(bloco=cd['bloco'], cargo=cd['cargo'], data_saida__isnull=True)\ - .exclude(pk=self.instance.pk).exists(): - raise ValidationError( - _("Cargo único já ocupado por outro membro.")) - elif not cd['data_saida'] and BlocoMembro.objects.filter(parlamentar=cd['parlamentar'], data_saida__isnull=True).exists(): - raise ValidationError( - _("Parlamentar já é membro do bloco parlamentar.")) + if ( + cd["cargo"].cargo_unico + and BlocoMembro.objects.filter( + bloco=cd["bloco"], cargo=cd["cargo"], data_saida__isnull=True + ) + .exclude(pk=self.instance.pk) + .exists() + ): + raise ValidationError(_("Cargo único já ocupado por outro membro.")) + elif ( + not cd["data_saida"] + and BlocoMembro.objects.filter( + parlamentar=cd["parlamentar"], data_saida__isnull=True + ).exists() + ): + raise ValidationError(_("Parlamentar já é membro do bloco parlamentar.")) return cd diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index f8c6a065a..4d85bfc35 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -1,4 +1,3 @@ - from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ @@ -15,19 +14,18 @@ from sapl.utils import (LISTA_DE_UFS, YES_NO_CHOICES, SaplGenericRelation, class Legislatura(models.Model): - numero = models.PositiveIntegerField(verbose_name=_('Número')) - data_inicio = models.DateField(verbose_name=_('Data Início')) - data_fim = models.DateField(verbose_name=_('Data Fim')) - data_eleicao = models.DateField(verbose_name=_('Data Eleição')) + numero = models.PositiveIntegerField(verbose_name=_("Número")) + data_inicio = models.DateField(verbose_name=_("Data Início")) + data_fim = models.DateField(verbose_name=_("Data Fim")) + data_eleicao = models.DateField(verbose_name=_("Data Eleição")) - observacao = models.TextField( - blank=True, verbose_name=_('Observação')) + observacao = models.TextField(blank=True, verbose_name=_("Observação")) class Meta: - ordering = ['-data_inicio'] - verbose_name = _('Legislatura') - verbose_name_plural = _('Legislaturas') - ordering = ('-numero', '-data_inicio', '-data_fim') + ordering = ["-data_inicio"] + verbose_name = _("Legislatura") + verbose_name_plural = _("Legislaturas") + ordering = ("-numero", "-data_inicio", "-data_fim") def atual(self): current_year = timezone.now().year @@ -39,381 +37,400 @@ class Legislatura(models.Model): def __str__(self): if not self.data_fim: self.data_fim = timezone.now().date() - return _('%(numero)sª (%(start)s - %(end)s)') % { - 'numero': self.numero, - 'start': self.data_inicio.year, - 'end': self.data_fim.year} + return _("%(numero)sª (%(start)s - %(end)s)") % { + "numero": self.numero, + "start": self.data_inicio.year, + "end": self.data_fim.year, + } class SessaoLegislativa(models.Model): TIPO_SESSAO_CHOICES = Choices( - ('O', 'ordinaria', _('Ordinária')), - ('E', 'extraordinaria', _('Extraordinária')), + ("O", "ordinaria", _("Ordinária")), + ("E", "extraordinaria", _("Extraordinária")), ) legislatura = models.ForeignKey( Legislatura, on_delete=models.PROTECT, - verbose_name=Legislatura._meta.verbose_name) - numero = models.PositiveIntegerField(verbose_name=_('Número')) + verbose_name=Legislatura._meta.verbose_name, + ) + numero = models.PositiveIntegerField(verbose_name=_("Número")) tipo = models.CharField( - max_length=1, verbose_name=_('Tipo'), choices=TIPO_SESSAO_CHOICES) - data_inicio = models.DateField(verbose_name=_('Data Início')) - data_fim = models.DateField(verbose_name=_('Data Fim')) + max_length=1, verbose_name=_("Tipo"), choices=TIPO_SESSAO_CHOICES + ) + data_inicio = models.DateField(verbose_name=_("Data Início")) + data_fim = models.DateField(verbose_name=_("Data Fim")) data_inicio_intervalo = models.DateField( - blank=True, null=True, verbose_name=_('Início Intervalo')) + blank=True, null=True, verbose_name=_("Início Intervalo") + ) data_fim_intervalo = models.DateField( - blank=True, null=True, verbose_name=_('Fim Intervalo')) + blank=True, null=True, verbose_name=_("Fim Intervalo") + ) class Meta: - verbose_name = _('Sessão Legislativa') - verbose_name_plural = _('Sessões Legislativas') - ordering = ['-data_inicio', '-data_fim'] + verbose_name = _("Sessão Legislativa") + verbose_name_plural = _("Sessões Legislativas") + ordering = ["-data_inicio", "-data_fim"] @vigencia_atual def __str__(self): - return _('%(numero)sº (%(inicio)s - %(fim)s)') % { - 'numero': self.numero, - 'inicio': self.data_inicio.year, - 'fim': self.data_fim.year} + return _("%(numero)sº (%(inicio)s - %(fim)s)") % { + "numero": self.numero, + "inicio": self.data_inicio.year, + "fim": self.data_fim.year, + } class Coligacao(models.Model): - legislatura = models.ForeignKey(Legislatura, - on_delete=models.PROTECT, - verbose_name=_('Legislatura')) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) + legislatura = models.ForeignKey( + Legislatura, on_delete=models.PROTECT, verbose_name=_("Legislatura") + ) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) numero_votos = models.PositiveIntegerField( - blank=True, null=True, - verbose_name=_('Nº Votos Recebidos (Coligação)')) + blank=True, null=True, verbose_name=_("Nº Votos Recebidos (Coligação)") + ) class Meta: - verbose_name = _('Coligação') - verbose_name_plural = _('Coligações') - ordering = ('legislatura', 'nome') + verbose_name = _("Coligação") + verbose_name_plural = _("Coligações") + ordering = ("legislatura", "nome") def __str__(self): return self.nome def get_logo_media_path(instance, subpath, filename): - return './sapl/partidos/%s/%s/%s' % (instance, subpath, filename) + return "./sapl/partidos/%s/%s/%s" % (instance, subpath, filename) def logo_upload_path(instance, filename): - return get_logo_media_path(instance, 'logo', filename) + return get_logo_media_path(instance, "logo", filename) class Partido(models.Model): - sigla = models.CharField(max_length=20, verbose_name=_('Sigla')) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) + sigla = models.CharField(max_length=20, verbose_name=_("Sigla")) + nome = models.CharField(max_length=50, verbose_name=_("Nome")) data_criacao = models.DateField( - blank=True, null=True, verbose_name=_('Data Criação')) + blank=True, null=True, verbose_name=_("Data Criação") + ) data_extincao = models.DateField( - blank=True, null=True, verbose_name=_('Data Extinção')) + blank=True, null=True, verbose_name=_("Data Extinção") + ) logo_partido = models.ImageField( blank=True, null=True, upload_to=logo_upload_path, - verbose_name=_('Logo Partido'), - validators=[restringe_tipos_de_arquivo_img]) - observacao = models.TextField( - blank=True, verbose_name=_('Observação')) + verbose_name=_("Logo Partido"), + validators=[restringe_tipos_de_arquivo_img], + ) + observacao = models.TextField(blank=True, verbose_name=_("Observação")) class Meta: - verbose_name = _('Partido') - verbose_name_plural = _('Partidos') - ordering = ['sigla', 'nome'] + verbose_name = _("Partido") + verbose_name_plural = _("Partidos") + ordering = ["sigla", "nome"] def __str__(self): - return _('%(sigla)s - %(nome)s') % { - 'sigla': self.sigla, 'nome': self.nome - } + return _("%(sigla)s - %(nome)s") % {"sigla": self.sigla, "nome": self.nome} class ComposicaoColigacao(models.Model): # TODO M2M - partido = models.ForeignKey(Partido, - on_delete=models.PROTECT, - verbose_name=_('Partidos da Coligação')) + partido = models.ForeignKey( + Partido, on_delete=models.PROTECT, verbose_name=_("Partidos da Coligação") + ) coligacao = models.ForeignKey(Coligacao, on_delete=models.PROTECT) class Meta: - verbose_name = (_('Composição Coligação')) - verbose_name_plural = (_('Composição Coligações')) - ordering = ('partido',) + verbose_name = _("Composição Coligação") + verbose_name_plural = _("Composição Coligações") + ordering = ("partido",) def __str__(self): - return _('%(partido)s - %(coligacao)s') % { - 'partido': self.partido, 'coligacao': self.coligacao + return _("%(partido)s - %(coligacao)s") % { + "partido": self.partido, + "coligacao": self.coligacao, } class NivelInstrucao(models.Model): - descricao = models.CharField( - max_length=50, verbose_name=_('Nível de Instrução')) + descricao = models.CharField(max_length=50, verbose_name=_("Nível de Instrução")) class Meta: - ordering = ['descricao'] - verbose_name = _('Nível Instrução') - verbose_name_plural = _('Níveis Instrução') + ordering = ["descricao"] + verbose_name = _("Nível Instrução") + verbose_name_plural = _("Níveis Instrução") def __str__(self): return self.descricao class SituacaoMilitar(models.Model): - descricao = models.CharField( - max_length=50, verbose_name=_('Situação Militar')) + descricao = models.CharField(max_length=50, verbose_name=_("Situação Militar")) class Meta: - verbose_name = _('Tipo Situação Militar') - verbose_name_plural = _('Tipos Situações Militares') - ordering = ['descricao'] + verbose_name = _("Tipo Situação Militar") + verbose_name_plural = _("Tipos Situações Militares") + ordering = ["descricao"] def __str__(self): return self.descricao def foto_upload_path(instance, filename): - return texto_upload_path(instance, filename, subpath='') + return texto_upload_path(instance, filename, subpath="") def true_false_none(x): - if x == 'True': + if x == "True": return True - elif x == 'False': + elif x == "False": return False else: return None class Parlamentar(models.Model): - FEMININO = 'F' - MASCULINO = 'M' - SEXO_CHOICE = ((FEMININO, _('Feminino')), - (MASCULINO, _('Masculino'))) + FEMININO = "F" + MASCULINO = "M" + SEXO_CHOICE = ((FEMININO, _("Feminino")), (MASCULINO, _("Masculino"))) nivel_instrucao = models.ForeignKey( NivelInstrucao, blank=True, null=True, on_delete=models.PROTECT, - verbose_name=_('Nível Instrução')) + verbose_name=_("Nível Instrução"), + ) situacao_militar = models.ForeignKey( SituacaoMilitar, blank=True, null=True, on_delete=models.PROTECT, - verbose_name=_('Situação Militar')) - nome_completo = models.CharField( - max_length=50, verbose_name=_('Nome Completo')) + verbose_name=_("Situação Militar"), + ) + nome_completo = models.CharField(max_length=50, verbose_name=_("Nome Completo")) nome_parlamentar = models.CharField( - max_length=50, - verbose_name=_('Nome Parlamentar')) - sexo = models.CharField( - max_length=1, verbose_name=_('Sexo'), choices=SEXO_CHOICE) + max_length=50, verbose_name=_("Nome Parlamentar") + ) + sexo = models.CharField(max_length=1, verbose_name=_("Sexo"), choices=SEXO_CHOICE) data_nascimento = models.DateField( - blank=True, null=True, verbose_name=_('Data Nascimento')) - cpf = models.CharField( - max_length=14, blank=True, verbose_name=_('C.P.F')) - rg = models.CharField( - max_length=20, blank=True, verbose_name=_('R.G.')) + blank=True, null=True, verbose_name=_("Data Nascimento") + ) + cpf = models.CharField(max_length=14, blank=True, verbose_name=_("C.P.F")) + rg = models.CharField(max_length=20, blank=True, verbose_name=_("R.G.")) titulo_eleitor = models.CharField( - max_length=25, - blank=True, - verbose_name=_('Título de Eleitor')) + max_length=25, blank=True, verbose_name=_("Título de Eleitor") + ) numero_gab_parlamentar = models.CharField( - max_length=10, blank=True, verbose_name=_('Nº Gabinete')) - telefone = models.CharField( - max_length=50, blank=True, verbose_name=_('Telefone')) + max_length=10, blank=True, verbose_name=_("Nº Gabinete") + ) + telefone = models.CharField(max_length=50, blank=True, verbose_name=_("Telefone")) telefone_celular = models.CharField( - max_length=50, blank=True, verbose_name=_('Telefone Celular')) - fax = models.CharField( - max_length=50, blank=True, verbose_name=_('Fax')) + max_length=50, blank=True, verbose_name=_("Telefone Celular") + ) + fax = models.CharField(max_length=50, blank=True, verbose_name=_("Fax")) endereco_residencia = models.CharField( - max_length=100, - blank=True, - verbose_name=_('Endereço Residencial')) + max_length=100, blank=True, verbose_name=_("Endereço Residencial") + ) municipio_residencia = models.CharField( - max_length=50, blank=True, verbose_name=_('Município')) + max_length=50, blank=True, verbose_name=_("Município") + ) uf_residencia = models.CharField( - max_length=2, blank=True, choices=LISTA_DE_UFS, verbose_name=_('UF')) - cep_residencia = models.CharField( - max_length=9, blank=True, verbose_name=_('CEP')) + max_length=2, blank=True, choices=LISTA_DE_UFS, verbose_name=_("UF") + ) + cep_residencia = models.CharField(max_length=9, blank=True, verbose_name=_("CEP")) telefone_residencia = models.CharField( - max_length=50, - blank=True, - verbose_name=_('Telefone Residencial')) + max_length=50, blank=True, verbose_name=_("Telefone Residencial") + ) fax_residencia = models.CharField( - max_length=50, - blank=True, - verbose_name=_('Fax Residencial')) + max_length=50, blank=True, verbose_name=_("Fax Residencial") + ) endereco_web = models.URLField( - max_length=100, blank=True, verbose_name=_('HomePage')) - profissao = models.CharField( - max_length=50, blank=True, verbose_name=_('Profissão')) - email = models.EmailField( - max_length=100, - blank=True, - verbose_name=_('E-mail')) + max_length=100, blank=True, verbose_name=_("HomePage") + ) + profissao = models.CharField(max_length=50, blank=True, verbose_name=_("Profissão")) + email = models.EmailField(max_length=100, blank=True, verbose_name=_("E-mail")) locais_atuacao = models.CharField( - max_length=100, - blank=True, - verbose_name=_('Locais de Atuação')) + max_length=100, blank=True, verbose_name=_("Locais de Atuação") + ) ativo = models.BooleanField( db_index=True, default=False, choices=YES_NO_CHOICES, - verbose_name=_('Ativo na Casa?')) - biografia = models.TextField( - blank=True, verbose_name=_('Biografia')) + verbose_name=_("Ativo na Casa?"), + ) + biografia = models.TextField(blank=True, verbose_name=_("Biografia")) fotografia = ImageCropField( - verbose_name=_('Fotografia'), upload_to=foto_upload_path, - validators=[restringe_tipos_de_arquivo_img], null=True, blank=True) + verbose_name=_("Fotografia"), + upload_to=foto_upload_path, + validators=[restringe_tipos_de_arquivo_img], + null=True, + blank=True, + ) cropping = ImageRatioField( - 'fotografia', '128x128', verbose_name=_('Avatar'), size_warning=True, - help_text=_('A configuração do Avatar ' - 'é possível após a atualização da fotografia.')) + "fotografia", + "128x128", + verbose_name=_("Avatar"), + size_warning=True, + help_text=_( + "A configuração do Avatar " "é possível após a atualização da fotografia." + ), + ) # campo conceitual de reversão genérica para o model Autor que dá a # o meio possível de localização de tipos de autores. autor = SaplGenericRelation( Autor, - related_query_name='parlamentar_set', + related_query_name="parlamentar_set", fields_search=( # na primeira posição dever ser campo simples sem __ - ('nome_completo', '__icontains'), - ('nome_parlamentar', '__icontains'), - ('filiacao__partido__sigla', '__icontains'), - )) + ("nome_completo", "__icontains"), + ("nome_parlamentar", "__icontains"), + ("filiacao__partido__sigla", "__icontains"), + ), + ) class Meta: - verbose_name = _('Parlamentar') - verbose_name_plural = _('Parlamentares') - ordering = ['nome_parlamentar'] + verbose_name = _("Parlamentar") + verbose_name_plural = _("Parlamentares") + ordering = ["nome_parlamentar"] def __str__(self): return self.nome_parlamentar @property def filiacao_atual(self): - ultima_filiacao = self.filiacao_set.order_by('-data').first() + ultima_filiacao = self.filiacao_set.order_by("-data").first() if ultima_filiacao and not ultima_filiacao.data_desfiliacao: return ultima_filiacao.partido.sigla else: - return _('Sem Partido') + return _("Sem Partido") @property def avatar_html(self): - return ''if self.fotografia else '' + return ( + '/materias', - ParlamentarMateriasView.as_view(), name='parlamentar_materias'), - - path('parlamentar//normas', - ParlamentarNormasView.as_view(), name='parlamentar_normas'), - - path('parlamentar//frentes/', - get_parlamentar_frentes, name='parlamentar_frentes'), - - path('parlamentar/vincular-parlamentar/', - VincularParlamentarView.as_view(), name='vincular_parlamentar'), - - re_path(r'^parlamentar/coligacao-legislatura/', - coligacao_legislatura, name="coligacao_legislatura"), - path('sistema/coligacao/', include(ColigacaoCrud.get_urls() + - ComposicaoColigacaoCrud.get_urls())), - re_path(r'^sistema/pesquisar-coligacao/', - PesquisarColigacaoView.as_view(), name='pesquisar_coligacao'), - - path('sistema/coligacao/', include(ColigacaoCrud.get_urls() + - ComposicaoColigacaoCrud.get_urls())), - - path('sistema/bloco/', include(BlocoCrud.get_urls())), - path('sistema/bloco-cargo/', include(BlocoCargoCrud.get_urls())), - path('sistema/bloco-membros/', include(BlocoMembroCrud.get_urls())), - - path('sistema/frente/', include(FrenteCrud.get_urls())), - path('sistema/frente-cargo/', include(FrenteCargoCrud.get_urls())), - path('sistema/frente-parlamentares/', - include(FrenteParlamentarCrud.get_urls())), - - re_path(r'^sistema/frente/atualiza-lista-parlamentares', + path( + "parlamentar/", + include( + ParlamentarCrud.get_urls() + + DependenteCrud.get_urls() + + FiliacaoCrud.get_urls() + + MandatoCrud.get_urls() + + ParticipacaoParlamentarCrud.get_urls() + + ProposicaoParlamentarCrud.get_urls() + + RelatoriaParlamentarCrud.get_urls() + + VotanteView.get_urls() + ), + ), + re_path( + r"^parlamentar/pesquisar-parlamentar/", + PesquisarParlamentarView.as_view(), + name="pesquisar_parlamentar", + ), + path( + "parlamentar//materias", + ParlamentarMateriasView.as_view(), + name="parlamentar_materias", + ), + path( + "parlamentar//normas", + ParlamentarNormasView.as_view(), + name="parlamentar_normas", + ), + path( + "parlamentar//frentes/", + get_parlamentar_frentes, + name="parlamentar_frentes", + ), + path( + "parlamentar/vincular-parlamentar/", + VincularParlamentarView.as_view(), + name="vincular_parlamentar", + ), + re_path( + r"^parlamentar/coligacao-legislatura/", + coligacao_legislatura, + name="coligacao_legislatura", + ), + path( + "sistema/coligacao/", + include(ColigacaoCrud.get_urls() + ComposicaoColigacaoCrud.get_urls()), + ), + re_path( + r"^sistema/pesquisar-coligacao/", + PesquisarColigacaoView.as_view(), + name="pesquisar_coligacao", + ), + path( + "sistema/coligacao/", + include(ColigacaoCrud.get_urls() + ComposicaoColigacaoCrud.get_urls()), + ), + path("sistema/bloco/", include(BlocoCrud.get_urls())), + path("sistema/bloco-cargo/", include(BlocoCargoCrud.get_urls())), + path("sistema/bloco-membros/", include(BlocoMembroCrud.get_urls())), + path("sistema/frente/", include(FrenteCrud.get_urls())), + path("sistema/frente-cargo/", include(FrenteCargoCrud.get_urls())), + path("sistema/frente-parlamentares/", include(FrenteParlamentarCrud.get_urls())), + re_path( + r"^sistema/frente/atualiza-lista-parlamentares", frente_atualiza_lista_parlamentares, - name='atualiza_lista_parlamentares'), - re_path(r'^sistema/frente/parlamentares-frente-selected', + name="atualiza_lista_parlamentares", + ), + re_path( + r"^sistema/frente/parlamentares-frente-selected", parlamentares_frente_selected, - name='parlamentares_frente_selected'), - - path('sistema/parlamentar/legislatura/', - include(LegislaturaCrud.get_urls())), - path('sistema/parlamentar/tipo-dependente/', - include(TipoDependenteCrud.get_urls())), - path('sistema/parlamentar/nivel-instrucao/', - include(NivelInstrucaoCrud.get_urls())), - path('sistema/parlamentar/tipo-afastamento/', - include(TipoAfastamentoCrud.get_urls())), - path('sistema/parlamentar/tipo-militar/', - include(TipoMilitarCrud.get_urls())), - - path('sistema/parlamentar/partido/', include(PartidoCrud.get_urls())), - re_path(r'^sistema/parlamentar/pesquisar-partido/', - PesquisarPartidoView.as_view(), name='pesquisar_partido'), - path('sistema/parlamentar/partido//filiados', - parlamentares_filiados, name='parlamentares_filiados'), - - path('sistema/mesa-diretora/sessao-legislativa/', - include(SessaoLegislativaCrud.get_urls())), - path('sistema/mesa-diretora/cargo-mesa/', - include(CargoMesaCrud.get_urls())), - - path('mesa-diretora/', - MesaDiretoraView.as_view(), name='mesa_diretora'), - - path('mesa-diretora/altera-field-mesa/', - altera_field_mesa, name='altera_field_mesa'), - - path('mesa-diretora/altera-field-mesa-public-view/', - altera_field_mesa_public_view, name='altera_field_mesa_public_view'), - - path('mesa-diretora/insere-parlamentar-composicao/', - insere_parlamentar_composicao, name='insere_parlamentar_composicao'), - - path('mesa-diretora/remove-parlamentar-composicao/', - remove_parlamentar_composicao, name='remove_parlamentar_composicao'), - - path('parlamentar/get-sessoes-legislatura/', - get_sessoes_legislatura, name='get_sessoes_legislatura'), - + name="parlamentares_frente_selected", + ), + path("sistema/parlamentar/legislatura/", include(LegislaturaCrud.get_urls())), + path( + "sistema/parlamentar/tipo-dependente/", include(TipoDependenteCrud.get_urls()) + ), + path( + "sistema/parlamentar/nivel-instrucao/", include(NivelInstrucaoCrud.get_urls()) + ), + path( + "sistema/parlamentar/tipo-afastamento/", include(TipoAfastamentoCrud.get_urls()) + ), + path("sistema/parlamentar/tipo-militar/", include(TipoMilitarCrud.get_urls())), + path("sistema/parlamentar/partido/", include(PartidoCrud.get_urls())), + re_path( + r"^sistema/parlamentar/pesquisar-partido/", + PesquisarPartidoView.as_view(), + name="pesquisar_partido", + ), + path( + "sistema/parlamentar/partido//filiados", + parlamentares_filiados, + name="parlamentares_filiados", + ), + path( + "sistema/mesa-diretora/sessao-legislativa/", + include(SessaoLegislativaCrud.get_urls()), + ), + path("sistema/mesa-diretora/cargo-mesa/", include(CargoMesaCrud.get_urls())), + path("mesa-diretora/", MesaDiretoraView.as_view(), name="mesa_diretora"), + path( + "mesa-diretora/altera-field-mesa/", altera_field_mesa, name="altera_field_mesa" + ), + path( + "mesa-diretora/altera-field-mesa-public-view/", + altera_field_mesa_public_view, + name="altera_field_mesa_public_view", + ), + path( + "mesa-diretora/insere-parlamentar-composicao/", + insere_parlamentar_composicao, + name="insere_parlamentar_composicao", + ), + path( + "mesa-diretora/remove-parlamentar-composicao/", + remove_parlamentar_composicao, + name="remove_parlamentar_composicao", + ), + path( + "parlamentar/get-sessoes-legislatura/", + get_sessoes_legislatura, + name="get_sessoes_legislatura", + ), ] diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index 4c135f328..6844350d0 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -1,6 +1,6 @@ -from datetime import datetime import json import logging +from datetime import datetime from django.contrib import messages from django.contrib.auth.mixins import PermissionRequiredMixin @@ -23,7 +23,7 @@ from django.views.generic.edit import UpdateView from django_filters.views import FilterView from image_cropping.utils import get_backend -from sapl.base.forms import SessaoLegislativaForm, PartidoForm +from sapl.base.forms import PartidoForm, SessaoLegislativaForm from sapl.base.models import Autor from sapl.comissoes.models import Participacao from sapl.crud.base import (RP_CHANGE, RP_DETAIL, RP_LIST, Crud, CrudAux, @@ -33,28 +33,29 @@ from sapl.materia.models import Autoria, Proposicao, Relatoria from sapl.norma.models import AutoriaNorma, NormaJuridica from sapl.parlamentares.apps import AppConfig from sapl.rules import SAPL_GROUP_VOTANTE -from sapl.utils import (parlamentares_ativos, show_results_filter_set) - -from .forms import (ColigacaoFilterSet, FiliacaoForm, FrenteForm, LegislaturaForm, MandatoForm, - ParlamentarCreateForm, ParlamentarForm, VotanteForm, - ParlamentarFilterSet, PartidoFilterSet, VincularParlamentarForm, - BlocoForm, FrenteParlamentarForm, BlocoMembroForm) -from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, - Dependente, Filiacao, Frente, Legislatura, Mandato, - NivelInstrucao, Parlamentar, Partido, SessaoLegislativa, - SituacaoMilitar, TipoAfastamento, TipoDependente, Votante, - Bloco, FrenteCargo, FrenteParlamentar, BlocoCargo, BlocoMembro, MesaDiretora) - -FrenteCargoCrud = CrudAux.build(FrenteCargo, 'frente_cargo') -BlocoCargoCrud = CrudAux.build(BlocoCargo, 'bloco_cargo') -CargoMesaCrud = CrudAux.build(CargoMesa, 'cargo_mesa') -TipoDependenteCrud = CrudAux.build(TipoDependente, 'tipo_dependente') -NivelInstrucaoCrud = CrudAux.build(NivelInstrucao, 'nivel_instrucao') -TipoAfastamentoCrud = CrudAux.build(TipoAfastamento, 'tipo_afastamento') -TipoMilitarCrud = CrudAux.build(SituacaoMilitar, 'tipo_situa_militar') - -DependenteCrud = MasterDetailCrud.build( - Dependente, 'parlamentar', 'dependente') +from sapl.utils import parlamentares_ativos, show_results_filter_set + +from .forms import (BlocoForm, BlocoMembroForm, ColigacaoFilterSet, + FiliacaoForm, FrenteForm, FrenteParlamentarForm, + LegislaturaForm, MandatoForm, ParlamentarCreateForm, + ParlamentarFilterSet, ParlamentarForm, PartidoFilterSet, + VincularParlamentarForm, VotanteForm) +from .models import (Bloco, BlocoCargo, BlocoMembro, CargoMesa, Coligacao, + ComposicaoColigacao, ComposicaoMesa, Dependente, Filiacao, + Frente, FrenteCargo, FrenteParlamentar, Legislatura, + Mandato, MesaDiretora, NivelInstrucao, Parlamentar, + Partido, SessaoLegislativa, SituacaoMilitar, + TipoAfastamento, TipoDependente, Votante) + +FrenteCargoCrud = CrudAux.build(FrenteCargo, "frente_cargo") +BlocoCargoCrud = CrudAux.build(BlocoCargo, "bloco_cargo") +CargoMesaCrud = CrudAux.build(CargoMesa, "cargo_mesa") +TipoDependenteCrud = CrudAux.build(TipoDependente, "tipo_dependente") +NivelInstrucaoCrud = CrudAux.build(NivelInstrucao, "nivel_instrucao") +TipoAfastamentoCrud = CrudAux.build(TipoAfastamento, "tipo_afastamento") +TipoMilitarCrud = CrudAux.build(SituacaoMilitar, "tipo_situa_militar") + +DependenteCrud = MasterDetailCrud.build(Dependente, "parlamentar", "dependente") class SessaoLegislativaCrud(CrudAux): @@ -78,28 +79,26 @@ class PartidoCrud(CrudAux): class DeleteView(CrudAux.DeleteView): def get_success_url(self): - return reverse('sapl.parlamentares:pesquisar_partido') + return reverse("sapl.parlamentares:pesquisar_partido") class VotanteView(MasterDetailCrud): model = Votante - parent_field = 'parlamentar' + parent_field = "parlamentar" UpdateView = None class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['user'] + list_field_names = ["user"] class CreateView(MasterDetailCrud.CreateView): form_class = VotanteForm layout_key = None class DetailView(MasterDetailCrud.DetailView): - def detail_create_url(self): return None class DeleteView(MasterDetailCrud.DeleteView): - def delete(self, *args, **kwargs): obj = self.get_object() @@ -108,79 +107,85 @@ class VotanteView(MasterDetailCrud): obj.delete() return HttpResponseRedirect( - reverse('sapl.parlamentares:votante_list', - kwargs={'pk': obj.parlamentar.pk})) + reverse( + "sapl.parlamentares:votante_list", kwargs={"pk": obj.parlamentar.pk} + ) + ) class FrenteList(MasterDetailCrud): public = [RP_DETAIL, RP_LIST] model = Frente is_m2m = True - parent_field = 'parlamentares' + parent_field = "parlamentares" CreateView, UpdateView, DeleteView = None, None, None class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['nome', 'data_criacao', 'data_extincao'] + list_field_names = ["nome", "data_criacao", "data_extincao"] @classmethod def url_name(cls, suffix): - return '%s_parlamentar_%s' % (cls.model._meta.model_name, suffix) + return "%s_parlamentar_%s" % (cls.model._meta.model_name, suffix) class RelatoriaParlamentarCrud(CrudBaseForListAndDetailExternalAppView): public = [RP_DETAIL, RP_LIST] model = Relatoria - parent_field = 'parlamentar' - help_topic = 'tramitacao_relatoria' + parent_field = "parlamentar" + help_topic = "tramitacao_relatoria" namespace = AppConfig.name class BaseMixin(CrudBaseForListAndDetailExternalAppView.BaseMixin): - @classmethod def url_name(cls, suffix): - return '%s_parlamentar_%s' % (cls.model._meta.model_name, suffix) + return "%s_parlamentar_%s" % (cls.model._meta.model_name, suffix) class ProposicaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView): model = Proposicao - list_field_names = ['tipo', 'descricao'] - parent_field = 'autor__parlamentar_set' + list_field_names = ["tipo", "descricao"] + parent_field = "autor__parlamentar_set" namespace = AppConfig.name class BaseMixin(CrudBaseForListAndDetailExternalAppView.BaseMixin): - @classmethod def url_name(cls, suffix): - return '%s_parlamentar_%s' % (cls.model._meta.model_name, suffix) + return "%s_parlamentar_%s" % (cls.model._meta.model_name, suffix) class ListView(CrudBaseForListAndDetailExternalAppView.ListView): - def get_context_data(self, **kwargs): - context = CrudBaseForListAndDetailExternalAppView \ - .ListView.get_context_data(self, **kwargs) + context = CrudBaseForListAndDetailExternalAppView.ListView.get_context_data( + self, **kwargs + ) return context def get_queryset(self): - return super().get_queryset().filter( - data_envio__isnull=False, - data_recebimento__isnull=False, - cancelado=False) + return ( + super() + .get_queryset() + .filter( + data_envio__isnull=False, + data_recebimento__isnull=False, + cancelado=False, + ) + ) class DetailView(CrudBaseForListAndDetailExternalAppView.DetailView): - def get_queryset(self): - return super().get_queryset().filter( - cancelado=False) + return super().get_queryset().filter(cancelado=False) @property def extras_url(self): if self.object.texto_articulado.exists(): ta = self.object.texto_articulado.first() - yield (str(reverse_lazy( - 'sapl.compilacao:ta_text', - kwargs={'ta_id': ta.pk})) + '?back_type=history', - 'btn-success', - _('Texto Eletrônico')) + yield ( + str( + reverse_lazy("sapl.compilacao:ta_text", kwargs={"ta_id": ta.pk}) + ) + + "?back_type=history", + "btn-success", + _("Texto Eletrônico"), + ) class PesquisarParlamentarView(FilterView): @@ -189,31 +194,30 @@ class PesquisarParlamentarView(FilterView): paginate_by = 20 def get_filterset_kwargs(self, filterset_class): - super(PesquisarParlamentarView, - self).get_filterset_kwargs(filterset_class) + super(PesquisarParlamentarView, self).get_filterset_kwargs(filterset_class) - kwargs = {'data': self.request.GET or None} + kwargs = {"data": self.request.GET or None} - qs = self.get_queryset().order_by('nome_parlamentar').distinct() + qs = self.get_queryset().order_by("nome_parlamentar").distinct() - kwargs.update({ - 'queryset': qs, - }) + kwargs.update( + { + "queryset": qs, + } + ) return kwargs def get_context_data(self, **kwargs): - context = super(PesquisarParlamentarView, - self).get_context_data(**kwargs) + context = super(PesquisarParlamentarView, self).get_context_data(**kwargs) - paginator = context['paginator'] - page_obj = context['page_obj'] + paginator = context["paginator"] + page_obj = context["page_obj"] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) - context['NO_ENTRIES_MSG'] = 'Nenhum parlamentar encontrado!' + context["NO_ENTRIES_MSG"] = "Nenhum parlamentar encontrado!" - context['title'] = _('Parlamentares') + context["title"] = _("Parlamentares") return context @@ -221,26 +225,28 @@ class PesquisarParlamentarView(FilterView): super(PesquisarParlamentarView, self).get(request) data = self.filterset.data - url = '' + url = "" if data: - url = "&" + str(self.request.META['QUERY_STRING']) + url = "&" + str(self.request.META["QUERY_STRING"]) if url.startswith("&page"): - url = '' + url = "" - if 'nome_parlamentar' in self.request.META['QUERY_STRING'] or\ - 'page' in self.request.META['QUERY_STRING']: + if ( + "nome_parlamentar" in self.request.META["QUERY_STRING"] + or "page" in self.request.META["QUERY_STRING"] + ): resultados = self.object_list else: resultados = [] - context = self.get_context_data(filter=self.filterset, - object_list=resultados, - filter_url=url, - numero_res=len(resultados) - ) + context = self.get_context_data( + filter=self.filterset, + object_list=resultados, + filter_url=url, + numero_res=len(resultados), + ) - context['show_results'] = show_results_filter_set( - self.request.GET.copy()) + context["show_results"] = show_results_filter_set(self.request.GET.copy()) return self.render_to_response(context) @@ -253,23 +259,24 @@ class PesquisarColigacaoView(FilterView): def get_filterset_kwargs(self, filterset_class): super(PesquisarColigacaoView, self).get_filterset_kwargs(filterset_class) - return ({ - 'data': self.request.GET or None, - 'queryset': self.get_queryset().order_by('nome').distinct() - }) + return { + "data": self.request.GET or None, + "queryset": self.get_queryset().order_by("nome").distinct(), + } def get_context_data(self, **kwargs): - context = super(PesquisarColigacaoView, - self).get_context_data(**kwargs) + context = super(PesquisarColigacaoView, self).get_context_data(**kwargs) - paginator = context['paginator'] - page_obj = context['page_obj'] + paginator = context["paginator"] + page_obj = context["page_obj"] - context.update({ - 'page_range': make_pagination(page_obj.number, paginator.num_pages), - 'NO_ENTRIES_MSG': 'Nenhuma coligação encontrada!', - 'title': _('Coligações') - }) + context.update( + { + "page_range": make_pagination(page_obj.number, paginator.num_pages), + "NO_ENTRIES_MSG": "Nenhuma coligação encontrada!", + "title": _("Coligações"), + } + ) return context @@ -277,26 +284,28 @@ class PesquisarColigacaoView(FilterView): super(PesquisarColigacaoView, self).get(request) data = self.filterset.data - url = '' + url = "" if data: - url = "&" + str(self.request.META['QUERY_STRING']) + url = "&" + str(self.request.META["QUERY_STRING"]) if url.startswith("&page"): - url = '' + url = "" - if 'nome' in self.request.META['QUERY_STRING'] or\ - 'page' in self.request.META['QUERY_STRING']: + if ( + "nome" in self.request.META["QUERY_STRING"] + or "page" in self.request.META["QUERY_STRING"] + ): resultados = self.object_list else: resultados = [] - context = self.get_context_data(filter=self.filterset, - object_list=resultados, - filter_url=url, - numero_res=len(resultados) - ) + context = self.get_context_data( + filter=self.filterset, + object_list=resultados, + filter_url=url, + numero_res=len(resultados), + ) - context['show_results'] = show_results_filter_set( - self.request.GET.copy()) + context["show_results"] = show_results_filter_set(self.request.GET.copy()) return self.render_to_response(context) @@ -309,22 +318,24 @@ class PesquisarPartidoView(FilterView): def get_filterset_kwargs(self, filterset_class): super(PesquisarPartidoView, self).get_filterset_kwargs(filterset_class) - return ({ - 'data': self.request.GET or None, - 'queryset': self.get_queryset().order_by('nome').distinct() - }) + return { + "data": self.request.GET or None, + "queryset": self.get_queryset().order_by("nome").distinct(), + } def get_context_data(self, **kwargs): context = super(PesquisarPartidoView, self).get_context_data(**kwargs) - paginator = context['paginator'] - page_obj = context['page_obj'] + paginator = context["paginator"] + page_obj = context["page_obj"] - context.update({ - 'page_range': make_pagination(page_obj.number, paginator.num_pages), - 'NO_ENTRIES_MSG': 'Nenhum partido encontrado!', - 'title': _('Partidos') - }) + context.update( + { + "page_range": make_pagination(page_obj.number, paginator.num_pages), + "NO_ENTRIES_MSG": "Nenhum partido encontrado!", + "title": _("Partidos"), + } + ) return context @@ -332,26 +343,28 @@ class PesquisarPartidoView(FilterView): super(PesquisarPartidoView, self).get(request) data = self.filterset.data - url = '' + url = "" if data: - url = "&" + str(self.request.META['QUERY_STRING']) + url = "&" + str(self.request.META["QUERY_STRING"]) if url.startswith("&page"): - url = '' + url = "" - if 'nome' in self.request.META['QUERY_STRING'] or\ - 'page' in self.request.META['QUERY_STRING']: + if ( + "nome" in self.request.META["QUERY_STRING"] + or "page" in self.request.META["QUERY_STRING"] + ): resultados = self.object_list else: resultados = [] - context = self.get_context_data(filter=self.filterset, - object_list=resultados, - filter_url=url, - numero_res=len(resultados) - ) + context = self.get_context_data( + filter=self.filterset, + object_list=resultados, + filter_url=url, + numero_res=len(resultados), + ) - context['show_results'] = show_results_filter_set( - self.request.GET.copy()) + context["show_results"] = show_results_filter_set(self.request.GET.copy()) return self.render_to_response(context) @@ -359,19 +372,21 @@ class PesquisarPartidoView(FilterView): class ParticipacaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView): public = [RP_DETAIL, RP_LIST] model = Participacao - parent_field = 'parlamentar' + parent_field = "parlamentar" namespace = AppConfig.name - list_field_names = ['composicao__comissao__nome', 'cargo__nome', ( - 'composicao__periodo__data_inicio', 'composicao__periodo__data_fim')] + list_field_names = [ + "composicao__comissao__nome", + "cargo__nome", + ("composicao__periodo__data_inicio", "composicao__periodo__data_fim"), + ] class BaseMixin(CrudBaseForListAndDetailExternalAppView.BaseMixin): - @classmethod def url_name(cls, suffix): - return '%s_parlamentar_%s' % (cls.model._meta.model_name, suffix) + return "%s_parlamentar_%s" % (cls.model._meta.model_name, suffix) class ListView(CrudBaseForListAndDetailExternalAppView.ListView): - ordering = ('-composicao__periodo') + ordering = "-composicao__periodo" def get_rows(self, object_list): """ @@ -387,79 +402,88 @@ class ParticipacaoParlamentarCrud(CrudBaseForListAndDetailExternalAppView): if data_fim: data_fim = data_fim.strftime("%d/%m/%Y") else: - data_fim = ' - ' + data_fim = " - " comissao = [ - (p.composicao.comissao.nome, reverse( - 'sapl.comissoes:comissao_detail', kwargs={ - 'pk': p.composicao.comissao.pk})), + ( + p.composicao.comissao.nome, + reverse( + "sapl.comissoes:comissao_detail", + kwargs={"pk": p.composicao.comissao.pk}, + ), + ), (p.cargo.nome, None), - (p.composicao.periodo.data_inicio.strftime( - "%d/%m/%Y") + ' a ' + - data_fim, - None) + ( + p.composicao.periodo.data_inicio.strftime("%d/%m/%Y") + + " a " + + data_fim, + None, + ), ] comissoes.append(comissao) return comissoes def get_headers(self): - return [_('Comissão'), _('Cargo'), _('Período de participação'), ] + return [ + _("Comissão"), + _("Cargo"), + _("Período de participação"), + ] class ColigacaoCrud(CrudAux): model = Coligacao - help_topic = 'coligacao' + help_topic = "coligacao" class ListView(CrudAux.ListView): - ordering = ('legislatura', '-nome') + ordering = ("legislatura", "-nome") def get_context_data(self, **kwargs): context = super(ColigacaoCrud.ListView, self).get_context_data( - kwargs=kwargs) - rows = context['rows'] + kwargs=kwargs + ) + rows = context["rows"] coluna_votos_recebidos = 2 for row in rows: if not row[coluna_votos_recebidos][0]: - row[coluna_votos_recebidos] = ('0', None) + row[coluna_votos_recebidos] = ("0", None) return context class DetailView(CrudAux.DetailView): - def get_context_data(self, **kwargs): context = super().get_context_data(kwargs=kwargs) - coligacao = context['coligacao'] + coligacao = context["coligacao"] if not coligacao.numero_votos: - coligacao.numero_votos = '0' + coligacao.numero_votos = "0" - context['subnav_template_name'] = 'parlamentares/subnav_coligacao.yaml' + context["subnav_template_name"] = "parlamentares/subnav_coligacao.yaml" return context class UpdateView(CrudAux.UpdateView): - def get_context_data(self, **kwargs): context = super(UpdateView, self).get_context_data(kwargs=kwargs) - context['subnav_template_name'] = 'parlamentares/subnav_coligacao.yaml' + context["subnav_template_name"] = "parlamentares/subnav_coligacao.yaml" return context class DeleteView(CrudAux.DeleteView): def get_success_url(self): - return reverse('sapl.parlamentares:pesquisar_coligacao') + return reverse("sapl.parlamentares:pesquisar_coligacao") def coligacao_legislatura(request): try: coligacoes = Coligacao.objects.filter( - legislatura=request.GET['legislatura']).order_by('nome') + legislatura=request.GET["legislatura"] + ).order_by("nome") except: coligacoes = [] - lista_coligacoes = [(coligacao.id, str(coligacao)) - for coligacao in coligacoes] + lista_coligacoes = [(coligacao.id, str(coligacao)) for coligacao in coligacoes] - return JsonResponse({'coligacoes': lista_coligacoes}) + return JsonResponse({"coligacoes": lista_coligacoes}) def json_date_convert(date): @@ -477,24 +501,23 @@ def frente_atualiza_lista_parlamentares(request): :param request: recebe os parâmetros do GET da chamada Ajax :return: retorna a lista atualizada dos parlamentares """ - ativos = json.loads(request.GET['ativos']) + ativos = json.loads(request.GET["ativos"]) parlamentares = Parlamentar.objects.all() if ativos: - if 'data_criacao' in request.GET and request.GET['data_criacao']: - data_criacao = json_date_convert(request.GET['data_criacao']) + if "data_criacao" in request.GET and request.GET["data_criacao"]: + data_criacao = json_date_convert(request.GET["data_criacao"]) - if 'data_extincao' in request.GET and request.GET['data_extincao']: - data_extincao = json_date_convert(request.GET['data_extincao']) - parlamentares = parlamentares_ativos(data_criacao, - data_extincao) + if "data_extincao" in request.GET and request.GET["data_extincao"]: + data_extincao = json_date_convert(request.GET["data_extincao"]) + parlamentares = parlamentares_ativos(data_criacao, data_extincao) else: parlamentares = parlamentares_ativos(data_criacao) parlamentares_list = [(p.id, p.__str__()) for p in parlamentares] - return JsonResponse({'parlamentares_list': parlamentares_list}) + return JsonResponse({"parlamentares_list": parlamentares_list}) def parlamentares_frente_selected(request): @@ -504,31 +527,45 @@ def parlamentares_frente_selected(request): logger = logging.getLogger(__name__) username = request.user.username try: - logger.info("user=" + username + - ". Tentando objet objeto Frente com id={}.".format(request.GET['frente_id'])) - frente = Frente.objects.get(id=int(request.GET['frente_id'])) + logger.info( + "user=" + + username + + ". Tentando objet objeto Frente com id={}.".format( + request.GET["frente_id"] + ) + ) + frente = Frente.objects.get(id=int(request.GET["frente_id"])) except ObjectDoesNotExist: - logger.error("user=" + username + - ". Frente buscada (id={}) não existe. Retornada lista vazia.".format(request.GET['frente_id'])) + logger.error( + "user=" + + username + + ". Frente buscada (id={}) não existe. Retornada lista vazia.".format( + request.GET["frente_id"] + ) + ) lista_parlamentar_id = [] else: - logger.info("user=" + username + - ". Frente (id={}) encontrada com sucesso.".format(request.GET['frente_id'])) - lista_parlamentar_id = frente.parlamentares.all().values_list( - 'id', flat=True) - return JsonResponse({'id_list': list(lista_parlamentar_id)}) + logger.info( + "user=" + + username + + ". Frente (id={}) encontrada com sucesso.".format( + request.GET["frente_id"] + ) + ) + lista_parlamentar_id = frente.parlamentares.all().values_list("id", flat=True) + return JsonResponse({"id_list": list(lista_parlamentar_id)}) class FrenteCrud(Crud): model = Frente - help_topic = 'tipo_situa_militar' + help_topic = "tipo_situa_militar" public = [RP_DETAIL, RP_LIST] - list_field_names = ['nome', 'data_criacao', 'data_extincao'] + list_field_names = ["nome", "data_criacao", "data_extincao"] class BaseMixin(Crud.BaseMixin): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context class CreateView(Crud.CreateView): @@ -543,8 +580,8 @@ class FrenteCrud(Crud): class FrenteParlamentarCrud(MasterDetailCrud): model = FrenteParlamentar - parent_field = 'frente' - help_topic = 'frente_parlamentares' + parent_field = "frente" + help_topic = "frente_parlamentares" public = [RP_LIST, RP_DETAIL] class CreateView(MasterDetailCrud.CreateView): @@ -552,11 +589,11 @@ class FrenteParlamentarCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context def get_initial(self): - self.initial['frente'] = Frente.objects.get(pk=self.kwargs['pk']) + self.initial["frente"] = Frente.objects.get(pk=self.kwargs["pk"]) return self.initial class UpdateView(MasterDetailCrud.UpdateView): @@ -564,38 +601,41 @@ class FrenteParlamentarCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context class DetailView(MasterDetailCrud.DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context class ListView(MasterDetailCrud.ListView): - layout_key = 'FrenteParlamentarList' - ordering = ('-cargo__cargo_unico', 'parlamentar') + layout_key = "FrenteParlamentarList" + ordering = ("-cargo__cargo_unico", "parlamentar") def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context def get_parlamentar_frentes(request, pk): - template_name = 'parlamentares/parlamentar_frentes_list.html' - frentes = [f for f in FrenteParlamentar.objects.filter(parlamentar_id=pk) - .select_related('frente', 'cargo') - .order_by('-data_entrada', '-data_saida')] + template_name = "parlamentares/parlamentar_frentes_list.html" + frentes = [ + f + for f in FrenteParlamentar.objects.filter(parlamentar_id=pk) + .select_related("frente", "cargo") + .order_by("-data_entrada", "-data_saida") + ] context = { - 'subnav_template_name': 'parlamentares/subnav.yaml', - 'root_pk': pk, - 'sexo_parlamentar': Parlamentar.objects.get(id=pk).sexo, - 'nome_parlamentar': Parlamentar.objects.get(id=pk).nome_parlamentar, - 'frentes': frentes, - 'num_frentes': len(frentes) + "subnav_template_name": "parlamentares/subnav.yaml", + "root_pk": pk, + "sexo_parlamentar": Parlamentar.objects.get(id=pk).sexo, + "nome_parlamentar": Parlamentar.objects.get(id=pk).nome_parlamentar, + "frentes": frentes, + "num_frentes": len(frentes), } return render(request, template_name, context) @@ -603,29 +643,31 @@ def get_parlamentar_frentes(request, pk): class MandatoCrud(MasterDetailCrud): model = Mandato - parent_field = 'parlamentar' + parent_field = "parlamentar" public = [RP_DETAIL, RP_LIST] - list_field_names = ['legislatura', - 'votos_recebidos', - 'coligacao', - 'coligacao__numero_votos', - 'titular'] + list_field_names = [ + "legislatura", + "votos_recebidos", + "coligacao", + "coligacao__numero_votos", + "titular", + ] class ListView(MasterDetailCrud.ListView): - ordering = ('-legislatura__numero') + ordering = "-legislatura__numero" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - rows = context['rows'] + rows = context["rows"] coluna_coligacao = 2 coluna_votos_recebidos = 3 for row in rows: if not row[coluna_coligacao][0]: - row[coluna_coligacao] = (' ', None) + row[coluna_coligacao] = (" ", None) if not row[coluna_votos_recebidos][0]: - row[coluna_votos_recebidos] = (' ', None) + row[coluna_votos_recebidos] = (" ", None) return context @@ -633,8 +675,7 @@ class MandatoCrud(MasterDetailCrud): form_class = MandatoForm def get_initial(self): - return {'parlamentar': Parlamentar.objects.get( - pk=self.kwargs['pk'])} + return {"parlamentar": Parlamentar.objects.get(pk=self.kwargs["pk"])} class UpdateView(MasterDetailCrud.UpdateView): form_class = MandatoForm @@ -642,29 +683,23 @@ class MandatoCrud(MasterDetailCrud): class ComposicaoColigacaoCrud(MasterDetailCrud): model = ComposicaoColigacao - parent_field = 'coligacao' - help_topic = 'coligacao' + parent_field = "coligacao" + help_topic = "coligacao" class BaseMixin(MasterDetailCrud.BaseMixin): - def get_context_data(self, **kwargs): context = super().get_context_data() - context['subnav_template_name'] = \ - 'parlamentares/subnav_coligacao.yaml' + context["subnav_template_name"] = "parlamentares/subnav_coligacao.yaml" return context class ListView(MasterDetailCrud.ListView): - ordering = '-partido__sigla' + ordering = "-partido__sigla" class LegislaturaCrud(CrudAux): model = Legislatura - help_topic = 'legislatura' - list_field_names = [ - 'numero', - 'data_eleicao', - 'data_inicio', - 'data_fim'] + help_topic = "legislatura" + list_field_names = ["numero", "data_eleicao", "data_inicio", "data_fim"] class CreateView(CrudAux.CreateView): logger = logging.getLogger(__name__) @@ -673,21 +708,24 @@ class LegislaturaCrud(CrudAux): def get_initial(self): username = self.request.user.username try: - self.logger.error("user=" + username + - ". Tentando obter última Legislatura.") - ultima_legislatura = Legislatura.objects.latest('numero') + self.logger.error( + "user=" + username + ". Tentando obter última Legislatura." + ) + ultima_legislatura = Legislatura.objects.latest("numero") numero = ultima_legislatura.numero + 1 except Legislatura.DoesNotExist: self.logger.error( - "user=" + username + ". Legislatura não encontrada. Número definido como 1.") + "user=" + + username + + ". Legislatura não encontrada. Número definido como 1." + ) numero = 1 - return {'numero': numero} + return {"numero": numero} class UpdateView(CrudAux.UpdateView): form_class = LegislaturaForm class DetailView(CrudAux.DetailView): - def has_permission(self): return True @@ -696,7 +734,6 @@ class LegislaturaCrud(CrudAux): return super().get(request, *args, **kwargs) class ListView(CrudAux.ListView): - def has_permission(self): return True @@ -707,12 +744,12 @@ class LegislaturaCrud(CrudAux): class FiliacaoCrud(MasterDetailCrud): model = Filiacao - parent_field = 'parlamentar' - help_topic = 'filiacoes_partidarias' + parent_field = "parlamentar" + help_topic = "filiacoes_partidarias" public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): - ordering = '-data' + ordering = "-data" class UpdateView(MasterDetailCrud.UpdateView): form_class = FiliacaoForm @@ -727,22 +764,18 @@ class ParlamentarCrud(Crud): class BaseMixin(Crud.BaseMixin): ordered_list = False - list_field_names = [ - 'nome_parlamentar', - 'filiacao_atual', - 'ativo'] + list_field_names = ["nome_parlamentar", "filiacao_atual", "ativo"] class DetailView(Crud.DetailView): - def get_template_names(self): if self.request.user.has_perm(self.permission(RP_CHANGE)): - if 'iframe' not in self.request.GET: - if not self.request.session.get('iframe'): - return ['crud/detail.html'] - elif self.request.GET['iframe'] == '0': - return ['crud/detail.html'] + if "iframe" not in self.request.GET: + if not self.request.session.get("iframe"): + return ["crud/detail.html"] + elif self.request.GET["iframe"] == "0": + return ["crud/detail.html"] - return ['parlamentares/parlamentar_perfil_publico.html'] + return ["parlamentares/parlamentar_perfil_publico.html"] @xframe_options_exempt def get(self, request, *args, **kwargs): @@ -751,16 +784,16 @@ class ParlamentarCrud(Crud): class UpdateView(Crud.UpdateView): form_class = ParlamentarForm - layout_key = 'ParlamentarUpdate' + layout_key = "ParlamentarUpdate" def render_to_response(self, context, **response_kwargs): - context['form'].helper.include_media = False + context["form"].helper.include_media = False return super().render_to_response(context, **response_kwargs) class CreateView(Crud.CreateView): form_class = ParlamentarCreateForm - layout_key = 'ParlamentarCreate' + layout_key = "ParlamentarCreate" def form_valid(self, form): """ @@ -783,12 +816,16 @@ class ParlamentarCrud(Crud): def take_legislatura_id(self): username = self.request.user.username try: - self.logger.debug("user=" + username + - ". Tentando obter id da legislatura.") - return int(self.request.GET['pk']) + self.logger.debug( + "user=" + username + ". Tentando obter id da legislatura." + ) + return int(self.request.GET["pk"]) except: self.logger.warning( - "User=" + username + ". Legislatura não possui ID. Buscando em todas as entradas.") + "User=" + + username + + ". Legislatura não possui ID. Buscando em todas as entradas." + ) legislaturas = Legislatura.objects.all() for l in legislaturas: if l.atual(): @@ -806,32 +843,38 @@ class ParlamentarCrud(Crud): username = self.request.user.username if legislatura_id >= 0: return queryset.filter( - mandato__legislatura_id=legislatura_id).distinct() + mandato__legislatura_id=legislatura_id + ).distinct() else: try: self.logger.debug( - "user=" + username + ". Tentando obter o mais recente registro do objeto Legislatura.") - l = Legislatura.objects.all().order_by( - '-data_inicio').first() + "user=" + + username + + ". Tentando obter o mais recente registro do objeto Legislatura." + ) + l = Legislatura.objects.all().order_by("-data_inicio").first() except ObjectDoesNotExist: self.logger.error( - "user=" + username + ". Objeto não encontrado. Retornando todos os registros.") + "user=" + + username + + ". Objeto não encontrado. Retornando todos os registros." + ) return Legislatura.objects.all() else: - self.logger.info("user=" + username + - ". Objeto encontrado com sucesso.") + self.logger.info( + "user=" + username + ". Objeto encontrado com sucesso." + ) if l is None: return Legislatura.objects.all() return queryset.filter(mandato__legislatura_id=l) def get_headers(self): - return [_('Parlamentar'), _('Partido'), - _('Ativo?'), _('Titular?')] + return [_("Parlamentar"), _("Partido"), _("Ativo?"), _("Titular?")] class ParlamentarMateriasView(FormView): template_name = "parlamentares/materias.html" - success_url = reverse_lazy('sapl.parlamentares:parlamentar_materia') + success_url = reverse_lazy("sapl.parlamentares:parlamentar_materia") logger = logging.getLogger(__name__) def get_autoria(self, resultset): @@ -839,55 +882,77 @@ class ParlamentarMateriasView(FormView): total_autoria = 0 for i in resultset: - row = autoria.get(i['materia__ano'], []) - columns = (i['materia__tipo__pk'], - i['materia__tipo__sigla'], - i['materia__tipo__descricao'], - int(i['total'])) + row = autoria.get(i["materia__ano"], []) + columns = ( + i["materia__tipo__pk"], + i["materia__tipo__sigla"], + i["materia__tipo__descricao"], + int(i["total"]), + ) row.append(columns) - autoria[i['materia__ano']] = row + autoria[i["materia__ano"]] = row total_autoria += columns[3] autoria = sorted(autoria.items(), reverse=True) return autoria, total_autoria @xframe_options_exempt def get(self, request, *args, **kwargs): - parlamentar_pk = kwargs['pk'] + parlamentar_pk = kwargs["pk"] username = request.user.username try: self.logger.debug( - "user=" + username + ". Tentando obter Autor (object_id={}).".format(parlamentar_pk)) + "user=" + + username + + ". Tentando obter Autor (object_id={}).".format(parlamentar_pk) + ) autor = Autor.objects.get( content_type=ContentType.objects.get_for_model(Parlamentar), - object_id=parlamentar_pk) + object_id=parlamentar_pk, + ) except ObjectDoesNotExist: mensagem = _( - 'Este Parlamentar não está associado como autor de matéria.'.format(parlamentar_pk)) + "Este Parlamentar não está associado como autor de matéria.".format( + parlamentar_pk + ) + ) self.logger.error( - "user=" + username + ". Este Parlamentar (pk={}) não é Autor de matéria.".format(parlamentar_pk)) + "user=" + + username + + ". Este Parlamentar (pk={}) não é Autor de matéria.".format( + parlamentar_pk + ) + ) messages.add_message(request, messages.ERROR, mensagem) return HttpResponseRedirect( reverse( - 'sapl.parlamentares:parlamentar_detail', - kwargs={'pk': parlamentar_pk})) - - autoria = Autoria.objects.filter( - autor=autor, primeiro_autor=True).values( - 'materia__ano', - 'materia__tipo__pk', - 'materia__tipo__sigla', - 'materia__tipo__descricao').annotate( - total=Count('materia__tipo__pk')).order_by( - '-materia__ano', 'materia__tipo') - - coautoria = Autoria.objects.filter( - autor=autor, primeiro_autor=False).values( - 'materia__ano', - 'materia__tipo__pk', - 'materia__tipo__sigla', - 'materia__tipo__descricao').annotate( - total=Count('materia__tipo__pk')).order_by( - '-materia__ano', 'materia__tipo') + "sapl.parlamentares:parlamentar_detail", + kwargs={"pk": parlamentar_pk}, + ) + ) + + autoria = ( + Autoria.objects.filter(autor=autor, primeiro_autor=True) + .values( + "materia__ano", + "materia__tipo__pk", + "materia__tipo__sigla", + "materia__tipo__descricao", + ) + .annotate(total=Count("materia__tipo__pk")) + .order_by("-materia__ano", "materia__tipo") + ) + + coautoria = ( + Autoria.objects.filter(autor=autor, primeiro_autor=False) + .values( + "materia__ano", + "materia__tipo__pk", + "materia__tipo__sigla", + "materia__tipo__descricao", + ) + .annotate(total=Count("materia__tipo__pk")) + .order_by("-materia__ano", "materia__tipo") + ) autor_list = self.get_autoria(autoria) coautor_list = self.get_autoria(coautoria) @@ -895,17 +960,20 @@ class ParlamentarMateriasView(FormView): parlamentar_pk = autor.autor_related.pk nome_parlamentar = autor.autor_related.nome_parlamentar - return self.render_to_response({'autor_pk': autor.pk, - 'root_pk': parlamentar_pk, - 'autoria': autor_list, - 'coautoria': coautor_list, - 'nome_parlamentar': nome_parlamentar - }) + return self.render_to_response( + { + "autor_pk": autor.pk, + "root_pk": parlamentar_pk, + "autoria": autor_list, + "coautoria": coautor_list, + "nome_parlamentar": nome_parlamentar, + } + ) class ParlamentarNormasView(FormView): template_name = "norma/normas.html" - success_url = reverse_lazy('sapl.parlamentares:parlamentar_normas') + success_url = reverse_lazy("sapl.parlamentares:parlamentar_normas") logger = logging.getLogger(__name__) def get_autoria(self, resultset): @@ -913,55 +981,77 @@ class ParlamentarNormasView(FormView): total_autoria = 0 for i in resultset: - row = autoria.get(i['norma__ano'], []) - columns = (i['norma__tipo__pk'], - i['norma__tipo__sigla'], - i['norma__tipo__descricao'], - int(i['total'])) + row = autoria.get(i["norma__ano"], []) + columns = ( + i["norma__tipo__pk"], + i["norma__tipo__sigla"], + i["norma__tipo__descricao"], + int(i["total"]), + ) row.append(columns) - autoria[i['norma__ano']] = row + autoria[i["norma__ano"]] = row total_autoria += columns[3] autoria = sorted(autoria.items(), reverse=True) return autoria, total_autoria @xframe_options_exempt def get(self, request, *args, **kwargs): - parlamentar_pk = kwargs['pk'] + parlamentar_pk = kwargs["pk"] username = request.user.username try: self.logger.debug( - "user=" + username + ". Tentando obter Autor (object_id={}).".format(parlamentar_pk)) + "user=" + + username + + ". Tentando obter Autor (object_id={}).".format(parlamentar_pk) + ) autor = Autor.objects.get( content_type=ContentType.objects.get_for_model(Parlamentar), - object_id=parlamentar_pk) + object_id=parlamentar_pk, + ) except ObjectDoesNotExist: mensagem = _( - 'Este Parlamentar não está associado como autor de matéria.'.format(parlamentar_pk)) + "Este Parlamentar não está associado como autor de matéria.".format( + parlamentar_pk + ) + ) self.logger.error( - "user=" + username + ". Este Parlamentar (pk={}) não é Autor de matéria.".format(parlamentar_pk)) + "user=" + + username + + ". Este Parlamentar (pk={}) não é Autor de matéria.".format( + parlamentar_pk + ) + ) messages.add_message(request, messages.ERROR, mensagem) return HttpResponseRedirect( reverse( - 'sapl.parlamentares:parlamentar_detail', - kwargs={'pk': parlamentar_pk})) - - autoria = AutoriaNorma.objects.filter( - autor=autor, primeiro_autor=True).values( - 'norma__ano', - 'norma__tipo__pk', - 'norma__tipo__sigla', - 'norma__tipo__descricao').annotate( - total=Count('norma__tipo__pk')).order_by( - '-norma__ano', 'norma__tipo') - - coautoria = AutoriaNorma.objects.filter( - autor=autor, primeiro_autor=False).values( - 'norma__ano', - 'norma__tipo__pk', - 'norma__tipo__sigla', - 'norma__tipo__descricao').annotate( - total=Count('norma__tipo__pk')).order_by( - '-norma__ano', 'norma__tipo') + "sapl.parlamentares:parlamentar_detail", + kwargs={"pk": parlamentar_pk}, + ) + ) + + autoria = ( + AutoriaNorma.objects.filter(autor=autor, primeiro_autor=True) + .values( + "norma__ano", + "norma__tipo__pk", + "norma__tipo__sigla", + "norma__tipo__descricao", + ) + .annotate(total=Count("norma__tipo__pk")) + .order_by("-norma__ano", "norma__tipo") + ) + + coautoria = ( + AutoriaNorma.objects.filter(autor=autor, primeiro_autor=False) + .values( + "norma__ano", + "norma__tipo__pk", + "norma__tipo__sigla", + "norma__tipo__descricao", + ) + .annotate(total=Count("norma__tipo__pk")) + .order_by("-norma__ano", "norma__tipo") + ) autor_list = self.get_autoria(autoria) coautor_list = self.get_autoria(coautoria) @@ -969,80 +1059,107 @@ class ParlamentarNormasView(FormView): parlamentar_pk = autor.autor_related.pk nome_parlamentar = autor.autor_related.nome_parlamentar - return self.render_to_response({'autor_pk': autor.pk, - 'root_pk': parlamentar_pk, - 'autoria': autor_list, - 'coautoria': coautor_list, - 'nome_parlamentar': nome_parlamentar - }) + return self.render_to_response( + { + "autor_pk": autor.pk, + "root_pk": parlamentar_pk, + "autoria": autor_list, + "coautoria": coautor_list, + "nome_parlamentar": nome_parlamentar, + } + ) def get_data_filicao(parlamentar): - return parlamentar.filiacao_set.order_by('-data').first().data.strftime('%d/%m/%Y') + return parlamentar.filiacao_set.order_by("-data").first().data.strftime("%d/%m/%Y") def parlamentares_filiados(request, pk): - template_name = 'parlamentares/partido_filiados.html' + template_name = "parlamentares/partido_filiados.html" parlamentares = Parlamentar.objects.all() partido = Partido.objects.get(pk=pk) - parlamentares_filiados = [(parlamentar, get_data_filicao(parlamentar)) for parlamentar in parlamentares if - parlamentar.filiacao_atual == partido.sigla] - return render(request, template_name, {'partido': partido, 'parlamentares': parlamentares_filiados}) + parlamentares_filiados = [ + (parlamentar, get_data_filicao(parlamentar)) + for parlamentar in parlamentares + if parlamentar.filiacao_atual == partido.sigla + ] + return render( + request, + template_name, + {"partido": partido, "parlamentares": parlamentares_filiados}, + ) class MesaDiretoraView(FormView): - template_name = 'parlamentares/composicaomesa_form.html' - success_url = reverse_lazy('sapl.parlamentares:mesa_diretora') + template_name = "parlamentares/composicaomesa_form.html" + success_url = reverse_lazy("sapl.parlamentares:mesa_diretora") logger = logging.getLogger(__name__) def get_template_names(self): - if self.request.user.has_perm('parlamentares.change_composicaomesa'): - if 'iframe' not in self.request.GET: - if not self.request.session.get('iframe'): - return 'parlamentares/composicaomesa_form.html' - elif self.request.GET['iframe'] == '0': - return 'parlamentares/composicaomesa_form.html' + if self.request.user.has_perm("parlamentares.change_composicaomesa"): + if "iframe" not in self.request.GET: + if not self.request.session.get("iframe"): + return "parlamentares/composicaomesa_form.html" + elif self.request.GET["iframe"] == "0": + return "parlamentares/composicaomesa_form.html" - return 'parlamentares/public_composicaomesa_form.html' + return "parlamentares/public_composicaomesa_form.html" # Essa função avisa quando se pode compor uma Mesa Legislativa def validation(self, request): username = request.user.username - self.logger.info('user=' + username + '. Não há nenhuma Sessão Legislativa cadastrada. ' + - 'Só é possível compor uma Mesa Diretora quando ' + - 'há uma Sessão Legislativa cadastrada.') - mensagem = _('Não há nenhuma Sessão Legislativa cadastrada. ' + - 'Só é possível compor uma Mesa Diretora quando ' + - 'há uma Sessão Legislativa cadastrada.') + self.logger.info( + "user=" + + username + + ". Não há nenhuma Sessão Legislativa cadastrada. " + + "Só é possível compor uma Mesa Diretora quando " + + "há uma Sessão Legislativa cadastrada." + ) + mensagem = _( + "Não há nenhuma Sessão Legislativa cadastrada. " + + "Só é possível compor uma Mesa Diretora quando " + + "há uma Sessão Legislativa cadastrada." + ) messages.add_message(request, messages.INFO, mensagem) return self.render_to_response( - {'legislaturas': Legislatura.objects.all( - ).order_by('-numero'), - 'legislatura_selecionada': Legislatura.objects.last(), - 'cargos_vagos': CargoMesa.objects.all()}) + { + "legislaturas": Legislatura.objects.all().order_by("-numero"), + "legislatura_selecionada": Legislatura.objects.last(), + "cargos_vagos": CargoMesa.objects.all(), + } + ) @xframe_options_exempt def get(self, request, *args, **kwargs): - - if (not Legislatura.objects.exists() or - not SessaoLegislativa.objects.exists()): + if not Legislatura.objects.exists() or not SessaoLegislativa.objects.exists(): return self.validation(request) legislatura = Legislatura.objects.first() - sessoes = SessaoLegislativa.objects.filter( - legislatura=legislatura).order_by("data_inicio") + sessoes = SessaoLegislativa.objects.filter(legislatura=legislatura).order_by( + "data_inicio" + ) year = timezone.now().year - sessao_atual = sessoes.filter(data_inicio__year__lte=year).exclude( - data_inicio__gt=timezone.now()).order_by('-data_inicio').first() - - mesa_diretora = sessao_atual.mesadiretora_set.order_by( - '-data_inicio').first() if sessao_atual else None - - composicao_mesa = ComposicaoMesa.objects.select_related('cargo', 'parlamentar').filter( - mesa_diretora=mesa_diretora).order_by('cargo__id_ordenacao', 'cargo_id') + sessao_atual = ( + sessoes.filter(data_inicio__year__lte=year) + .exclude(data_inicio__gt=timezone.now()) + .order_by("-data_inicio") + .first() + ) + + mesa_diretora = ( + sessao_atual.mesadiretora_set.order_by("-data_inicio").first() + if sessao_atual + else None + ) + + composicao_mesa = ( + ComposicaoMesa.objects.select_related("cargo", "parlamentar") + .filter(mesa_diretora=mesa_diretora) + .order_by("cargo__id_ordenacao", "cargo_id") + ) cargos_ocupados = [m.cargo for m in composicao_mesa] cargos = CargoMesa.objects.all() @@ -1051,9 +1168,9 @@ class MesaDiretoraView(FormView): parlamentares = legislatura.mandato_set.all() parlamentares_ocupados = [m.parlamentar for m in composicao_mesa] parlamentares_vagos = list( - set( - [p.parlamentar for p in parlamentares if p.parlamentar.ativo]) - set( - parlamentares_ocupados)) + set([p.parlamentar for p in parlamentares if p.parlamentar.ativo]) + - set(parlamentares_ocupados) + ) parlamentares_vagos.sort(key=lambda x: x.nome_parlamentar) # Se todos os cargos estiverem ocupados, a listagem de parlamentares # deve ser renderizada vazia @@ -1061,61 +1178,70 @@ class MesaDiretoraView(FormView): parlamentares_vagos = [] return self.render_to_response( - {'legislaturas': Legislatura.objects.all( - ).order_by('-numero'), - 'legislatura_selecionada': legislatura, - 'sessoes': sessoes, - 'sessao_selecionada': sessao_atual, - 'composicao_mesa': composicao_mesa, - 'parlamentares': parlamentares_vagos, - 'cargos_vagos': cargos_vagos - }) + { + "legislaturas": Legislatura.objects.all().order_by("-numero"), + "legislatura_selecionada": legislatura, + "sessoes": sessoes, + "sessao_selecionada": sessao_atual, + "composicao_mesa": composicao_mesa, + "parlamentares": parlamentares_vagos, + "cargos_vagos": cargos_vagos, + } + ) def altera_field_mesa(request): """ - Essa função lida com qualquer alteração nos campos - da Mesa Diretora, após qualquer - operação (Legislatura/Sessão/Inclusão/Remoção), - atualizando os campos após cada alteração + Essa função lida com qualquer alteração nos campos + da Mesa Diretora, após qualquer + operação (Legislatura/Sessão/Inclusão/Remoção), + atualizando os campos após cada alteração """ # TODO: Adicionar opção de selecionar mesa diretora no CRUD logger = logging.getLogger(__name__) - legislatura = request.GET['legislatura'] - sessoes = SessaoLegislativa.objects.filter( - legislatura=legislatura).order_by('-data_inicio') + legislatura = request.GET["legislatura"] + sessoes = SessaoLegislativa.objects.filter(legislatura=legislatura).order_by( + "-data_inicio" + ) username = request.user.username if not sessoes: - return JsonResponse({'msg': ('Nenhuma sessão encontrada!', 0)}) + return JsonResponse({"msg": ("Nenhuma sessão encontrada!", 0)}) # Verifica se já tem uma sessão selecionada. Ocorre quando # é alterado o campo de sessão ou feita alguma operação # de inclusão/remoção. - if request.GET['sessao']: - sessao_selecionada = SessaoLegislativa.objects.get( - id=request.GET['sessao']) + if request.GET["sessao"]: + sessao_selecionada = SessaoLegislativa.objects.get(id=request.GET["sessao"]) # Caso a mudança tenha sido no campo legislatura, a sessão # atual deve ser a primeira daquela legislatura else: year = timezone.now().year logger.debug( - "user={}. Tentando obter id de sessoes com data_inicio.ano={}.".format(username, year)) + "user={}. Tentando obter id de sessoes com data_inicio.ano={}.".format( + username, year + ) + ) sessao_selecionada = sessoes.filter(data_inicio__year=year).first() if not sessao_selecionada: - logger.error("user=" + username + ". Id de sessoes com data_inicio.ano={} não encontrado. " - "Selecionado o ID da primeira sessão.".format(year)) + logger.error( + "user=" + + username + + ". Id de sessoes com data_inicio.ano={} não encontrado. " + "Selecionado o ID da primeira sessão.".format(year) + ) sessao_selecionada = sessoes.first() - mesa_diretora = request.GET.get('mesa_diretora') + mesa_diretora = request.GET.get("mesa_diretora") # Mesa nao deve ser informada ainda if not mesa_diretora: # Cria nova mesa diretora ou retorna a primeira mesa_diretora, _ = MesaDiretora.objects.get_or_create( - sessao_legislativa=sessao_selecionada) + sessao_legislativa=sessao_selecionada + ) # TODO: quando a mesa for criada explicitamente em tabelas auxiliares, # deve-se somente tentar recuperar a mesa, e caso nao exista @@ -1124,151 +1250,184 @@ def altera_field_mesa(request): else: try: mesa_diretora = MesaDiretora.objects.get( - id=mesa_diretora, sessao_legislativa=sessao_selecionada) + id=mesa_diretora, sessao_legislativa=sessao_selecionada + ) except ObjectDoesNotExist: mesa_diretora = MesaDiretora.objects.filter( - sessao_legislativa=sessao_selecionada).first() + sessao_legislativa=sessao_selecionada + ).first() # Atualiza os componentes da view após a mudança - composicao_mesa = ComposicaoMesa.objects.select_related('cargo', 'parlamentar').filter( - mesa_diretora=mesa_diretora).order_by('cargo_id') + composicao_mesa = ( + ComposicaoMesa.objects.select_related("cargo", "parlamentar") + .filter(mesa_diretora=mesa_diretora) + .order_by("cargo_id") + ) cargos_ocupados = [m.cargo for m in composicao_mesa] cargos = CargoMesa.objects.all() cargos_vagos = list(set(cargos) - set(cargos_ocupados)) - parlamentares = Legislatura.objects.get( - id=legislatura).mandato_set.all() + parlamentares = Legislatura.objects.get(id=legislatura).mandato_set.all() parlamentares_ocupados = [m.parlamentar for m in composicao_mesa] parlamentares_vagos = list( - set( - [p.parlamentar for p in parlamentares]) - set( - parlamentares_ocupados)) + set([p.parlamentar for p in parlamentares]) - set(parlamentares_ocupados) + ) parlamentares_vagos.sort(key=lambda x: x.nome_parlamentar) lista_sessoes = [(s.id, s.__str__()) for s in sessoes] - lista_composicao = [(c.id, c.parlamentar.__str__(), - c.cargo.__str__()) for c in composicao_mesa] - lista_parlamentares = [( - p.id, p.__str__()) for p in parlamentares_vagos] + lista_composicao = [ + (c.id, c.parlamentar.__str__(), c.cargo.__str__()) for c in composicao_mesa + ] + lista_parlamentares = [(p.id, p.__str__()) for p in parlamentares_vagos] lista_cargos = [(c.id, c.__str__()) for c in cargos_vagos] return JsonResponse( - {'lista_sessoes': lista_sessoes, - 'lista_composicao': lista_composicao, - 'lista_parlamentares': lista_parlamentares, - 'lista_cargos': lista_cargos, - 'sessao_selecionada': sessao_selecionada.id, - 'msg': ('', 1)}) + { + "lista_sessoes": lista_sessoes, + "lista_composicao": lista_composicao, + "lista_parlamentares": lista_parlamentares, + "lista_cargos": lista_cargos, + "sessao_selecionada": sessao_selecionada.id, + "msg": ("", 1), + } + ) def insere_parlamentar_composicao(request): """ - Essa função lida com qualquer operação de inserção - na composição da Mesa Diretora + Essa função lida com qualquer operação de inserção + na composição da Mesa Diretora """ logger = logging.getLogger(__name__) username = request.user.username if request.user.has_perm( - '%s.add_%s' % ( - AppConfig.label, ComposicaoMesa._meta.model_name)): + "%s.add_%s" % (AppConfig.label, ComposicaoMesa._meta.model_name) + ): composicao = ComposicaoMesa() try: # logger.debug( # "user=" + username + ". Tentando obter SessaoLegislativa com id={}.".format(request.POST['sessao'])) mesa_diretora, _ = MesaDiretora.objects.get_or_create( - sessao_legislativa_id=int(request.POST['sessao'])) + sessao_legislativa_id=int(request.POST["sessao"]) + ) composicao.mesa_diretora = mesa_diretora except MultiValueDictKeyError: logger.error( - "user=" + username + ". 'MultiValueDictKeyError', nenhuma sessão foi inserida!") - return JsonResponse({'msg': ('Nenhuma sessão foi inserida!', 0)}) + "user=" + + username + + ". 'MultiValueDictKeyError', nenhuma sessão foi inserida!" + ) + return JsonResponse({"msg": ("Nenhuma sessão foi inserida!", 0)}) try: logger.debug( - "user=" + username + ". Tentando obter Parlamentar com id={}.".format(request.POST['parlamentar'])) + "user=" + + username + + ". Tentando obter Parlamentar com id={}.".format( + request.POST["parlamentar"] + ) + ) composicao.parlamentar = Parlamentar.objects.get( - id=int(request.POST['parlamentar'])) + id=int(request.POST["parlamentar"]) + ) except MultiValueDictKeyError: logger.error( - "user=" + username + ". 'MultiValueDictKeyError', nenhum parlamentar foi inserido!") - return JsonResponse({ - 'msg': ('Nenhum parlamentar foi inserido!', 0)}) + "user=" + + username + + ". 'MultiValueDictKeyError', nenhum parlamentar foi inserido!" + ) + return JsonResponse({"msg": ("Nenhum parlamentar foi inserido!", 0)}) try: - logger.info("user=" + username + - ". Tentando obter CargoMesa com id={}.".format(request.POST['cargo'])) - composicao.cargo = CargoMesa.objects.get( - id=int(request.POST['cargo'])) + logger.info( + "user=" + + username + + ". Tentando obter CargoMesa com id={}.".format(request.POST["cargo"]) + ) + composicao.cargo = CargoMesa.objects.get(id=int(request.POST["cargo"])) parlamentar_ja_inserido = ComposicaoMesa.objects.filter( - mesa_diretora=mesa_diretora, - cargo=composicao.cargo).exists() + mesa_diretora=mesa_diretora, cargo=composicao.cargo + ).exists() if parlamentar_ja_inserido: - return JsonResponse({'msg': ('Parlamentar já inserido!', 0)}) + return JsonResponse({"msg": ("Parlamentar já inserido!", 0)}) composicao.save() except MultiValueDictKeyError: - logger.error("user=" + username + - ". 'MultiValueDictKeyError', nenhum cargo foi inserido!") - return JsonResponse({'msg': ('Nenhum cargo foi inserido!', 0)}) + logger.error( + "user=" + + username + + ". 'MultiValueDictKeyError', nenhum cargo foi inserido!" + ) + return JsonResponse({"msg": ("Nenhum cargo foi inserido!", 0)}) logger.info("user=" + username + ". Parlamentar inserido com sucesso!") - return JsonResponse({'msg': ('Parlamentar inserido com sucesso!', 1)}) + return JsonResponse({"msg": ("Parlamentar inserido com sucesso!", 1)}) else: - logger.error("user=" + username + - " não tem permissão para esta operação!") - return JsonResponse( - {'msg': ('Você não tem permissão para esta operação!', 0)}) + logger.error("user=" + username + " não tem permissão para esta operação!") + return JsonResponse({"msg": ("Você não tem permissão para esta operação!", 0)}) def remove_parlamentar_composicao(request): """ - Essa função lida com qualquer operação de remoção - na composição da Mesa Diretora + Essa função lida com qualquer operação de remoção + na composição da Mesa Diretora """ logger = logging.getLogger(__name__) username = request.user.username if request.POST and request.user.has_perm( - '%s.delete_%s' % ( - AppConfig.label, ComposicaoMesa._meta.model_name)): - - if 'composicao_mesa' in request.POST: + "%s.delete_%s" % (AppConfig.label, ComposicaoMesa._meta.model_name) + ): + if "composicao_mesa" in request.POST: try: - logger.debug("user=" + username + ". Tentando obter ComposicaoMesa com id={}.".format( - request.POST['composicao_mesa'])) + logger.debug( + "user=" + + username + + ". Tentando obter ComposicaoMesa com id={}.".format( + request.POST["composicao_mesa"] + ) + ) composicao = ComposicaoMesa.objects.get( - id=request.POST['composicao_mesa']) + id=request.POST["composicao_mesa"] + ) except ObjectDoesNotExist: logger.error( - "user=" + username + - ". ComposicaoMesa com id={} não encontrada, portanto não pode ser removida." - .format(request.POST['composicao_mesa'])) + "user=" + + username + + ". ComposicaoMesa com id={} não encontrada, portanto não pode ser removida.".format( + request.POST["composicao_mesa"] + ) + ) return JsonResponse( - {'msg': ( - 'Composição da Mesa não pôde ser removida!', 0)}) + {"msg": ("Composição da Mesa não pôde ser removida!", 0)} + ) composicao.delete() - logger.info("user=" + username + ". ComposicaoMesa com id={} excluido com sucesso!".format( - request.POST['composicao_mesa'])) - return JsonResponse( - {'msg': ( - 'Parlamentar excluido com sucesso!', 1)}) + logger.info( + "user=" + + username + + ". ComposicaoMesa com id={} excluido com sucesso!".format( + request.POST["composicao_mesa"] + ) + ) + return JsonResponse({"msg": ("Parlamentar excluido com sucesso!", 1)}) else: - logger.info("user=" + username + - ". Nenhum parlamentar escolhido para ser excluído.") + logger.info( + "user=" + username + ". Nenhum parlamentar escolhido para ser excluído." + ) return JsonResponse( - {'msg': ( - 'Selecione algum parlamentar para ser excluido!', 0)}) + {"msg": ("Selecione algum parlamentar para ser excluido!", 0)} + ) def partido_parlamentar_sessao_legislativa(sessao, parlamentar): """ - Função para descobrir o partido do parlamentar durante - o período de uma dada Sessão Legislativa + Função para descobrir o partido do parlamentar durante + o período de uma dada Sessão Legislativa """ # As condições para mostrar a filiação são: @@ -1277,85 +1436,99 @@ def partido_parlamentar_sessao_legislativa(sessao, parlamentar): # ou igual a data de fim da sessao logger = logging.getLogger(__name__) try: - logger.debug("Tentando obter filiação do parlamentar com (data<={} e data_desfiliacao>={}) " - "ou (data<={} e data_desfiliacao=Null))." - .format(sessao.data_fim, sessao.data_fim, sessao.data_fim)) + logger.debug( + "Tentando obter filiação do parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null)).".format( + sessao.data_fim, sessao.data_fim, sessao.data_fim + ) + ) logger.info("Tentando obter filiação correspondente.") - filiacao = parlamentar.filiacao_set.get(Q( - data__lte=sessao.data_fim, - data_desfiliacao__gte=sessao.data_fim) | Q( - data__lte=sessao.data_fim, - data_desfiliacao__isnull=True)) + filiacao = parlamentar.filiacao_set.get( + Q(data__lte=sessao.data_fim, data_desfiliacao__gte=sessao.data_fim) + | Q(data__lte=sessao.data_fim, data_desfiliacao__isnull=True) + ) # Caso não exista filiação com essas condições except ObjectDoesNotExist: - logger.error("Filiação do parlamentar com (data<={} e data_desfiliacao>={}) " - "ou (data<={} e data_desfiliacao=Null não encontrada. Retornando vazio." - .format(sessao.data_fim, sessao.data_fim, sessao.data_fim)) - return '' + logger.error( + "Filiação do parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null não encontrada. Retornando vazio.".format( + sessao.data_fim, sessao.data_fim, sessao.data_fim + ) + ) + return "" # Caso exista mais de uma filiação nesse intervalo # Entretanto, NÃO DEVE OCORRER except MultipleObjectsReturned: - logger.error("O Parlamentar com (data<={} e data_desfiliacao>={}) " - "ou (data<={} e data_desfiliacao=Null possui duas filiações conflitantes." - .format(sessao.data_fim, sessao.data_fim, sessao.data_fim)) - return 'O Parlamentar possui duas filiações conflitantes' + logger.error( + "O Parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null possui duas filiações conflitantes.".format( + sessao.data_fim, sessao.data_fim, sessao.data_fim + ) + ) + return "O Parlamentar possui duas filiações conflitantes" # Caso encontre UMA filiação nessas condições else: - logger.info("Filiação do parlamentar com (data<={} e data_desfiliacao>={}) " - "ou (data<={} e data_desfiliacao=Null encontrada com sucesso." - .format(sessao.data_fim, sessao.data_fim, sessao.data_fim)) + logger.info( + "Filiação do parlamentar com (data<={} e data_desfiliacao>={}) " + "ou (data<={} e data_desfiliacao=Null encontrada com sucesso.".format( + sessao.data_fim, sessao.data_fim, sessao.data_fim + ) + ) return filiacao.partido.sigla def altera_field_mesa_public_view(request): """ - Essa função lida com qualquer alteração nos campos - da Mesa Diretora para usuários anônimos, - atualizando os campos após cada alteração + Essa função lida com qualquer alteração nos campos + da Mesa Diretora para usuários anônimos, + atualizando os campos após cada alteração """ # TODO: Adicionar opção de selecionar mesa diretora no CRUD logger = logging.getLogger(__name__) username = request.user.username - legislatura = request.GET['legislatura'] + legislatura = request.GET["legislatura"] if legislatura: legislatura = Legislatura.objects.get(id=legislatura) else: - legislatura = Legislatura.objects.order_by('-data_inicio').first() + legislatura = Legislatura.objects.order_by("-data_inicio").first() - sessoes = legislatura.sessaolegislativa_set.filter( - tipo='O').order_by('-data_inicio') + sessoes = legislatura.sessaolegislativa_set.filter(tipo="O").order_by( + "-data_inicio" + ) if not sessoes: - return JsonResponse({'msg': ('Nenhuma sessão encontrada!', 0)}) + return JsonResponse({"msg": ("Nenhuma sessão encontrada!", 0)}) # Verifica se já tem uma sessão selecionada. Ocorre quando é alterado o # campo de sessão - sessao_selecionada = request.GET['sessao'] + sessao_selecionada = request.GET["sessao"] if not sessao_selecionada: year = timezone.now().year logger.info( - f"user={username}. Tentando obter sessões com data_inicio.ano = {year}.") + f"user={username}. Tentando obter sessões com data_inicio.ano = {year}." + ) sessao_selecionada = sessoes.filter(data_inicio__year=year).first() if sessao_selecionada is None: - logger.error(f"user={username}. Sessões não encontradas com com data_inicio.ano = {year}. " - "Selecionado o id da primeira sessão.") + logger.error( + f"user={username}. Sessões não encontradas com com data_inicio.ano = {year}. " + "Selecionado o id da primeira sessão." + ) sessao_selecionada = sessoes.first() else: - sessao_selecionada = SessaoLegislativa.objects.get( - id=sessao_selecionada) + sessao_selecionada = SessaoLegislativa.objects.get(id=sessao_selecionada) # Atualiza os componentes da view após a mudança lista_sessoes = [(s.id, s.__str__()) for s in sessoes] # Pegar Mesas diretoras da sessao - mesa_diretora = request.GET.get('mesa_diretora') + mesa_diretora = request.GET.get("mesa_diretora") # Mesa nao deve ser informada ainda if not mesa_diretora: @@ -1363,11 +1536,13 @@ def altera_field_mesa_public_view(request): mesa_diretora = sessao_selecionada.mesadiretora_set.first() except ObjectDoesNotExist: logger.error( - f"user={username}. Mesa não encontrada com sessão Nº {sessao_selecionada.id}. ") + f"user={username}. Mesa não encontrada com sessão Nº {sessao_selecionada.id}. " + ) else: # Cria nova mesa diretora ou retorna a primeira mesa_diretora, _ = MesaDiretora.objects.get_or_create( - sessao_legislativa=sessao_selecionada) + sessao_legislativa=sessao_selecionada + ) # TODO: quando a mesa for criada explicitamente em tabelas auxiliares, # deve-se somente tentar recuperar a mesa, e caso nao exista @@ -1375,12 +1550,15 @@ def altera_field_mesa_public_view(request): # logger.error(f"user={username}. Mesa Nº {mesa_diretora} não encontrada na sessão Nº {sessao_selecionada.id}. " # "Selecionada a mesa com o primeiro id na sessão") - composicao_mesa = ComposicaoMesa.objects.select_related('cargo', 'parlamentar').filter( - mesa_diretora=mesa_diretora).order_by('cargo_id') - cargos_ocupados = list(composicao_mesa.values_list( - 'cargo__id', 'cargo__descricao')) - parlamentares_ocupados = list(composicao_mesa.values_list( - 'parlamentar__id', 'parlamentar__nome_parlamentar')) + composicao_mesa = ( + ComposicaoMesa.objects.select_related("cargo", "parlamentar") + .filter(mesa_diretora=mesa_diretora) + .order_by("cargo_id") + ) + cargos_ocupados = list(composicao_mesa.values_list("cargo__id", "cargo__descricao")) + parlamentares_ocupados = list( + composicao_mesa.values_list("parlamentar__id", "parlamentar__nome_parlamentar") + ) lista_fotos = [] lista_partidos = [] @@ -1389,63 +1567,64 @@ def altera_field_mesa_public_view(request): for p in parlamentares_ocupados: parlamentar = Parlamentar.objects.get(id=p[0]) lista_partidos.append( - partido_parlamentar_sessao_legislativa(sessao, parlamentar)) + partido_parlamentar_sessao_legislativa(sessao, parlamentar) + ) if parlamentar.fotografia: try: - logger.warning( - f"Iniciando cropping da imagem {parlamentar.fotografia}") + logger.warning(f"Iniciando cropping da imagem {parlamentar.fotografia}") thumbnail_url = get_backend().get_thumbnail_url( parlamentar.fotografia, { - 'size': (128, 128), - 'box': parlamentar.cropping, - 'crop': True, - 'detail': True, - } + "size": (128, 128), + "box": parlamentar.cropping, + "crop": True, + "detail": True, + }, ) logger.warning( - f"Cropping da imagem {parlamentar.fotografia} realizado com sucesso") + f"Cropping da imagem {parlamentar.fotografia} realizado com sucesso" + ) lista_fotos.append(thumbnail_url) except Exception as e: logger.error(e) - logger.error( - F'erro processando arquivo: {parlamentar.fotografia.path}') + logger.error(f"erro processando arquivo: {parlamentar.fotografia.path}") else: lista_fotos.append(None) - return JsonResponse({ - 'lista_parlamentares': parlamentares_ocupados, - 'lista_partidos': lista_partidos, - 'lista_cargos': cargos_ocupados, - 'lista_sessoes': lista_sessoes, - 'lista_fotos': lista_fotos, - 'sessao_selecionada': sessao_selecionada.id, - 'mesa_diretora': mesa_diretora.id, - 'msg': ('', 1) - }) + return JsonResponse( + { + "lista_parlamentares": parlamentares_ocupados, + "lista_partidos": lista_partidos, + "lista_cargos": cargos_ocupados, + "lista_sessoes": lista_sessoes, + "lista_fotos": lista_fotos, + "sessao_selecionada": sessao_selecionada.id, + "mesa_diretora": mesa_diretora.id, + "msg": ("", 1), + } + ) class VincularParlamentarView(PermissionRequiredMixin, FormView): logger = logging.getLogger(__name__) form_class = VincularParlamentarForm - template_name = 'parlamentares/vincular_parlamentar.html' - permission_required = ('parlamentares.add_parlamentar',) + template_name = "parlamentares/vincular_parlamentar.html" + permission_required = ("parlamentares.add_parlamentar",) def get_success_url(self): - return reverse('sapl.parlamentares:parlamentar_list') + return reverse("sapl.parlamentares:parlamentar_list") def form_valid(self, form): kwargs = { - 'parlamentar': form.cleaned_data['parlamentar'], - 'legislatura': form.cleaned_data['legislatura'], - 'data_inicio_mandato': form.cleaned_data['legislatura'].data_inicio, - 'data_fim_mandato': form.cleaned_data['legislatura'].data_fim + "parlamentar": form.cleaned_data["parlamentar"], + "legislatura": form.cleaned_data["legislatura"], + "data_inicio_mandato": form.cleaned_data["legislatura"].data_inicio, + "data_fim_mandato": form.cleaned_data["legislatura"].data_fim, } - data_expedicao_diploma = form.cleaned_data.get( - 'data_expedicao_diploma') + data_expedicao_diploma = form.cleaned_data.get("data_expedicao_diploma") if data_expedicao_diploma: - kwargs.update({'data_expedicao_diploma': data_expedicao_diploma}) + kwargs.update({"data_expedicao_diploma": data_expedicao_diploma}) mandato = Mandato.objects.create(**kwargs) mandato.save() @@ -1461,19 +1640,19 @@ class BlocoCrud(CrudAux): form_class = BlocoForm def get_success_url(self): - return reverse('sapl.parlamentares:bloco_list') + return reverse("sapl.parlamentares:bloco_list") class UpdateView(CrudAux.UpdateView): form_class = BlocoForm def get_success_url(self): - return reverse('sapl.parlamentares:bloco_list') + return reverse("sapl.parlamentares:bloco_list") class BlocoMembroCrud(MasterDetailCrud): model = BlocoMembro - parent_field = 'bloco' - help_topic = 'bloco_membros' + parent_field = "bloco" + help_topic = "bloco_membros" public = [RP_LIST, RP_DETAIL] class CreateView(MasterDetailCrud.CreateView): @@ -1481,11 +1660,11 @@ class BlocoMembroCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context def get_initial(self): - self.initial['bloco'] = Bloco.objects.get(pk=self.kwargs['pk']) + self.initial["bloco"] = Bloco.objects.get(pk=self.kwargs["pk"]) return self.initial class UpdateView(MasterDetailCrud.UpdateView): @@ -1493,30 +1672,30 @@ class BlocoMembroCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context class DetailView(MasterDetailCrud.DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context class ListView(MasterDetailCrud.ListView): - layout_key = 'BlocoMembroList' - ordering = ('-cargo__cargo_unico', 'parlamentar') + layout_key = "BlocoMembroList" + ordering = ("-cargo__cargo_unico", "parlamentar") def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['subnav_template_name'] = '' + context["subnav_template_name"] = "" return context def get_sessoes_legislatura(request): - legislatura_id = request.GET['legislatura'] + legislatura_id = request.GET["legislatura"] - json_response = {'sessoes_legislativas': []} + json_response = {"sessoes_legislativas": []} for s in SessaoLegislativa.objects.filter(legislatura_id=legislatura_id): - json_response['sessoes_legislativas'].append((s.id, str(s))) + json_response["sessoes_legislativas"].append((s.id, str(s))) return JsonResponse(json_response) diff --git a/sapl/protocoloadm/admin.py b/sapl/protocoloadm/admin.py index c786c0faa..de3e4665c 100644 --- a/sapl/protocoloadm/admin.py +++ b/sapl/protocoloadm/admin.py @@ -1,6 +1,5 @@ from sapl.utils import register_all_models_in_admin -register_all_models_in_admin(__name__, exclude_list=['timestamp', - 'data', - 'hora', - 'timestamp_anulacao']) +register_all_models_in_admin( + __name__, exclude_list=["timestamp", "data", "hora", "timestamp_anulacao"] +) diff --git a/sapl/protocoloadm/apps.py b/sapl/protocoloadm/apps.py index 306ce5f9b..b8b1cbf07 100644 --- a/sapl/protocoloadm/apps.py +++ b/sapl/protocoloadm/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.protocoloadm' - label = 'protocoloadm' - verbose_name = _('Protocolo Administrativo') + name = "sapl.protocoloadm" + label = "protocoloadm" + verbose_name = _("Protocolo Administrativo") diff --git a/sapl/protocoloadm/forms.py b/sapl/protocoloadm/forms.py index f2a750bc6..d82395bac 100644 --- a/sapl/protocoloadm/forms.py +++ b/sapl/protocoloadm/forms.py @@ -1,9 +1,9 @@ import logging import re -from crispy_forms.bootstrap import InlineRadios, Alert, FormActions -from crispy_forms.layout import (Button, Div, Fieldset, HTML, - Layout, Submit) +import django_filters +from crispy_forms.bootstrap import Alert, FormActions, InlineRadios +from crispy_forms.layout import HTML, Button, Div, Fieldset, Layout, Submit from django import forms from django.core.exceptions import (MultipleObjectsReturned, ObjectDoesNotExist, ValidationError) @@ -12,249 +12,249 @@ from django.db.models import Max from django.forms import ModelForm from django.utils import timezone from django.utils.translation import gettext_lazy as _ -import django_filters -from sapl.base.models import Autor, TipoAutor, AppConfig -from sapl.crispy_layout_mixin import (form_actions, SaplFormHelper, - SaplFormLayout, to_row) -from sapl.materia.models import (MateriaLegislativa, - TipoMateriaLegislativa, +from sapl.base.models import AppConfig, Autor, TipoAutor +from sapl.crispy_layout_mixin import (SaplFormHelper, SaplFormLayout, + form_actions, to_row) +from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa, UnidadeTramitacao) from sapl.protocoloadm.models import VinculoDocAdminMateria -from sapl.utils import (AnoNumeroOrderingFilter, autor_label, autor_modal, - choice_anos_com_documentoadministrativo, - choice_anos_com_materias, timing, - choice_anos_com_protocolo, choice_force_optional, +from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, AnoNumeroOrderingFilter, FileFieldCheckMixin, FilterOverridesMetaMixin, - lista_anexados, RANGE_ANOS, - validar_arquivo, YES_NO_CHOICES, - GoogleRecapthaMixin) - -from .models import (Anexado, AcompanhamentoDocumento, - DocumentoAcessorioAdministrativo, - DocumentoAdministrativo, Protocolo, - TipoDocumentoAdministrativo, - TramitacaoAdministrativo) + GoogleRecapthaMixin, autor_label, autor_modal, + choice_anos_com_documentoadministrativo, + choice_anos_com_materias, choice_anos_com_protocolo, + choice_force_optional, lista_anexados, timing, + validar_arquivo) +from .models import (AcompanhamentoDocumento, Anexado, + DocumentoAcessorioAdministrativo, DocumentoAdministrativo, + Protocolo, TipoDocumentoAdministrativo, + TramitacaoAdministrativo) -TIPOS_PROTOCOLO = [('0', 'Recebido'), ('1', 'Enviado'), - ('2', 'Interno')] -TIPOS_PROTOCOLO_CREATE = [ - ('0', 'Recebido'), ('1', 'Enviado'), ('2', 'Interno')] +TIPOS_PROTOCOLO = [("0", "Recebido"), ("1", "Enviado"), ("2", "Interno")] +TIPOS_PROTOCOLO_CREATE = [("0", "Recebido"), ("1", "Enviado"), ("2", "Interno")] -NATUREZA_PROCESSO = [('0', 'Administrativo'), - ('1', 'Legislativo')] +NATUREZA_PROCESSO = [("0", "Administrativo"), ("1", "Legislativo")] -EM_TRAMITACAO = [(0, 'Sim'), (1, 'Não')] +EM_TRAMITACAO = [(0, "Sim"), (1, "Não")] class AcompanhamentoDocumentoForm(GoogleRecapthaMixin, ModelForm): - class Meta: model = AcompanhamentoDocumento - fields = ['email'] + fields = ["email"] def __init__(self, *args, **kwargs): - - kwargs['title_label'] = _('Acompanhamento de Documento por e-mail') - kwargs['action_label'] = _('Cadastrar') + kwargs["title_label"] = _("Acompanhamento de Documento por e-mail") + kwargs["action_label"] = _("Cadastrar") super().__init__(*args, **kwargs) class ProtocoloFilterSet(django_filters.FilterSet): - ano = django_filters.ChoiceFilter( - required=False, - label='Ano', - choices=choice_anos_com_protocolo) + required=False, label="Ano", choices=choice_anos_com_protocolo + ) assunto_ementa = django_filters.CharFilter( - label=_('Assunto'), - lookup_expr='icontains') + label=_("Assunto"), lookup_expr="icontains" + ) interessado = django_filters.CharFilter( - label=_('Interessado'), - lookup_expr='icontains') + label=_("Interessado"), lookup_expr="icontains" + ) autor = django_filters.CharFilter(widget=forms.HiddenInput()) tipo_protocolo = django_filters.ChoiceFilter( required=False, - label='Tipo de Protocolo', + label="Tipo de Protocolo", choices=TIPOS_PROTOCOLO, - widget=forms.Select( - attrs={'class': 'selector'})) + widget=forms.Select(attrs={"class": "selector"}), + ) tipo_processo = django_filters.ChoiceFilter( required=False, - label='Natureza do Processo', + label="Natureza do Processo", choices=NATUREZA_PROCESSO, - widget=forms.Select( - attrs={'class': 'selector'})) + widget=forms.Select(attrs={"class": "selector"}), + ) - o = AnoNumeroOrderingFilter(help_text='') + o = AnoNumeroOrderingFilter(help_text="") class Meta(FilterOverridesMetaMixin): model = Protocolo - fields = ['numero', - 'tipo_documento', - 'timestamp', - 'tipo_materia', - ] + fields = [ + "numero", + "tipo_documento", + "timestamp", + "tipo_materia", + ] def __init__(self, *args, **kwargs): super(ProtocoloFilterSet, self).__init__(*args, **kwargs) - self.filters['timestamp'].label = 'Data (Inicial - Final)' + self.filters["timestamp"].label = "Data (Inicial - Final)" - row1 = to_row( - [('numero', 4), - ('ano', 4), - ('timestamp', 4)]) + row1 = to_row([("numero", 4), ("ano", 4), ("timestamp", 4)]) row2 = to_row( - [('tipo_documento', 4), - ('tipo_protocolo', 4), - ('tipo_materia', 4)]) + [("tipo_documento", 4), ("tipo_protocolo", 4), ("tipo_materia", 4)] + ) - row3 = to_row( - [('interessado', 6), - ('assunto_ementa', 6)]) + row3 = to_row([("interessado", 6), ("assunto_ementa", 6)]) row4 = to_row( - [('autor', 0), - (Button('pesquisar', - 'Pesquisar Autor', - css_class='btn btn-primary btn-sm'), 2), - (Button('limpar', - 'Limpar Autor', - css_class='btn btn-primary btn-sm'), 10)]) - row5 = to_row( - [('tipo_processo', 6), ('o', 6)]) + [ + ("autor", 0), + ( + Button( + "pesquisar", + "Pesquisar Autor", + css_class="btn btn-primary btn-sm", + ), + 2, + ), + ( + Button( + "limpar", "Limpar Autor", css_class="btn btn-primary btn-sm" + ), + 10, + ), + ] + ) + row5 = to_row([("tipo_processo", 6), ("o", 6)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisar Protocolo'), - row1, row2, - row3, - row5, - HTML(autor_label), - HTML(autor_modal), - row4, - form_actions(label='Pesquisar')) + Fieldset( + _("Pesquisar Protocolo"), + row1, + row2, + row3, + row5, + HTML(autor_label), + HTML(autor_modal), + row4, + form_actions(label="Pesquisar"), + ) ) class DocumentoAdministrativoFilterSet(django_filters.FilterSet): - ano = django_filters.ChoiceFilter( - required=False, - label='Ano', - choices=choice_anos_com_documentoadministrativo) + required=False, label="Ano", choices=choice_anos_com_documentoadministrativo + ) - tramitacao = django_filters.ChoiceFilter(required=False, - label='Em Tramitação?', - choices=YES_NO_CHOICES) + tramitacao = django_filters.ChoiceFilter( + required=False, label="Em Tramitação?", choices=YES_NO_CHOICES + ) - assunto = django_filters.CharFilter( - label=_('Assunto'), - lookup_expr='icontains') + assunto = django_filters.CharFilter(label=_("Assunto"), lookup_expr="icontains") interessado = django_filters.CharFilter( - label=_('Interessado'), - lookup_expr='icontains') + label=_("Interessado"), lookup_expr="icontains" + ) - o = AnoNumeroOrderingFilter(help_text='') + o = AnoNumeroOrderingFilter(help_text="") class Meta(FilterOverridesMetaMixin): model = DocumentoAdministrativo - fields = ['tipo', - 'numero', - 'complemento', - 'protocolo__numero', - 'numero_externo', - 'data', - 'tramitacaoadministrativo__unidade_tramitacao_destino', - 'tramitacaoadministrativo__status'] + fields = [ + "tipo", + "numero", + "complemento", + "protocolo__numero", + "numero_externo", + "data", + "tramitacaoadministrativo__unidade_tramitacao_destino", + "tramitacaoadministrativo__status", + ] def __init__(self, *args, **kwargs): super(DocumentoAdministrativoFilterSet, self).__init__(*args, **kwargs) - local_atual = 'tramitacaoadministrativo__unidade_tramitacao_destino' - self.filters['tipo'].label = 'Tipo de Documento' - self.filters['protocolo__numero'].label = 'Núm. Protocolo' - self.filters['tramitacaoadministrativo__status'].label = 'Situação' - self.filters[local_atual].label = 'Localização Atual' + local_atual = "tramitacaoadministrativo__unidade_tramitacao_destino" + self.filters["tipo"].label = "Tipo de Documento" + self.filters["protocolo__numero"].label = "Núm. Protocolo" + self.filters["tramitacaoadministrativo__status"].label = "Situação" + self.filters[local_atual].label = "Localização Atual" row1 = to_row( - [('tipo', 8), - ('o', 4), ]) + [ + ("tipo", 8), + ("o", 4), + ] + ) - row2 = to_row( - [('numero', 5), - ('complemento', 2), - ('ano', 5)]) + row2 = to_row([("numero", 5), ("complemento", 2), ("ano", 5)]) - row3 = to_row( - [('protocolo__numero', 4), - ('numero_externo', 4), - ('data', 4) - ]) + row3 = to_row([("protocolo__numero", 4), ("numero_externo", 4), ("data", 4)]) - row4 = to_row( - [('interessado', 6), - ('assunto', 6)]) + row4 = to_row([("interessado", 6), ("assunto", 6)]) row5 = to_row( [ - ('tramitacao', 2), - ('tramitacaoadministrativo__status', 4), - ('tramitacaoadministrativo__unidade_tramitacao_destino', 6), - ]) + ("tramitacao", 2), + ("tramitacaoadministrativo__status", 4), + ("tramitacaoadministrativo__unidade_tramitacao_destino", 6), + ] + ) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisar Documento'), - row1, row2, - row3, row4, - row5, buttons,) + Fieldset( + _("Pesquisar Documento"), + row1, + row2, + row3, + row4, + row5, + buttons, + ) ) class AnularProtocoloAdmForm(ModelForm): - logger = logging.getLogger(__name__) - numero = forms.CharField(required=True, - label=Protocolo._meta. - get_field('numero').verbose_name - ) - ano = forms.ChoiceField(required=True, - label=Protocolo._meta. - get_field('ano').verbose_name, - choices=RANGE_ANOS, - widget=forms.Select(attrs={'class': 'selector'})) + numero = forms.CharField( + required=True, label=Protocolo._meta.get_field("numero").verbose_name + ) + ano = forms.ChoiceField( + required=True, + label=Protocolo._meta.get_field("ano").verbose_name, + choices=RANGE_ANOS, + widget=forms.Select(attrs={"class": "selector"}), + ) justificativa_anulacao = forms.CharField( required=True, - label=Protocolo._meta.get_field('justificativa_anulacao').verbose_name, - widget=forms.Textarea) + label=Protocolo._meta.get_field("justificativa_anulacao").verbose_name, + widget=forms.Textarea, + ) def clean(self): super(AnularProtocoloAdmForm, self).clean() @@ -264,158 +264,172 @@ class AnularProtocoloAdmForm(ModelForm): if not self.is_valid(): return cleaned_data - numero = cleaned_data['numero'] - ano = cleaned_data['ano'] + numero = cleaned_data["numero"] + ano = cleaned_data["ano"] try: self.logger.debug( - "Tentando obter Protocolo com numero={} e ano={}.".format(numero, ano)) + "Tentando obter Protocolo com numero={} e ano={}.".format(numero, ano) + ) protocolo = Protocolo.objects.get(numero=numero, ano=ano) if protocolo.anulado: self.logger.error( - "Protocolo %s/%s já encontra-se anulado" % (numero, ano)) + "Protocolo %s/%s já encontra-se anulado" % (numero, ano) + ) raise forms.ValidationError( - _("Protocolo %s/%s já encontra-se anulado") - % (numero, ano)) + _("Protocolo %s/%s já encontra-se anulado") % (numero, ano) + ) except ObjectDoesNotExist: self.logger.error("Protocolo %s/%s não existe" % (numero, ano)) - raise forms.ValidationError( - _("Protocolo %s/%s não existe" % (numero, ano))) + raise forms.ValidationError(_("Protocolo %s/%s não existe" % (numero, ano))) exists = False if protocolo.tipo_materia: exists = MateriaLegislativa.objects.filter( - numero_protocolo=protocolo.numero, ano=protocolo.ano).exists() + numero_protocolo=protocolo.numero, ano=protocolo.ano + ).exists() elif protocolo.tipo_documento: - exists = protocolo.documentoadministrativo_set.all( - ).order_by('-ano', '-numero').exists() + exists = ( + protocolo.documentoadministrativo_set.all() + .order_by("-ano", "-numero") + .exists() + ) if exists: - self.logger.error("Protocolo %s/%s não pode ser removido pois existem " - "documentos vinculados a ele." % (numero, ano)) + self.logger.error( + "Protocolo %s/%s não pode ser removido pois existem " + "documentos vinculados a ele." % (numero, ano) + ) raise forms.ValidationError( - _("Protocolo %s/%s não pode ser removido pois existem " - "documentos vinculados a ele." % (numero, ano))) + _( + "Protocolo %s/%s não pode ser removido pois existem " + "documentos vinculados a ele." % (numero, ano) + ) + ) return cleaned_data class Meta: model = Protocolo - fields = ['justificativa_anulacao', - 'anulado', - 'user_anulacao', - 'ip_anulacao', - ] - widgets = {'anulado': forms.HiddenInput(), - 'user_anulacao': forms.HiddenInput(), - 'ip_anulacao': forms.HiddenInput(), - } + fields = [ + "justificativa_anulacao", + "anulado", + "user_anulacao", + "ip_anulacao", + ] + widgets = { + "anulado": forms.HiddenInput(), + "user_anulacao": forms.HiddenInput(), + "ip_anulacao": forms.HiddenInput(), + } def __init__(self, *args, **kwargs): - - row1 = to_row( - [('numero', 6), - ('ano', 6)]) - row2 = to_row( - [('justificativa_anulacao', 12)]) + row1 = to_row([("numero", 6), ("ano", 6)]) + row2 = to_row([("justificativa_anulacao", 12)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset(_('Identificação do Protocolo'), - row1, - row2, - HTML(" "), - form_actions(label='Anular') - ) + Fieldset( + _("Identificação do Protocolo"), + row1, + row2, + HTML(" "), + form_actions(label="Anular"), + ) ) - super(AnularProtocoloAdmForm, self).__init__( - *args, **kwargs) + super(AnularProtocoloAdmForm, self).__init__(*args, **kwargs) class ProtocoloDocumentoForm(ModelForm): - - tipo_protocolo = forms.ChoiceField(required=True, - label=_('Tipo de Protocolo'), - choices=TIPOS_PROTOCOLO_CREATE, - widget=forms.RadioSelect(), # sem isso o Crispy Form buga com InlineRadios! - initial=0,) + tipo_protocolo = forms.ChoiceField( + required=True, + label=_("Tipo de Protocolo"), + choices=TIPOS_PROTOCOLO_CREATE, + widget=forms.RadioSelect(), # sem isso o Crispy Form buga com InlineRadios! + initial=0, + ) tipo_documento = forms.ModelChoiceField( - label=_('Tipo de Documento'), + label=_("Tipo de Documento"), required=True, queryset=TipoDocumentoAdministrativo.objects.all(), - empty_label='Selecione', + empty_label="Selecione", ) - numero_paginas = forms.CharField(label=_('Núm. Páginas'), required=True) - assunto = forms.CharField( - widget=forms.Textarea, label=_('Assunto'), required=True) + numero_paginas = forms.CharField(label=_("Núm. Páginas"), required=True) + assunto = forms.CharField(widget=forms.Textarea, label=_("Assunto"), required=True) - interessado = forms.CharField(required=True, - label=_('Interessado')) + interessado = forms.CharField(required=True, label=_("Interessado")) - observacao = forms.CharField(required=False, - widget=forms.Textarea, label=_('Observação')) + observacao = forms.CharField( + required=False, widget=forms.Textarea, label=_("Observação") + ) data_hora_manual = forms.ChoiceField( - label=_('Informar data e hora manualmente?'), + label=_("Informar data e hora manualmente?"), widget=forms.RadioSelect(), choices=YES_NO_CHOICES, - initial=False) + initial=False, + ) class Meta: model = Protocolo - fields = ['tipo_protocolo', - 'tipo_documento', - 'numero_paginas', - 'assunto', - 'interessado', - 'observacao', - 'data', - 'hora', - ] + fields = [ + "tipo_protocolo", + "tipo_documento", + "numero_paginas", + "assunto", + "interessado", + "observacao", + "data", + "hora", + ] def __init__(self, *args, **kwargs): - - row1 = to_row( - [(InlineRadios('tipo_protocolo'), 12)]) + row1 = to_row([(InlineRadios("tipo_protocolo"), 12)]) row2 = to_row( - [('tipo_documento', 5), - ('numero_paginas', 2), - (Div(), 1), - (InlineRadios('data_hora_manual'), 4), - ]) - row3 = to_row([ - (Div(), 2), - (Alert( - """ + [ + ("tipo_documento", 5), + ("numero_paginas", 2), + (Div(), 1), + (InlineRadios("data_hora_manual"), 4), + ] + ) + row3 = to_row( + [ + (Div(), 2), + ( + Alert( + """ Usuário: {} - {}
        IP: {} - {}
        """.format( - kwargs['initial']['user_data_hora_manual'], - Protocolo._meta.get_field( - 'user_data_hora_manual').help_text, - kwargs['initial']['ip_data_hora_manual'], - Protocolo._meta.get_field( - 'ip_data_hora_manual').help_text, - + kwargs["initial"]["user_data_hora_manual"], + Protocolo._meta.get_field( + "user_data_hora_manual" + ).help_text, + kwargs["initial"]["ip_data_hora_manual"], + Protocolo._meta.get_field("ip_data_hora_manual").help_text, + ), + dismiss=False, + css_class="alert-info", + ), + 6, ), - dismiss=False, - css_class='alert-info'), 6), - ('data', 2), - ('hora', 2), - ]) - row4 = to_row( - [('assunto', 12)]) - row5 = to_row( - [('interessado', 12)]) - row6 = to_row( - [('observacao', 12)]) - - fieldset = Fieldset(_('Protocolo com data e hora informados manualmente'), - row3, - css_id='protocolo_data_hora_manual') + ("data", 2), + ("hora", 2), + ] + ) + row4 = to_row([("assunto", 12)]) + row5 = to_row([("interessado", 12)]) + row6 = to_row([("observacao", 12)]) + + fieldset = Fieldset( + _("Protocolo com data e hora informados manualmente"), + row3, + css_id="protocolo_data_hora_manual", + ) config = AppConfig.objects.first() if not config.protocolo_manual: @@ -425,99 +439,97 @@ class ProtocoloDocumentoForm(ModelForm): self.helper = SaplFormHelper() self.helper.template_pack = "bootstrap4" self.helper.layout = Layout( - Fieldset(_('Identificação de Documento'), - row1, - row2), + Fieldset(_("Identificação de Documento"), row1, row2), fieldset, row4, row5, HTML(" "), - Fieldset(HTML(" "), - form_actions(label=_('Protocolar Documento')) - ) + Fieldset(HTML(" "), form_actions(label=_("Protocolar Documento"))), ) - super(ProtocoloDocumentoForm, self).__init__( - *args, **kwargs) + super(ProtocoloDocumentoForm, self).__init__(*args, **kwargs) if not config.protocolo_manual: - self.fields['data_hora_manual'].widget = forms.HiddenInput() + self.fields["data_hora_manual"].widget = forms.HiddenInput() class ProtocoloMateriaForm(ModelForm): - logger = logging.getLogger(__name__) - autor = forms.ModelChoiceField(required=True, - empty_label='------', - queryset=Autor.objects.all() - ) + autor = forms.ModelChoiceField( + required=True, empty_label="------", queryset=Autor.objects.all() + ) - tipo_autor = forms.ModelChoiceField(required=True, - empty_label='------', - queryset=TipoAutor.objects.all() - ) + tipo_autor = forms.ModelChoiceField( + required=True, empty_label="------", queryset=TipoAutor.objects.all() + ) tipo_materia = forms.ModelChoiceField( - label=_('Tipo de Matéria'), + label=_("Tipo de Matéria"), required=True, queryset=TipoMateriaLegislativa.objects.all(), - empty_label='------', + empty_label="------", ) - numero_materia = forms.CharField( - label=_('Número matéria'), required=False) + numero_materia = forms.CharField(label=_("Número matéria"), required=False) - ano_materia = forms.CharField( - label=_('Ano matéria'), required=False) + ano_materia = forms.CharField(label=_("Ano matéria"), required=False) vincular_materia = forms.ChoiceField( - label=_('Vincular a matéria existente?'), + label=_("Vincular a matéria existente?"), widget=forms.RadioSelect(), choices=YES_NO_CHOICES, - initial=False) + initial=False, + ) - numero_paginas = forms.CharField(label=_('Núm. Páginas'), required=True) + numero_paginas = forms.CharField(label=_("Núm. Páginas"), required=True) - observacao = forms.CharField(required=False, - widget=forms.Textarea, label=_('Observação')) + observacao = forms.CharField( + required=False, widget=forms.Textarea, label=_("Observação") + ) - assunto_ementa = forms.CharField(required=True, - widget=forms.Textarea, label=_('Ementa')) + assunto_ementa = forms.CharField( + required=True, widget=forms.Textarea, label=_("Ementa") + ) data_hora_manual = forms.ChoiceField( - label=_('Informar data e hora manualmente?'), + label=_("Informar data e hora manualmente?"), widget=forms.RadioSelect(), choices=YES_NO_CHOICES, - initial=False) + initial=False, + ) class Meta: model = Protocolo - fields = ['tipo_materia', - 'numero_paginas', - 'autor', - 'tipo_autor', - 'assunto_ementa', - 'observacao', - 'numero_materia', - 'ano_materia', - 'vincular_materia', - 'data', - 'hora', - ] + fields = [ + "tipo_materia", + "numero_paginas", + "autor", + "tipo_autor", + "assunto_ementa", + "observacao", + "numero_materia", + "ano_materia", + "vincular_materia", + "data", + "hora", + ] def clean_autor(self): - autor_field = self.cleaned_data['autor'] + autor_field = self.cleaned_data["autor"] try: - self.logger.debug( - "Tentando obter Autor com id={}.".format(autor_field.id)) + self.logger.debug("Tentando obter Autor com id={}.".format(autor_field.id)) autor = Autor.objects.get(id=autor_field.id) except ObjectDoesNotExist: self.logger.error( - "Autor com id={} não encontrado. Definido como None.".format(autor_field.id)) + "Autor com id={} não encontrado. Definido como None.".format( + autor_field.id + ) + ) autor_field = None else: self.logger.info( - "Autor com id={} encontrado com sucesso.".format(autor_field.id)) + "Autor com id={} encontrado com sucesso.".format(autor_field.id) + ) autor_field = autor return autor_field @@ -529,74 +541,106 @@ class ProtocoloMateriaForm(ModelForm): data = self.cleaned_data if self.is_valid(): - if data['vincular_materia'] == 'True': + if data["vincular_materia"] == "True": try: - if not data['ano_materia'] or not data['numero_materia']: + if not data["ano_materia"] or not data["numero_materia"]: self.logger.error( - "Não foram informados o número ou ano da matéria a ser vinculada") + "Não foram informados o número ou ano da matéria a ser vinculada" + ) raise ValidationError( - 'Favor informar o número e ano da matéria a ser vinculada') - self.logger.debug("Tentando obter MateriaLegislativa com ano={}, numero={} e data={}." - .format(data['ano_materia'], data['numero_materia'], data['tipo_materia'])) - self.materia = MateriaLegislativa.objects.get(ano=data['ano_materia'], - numero=data['numero_materia'], - tipo=data['tipo_materia']) + "Favor informar o número e ano da matéria a ser vinculada" + ) + self.logger.debug( + "Tentando obter MateriaLegislativa com ano={}, numero={} e data={}.".format( + data["ano_materia"], + data["numero_materia"], + data["tipo_materia"], + ) + ) + self.materia = MateriaLegislativa.objects.get( + ano=data["ano_materia"], + numero=data["numero_materia"], + tipo=data["tipo_materia"], + ) if self.materia.numero_protocolo: - self.logger.error("MateriaLegislativa informada já possui o protocolo {}/{} vinculado." - .format(self.materia.numero_protocolo, self.materia.ano)) - raise ValidationError(_('Matéria Legislativa informada já possui o protocolo {}/{} vinculado.' - .format(self.materia.numero_protocolo, self.materia.ano))) + self.logger.error( + "MateriaLegislativa informada já possui o protocolo {}/{} vinculado.".format( + self.materia.numero_protocolo, self.materia.ano + ) + ) + raise ValidationError( + _( + "Matéria Legislativa informada já possui o protocolo {}/{} vinculado.".format( + self.materia.numero_protocolo, self.materia.ano + ) + ) + ) except ObjectDoesNotExist: - self.logger.error("MateriaLegislativa informada (ano={}, numero={} e data={}) não existente." - .format(data['ano_materia'], data['numero_materia'], data['tipo_materia'])) + self.logger.error( + "MateriaLegislativa informada (ano={}, numero={} e data={}) não existente.".format( + data["ano_materia"], + data["numero_materia"], + data["tipo_materia"], + ) + ) raise ValidationError( - _('Matéria Legislativa informada não existente.')) + _("Matéria Legislativa informada não existente.") + ) return data def __init__(self, *args, **kwargs): - row1 = to_row( - [('tipo_materia', 4), - ('numero_paginas', 2), - ('tipo_autor', 3), - ('autor', 3)]) + [ + ("tipo_materia", 4), + ("numero_paginas", 2), + ("tipo_autor", 3), + ("autor", 3), + ] + ) row2 = to_row( - [(InlineRadios('vincular_materia'), 3), - ('numero_materia', 2), - ('ano_materia', 2), - (Div(), 1), - (InlineRadios('data_hora_manual'), 4), - ]) - row3 = to_row([ - (Div(), 2), - (Alert( - """ + [ + (InlineRadios("vincular_materia"), 3), + ("numero_materia", 2), + ("ano_materia", 2), + (Div(), 1), + (InlineRadios("data_hora_manual"), 4), + ] + ) + row3 = to_row( + [ + (Div(), 2), + ( + Alert( + """ Usuário: {} - {}
        IP: {} - {}
        """.format( - kwargs['initial']['user_data_hora_manual'], - Protocolo._meta.get_field( - 'user_data_hora_manual').help_text, - kwargs['initial']['ip_data_hora_manual'], - Protocolo._meta.get_field( - 'ip_data_hora_manual').help_text, - + kwargs["initial"]["user_data_hora_manual"], + Protocolo._meta.get_field( + "user_data_hora_manual" + ).help_text, + kwargs["initial"]["ip_data_hora_manual"], + Protocolo._meta.get_field("ip_data_hora_manual").help_text, + ), + dismiss=False, + css_class="alert-info", + ), + 6, ), - dismiss=False, - css_class='alert-info'), 6), - ('data', 2), - ('hora', 2), - ]) - row4 = to_row( - [('assunto_ementa', 12)]) - row5 = to_row( - [('observacao', 12)]) + ("data", 2), + ("hora", 2), + ] + ) + row4 = to_row([("assunto_ementa", 12)]) + row5 = to_row([("observacao", 12)]) - fieldset = Fieldset(_('Protocolo com data e hora informados manualmente'), - row3, - css_id='protocolo_data_hora_manual') + fieldset = Fieldset( + _("Protocolo com data e hora informados manualmente"), + row3, + css_id="protocolo_data_hora_manual", + ) config = AppConfig.objects.first() if not config.protocolo_manual: @@ -605,38 +649,26 @@ class ProtocoloMateriaForm(ModelForm): self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset(_('Identificação da Matéria'), - row1, - row2), + Fieldset(_("Identificação da Matéria"), row1, row2), fieldset, row4, row5, HTML(" "), - Fieldset(HTML(" "), - form_actions(label=_('Protocolar Matéria'))) + Fieldset(HTML(" "), form_actions(label=_("Protocolar Matéria"))), ) - super(ProtocoloMateriaForm, self).__init__( - *args, **kwargs) + super(ProtocoloMateriaForm, self).__init__(*args, **kwargs) if not config.protocolo_manual: - self.fields['data_hora_manual'].widget = forms.HiddenInput() + self.fields["data_hora_manual"].widget = forms.HiddenInput() class DocumentoAcessorioAdministrativoForm(FileFieldCheckMixin, ModelForm): - class Meta: model = DocumentoAcessorioAdministrativo - fields = ['tipo', - 'nome', - 'data', - 'autor', - 'arquivo', - 'assunto'] + fields = ["tipo", "nome", "data", "autor", "arquivo", "assunto"] - widgets = { - 'data': forms.DateInput(format='%d/%m/%Y') - } + widgets = {"data": forms.DateInput(format="%d/%m/%Y")} def clean(self): super(DocumentoAcessorioAdministrativoForm, self).clean() @@ -644,7 +676,7 @@ class DocumentoAcessorioAdministrativoForm(FileFieldCheckMixin, ModelForm): if not self.is_valid(): return self.cleaned_data - arquivo = self.cleaned_data.get('arquivo') + arquivo = self.cleaned_data.get("arquivo") if arquivo: validar_arquivo(arquivo, "Arquivo") @@ -659,39 +691,41 @@ class DocumentoAcessorioAdministrativoForm(FileFieldCheckMixin, ModelForm): class TramitacaoAdmForm(ModelForm): - logger = logging.getLogger(__name__) class Meta: model = TramitacaoAdministrativo - fields = ['data_tramitacao', - 'unidade_tramitacao_local', - 'status', - 'urgente', - 'unidade_tramitacao_destino', - 'data_encaminhamento', - 'data_fim_prazo', - 'texto', - 'user', - 'ip', - 'ultima_edicao'] - - widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput()} + fields = [ + "data_tramitacao", + "unidade_tramitacao_local", + "status", + "urgente", + "unidade_tramitacao_destino", + "data_encaminhamento", + "data_fim_prazo", + "texto", + "user", + "ip", + "ultima_edicao", + ] + + widgets = { + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), + } def __init__(self, *args, **kwargs): super(TramitacaoAdmForm, self).__init__(*args, **kwargs) - self.fields['data_tramitacao'].initial = timezone.now().date() + self.fields["data_tramitacao"].initial = timezone.now().date() ust = UnidadeTramitacao.objects.select_related().all() - unidade_tramitacao_destino = [('', '---------')] + [(ut.pk, ut) - for ut in ust if ut.comissao and ut.comissao.ativa] - unidade_tramitacao_destino.extend( - [(ut.pk, ut) for ut in ust if ut.orgao]) - unidade_tramitacao_destino.extend( - [(ut.pk, ut) for ut in ust if ut.parlamentar]) - self.fields['unidade_tramitacao_destino'].choices = unidade_tramitacao_destino - self.fields['urgente'].label = "Urgente? *" + unidade_tramitacao_destino = [("", "---------")] + [ + (ut.pk, ut) for ut in ust if ut.comissao and ut.comissao.ativa + ] + unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.orgao]) + unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.parlamentar]) + self.fields["unidade_tramitacao_destino"].choices = unidade_tramitacao_destino + self.fields["urgente"].label = "Urgente? *" def clean(self): cleaned_data = super(TramitacaoAdmForm, self).clean() @@ -699,67 +733,91 @@ class TramitacaoAdmForm(ModelForm): if not self.is_valid(): return self.cleaned_data - if 'data_encaminhamento' in cleaned_data: - data_enc_form = cleaned_data['data_encaminhamento'] - if 'data_fim_prazo' in cleaned_data: - data_prazo_form = cleaned_data['data_fim_prazo'] - if 'data_tramitacao' in cleaned_data: - data_tram_form = cleaned_data['data_tramitacao'] + if "data_encaminhamento" in cleaned_data: + data_enc_form = cleaned_data["data_encaminhamento"] + if "data_fim_prazo" in cleaned_data: + data_prazo_form = cleaned_data["data_fim_prazo"] + if "data_tramitacao" in cleaned_data: + data_tram_form = cleaned_data["data_tramitacao"] if not self.is_valid(): return cleaned_data - ultima_tramitacao = TramitacaoAdministrativo.objects.filter( - documento_id=self.instance.documento_id).exclude( - id=self.instance.id).order_by( - '-data_tramitacao', - '-id').first() + ultima_tramitacao = ( + TramitacaoAdministrativo.objects.filter( + documento_id=self.instance.documento_id + ) + .exclude(id=self.instance.id) + .order_by("-data_tramitacao", "-id") + .first() + ) if not self.instance.data_tramitacao: if ultima_tramitacao: destino = ultima_tramitacao.unidade_tramitacao_destino - if (destino != self.cleaned_data['unidade_tramitacao_local']): - self.logger.error('A origem da nova tramitação ({}) deve ser ' - 'igual ao destino ({}) da última adicionada!' - .format(self.cleaned_data['unidade_tramitacao_local'], destino)) - msg = _('A origem da nova tramitação deve ser igual ao ' - 'destino da última adicionada!') + if destino != self.cleaned_data["unidade_tramitacao_local"]: + self.logger.error( + "A origem da nova tramitação ({}) deve ser " + "igual ao destino ({}) da última adicionada!".format( + self.cleaned_data["unidade_tramitacao_local"], destino + ) + ) + msg = _( + "A origem da nova tramitação deve ser igual ao " + "destino da última adicionada!" + ) raise ValidationError(msg) - if self.cleaned_data['data_tramitacao'] > timezone.now().date(): - self.logger.error('A data de tramitação ({}) deve ser ' - 'menor ou igual a data de hoje ({})!' - .format(self.cleaned_data['data_tramitacao'], timezone.now().date())) + if self.cleaned_data["data_tramitacao"] > timezone.now().date(): + self.logger.error( + "A data de tramitação ({}) deve ser " + "menor ou igual a data de hoje ({})!".format( + self.cleaned_data["data_tramitacao"], timezone.now().date() + ) + ) msg = _( - 'A data de tramitação deve ser ' + - 'menor ou igual a data de hoje!') + "A data de tramitação deve ser " + "menor ou igual a data de hoje!" + ) raise ValidationError(msg) - if (ultima_tramitacao and - data_tram_form < ultima_tramitacao.data_tramitacao): - self.logger.error('A data da nova tramitação ({}) deve ser ' - 'maior que a data da última tramitação ({})!' - .format(data_tram_form, ultima_tramitacao.data_tramitacao)) - msg = _('A data da nova tramitação deve ser ' + - 'maior que a data da última tramitação!') + if ultima_tramitacao and data_tram_form < ultima_tramitacao.data_tramitacao: + self.logger.error( + "A data da nova tramitação ({}) deve ser " + "maior que a data da última tramitação ({})!".format( + data_tram_form, ultima_tramitacao.data_tramitacao + ) + ) + msg = _( + "A data da nova tramitação deve ser " + + "maior que a data da última tramitação!" + ) raise ValidationError(msg) 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.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!" + ) raise ValidationError(msg) if data_prazo_form: if data_prazo_form < data_tram_form: - self.logger.error('A data fim de prazo ({}) deve ser ' - 'maior que a data de tramitação ({})!' - .format(data_prazo_form, data_tram_form)) - msg = _('A data fim de prazo deve ser ' + - 'maior que a data de tramitação!') + self.logger.error( + "A data fim de prazo ({}) deve ser " + "maior que a data de tramitação ({})!".format( + data_prazo_form, data_tram_form + ) + ) + msg = _( + "A data fim de prazo deve ser " + "maior que a data de tramitação!" + ) raise ValidationError(msg) return self.cleaned_data @@ -772,30 +830,36 @@ class TramitacaoAdmForm(ModelForm): documento.tramitacao = False if tramitacao.status.indicador == "F" else True documento.save() - tramitar_anexados = AppConfig.attr('tramitacao_documento') + tramitar_anexados = AppConfig.attr("tramitacao_documento") if tramitar_anexados: lista_tramitacao = [] anexados_list = lista_anexados(documento) for da in anexados_list: - if not da.tramitacaoadministrativo_set.all() \ - or da.tramitacaoadministrativo_set.last() \ - .unidade_tramitacao_destino == tramitacao.unidade_tramitacao_local: - da.tramitacao = False if tramitacao.status.indicador == "F" else True + if ( + not da.tramitacaoadministrativo_set.all() + or da.tramitacaoadministrativo_set.last().unidade_tramitacao_destino + == tramitacao.unidade_tramitacao_local + ): + da.tramitacao = ( + False if tramitacao.status.indicador == "F" else True + ) da.save() - lista_tramitacao.append(TramitacaoAdministrativo( - status=tramitacao.status, - documento=da, - data_tramitacao=tramitacao.data_tramitacao, - unidade_tramitacao_local=tramitacao.unidade_tramitacao_local, - data_encaminhamento=tramitacao.data_encaminhamento, - unidade_tramitacao_destino=tramitacao.unidade_tramitacao_destino, - urgente=tramitacao.urgente, - texto=tramitacao.texto, - data_fim_prazo=tramitacao.data_fim_prazo, - user=tramitacao.user, - ip=tramitacao.ip, - ultima_edicao=tramitacao.ultima_edicao - )) + lista_tramitacao.append( + TramitacaoAdministrativo( + status=tramitacao.status, + documento=da, + data_tramitacao=tramitacao.data_tramitacao, + unidade_tramitacao_local=tramitacao.unidade_tramitacao_local, + data_encaminhamento=tramitacao.data_encaminhamento, + unidade_tramitacao_destino=tramitacao.unidade_tramitacao_destino, + urgente=tramitacao.urgente, + texto=tramitacao.texto, + data_fim_prazo=tramitacao.data_fim_prazo, + user=tramitacao.user, + ip=tramitacao.ip, + ultima_edicao=tramitacao.ultima_edicao, + ) + ) # TODO: BULK UPDATE não envia Signal para Tramitacao TramitacaoAdministrativo.objects.bulk_create(lista_tramitacao) @@ -808,19 +872,24 @@ def compara_tramitacoes_doc(tramitacao1, tramitacao2): if not tramitacao1 or not tramitacao2: return False - lst_items = ['id', 'documento_id', 'timestamp', 'ultima_edicao'] - values = [(k, v) for k, v in tramitacao1.__dict__.items() - if ((k not in lst_items) and (k[0] != '_'))] - other_values = [(k, v) for k, v in tramitacao2.__dict__.items() - if (k not in lst_items and k[0] != '_')] + lst_items = ["id", "documento_id", "timestamp", "ultima_edicao"] + values = [ + (k, v) + for k, v in tramitacao1.__dict__.items() + if ((k not in lst_items) and (k[0] != "_")) + ] + other_values = [ + (k, v) + for k, v in tramitacao2.__dict__.items() + if (k not in lst_items and k[0] != "_") + ] return values == other_values class TramitacaoAdmEditForm(TramitacaoAdmForm): - unidade_tramitacao_local = forms.ModelChoiceField( - queryset=UnidadeTramitacao.objects.all(), - widget=forms.HiddenInput()) + queryset=UnidadeTramitacao.objects.all(), widget=forms.HiddenInput() + ) data_tramitacao = forms.DateField(widget=forms.HiddenInput()) @@ -828,21 +897,25 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): class Meta: model = TramitacaoAdministrativo - fields = ['data_tramitacao', - 'unidade_tramitacao_local', - 'status', - 'urgente', - 'unidade_tramitacao_destino', - 'data_encaminhamento', - 'data_fim_prazo', - 'texto', - 'user', - 'ip', - 'ultima_edicao'] - - widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput()} + fields = [ + "data_tramitacao", + "unidade_tramitacao_local", + "status", + "urgente", + "unidade_tramitacao_destino", + "data_encaminhamento", + "data_fim_prazo", + "texto", + "user", + "ip", + "ultima_edicao", + ] + + widgets = { + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), + } def clean(self): super(TramitacaoAdmEditForm, self).clean() @@ -853,51 +926,58 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): cd = self.cleaned_data obj = self.instance - ultima_tramitacao = TramitacaoAdministrativo.objects.filter( - documento_id=obj.documento_id).order_by( - '-data_tramitacao', - '-id').first() + ultima_tramitacao = ( + TramitacaoAdministrativo.objects.filter(documento_id=obj.documento_id) + .order_by("-data_tramitacao", "-id") + .first() + ) # Se a Tramitação que está sendo editada não for a mais recente, # ela não pode ter seu destino alterado. if ultima_tramitacao != obj: - if cd['unidade_tramitacao_destino'] != \ - obj.unidade_tramitacao_destino: - self.logger.error('Você não pode mudar a Unidade de Destino desta ' - 'tramitação (id={}), pois irá conflitar com a Unidade ' - 'Local da tramitação seguinte'.format(obj.documento_id)) + if cd["unidade_tramitacao_destino"] != obj.unidade_tramitacao_destino: + self.logger.error( + "Você não pode mudar a Unidade de Destino desta " + "tramitação (id={}), pois irá conflitar com a Unidade " + "Local da tramitação seguinte".format(obj.documento_id) + ) raise ValidationError( - 'Você não pode mudar a Unidade de Destino desta ' - 'tramitação, pois irá conflitar com a Unidade ' - 'Local da tramitação seguinte') + "Você não pode mudar a Unidade de Destino desta " + "tramitação, pois irá conflitar com a Unidade " + "Local da tramitação seguinte" + ) # Se não houve qualquer alteração em um dos dados, mantém o usuário e # ip - if not (cd['data_tramitacao'] != obj.data_tramitacao or - cd['unidade_tramitacao_destino'] != obj.unidade_tramitacao_destino or - cd['status'] != obj.status or cd['texto'] != obj.texto or - cd['data_encaminhamento'] != obj.data_encaminhamento or - cd['data_fim_prazo'] != obj.data_fim_prazo): - cd['user'] = obj.user - cd['ip'] = obj.ip - cd['ultima_edicao'] = obj.ultima_edicao - - cd['data_tramitacao'] = obj.data_tramitacao - cd['unidade_tramitacao_local'] = obj.unidade_tramitacao_local + if not ( + cd["data_tramitacao"] != obj.data_tramitacao + or cd["unidade_tramitacao_destino"] != obj.unidade_tramitacao_destino + or cd["status"] != obj.status + or cd["texto"] != obj.texto + or cd["data_encaminhamento"] != obj.data_encaminhamento + or cd["data_fim_prazo"] != obj.data_fim_prazo + ): + cd["user"] = obj.user + cd["ip"] = obj.ip + cd["ultima_edicao"] = obj.ultima_edicao + + cd["data_tramitacao"] = obj.data_tramitacao + cd["unidade_tramitacao_local"] = obj.unidade_tramitacao_local return cd @timing @transaction.atomic def save(self, commit=True): - ant_tram_principal = TramitacaoAdministrativo.objects.get( - id=self.instance.id) + ant_tram_principal = TramitacaoAdministrativo.objects.get(id=self.instance.id) nova_tram_principal = super(TramitacaoAdmEditForm, self).save(commit) documento = nova_tram_principal.documento - documento.tramitacao = False if nova_tram_principal.status.indicador == "F" else True + documento.tramitacao = ( + False if nova_tram_principal.status.indicador == "F" else True + ) documento.save() - tramitar_anexados = AppConfig.attr('tramitacao_documento') + tramitar_anexados = AppConfig.attr("tramitacao_documento") if tramitar_anexados: anexados_list = lista_anexados(documento) for da in anexados_list: @@ -905,9 +985,15 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): if compara_tramitacoes_doc(ant_tram_principal, tram_anexada): tram_anexada.status = nova_tram_principal.status tram_anexada.data_tramitacao = nova_tram_principal.data_tramitacao - tram_anexada.unidade_tramitacao_local = nova_tram_principal.unidade_tramitacao_local - tram_anexada.data_encaminhamento = nova_tram_principal.data_encaminhamento - tram_anexada.unidade_tramitacao_destino = nova_tram_principal.unidade_tramitacao_destino + tram_anexada.unidade_tramitacao_local = ( + nova_tram_principal.unidade_tramitacao_local + ) + tram_anexada.data_encaminhamento = ( + nova_tram_principal.data_encaminhamento + ) + tram_anexada.unidade_tramitacao_destino = ( + nova_tram_principal.unidade_tramitacao_destino + ) tram_anexada.urgente = nova_tram_principal.urgente tram_anexada.texto = nova_tram_principal.texto tram_anexada.data_fim_prazo = nova_tram_principal.data_fim_prazo @@ -916,26 +1002,27 @@ class TramitacaoAdmEditForm(TramitacaoAdmForm): tram_anexada.ultima_edicao = nova_tram_principal.ultima_edicao tram_anexada.save() - da.tramitacao = False if nova_tram_principal.status.indicador == "F" else True + da.tramitacao = ( + False if nova_tram_principal.status.indicador == "F" else True + ) da.save() # TODO: refatorar? return nova_tram_principal class AnexadoForm(ModelForm): - logger = logging.getLogger(__name__) tipo = forms.ModelChoiceField( - label='Tipo', + label="Tipo", required=True, queryset=TipoDocumentoAdministrativo.objects.all(), - empty_label='Selecione' + empty_label="Selecione", ) - numero = forms.CharField(label='Número', required=True) + numero = forms.CharField(label="Número", required=True) - ano = forms.CharField(label='Ano', required=True) + ano = forms.CharField(label="Ano", required=True) def __init__(self, *args, **kwargs): return super(AnexadoForm, self).__init__(*args, **kwargs) @@ -948,159 +1035,177 @@ class AnexadoForm(ModelForm): cleaned_data = self.cleaned_data - data_anexacao = cleaned_data['data_anexacao'] - data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao + data_anexacao = cleaned_data["data_anexacao"] + data_desanexacao = ( + cleaned_data["data_desanexacao"] + if cleaned_data["data_desanexacao"] + else data_anexacao + ) if data_anexacao > data_desanexacao: - self.logger.error( - "Data de anexação posterior à data de desanexação.") + self.logger.error("Data de anexação posterior à data de desanexação.") raise ValidationError( - _("Data de anexação posterior à data de desanexação.")) + _("Data de anexação posterior à data de desanexação.") + ) try: self.logger.info( - "Tentando obter objeto DocumentoAdministrativo (numero={}, ano={}, tipo={})." - .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo']) + "Tentando obter objeto DocumentoAdministrativo (numero={}, ano={}, tipo={}).".format( + cleaned_data["numero"], cleaned_data["ano"], cleaned_data["tipo"] + ) ) documento_anexado = DocumentoAdministrativo.objects.get( - numero=cleaned_data['numero'], - ano=cleaned_data['ano'], - tipo=cleaned_data['tipo'] + numero=cleaned_data["numero"], + ano=cleaned_data["ano"], + tipo=cleaned_data["tipo"], ) except ObjectDoesNotExist: - msg = _('O {} {}/{} não existe no cadastro de documentos administrativos.' - .format(cleaned_data['tipo'], cleaned_data['numero'], cleaned_data['ano'])) - self.logger.error("O documento a ser anexado não existe no cadastro" - " de documentos administrativos") + msg = _( + "O {} {}/{} não existe no cadastro de documentos administrativos.".format( + cleaned_data["tipo"], cleaned_data["numero"], cleaned_data["ano"] + ) + ) + self.logger.error( + "O documento a ser anexado não existe no cadastro" + " de documentos administrativos" + ) raise ValidationError(msg) documento_principal = self.instance.documento_principal if documento_principal == documento_anexado: self.logger.error("O documento não pode ser anexado a si mesmo.") - raise ValidationError( - _("O documento não pode ser anexado a si mesmo")) + raise ValidationError(_("O documento não pode ser anexado a si mesmo")) - is_anexado = Anexado.objects.filter(documento_principal=documento_principal, - documento_anexado=documento_anexado - ).exclude(pk=self.instance.pk).exists() + is_anexado = ( + Anexado.objects.filter( + documento_principal=documento_principal, + documento_anexado=documento_anexado, + ) + .exclude(pk=self.instance.pk) + .exists() + ) if is_anexado: self.logger.error("Documento já se encontra anexado.") - raise ValidationError(_('Documento já se encontra anexado')) + raise ValidationError(_("Documento já se encontra anexado")) ciclico = False - anexados_anexado = Anexado.objects.filter( - documento_principal=documento_anexado) + anexados_anexado = Anexado.objects.filter(documento_principal=documento_anexado) - while(anexados_anexado and not ciclico): + while anexados_anexado and not ciclico: anexados = [] for anexo in anexados_anexado: - if documento_principal == anexo.documento_anexado: ciclico = True else: - for a in Anexado.objects.filter(documento_principal=anexo.documento_anexado): + for a in Anexado.objects.filter( + documento_principal=anexo.documento_anexado + ): anexados.append(a) anexados_anexado = anexados if ciclico: self.logger.error( - "O documento não pode ser anexado por um de seus anexados.") + "O documento não pode ser anexado por um de seus anexados." + ) raise ValidationError( - _('O documento não pode ser anexado por um de seus anexados')) + _("O documento não pode ser anexado por um de seus anexados") + ) - cleaned_data['documento_anexado'] = documento_anexado + cleaned_data["documento_anexado"] = documento_anexado return cleaned_data def save(self, commit=False): anexado = super(AnexadoForm, self).save(commit) - anexado.documento_anexado = self.cleaned_data['documento_anexado'] + anexado.documento_anexado = self.cleaned_data["documento_anexado"] anexado.save() return anexado class Meta: model = Anexado - fields = ['tipo', 'numero', 'ano', 'data_anexacao', 'data_desanexacao'] + fields = ["tipo", "numero", "ano", "data_anexacao", "data_desanexacao"] class AnexadoEmLoteFilterSet(django_filters.FilterSet): - class Meta(FilterOverridesMetaMixin): model = DocumentoAdministrativo - fields = ['tipo', 'data'] + fields = ["tipo", "data"] def __init__(self, *args, **kwargs): super(AnexadoEmLoteFilterSet, self).__init__(*args, **kwargs) - self.filters['tipo'].label = 'Tipo de Documento*' - self.filters['data'].label = 'Data (Inicial - Final)*' + self.filters["tipo"].label = "Tipo de Documento*" + self.filters["data"].label = "Data (Inicial - Final)*" - row1 = to_row([('tipo', 12)]) - row2 = to_row([('data', 12)]) + row1 = to_row([("tipo", 12)]) + row2 = to_row([("data", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Documentos'), - row1, row2, form_actions(label='Pesquisar')) + Fieldset( + _("Pesquisa de Documentos"), row1, row2, form_actions(label="Pesquisar") + ) ) class DocumentoAdministrativoForm(FileFieldCheckMixin, ModelForm): - logger = logging.getLogger(__name__) data = forms.DateField(initial=timezone.now) ano_protocolo = forms.ChoiceField( required=False, - label=Protocolo._meta. - get_field('ano').verbose_name, + label=Protocolo._meta.get_field("ano").verbose_name, choices=choice_force_optional(choice_anos_com_protocolo), - widget=forms.Select( - attrs={'class': 'selector'})) + widget=forms.Select(attrs={"class": "selector"}), + ) - numero_protocolo = forms.IntegerField(required=False, - label=Protocolo._meta. - get_field('numero').verbose_name) + numero_protocolo = forms.IntegerField( + required=False, label=Protocolo._meta.get_field("numero").verbose_name + ) - restrito = forms.ChoiceField(label=_('Acesso Restrito'), - widget=forms.RadioSelect(), - choices=YES_NO_CHOICES, - initial=False) + restrito = forms.ChoiceField( + label=_("Acesso Restrito"), + widget=forms.RadioSelect(), + choices=YES_NO_CHOICES, + initial=False, + ) class Meta: model = DocumentoAdministrativo - fields = ['tipo', - 'numero', - 'complemento', - 'ano', - 'data', - 'numero_protocolo', - 'ano_protocolo', - 'assunto', - 'interessado', - 'tramitacao', - 'dias_prazo', - 'data_fim_prazo', - 'numero_externo', - 'observacao', - 'texto_integral', - 'protocolo', - 'restrito', - 'user', - 'ip', - 'ultima_edicao', - 'autor' - ] - - widgets = {'protocolo': forms.HiddenInput(), - 'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput() - } + fields = [ + "tipo", + "numero", + "complemento", + "ano", + "data", + "numero_protocolo", + "ano_protocolo", + "assunto", + "interessado", + "tramitacao", + "dias_prazo", + "data_fim_prazo", + "numero_externo", + "observacao", + "texto_integral", + "protocolo", + "restrito", + "user", + "ip", + "ultima_edicao", + "autor", + ] + + widgets = { + "protocolo": forms.HiddenInput(), + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), + } def clean(self): super(DocumentoAdministrativoForm, self).clean() @@ -1110,62 +1215,77 @@ class DocumentoAdministrativoForm(FileFieldCheckMixin, ModelForm): if not self.is_valid(): return cleaned_data - numero_protocolo = self.data['numero_protocolo'] - ano_protocolo = self.data['ano_protocolo'] - complemento = re.sub(r'\s+', '', self.data['complemento']).upper() - numero_documento = int(self.cleaned_data['numero']) - tipo_documento = int(self.data['tipo']) - ano_documento = int(self.data['ano']) + numero_protocolo = self.data["numero_protocolo"] + ano_protocolo = self.data["ano_protocolo"] + complemento = re.sub(r"\s+", "", self.data["complemento"]).upper() + numero_documento = int(self.cleaned_data["numero"]) + tipo_documento = int(self.data["tipo"]) + ano_documento = int(self.data["ano"]) # não permite atualizar para numero/ano/tipo existente if self.instance.pk: - mudanca_doc = numero_documento != self.instance.numero \ - or ano_documento != self.instance.ano \ - or tipo_documento != self.instance.tipo.pk \ + mudanca_doc = ( + numero_documento != self.instance.numero + or ano_documento != self.instance.ano + or tipo_documento != self.instance.tipo.pk or complemento != self.instance.complemento + ) if not self.instance.pk or mudanca_doc: - doc_exists = DocumentoAdministrativo.objects.filter(numero=numero_documento, - tipo=tipo_documento, - ano=ano_documento, - complemento=complemento).exists() + doc_exists = DocumentoAdministrativo.objects.filter( + numero=numero_documento, + tipo=tipo_documento, + ano=ano_documento, + complemento=complemento, + ).exists() if doc_exists: - self.logger.error("DocumentoAdministrativo " - "(numero={}, tipo={}, ano={}, " - "complemento={}) já existe." - .format(numero_documento, - tipo_documento, - ano_documento, - complemento)) - tipo = TipoDocumentoAdministrativo.objects.get( - id=tipo_documento) + self.logger.error( + "DocumentoAdministrativo " + "(numero={}, tipo={}, ano={}, " + "complemento={}) já existe.".format( + numero_documento, tipo_documento, ano_documento, complemento + ) + ) + tipo = TipoDocumentoAdministrativo.objects.get(id=tipo_documento) raise ValidationError( - _('{}/{} ({}) já existente! ' - 'Você diferenciar preenchendo o campo complemento'.format(numero_documento, - ano_documento, - tipo))) + _( + "{}/{} ({}) já existente! " + "Você diferenciar preenchendo o campo complemento".format( + numero_documento, ano_documento, tipo + ) + ) + ) # campos opcionais, mas que se informados devem ser válidos if numero_protocolo and ano_protocolo: try: - self.logger.debug("Tentando obter Protocolo com numero={} e ano={}." - .format(numero_protocolo, ano_protocolo)) - self.fields['protocolo'].initial = Protocolo.objects.get( - numero=numero_protocolo, - ano=ano_protocolo).pk + self.logger.debug( + "Tentando obter Protocolo com numero={} e ano={}.".format( + numero_protocolo, ano_protocolo + ) + ) + self.fields["protocolo"].initial = Protocolo.objects.get( + numero=numero_protocolo, ano=ano_protocolo + ).pk except ObjectDoesNotExist: - self.logger.error("Protocolo %s/%s inexistente." % ( - numero_protocolo, ano_protocolo)) - msg = _('Protocolo %s/%s inexistente.' % ( - numero_protocolo, ano_protocolo)) + self.logger.error( + "Protocolo %s/%s inexistente." % (numero_protocolo, ano_protocolo) + ) + msg = _( + "Protocolo %s/%s inexistente." % (numero_protocolo, ano_protocolo) + ) raise ValidationError(msg) except MultipleObjectsReturned: - self.logger.error("Existe mais de um Protocolo com este ano ({}) e número ({}).".format( - ano_protocolo, numero_protocolo)) + self.logger.error( + "Existe mais de um Protocolo com este ano ({}) e número ({}).".format( + ano_protocolo, numero_protocolo + ) + ) msg = _( - 'Existe mais de um Protocolo com este ano (%s) e número (%s).' % ( - ano_protocolo, numero_protocolo)) + "Existe mais de um Protocolo com este ano (%s) e número (%s)." + % (ano_protocolo, numero_protocolo) + ) raise ValidationError(msg) inst = self.instance.protocolo @@ -1173,20 +1293,25 @@ class DocumentoAdministrativoForm(FileFieldCheckMixin, ModelForm): if str(protocolo_antigo) != numero_protocolo: exist_materia = MateriaLegislativa.objects.filter( - numero_protocolo=numero_protocolo, - ano=ano_protocolo).exists() + numero_protocolo=numero_protocolo, ano=ano_protocolo + ).exists() exist_doc = DocumentoAdministrativo.objects.filter( - protocolo__numero=numero_protocolo, - protocolo__ano=ano_protocolo).exists() + protocolo__numero=numero_protocolo, protocolo__ano=ano_protocolo + ).exists() if exist_materia or exist_doc: - self.logger.error('Protocolo com numero=%s e ano=%s já possui' - ' documento vinculado' % (numero_protocolo, ano_protocolo)) - raise ValidationError(_('Protocolo %s/%s já possui' - ' documento vinculado' - % (numero_protocolo, ano_protocolo))) + self.logger.error( + "Protocolo com numero=%s e ano=%s já possui" + " documento vinculado" % (numero_protocolo, ano_protocolo) + ) + raise ValidationError( + _( + "Protocolo %s/%s já possui" + " documento vinculado" % (numero_protocolo, ano_protocolo) + ) + ) - texto_integral = self.cleaned_data.get('texto_integral') + texto_integral = self.cleaned_data.get("texto_integral") if texto_integral: validar_arquivo(texto_integral, "Texto Integral") @@ -1201,60 +1326,56 @@ class DocumentoAdministrativoForm(FileFieldCheckMixin, ModelForm): def save(self, commit=True): documento = super(DocumentoAdministrativoForm, self).save(False) - if self.fields['protocolo'].initial: + if self.fields["protocolo"].initial: documento.protocolo = Protocolo.objects.get( - id=int(self.fields['protocolo'].initial)) + id=int(self.fields["protocolo"].initial) + ) documento.save() return documento def __init__(self, *args, **kwargs): - - row1 = to_row( - [('tipo', 3), ('numero', 3), ('complemento', 3), ('ano', 3)]) + row1 = to_row([("tipo", 3), ("numero", 3), ("complemento", 3), ("ano", 3)]) row2 = to_row( - [('data', 3), ('numero_protocolo', 3), ('ano_protocolo', 3), ('autor', 3)]) + [("data", 3), ("numero_protocolo", 3), ("ano_protocolo", 3), ("autor", 3)] + ) - row3 = to_row( - [('assunto', 12)]) + row3 = to_row([("assunto", 12)]) row4 = to_row( - [('interessado', 7), ('tramitacao', 2), (InlineRadios('restrito'), 3)]) + [("interessado", 7), ("tramitacao", 2), (InlineRadios("restrito"), 3)] + ) - row5 = to_row( - [('texto_integral', 12)]) + row5 = to_row([("texto_integral", 12)]) - row6 = to_row( - [('numero_externo', 4), ('dias_prazo', 6), ('data_fim_prazo', 2)]) + row6 = to_row([("numero_externo", 4), ("dias_prazo", 6), ("data_fim_prazo", 2)]) - row7 = to_row( - [('observacao', 12)]) + row7 = to_row([("observacao", 12)]) self.helper = SaplFormHelper() self.helper.layout = SaplFormLayout( - Fieldset(_('Identificação Básica'), - row1, row2, row3, row4, row5), - Fieldset(_('Outras Informações'), - row6, row7)) - super(DocumentoAdministrativoForm, self).__init__( - *args, **kwargs) + Fieldset(_("Identificação Básica"), row1, row2, row3, row4, row5), + Fieldset(_("Outras Informações"), row6, row7), + ) + super(DocumentoAdministrativoForm, self).__init__(*args, **kwargs) class DesvincularDocumentoForm(ModelForm): - logger = logging.getLogger(__name__) numero = forms.CharField( required=True, - label=DocumentoAdministrativo._meta.get_field('numero').verbose_name) + label=DocumentoAdministrativo._meta.get_field("numero").verbose_name, + ) ano = forms.ChoiceField( required=True, - label=DocumentoAdministrativo._meta.get_field('ano').verbose_name, + label=DocumentoAdministrativo._meta.get_field("ano").verbose_name, choices=choice_anos_com_documentoadministrativo, - widget=forms.Select(attrs={'class': 'selector'})) + widget=forms.Select(attrs={"class": "selector"}), + ) def clean(self): super(DesvincularDocumentoForm, self).clean() @@ -1264,68 +1385,77 @@ class DesvincularDocumentoForm(ModelForm): if not self.is_valid(): return cleaned_data - numero = cleaned_data['numero'] - ano = cleaned_data['ano'] - tipo = cleaned_data['tipo'] + numero = cleaned_data["numero"] + ano = cleaned_data["ano"] + tipo = cleaned_data["tipo"] try: - self.logger.debug("Tentando obter DocumentoAdministrativo com numero={}, ano={} e tipo={}." - .format(numero, ano, tipo)) + self.logger.debug( + "Tentando obter DocumentoAdministrativo com numero={}, ano={} e tipo={}.".format( + numero, ano, tipo + ) + ) documento = DocumentoAdministrativo.objects.get( - numero=numero, ano=ano, tipo=tipo) + numero=numero, ano=ano, tipo=tipo + ) if not documento.protocolo: self.logger.error( - "DocumentoAdministrativo %s %s/%s não se encontra vinculado a nenhum protocolo." % (tipo, numero, ano)) + "DocumentoAdministrativo %s %s/%s não se encontra vinculado a nenhum protocolo." + % (tipo, numero, ano) + ) raise forms.ValidationError( - _("%s %s/%s não se encontra vinculado a nenhum protocolo" % (tipo, numero, ano))) + _( + "%s %s/%s não se encontra vinculado a nenhum protocolo" + % (tipo, numero, ano) + ) + ) except ObjectDoesNotExist: self.logger.error( - "DocumentoAdministrativo %s %s/%s não existe" % (tipo, numero, ano)) - raise forms.ValidationError( - _("%s %s/%s não existe" % (tipo, numero, ano))) + "DocumentoAdministrativo %s %s/%s não existe" % (tipo, numero, ano) + ) + raise forms.ValidationError(_("%s %s/%s não existe" % (tipo, numero, ano))) return cleaned_data class Meta: model = DocumentoAdministrativo - fields = ['tipo', - 'numero', - 'ano', - ] + fields = [ + "tipo", + "numero", + "ano", + ] def __init__(self, *args, **kwargs): - - row1 = to_row( - [('numero', 4), - ('ano', 4), - ('tipo', 4)]) + row1 = to_row([("numero", 4), ("ano", 4), ("tipo", 4)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset(_('Identificação do Documento'), - row1, - HTML(" "), - form_actions(label='Desvincular') - ) + Fieldset( + _("Identificação do Documento"), + row1, + HTML(" "), + form_actions(label="Desvincular"), + ) ) - super(DesvincularDocumentoForm, self).__init__( - *args, **kwargs) + super(DesvincularDocumentoForm, self).__init__(*args, **kwargs) class DesvincularMateriaForm(forms.Form): - logger = logging.getLogger(__name__) - numero = forms.CharField(required=True, - label=_('Número da Matéria')) - ano = forms.ChoiceField(required=True, - label=_('Ano da Matéria'), - choices=choice_anos_com_materias, - widget=forms.Select(attrs={'class': 'selector'})) - tipo = forms.ModelChoiceField(label=_('Tipo de Matéria'), - required=True, - queryset=TipoMateriaLegislativa.objects.all(), - empty_label='------') + numero = forms.CharField(required=True, label=_("Número da Matéria")) + ano = forms.ChoiceField( + required=True, + label=_("Ano da Matéria"), + choices=choice_anos_com_materias, + widget=forms.Select(attrs={"class": "selector"}), + ) + tipo = forms.ModelChoiceField( + label=_("Tipo de Matéria"), + required=True, + queryset=TipoMateriaLegislativa.objects.all(), + empty_label="------", + ) def clean(self): super(DesvincularMateriaForm, self).clean() @@ -1335,111 +1465,116 @@ class DesvincularMateriaForm(forms.Form): if not self.is_valid(): return cleaned_data - numero = cleaned_data['numero'] - ano = cleaned_data['ano'] - tipo = cleaned_data['tipo'] + numero = cleaned_data["numero"] + ano = cleaned_data["ano"] + tipo = cleaned_data["tipo"] try: - self.logger.info("Tentando obter MateriaLegislativa com numero={}, ano={} e tipo={}." - .format(numero, ano, tipo)) - materia = MateriaLegislativa.objects.get( - numero=numero, ano=ano, tipo=tipo) + self.logger.info( + "Tentando obter MateriaLegislativa com numero={}, ano={} e tipo={}.".format( + numero, ano, tipo + ) + ) + materia = MateriaLegislativa.objects.get(numero=numero, ano=ano, tipo=tipo) if not materia.numero_protocolo: self.logger.error( - "MateriaLegislativa %s %s/%s não se encontra vinculada a nenhum protocolo" % (tipo, numero, ano)) + "MateriaLegislativa %s %s/%s não se encontra vinculada a nenhum protocolo" + % (tipo, numero, ano) + ) raise forms.ValidationError( - _("%s %s/%s não se encontra vinculada a nenhum protocolo" % (tipo, numero, ano))) + _( + "%s %s/%s não se encontra vinculada a nenhum protocolo" + % (tipo, numero, ano) + ) + ) except ObjectDoesNotExist: self.logger.error( - "MateriaLegislativa %s %s/%s não existe" % (tipo, numero, ano)) - raise forms.ValidationError( - _("%s %s/%s não existe" % (tipo, numero, ano))) + "MateriaLegislativa %s %s/%s não existe" % (tipo, numero, ano) + ) + raise forms.ValidationError(_("%s %s/%s não existe" % (tipo, numero, ano))) return cleaned_data def __init__(self, *args, **kwargs): super(DesvincularMateriaForm, self).__init__(*args, **kwargs) - row1 = to_row( - [('numero', 4), - ('ano', 4), - ('tipo', 4)]) + row1 = to_row([("numero", 4), ("ano", 4), ("tipo", 4)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset(_('Identificação da Matéria'), - row1, - HTML(" "), - form_actions(label='Desvincular') - ) + Fieldset( + _("Identificação da Matéria"), + row1, + HTML(" "), + form_actions(label="Desvincular"), + ) ) def pega_ultima_tramitacao_adm(): - return TramitacaoAdministrativo.objects.values( - 'documento_id').annotate(data_encaminhamento=Max( - 'data_encaminhamento'), - id=Max('id')).values_list('id', flat=True) + return ( + TramitacaoAdministrativo.objects.values("documento_id") + .annotate(data_encaminhamento=Max("data_encaminhamento"), id=Max("id")) + .values_list("id", flat=True) + ) def filtra_tramitacao_adm_status(status): lista = pega_ultima_tramitacao_adm() - return TramitacaoAdministrativo.objects.filter( - id__in=lista, - status=status).distinct().values_list('documento_id', flat=True) + return ( + TramitacaoAdministrativo.objects.filter(id__in=lista, status=status) + .distinct() + .values_list("documento_id", flat=True) + ) def filtra_tramitacao_adm_destino(destino): lista = pega_ultima_tramitacao_adm() - return TramitacaoAdministrativo.objects.filter( - id__in=lista, - unidade_tramitacao_destino=destino).distinct().values_list( - 'documento_id', flat=True) + return ( + TramitacaoAdministrativo.objects.filter( + id__in=lista, unidade_tramitacao_destino=destino + ) + .distinct() + .values_list("documento_id", flat=True) + ) def filtra_tramitacao_adm_destino_and_status(status, destino): lista = pega_ultima_tramitacao_adm() - return TramitacaoAdministrativo.objects.filter( - id__in=lista, - status=status, - unidade_tramitacao_destino=destino).distinct().values_list( - 'documento_id', flat=True) + return ( + TramitacaoAdministrativo.objects.filter( + id__in=lista, status=status, unidade_tramitacao_destino=destino + ) + .distinct() + .values_list("documento_id", flat=True) + ) class FichaPesquisaAdmForm(forms.Form): - logger = logging.getLogger(__name__) tipo_documento = forms.ModelChoiceField( label=TipoDocumentoAdministrativo._meta.verbose_name, queryset=TipoDocumentoAdministrativo.objects.all(), - empty_label='Selecione') + empty_label="Selecione", + ) data_inicial = forms.DateField( - label='Data Inicial', - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Inicial", widget=forms.DateInput(format="%d/%m/%Y") ) data_final = forms.DateField( - label='Data Final', - widget=forms.DateInput(format='%d/%m/%Y') + label="Data Final", widget=forms.DateInput(format="%d/%m/%Y") ) def __init__(self, *args, **kwargs): super(FichaPesquisaAdmForm, self).__init__(*args, **kwargs) - row1 = to_row( - [('tipo_documento', 6), - ('data_inicial', 3), - ('data_final', 3)]) + row1 = to_row([("tipo_documento", 6), ("data_inicial", 3), ("data_final", 3)]) self.helper = SaplFormHelper() self.helper.layout = Layout( - Fieldset( - ('Formulário de Ficha'), - row1, - form_actions(label='Pesquisar') - ) + Fieldset(("Formulário de Ficha"), row1, form_actions(label="Pesquisar")) ) def clean(self): @@ -1453,11 +1588,15 @@ class FichaPesquisaAdmForm(forms.Form): if not self.is_valid(): return cleaned_data - if cleaned_data['data_final'] < cleaned_data['data_inicial']: - self.logger.error("A Data Final ({}) não pode ser menor que a Data Inicial ({})." - .format(cleaned_data['data_final'], cleaned_data['data_inicial'])) - raise ValidationError(_( - 'A Data Final não pode ser menor que a Data Inicial')) + if cleaned_data["data_final"] < cleaned_data["data_inicial"]: + self.logger.error( + "A Data Final ({}) não pode ser menor que a Data Inicial ({}).".format( + cleaned_data["data_final"], cleaned_data["data_inicial"] + ) + ) + raise ValidationError( + _("A Data Final não pode ser menor que a Data Inicial") + ) return cleaned_data @@ -1466,47 +1605,47 @@ class FichaSelecionaAdmForm(forms.Form): documento = forms.ModelChoiceField( widget=forms.RadioSelect, queryset=DocumentoAdministrativo.objects.all(), - label='') + label="", + ) def __init__(self, *args, **kwargs): super(FichaSelecionaAdmForm, self).__init__(*args, **kwargs) - row1 = to_row( - [('documento', 12)]) + row1 = to_row([("documento", 12)]) self.helper = SaplFormHelper() self.helper.layout = Layout( Fieldset( - ('Selecione a ficha que deseja imprimir'), + ("Selecione a ficha que deseja imprimir"), row1, - form_actions(label='Gerar Impresso') + form_actions(label="Gerar Impresso"), ) ) class PrimeiraTramitacaoEmLoteAdmFilterSet(django_filters.FilterSet): - class Meta(FilterOverridesMetaMixin): model = DocumentoAdministrativo - fields = ['tipo', 'data'] + fields = ["tipo", "data"] def __init__(self, *args, **kwargs): - super(PrimeiraTramitacaoEmLoteAdmFilterSet, self).__init__( - *args, **kwargs) + super(PrimeiraTramitacaoEmLoteAdmFilterSet, self).__init__(*args, **kwargs) - self.filters['tipo'].label = 'Tipo de Documento' - self.filters['data'].label = 'Data (Inicial - Final)' - self.form.fields['tipo'].required = True - self.form.fields['data'].required = False + self.filters["tipo"].label = "Tipo de Documento" + self.filters["data"].label = "Data (Inicial - Final)" + self.form.fields["tipo"].required = True + self.form.fields["data"].required = False - row1 = to_row([('tipo', 12)]) - row2 = to_row([('data', 12)]) + row1 = to_row([("tipo", 12)]) + row2 = to_row([("data", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Primeira Tramitação'), - row1, row2, form_actions(label='Pesquisar'))) + Fieldset( + _("Primeira Tramitação"), row1, row2, form_actions(label="Pesquisar") + ) + ) class TramitacaoEmLoteAdmForm(ModelForm): @@ -1514,53 +1653,51 @@ class TramitacaoEmLoteAdmForm(ModelForm): class Meta: model = TramitacaoAdministrativo - fields = ['data_tramitacao', - 'unidade_tramitacao_local', - 'status', - 'urgente', - 'unidade_tramitacao_destino', - 'data_encaminhamento', - 'data_fim_prazo', - 'texto', - 'user', - 'ip', - 'ultima_edicao'] - - widgets = {'user': forms.HiddenInput(), - 'ip': forms.HiddenInput(), - 'ultima_edicao': forms.HiddenInput()} + fields = [ + "data_tramitacao", + "unidade_tramitacao_local", + "status", + "urgente", + "unidade_tramitacao_destino", + "data_encaminhamento", + "data_fim_prazo", + "texto", + "user", + "ip", + "ultima_edicao", + ] + + widgets = { + "user": forms.HiddenInput(), + "ip": forms.HiddenInput(), + "ultima_edicao": forms.HiddenInput(), + } def __init__(self, *args, **kwargs): super(TramitacaoEmLoteAdmForm, self).__init__(*args, **kwargs) - self.fields['data_tramitacao'].initial = timezone.now().date() + self.fields["data_tramitacao"].initial = timezone.now().date() ust = UnidadeTramitacao.objects.select_related().all() - unidade_tramitacao_destino = [('', '---------')] + [(ut.pk, ut) - for ut in ust if ut.comissao and ut.comissao.ativa] - unidade_tramitacao_destino.extend( - [(ut.pk, ut) for ut in ust if ut.orgao]) - unidade_tramitacao_destino.extend( - [(ut.pk, ut) for ut in ust if ut.parlamentar]) - self.fields['unidade_tramitacao_destino'].choices = unidade_tramitacao_destino - self.fields['urgente'].label = "Urgente? *" - - row1 = to_row([ - ('data_tramitacao', 4), - ('data_encaminhamento', 4), - ('data_fim_prazo', 4) - ]) - row2 = to_row([ - ('unidade_tramitacao_local', 6), - ('unidade_tramitacao_destino', 6), - ]) - row3 = to_row([ - ('status', 6), - ('urgente', 6) - ]) - row4 = to_row([ - ('texto', 12) - ]) - - documentos_checkbox_HTML = r''' + unidade_tramitacao_destino = [("", "---------")] + [ + (ut.pk, ut) for ut in ust if ut.comissao and ut.comissao.ativa + ] + unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.orgao]) + unidade_tramitacao_destino.extend([(ut.pk, ut) for ut in ust if ut.parlamentar]) + self.fields["unidade_tramitacao_destino"].choices = unidade_tramitacao_destino + self.fields["urgente"].label = "Urgente? *" + + row1 = to_row( + [("data_tramitacao", 4), ("data_encaminhamento", 4), ("data_fim_prazo", 4)] + ) + row2 = to_row( + [ + ("unidade_tramitacao_local", 6), + ("unidade_tramitacao_destino", 6), + ] + ) + row3 = to_row([("status", 6), ("urgente", 6)]) + row4 = to_row([("texto", 12)]) + + documentos_checkbox_HTML = r"""
        Selecione os documentos para tramitação: @@ -1589,15 +1726,18 @@ class TramitacaoEmLoteAdmForm(ModelForm):
        - ''' + """ self.helper = SaplFormHelper() self.helper.layout = Layout( Fieldset( - 'Detalhes da tramitação:', - row1, row2, row3, row4, + "Detalhes da tramitação:", + row1, + row2, + row3, + row4, HTML(documentos_checkbox_HTML), - form_actions(label='Salvar') + form_actions(label="Salvar"), ) ) @@ -1607,40 +1747,51 @@ class TramitacaoEmLoteAdmForm(ModelForm): if not self.is_valid(): return self.cleaned_data - if 'data_encaminhamento' in cleaned_data: - data_enc_form = cleaned_data['data_encaminhamento'] - if 'data_fim_prazo' in cleaned_data: - data_prazo_form = cleaned_data['data_fim_prazo'] - if 'data_tramitacao' in cleaned_data: - data_tram_form = cleaned_data['data_tramitacao'] + if "data_encaminhamento" in cleaned_data: + data_enc_form = cleaned_data["data_encaminhamento"] + if "data_fim_prazo" in cleaned_data: + data_prazo_form = cleaned_data["data_fim_prazo"] + if "data_tramitacao" in cleaned_data: + data_tram_form = cleaned_data["data_tramitacao"] if not self.instance.data_tramitacao: - - if cleaned_data['data_tramitacao'] > timezone.now().date(): - self.logger.error('A data de tramitação ({}) deve ser ' - 'menor ou igual a data de hoje ({})!' - .format(cleaned_data['data_tramitacao'], timezone.now().date())) + if cleaned_data["data_tramitacao"] > timezone.now().date(): + self.logger.error( + "A data de tramitação ({}) deve ser " + "menor ou igual a data de hoje ({})!".format( + cleaned_data["data_tramitacao"], timezone.now().date() + ) + ) msg = _( - 'A data de tramitação deve ser ' + - 'menor ou igual a data de hoje!') + "A data de tramitação deve ser " + "menor ou igual a data de hoje!" + ) raise ValidationError(msg) 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.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!" + ) raise ValidationError(msg) if data_prazo_form: if data_prazo_form < data_tram_form: - self.logger.error('A data fim de prazo ({}) deve ser ' - 'maior que a data de tramitação ({})!' - .format(data_prazo_form, data_tram_form)) - msg = _('A data fim de prazo deve ser ' + - 'maior que a data de tramitação!') + self.logger.error( + "A data fim de prazo ({}) deve ser " + "maior que a data de tramitação ({})!".format( + data_prazo_form, data_tram_form + ) + ) + msg = _( + "A data fim de prazo deve ser " + "maior que a data de tramitação!" + ) raise ValidationError(msg) return cleaned_data @@ -1650,27 +1801,29 @@ class TramitacaoEmLoteAdmForm(ModelForm): def save(self, commit=True): cd = self.cleaned_data - documentos = self.initial['documentos'] - user = self.initial['user'] if 'user' in self.initial else None - ip = self.initial['ip'] if 'ip' in self.initial else '' - ultima_edicao = self.initial['ultima_edicao'] if 'ultima_edicao' in self.initial else '' + documentos = self.initial["documentos"] + user = self.initial["user"] if "user" in self.initial else None + ip = self.initial["ip"] if "ip" in self.initial else "" + ultima_edicao = ( + self.initial["ultima_edicao"] if "ultima_edicao" in self.initial else "" + ) - tramitar_anexados = AppConfig.attr('tramitacao_documento') + tramitar_anexados = AppConfig.attr("tramitacao_documento") for doc_id in documentos: doc = DocumentoAdministrativo.objects.get(id=doc_id) tramitacao = TramitacaoAdministrativo.objects.create( - status=cd['status'], + status=cd["status"], documento=doc, - data_tramitacao=cd['data_tramitacao'], - unidade_tramitacao_local=cd['unidade_tramitacao_local'], - unidade_tramitacao_destino=cd['unidade_tramitacao_destino'], - data_encaminhamento=cd['data_encaminhamento'], - urgente=cd['urgente'], - texto=cd['texto'], - data_fim_prazo=cd['data_fim_prazo'], + data_tramitacao=cd["data_tramitacao"], + unidade_tramitacao_local=cd["unidade_tramitacao_local"], + unidade_tramitacao_destino=cd["unidade_tramitacao_destino"], + data_encaminhamento=cd["data_encaminhamento"], + urgente=cd["urgente"], + texto=cd["texto"], + data_fim_prazo=cd["data_fim_prazo"], user=user, ip=ip, - ultima_edicao=ultima_edicao + ultima_edicao=ultima_edicao, ) doc.tramitacao = False if tramitacao.status.indicador == "F" else True doc.save() @@ -1679,25 +1832,31 @@ class TramitacaoEmLoteAdmForm(ModelForm): lista_tramitacao = [] anexados = lista_anexados(doc) for da in anexados: - if not da.tramitacaoadministrativo_set.all() \ - or da.tramitacaoadministrativo_set.last() \ - .unidade_tramitacao_destino == tramitacao.unidade_tramitacao_local: - da.tramitacao = False if tramitacao.status.indicador == "F" else True + if ( + not da.tramitacaoadministrativo_set.all() + or da.tramitacaoadministrativo_set.last().unidade_tramitacao_destino + == tramitacao.unidade_tramitacao_local + ): + da.tramitacao = ( + False if tramitacao.status.indicador == "F" else True + ) da.save() - lista_tramitacao.append(TramitacaoAdministrativo( - status=tramitacao.status, - documento=da, - data_tramitacao=tramitacao.data_tramitacao, - unidade_tramitacao_local=tramitacao.unidade_tramitacao_local, - data_encaminhamento=tramitacao.data_encaminhamento, - unidade_tramitacao_destino=tramitacao.unidade_tramitacao_destino, - urgente=tramitacao.urgente, - texto=tramitacao.texto, - data_fim_prazo=tramitacao.data_fim_prazo, - user=tramitacao.user, - ip=tramitacao.ip, - ultima_edicao=tramitacao.ultima_edicao - )) + lista_tramitacao.append( + TramitacaoAdministrativo( + status=tramitacao.status, + documento=da, + data_tramitacao=tramitacao.data_tramitacao, + unidade_tramitacao_local=tramitacao.unidade_tramitacao_local, + data_encaminhamento=tramitacao.data_encaminhamento, + unidade_tramitacao_destino=tramitacao.unidade_tramitacao_destino, + urgente=tramitacao.urgente, + texto=tramitacao.texto, + data_fim_prazo=tramitacao.data_fim_prazo, + user=tramitacao.user, + ip=tramitacao.ip, + ultima_edicao=tramitacao.ultima_edicao, + ) + ) # TODO: BULK UPDATE não envia Signal para Tramitacao TramitacaoAdministrativo.objects.bulk_create(lista_tramitacao) @@ -1707,55 +1866,64 @@ class TramitacaoEmLoteAdmForm(ModelForm): class TramitacaoEmLoteAdmFilterSet(django_filters.FilterSet): class Meta(FilterOverridesMetaMixin): model = DocumentoAdministrativo - fields = ['tipo', 'data', 'tramitacaoadministrativo__status', - 'tramitacaoadministrativo__unidade_tramitacao_destino'] + fields = [ + "tipo", + "data", + "tramitacaoadministrativo__status", + "tramitacaoadministrativo__unidade_tramitacao_destino", + ] def __init__(self, *args, **kwargs): - super(TramitacaoEmLoteAdmFilterSet, self).__init__( - *args, **kwargs) - - self.filters['tipo'].label = _('Tipo de Documento') - self.filters['data'].label = _('Data (Inicial - Final)') - self.filters['tramitacaoadministrativo__unidade_tramitacao_destino' - ].label = _('Unidade Destino (Último Destino)') - self.filters['tramitacaoadministrativo__status'].label = _('Status') - self.form.fields['tipo'].required = True - self.form.fields['data'].required = False - self.form.fields['tramitacaoadministrativo__status'].required = True + super(TramitacaoEmLoteAdmFilterSet, self).__init__(*args, **kwargs) + + self.filters["tipo"].label = _("Tipo de Documento") + self.filters["data"].label = _("Data (Inicial - Final)") + self.filters["tramitacaoadministrativo__unidade_tramitacao_destino"].label = _( + "Unidade Destino (Último Destino)" + ) + self.filters["tramitacaoadministrativo__status"].label = _("Status") + self.form.fields["tipo"].required = True + self.form.fields["data"].required = False + self.form.fields["tramitacaoadministrativo__status"].required = True self.form.fields[ - 'tramitacaoadministrativo__unidade_tramitacao_destino'].required = True + "tramitacaoadministrativo__unidade_tramitacao_destino" + ].required = True - row1 = to_row([ - ('tipo', 4), - ('tramitacaoadministrativo__unidade_tramitacao_destino', 4), - ('tramitacaoadministrativo__status', 4)]) - row2 = to_row([('data', 12)]) + row1 = to_row( + [ + ("tipo", 4), + ("tramitacaoadministrativo__unidade_tramitacao_destino", 4), + ("tramitacaoadministrativo__status", 4), + ] + ) + row2 = to_row([("data", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Tramitação em Lote'), - row1, row2, form_actions(label=_('Pesquisar')))) + Fieldset( + _("Tramitação em Lote"), row1, row2, form_actions(label=_("Pesquisar")) + ) + ) class VinculoDocAdminMateriaForm(ModelForm): - logger = logging.getLogger(__name__) tipo = forms.ModelChoiceField( - label='Tipo', + label="Tipo", required=True, queryset=TipoMateriaLegislativa.objects.all(), - empty_label='Selecione', + empty_label="Selecione", ) - numero = forms.IntegerField(label='Número', required=True) + numero = forms.IntegerField(label="Número", required=True) - ano = forms.CharField(label='Ano', required=True) + ano = forms.CharField(label="Ano", required=True) class Meta: model = VinculoDocAdminMateria - fields = ['tipo', 'numero', 'ano', 'data_anexacao', 'data_desanexacao'] + fields = ["tipo", "numero", "ano", "data_anexacao", "data_desanexacao"] def __init__(self, *args, **kwargs): return super().__init__(*args, **kwargs) @@ -1768,68 +1936,85 @@ class VinculoDocAdminMateriaForm(ModelForm): cleaned_data = self.cleaned_data - data_anexacao = cleaned_data['data_anexacao'] - data_desanexacao = cleaned_data['data_desanexacao'] if cleaned_data['data_desanexacao'] else data_anexacao + data_anexacao = cleaned_data["data_anexacao"] + data_desanexacao = ( + cleaned_data["data_desanexacao"] + if cleaned_data["data_desanexacao"] + else data_anexacao + ) if data_anexacao > data_desanexacao: - self.logger.error( - "Data de anexação posterior à data de desanexação.") + self.logger.error("Data de anexação posterior à data de desanexação.") raise ValidationError( - _("Data de anexação posterior à data de desanexação.")) + _("Data de anexação posterior à data de desanexação.") + ) try: - self.logger.info("Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={})." - .format(cleaned_data['numero'], cleaned_data['ano'], cleaned_data['tipo'])) + self.logger.info( + "Tentando obter objeto MateriaLegislativa (numero={}, ano={}, tipo={}).".format( + cleaned_data["numero"], cleaned_data["ano"], cleaned_data["tipo"] + ) + ) materia = MateriaLegislativa.objects.get( - numero=cleaned_data['numero'], - ano=cleaned_data['ano'], - tipo=cleaned_data['tipo']) + numero=cleaned_data["numero"], + ano=cleaned_data["ano"], + tipo=cleaned_data["tipo"], + ) except ObjectDoesNotExist: - msg = _('A {} {}/{} não existe no cadastro de matérias legislativas.' - .format(cleaned_data['tipo'], cleaned_data['numero'], cleaned_data['ano'])) + msg = _( + "A {} {}/{} não existe no cadastro de matérias legislativas.".format( + cleaned_data["tipo"], cleaned_data["numero"], cleaned_data["ano"] + ) + ) self.logger.warning( - "A matéria a ser anexada não existe no cadastro de matérias legislativas.") + "A matéria a ser anexada não existe no cadastro de matérias legislativas." + ) raise ValidationError(msg) - if VinculoDocAdminMateria.objects.filter( - documento=self.instance.documento, materia=materia - ).exclude(pk=self.instance.pk).exists(): - self.logger.error( - "Matéria já se encontra vinculada a este documento.") + if ( + VinculoDocAdminMateria.objects.filter( + documento=self.instance.documento, materia=materia + ) + .exclude(pk=self.instance.pk) + .exists() + ): + self.logger.error("Matéria já se encontra vinculada a este documento.") raise ValidationError( - _('Matéria já se encontra vinculada a este documento')) + _("Matéria já se encontra vinculada a este documento") + ) - cleaned_data['materia'] = materia + cleaned_data["materia"] = materia return cleaned_data def save(self, commit=False): vinculo = super().save(commit) - vinculo.materia = self.cleaned_data['materia'] + vinculo.materia = self.cleaned_data["materia"] vinculo.save() return vinculo class VinculoDocAdminMateriaEmLoteFilterSet(django_filters.FilterSet): - class Meta(FilterOverridesMetaMixin): model = MateriaLegislativa - fields = ['tipo', 'data_apresentacao'] + fields = ["tipo", "data_apresentacao"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.filters['tipo'].label = 'Tipo de Matéria' - self.filters['data_apresentacao'].label = 'Data (Inicial - Final)' + self.filters["tipo"].label = "Tipo de Matéria" + self.filters["data_apresentacao"].label = "Data (Inicial - Final)" - self.form.fields['tipo'].required = True - self.form.fields['data_apresentacao'].required = True + self.form.fields["tipo"].required = True + self.form.fields["data_apresentacao"].required = True - row1 = to_row([('tipo', 12)]) - row2 = to_row([('data_apresentacao', 12)]) + row1 = to_row([("tipo", 12)]) + row2 = to_row([("data_apresentacao", 12)]) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Matérias'), - row1, row2, form_actions(label='Pesquisar'))) + Fieldset( + _("Pesquisa de Matérias"), row1, row2, form_actions(label="Pesquisar") + ) + ) diff --git a/sapl/protocoloadm/models.py b/sapl/protocoloadm/models.py index e947a7d2f..343d82c56 100644 --- a/sapl/protocoloadm/models.py +++ b/sapl/protocoloadm/models.py @@ -6,22 +6,22 @@ from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ from model_utils import Choices -from sapl.base.models import Autor, AppConfig as SaplAppConfig -from sapl.materia.models import TipoMateriaLegislativa, UnidadeTramitacao,\ - MateriaLegislativa -from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, texto_upload_path, - get_settings_auth_user_model, - OverwriteStorage) +from sapl.base.models import AppConfig as SaplAppConfig +from sapl.base.models import Autor +from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa, + UnidadeTramitacao) +from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, OverwriteStorage, + get_settings_auth_user_model, texto_upload_path) class TipoDocumentoAdministrativo(models.Model): - sigla = models.CharField(max_length=5, verbose_name=_('Sigla')) - descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) + sigla = models.CharField(max_length=5, verbose_name=_("Sigla")) + descricao = models.CharField(max_length=50, verbose_name=_("Descrição")) class Meta: - verbose_name = _('Tipo de Documento Administrativo') - verbose_name_plural = _('Tipos de Documento Administrativo') - ordering = ['descricao'] + verbose_name = _("Tipo de Documento Administrativo") + verbose_name_plural = _("Tipos de Documento Administrativo") + ordering = ["descricao"] def __str__(self): return self.descricao @@ -54,225 +54,225 @@ def texto_upload_path(instance, filename): class Protocolo(models.Model): numero = models.PositiveIntegerField( - blank=False, - null=False, - verbose_name=_('Número de Protocolo')) + 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')) + 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')) + 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')) + 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, - verbose_name=_('IP'), - help_text=_('Usuário que está realizando Protocolo e informando data e hora manualmente.')) + verbose_name=_("IP"), + 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, - 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.')) + 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." + ), + ) user = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Usuário'), + verbose_name=_("Usuário"), on_delete=models.PROTECT, null=True, - blank=True + blank=True, ) de_proposicao = models.BooleanField(default=False) # Não foi utilizado auto_now_add=True em timestamp porque ele usa # datetime.now que não é timezone aware. - timestamp = models.DateTimeField( - null=True, - blank=True, - default=timezone.now) + timestamp = models.DateTimeField(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.SET_NULL) + 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, blank=True, null=True, on_delete=models.PROTECT, - verbose_name=_('Tipo de Documento')) + verbose_name=_("Tipo de Documento"), + ) tipo_materia = models.ForeignKey( TipoMateriaLegislativa, blank=True, null=True, on_delete=models.PROTECT, - verbose_name=_('Tipo de Matéria')) + 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: - verbose_name = _('Protocolo') - verbose_name_plural = _('Protocolos') - ordering = ('id',) + verbose_name = _("Protocolo") + verbose_name_plural = _("Protocolos") + ordering = ("id",) permissions = ( - ('action_anular_protocolo', _('Permissão para Anular Protocolo')), + ("action_anular_protocolo", _("Permissão para Anular Protocolo")), + ) + unique_together = ( + "numero", + "ano", ) - unique_together = ('numero', 'ano',) def __str__(self): - return _('%(numero)s/%(ano)s') % { - 'numero': self.numero, 'ano': self.ano - } + return _("%(numero)s/%(ano)s") % {"numero": self.numero, "ano": self.ano} class DocumentoAdministrativo(models.Model): tipo = models.ForeignKey( - TipoDocumentoAdministrativo, on_delete=models.PROTECT, - verbose_name=_('Tipo Documento')) - numero = models.PositiveIntegerField(verbose_name=_('Número')) + TipoDocumentoAdministrativo, + on_delete=models.PROTECT, + verbose_name=_("Tipo Documento"), + ) + numero = models.PositiveIntegerField(verbose_name=_("Número")) - complemento = models.CharField(max_length=10, blank=True, - verbose_name=_('Complemento')) + complemento = models.CharField( + max_length=10, blank=True, verbose_name=_("Complemento") + ) - ano = models.PositiveSmallIntegerField(verbose_name=_('Ano'), - choices=RANGE_ANOS) + ano = models.PositiveSmallIntegerField(verbose_name=_("Ano"), choices=RANGE_ANOS) protocolo = models.ForeignKey( Protocolo, blank=True, null=True, on_delete=models.PROTECT, - verbose_name=_('Protocolo')) - data = models.DateField(verbose_name=_('Data')) + verbose_name=_("Protocolo"), + ) + data = models.DateField(verbose_name=_("Data")) interessado = models.CharField( - max_length=50, blank=True, verbose_name=_('Interessado')) - autor = models.ForeignKey(Autor, blank=True, null=True, - on_delete=models.PROTECT, verbose_name=_('Autoria')) + max_length=50, blank=True, verbose_name=_("Interessado") + ) + autor = models.ForeignKey( + Autor, + blank=True, + null=True, + on_delete=models.PROTECT, + verbose_name=_("Autoria"), + ) dias_prazo = models.PositiveIntegerField( - blank=True, null=True, verbose_name=_('Dias Prazo')) + blank=True, null=True, verbose_name=_("Dias Prazo") + ) data_fim_prazo = models.DateField( - blank=True, null=True, verbose_name=_('Data Fim Prazo')) + blank=True, null=True, verbose_name=_("Data Fim Prazo") + ) tramitacao = models.BooleanField( - verbose_name=_('Em Tramitação?'), - choices=YES_NO_CHOICES, - default=False) - assunto = models.TextField(verbose_name=_('Assunto')) + verbose_name=_("Em Tramitação?"), choices=YES_NO_CHOICES, default=False + ) + assunto = models.TextField(verbose_name=_("Assunto")) numero_externo = models.PositiveIntegerField( - blank=True, - null=True, - verbose_name=_('Número Externo')) - observacao = models.TextField( - blank=True, verbose_name=_('Observação')) + blank=True, null=True, verbose_name=_("Número Externo") + ) + observacao = models.TextField(blank=True, verbose_name=_("Observação")) texto_integral = models.FileField( max_length=300, blank=True, null=True, storage=OverwriteStorage(), upload_to=texto_upload_path, - verbose_name=_('Texto Integral')) - restrito = models.BooleanField(default=False, - verbose_name=_('Acesso Restrito'), - blank=True) + verbose_name=_("Texto Integral"), + ) + restrito = models.BooleanField( + default=False, verbose_name=_("Acesso Restrito"), blank=True + ) anexados = models.ManyToManyField( - 'self', + "self", blank=True, - through='Anexado', + through="Anexado", symmetrical=False, - related_name='anexo_de', - through_fields=( - 'documento_principal', - 'documento_anexado' - ) + related_name="anexo_de", + through_fields=("documento_principal", "documento_anexado"), ) materiasvinculadas = models.ManyToManyField( MateriaLegislativa, blank=True, - through='VinculoDocAdminMateria', - related_name='docadmvinculados', - through_fields=( - 'documento', - 'materia' - ) + through="VinculoDocAdminMateria", + related_name="docadmvinculados", + through_fields=("documento", "materia"), ) user = models.ForeignKey( get_settings_auth_user_model(), - verbose_name=_('Usuário'), + verbose_name=_("Usuário"), on_delete=models.PROTECT, null=True, - blank=True - ) - ip = models.CharField( - verbose_name=_('IP'), - max_length=60, blank=True, - default='' ) + ip = models.CharField(verbose_name=_("IP"), max_length=60, blank=True, default="") ultima_edicao = models.DateTimeField( - verbose_name=_('Data e Hora da Edição'), - blank=True, null=True + verbose_name=_("Data e Hora da Edição"), blank=True, null=True ) class Meta: - verbose_name = _('Documento Administrativo') - verbose_name_plural = _('Documentos Administrativos') - ordering = ('ano', 'numero', 'id',) + verbose_name = _("Documento Administrativo") + verbose_name_plural = _("Documentos Administrativos") + ordering = ( + "ano", + "numero", + "id", + ) @classmethod def mask_to_str(cls, values, mask): erro = set() - pattern = '({[^{}]+}|{[ /.-]*})' + pattern = "({[^{}]+}|{[ /.-]*})" campos_escolhidos = re.findall(pattern, mask) campos_permitidos = { - '{.}', '{/}', '{-}', - '{sigla}', - '{nome}', - '{numero}', - '{ano}', - '{complemento}', - '{assunto}', + "{.}", + "{/}", + "{-}", + "{sigla}", + "{nome}", + "{numero}", + "{ano}", + "{complemento}", + "{assunto}", } condicionais = { - '{.}': '.', - '{/}': '/', - '{-}': '-', + "{.}": ".", + "{/}": "/", + "{-}": "-", } erro = set(campos_escolhidos) - campos_permitidos if erro: - mask = '{sigla} Nº {numero}/{ano}{-}{complemento} - {nome}' + mask = "{sigla} Nº {numero}/{ano}{-}{complemento} - {nome}" campos_escolhidos = re.findall(pattern, mask) for i, k in enumerate(campos_escolhidos): @@ -280,29 +280,29 @@ class DocumentoAdministrativo(models.Model): if i > 0 and campos_escolhidos[i - 1] in condicionais: mask = mask.replace( campos_escolhidos[i - 1], - condicionais[campos_escolhidos[i - 1]]if values[k] else '', 1) + condicionais[campos_escolhidos[i - 1]] if values[k] else "", + 1, + ) mask = mask.replace(k, values[k], 1) elif k in condicionais: if i > 0 and campos_escolhidos[i - 1] in condicionais: - mask = mask.replace( - campos_escolhidos[i - 1], - '', 1) + mask = mask.replace(campos_escolhidos[i - 1], "", 1) if i + 1 == len(campos_escolhidos): - mask = mask.replace(k, '', 1) + mask = mask.replace(k, "", 1) return mask, erro @cached_property def _identificacao_de_documento(self): - mask = SaplAppConfig.attr('identificacao_de_documentos') + mask = SaplAppConfig.attr("identificacao_de_documentos") values = { - '{sigla}': self.tipo.sigla, - '{nome}': self.tipo.descricao, - '{numero}': f'{self.numero:0>3}', - '{ano}': f'{self.ano}', - '{complemento}': self.complemento, - '{assunto}': self.assunto + "{sigla}": self.tipo.sigla, + "{nome}": self.tipo.descricao, + "{numero}": f"{self.numero:0>3}", + "{ano}": f"{self.ano}", + "{complemento}": self.complemento, + "{assunto}": self.assunto, } return DocumentoAdministrativo.mask_to_str(values, mask)[0] @@ -323,50 +323,53 @@ class DocumentoAdministrativo(models.Model): return result - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): - + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): if not self.pk and self.texto_integral: texto_integral = self.texto_integral self.texto_integral = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.texto_integral = texto_integral - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) class DocumentoAcessorioAdministrativo(models.Model): - documento = models.ForeignKey(DocumentoAdministrativo, - on_delete=models.PROTECT) + documento = models.ForeignKey(DocumentoAdministrativo, on_delete=models.PROTECT) tipo = models.ForeignKey( - TipoDocumentoAdministrativo, - on_delete=models.PROTECT, - verbose_name=_('Tipo')) - nome = models.CharField(max_length=30, verbose_name=_('Nome')) + TipoDocumentoAdministrativo, on_delete=models.PROTECT, verbose_name=_("Tipo") + ) + nome = models.CharField(max_length=30, verbose_name=_("Nome")) arquivo = models.FileField( max_length=300, blank=True, null=True, upload_to=texto_upload_path, storage=OverwriteStorage(), - verbose_name=_('Arquivo')) - data = models.DateField(blank=True, null=True, verbose_name=_('Data')) - autor = models.CharField( - max_length=200, blank=True, verbose_name=_('Autor')) - assunto = models.TextField( - blank=True, verbose_name=_('Assunto')) + verbose_name=_("Arquivo"), + ) + data = models.DateField(blank=True, null=True, verbose_name=_("Data")) + autor = models.CharField(max_length=200, blank=True, verbose_name=_("Autor")) + assunto = models.TextField(blank=True, verbose_name=_("Assunto")) indexacao = models.TextField(blank=True) class Meta: - verbose_name = _('Documento Acessório') - verbose_name_plural = _('Documentos Acessórios') - ordering = ('data', 'id') + verbose_name = _("Documento Acessório") + verbose_name_plural = _("Documentos Acessórios") + ordering = ("data", "id") def __str__(self): return self.nome @@ -380,42 +383,50 @@ class DocumentoAcessorioAdministrativo(models.Model): return result - def save(self, force_insert=False, force_update=False, using=None, - update_fields=None): - + def save( + self, force_insert=False, force_update=False, using=None, update_fields=None + ): if not self.pk and self.arquivo: arquivo = self.arquivo self.arquivo = None - models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) self.arquivo = arquivo - return models.Model.save(self, force_insert=force_insert, - force_update=force_update, - using=using, - update_fields=update_fields) + return models.Model.save( + self, + force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields, + ) class StatusTramitacaoAdministrativo(models.Model): INDICADOR_CHOICES = Choices( - ('F', 'fim', _('Fim')), - ('R', 'retorno', _('Retorno')), + ("F", "fim", _("Fim")), + ("R", "retorno", _("Retorno")), ) - sigla = models.CharField(max_length=10, verbose_name=_('Sigla')) - descricao = models.CharField(max_length=60, verbose_name=_('Descrição')) + sigla = models.CharField(max_length=10, verbose_name=_("Sigla")) + descricao = models.CharField(max_length=60, verbose_name=_("Descrição")) # TODO make specific migration considering both ind_fim_tramitacao, # ind_retorno_tramitacao indicador = models.CharField( - max_length=1, verbose_name=_('Indicador da Tramitação'), - choices=INDICADOR_CHOICES) + max_length=1, + verbose_name=_("Indicador da Tramitação"), + choices=INDICADOR_CHOICES, + ) class Meta: - verbose_name = _('Status de Tramitação') - verbose_name_plural = _('Status de Tramitação') - ordering = ('id',) + verbose_name = _("Status de Tramitação") + verbose_name_plural = _("Status de Tramitação") + ordering = ("id",) def __str__(self): return self.descricao @@ -425,139 +436,143 @@ class TramitacaoAdministrativo(models.Model): status = models.ForeignKey( StatusTramitacaoAdministrativo, on_delete=models.PROTECT, - verbose_name=_('Status')) - documento = models.ForeignKey(DocumentoAdministrativo, - on_delete=models.PROTECT) + verbose_name=_("Status"), + ) + documento = models.ForeignKey(DocumentoAdministrativo, on_delete=models.PROTECT) timestamp = models.DateTimeField(default=timezone.now) - data_tramitacao = models.DateField( - verbose_name=_('Data Tramitação')) + data_tramitacao = models.DateField(verbose_name=_("Data Tramitação")) unidade_tramitacao_local = models.ForeignKey( UnidadeTramitacao, - related_name='adm_tramitacoes_origem', + related_name="adm_tramitacoes_origem", on_delete=models.PROTECT, - verbose_name=_('Unidade Local')) + verbose_name=_("Unidade Local"), + ) data_encaminhamento = models.DateField( - blank=True, null=True, verbose_name=_('Data Encaminhamento')) + blank=True, null=True, verbose_name=_("Data Encaminhamento") + ) unidade_tramitacao_destino = models.ForeignKey( UnidadeTramitacao, - related_name='adm_tramitacoes_destino', + related_name="adm_tramitacoes_destino", on_delete=models.PROTECT, - verbose_name=_('Unidade Destino')) - urgente = models.BooleanField(verbose_name=_('Urgente ?'), - choices=YES_NO_CHOICES, - default=False) - texto = models.TextField(verbose_name=_('Texto da Ação')) + verbose_name=_("Unidade Destino"), + ) + urgente = models.BooleanField( + verbose_name=_("Urgente ?"), choices=YES_NO_CHOICES, default=False + ) + texto = models.TextField(verbose_name=_("Texto da Ação")) data_fim_prazo = models.DateField( - blank=True, null=True, verbose_name=_('Data Fim do Prazo')) - user = models.ForeignKey(get_settings_auth_user_model(), - verbose_name=_('Usuário'), - on_delete=models.PROTECT, - null=True, - blank=True) - ip = models.CharField(verbose_name=_('IP'), - max_length=60, - blank=True, - default='') + blank=True, null=True, verbose_name=_("Data Fim do Prazo") + ) + user = models.ForeignKey( + get_settings_auth_user_model(), + verbose_name=_("Usuário"), + on_delete=models.PROTECT, + null=True, + blank=True, + ) + ip = models.CharField(verbose_name=_("IP"), max_length=60, blank=True, default="") ultima_edicao = models.DateTimeField( - verbose_name=_('Data e Hora da Edição'), - blank=True, null=True + verbose_name=_("Data e Hora da Edição"), blank=True, null=True ) class Meta: - verbose_name = _('Tramitação de Documento Administrativo') - verbose_name_plural = _('Tramitações de Documento Administrativo') - ordering = ('id',) + verbose_name = _("Tramitação de Documento Administrativo") + verbose_name_plural = _("Tramitações de Documento Administrativo") + ordering = ("id",) def __str__(self): - return _('%(documento)s - %(status)s') % { - 'documento': self.documento, 'status': self.status + return _("%(documento)s - %(status)s") % { + "documento": self.documento, + "status": self.status, } class Anexado(models.Model): documento_principal = models.ForeignKey( - DocumentoAdministrativo, related_name='documento_principal_set', + DocumentoAdministrativo, + related_name="documento_principal_set", on_delete=models.CASCADE, - verbose_name=_('Documento Principal') + verbose_name=_("Documento Principal"), ) documento_anexado = models.ForeignKey( - DocumentoAdministrativo, related_name='documento_anexado_set', + DocumentoAdministrativo, + related_name="documento_anexado_set", on_delete=models.CASCADE, - verbose_name=_('Documento Anexado') + verbose_name=_("Documento Anexado"), ) - data_anexacao = models.DateField(verbose_name=_('Data Anexação')) + data_anexacao = models.DateField(verbose_name=_("Data Anexação")) data_desanexacao = models.DateField( - blank=True, null=True, verbose_name=_('Data Desanexação') + blank=True, null=True, verbose_name=_("Data Desanexação") ) class Meta: - verbose_name = _('Anexado') - verbose_name_plural = _('Anexados') - ordering = ('id',) + verbose_name = _("Anexado") + verbose_name_plural = _("Anexados") + ordering = ("id",) def __str__(self): - return _('Anexado: %(documento_anexado_tipo)s %(documento_anexado_numero)s' - '/%(documento_anexado_ano)s\n') % { - 'documento_anexado_tipo': self.documento_anexado.tipo, - 'documento_anexado_numero': self.documento_anexado.numero, - 'documento_anexado_ano': self.documento_anexado.ano + return _( + "Anexado: %(documento_anexado_tipo)s %(documento_anexado_numero)s" + "/%(documento_anexado_ano)s\n" + ) % { + "documento_anexado_tipo": self.documento_anexado.tipo, + "documento_anexado_numero": self.documento_anexado.numero, + "documento_anexado_ano": self.documento_anexado.ano, } class VinculoDocAdminMateria(models.Model): documento = models.ForeignKey( - DocumentoAdministrativo, related_name='materialegislativa_vinculada_set', + DocumentoAdministrativo, + related_name="materialegislativa_vinculada_set", on_delete=models.CASCADE, - verbose_name=_('Documento Administrativo') + verbose_name=_("Documento Administrativo"), ) materia = models.ForeignKey( - MateriaLegislativa, related_name='documentoadministrativo_vinculado_set', + MateriaLegislativa, + related_name="documentoadministrativo_vinculado_set", on_delete=models.CASCADE, - verbose_name=_('Matéria Legislativa') + verbose_name=_("Matéria Legislativa"), ) - data_anexacao = models.DateField(verbose_name=_('Data Anexação')) + data_anexacao = models.DateField(verbose_name=_("Data Anexação")) data_desanexacao = models.DateField( - blank=True, null=True, verbose_name=_('Data Desanexação') + blank=True, null=True, verbose_name=_("Data Desanexação") ) class Meta: - verbose_name = _( - 'Vinculo entre Documento Administrativo e Matéria Legislativa') + verbose_name = _("Vinculo entre Documento Administrativo e Matéria Legislativa") verbose_name_plural = _( - 'Vinculos entre Documento Administrativo e Matéria Legislativa') - ordering = ('id',) - unique_together = ( - ('documento', 'materia'), + "Vinculos entre Documento Administrativo e Matéria Legislativa" ) + ordering = ("id",) + unique_together = (("documento", "materia"),) def __str__(self): - return f'Vinculo: {self.documento} - {self.materia}' + return f"Vinculo: {self.documento} - {self.materia}" class AcompanhamentoDocumento(models.Model): usuario = models.CharField(max_length=50) - documento = models.ForeignKey( - DocumentoAdministrativo, on_delete=models.CASCADE) - email = models.EmailField( - max_length=100, verbose_name=_('E-mail')) + documento = models.ForeignKey(DocumentoAdministrativo, on_delete=models.CASCADE) + email = models.EmailField(max_length=100, verbose_name=_("E-mail")) data_cadastro = models.DateField(auto_now_add=True) hash = models.CharField(max_length=8) confirmado = models.BooleanField(default=False) class Meta: - verbose_name = _('Acompanhamento de Documento') - verbose_name_plural = _('Acompanhamentos de Documento') - ordering = ('id',) + verbose_name = _("Acompanhamento de Documento") + verbose_name_plural = _("Acompanhamentos de Documento") + ordering = ("id",) def __str__(self): if self.data_cadastro is None: - return _('%(documento)s - %(email)s') % { - 'documento': self.documento, - 'email': self.email + return _("%(documento)s - %(email)s") % { + "documento": self.documento, + "email": self.email, } else: - return _('%(documento)s - %(email)s - Registrado em: %(data)s') % { - 'documento': self.documento, - 'email': self.email, - 'data': str(self.data_cadastro.strftime('%d/%m/%Y')) + return _("%(documento)s - %(email)s - Registrado em: %(data)s") % { + "documento": self.documento, + "email": self.email, + "data": str(self.data_cadastro.strftime("%d/%m/%Y")), } diff --git a/sapl/protocoloadm/tests/test_docadm_email_templates.py b/sapl/protocoloadm/tests/test_docadm_email_templates.py index ec79098fa..68e8f5c6b 100644 --- a/sapl/protocoloadm/tests/test_docadm_email_templates.py +++ b/sapl/protocoloadm/tests/test_docadm_email_templates.py @@ -5,61 +5,70 @@ from sapl.base.email_utils import enviar_emails, load_email_templates def test_email_template_loading(): expected = "Hello Django" - emails = load_email_templates(['email/test_tramitacao.html'], - context={"name": "Django"}) + emails = load_email_templates( + ["email/test_tramitacao.html"], context={"name": "Django"} + ) # strip \n and \r to compare with expected - actual = emails[0].replace('\n', '').replace('\r', '') + actual = emails[0].replace("\n", "").replace("\r", "") assert actual == expected def test_html_email_body_with_materia(): - templates = load_email_templates(['email/tramitacao.txt', - 'email/tramitacao.html'], - {"image": 'img/logo.png', - "casa_legislativa": - "Assembléia Parlamentar", - "data_registro": "25/02/2016", - "cod_materia": "1", - "descricao_materia": "Assunto de teste", - "data": "25/02/2016", - "status": "Arquivado", - "texto_acao": "Deliberado", - "hash_txt": "abc01f", - "materia_id": "794", - "base_url": "http://localhost:8000", - "materia_url": - "/docadm/764/acompanhar-documento", - "excluir_url": - "/docadm/764/acompanhar-excluir"}) + templates = load_email_templates( + ["email/tramitacao.txt", "email/tramitacao.html"], + { + "image": "img/logo.png", + "casa_legislativa": "Assembléia Parlamentar", + "data_registro": "25/02/2016", + "cod_materia": "1", + "descricao_materia": "Assunto de teste", + "data": "25/02/2016", + "status": "Arquivado", + "texto_acao": "Deliberado", + "hash_txt": "abc01f", + "materia_id": "794", + "base_url": "http://localhost:8000", + "materia_url": "/docadm/764/acompanhar-documento", + "excluir_url": "/docadm/764/acompanhar-excluir", + }, + ) assert len(templates) == 2 def test_enviar_email_distintos(): NUM_MESSAGES = 10 - messages = [{'recipient': 'user-' + str(i) + '@test.com', - 'subject': 'subject: ' + str(i), - 'txt_message': 'txt: ' + str(i), - 'html_message': '', - } for i in range(NUM_MESSAGES)] - - recipients = [m['recipient'] for m in messages] - - enviar_emails('test@sapl.com', recipients, messages) + messages = [ + { + "recipient": "user-" + str(i) + "@test.com", + "subject": "subject: " + str(i), + "txt_message": "txt: " + str(i), + "html_message": "", + } + for i in range(NUM_MESSAGES) + ] + + recipients = [m["recipient"] for m in messages] + + enviar_emails("test@sapl.com", recipients, messages) assert len(mail.outbox) == NUM_MESSAGES def test_enviar_same_email(): NUM_MESSAGES = 10 - messages = [{'recipient': 'user-' + str(i) + '@test.com', - 'subject': 'subject: ' + str(i), - 'txt_message': 'txt: ' + str(i), - 'html_message': '', - } for i in range(NUM_MESSAGES)] - - recipients = [m['recipient'] for m in messages] - - enviar_emails('test@sapl.com', recipients, [messages[0]]) + messages = [ + { + "recipient": "user-" + str(i) + "@test.com", + "subject": "subject: " + str(i), + "txt_message": "txt: " + str(i), + "html_message": "", + } + for i in range(NUM_MESSAGES) + ] + + recipients = [m["recipient"] for m in messages] + + enviar_emails("test@sapl.com", recipients, [messages[0]]) assert len(mail.outbox) == 1 diff --git a/sapl/protocoloadm/tests/test_protocoloadm.py b/sapl/protocoloadm/tests/test_protocoloadm.py index e6db7dd8b..72c608519 100644 --- a/sapl/protocoloadm/tests/test_protocoloadm.py +++ b/sapl/protocoloadm/tests/test_protocoloadm.py @@ -1,48 +1,54 @@ from datetime import date, timedelta +from urllib.parse import urlencode +import pytest from django.urls import reverse from django.utils import timezone from django.utils.encoding import force_str from django.utils.translation import gettext_lazy as _ from model_bakery import baker -from urllib.parse import urlencode -import pytest from sapl.base.models import AppConfig from sapl.comissoes.models import Comissao, TipoComissao from sapl.materia.models import UnidadeTramitacao from sapl.protocoloadm.forms import (AnularProtocoloAdmForm, DocumentoAdministrativoForm, - MateriaLegislativa, ProtocoloDocumentoForm, - ProtocoloMateriaForm, TramitacaoAdmForm, - TramitacaoAdmEditForm, - compara_tramitacoes_doc, - TramitacaoEmLoteAdmForm) -from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, + MateriaLegislativa, + ProtocoloDocumentoForm, + ProtocoloMateriaForm, + TramitacaoAdmEditForm, TramitacaoAdmForm, + TramitacaoEmLoteAdmForm, + compara_tramitacoes_doc) +from sapl.protocoloadm.models import (Anexado, DocumentoAdministrativo, + Protocolo, StatusTramitacaoAdministrativo, TipoDocumentoAdministrativo, - TipoMateriaLegislativa, Anexado, + TipoMateriaLegislativa, TramitacaoAdministrativo) from sapl.utils import lista_anexados @pytest.mark.django_db(transaction=False) def test_anular_protocolo_acessivel(admin_client): - response = admin_client.get(reverse('sapl.protocoloadm:anular_protocolo')) + response = admin_client.get(reverse("sapl.protocoloadm:anular_protocolo")) assert response.status_code == 200 @pytest.mark.django_db(transaction=False) def test_anular_protocolo_submit(admin_client): - baker.make(Protocolo, numero='76', ano='2016', anulado=False) + baker.make(Protocolo, numero="76", ano="2016", anulado=False) # TODO: setar usuario e IP - response = admin_client.post(reverse('sapl.protocoloadm:anular_protocolo'), - {'numero': '76', - 'ano': '2016', - 'justificativa_anulacao': 'TESTE', - 'salvar': 'Anular'}, - follow=True) + response = admin_client.post( + reverse("sapl.protocoloadm:anular_protocolo"), + { + "numero": "76", + "ano": "2016", + "justificativa_anulacao": "TESTE", + "salvar": "Anular", + }, + follow=True, + ) assert response.status_code == 200 @@ -52,100 +58,90 @@ def test_anular_protocolo_submit(admin_client): if not protocolo.anulado: pytest.fail(_("Protocolo deveria estar anulado")) - assert protocolo.justificativa_anulacao == 'TESTE' + assert protocolo.justificativa_anulacao == "TESTE" @pytest.mark.django_db(transaction=False) def test_form_anular_protocolo_inexistente(): - form = AnularProtocoloAdmForm({'numero': '1', - 'ano': '2016', - 'justificativa_anulacao': 'TESTE'}) + form = AnularProtocoloAdmForm( + {"numero": "1", "ano": "2016", "justificativa_anulacao": "TESTE"} + ) # Não usa o assert form.is_valid() == False por causa do PEP8 if form.is_valid(): pytest.fail(_("Form deve ser inválido")) - assert form.errors['__all__'] == [_("Protocolo 1/2016 não existe")] + assert form.errors["__all__"] == [_("Protocolo 1/2016 não existe")] @pytest.mark.django_db(transaction=False) def test_form_anular_protocolo_valido(): - baker.make(Protocolo, numero='1', ano='2016', anulado=False) - form = AnularProtocoloAdmForm({'numero': '1', - 'ano': '2016', - 'justificativa_anulacao': 'TESTE'}) + baker.make(Protocolo, numero="1", ano="2016", anulado=False) + form = AnularProtocoloAdmForm( + {"numero": "1", "ano": "2016", "justificativa_anulacao": "TESTE"} + ) if not form.is_valid(): pytest.fail(_("Form deve ser válido")) @pytest.mark.django_db(transaction=False) def test_form_anular_protocolo_anulado(): - baker.make(Protocolo, numero='1', ano='2016', anulado=True) - form = AnularProtocoloAdmForm({'numero': '1', - 'ano': '2016', - 'justificativa_anulacao': 'TESTE'}) - assert form.errors['__all__'] == \ - [_("Protocolo 1/2016 já encontra-se anulado")] + baker.make(Protocolo, numero="1", ano="2016", anulado=True) + form = AnularProtocoloAdmForm( + {"numero": "1", "ano": "2016", "justificativa_anulacao": "TESTE"} + ) + assert form.errors["__all__"] == [_("Protocolo 1/2016 já encontra-se anulado")] @pytest.mark.django_db(transaction=False) def test_form_anular_protocolo_campos_obrigatorios(): - baker.make(Protocolo, numero='1', ano='2016', anulado=False) + baker.make(Protocolo, numero="1", ano="2016", anulado=False) # TODO: generalizar para diminuir o tamanho deste método # numero ausente - form = AnularProtocoloAdmForm({'numero': '', - 'ano': '2016', - 'justificativa_anulacao': 'TESTE'}) + form = AnularProtocoloAdmForm( + {"numero": "", "ano": "2016", "justificativa_anulacao": "TESTE"} + ) if form.is_valid(): pytest.fail(_("Form deve ser inválido")) assert len(form.errors) == 1 - assert form.errors['numero'] == [_('Este campo é obrigatório.')] + assert form.errors["numero"] == [_("Este campo é obrigatório.")] # ano ausente - form = AnularProtocoloAdmForm({'numero': '1', - 'ano': '', - 'justificativa_anulacao': 'TESTE'}) + form = AnularProtocoloAdmForm( + {"numero": "1", "ano": "", "justificativa_anulacao": "TESTE"} + ) if form.is_valid(): pytest.fail(_("Form deve ser inválido")) assert len(form.errors) == 1 - assert form.errors['ano'] == [_('Este campo é obrigatório.')] + assert form.errors["ano"] == [_("Este campo é obrigatório.")] # justificativa_anulacao ausente - form = AnularProtocoloAdmForm({'numero': '1', - 'ano': '2016', - 'justificativa_anulacao': ''}) + form = AnularProtocoloAdmForm( + {"numero": "1", "ano": "2016", "justificativa_anulacao": ""} + ) if form.is_valid(): pytest.fail(_("Form deve ser inválido")) assert len(form.errors) == 1 - assert form.errors['justificativa_anulacao'] == \ - [_('Este campo é obrigatório.')] + assert form.errors["justificativa_anulacao"] == [_("Este campo é obrigatório.")] @pytest.mark.django_db(transaction=False) def test_create_tramitacao(admin_client): - tipo_doc = baker.make( - TipoDocumentoAdministrativo, - descricao='Teste Tipo_DocAdm') + tipo_doc = baker.make(TipoDocumentoAdministrativo, descricao="Teste Tipo_DocAdm") - documento_adm = baker.make( - DocumentoAdministrativo, - tipo=tipo_doc) + documento_adm = baker.make(DocumentoAdministrativo, tipo=tipo_doc) - unidade_tramitacao_local_1 = baker.make( - UnidadeTramitacao, pk=1) + unidade_tramitacao_local_1 = baker.make(UnidadeTramitacao, pk=1) - unidade_tramitacao_destino_1 = baker.make( - UnidadeTramitacao, pk=2) + unidade_tramitacao_destino_1 = baker.make(UnidadeTramitacao, pk=2) - unidade_tramitacao_destino_2 = baker.make( - UnidadeTramitacao, pk=3) + unidade_tramitacao_destino_2 = baker.make(UnidadeTramitacao, pk=3) - status = baker.make( - StatusTramitacaoAdministrativo) + status = baker.make(StatusTramitacaoAdministrativo) tramitacao = baker.make( TramitacaoAdministrativo, @@ -153,123 +149,148 @@ def test_create_tramitacao(admin_client): unidade_tramitacao_destino=unidade_tramitacao_destino_1, status=status, documento=documento_adm, - data_tramitacao=date(2016, 8, 21)) + data_tramitacao=date(2016, 8, 21), + ) response = admin_client.post( reverse( - 'sapl.protocoloadm:tramitacaoadministrativo_create', - kwargs={'pk': documento_adm.pk}), - {'unidade_tramitacao_local': unidade_tramitacao_destino_2.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_local_1.pk, - 'documento': documento_adm.pk, - 'status': status.pk, - 'urgente': False, - 'texto': 'teste', - 'data_tramitacao': date(2016, 8, 21)}, - follow=True) - - msg = force_str(_('A origem da nova tramitação deve ser igual ao ' - 'destino da última adicionada!')) - + "sapl.protocoloadm:tramitacaoadministrativo_create", + kwargs={"pk": documento_adm.pk}, + ), + { + "unidade_tramitacao_local": unidade_tramitacao_destino_2.pk, + "unidade_tramitacao_destino": unidade_tramitacao_local_1.pk, + "documento": documento_adm.pk, + "status": status.pk, + "urgente": False, + "texto": "teste", + "data_tramitacao": date(2016, 8, 21), + }, + follow=True, + ) + + msg = force_str( + _( + "A origem da nova tramitação deve ser igual ao " + "destino da última adicionada!" + ) + ) + # Verifica se a origem da nova tramitacao é igual ao destino da última - assert msg in response.context_data[ - 'form'].errors['__all__'] + assert msg in response.context_data["form"].errors["__all__"] response = admin_client.post( reverse( - 'sapl.protocoloadm:tramitacaoadministrativo_create', - kwargs={'pk': documento_adm.pk}), - {'unidade_tramitacao_local': unidade_tramitacao_destino_1.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.pk, - 'documento': documento_adm.pk, - 'status': status.pk, - 'urgente': False, - 'texto': 'teste', - 'data_tramitacao': date(2016, 8, 20)}, - follow=True) - - msg = _('A data da nova tramitação deve ser ' + - 'maior que a data da última tramitação!') + "sapl.protocoloadm:tramitacaoadministrativo_create", + kwargs={"pk": documento_adm.pk}, + ), + { + "unidade_tramitacao_local": unidade_tramitacao_destino_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "documento": documento_adm.pk, + "status": status.pk, + "urgente": False, + "texto": "teste", + "data_tramitacao": date(2016, 8, 20), + }, + follow=True, + ) + + msg = _( + "A data da nova tramitação deve ser " + "maior que a data da última tramitação!" + ) # Verifica se a data da nova tramitação é maior do que a última - assert msg in response.context_data[ - 'form'].errors['__all__'] + assert msg in response.context_data["form"].errors["__all__"] response = admin_client.post( reverse( - 'sapl.protocoloadm:tramitacaoadministrativo_create', - kwargs={'pk': documento_adm.pk}), - {'unidade_tramitacao_local': unidade_tramitacao_destino_1.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.pk, - 'documento': documento_adm.pk, - 'status': status.pk, - 'urgente': False, - 'texto': 'teste', - 'data_tramitacao': timezone.now().date() + timedelta( - days=1)}, - follow=True) - - msg = force_str(_('A data de tramitação deve ser ' + - 'menor ou igual a data de hoje!')) + "sapl.protocoloadm:tramitacaoadministrativo_create", + kwargs={"pk": documento_adm.pk}, + ), + { + "unidade_tramitacao_local": unidade_tramitacao_destino_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "documento": documento_adm.pk, + "status": status.pk, + "urgente": False, + "texto": "teste", + "data_tramitacao": timezone.now().date() + timedelta(days=1), + }, + follow=True, + ) + + msg = force_str( + _("A data de tramitação deve ser " + "menor ou igual a data de hoje!") + ) # Verifica se a data da tramitação é menor do que a data de hoje - assert msg in response.context_data[ - 'form'].errors['__all__'] + assert msg in response.context_data["form"].errors["__all__"] response = admin_client.post( reverse( - 'sapl.protocoloadm:tramitacaoadministrativo_create', - kwargs={'pk': documento_adm.pk}), - {'unidade_tramitacao_local': unidade_tramitacao_destino_1.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.pk, - 'documento': documento_adm.pk, - 'status': status.pk, - 'urgente': False, - 'texto': 'teste', - 'data_tramitacao': date(2016, 8, 21), - 'data_encaminhamento': date(2016, 8, 20)}, - follow=True) - - msg = force_str(_('A data de encaminhamento deve ser ' + - 'maior que a data de tramitação!')) + "sapl.protocoloadm:tramitacaoadministrativo_create", + kwargs={"pk": documento_adm.pk}, + ), + { + "unidade_tramitacao_local": unidade_tramitacao_destino_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "documento": documento_adm.pk, + "status": status.pk, + "urgente": False, + "texto": "teste", + "data_tramitacao": date(2016, 8, 21), + "data_encaminhamento": date(2016, 8, 20), + }, + follow=True, + ) + + msg = force_str( + _("A data de encaminhamento deve ser " + "maior que a data de tramitação!") + ) # Verifica se a data da encaminhamento é menor do que a data de tramitacao - assert msg in response.context_data[ - 'form'].errors['__all__'] + assert msg in response.context_data["form"].errors["__all__"] response = admin_client.post( reverse( - 'sapl.protocoloadm:tramitacaoadministrativo_create', - kwargs={'pk': documento_adm.pk}), - {'unidade_tramitacao_local': unidade_tramitacao_destino_1.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.pk, - 'documento': documento_adm.pk, - 'status': status.pk, - 'urgente': False, - 'texto': 'teste', - 'data_tramitacao': date(2016, 8, 21), - 'data_fim_prazo': date(2016, 8, 20)}, - follow=True) - - msg = _('A data fim de prazo deve ser ' + - 'maior que a data de tramitação!') + "sapl.protocoloadm:tramitacaoadministrativo_create", + kwargs={"pk": documento_adm.pk}, + ), + { + "unidade_tramitacao_local": unidade_tramitacao_destino_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "documento": documento_adm.pk, + "status": status.pk, + "urgente": False, + "texto": "teste", + "data_tramitacao": date(2016, 8, 21), + "data_fim_prazo": date(2016, 8, 20), + }, + follow=True, + ) + + msg = _("A data fim de prazo deve ser " + "maior que a data de tramitação!") # Verifica se a data da do fim do prazo é menor do que a data de tramitacao - assert msg in response.context_data[ - 'form'].errors['__all__'] + assert msg in response.context_data["form"].errors["__all__"] response = admin_client.post( reverse( - 'sapl.protocoloadm:tramitacaoadministrativo_create', - kwargs={'pk': documento_adm.pk}), - {'unidade_tramitacao_local': unidade_tramitacao_destino_1.pk, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.pk, - 'documento': documento_adm.pk, - 'status': status.pk, - 'urgente': False, - 'texto': 'teste', - 'data_tramitacao': date(2016, 8, 21)}, - follow=True) + "sapl.protocoloadm:tramitacaoadministrativo_create", + kwargs={"pk": documento_adm.pk}, + ), + { + "unidade_tramitacao_local": unidade_tramitacao_destino_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "documento": documento_adm.pk, + "status": status.pk, + "urgente": False, + "texto": "teste", + "data_tramitacao": date(2016, 8, 21), + }, + follow=True, + ) tramitacao = TramitacaoAdministrativo.objects.last() # Verifica se a tramitacao que obedece as regras de negócios é criada @@ -278,94 +299,84 @@ def test_create_tramitacao(admin_client): @pytest.mark.django_db(transaction=False) def test_anular_protocolo_dados_invalidos(): - form = AnularProtocoloAdmForm(data={}) assert not form.is_valid() errors = form.errors - assert errors['numero'] == [_('Este campo é obrigatório.')] - assert errors['ano'] == [_('Este campo é obrigatório.')] - assert errors['justificativa_anulacao'] == [_('Este campo é obrigatório.')] + assert errors["numero"] == [_("Este campo é obrigatório.")] + assert errors["ano"] == [_("Este campo é obrigatório.")] + assert errors["justificativa_anulacao"] == [_("Este campo é obrigatório.")] assert len(errors) == 3 @pytest.mark.django_db(transaction=False) def test_anular_protocolo_form_anula_protocolo_inexistente(): - form = AnularProtocoloAdmForm(data={'numero': '1', - 'ano': '2017', - 'justificativa_anulacao': 'teste' - }) + form = AnularProtocoloAdmForm( + data={"numero": "1", "ano": "2017", "justificativa_anulacao": "teste"} + ) assert not form.is_valid() - assert form.errors['__all__'] == [_( - 'Protocolo 1/2017 não existe')] + assert form.errors["__all__"] == [_("Protocolo 1/2017 não existe")] @pytest.mark.django_db(transaction=False) def test_anular_protocolo_form_anula_protocolo_anulado(): baker.make(Protocolo, numero=1, ano=2017, anulado=True) - form = AnularProtocoloAdmForm(data={'numero': '1', - 'ano': '2017', - 'justificativa_anulacao': 'teste' - }) + form = AnularProtocoloAdmForm( + data={"numero": "1", "ano": "2017", "justificativa_anulacao": "teste"} + ) assert not form.is_valid() - assert form.errors['__all__'] == [_( - 'Protocolo 1/2017 já encontra-se anulado')] + assert form.errors["__all__"] == [_("Protocolo 1/2017 já encontra-se anulado")] @pytest.mark.django_db(transaction=False) def test_anular_protocolo_form_anula_protocolo_com_doc_vinculado(): tipo_materia = baker.make(TipoMateriaLegislativa) - baker.make(Protocolo, - numero=1, - ano=2017, - tipo_materia=tipo_materia, - anulado=False) + baker.make(Protocolo, numero=1, ano=2017, tipo_materia=tipo_materia, anulado=False) - baker.make(MateriaLegislativa, - ano=2017, - numero_protocolo=1) + baker.make(MateriaLegislativa, ano=2017, numero_protocolo=1) - form = AnularProtocoloAdmForm(data={'numero': '1', - 'ano': '2017', - 'justificativa_anulacao': 'teste' - }) + form = AnularProtocoloAdmForm( + data={"numero": "1", "ano": "2017", "justificativa_anulacao": "teste"} + ) assert not form.is_valid() - assert form.errors['__all__'] == \ - [_("Protocolo 1/2017 não pode ser removido pois existem " - "documentos vinculados a ele.")] + assert form.errors["__all__"] == [ + _( + "Protocolo 1/2017 não pode ser removido pois existem " + "documentos vinculados a ele." + ) + ] tipo_documento = baker.make(TipoDocumentoAdministrativo) - protocolo_documento = baker.make(Protocolo, - numero=2, - ano=2017, - tipo_documento=tipo_documento, - anulado=False) + protocolo_documento = baker.make( + Protocolo, numero=2, ano=2017, tipo_documento=tipo_documento, anulado=False + ) - baker.make(DocumentoAdministrativo, - protocolo=protocolo_documento) + baker.make(DocumentoAdministrativo, protocolo=protocolo_documento) - form = AnularProtocoloAdmForm(data={'numero': '2', - 'ano': '2017', - 'justificativa_anulacao': 'teste' - }) + form = AnularProtocoloAdmForm( + data={"numero": "2", "ano": "2017", "justificativa_anulacao": "teste"} + ) assert not form.is_valid() - assert form.errors['__all__'] == \ - [_("Protocolo 2/2017 não pode ser removido pois existem " - "documentos vinculados a ele.")] + assert form.errors["__all__"] == [ + _( + "Protocolo 2/2017 não pode ser removido pois existem " + "documentos vinculados a ele." + ) + ] def test_documento_administrativo_invalido(): @@ -374,141 +385,141 @@ def test_documento_administrativo_invalido(): assert not form.is_valid() errors = form.errors - assert errors['ano'] == [_('Este campo é obrigatório.')] - assert errors['tipo'] == [_('Este campo é obrigatório.')] - assert errors['assunto'] == [_('Este campo é obrigatório.')] - assert errors['numero'] == [_('Este campo é obrigatório.')] - assert errors['data'] == [_('Este campo é obrigatório.')] - assert errors['restrito'] == [_('Este campo é obrigatório.')] - assert errors['tramitacao'] == [_('Este campo é obrigatório.')] + assert errors["ano"] == [_("Este campo é obrigatório.")] + assert errors["tipo"] == [_("Este campo é obrigatório.")] + assert errors["assunto"] == [_("Este campo é obrigatório.")] + assert errors["numero"] == [_("Este campo é obrigatório.")] + assert errors["data"] == [_("Este campo é obrigatório.")] + assert errors["restrito"] == [_("Este campo é obrigatório.")] + assert errors["tramitacao"] == [_("Este campo é obrigatório.")] assert len(errors) == 7 @pytest.mark.django_db(transaction=False) def test_documento_administrativo_protocolo_inexistente(): - tipo = baker.make(TipoDocumentoAdministrativo) - protocolo = baker.make(Protocolo, - ano=2017, - numero=10, - anulado=False, - tipo_documento=tipo) - - form = DocumentoAdministrativoForm(data={'ano': '2017', - 'tipo': str(tipo.pk), - 'assunto': 'teste', - 'numero': '1', - 'complemento':'', - 'data': '2017-10-10', - 'numero_protocolo': '11', - 'ano_protocolo': '2017', - 'restrito': False, - 'tramitacao': False - }) + protocolo = baker.make( + Protocolo, ano=2017, numero=10, anulado=False, tipo_documento=tipo + ) + + form = DocumentoAdministrativoForm( + data={ + "ano": "2017", + "tipo": str(tipo.pk), + "assunto": "teste", + "numero": "1", + "complemento": "", + "data": "2017-10-10", + "numero_protocolo": "11", + "ano_protocolo": "2017", + "restrito": False, + "tramitacao": False, + } + ) assert not form.is_valid() - assert form.errors['__all__'] == [_('Protocolo 11/2017 inexistente.')] + assert form.errors["__all__"] == [_("Protocolo 11/2017 inexistente.")] @pytest.mark.django_db(transaction=False) def test_protocolo_documento_form_invalido(): - config = baker.make(AppConfig) form = ProtocoloDocumentoForm( data={}, initial={ - 'user_data_hora_manual': '', - 'ip_data_hora_manual': '', - 'data': timezone.localdate(timezone.now()), - 'hora': timezone.localtime(timezone.now())}) + "user_data_hora_manual": "", + "ip_data_hora_manual": "", + "data": timezone.localdate(timezone.now()), + "hora": timezone.localtime(timezone.now()), + }, + ) assert not form.is_valid() errors = form.errors - assert errors['data_hora_manual'] == [_('Este campo é obrigatório.')] - assert errors['tipo_protocolo'] == [_('Este campo é obrigatório.')] - assert errors['interessado'] == [_('Este campo é obrigatório.')] - assert errors['tipo_documento'] == [_('Este campo é obrigatório.')] - assert errors['numero_paginas'] == [_('Este campo é obrigatório.')] - assert errors['assunto'] == [_('Este campo é obrigatório.')] + assert errors["data_hora_manual"] == [_("Este campo é obrigatório.")] + assert errors["tipo_protocolo"] == [_("Este campo é obrigatório.")] + assert errors["interessado"] == [_("Este campo é obrigatório.")] + assert errors["tipo_documento"] == [_("Este campo é obrigatório.")] + assert errors["numero_paginas"] == [_("Este campo é obrigatório.")] + assert errors["assunto"] == [_("Este campo é obrigatório.")] assert len(errors) == 6 @pytest.mark.django_db(transaction=False) def test_protocolo_materia_invalido(): - config = baker.make(AppConfig) - form = ProtocoloMateriaForm(data={}, - initial={ - 'user_data_hora_manual': '', - 'ip_data_hora_manual': '', - 'data': timezone.localdate(timezone.now()), - 'hora': timezone.localtime(timezone.now())}) + form = ProtocoloMateriaForm( + data={}, + initial={ + "user_data_hora_manual": "", + "ip_data_hora_manual": "", + "data": timezone.localdate(timezone.now()), + "hora": timezone.localtime(timezone.now()), + }, + ) assert not form.is_valid() errors = form.errors - assert errors['data_hora_manual'] == [_('Este campo é obrigatório.')] - assert errors['assunto_ementa'] == [_('Este campo é obrigatório.')] - assert errors['tipo_autor'] == [_('Este campo é obrigatório.')] - assert errors['tipo_materia'] == [_('Este campo é obrigatório.')] - assert errors['numero_paginas'] == [_('Este campo é obrigatório.')] - assert errors['autor'] == [_('Este campo é obrigatório.')] - assert errors['vincular_materia'] == [_('Este campo é obrigatório.')] + assert errors["data_hora_manual"] == [_("Este campo é obrigatório.")] + assert errors["assunto_ementa"] == [_("Este campo é obrigatório.")] + assert errors["tipo_autor"] == [_("Este campo é obrigatório.")] + assert errors["tipo_materia"] == [_("Este campo é obrigatório.")] + assert errors["numero_paginas"] == [_("Este campo é obrigatório.")] + assert errors["autor"] == [_("Este campo é obrigatório.")] + assert errors["vincular_materia"] == [_("Este campo é obrigatório.")] assert len(errors) == 7 @pytest.mark.django_db(transaction=False) def test_lista_documentos_anexados(): - tipo_documento = baker.make( - TipoDocumentoAdministrativo, - descricao="Tipo_Teste" - ) + tipo_documento = baker.make(TipoDocumentoAdministrativo, descricao="Tipo_Teste") documento_principal = baker.make( - DocumentoAdministrativo, - numero=20, - ano=2018, - data="2018-01-04", - tipo=tipo_documento + DocumentoAdministrativo, + numero=20, + ano=2018, + data="2018-01-04", + tipo=tipo_documento, ) documento_anexado = baker.make( - DocumentoAdministrativo, - numero=21, - ano=2019, - data="2019-05-04", - tipo=tipo_documento + DocumentoAdministrativo, + numero=21, + ano=2019, + data="2019-05-04", + tipo=tipo_documento, ) documento_anexado_anexado = baker.make( - DocumentoAdministrativo, - numero=22, - ano=2020, - data="2020-01-05", - tipo=tipo_documento + DocumentoAdministrativo, + numero=22, + ano=2020, + data="2020-01-05", + tipo=tipo_documento, ) baker.make( - Anexado, - documento_principal=documento_principal, - documento_anexado=documento_anexado, - data_anexacao="2019-05-11" + Anexado, + documento_principal=documento_principal, + documento_anexado=documento_anexado, + data_anexacao="2019-05-11", ) baker.make( - Anexado, - documento_principal=documento_anexado, - documento_anexado=documento_anexado_anexado, - data_anexacao="2020-11-05" + Anexado, + documento_principal=documento_anexado, + documento_anexado=documento_anexado_anexado, + data_anexacao="2020-11-05", ) lista = lista_anexados(documento_principal) - + assert len(lista) == 2 assert lista[0] == documento_anexado assert lista[1] == documento_anexado_anexado @@ -518,11 +529,13 @@ def test_lista_documentos_anexados(): def make_unidade_tramitacao(descricao): # Cria uma comissão para ser a unidade de tramitação tipo_comissao = baker.make(TipoComissao) - comissao = baker.make(Comissao, - tipo=tipo_comissao, - nome=descricao, - sigla='T', - data_criacao='2016-03-21') + comissao = baker.make( + Comissao, + tipo=tipo_comissao, + nome=descricao, + sigla="T", + data_criacao="2016-03-21", + ) # Testa a comissão assert comissao.tipo == tipo_comissao @@ -534,184 +547,240 @@ def make_unidade_tramitacao(descricao): return unidade - + @pytest.mark.django_db(transaction=False) def test_tramitacoes_documentos_anexados(admin_client): - config = baker.make(AppConfig, tramitacao_documento=True) - tipo_documento = baker.make( - TipoDocumentoAdministrativo, - descricao="Tipo_Teste" - ) + tipo_documento = baker.make(TipoDocumentoAdministrativo, descricao="Tipo_Teste") documento_principal = baker.make( - DocumentoAdministrativo, - numero=20, - ano=2018, - data="2018-01-04", - tipo=tipo_documento + DocumentoAdministrativo, + numero=20, + ano=2018, + data="2018-01-04", + tipo=tipo_documento, ) documento_anexado = baker.make( - DocumentoAdministrativo, - numero=21, - ano=2019, - data="2019-05-04", - tipo=tipo_documento + DocumentoAdministrativo, + numero=21, + ano=2019, + data="2019-05-04", + tipo=tipo_documento, ) documento_anexado_anexado = baker.make( - DocumentoAdministrativo, - numero=22, - ano=2020, - data="2020-01-05", - tipo=tipo_documento + DocumentoAdministrativo, + numero=22, + ano=2020, + data="2020-01-05", + tipo=tipo_documento, ) baker.make( - Anexado, - documento_principal=documento_principal, - documento_anexado=documento_anexado, - data_anexacao="2019-05-11" + Anexado, + documento_principal=documento_principal, + documento_anexado=documento_anexado, + data_anexacao="2019-05-11", ) baker.make( - Anexado, - documento_principal=documento_anexado, - documento_anexado=documento_anexado_anexado, - data_anexacao="2020-11-05" + Anexado, + documento_principal=documento_anexado, + documento_anexado=documento_anexado_anexado, + data_anexacao="2020-11-05", ) - unidade_tramitacao_local_1 = make_unidade_tramitacao(descricao="Teste 1") unidade_tramitacao_destino_1 = make_unidade_tramitacao(descricao="Teste 2") unidade_tramitacao_destino_2 = make_unidade_tramitacao(descricao="Teste 3") - status = baker.make( - StatusTramitacaoAdministrativo, - indicador='R') + status = baker.make(StatusTramitacaoAdministrativo, indicador="R") # Teste criação de Tramitacao form = TramitacaoAdmForm(data={}) - form.data = {'data_tramitacao':date(2019, 5, 6), - 'unidade_tramitacao_local':unidade_tramitacao_local_1.pk, - 'unidade_tramitacao_destino':unidade_tramitacao_destino_1.pk, - 'status':status.pk, - 'urgente': False, - 'texto': "Texto de teste"} - form.instance.documento_id=documento_principal.pk + form.data = { + "data_tramitacao": date(2019, 5, 6), + "unidade_tramitacao_local": unidade_tramitacao_local_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.pk, + "status": status.pk, + "urgente": False, + "texto": "Texto de teste", + } + form.instance.documento_id = documento_principal.pk assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = documento_anexado.tramitacaoadministrativo_set.last() - tramitacao_anexada_anexada = documento_anexado_anexado.tramitacaoadministrativo_set.last() + tramitacao_anexada_anexada = ( + documento_anexado_anexado.tramitacaoadministrativo_set.last() + ) # Verifica se foram criadas as tramitações para os documentos anexados e anexados aos anexados - assert documento_principal.tramitacaoadministrativo_set.last() == tramitacao_principal - assert tramitacao_principal.documento.tramitacao == (tramitacao_principal.status.indicador != "F") + assert ( + documento_principal.tramitacaoadministrativo_set.last() == tramitacao_principal + ) + assert tramitacao_principal.documento.tramitacao == ( + tramitacao_principal.status.indicador != "F" + ) assert compara_tramitacoes_doc(tramitacao_principal, tramitacao_anexada) - assert DocumentoAdministrativo.objects.get(id=documento_anexado.pk).tramitacao \ - == (tramitacao_anexada.status.indicador != "F") + assert DocumentoAdministrativo.objects.get(id=documento_anexado.pk).tramitacao == ( + tramitacao_anexada.status.indicador != "F" + ) assert compara_tramitacoes_doc(tramitacao_anexada_anexada, tramitacao_principal) - assert DocumentoAdministrativo.objects.get(id=documento_anexado_anexado.pk).tramitacao \ - == (tramitacao_anexada_anexada.status.indicador != "F") - + assert DocumentoAdministrativo.objects.get( + id=documento_anexado_anexado.pk + ).tramitacao == (tramitacao_anexada_anexada.status.indicador != "F") # Teste Edição de Tramitacao form = TramitacaoAdmEditForm(data={}) # Alterando unidade_tramitacao_destino - form.data = {'data_tramitacao':tramitacao_principal.data_tramitacao, - 'unidade_tramitacao_local':tramitacao_principal.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino':unidade_tramitacao_destino_2.pk, - 'status':tramitacao_principal.status.pk, - 'urgente': tramitacao_principal.urgente, - 'texto': tramitacao_principal.texto} + form.data = { + "data_tramitacao": tramitacao_principal.data_tramitacao, + "unidade_tramitacao_local": tramitacao_principal.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "status": tramitacao_principal.status.pk, + "urgente": tramitacao_principal.urgente, + "texto": tramitacao_principal.texto, + } form.instance = tramitacao_principal assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = documento_anexado.tramitacaoadministrativo_set.last() - tramitacao_anexada_anexada = documento_anexado_anexado.tramitacaoadministrativo_set.last() + tramitacao_anexada_anexada = ( + documento_anexado_anexado.tramitacaoadministrativo_set.last() + ) - assert tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + assert ( + tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + ) assert tramitacao_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 - assert tramitacao_anexada_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 - + assert ( + tramitacao_anexada_anexada.unidade_tramitacao_destino + == unidade_tramitacao_destino_2 + ) # Teste Remoção de Tramitacao - url = reverse('sapl.protocoloadm:tramitacaoadministrativo_delete', - kwargs={'pk': tramitacao_principal.pk}) - response = admin_client.post(url, {'confirmar':'confirmar'} ,follow=True) - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_principal.pk).count() == 0 - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada.pk).count() == 0 - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada_anexada.pk).count() == 0 - - + url = reverse( + "sapl.protocoloadm:tramitacaoadministrativo_delete", + kwargs={"pk": tramitacao_principal.pk}, + ) + response = admin_client.post(url, {"confirmar": "confirmar"}, follow=True) + assert ( + TramitacaoAdministrativo.objects.filter(id=tramitacao_principal.pk).count() == 0 + ) + assert ( + TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada.pk).count() == 0 + ) + assert ( + TramitacaoAdministrativo.objects.filter( + id=tramitacao_anexada_anexada.pk + ).count() + == 0 + ) + # Testes para quando as tramitações das anexadas divergem form = TramitacaoAdmForm(data={}) - form.data = {'data_tramitacao':date(2019, 5, 6), - 'unidade_tramitacao_local':unidade_tramitacao_local_1.pk, - 'unidade_tramitacao_destino':unidade_tramitacao_destino_1.pk, - 'status':status.pk, - 'urgente': False, - 'texto': "Texto de teste"} - form.instance.documento_id=documento_principal.pk + form.data = { + "data_tramitacao": date(2019, 5, 6), + "unidade_tramitacao_local": unidade_tramitacao_local_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.pk, + "status": status.pk, + "urgente": False, + "texto": "Texto de teste", + } + form.instance.documento_id = documento_principal.pk assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = documento_anexado.tramitacaoadministrativo_set.last() - tramitacao_anexada_anexada = documento_anexado_anexado.tramitacaoadministrativo_set.last() + tramitacao_anexada_anexada = ( + documento_anexado_anexado.tramitacaoadministrativo_set.last() + ) form = TramitacaoAdmEditForm(data={}) # Alterando unidade_tramitacao_destino - form.data = {'data_tramitacao':tramitacao_anexada.data_tramitacao, - 'unidade_tramitacao_local':tramitacao_anexada.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino':unidade_tramitacao_destino_2.pk, - 'status':tramitacao_anexada.status.pk, - 'urgente': tramitacao_anexada.urgente, - 'texto': tramitacao_anexada.texto} + form.data = { + "data_tramitacao": tramitacao_anexada.data_tramitacao, + "unidade_tramitacao_local": tramitacao_anexada.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "status": tramitacao_anexada.status.pk, + "urgente": tramitacao_anexada.urgente, + "texto": tramitacao_anexada.texto, + } form.instance = tramitacao_anexada assert form.is_valid() tramitacao_anexada = form.save() - tramitacao_anexada_anexada = documento_anexado_anexado.tramitacaoadministrativo_set.last() + tramitacao_anexada_anexada = ( + documento_anexado_anexado.tramitacaoadministrativo_set.last() + ) - assert tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_1 + assert ( + tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_1 + ) assert tramitacao_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 - assert tramitacao_anexada_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + assert ( + tramitacao_anexada_anexada.unidade_tramitacao_destino + == unidade_tramitacao_destino_2 + ) # Editando a tramitação principal, as tramitações anexadas não devem ser editadas form = TramitacaoAdmEditForm(data={}) # Alterando o texto - form.data = {'data_tramitacao':tramitacao_principal.data_tramitacao, - 'unidade_tramitacao_local':tramitacao_principal.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino':tramitacao_principal.unidade_tramitacao_destino.pk, - 'status':tramitacao_principal.status.pk, - 'urgente': tramitacao_principal.urgente, - 'texto': "Testando a alteração"} + form.data = { + "data_tramitacao": tramitacao_principal.data_tramitacao, + "unidade_tramitacao_local": tramitacao_principal.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": tramitacao_principal.unidade_tramitacao_destino.pk, + "status": tramitacao_principal.status.pk, + "urgente": tramitacao_principal.urgente, + "texto": "Testando a alteração", + } form.instance = tramitacao_principal assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = documento_anexado.tramitacaoadministrativo_set.last() - tramitacao_anexada_anexada = documento_anexado_anexado.tramitacaoadministrativo_set.last() + tramitacao_anexada_anexada = ( + documento_anexado_anexado.tramitacaoadministrativo_set.last() + ) assert tramitacao_principal.texto == "Testando a alteração" assert not tramitacao_anexada.texto == "Testando a alteração" assert not tramitacao_anexada_anexada.texto == "Testando a alteração" # Removendo a tramitação pricipal, as tramitações anexadas não devem ser removidas, pois divergiram - url = reverse('sapl.protocoloadm:tramitacaoadministrativo_delete', - kwargs={'pk': tramitacao_principal.pk}) - response = admin_client.post(url, {'confirmar':'confirmar'} ,follow=True) - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_principal.pk).count() == 0 - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada.pk).count() == 1 - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada_anexada.pk).count() == 1 + url = reverse( + "sapl.protocoloadm:tramitacaoadministrativo_delete", + kwargs={"pk": tramitacao_principal.pk}, + ) + response = admin_client.post(url, {"confirmar": "confirmar"}, follow=True) + assert ( + TramitacaoAdministrativo.objects.filter(id=tramitacao_principal.pk).count() == 0 + ) + assert ( + TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada.pk).count() == 1 + ) + assert ( + TramitacaoAdministrativo.objects.filter( + id=tramitacao_anexada_anexada.pk + ).count() + == 1 + ) # Removendo a tramitação anexada, a tramitação anexada à anexada deve ser removida - url = reverse('sapl.protocoloadm:tramitacaoadministrativo_delete', - kwargs={'pk': tramitacao_anexada.pk}) - response = admin_client.post(url, {'confirmar':'confirmar'} ,follow=True) - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada.pk).count() == 0 - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada_anexada.pk).count() == 0 - + url = reverse( + "sapl.protocoloadm:tramitacaoadministrativo_delete", + kwargs={"pk": tramitacao_anexada.pk}, + ) + response = admin_client.post(url, {"confirmar": "confirmar"}, follow=True) + assert ( + TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada.pk).count() == 0 + ) + assert ( + TramitacaoAdministrativo.objects.filter( + id=tramitacao_anexada_anexada.pk + ).count() + == 0 + ) # Agora testando para caso não seja desejado tramitar os documentos anexados # junto com os documentos principais @@ -720,179 +789,213 @@ def test_tramitacoes_documentos_anexados(admin_client): # Teste criação de Tramitacao form = TramitacaoAdmForm(data={}) - form.data = {'data_tramitacao':date(2019, 5, 6), - 'unidade_tramitacao_local':unidade_tramitacao_local_1.pk, - 'unidade_tramitacao_destino':unidade_tramitacao_destino_1.pk, - 'status':status.pk, - 'urgente': False, - 'texto': "Texto de teste"} - form.instance.documento_id=documento_principal.pk + form.data = { + "data_tramitacao": date(2019, 5, 6), + "unidade_tramitacao_local": unidade_tramitacao_local_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.pk, + "status": status.pk, + "urgente": False, + "texto": "Texto de teste", + } + form.instance.documento_id = documento_principal.pk assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = documento_anexado.tramitacaoadministrativo_set.last() - tramitacao_anexada_anexada = documento_anexado_anexado.tramitacaoadministrativo_set.last() + tramitacao_anexada_anexada = ( + documento_anexado_anexado.tramitacaoadministrativo_set.last() + ) # Verifica se não foram criadas as tramitações para os documentos anexados e anexados aos anexados - assert documento_principal.tramitacaoadministrativo_set.last() == tramitacao_principal - assert tramitacao_principal.documento.tramitacao == (tramitacao_principal.status.indicador != "F") + assert ( + documento_principal.tramitacaoadministrativo_set.last() == tramitacao_principal + ) + assert tramitacao_principal.documento.tramitacao == ( + tramitacao_principal.status.indicador != "F" + ) assert not tramitacao_anexada assert not tramitacao_anexada_anexada - # Cria uma tramitação igual na tramitação anexada para testar a edição form = TramitacaoAdmForm(data={}) - form.data = {'data_tramitacao':date(2019, 5, 6), - 'unidade_tramitacao_local':unidade_tramitacao_local_1.pk, - 'unidade_tramitacao_destino':unidade_tramitacao_destino_1.pk, - 'status':status.pk, - 'urgente': False, - 'texto': "Texto de teste"} - form.instance.documento_id=documento_anexado.pk + form.data = { + "data_tramitacao": date(2019, 5, 6), + "unidade_tramitacao_local": unidade_tramitacao_local_1.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.pk, + "status": status.pk, + "urgente": False, + "texto": "Texto de teste", + } + form.instance.documento_id = documento_anexado.pk assert form.is_valid() tramitacao_anexada = form.save() - tramitacao_principal = documento_principal.tramitacaoadministrativo_set.last() - tramitacao_anexada_anexada = documento_anexado_anexado.tramitacaoadministrativo_set.last() + tramitacao_principal = documento_principal.tramitacaoadministrativo_set.last() + tramitacao_anexada_anexada = ( + documento_anexado_anexado.tramitacaoadministrativo_set.last() + ) assert documento_principal.tramitacaoadministrativo_set.all().count() == 1 assert documento_anexado.tramitacaoadministrativo_set.last() == tramitacao_anexada assert not tramitacao_anexada_anexada form = TramitacaoAdmEditForm(data={}) - # Alterando unidade_tramitacao_destino da matéria principal, + # Alterando unidade_tramitacao_destino da matéria principal, # as anexadas não devem ser alteradas - form.data = {'data_tramitacao':tramitacao_principal.data_tramitacao, - 'unidade_tramitacao_local':tramitacao_principal.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino':unidade_tramitacao_destino_2.pk, - 'status':tramitacao_principal.status.pk, - 'urgente': tramitacao_principal.urgente, - 'texto': tramitacao_principal.texto} + form.data = { + "data_tramitacao": tramitacao_principal.data_tramitacao, + "unidade_tramitacao_local": tramitacao_principal.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "status": tramitacao_principal.status.pk, + "urgente": tramitacao_principal.urgente, + "texto": tramitacao_principal.texto, + } form.instance = tramitacao_principal assert form.is_valid() tramitacao_principal = form.save() tramitacao_anexada = documento_anexado.tramitacaoadministrativo_set.last() - tramitacao_anexada_anexada = documento_anexado_anexado.tramitacaoadministrativo_set.last() + tramitacao_anexada_anexada = ( + documento_anexado_anexado.tramitacaoadministrativo_set.last() + ) - assert tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + assert ( + tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + ) assert tramitacao_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_1 assert not tramitacao_anexada_anexada - form = TramitacaoAdmEditForm(data={}) # Alterando a anexada da principal para testar a remoção de tramitação - form.data = {'data_tramitacao':tramitacao_principal.data_tramitacao, - 'unidade_tramitacao_local':tramitacao_principal.unidade_tramitacao_local.pk, - 'unidade_tramitacao_destino':unidade_tramitacao_destino_2.pk, - 'status':tramitacao_principal.status.pk, - 'urgente': tramitacao_principal.urgente, - 'texto': tramitacao_principal.texto} + form.data = { + "data_tramitacao": tramitacao_principal.data_tramitacao, + "unidade_tramitacao_local": tramitacao_principal.unidade_tramitacao_local.pk, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.pk, + "status": tramitacao_principal.status.pk, + "urgente": tramitacao_principal.urgente, + "texto": tramitacao_principal.texto, + } form.instance = tramitacao_anexada assert form.is_valid() - tramitacao_anexada = form.save() + tramitacao_anexada = form.save() tramitacao_principal = documento_principal.tramitacaoadministrativo_set.last() - tramitacao_anexada_anexada = documento_anexado_anexado.tramitacaoadministrativo_set.last() + tramitacao_anexada_anexada = ( + documento_anexado_anexado.tramitacaoadministrativo_set.last() + ) - assert tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + assert ( + tramitacao_principal.unidade_tramitacao_destino == unidade_tramitacao_destino_2 + ) assert tramitacao_anexada.unidade_tramitacao_destino == unidade_tramitacao_destino_2 assert not tramitacao_anexada_anexada assert compara_tramitacoes_doc(tramitacao_anexada, tramitacao_principal) # Removendo a tramitação principal, a tramitação anexada não deve ser removida - url = reverse('sapl.protocoloadm:tramitacaoadministrativo_delete', - kwargs={'pk': tramitacao_principal.pk}) - response = admin_client.post(url, {'confirmar':'confirmar'} ,follow=True) - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_principal.pk).count() == 0 - assert TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada.pk).count() == 1 + url = reverse( + "sapl.protocoloadm:tramitacaoadministrativo_delete", + kwargs={"pk": tramitacao_principal.pk}, + ) + response = admin_client.post(url, {"confirmar": "confirmar"}, follow=True) + assert ( + TramitacaoAdministrativo.objects.filter(id=tramitacao_principal.pk).count() == 0 + ) + assert ( + TramitacaoAdministrativo.objects.filter(id=tramitacao_anexada.pk).count() == 1 + ) @pytest.mark.django_db(transaction=False) def test_tramitacao_lote_documentos_form(admin_client): - tipo_documento = baker.make( - TipoDocumentoAdministrativo, - descricao="Tipo_Teste" - ) + tipo_documento = baker.make(TipoDocumentoAdministrativo, descricao="Tipo_Teste") documento = baker.make( - DocumentoAdministrativo, - numero=20, - ano=2018, - data="2019-05-16", - tipo=tipo_documento + DocumentoAdministrativo, + numero=20, + ano=2018, + data="2019-05-16", + tipo=tipo_documento, ) unidade_tramitacao_local_1 = make_unidade_tramitacao(descricao="Teste 1") unidade_tramitacao_destino_1 = make_unidade_tramitacao(descricao="Teste 2") - status = baker.make( - StatusTramitacaoAdministrativo, - indicador='R') + status = baker.make(StatusTramitacaoAdministrativo, indicador="R") # Form sem campos obrigatórios documentos = [] - form = TramitacaoEmLoteAdmForm(initial={'documentos': documentos}, data={}) + form = TramitacaoEmLoteAdmForm(initial={"documentos": documentos}, data={}) errors = form.errors - assert errors['data_tramitacao'] == ['Este campo é obrigatório.'] - assert errors['unidade_tramitacao_local'] == ['Este campo é obrigatório.'] - assert errors['status'] == ['Este campo é obrigatório.'] - assert errors['unidade_tramitacao_destino'] == ['Este campo é obrigatório.'] - assert errors['texto'] == ['Este campo é obrigatório.'] + assert errors["data_tramitacao"] == ["Este campo é obrigatório."] + assert errors["unidade_tramitacao_local"] == ["Este campo é obrigatório."] + assert errors["status"] == ["Este campo é obrigatório."] + assert errors["unidade_tramitacao_destino"] == ["Este campo é obrigatório."] + assert errors["texto"] == ["Este campo é obrigatório."] assert not form.is_valid() # Tramitar apenas um documento sem anexados documentos = [documento.id] now = timezone.now().date() - form = TramitacaoEmLoteAdmForm(initial={'documentos': documentos}, data={}) - form.data = {'data_tramitacao': now + timedelta(days=5), - 'unidade_tramitacao_local': unidade_tramitacao_local_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa'} - - assert form.errors['__all__'] == \ - ["A data de tramitação deve ser menor ou igual a data de hoje!"] + form = TramitacaoEmLoteAdmForm(initial={"documentos": documentos}, data={}) + form.data = { + "data_tramitacao": now + timedelta(days=5), + "unidade_tramitacao_local": unidade_tramitacao_local_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + } + + assert form.errors["__all__"] == [ + "A data de tramitação deve ser menor ou igual a data de hoje!" + ] assert not form.is_valid() - form = TramitacaoEmLoteAdmForm(initial={'documentos': documentos}, data={}) - form.data = {'data_tramitacao': '2019-05-14', - 'data_encaminhamento' : '2019-05-09', - 'unidade_tramitacao_local': unidade_tramitacao_local_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa'} - - assert form.errors['__all__'] == \ - ["A data de encaminhamento deve ser maior que a data de tramitação!"] + form = TramitacaoEmLoteAdmForm(initial={"documentos": documentos}, data={}) + form.data = { + "data_tramitacao": "2019-05-14", + "data_encaminhamento": "2019-05-09", + "unidade_tramitacao_local": unidade_tramitacao_local_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + } + + assert form.errors["__all__"] == [ + "A data de encaminhamento deve ser maior que a data de tramitação!" + ] assert not form.is_valid() - form = TramitacaoEmLoteAdmForm(initial={'documentos': documentos}, data={}) - form.data = {'data_tramitacao': '2019-05-14', - 'data_encaminhamento' : '2019-05-15', - 'data_fim_prazo': '2019-05-09', - 'unidade_tramitacao_local': unidade_tramitacao_local_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa'} - - assert form.errors['__all__'] == \ - ["A data fim de prazo deve ser maior que a data de tramitação!"] + form = TramitacaoEmLoteAdmForm(initial={"documentos": documentos}, data={}) + form.data = { + "data_tramitacao": "2019-05-14", + "data_encaminhamento": "2019-05-15", + "data_fim_prazo": "2019-05-09", + "unidade_tramitacao_local": unidade_tramitacao_local_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + } + + assert form.errors["__all__"] == [ + "A data fim de prazo deve ser maior que a data de tramitação!" + ] assert not form.is_valid() - form = TramitacaoEmLoteAdmForm(initial={'documentos': documentos}, data={}) - form.data = {'data_tramitacao': '2019-05-14', - 'data_encaminhamento' : '2019-05-15', - 'data_fim_prazo': '2019-05-18', - 'unidade_tramitacao_local': unidade_tramitacao_local_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa'} + form = TramitacaoEmLoteAdmForm(initial={"documentos": documentos}, data={}) + form.data = { + "data_tramitacao": "2019-05-14", + "data_encaminhamento": "2019-05-15", + "data_fim_prazo": "2019-05-18", + "unidade_tramitacao_local": unidade_tramitacao_local_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + } assert form.is_valid() @@ -901,51 +1004,48 @@ def test_tramitacao_lote_documentos_form(admin_client): def test_tramitacao_lote_documentos_views(admin_client): config = baker.make(AppConfig, tramitacao_documento=True) - tipo_documento = baker.make( - TipoDocumentoAdministrativo, - descricao="Tipo_Teste" - ) + tipo_documento = baker.make(TipoDocumentoAdministrativo, descricao="Tipo_Teste") documento_principal = baker.make( - DocumentoAdministrativo, - numero=20, - ano=2018, - data="2018-01-04", - tipo=tipo_documento + DocumentoAdministrativo, + numero=20, + ano=2018, + data="2018-01-04", + tipo=tipo_documento, ) documento_anexado = baker.make( - DocumentoAdministrativo, - numero=21, - ano=2019, - data="2019-05-04", - tipo=tipo_documento + DocumentoAdministrativo, + numero=21, + ano=2019, + data="2019-05-04", + tipo=tipo_documento, ) documento_anexado_anexado = baker.make( - DocumentoAdministrativo, - numero=22, - ano=2020, - data="2020-01-05", - tipo=tipo_documento + DocumentoAdministrativo, + numero=22, + ano=2020, + data="2020-01-05", + tipo=tipo_documento, ) documento_sem_anexados = baker.make( - DocumentoAdministrativo, - numero=23, - ano=2020, - data="2021-01-05", - tipo=tipo_documento + DocumentoAdministrativo, + numero=23, + ano=2020, + data="2021-01-05", + tipo=tipo_documento, ) baker.make( - Anexado, - documento_principal=documento_principal, - documento_anexado=documento_anexado, - data_anexacao="2019-05-11" + Anexado, + documento_principal=documento_principal, + documento_anexado=documento_anexado, + data_anexacao="2019-05-11", ) baker.make( - Anexado, - documento_principal=documento_anexado, - documento_anexado=documento_anexado_anexado, - data_anexacao="2020-11-05" + Anexado, + documento_principal=documento_anexado, + documento_anexado=documento_anexado_anexado, + data_anexacao="2020-11-05", ) unidade_tramitacao_local_1 = make_unidade_tramitacao(descricao="Teste 1") @@ -953,44 +1053,48 @@ def test_tramitacao_lote_documentos_views(admin_client): unidade_tramitacao_destino_2 = make_unidade_tramitacao(descricao="Teste 3") unidade_tramitacao_destino_3 = make_unidade_tramitacao(descricao="Teste 4") - status = baker.make( - StatusTramitacaoAdministrativo, - indicador='R') + status = baker.make(StatusTramitacaoAdministrativo, indicador="R") - url = reverse('sapl.protocoloadm:primeira_tramitacao_em_lote_docadm') - url = url + '?' + urlencode({'tipo':tipo_documento.id, 'data_0':'', 'data_1':''}) + url = reverse("sapl.protocoloadm:primeira_tramitacao_em_lote_docadm") + url = url + "?" + urlencode({"tipo": tipo_documento.id, "data_0": "", "data_1": ""}) - response = admin_client.post(url, {'salvar':'salvar'}, follow=True) + response = admin_client.post(url, {"salvar": "salvar"}, follow=True) assert response.status_code == 200 - msgs = [m.message for m in response.context['messages']] + msgs = [m.message for m in response.context["messages"]] assert len(msgs) == 1 - assert msgs[0] == 'Escolha algum Documento para ser tramitado.' + assert msgs[0] == "Escolha algum Documento para ser tramitado." documentos = [documento_sem_anexados.id, documento_anexado_anexado.id] - response = admin_client.post(url, {'documentos': documentos,'salvar':'salvar'}, follow=True) - msgs = [m.message for m in response.context['messages']] + response = admin_client.post( + url, {"documentos": documentos, "salvar": "salvar"}, follow=True + ) + msgs = [m.message for m in response.context["messages"]] - assert 'Data Tramitação: Este campo é obrigatório.' in msgs - assert 'Unidade Local: Este campo é obrigatório.' in msgs - assert 'Status: Este campo é obrigatório.' in msgs - assert 'Unidade Destino: Este campo é obrigatório.' in msgs - assert 'Texto da Ação: Este campo é obrigatório.' in msgs + assert "Data Tramitação: Este campo é obrigatório." in msgs + assert "Unidade Local: Este campo é obrigatório." in msgs + assert "Status: Este campo é obrigatório." in msgs + assert "Unidade Destino: Este campo é obrigatório." in msgs + assert "Texto da Ação: Este campo é obrigatório." in msgs # Primeira tramitação em lote - response = admin_client.post(url, - {'documentos': documentos, - 'data_tramitacao': date(2019, 5, 15), - 'unidade_tramitacao_local': unidade_tramitacao_local_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa', - 'salvar':'salvar'}, - follow=True) - + response = admin_client.post( + url, + { + "documentos": documentos, + "data_tramitacao": date(2019, 5, 15), + "unidade_tramitacao_local": unidade_tramitacao_local_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + "salvar": "salvar", + }, + follow=True, + ) + assert response.status_code == 200 assert TramitacaoAdministrativo.objects.all().count() == 2 @@ -999,49 +1103,62 @@ def test_tramitacao_lote_documentos_views(admin_client): # Segunda tramitação em lote - url_lote = reverse('sapl.protocoloadm:tramitacao_em_lote_docadm') - url_lote = url_lote + '?' + urlencode( - {'tipo':tipo_documento.id, - 'tramitacaoadministrativo__unidade_tramitacao_destino':unidade_tramitacao_destino_1.id, - 'tramitacaoadministrativo__status': status.id, - 'data_0':'', - 'data_1':''}) + url_lote = reverse("sapl.protocoloadm:tramitacao_em_lote_docadm") + url_lote = ( + url_lote + + "?" + + urlencode( + { + "tipo": tipo_documento.id, + "tramitacaoadministrativo__unidade_tramitacao_destino": unidade_tramitacao_destino_1.id, + "tramitacaoadministrativo__status": status.id, + "data_0": "", + "data_1": "", + } + ) + ) - response = admin_client.post(url_lote, {'salvar':'salvar'}, follow=True) + response = admin_client.post(url_lote, {"salvar": "salvar"}, follow=True) assert response.status_code == 200 - assert response.context_data['object_list'].count() == 2 + assert response.context_data["object_list"].count() == 2 - msgs = [m.message for m in response.context['messages']] + msgs = [m.message for m in response.context["messages"]] assert len(msgs) == 1 - assert msgs[0] == 'Escolha algum Documento para ser tramitado.' + assert msgs[0] == "Escolha algum Documento para ser tramitado." - response = admin_client.post(url_lote, {'documentos':documentos, 'salvar':'salvar'}, follow=True) + response = admin_client.post( + url_lote, {"documentos": documentos, "salvar": "salvar"}, follow=True + ) assert response.status_code == 200 - msgs = [m.message for m in response.context['messages']] - - assert 'Data Tramitação: Este campo é obrigatório.' in msgs - assert 'Unidade Local: Este campo é obrigatório.' in msgs - assert 'Status: Este campo é obrigatório.' in msgs - assert 'Unidade Destino: Este campo é obrigatório.' in msgs - assert 'Texto da Ação: Este campo é obrigatório.' in msgs - - response = admin_client.post(url_lote, - {'documentos': documentos, - 'data_tramitacao': date(2019, 5, 15), - 'unidade_tramitacao_local': unidade_tramitacao_destino_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa', - 'salvar':'salvar'}, - follow=True) + msgs = [m.message for m in response.context["messages"]] + + assert "Data Tramitação: Este campo é obrigatório." in msgs + assert "Unidade Local: Este campo é obrigatório." in msgs + assert "Status: Este campo é obrigatório." in msgs + assert "Unidade Destino: Este campo é obrigatório." in msgs + assert "Texto da Ação: Este campo é obrigatório." in msgs + + response = admin_client.post( + url_lote, + { + "documentos": documentos, + "data_tramitacao": date(2019, 5, 15), + "unidade_tramitacao_local": unidade_tramitacao_destino_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 - msgs = [m.message for m in response.context['messages']] + msgs = [m.message for m in response.context["messages"]] - assert 'Tramitação completa.' in msgs + assert "Tramitação completa." in msgs assert TramitacaoAdministrativo.objects.all().count() == 4 assert documento_sem_anexados.tramitacaoadministrativo_set.all().count() == 2 @@ -1051,17 +1168,21 @@ def test_tramitacao_lote_documentos_views(admin_client): # O documento anexado ao anexado não deve tramitar junto porque já está com tramitação diferente documentos = [documento_principal.id] - response = admin_client.post(url, - {'documentos': documentos, - 'data_tramitacao': date(2019, 5, 15), - 'unidade_tramitacao_local': unidade_tramitacao_local_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa', - 'salvar':'salvar'}, - follow=True) - + response = admin_client.post( + url, + { + "documentos": documentos, + "data_tramitacao": date(2019, 5, 15), + "unidade_tramitacao_local": unidade_tramitacao_local_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + "salvar": "salvar", + }, + follow=True, + ) + assert response.status_code == 200 assert TramitacaoAdministrativo.objects.all().count() == 6 @@ -1069,52 +1190,59 @@ def test_tramitacao_lote_documentos_views(admin_client): assert documento_anexado.tramitacaoadministrativo_set.all().count() == 1 # Segunda tramitação com documentos anexados - response = admin_client.post(url_lote, - {'documentos': documentos, - 'data_tramitacao': date(2019, 5, 15), - 'unidade_tramitacao_local': unidade_tramitacao_destino_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa', - 'salvar':'salvar'}, - follow=True) + response = admin_client.post( + url_lote, + { + "documentos": documentos, + "data_tramitacao": date(2019, 5, 15), + "unidade_tramitacao_local": unidade_tramitacao_destino_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 - msgs = [m.message for m in response.context['messages']] + msgs = [m.message for m in response.context["messages"]] - assert 'Tramitação completa.' in msgs + assert "Tramitação completa." in msgs assert TramitacaoAdministrativo.objects.all().count() == 8 assert documento_principal.tramitacaoadministrativo_set.all().count() == 2 assert documento_anexado.tramitacaoadministrativo_set.all().count() == 2 # Terceira tramitação em lote - # Agora, o documento anexado ao anexado deve tramitar junto com o documento principal, + # Agora, o documento anexado ao anexado deve tramitar junto com o documento principal, # pois suas tramitações convergiram - response = admin_client.post(url_lote, - {'documentos': documentos, - 'data_tramitacao': date(2019, 5, 15), - 'unidade_tramitacao_local': unidade_tramitacao_destino_2.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_3.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa', - 'salvar':'salvar'}, - follow=True) + response = admin_client.post( + url_lote, + { + "documentos": documentos, + "data_tramitacao": date(2019, 5, 15), + "unidade_tramitacao_local": unidade_tramitacao_destino_2.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_3.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 - msgs = [m.message for m in response.context['messages']] + msgs = [m.message for m in response.context["messages"]] - assert 'Tramitação completa.' in msgs + assert "Tramitação completa." in msgs assert TramitacaoAdministrativo.objects.all().count() == 11 assert documento_principal.tramitacaoadministrativo_set.all().count() == 3 assert documento_anexado.tramitacaoadministrativo_set.all().count() == 3 assert documento_anexado_anexado.tramitacaoadministrativo_set.all().count() == 3 - # Agora testando para caso não seja desejado tramitar os documentos anexados # junto com os documentos principais config.tramitacao_documento = False @@ -1128,17 +1256,21 @@ def test_tramitacao_lote_documentos_views(admin_client): # O documento anexado não deve tramitar junto com o prinicpal documentos = [documento_principal.id] - response = admin_client.post(url, - {'documentos': documentos, - 'data_tramitacao': date(2019, 5, 15), - 'unidade_tramitacao_local': unidade_tramitacao_local_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa', - 'salvar':'salvar'}, - follow=True) - + response = admin_client.post( + url, + { + "documentos": documentos, + "data_tramitacao": date(2019, 5, 15), + "unidade_tramitacao_local": unidade_tramitacao_local_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + "salvar": "salvar", + }, + follow=True, + ) + assert response.status_code == 200 assert TramitacaoAdministrativo.objects.all().count() == 1 @@ -1149,17 +1281,21 @@ def test_tramitacao_lote_documentos_views(admin_client): # Tramitar o doc anexado ao principal para testar a segunda tramitação em lote documentos = [documento_anexado.id] - response = admin_client.post(url, - {'documentos': documentos, - 'data_tramitacao': date(2019, 5, 15), - 'unidade_tramitacao_local': unidade_tramitacao_local_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_1.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa', - 'salvar':'salvar'}, - follow=True) - + response = admin_client.post( + url, + { + "documentos": documentos, + "data_tramitacao": date(2019, 5, 15), + "unidade_tramitacao_local": unidade_tramitacao_local_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_1.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + "salvar": "salvar", + }, + follow=True, + ) + assert response.status_code == 200 assert TramitacaoAdministrativo.objects.all().count() == 2 @@ -1173,23 +1309,27 @@ def test_tramitacao_lote_documentos_views(admin_client): documentos = [documento_principal.id] # Segunda tramitação, o documento anexado não deve tramitar com o principal - response = admin_client.post(url_lote, - {'documentos': documentos, - 'data_tramitacao': date(2019, 5, 15), - 'unidade_tramitacao_local': unidade_tramitacao_destino_1.id, - 'unidade_tramitacao_destino': unidade_tramitacao_destino_2.id, - 'status': status.id, - 'urgente': False, - 'texto': 'aaaa', - 'salvar':'salvar'}, - follow=True) + response = admin_client.post( + url_lote, + { + "documentos": documentos, + "data_tramitacao": date(2019, 5, 15), + "unidade_tramitacao_local": unidade_tramitacao_destino_1.id, + "unidade_tramitacao_destino": unidade_tramitacao_destino_2.id, + "status": status.id, + "urgente": False, + "texto": "aaaa", + "salvar": "salvar", + }, + follow=True, + ) assert response.status_code == 200 - msgs = [m.message for m in response.context['messages']] + msgs = [m.message for m in response.context["messages"]] - assert 'Tramitação completa.' in msgs + assert "Tramitação completa." in msgs assert TramitacaoAdministrativo.objects.all().count() == 3 assert documento_principal.tramitacaoadministrativo_set.all().count() == 2 assert documento_anexado.tramitacaoadministrativo_set.all().count() == 1 - assert documento_anexado_anexado.tramitacaoadministrativo_set.all().count() == 0 \ No newline at end of file + assert documento_anexado_anexado.tramitacaoadministrativo_set.all().count() == 0 diff --git a/sapl/protocoloadm/urls.py b/sapl/protocoloadm/urls.py index 458c7d321..af69e0259 100644 --- a/sapl/protocoloadm/urls.py +++ b/sapl/protocoloadm/urls.py @@ -1,134 +1,180 @@ from django.urls import include, path, re_path -from sapl.protocoloadm.views import (AcompanhamentoDocumentoView, - AcompanhamentoConfirmarView, - AcompanhamentoExcluirView, +from sapl.protocoloadm.views import (AcompanhamentoConfirmarView, + AcompanhamentoDocumentoView, + AcompanhamentoExcluirView, AnexadoCrud, AnularProtocoloAdmView, ComprovanteProtocoloView, CriarDocumentoProtocolo, + DesvincularDocumentoView, + DesvincularMateriaView, DocumentoAcessorioAdministrativoCrud, DocumentoAdministrativoCrud, + DocumentoAnexadoEmLoteView, PesquisarDocumentoAdministrativoView, + PrimeiraTramitacaoEmLoteAdmView, ProtocoloDocumentoView, ProtocoloMateriaTemplateView, ProtocoloMateriaView, ProtocoloMostrarView, ProtocoloPesquisaView, StatusTramitacaoAdministrativoCrud, - recuperar_materia_protocolo, TipoDocumentoAdministrativoCrud, TramitacaoAdmCrud, - atualizar_numero_documento, - doc_texto_integral, - DesvincularDocumentoView, - DesvincularMateriaView, - AnexadoCrud, DocumentoAnexadoEmLoteView, - PrimeiraTramitacaoEmLoteAdmView, TramitacaoEmLoteAdmView, - apaga_protocolos_view, VinculoDocAdminMateriaCrud, VinculoDocAdminMateriaEmLoteView, - get_pdf_docacessorios) + apaga_protocolos_view, + atualizar_numero_documento, + doc_texto_integral, get_pdf_docacessorios, + recuperar_materia_protocolo) from .apps import AppConfig app_name = AppConfig.name urlpatterns_documento_administrativo = [ - path('docadm/', - include(DocumentoAdministrativoCrud.get_urls() + - AnexadoCrud.get_urls() + - TramitacaoAdmCrud.get_urls() + - DocumentoAcessorioAdministrativoCrud.get_urls() + - VinculoDocAdminMateriaCrud.get_urls())), - - re_path(r'^docadm/pesq-doc-adm', - PesquisarDocumentoAdministrativoView.as_view(), name='pesq_doc_adm'), - - path('docadm/texto_integral/', doc_texto_integral, - name='doc_texto_integral'), - - re_path(r'^docadm/(?P\d+)/anexado_em_lote', DocumentoAnexadoEmLoteView.as_view(), - name='anexado_em_lote'), - re_path(r'^docadm/(?P\d+)/vinculo-em-lote', VinculoDocAdminMateriaEmLoteView.as_view(), - name='vinculodocadminmateria_em_lote'), - path('docadm/documentoacessorioadministrativo/pdf/', get_pdf_docacessorios, - name='merge_docacessorios') + path( + "docadm/", + include( + DocumentoAdministrativoCrud.get_urls() + + AnexadoCrud.get_urls() + + TramitacaoAdmCrud.get_urls() + + DocumentoAcessorioAdministrativoCrud.get_urls() + + VinculoDocAdminMateriaCrud.get_urls() + ), + ), + re_path( + r"^docadm/pesq-doc-adm", + PesquisarDocumentoAdministrativoView.as_view(), + name="pesq_doc_adm", + ), + path( + "docadm/texto_integral/", doc_texto_integral, name="doc_texto_integral" + ), + re_path( + r"^docadm/(?P\d+)/anexado_em_lote", + DocumentoAnexadoEmLoteView.as_view(), + name="anexado_em_lote", + ), + re_path( + r"^docadm/(?P\d+)/vinculo-em-lote", + VinculoDocAdminMateriaEmLoteView.as_view(), + name="vinculodocadminmateria_em_lote", + ), + path( + "docadm/documentoacessorioadministrativo/pdf/", + get_pdf_docacessorios, + name="merge_docacessorios", + ), ] urlpatterns_protocolo = [ - # url(r'^protocoloadm/protocolo-doc/', # include(ProtocoloDocumentoCrud.get_urls())), # url(r'^protocoloadm/protocolo-mat/', # include(ProtocoloMateriaCrud.get_urls()), name='protocolomat'), # url(r'^protocoloadm/protocolo-list$', # ProtocoloListView.as_view(), name='protocolo_list'), - - path('protocoloadm/', - ProtocoloPesquisaView.as_view(), name='protocolo'), - - re_path(r'^protocoloadm/protocolar-doc', - ProtocoloDocumentoView.as_view(), name='protocolar_doc'), - - - path('protocoloadm//protocolo-mostrar', - ProtocoloMostrarView.as_view(), name='protocolo_mostrar'), - - path('docadm//acompanhar-documento/', - AcompanhamentoDocumentoView.as_view(), name='acompanhar_documento'), - path('docadm//acompanhar-confirmar', + path("protocoloadm/", ProtocoloPesquisaView.as_view(), name="protocolo"), + re_path( + r"^protocoloadm/protocolar-doc", + ProtocoloDocumentoView.as_view(), + name="protocolar_doc", + ), + path( + "protocoloadm//protocolo-mostrar", + ProtocoloMostrarView.as_view(), + name="protocolo_mostrar", + ), + path( + "docadm//acompanhar-documento/", + AcompanhamentoDocumentoView.as_view(), + name="acompanhar_documento", + ), + path( + "docadm//acompanhar-confirmar", AcompanhamentoConfirmarView.as_view(), - name='acompanhar_confirmar'), - path('docadm//acompanhar-excluir', + name="acompanhar_confirmar", + ), + path( + "docadm//acompanhar-excluir", AcompanhamentoExcluirView.as_view(), - name='acompanhar_excluir'), - - - - path('protocoloadm//continuar', - ProtocoloMateriaTemplateView.as_view(), name='materia_continuar'), - - - re_path(r'^protocoloadm/anular-protocolo', - AnularProtocoloAdmView.as_view(), name='anular_protocolo'), - re_path(r'^protocoloadm/desvincular-documento', - DesvincularDocumentoView.as_view(), name='desvincular_documento'), - re_path(r'^protocoloadm/desvincular-materia', - DesvincularMateriaView.as_view(), name='desvincular_materia'), - re_path(r'^protocoloadm/protocolar-mat', - ProtocoloMateriaView.as_view(), name='protocolar_mat'), - - path('protocoloadm//comprovante', - ComprovanteProtocoloView.as_view(), name='comprovante_protocolo'), - path('protocoloadm//criar-documento', - CriarDocumentoProtocolo.as_view(), name='criar_documento'), - - path('protocoloadm/atualizar_numero_documento', - atualizar_numero_documento, name='atualizar_numero_documento'), - re_path(r'^protocoloadm/recuperar-materia', - recuperar_materia_protocolo, name='recuperar_materia_protocolo'), - - re_path(r'^protocoloadm/primeira-tramitacao-em-lote', + name="acompanhar_excluir", + ), + path( + "protocoloadm//continuar", + ProtocoloMateriaTemplateView.as_view(), + name="materia_continuar", + ), + re_path( + r"^protocoloadm/anular-protocolo", + AnularProtocoloAdmView.as_view(), + name="anular_protocolo", + ), + re_path( + r"^protocoloadm/desvincular-documento", + DesvincularDocumentoView.as_view(), + name="desvincular_documento", + ), + re_path( + r"^protocoloadm/desvincular-materia", + DesvincularMateriaView.as_view(), + name="desvincular_materia", + ), + re_path( + r"^protocoloadm/protocolar-mat", + ProtocoloMateriaView.as_view(), + name="protocolar_mat", + ), + path( + "protocoloadm//comprovante", + ComprovanteProtocoloView.as_view(), + name="comprovante_protocolo", + ), + path( + "protocoloadm//criar-documento", + CriarDocumentoProtocolo.as_view(), + name="criar_documento", + ), + path( + "protocoloadm/atualizar_numero_documento", + atualizar_numero_documento, + name="atualizar_numero_documento", + ), + re_path( + r"^protocoloadm/recuperar-materia", + recuperar_materia_protocolo, + name="recuperar_materia_protocolo", + ), + re_path( + r"^protocoloadm/primeira-tramitacao-em-lote", PrimeiraTramitacaoEmLoteAdmView.as_view(), - name='primeira_tramitacao_em_lote_docadm'), - - re_path(r'^protocoloadm/tramitacao-em-lote', TramitacaoEmLoteAdmView.as_view(), - name='tramitacao_em_lote_docadm'), - - re_path(r'^protocoloadm/apaga_protocolos', apaga_protocolos_view, - name='apaga_protocolos_view'), - - + name="primeira_tramitacao_em_lote_docadm", + ), + re_path( + r"^protocoloadm/tramitacao-em-lote", + TramitacaoEmLoteAdmView.as_view(), + name="tramitacao_em_lote_docadm", + ), + re_path( + r"^protocoloadm/apaga_protocolos", + apaga_protocolos_view, + name="apaga_protocolos_view", + ), ] urlpatterns_sistema = [ - path('sistema/tipo-documento-adm/', - include(TipoDocumentoAdministrativoCrud.get_urls())), - path('sistema/status-tramitacao-adm/', - include(StatusTramitacaoAdministrativoCrud.get_urls())), + path( + "sistema/tipo-documento-adm/", + include(TipoDocumentoAdministrativoCrud.get_urls()), + ), + path( + "sistema/status-tramitacao-adm/", + include(StatusTramitacaoAdministrativoCrud.get_urls()), + ), ] -urlpatterns = (urlpatterns_documento_administrativo + - urlpatterns_protocolo + - urlpatterns_sistema) +urlpatterns = ( + urlpatterns_documento_administrativo + urlpatterns_protocolo + urlpatterns_sistema +) diff --git a/sapl/protocoloadm/views.py b/sapl/protocoloadm/views.py index a42f36dd7..73b09c605 100755 --- a/sapl/protocoloadm/views.py +++ b/sapl/protocoloadm/views.py @@ -1,13 +1,12 @@ +import logging import os +import re import time from datetime import datetime -import logging from io import BytesIO from random import choice -import re from string import ascii_letters, digits -from PyPDF4 import PdfFileMerger from braces.views import FormValidMessageMixin from django.conf import settings from django.contrib import messages @@ -20,80 +19,96 @@ from django.db import transaction from django.db.models import Max, Q from django.http import Http404, HttpResponse, JsonResponse from django.http.response import HttpResponseRedirect -from django.shortcuts import redirect, get_object_or_404 -from django.shortcuts import render +from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils import timezone from django.utils.translation import gettext_lazy as _ -from django.views.generic import ListView, CreateView, UpdateView +from django.views.generic import CreateView, ListView, UpdateView from django.views.generic.base import RedirectView, TemplateView from django.views.generic.edit import FormView from django_filters.views import FilterView +from PyPDF4 import PdfFileMerger import sapl from sapl.base.email_utils import do_envia_email_confirmacao -from sapl.base.models import Autor, CasaLegislativa, AppConfig +from sapl.base.models import AppConfig, Autor, CasaLegislativa from sapl.comissoes.models import Comissao -from sapl.crud.base import (Crud, CrudAux, MasterDetailCrud, make_pagination, - RP_LIST, RP_DETAIL) -from sapl.materia.models import MateriaLegislativa, TipoMateriaLegislativa, UnidadeTramitacao +from sapl.crud.base import (RP_DETAIL, RP_LIST, Crud, CrudAux, + MasterDetailCrud, make_pagination) +from sapl.materia.models import (MateriaLegislativa, TipoMateriaLegislativa, + UnidadeTramitacao) from sapl.materia.views import gerar_pdf_impressos from sapl.parlamentares.models import Legislatura, Parlamentar -from sapl.protocoloadm.forms import VinculoDocAdminMateriaForm,\ - VinculoDocAdminMateriaEmLoteFilterSet -from sapl.protocoloadm.models import Protocolo, DocumentoAdministrativo,\ - VinculoDocAdminMateria +from sapl.protocoloadm.forms import (VinculoDocAdminMateriaEmLoteFilterSet, + VinculoDocAdminMateriaForm) +from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, + VinculoDocAdminMateria) from sapl.relatorios.views import relatorio_doc_administrativos -from sapl.utils import (create_barcode, get_base_url, get_client_ip, - get_mime_type_from_file_extension, lista_anexados, - show_results_filter_set, mail_service_configured, from_date_to_datetime_utc, - google_recaptcha_configured, get_tempfile_dir, MultiFormatOutputMixin) +from sapl.utils import (MultiFormatOutputMixin, create_barcode, + from_date_to_datetime_utc, get_base_url, get_client_ip, + get_mime_type_from_file_extension, get_tempfile_dir, + google_recaptcha_configured, lista_anexados, + mail_service_configured, show_results_filter_set) -from .forms import (AcompanhamentoDocumentoForm, AnexadoEmLoteFilterSet, AnexadoForm, - AnularProtocoloAdmForm, compara_tramitacoes_doc, +from ..settings import MEDIA_ROOT +from .forms import (AcompanhamentoDocumentoForm, AnexadoEmLoteFilterSet, + AnexadoForm, AnularProtocoloAdmForm, DesvincularDocumentoForm, DesvincularMateriaForm, - DocumentoAcessorioAdministrativoForm, DocumentoAdministrativoFilterSet, - DocumentoAdministrativoForm, FichaPesquisaAdmForm, FichaSelecionaAdmForm, - filtra_tramitacao_adm_destino, filtra_tramitacao_adm_destino_and_status, - filtra_tramitacao_adm_status, PrimeiraTramitacaoEmLoteAdmFilterSet, - ProtocoloDocumentoForm, ProtocoloFilterSet, ProtocoloMateriaForm, - TramitacaoAdmEditForm, TramitacaoAdmForm, TramitacaoEmLoteAdmForm, - TramitacaoEmLoteAdmFilterSet) -from .models import (Anexado, AcompanhamentoDocumento, DocumentoAcessorioAdministrativo, - DocumentoAdministrativo, StatusTramitacaoAdministrativo, + DocumentoAcessorioAdministrativoForm, + DocumentoAdministrativoFilterSet, + DocumentoAdministrativoForm, FichaPesquisaAdmForm, + FichaSelecionaAdmForm, + PrimeiraTramitacaoEmLoteAdmFilterSet, + ProtocoloDocumentoForm, ProtocoloFilterSet, + ProtocoloMateriaForm, TramitacaoAdmEditForm, + TramitacaoAdmForm, TramitacaoEmLoteAdmFilterSet, + TramitacaoEmLoteAdmForm, compara_tramitacoes_doc, + filtra_tramitacao_adm_destino, + filtra_tramitacao_adm_destino_and_status, + filtra_tramitacao_adm_status) +from .models import (AcompanhamentoDocumento, Anexado, + DocumentoAcessorioAdministrativo, DocumentoAdministrativo, + StatusTramitacaoAdministrativo, TipoDocumentoAdministrativo, TramitacaoAdministrativo) -from ..settings import MEDIA_ROOT -TipoDocumentoAdministrativoCrud = CrudAux.build( - TipoDocumentoAdministrativo, '') +TipoDocumentoAdministrativoCrud = CrudAux.build(TipoDocumentoAdministrativo, "") # ProtocoloDocumentoCrud = Crud.build(Protocolo, '') # FIXME precisa de uma chave diferente para o layout # ProtocoloMateriaCrud = Crud.build(Protocolo, '') -@permission_required('protocoloadm.add_protocolo') + +@permission_required("protocoloadm.add_protocolo") def recuperar_materia_protocolo(request): - tipo = request.GET.get('tipo') - ano = request.GET.get('ano') - numero = request.GET.get('numero') + tipo = request.GET.get("tipo") + ano = request.GET.get("ano") + numero = request.GET.get("numero") logger = logging.getLogger(__name__) username = request.user.username try: - logger.debug("user=" + username + - ". Tentando obter matéria com tipo={}, ano={} e numero={}.".format(tipo, ano, numero)) - materia = MateriaLegislativa.objects.get( - tipo=tipo, ano=ano, numero=numero) + logger.debug( + "user=" + + username + + ". Tentando obter matéria com tipo={}, ano={} e numero={}.".format( + tipo, ano, numero + ) + ) + materia = MateriaLegislativa.objects.get(tipo=tipo, ano=ano, numero=numero) autoria = materia.autoria_set.first() - content = {'ementa': materia.ementa.strip(), - 'ano': materia.ano, 'numero': materia.numero} + content = { + "ementa": materia.ementa.strip(), + "ano": materia.ano, + "numero": materia.numero, + } if autoria: - content.update({'autor': autoria.autor.pk, - 'tipo_autor': autoria.autor.tipo.pk}) + content.update( + {"autor": autoria.autor.pk, "tipo_autor": autoria.autor.tipo.pk} + ) response = JsonResponse(content) except Exception as e: logger.error("user=" + username + ". " + str(e)) - response = JsonResponse({'error': e}) + response = JsonResponse({"error": e}) return response @@ -102,7 +117,7 @@ def doc_texto_integral(request, pk): if not request.user.is_authenticated: app_config = AppConfig.objects.last() - if app_config and app_config.documentos_administrativos == 'R': + if app_config and app_config.documentos_administrativos == "R": can_see = False if can_see: @@ -112,12 +127,13 @@ def doc_texto_integral(request, pk): mime = get_mime_type_from_file_extension(arquivo.name) - with open(arquivo.path, 'rb') as f: + with open(arquivo.path, "rb") as f: data = f.read() - response = HttpResponse(data, content_type='%s' % mime) - response['Content-Disposition'] = ( - 'inline; filename="%s"' % arquivo.name.split('/')[-1]) + response = HttpResponse(data, content_type="%s" % mime) + response["Content-Disposition"] = ( + 'inline; filename="%s"' % arquivo.name.split("/")[-1] + ) return response raise Http404 @@ -125,54 +141,64 @@ def doc_texto_integral(request, pk): def get_pdf_docacessorios(request, pk): documento_administrativo = get_object_or_404(DocumentoAdministrativo, pk=pk) logger = logging.getLogger(__name__) - username = 'Usuário anônimo' if request.user.is_anonymous else request.user.username + username = "Usuário anônimo" if request.user.is_anonymous else request.user.username try: external_name, data = create_pdf_docacessorios(documento_administrativo) logger.info( - "user= {}. Gerou o pdf compilado de documento acessorios".format(username)) + "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.') + msg = _("Não há arquivos cadastrados nesses documentos acessórios.") messages.add_message(request, messages.ERROR, msg) - return redirect(reverse('sapl.materia:documentoacessorio_list', - kwargs={'pk': pk})) + return redirect( + reverse("sapl.materia:documentoacessorio_list", kwargs={"pk": pk}) + ) except Exception as e: - logger.error("user= {}.Um erro inesperado ocorreu na criação do pdf de documentos acessorios: {}" - .format(username, str(e))) - msg = _('Um erro inesperado ocorreu. Entre em contato com o suporte do SAPL.') + logger.error( + "user= {}.Um erro inesperado ocorreu na criação do pdf de documentos acessorios: {}".format( + username, str(e) + ) + ) + msg = _("Um erro inesperado ocorreu. Entre em contato com o suporte do SAPL.") messages.add_message(request, messages.ERROR, msg) - return redirect(reverse('sapl.materia:documentoacessorio_list', - kwargs={'pk': pk})) + return redirect( + reverse("sapl.materia:documentoacessorio_list", kwargs={"pk": pk}) + ) if not data: - msg = _('Não há nenhum documento acessório PDF cadastrado.') + msg = _("Não há nenhum documento acessório PDF cadastrado.") messages.add_message(request, messages.ERROR, msg) - return redirect(reverse('sapl.materia:documentoacessorio_list', - kwargs={'pk': pk})) + return redirect( + reverse("sapl.materia:documentoacessorio_list", kwargs={"pk": pk}) + ) - response = HttpResponse(data, content_type='application/pdf') - response['Content-Disposition'] = ('attachment; filename="%s"' - % external_name) + response = HttpResponse(data, content_type="application/pdf") + response["Content-Disposition"] = 'attachment; filename="%s"' % external_name return response def create_pdf_docacessorios(docadministrativo): """ - Creates a unified in memory PDF file + Creates a unified in memory PDF file """ logger = logging.getLogger(__name__) - docs = docadministrativo.documentoacessorioadministrativo_set. \ - all().values_list('arquivo', flat=True) + docs = docadministrativo.documentoacessorioadministrativo_set.all().values_list( + "arquivo", flat=True + ) if not docs: return None, None - docs_path = [os.path.join(MEDIA_ROOT, i) - for i in docs if i.lower().endswith('pdf')] + docs_path = [os.path.join(MEDIA_ROOT, i) for i in docs if i.lower().endswith("pdf")] if not docs_path: raise FileNotFoundError( - "Não há arquivos PDF cadastrados em documentos acessorios.") - logger.info("Gerando compilado PDF de documentos acessorios com {} documentos" - .format(docs_path)) + "Não há arquivos PDF cadastrados em documentos acessorios." + ) + logger.info( + "Gerando compilado PDF de documentos acessorios com {} documentos".format( + docs_path + ) + ) merger = PdfFileMerger(strict=False) for f in docs_path: @@ -183,36 +209,44 @@ def create_pdf_docacessorios(docadministrativo): merger.close() external_name = "docadm_{}_{}_docacessorios.pdf".format( - docadministrativo.numero, docadministrativo.ano) + docadministrativo.numero, docadministrativo.ano + ) return external_name, data.getvalue() class AcompanhamentoConfirmarView(TemplateView): - logger = logging.getLogger(__name__) def get_redirect_url(self, email): username = self.request.user.username self.logger.info( - 'user=' + username + '. Este documento está sendo acompanhado pelo e-mail: {}'.format(email)) - msg = _('Este documento está sendo acompanhado pelo e-mail: %s') % ( - email) + "user=" + + username + + ". Este documento está sendo acompanhado pelo e-mail: {}".format(email) + ) + msg = _("Este documento está sendo acompanhado pelo e-mail: %s") % (email) messages.add_message(self.request, messages.SUCCESS, msg) - return reverse('sapl.protocoloadm:documentoadministrativo_detail', - kwargs={'pk': self.kwargs['pk']}) + return reverse( + "sapl.protocoloadm:documentoadministrativo_detail", + kwargs={"pk": self.kwargs["pk"]}, + ) def get(self, request, *args, **kwargs): - - documento_id = kwargs['pk'] - hash_txt = request.GET.get('hash_txt', '') + documento_id = kwargs["pk"] + hash_txt = request.GET.get("hash_txt", "") username = request.user.username try: - self.logger.debug("user=" + username + ". Tentando obter objeto AcompanhamentoDocumento com documento_id={} e hash={}" - .format(documento_id, hash_txt)) + self.logger.debug( + "user=" + + username + + ". Tentando obter objeto AcompanhamentoDocumento com documento_id={} e hash={}".format( + documento_id, hash_txt + ) + ) acompanhar = AcompanhamentoDocumento.objects.get( - documento_id=documento_id, - hash=hash_txt) + documento_id=documento_id, hash=hash_txt + ) except ObjectDoesNotExist as e: self.logger.error("user=" + username + ". " + str(e)) raise Http404() @@ -228,30 +262,47 @@ class AcompanhamentoConfirmarView(TemplateView): class AcompanhamentoExcluirView(TemplateView): - logger = logging.getLogger(__name__) def get_success_url(self): username = self.request.user.username self.logger.info( - "user=" + username + ". Você parou de acompanhar este Documento (pk={}).".format(self.kwargs['pk'])) - msg = _('Você parou de acompanhar este Documento.') + "user=" + + username + + ". Você parou de acompanhar este Documento (pk={}).".format( + self.kwargs["pk"] + ) + ) + msg = _("Você parou de acompanhar este Documento.") messages.add_message(self.request, messages.INFO, msg) - return reverse('sapl.protocoloadm:documentoadministrativo_detail', - kwargs={'pk': self.kwargs['pk']}) + return reverse( + "sapl.protocoloadm:documentoadministrativo_detail", + kwargs={"pk": self.kwargs["pk"]}, + ) def get(self, request, *args, **kwargs): - documento_id = kwargs['pk'] - hash_txt = request.GET.get('hash_txt', '') + documento_id = kwargs["pk"] + hash_txt = request.GET.get("hash_txt", "") username = request.user.username try: - self.logger.debug("user=" + username + ". Tentando obter AcompanhamentoDocumento com documento_id={} e hash={}." - .format(documento_id, hash_txt)) - AcompanhamentoDocumento.objects.get(documento_id=documento_id, - hash=hash_txt).delete() + self.logger.debug( + "user=" + + username + + ". Tentando obter AcompanhamentoDocumento com documento_id={} e hash={}.".format( + documento_id, hash_txt + ) + ) + AcompanhamentoDocumento.objects.get( + documento_id=documento_id, hash=hash_txt + ).delete() except ObjectDoesNotExist: - self.logger.error("user=" + username + ". AcompanhamentoDocumento com documento_id={} e hash={} não encontrado." - .format(documento_id, hash_txt)) + self.logger.error( + "user=" + + username + + ". AcompanhamentoDocumento com documento_id={} e hash={} não encontrado.".format( + documento_id, hash_txt + ) + ) return HttpResponseRedirect(self.get_success_url()) @@ -263,52 +314,56 @@ class AcompanhamentoDocumentoView(CreateView): def get_random_chars(self): s = ascii_letters + digits - return ''.join(choice(s) for i in range(choice([6, 7]))) + return "".join(choice(s) for i in range(choice([6, 7]))) def get(self, request, *args, **kwargs): if not mail_service_configured(): - self.logger.warning(_('Servidor de email não configurado.')) - messages.error(request, _('Serviço de Acompanhamento de ' - 'Documentos não foi configurado')) - return redirect('/') + self.logger.warning(_("Servidor de email não configurado.")) + messages.error( + request, + _("Serviço de Acompanhamento de " "Documentos não foi configurado"), + ) + return redirect("/") if not google_recaptcha_configured(): - self.logger.warning(_('Google Recaptcha não configurado!')) - messages.error(request, _('Google Recaptcha não configurado!')) - return redirect(request.headers.get('referer', '/')) + self.logger.warning(_("Google Recaptcha não configurado!")) + messages.error(request, _("Google Recaptcha não configurado!")) + return redirect(request.headers.get("referer", "/")) - pk = self.kwargs['pk'] + pk = self.kwargs["pk"] documento = DocumentoAdministrativo.objects.get(id=pk) return self.render_to_response( - {'form': AcompanhamentoDocumentoForm(), - 'documento': documento}) + {"form": AcompanhamentoDocumentoForm(), "documento": documento} + ) def post(self, request, *args, **kwargs): if not mail_service_configured(): - self.logger.warning(_('Servidor de email não configurado.')) - messages.error(request, _('Serviço de Acompanhamento de ' - 'Documentos não foi configurado')) - return redirect('/') + self.logger.warning(_("Servidor de email não configurado.")) + messages.error( + request, + _("Serviço de Acompanhamento de " "Documentos não foi configurado"), + ) + return redirect("/") if not google_recaptcha_configured(): - self.logger.warning(_('Google Recaptcha não configurado!')) - messages.error(request, _('Google Recaptcha não configurado!')) - return redirect(request.headers.get('referer', '/')) + self.logger.warning(_("Google Recaptcha não configurado!")) + messages.error(request, _("Google Recaptcha não configurado!")) + return redirect(request.headers.get("referer", "/")) form = AcompanhamentoDocumentoForm(request.POST) - pk = self.kwargs['pk'] + pk = self.kwargs["pk"] documento = DocumentoAdministrativo.objects.get(id=pk) if form.is_valid(): - email = form.cleaned_data['email'] + email = form.cleaned_data["email"] usuario = request.user hash_txt = self.get_random_chars() acompanhar = AcompanhamentoDocumento.objects.get_or_create( - documento=documento, - email=form.data['email']) + documento=documento, email=form.data["email"] + ) # Se o segundo elemento do retorno do get_or_create for True # quer dizer que o elemento não existia @@ -322,22 +377,25 @@ class AcompanhamentoDocumentoView(CreateView): base_url = get_base_url(request) destinatario = AcompanhamentoDocumento.objects.get( - documento=documento, - email=email, - confirmado=False) + documento=documento, email=email, confirmado=False + ) casa = CasaLegislativa.objects.first() - do_envia_email_confirmacao(base_url, - casa, - "documento", - documento, - destinatario) - self.logger.info('user={}. Foi enviado um e-mail de confirmação. Confira sua caixa ' - 'de mensagens e clique no link que nós enviamos para ' - 'confirmar o acompanhamento deste documento.'.format(usuario.username)) - msg = _('Foi enviado um e-mail de confirmação. Confira sua caixa \ + do_envia_email_confirmacao( + base_url, casa, "documento", documento, destinatario + ) + self.logger.info( + "user={}. Foi enviado um e-mail de confirmação. Confira sua caixa " + "de mensagens e clique no link que nós enviamos para " + "confirmar o acompanhamento deste documento.".format( + usuario.username + ) + ) + msg = _( + "Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ - confirmar o acompanhamento deste documento.') + confirmar o acompanhamento deste documento." + ) messages.add_message(request, messages.SUCCESS, msg) # Se o elemento existir e o email não foi confirmado: @@ -350,56 +408,64 @@ class AcompanhamentoDocumentoView(CreateView): base_url = get_base_url(request) destinatario = AcompanhamentoDocumento.objects.get( - documento=documento, - email=email, - confirmado=False + documento=documento, email=email, confirmado=False ) casa = CasaLegislativa.objects.first() - do_envia_email_confirmacao(base_url, - casa, - "documento", - documento, - destinatario) + do_envia_email_confirmacao( + base_url, casa, "documento", documento, destinatario + ) - self.logger.info('user={}. Foi enviado um e-mail de confirmação. Confira sua caixa \ + self.logger.info( + "user={}. Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ - confirmar o acompanhamento deste documento.'.format(usuario.username)) + confirmar o acompanhamento deste documento.".format( + usuario.username + ) + ) - msg = _('Foi enviado um e-mail de confirmação. Confira sua caixa \ + msg = _( + "Foi enviado um e-mail de confirmação. Confira sua caixa \ de mensagens e clique no link que nós enviamos para \ - confirmar o acompanhamento deste documento.') + confirmar o acompanhamento deste documento." + ) messages.add_message(request, messages.SUCCESS, msg) # Caso esse Acompanhamento já exista # avisa ao usuário que esse documento já está sendo acompanhado else: - self.logger.info('user=' + request.user.username + - '. Este e-mail já está acompanhando esse documento (pk={}).'.format(pk)) - msg = _('Este e-mail já está acompanhando esse documento.') + self.logger.info( + "user=" + + request.user.username + + ". Este e-mail já está acompanhando esse documento (pk={}).".format( + pk + ) + ) + msg = _("Este e-mail já está acompanhando esse documento.") messages.add_message(request, messages.ERROR, msg) return self.render_to_response( - {'form': form, - 'documento': documento, - }) + { + "form": form, + "documento": documento, + } + ) return HttpResponseRedirect(self.get_success_url()) else: - return self.render_to_response( - {'form': form, - 'documento': documento}) + return self.render_to_response({"form": form, "documento": documento}) def get_success_url(self): - return reverse('sapl.protocoloadm:documentoadministrativo_detail', - kwargs={'pk': self.kwargs['pk']}) + return reverse( + "sapl.protocoloadm:documentoadministrativo_detail", + kwargs={"pk": self.kwargs["pk"]}, + ) class DocumentoAdministrativoMixin: - def has_permission(self): app_config = AppConfig.objects.last() - if app_config and app_config.documentos_administrativos == 'O': + if app_config and app_config.documentos_administrativos == "O": return True return super().has_permission() @@ -407,25 +473,32 @@ class DocumentoAdministrativoMixin: class DocumentoAdministrativoCrud(Crud): model = DocumentoAdministrativo - help_topic = 'numeracao_docsacess' + help_topic = "numeracao_docsacess" class BaseMixin(Crud.BaseMixin): - list_field_names = ['tipo', 'numero', 'ano', 'data', - 'protocolo__numero', 'assunto', - 'interessado', 'tramitacao', 'texto_integral'] + list_field_names = [ + "tipo", + "numero", + "ano", + "data", + "protocolo__numero", + "assunto", + "interessado", + "tramitacao", + "texto_integral", + ] @property def search_url(self): namespace = self.model._meta.app_config.name - return reverse('%s:%s' % (namespace, 'pesq_doc_adm')) + return reverse("%s:%s" % (namespace, "pesq_doc_adm")) - list_url = '' + list_url = "" class ListView(RedirectView, DocumentoAdministrativoMixin, Crud.ListView): - def get_redirect_url(self, *args, **kwargs): namespace = self.model._meta.app_config.name - return reverse('%s:%s' % (namespace, 'pesq_doc_adm')) + return reverse("%s:%s" % (namespace, "pesq_doc_adm")) class CreateView(Crud.CreateView): form_class = DocumentoAdministrativoForm @@ -434,11 +507,12 @@ class DocumentoAdministrativoCrud(Crud): def get_initial(self): initial = super().get_initial() - initial['user'] = self.request.user - initial['ip'] = get_client_ip(self.request) + initial["user"] = self.request.user + initial["ip"] = get_client_ip(self.request) from django.utils import timezone - initial['ultima_edicao'] = timezone.now() + + initial["ultima_edicao"] = timezone.now() return initial @@ -448,7 +522,8 @@ class DocumentoAdministrativoCrud(Crud): def form_valid(self, form): form.instance.complemento = re.sub( - r'\s+', '', form.instance.complemento).upper() + r"\s+", "", form.instance.complemento + ).upper() return super().form_valid(form) class UpdateView(Crud.UpdateView): @@ -457,16 +532,27 @@ class DocumentoAdministrativoCrud(Crud): def form_valid(self, form): dict_objeto_antigo = DocumentoAdministrativo.objects.get( - pk=self.kwargs['pk'] + pk=self.kwargs["pk"] ).__dict__ self.object = form.save() dict_objeto_novo = self.object.__dict__ atributos = [ - 'tipo_id', 'ano', 'numero', 'data', 'protocolo_id', 'assunto', - 'interessado', 'tramitacao', 'restrito', 'texto_integral', 'numero_externo', - 'dias_prazo', 'data_fim_prazo', 'observacao' + "tipo_id", + "ano", + "numero", + "data", + "protocolo_id", + "assunto", + "interessado", + "tramitacao", + "restrito", + "texto_integral", + "numero_externo", + "dias_prazo", + "data_fim_prazo", + "observacao", ] for atributo in atributos: @@ -475,99 +561,96 @@ class DocumentoAdministrativoCrud(Crud): self.object.ip = get_client_ip(self.request) from django.utils import timezone + self.object.ultima_edicao = timezone.now() self.object.save() break form.instance.complemento = re.sub( - r'\s+', '', form.instance.complemento).upper() + r"\s+", "", form.instance.complemento + ).upper() return super().form_valid(form) def get_initial(self): if self.object.protocolo: p = self.object.protocolo - return {'ano_protocolo': p.ano, - 'numero_protocolo': p.numero} + return {"ano_protocolo": p.ano, "numero_protocolo": p.numero} class DetailView(DocumentoAdministrativoMixin, Crud.DetailView): - def get(self, *args, **kwargs): - pk = self.kwargs['pk'] + pk = self.kwargs["pk"] documento = DocumentoAdministrativo.objects.get(id=pk) if documento.restrito and self.request.user.is_anonymous: - return redirect('/') + return redirect("/") return super(Crud.DetailView, self).get(args, kwargs) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['user'] = self.request.user - context['documentoadministrativo'] = DocumentoAdministrativo.objects.get( - pk=self.kwargs['pk'] + context["user"] = self.request.user + context["documentoadministrativo"] = DocumentoAdministrativo.objects.get( + pk=self.kwargs["pk"] ) return context def urlize(self, obj, fieldname): a = '%s' % ( - reverse( - 'sapl.protocoloadm:doc_texto_integral', - kwargs={'pk': obj.pk}), - obj.texto_integral.name.split('/')[-1]) + reverse("sapl.protocoloadm:doc_texto_integral", kwargs={"pk": obj.pk}), + obj.texto_integral.name.split("/")[-1], + ) return obj.texto_integral.field.verbose_name, a class DeleteView(Crud.DeleteView): - def get_success_url(self): return self.search_url class StatusTramitacaoAdministrativoCrud(CrudAux): model = StatusTramitacaoAdministrativo - help_topic = 'status_tramitacao' + help_topic = "status_tramitacao" class BaseMixin(CrudAux.BaseMixin): - list_field_names = ['sigla', 'indicador', 'descricao'] + list_field_names = ["sigla", "indicador", "descricao"] class ListView(CrudAux.ListView): - ordering = 'sigla' + ordering = "sigla" class ProtocoloPesquisaView(PermissionRequiredMixin, FilterView): model = Protocolo filterset_class = ProtocoloFilterSet paginate_by = 10 - permission_required = ('protocoloadm.list_protocolo',) + permission_required = ("protocoloadm.list_protocolo",) def get_filterset_kwargs(self, filterset_class): - super(ProtocoloPesquisaView, - self).get_filterset_kwargs(filterset_class) + super(ProtocoloPesquisaView, self).get_filterset_kwargs(filterset_class) - kwargs = {'data': self.request.GET or None} + kwargs = {"data": self.request.GET or None} - qs = self.get_queryset().order_by('ano', 'numero').distinct() + qs = self.get_queryset().order_by("ano", "numero").distinct() - if 'o' in self.request.GET and not self.request.GET['o']: - qs = qs.order_by('-ano', '-numero') + if "o" in self.request.GET and not self.request.GET["o"]: + qs = qs.order_by("-ano", "-numero") - kwargs.update({ - 'queryset': qs, - }) + kwargs.update( + { + "queryset": qs, + } + ) return kwargs def get_context_data(self, **kwargs): - context = super(ProtocoloPesquisaView, - self).get_context_data(**kwargs) + context = super(ProtocoloPesquisaView, self).get_context_data(**kwargs) - paginator = context['paginator'] - page_obj = context['page_obj'] + paginator = context["paginator"] + page_obj = context["page_obj"] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) - context['title'] = _('Protocolo') + context["title"] = _("Protocolo") return context @@ -579,103 +662,100 @@ class ProtocoloPesquisaView(PermissionRequiredMixin, FilterView): # Provavelmente você criou um novo campo no Form/FilterSet # Então a ordem da URL está diferente data = self.filterset.data - if data and data.get('numero') is not None: - url = "&" + str(self.request.environ['QUERY_STRING']) + if data and data.get("numero") is not None: + url = "&" + str(self.request.environ["QUERY_STRING"]) if url.startswith("&page"): - ponto_comeco = url.find('numero=') - 1 + ponto_comeco = url.find("numero=") - 1 url = url[ponto_comeco:] else: - url = '' + url = "" - self.filterset.form.fields['o'].label = _('Ordenação') + self.filterset.form.fields["o"].label = _("Ordenação") - context = self.get_context_data(filter=self.filterset, - object_list=self.object_list, - filter_url=url, - numero_res=len(self.object_list) - ) + 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()) + context["show_results"] = show_results_filter_set(self.request.GET.copy()) return self.render_to_response(context) class ProtocoloListView(PermissionRequiredMixin, ListView): - template_name = 'protocoloadm/protocolo_list.html' - context_object_name = 'protocolos' + template_name = "protocoloadm/protocolo_list.html" + context_object_name = "protocolos" model = Protocolo paginate_by = 10 - permission_required = ('protocoloadm.list_protocolo',) + permission_required = ("protocoloadm.list_protocolo",) def get_queryset(self): - kwargs = self.request.session['kwargs'] - return Protocolo.objects.filter( - **kwargs) + kwargs = self.request.session["kwargs"] + return Protocolo.objects.filter(**kwargs) def get_context_data(self, **kwargs): - context = super(ProtocoloListView, self).get_context_data( - **kwargs) + context = super(ProtocoloListView, self).get_context_data(**kwargs) - paginator = context['paginator'] - page_obj = context['page_obj'] + paginator = context["paginator"] + page_obj = context["page_obj"] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + context["page_range"] = make_pagination(page_obj.number, paginator.num_pages) return context class AnularProtocoloAdmView(PermissionRequiredMixin, CreateView): - template_name = 'protocoloadm/anular_protocoloadm.html' + template_name = "protocoloadm/anular_protocoloadm.html" form_class = AnularProtocoloAdmForm - form_valid_message = _('Protocolo anulado com sucesso!') - permission_required = ('protocoloadm.action_anular_protocolo', ) + form_valid_message = _("Protocolo anulado com sucesso!") + permission_required = ("protocoloadm.action_anular_protocolo",) def get_success_url(self): - return reverse('sapl.protocoloadm:protocolo') + return reverse("sapl.protocoloadm:protocolo") def get_initial(self): initial_data = {} - initial_data['user_anulacao'] = self.request.user.username - initial_data['ip_anulacao'] = get_client_ip(self.request) + initial_data["user_anulacao"] = self.request.user.username + initial_data["ip_anulacao"] = get_client_ip(self.request) return initial_data def form_valid(self, form): - protocolo = Protocolo.objects.get(numero=form.cleaned_data['numero'], - ano=form.cleaned_data['ano']) + protocolo = Protocolo.objects.get( + numero=form.cleaned_data["numero"], ano=form.cleaned_data["ano"] + ) protocolo.anulado = True - protocolo.justificativa_anulacao = ( - form.cleaned_data['justificativa_anulacao']) - protocolo.user_anulacao = form.cleaned_data['user_anulacao'] - protocolo.ip_anulacao = form.cleaned_data['ip_anulacao'] + protocolo.justificativa_anulacao = form.cleaned_data["justificativa_anulacao"] + protocolo.user_anulacao = form.cleaned_data["user_anulacao"] + protocolo.ip_anulacao = form.cleaned_data["ip_anulacao"] protocolo.timestamp_anulacao = timezone.now() protocolo.save() return redirect(self.get_success_url()) -class ProtocoloDocumentoView(PermissionRequiredMixin, - FormValidMessageMixin, - CreateView): - +class ProtocoloDocumentoView( + PermissionRequiredMixin, FormValidMessageMixin, CreateView +): logger = logging.getLogger(__name__) template_name = "protocoloadm/protocolar_documento.html" form_class = ProtocoloDocumentoForm - form_valid_message = _('Protocolo cadastrado com sucesso!') - permission_required = ('protocoloadm.add_protocolo', ) + form_valid_message = _("Protocolo cadastrado com sucesso!") + permission_required = ("protocoloadm.add_protocolo",) def get_success_url(self): - return reverse('sapl.protocoloadm:protocolo_mostrar', - kwargs={'pk': self.object.id}) + return reverse( + "sapl.protocoloadm:protocolo_mostrar", kwargs={"pk": self.object.id} + ) def get_initial(self): initial = super().get_initial() - initial['user'] = self.request.user.username - initial['user_data_hora_manual'] = self.request.user.username - initial['ip_data_hora_manual'] = get_client_ip(self.request) - initial['data'] = timezone.localdate(timezone.now()) - initial['hora'] = timezone.localtime(timezone.now()) + initial["user"] = self.request.user.username + initial["user_data_hora_manual"] = self.request.user.username + initial["ip_data_hora_manual"] = get_client_ip(self.request) + initial["data"] = timezone.localdate(timezone.now()) + initial["hora"] = timezone.localtime(timezone.now()) return initial @transaction.atomic @@ -683,26 +763,29 @@ class ProtocoloDocumentoView(PermissionRequiredMixin, protocolo = form.save(commit=False) username = self.request.user.username - self.logger.debug("user=" + username + - ". Tentando obter sequência de numeração.") - numeracao = AppConfig.objects.last( - ).sequencia_numeracao_protocolo + self.logger.debug( + "user=" + username + ". Tentando obter sequência de numeração." + ) + numeracao = AppConfig.objects.last().sequencia_numeracao_protocolo if not numeracao: - self.logger.error("user=" + username + ". É preciso definir a sequencia de " - "numeração na tabelas auxiliares! ") - msg = _('É preciso definir a sequencia de ' + - 'numeração na tabelas auxiliares!') + self.logger.error( + "user=" + username + ". É preciso definir a sequencia de " + "numeração na tabelas auxiliares! " + ) + msg = _( + "É preciso definir a sequencia de " + "numeração na tabelas auxiliares!" + ) messages.add_message(self.request, messages.ERROR, msg) return self.render_to_response(self.get_context_data()) - if numeracao == 'A': + if numeracao == "A": numero_max = Protocolo.objects.filter(ano=timezone.now().year).aggregate( - Max('numero') - )['numero__max'] - elif numeracao == 'L': + Max("numero") + )["numero__max"] + elif numeracao == "L": legislatura = Legislatura.objects.filter( data_inicio__year__lte=timezone.now().year, - data_fim__year__gte=timezone.now().year + data_fim__year__gte=timezone.now().year, ).first() data_inicio = legislatura.data_inicio @@ -712,20 +795,22 @@ class ProtocoloDocumentoView(PermissionRequiredMixin, data_fim_utc = from_date_to_datetime_utc(data_fim) numero_max = Protocolo.objects.filter( - Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) | Q( - timestamp__isnull=False, timestamp__gte=data_inicio_utc, - timestamp__lte=data_fim_utc - ) | Q( + Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) + | Q( + timestamp__isnull=False, + timestamp__gte=data_inicio_utc, + timestamp__lte=data_fim_utc, + ) + | Q( timestamp_data_hora_manual__isnull=False, timestamp_data_hora_manual__gte=data_inicio_utc, timestamp_data_hora_manual__lte=data_fim_utc, ) - ).aggregate(Max('numero'))['numero__max'] - elif numeracao == 'U': - numero_max = Protocolo.objects.all().aggregate(Max('numero'))[ - 'numero__max'] + ).aggregate(Max("numero"))["numero__max"] + elif numeracao == "U": + numero_max = Protocolo.objects.all().aggregate(Max("numero"))["numero__max"] - protocolo.tipo_processo = '0' # TODO validar o significado + protocolo.tipo_processo = "0" # TODO validar o significado protocolo.anulado = False inicio_numeracao = AppConfig.objects.first().inicio_numeracao_protocolo @@ -735,18 +820,18 @@ class ProtocoloDocumentoView(PermissionRequiredMixin, ) protocolo.ano = timezone.now().year - protocolo.assunto_ementa = self.request.POST['assunto'] + protocolo.assunto_ementa = self.request.POST["assunto"] protocolo.user = self.request.user - if form.cleaned_data['data_hora_manual'] == 'True': + if form.cleaned_data["data_hora_manual"] == "True": protocolo.timestamp = None protocolo.user_data_hora_manual = username protocolo.ip_data_hora_manual = get_client_ip(self.request) else: protocolo.data = None protocolo.hora = None - protocolo.user_data_hora_manual = '' - protocolo.ip_data_hora_manual = '' + protocolo.user_data_hora_manual = "" + protocolo.ip_data_hora_manual = "" protocolo.save() self.object = protocolo @@ -756,38 +841,40 @@ class ProtocoloDocumentoView(PermissionRequiredMixin, class CriarDocumentoProtocolo(PermissionRequiredMixin, CreateView): template_name = "protocoloadm/criar_documento.html" form_class = DocumentoAdministrativoForm - permission_required = ('protocoloadm.add_documentoadministrativo',) + permission_required = ("protocoloadm.add_documentoadministrativo",) def get_initial(self): - protocolo = Protocolo.objects.get(pk=self.kwargs['pk']) + protocolo = Protocolo.objects.get(pk=self.kwargs["pk"]) return self.criar_documento(protocolo) def get_success_url(self): - return reverse('sapl.protocoloadm:protocolo_mostrar', - kwargs={'pk': self.kwargs['pk']}) + return reverse( + "sapl.protocoloadm:protocolo_mostrar", kwargs={"pk": self.kwargs["pk"]} + ) def criar_documento(self, protocolo): curr_year = timezone.now().year numero_max = DocumentoAdministrativo.objects.filter( tipo=protocolo.tipo_documento, ano=curr_year - ).aggregate(Max('numero'))['numero__max'] + ).aggregate(Max("numero"))["numero__max"] doc = {} - doc['tipo'] = protocolo.tipo_documento - doc['ano'] = curr_year - doc['data'] = timezone.now() - doc['numero_protocolo'] = protocolo.numero - doc['ano_protocolo'] = protocolo.ano - doc['protocolo'] = protocolo.id - doc['assunto'] = protocolo.assunto_ementa - doc['interessado'] = protocolo.interessado - doc['numero'] = numero_max + 1 if numero_max else 1 - doc['user'] = self.request.user - doc['ip'] = get_client_ip(self.request) + doc["tipo"] = protocolo.tipo_documento + doc["ano"] = curr_year + doc["data"] = timezone.now() + doc["numero_protocolo"] = protocolo.numero + doc["ano_protocolo"] = protocolo.ano + doc["protocolo"] = protocolo.id + doc["assunto"] = protocolo.assunto_ementa + doc["interessado"] = protocolo.interessado + doc["numero"] = numero_max + 1 if numero_max else 1 + doc["user"] = self.request.user + doc["ip"] = get_client_ip(self.request) from django.utils import timezone - doc['ultima_edicao'] = timezone.now() + + doc["ultima_edicao"] = timezone.now() return doc @@ -796,53 +883,59 @@ class ProtocoloMostrarView(PermissionRequiredMixin, TemplateView): logger = logging.getLogger(__name__) template_name = "protocoloadm/protocolo_mostrar.html" - permission_required = ('protocoloadm.detail_protocolo', ) + permission_required = ("protocoloadm.detail_protocolo",) def get_context_data(self, **kwargs): - context = super(ProtocoloMostrarView, self).get_context_data(**kwargs) - protocolo = Protocolo.objects.get(pk=self.kwargs['pk']) + protocolo = Protocolo.objects.get(pk=self.kwargs["pk"]) username = self.request.user.username if protocolo.tipo_materia: self.logger.debug( - "user=" + username + - ". Tentando obter objeto MateriaLegislativa com numero_protocolo={} e ano={}." - .format(protocolo.numero, protocolo.ano)) + "user=" + + username + + ". Tentando obter objeto MateriaLegislativa com numero_protocolo={} e ano={}.".format( + protocolo.numero, protocolo.ano + ) + ) materia = MateriaLegislativa.objects.filter( - numero_protocolo=protocolo.numero, ano=protocolo.ano) - context['materia'] = materia + numero_protocolo=protocolo.numero, ano=protocolo.ano + ) + context["materia"] = materia if len(materia) > 1: - msg = _('Foi encontrada mais de uma matéria com o mesmo número de protocolo e ano.' - ' Isso é um erro de uso!' - ' Reporte isso ao suporte para que seja corrigido.') + msg = _( + "Foi encontrada mais de uma matéria com o mesmo número de protocolo e ano." + " Isso é um erro de uso!" + " Reporte isso ao suporte para que seja corrigido." + ) messages.add_message(self.request, messages.ERROR, msg) self.logger.error( - "user=" + username + ". Objeto MateriaLegislativa com numero_protocolo={} e ano={}" - " encontrado mais de um registro." - " Erro relatado ao usuário.".format(protocolo.numero, protocolo.ano)) + "user=" + + username + + ". Objeto MateriaLegislativa com numero_protocolo={} e ano={}" + " encontrado mais de um registro." + " Erro relatado ao usuário.".format(protocolo.numero, protocolo.ano) + ) if protocolo.tipo_documento: context[ - 'documentos'] = protocolo.documentoadministrativo_set\ - .all().order_by('-ano', '-numero') + "documentos" + ] = protocolo.documentoadministrativo_set.all().order_by("-ano", "-numero") - context['protocolo'] = protocolo + context["protocolo"] = protocolo return context class ComprovanteProtocoloView(PermissionRequiredMixin, TemplateView): - template_name = "protocoloadm/comprovante.html" - permission_required = ('protocoloadm.detail_protocolo', ) + permission_required = ("protocoloadm.detail_protocolo",) def get_context_data(self, **kwargs): - context = super(ComprovanteProtocoloView, self).get_context_data( - **kwargs) - protocolo = Protocolo.objects.get(pk=self.kwargs['pk']) + context = super(ComprovanteProtocoloView, self).get_context_data(**kwargs) + protocolo = Protocolo.objects.get(pk=self.kwargs["pk"]) # numero is string, padd with zeros left via .zfill() base64_data = create_barcode(str(protocolo.numero).zfill(6)) - barcode = 'data:image/png;base64,{0}'.format(base64_data) + barcode = "data:image/png;base64,{0}".format(base64_data) autenticacao = _("** NULO **") @@ -853,69 +946,73 @@ class ComprovanteProtocoloView(PermissionRequiredMixin, TemplateView): data = protocolo.data.strftime("%Y/%m/%d") # data is not i18n sensitive 'Y-m-d' is the right format. - autenticacao = str(protocolo.tipo_processo) + \ - data + str(protocolo.numero).zfill(6) + autenticacao = ( + str(protocolo.tipo_processo) + data + str(protocolo.numero).zfill(6) + ) if protocolo.tipo_materia: materia = MateriaLegislativa.objects.filter( - numero_protocolo=protocolo.numero, - ano=protocolo.ano).first() + numero_protocolo=protocolo.numero, ano=protocolo.ano + ).first() if materia: - context['materia'] = materia.numero + context["materia"] = materia.numero - context.update({"protocolo": protocolo, - "barcode": barcode, - "autenticacao": autenticacao}) + context.update( + {"protocolo": protocolo, "barcode": barcode, "autenticacao": autenticacao} + ) return context class ProtocoloMateriaView(PermissionRequiredMixin, CreateView): - logger = logging.getLogger(__name__) template_name = "protocoloadm/protocolar_materia.html" form_class = ProtocoloMateriaForm - form_valid_message = _('Matéria cadastrada com sucesso!') - permission_required = ('protocoloadm.add_protocolo',) + form_valid_message = _("Matéria cadastrada com sucesso!") + permission_required = ("protocoloadm.add_protocolo",) def get_success_url(self, protocolo): - return reverse('sapl.protocoloadm:materia_continuar', kwargs={ - 'pk': protocolo.pk}) + return reverse( + "sapl.protocoloadm:materia_continuar", kwargs={"pk": protocolo.pk} + ) def get_initial(self): initial = super().get_initial() - initial['user'] = self.request.user.username - initial['user_data_hora_manual'] = self.request.user.username - initial['ip_data_hora_manual'] = get_client_ip(self.request) - initial['data'] = timezone.localdate(timezone.now()) - initial['hora'] = timezone.localtime(timezone.now()) + initial["user"] = self.request.user.username + initial["user_data_hora_manual"] = self.request.user.username + initial["ip_data_hora_manual"] = get_client_ip(self.request) + initial["data"] = timezone.localdate(timezone.now()) + initial["hora"] = timezone.localtime(timezone.now()) return initial @transaction.atomic def form_valid(self, form): protocolo = form.save(commit=False) username = self.request.user.username - self.logger.debug("user=" + username + - ". Tentando obter sequência de numeração.") - numeracao = AppConfig.objects.last( - ).sequencia_numeracao_protocolo + self.logger.debug( + "user=" + username + ". Tentando obter sequência de numeração." + ) + numeracao = AppConfig.objects.last().sequencia_numeracao_protocolo if not numeracao: - self.logger.error("user=" + username + ". É preciso definir a sequencia de " - "numeração na tabelas auxiliares!") - msg = _('É preciso definir a sequencia de ' + - 'numeração na tabelas auxiliares!') + self.logger.error( + "user=" + username + ". É preciso definir a sequencia de " + "numeração na tabelas auxiliares!" + ) + msg = _( + "É preciso definir a sequencia de " + "numeração na tabelas auxiliares!" + ) messages.add_message(self.request, messages.ERROR, msg) return self.render_to_response(self.get_context_data()) - if numeracao == 'A': + if numeracao == "A": numero_max = Protocolo.objects.filter(ano=timezone.now().year).aggregate( - Max('numero') - )['numero__max'] - elif numeracao == 'L': + Max("numero") + )["numero__max"] + elif numeracao == "L": legislatura = Legislatura.objects.filter( data_inicio__year__lte=timezone.now().year, - data_fim__year__gte=timezone.now().year + data_fim__year__gte=timezone.now().year, ).first() data_inicio = legislatura.data_inicio @@ -925,18 +1022,20 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView): data_fim_utc = from_date_to_datetime_utc(data_fim) numero_max = Protocolo.objects.filter( - Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) | Q( - timestamp__isnull=False, timestamp__gte=data_inicio_utc, - timestamp__lte=data_fim_utc - ) | Q( + Q(data__isnull=False, data__gte=data_inicio, data__lte=data_fim) + | Q( + timestamp__isnull=False, + timestamp__gte=data_inicio_utc, + timestamp__lte=data_fim_utc, + ) + | Q( timestamp_data_hora_manual__isnull=False, timestamp_data_hora_manual__gte=data_inicio_utc, timestamp_data_hora_manual__lte=data_fim_utc, ) - ).aggregate(Max('numero'))['numero__max'] - elif numeracao == 'U': - numero_max = Protocolo.objects.all().aggregate(Max('numero'))[ - 'numero__max'] + ).aggregate(Max("numero"))["numero__max"] + elif numeracao == "U": + numero_max = Protocolo.objects.all().aggregate(Max("numero"))["numero__max"] inicio_numeracao = AppConfig.objects.first().inicio_numeracao_protocolo numero = int(numero_max) if numero_max else 0 @@ -947,35 +1046,36 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView): protocolo.ano = timezone.now().year protocolo.tipo_protocolo = 0 - protocolo.tipo_processo = '1' # TODO validar o significado + protocolo.tipo_processo = "1" # TODO validar o significado protocolo.anulado = False - if form.cleaned_data['autor']: - protocolo.autor = form.cleaned_data['autor'] + if form.cleaned_data["autor"]: + protocolo.autor = form.cleaned_data["autor"] protocolo.tipo_materia = TipoMateriaLegislativa.objects.get( - id=self.request.POST['tipo_materia']) - protocolo.numero_paginas = self.request.POST['numero_paginas'] - protocolo.observacao = self.request.POST['observacao'] - protocolo.assunto_ementa = self.request.POST['assunto_ementa'] + id=self.request.POST["tipo_materia"] + ) + protocolo.numero_paginas = self.request.POST["numero_paginas"] + protocolo.observacao = self.request.POST["observacao"] + protocolo.assunto_ementa = self.request.POST["assunto_ementa"] protocolo.user = self.request.user - if form.cleaned_data['data_hora_manual'] == 'True': + if form.cleaned_data["data_hora_manual"] == "True": protocolo.timestamp = None protocolo.user_data_hora_manual = username protocolo.ip_data_hora_manual = get_client_ip(self.request) else: protocolo.data = None protocolo.hora = None - protocolo.user_data_hora_manual = '' - protocolo.ip_data_hora_manual = '' + protocolo.user_data_hora_manual = "" + protocolo.ip_data_hora_manual = "" protocolo.save() data = form.cleaned_data - if data['vincular_materia'] == 'True': + if data["vincular_materia"] == "True": materia = MateriaLegislativa.objects.get( - ano=data['ano_materia'], - numero=data['numero_materia'], - tipo=data['tipo_materia'] + ano=data["ano_materia"], + numero=data["numero_materia"], + tipo=data["tipo_materia"], ) materia.numero_protocolo = protocolo.numero @@ -983,6 +1083,7 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView): materia.ip = get_client_ip(self.request) from django.utils import timezone + materia.ultima_edicao = timezone.now() materia.save() @@ -994,86 +1095,99 @@ class ProtocoloMateriaView(PermissionRequiredMixin, CreateView): autores_ativos = self.autores_ativos() autores = [] - autores.append(['0', '------']) + autores.append(["0", "------"]) for a in autores_ativos: autores.append([a.id, a.__str__()]) - context['form'].fields['autor'].choices = autores + context["form"].fields["autor"].choices = autores return context def autores_ativos(self): - lista_parlamentares = Parlamentar.objects.filter( - ativo=True).values_list('id', flat=True) + lista_parlamentares = Parlamentar.objects.filter(ativo=True).values_list( + "id", flat=True + ) model_parlamentar = ContentType.objects.get_for_model(Parlamentar) autor_parlamentar = Autor.objects.filter( - content_type=model_parlamentar, object_id__in=lista_parlamentares) + content_type=model_parlamentar, object_id__in=lista_parlamentares + ) - lista_comissoes = Comissao.objects.filter(Q( - data_extincao__isnull=True) | Q( - data_extincao__gt=timezone.now())).values_list('id', flat=True) + lista_comissoes = Comissao.objects.filter( + Q(data_extincao__isnull=True) | Q(data_extincao__gt=timezone.now()) + ).values_list("id", flat=True) model_comissao = ContentType.objects.get_for_model(Comissao) autor_comissoes = Autor.objects.filter( - content_type=model_comissao, object_id__in=lista_comissoes) + content_type=model_comissao, object_id__in=lista_comissoes + ) autores_outros = Autor.objects.exclude( - content_type__in=[model_parlamentar, model_comissao]) + content_type__in=[model_parlamentar, model_comissao] + ) q = autor_parlamentar | autor_comissoes | autores_outros return q class ProtocoloMateriaTemplateView(PermissionRequiredMixin, TemplateView): - template_name = "protocoloadm/MateriaTemplate.html" - permission_required = ('protocoloadm.detail_protocolo', ) + permission_required = ("protocoloadm.detail_protocolo",) def get_context_data(self, **kwargs): - context = super(ProtocoloMateriaTemplateView, self).get_context_data( - **kwargs) - protocolo = Protocolo.objects.get(pk=self.kwargs['pk']) - context.update({'protocolo': protocolo}) + context = super(ProtocoloMateriaTemplateView, self).get_context_data(**kwargs) + protocolo = Protocolo.objects.get(pk=self.kwargs["pk"]) + context.update({"protocolo": protocolo}) return context -class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin, - MultiFormatOutputMixin, - PermissionRequiredMixin, - FilterView): +class PesquisarDocumentoAdministrativoView( + DocumentoAdministrativoMixin, + MultiFormatOutputMixin, + PermissionRequiredMixin, + FilterView, +): model = DocumentoAdministrativo filterset_class = DocumentoAdministrativoFilterSet paginate_by = 10 - permission_required = ('protocoloadm.list_documentoadministrativo', ) + permission_required = ("protocoloadm.list_documentoadministrativo",) fields_base_report = [ - 'id', 'ano', 'numero', 'tipo__sigla', 'tipo__descricao', 'assunto' + "id", + "ano", + "numero", + "tipo__sigla", + "tipo__descricao", + "assunto", ] fields_report = { - 'csv': fields_base_report, - 'xlsx': fields_base_report, - 'json': fields_base_report, + "csv": fields_base_report, + "xlsx": fields_base_report, + "json": fields_base_report, } def get_filterset_kwargs(self, filterset_class): - super(PesquisarDocumentoAdministrativoView, - self).get_filterset_kwargs(filterset_class) + super(PesquisarDocumentoAdministrativoView, self).get_filterset_kwargs( + filterset_class + ) - kwargs = {'data': self.request.GET or None} + kwargs = {"data": self.request.GET or None} - status_tramitacao = self.request.GET.get( - 'tramitacaoadministrativo__status') + status_tramitacao = self.request.GET.get("tramitacaoadministrativo__status") unidade_destino = self.request.GET.get( - 'tramitacaoadministrativo__unidade_tramitacao_destino') + "tramitacaoadministrativo__unidade_tramitacao_destino" + ) qs = self.get_queryset() - qs = qs.prefetch_related("documentoacessorioadministrativo_set", - "tramitacaoadministrativo_set", - "tipo", - "tramitacaoadministrativo_set__status", - "tramitacaoadministrativo_set__unidade_tramitacao_local", - "tramitacaoadministrativo_set__unidade_tramitacao_destino") + qs = qs.prefetch_related( + "documentoacessorioadministrativo_set", + "tramitacaoadministrativo_set", + "tipo", + "tramitacaoadministrativo_set__status", + "tramitacaoadministrativo_set__unidade_tramitacao_local", + "tramitacaoadministrativo_set__unidade_tramitacao_destino", + ) if status_tramitacao and unidade_destino: - lista = filtra_tramitacao_adm_destino_and_status(status_tramitacao, - unidade_destino) + lista = filtra_tramitacao_adm_destino_and_status( + status_tramitacao, unidade_destino + ) qs = qs.filter(id__in=lista).distinct() elif status_tramitacao: @@ -1084,23 +1198,27 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin, lista = filtra_tramitacao_adm_destino(unidade_destino) qs = qs.filter(id__in=lista).distinct() - if 'o' in self.request.GET and not self.request.GET['o']: - qs = qs.order_by('-ano', '-numero') + if "o" in self.request.GET and not self.request.GET["o"]: + qs = qs.order_by("-ano", "-numero") - kwargs.update({ - 'queryset': qs, - }) + kwargs.update( + { + "queryset": qs, + } + ) return kwargs def get_context_data(self, **kwargs): - context = super(PesquisarDocumentoAdministrativoView, - self).get_context_data(**kwargs) + context = super(PesquisarDocumentoAdministrativoView, self).get_context_data( + **kwargs + ) if self.paginate_by: - paginator = context['paginator'] - page_obj = context['page_obj'] - context['page_range'] = make_pagination( - page_obj.number, paginator.num_pages) + paginator = context["paginator"] + page_obj = context["page_obj"] + context["page_range"] = make_pagination( + page_obj.number, paginator.num_pages + ) return context @@ -1111,14 +1229,14 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin, # Provavelmente você criou um novo campo no Form/FilterSet # Então a ordem da URL está diferente data = self.filterset.data - if data and data.get('tipo') is not None: - url = "&" + str(self.request.environ['QUERY_STRING']) + if data and data.get("tipo") is not None: + url = "&" + str(self.request.environ["QUERY_STRING"]) if url.startswith("&page"): - ponto_comeco = url.find('tipo=') - 1 + ponto_comeco = url.find("tipo=") - 1 url = url[ponto_comeco:] else: - url = '' - self.filterset.form.fields['o'].label = _('Ordenação') + url = "" + self.filterset.form.fields["o"].label = _("Ordenação") # é usada essa verificação anônima para quando os documentos administrativos # estão no modo ostensivo, mas podem existir documentos administrativos # restritos @@ -1127,14 +1245,12 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin, else: length = self.object_list.count() - is_relatorio = url != '' and request.GET.get('relatorio', None) + is_relatorio = url != "" and request.GET.get("relatorio", None) self.paginate_by = None if is_relatorio else self.paginate_by - context = self.get_context_data(filter=self.filterset, - filter_url=url, - numero_res=length - ) - context['show_results'] = show_results_filter_set( - self.request.GET.copy()) + context = self.get_context_data( + filter=self.filterset, filter_url=url, numero_res=length + ) + context["show_results"] = show_results_filter_set(self.request.GET.copy()) if is_relatorio: return relatorio_doc_administrativos(request, context) @@ -1144,12 +1260,12 @@ class PesquisarDocumentoAdministrativoView(DocumentoAdministrativoMixin, class AnexadoCrud(MasterDetailCrud): model = Anexado - parent_field = 'documento_principal' - help_topic = 'documento_anexado' + parent_field = "documento_principal" + help_topic = "documento_anexado" public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['documento_anexado', 'data_anexacao'] + list_field_names = ["documento_anexado", "data_anexacao"] class CreateView(MasterDetailCrud.CreateView): form_class = AnexadoForm @@ -1159,125 +1275,132 @@ class AnexadoCrud(MasterDetailCrud): def get_initial(self): initial = super(UpdateView, self).get_initial() - initial['tipo'] = self.object.documento_anexado.tipo.id - initial['numero'] = self.object.documento_anexado.numero - initial['ano'] = self.object.documento_anexado.ano + initial["tipo"] = self.object.documento_anexado.tipo.id + initial["numero"] = self.object.documento_anexado.numero + initial["ano"] = self.object.documento_anexado.ano return initial class DetailView(MasterDetailCrud.DetailView): - @property def layout_key(self): - return 'AnexadoDetail' + return "AnexadoDetail" class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView): filterset_class = AnexadoEmLoteFilterSet - template_name = 'protocoloadm/em_lote/anexado.html' - permission_required = ('protocoloadm.add_anexado', ) + template_name = "protocoloadm/em_lote/anexado.html" + permission_required = ("protocoloadm.add_anexado",) def get_context_data(self, **kwargs): - context = super( - DocumentoAnexadoEmLoteView, self - ).get_context_data(**kwargs) + context = super(DocumentoAnexadoEmLoteView, self).get_context_data(**kwargs) - context['root_pk'] = self.kwargs['pk'] + context["root_pk"] = self.kwargs["pk"] - context['subnav_template_name'] = 'protocoloadm/subnav.yaml' + context["subnav_template_name"] = "protocoloadm/subnav.yaml" - context['title'] = _('Documentos Anexados em Lote') + context["title"] = _("Documentos Anexados em Lote") # Verifica se os campos foram preenchidos - if not self.request.GET.get('tipo', " "): - msg = _('Por favor, selecione um tipo de documento.') + if not self.request.GET.get("tipo", " "): + msg = _("Por favor, selecione um tipo de documento.") messages.add_message(self.request, messages.ERROR, msg) - if not self.request.GET.get('data_0', " ") or not self.request.GET.get('data_1', " "): - msg = _('Por favor, preencha as datas.') + if not self.request.GET.get("data_0", " ") or not self.request.GET.get( + "data_1", " " + ): + msg = _("Por favor, preencha as datas.") messages.add_message(self.request, messages.ERROR, msg) return context - if not self.request.GET.get('data_0', " ") or not self.request.GET.get('data_1', " "): - msg = _('Por favor, preencha as datas.') + if not self.request.GET.get("data_0", " ") or not self.request.GET.get( + "data_1", " " + ): + msg = _("Por favor, preencha as datas.") messages.add_message(self.request, messages.ERROR, msg) return context qr = self.request.GET.copy() if not len(qr): - context['object_list'] = [] + context["object_list"] = [] else: - context['temp_object_list'] = context['object_list'].order_by( - 'numero', '-ano') - context['object_list'] = [] - for obj in context['temp_object_list']: - if not obj.pk == int(context['root_pk']): + context["temp_object_list"] = context["object_list"].order_by( + "numero", "-ano" + ) + context["object_list"] = [] + for obj in context["temp_object_list"]: + if not obj.pk == int(context["root_pk"]): documento_principal = DocumentoAdministrativo.objects.get( - id=context['root_pk']) + id=context["root_pk"] + ) documento_anexado = obj - is_anexado = Anexado.objects.filter(documento_principal=documento_principal, - documento_anexado=documento_anexado).exists() + is_anexado = Anexado.objects.filter( + documento_principal=documento_principal, + documento_anexado=documento_anexado, + ).exists() if not is_anexado: ciclico = False anexados_anexado = Anexado.objects.filter( - documento_principal=documento_anexado) + documento_principal=documento_anexado + ) while anexados_anexado and not ciclico: anexados = [] for anexo in anexados_anexado: - if documento_principal == anexo.documento_anexado: ciclico = True else: - for a in Anexado.objects.filter(documento_principal=anexo.documento_anexado): + for a in Anexado.objects.filter( + documento_principal=anexo.documento_anexado + ): anexados.append(a) anexados_anexado = anexados if not ciclico: - context['object_list'].append(obj) + context["object_list"].append(obj) - context['numero_res'] = len(context['object_list']) + context["numero_res"] = len(context["object_list"]) - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" - context['show_results'] = show_results_filter_set(qr) + context["show_results"] = show_results_filter_set(qr) return context def post(self, request, *args, **kwargs): - marcados = request.POST.getlist('documento_id') + marcados = request.POST.getlist("documento_id") data_anexacao = datetime.strptime( - request.POST['data_anexacao'], "%d/%m/%Y" + request.POST["data_anexacao"], "%d/%m/%Y" ).date() - if request.POST['data_desanexacao'] == '': + if request.POST["data_desanexacao"] == "": data_desanexacao = None v_data_desanexacao = data_anexacao else: data_desanexacao = datetime.strptime( - request.POST['data_desanexacao'], "%d/%m/%Y" + request.POST["data_desanexacao"], "%d/%m/%Y" ).date() v_data_desanexacao = data_desanexacao if len(marcados) == 0: - msg = _('Nenhum documento foi selecionado') + msg = _("Nenhum documento foi selecionado") messages.add_message(request, messages.ERROR, msg) if data_anexacao > v_data_desanexacao: - msg = _('Data de anexação posterior à data de desanexação.') + msg = _("Data de anexação posterior à data de desanexação.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) if data_anexacao > v_data_desanexacao: - msg = _('Data de anexação posterior à data de desanexação.') + msg = _("Data de anexação posterior à data de desanexação.") messages.add_message(request, messages.ERROR, msg) return self.get(request, messages.ERROR, msg) - principal = DocumentoAdministrativo.objects.get(pk=kwargs['pk']) + principal = DocumentoAdministrativo.objects.get(pk=kwargs["pk"]) for documento in DocumentoAdministrativo.objects.filter(id__in=marcados): anexado = Anexado() anexado.documento_principal = principal @@ -1286,49 +1409,59 @@ class DocumentoAnexadoEmLoteView(PermissionRequiredMixin, FilterView): anexado.data_desanexacao = data_desanexacao anexado.save() - msg = _('Documento(s) anexado(s).') + msg = _("Documento(s) anexado(s).") messages.add_message(request, messages.SUCCESS, msg) - success_url = reverse('sapl.protocoloadm:anexado_list', kwargs={ - 'pk': kwargs['pk']}) + success_url = reverse( + "sapl.protocoloadm:anexado_list", kwargs={"pk": kwargs["pk"]} + ) return HttpResponseRedirect(success_url) class TramitacaoAdmCrud(MasterDetailCrud): model = TramitacaoAdministrativo - parent_field = 'documento' - help_topic = 'unidade_tramitacao' + parent_field = "documento" + help_topic = "unidade_tramitacao" class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['data_tramitacao', 'unidade_tramitacao_local', - 'unidade_tramitacao_destino', 'status'] + list_field_names = [ + "data_tramitacao", + "unidade_tramitacao_local", + "unidade_tramitacao_destino", + "status", + ] class CreateView(MasterDetailCrud.CreateView): form_class = TramitacaoAdmForm logger = logging.getLogger(__name__) def get_success_url(self): - return reverse('sapl.protocoloadm:tramitacaoadministrativo_list', kwargs={ - 'pk': self.kwargs['pk']}) + return reverse( + "sapl.protocoloadm:tramitacaoadministrativo_list", + kwargs={"pk": self.kwargs["pk"]}, + ) def get_initial(self): initial = super(CreateView, self).get_initial() - local = DocumentoAdministrativo.objects.get( - pk=self.kwargs['pk']).tramitacaoadministrativo_set.order_by( - '-data_tramitacao', - '-id').first() + local = ( + DocumentoAdministrativo.objects.get(pk=self.kwargs["pk"]) + .tramitacaoadministrativo_set.order_by("-data_tramitacao", "-id") + .first() + ) if local: - initial['unidade_tramitacao_local' - ] = local.unidade_tramitacao_destino.pk + initial[ + "unidade_tramitacao_local" + ] = local.unidade_tramitacao_destino.pk else: - initial['unidade_tramitacao_local'] = '' - initial['data_tramitacao'] = timezone.now().date() - initial['ip'] = get_client_ip(self.request) - initial['user'] = self.request.user + initial["unidade_tramitacao_local"] = "" + initial["data_tramitacao"] = timezone.now().date() + initial["ip"] = get_client_ip(self.request) + initial["user"] = self.request.user from django.utils import timezone - initial['ultima_edicao'] = timezone.now() + + initial["ultima_edicao"] = timezone.now() return initial @@ -1336,35 +1469,45 @@ class TramitacaoAdmCrud(MasterDetailCrud): context = super().get_context_data(**kwargs) username = self.request.user.username - ultima_tramitacao = TramitacaoAdministrativo.objects.filter( - documento_id=self.kwargs['pk']).order_by( - '-data_tramitacao', - '-timestamp', - '-id').first() + ultima_tramitacao = ( + TramitacaoAdministrativo.objects.filter(documento_id=self.kwargs["pk"]) + .order_by("-data_tramitacao", "-timestamp", "-id") + .first() + ) # TODO: Esta checagem foi inserida na issue #2027, mas é mesmo # necessária? if ultima_tramitacao: if ultima_tramitacao.unidade_tramitacao_destino: - context['form'].fields[ - 'unidade_tramitacao_local'].choices = [ - (ultima_tramitacao.unidade_tramitacao_destino.pk, - ultima_tramitacao.unidade_tramitacao_destino)] + context["form"].fields["unidade_tramitacao_local"].choices = [ + ( + ultima_tramitacao.unidade_tramitacao_destino.pk, + ultima_tramitacao.unidade_tramitacao_destino, + ) + ] else: - self.logger.error('user=' + username + '. Unidade de tramitação destino ' - 'da última tramitação não pode ser vazia!') - msg = _('Unidade de tramitação destino ' - ' da última tramitação não pode ser vazia!') + self.logger.error( + "user=" + username + ". Unidade de tramitação destino " + "da última tramitação não pode ser vazia!" + ) + msg = _( + "Unidade de tramitação destino " + " da última tramitação não pode ser vazia!" + ) messages.add_message(self.request, messages.ERROR, msg) - primeira_tramitacao = not(TramitacaoAdministrativo.objects.filter( - documento_id=int(kwargs['root_pk'])).exists()) + primeira_tramitacao = not ( + TramitacaoAdministrativo.objects.filter( + documento_id=int(kwargs["root_pk"]) + ).exists() + ) # Se não for a primeira tramitação daquela matéria, o campo # não pode ser modificado if not primeira_tramitacao: - context['form'].fields[ - 'unidade_tramitacao_local'].widget.attrs['readonly'] = True + context["form"].fields["unidade_tramitacao_local"].widget.attrs[ + "readonly" + ] = True return context class UpdateView(MasterDetailCrud.UpdateView): @@ -1373,55 +1516,53 @@ class TramitacaoAdmCrud(MasterDetailCrud): def get_initial(self): initial = super(UpdateView, self).get_initial() - initial['ip'] = get_client_ip(self.request) - initial['user'] = self.request.user + initial["ip"] = get_client_ip(self.request) + initial["user"] = self.request.user from django.utils import timezone - initial['ultima_edicao'] = timezone.now() + + initial["ultima_edicao"] = timezone.now() return initial class ListView(DocumentoAdministrativoMixin, MasterDetailCrud.ListView): - def get_queryset(self): qs = super(MasterDetailCrud.ListView, self).get_queryset() - kwargs = {self.crud.parent_field: self.kwargs['pk']} - return qs.filter(**kwargs).order_by('-data_tramitacao', - '-id') + kwargs = {self.crud.parent_field: self.kwargs["pk"]} + return qs.filter(**kwargs).order_by("-data_tramitacao", "-id") - class DetailView(DocumentoAdministrativoMixin, - MasterDetailCrud.DetailView): - - template_name = 'protocoloadm/tramitacaoadministrativo_detail.html' + class DetailView(DocumentoAdministrativoMixin, MasterDetailCrud.DetailView): + template_name = "protocoloadm/tramitacaoadministrativo_detail.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['user'] = self.request.user + context["user"] = self.request.user return context class DeleteView(MasterDetailCrud.DeleteView): - logger = logging.getLogger(__name__) def delete(self, request, *args, **kwargs): - tramitacao = TramitacaoAdministrativo.objects.get( - id=self.kwargs['pk']) + tramitacao = TramitacaoAdministrativo.objects.get(id=self.kwargs["pk"]) documento = tramitacao.documento url = reverse( - 'sapl.protocoloadm:tramitacaoadministrativo_list', - kwargs={'pk': documento.id}) + "sapl.protocoloadm:tramitacaoadministrativo_list", + kwargs={"pk": documento.id}, + ) - ultima_tramitacao = \ - documento.tramitacaoadministrativo_set.order_by( - '-data_tramitacao', - '-id').first() + ultima_tramitacao = documento.tramitacaoadministrativo_set.order_by( + "-data_tramitacao", "-id" + ).first() if tramitacao.pk != ultima_tramitacao.pk: username = request.user.username - 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!') + 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) else: @@ -1429,7 +1570,7 @@ class TramitacaoAdmCrud(MasterDetailCrud): if documento.tramitacaoadministrativo_set.count() == 0: documento.tramitacao = False documento.save() - tramitar_anexados = AppConfig.attr('tramitacao_documento') + tramitar_anexados = AppConfig.attr("tramitacao_documento") if tramitar_anexados: docs_anexados = lista_anexados(documento) for da in docs_anexados: @@ -1440,7 +1581,8 @@ class TramitacaoAdmCrud(MasterDetailCrud): da.tramitacao = False da.save() TramitacaoAdministrativo.objects.filter( - id__in=[t.id for t in tramitacoes_deletar]).delete() + id__in=[t.id for t in tramitacoes_deletar] + ).delete() # TODO: otimizar para passar a lista de matérias # for tramitacao in tramitacoes_deletar: @@ -1454,13 +1596,11 @@ class TramitacaoAdmCrud(MasterDetailCrud): class DocumentoAcessorioAdministrativoCrud(MasterDetailCrud): model = DocumentoAcessorioAdministrativo - parent_field = 'documento' - help_topic = 'numeracao_docsacess' + parent_field = "documento" + help_topic = "numeracao_docsacess" class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['nome', 'tipo', - 'data', 'autor', - 'assunto'] + list_field_names = ["nome", "tipo", "data", "autor", "assunto"] class CreateView(MasterDetailCrud.CreateView): form_class = DocumentoAcessorioAdministrativoForm @@ -1469,56 +1609,59 @@ class DocumentoAcessorioAdministrativoCrud(MasterDetailCrud): form_class = DocumentoAcessorioAdministrativoForm class ListView(DocumentoAdministrativoMixin, MasterDetailCrud.ListView): - def get_queryset(self): qs = super(MasterDetailCrud.ListView, self).get_queryset() - kwargs = {self.crud.parent_field: self.kwargs['pk']} - return qs.filter(**kwargs).order_by('-data', '-id') + kwargs = {self.crud.parent_field: self.kwargs["pk"]} + return qs.filter(**kwargs).order_by("-data", "-id") - class DetailView(DocumentoAdministrativoMixin, - MasterDetailCrud.DetailView): + class DetailView(DocumentoAdministrativoMixin, MasterDetailCrud.DetailView): pass def atualizar_numero_documento(request): - tipo = TipoDocumentoAdministrativo.objects.get(pk=request.GET['tipo']) - ano = request.GET['ano'] + tipo = TipoDocumentoAdministrativo.objects.get(pk=request.GET["tipo"]) + ano = request.GET["ano"] - param = {'tipo': tipo} - param['ano'] = ano if ano else timezone.now().year + param = {"tipo": tipo} + param["ano"] = ano if ano else timezone.now().year - doc = DocumentoAdministrativo.objects.filter(**param).order_by( - 'tipo', 'ano', 'numero').values_list('numero', 'ano').last() + doc = ( + DocumentoAdministrativo.objects.filter(**param) + .order_by("tipo", "ano", "numero") + .values_list("numero", "ano") + .last() + ) if doc: - response = JsonResponse({'numero': int(doc[0]) + 1, - 'ano': doc[1]}) + response = JsonResponse({"numero": int(doc[0]) + 1, "ano": doc[1]}) else: - response = JsonResponse( - {'numero': 1, 'ano': ano}) + response = JsonResponse({"numero": 1, "ano": ano}) return response class DesvincularDocumentoView(PermissionRequiredMixin, CreateView): - template_name = 'protocoloadm/anular_protocoloadm.html' + template_name = "protocoloadm/anular_protocoloadm.html" form_class = DesvincularDocumentoForm - form_valid_message = _('Documento desvinculado com sucesso!') - permission_required = ('protocoloadm.action_anular_protocolo', ) + form_valid_message = _("Documento desvinculado com sucesso!") + permission_required = ("protocoloadm.action_anular_protocolo",) def get_success_url(self): - return reverse('sapl.protocoloadm:protocolo') + return reverse("sapl.protocoloadm:protocolo") def form_valid(self, form): - documento = DocumentoAdministrativo.objects.get(numero=form.cleaned_data['numero'], - ano=form.cleaned_data['ano'], - tipo=form.cleaned_data['tipo']) + documento = DocumentoAdministrativo.objects.get( + numero=form.cleaned_data["numero"], + ano=form.cleaned_data["ano"], + tipo=form.cleaned_data["tipo"], + ) documento.protocolo = None documento.user = self.request.user documento.ip = get_client_ip(self.request) from django.utils import timezone + documento.ultima_edicao = timezone.now() documento.save() @@ -1526,19 +1669,19 @@ class DesvincularDocumentoView(PermissionRequiredMixin, CreateView): class DesvincularMateriaView(PermissionRequiredMixin, FormView): - template_name = 'protocoloadm/anular_protocoloadm.html' + template_name = "protocoloadm/anular_protocoloadm.html" form_class = DesvincularMateriaForm - form_valid_message = _('Matéria desvinculado com sucesso!') - permission_required = ('protocoloadm.action_anular_protocolo', ) + form_valid_message = _("Matéria desvinculado com sucesso!") + permission_required = ("protocoloadm.action_anular_protocolo",) def get_success_url(self): - return reverse('sapl.protocoloadm:protocolo') + return reverse("sapl.protocoloadm:protocolo") def form_valid(self, form): materia = MateriaLegislativa.objects.get( - numero=form.cleaned_data['numero'], - ano=form.cleaned_data['ano'], - tipo=form.cleaned_data['tipo'] + numero=form.cleaned_data["numero"], + ano=form.cleaned_data["ano"], + tipo=form.cleaned_data["tipo"], ) materia.numero_protocolo = None @@ -1547,6 +1690,7 @@ class DesvincularMateriaView(PermissionRequiredMixin, FormView): materia.ip = get_client_ip(self.request) from django.utils import timezone + materia.ultima_edicao = timezone.now() materia.save() @@ -1554,23 +1698,26 @@ class DesvincularMateriaView(PermissionRequiredMixin, FormView): class ImpressosView(PermissionRequiredMixin, TemplateView): - template_name = 'materia/impressos/impressos.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos.html" + permission_required = ("materia.can_access_impressos",) class FichaPesquisaAdmView(PermissionRequiredMixin, FormView): form_class = FichaPesquisaAdmForm - template_name = 'materia/impressos/impressos_form.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos_form.html" + permission_required = ("materia.can_access_impressos",) def form_valid(self, form): - tipo_documento = form.data['tipo_documento'] - data_inicial = form.data['data_inicial'] - data_final = form.data['data_final'] - - url = reverse('sapl.materia:impressos_ficha_seleciona_adm') - url = url + '?tipo=%s&data_inicial=%s&data_final=%s' % ( - tipo_documento, data_inicial, data_final) + tipo_documento = form.data["tipo_documento"] + data_inicial = form.data["data_inicial"] + data_final = form.data["data_final"] + + url = reverse("sapl.materia:impressos_ficha_seleciona_adm") + url = url + "?tipo=%s&data_inicial=%s&data_final=%s" % ( + tipo_documento, + data_inicial, + data_final, + ) return HttpResponseRedirect(url) @@ -1578,49 +1725,63 @@ class FichaPesquisaAdmView(PermissionRequiredMixin, FormView): class FichaSelecionaAdmView(PermissionRequiredMixin, FormView): logger = logging.getLogger(__name__) form_class = FichaSelecionaAdmForm - template_name = 'materia/impressos/impressos_form.html' - permission_required = ('materia.can_access_impressos', ) + template_name = "materia/impressos/impressos_form.html" + permission_required = ("materia.can_access_impressos",) def get_context_data(self, **kwargs): - if ('tipo' not in self.request.GET or - 'data_inicial' not in self.request.GET or - 'data_final' not in self.request.GET): - return HttpResponseRedirect(reverse( - 'sapl.materia:impressos_ficha_pesquisa_adm')) + if ( + "tipo" not in self.request.GET + or "data_inicial" not in self.request.GET + or "data_final" not in self.request.GET + ): + return HttpResponseRedirect( + reverse("sapl.materia:impressos_ficha_pesquisa_adm") + ) - context = super(FichaSelecionaAdmView, self).get_context_data( - **kwargs) + context = super(FichaSelecionaAdmView, self).get_context_data(**kwargs) - tipo = self.request.GET['tipo'] + tipo = self.request.GET["tipo"] data_inicial = datetime.strptime( - self.request.GET['data_inicial'], "%d/%m/%Y").date() + self.request.GET["data_inicial"], "%d/%m/%Y" + ).date() data_final = datetime.strptime( - self.request.GET['data_final'], "%d/%m/%Y").date() + self.request.GET["data_final"], "%d/%m/%Y" + ).date() documento_list = DocumentoAdministrativo.objects.filter( - tipo=tipo, - data__range=(data_inicial, data_final)) - context['quantidade'] = len(documento_list) + tipo=tipo, data__range=(data_inicial, data_final) + ) + context["quantidade"] = len(documento_list) documento_list = documento_list[:100] - context['form'].fields['documento'].choices = [ - (d.id, str(d)) for d in documento_list] + context["form"].fields["documento"].choices = [ + (d.id, str(d)) for d in documento_list + ] username = self.request.user.username - if context['quantidade'] > 100: - self.logger.info('user=' + username + '. Sua pesquisa (tipo={}, data_inicial={}, data_final={}) retornou mais do que ' - '100 impressos. Por questões de ' - 'performance, foram retornados ' - 'apenas os 100 primeiros. Caso ' - 'queira outros, tente fazer uma ' - 'pesquisa mais específica'.format(tipo, data_inicial, data_final)) - messages.info(self.request, _('Sua pesquisa retornou mais do que ' - '100 impressos. Por questões de ' - 'performance, foram retornados ' - 'apenas os 100 primeiros. Caso ' - 'queira outros, tente fazer uma ' - 'pesquisa mais específica')) + if context["quantidade"] > 100: + self.logger.info( + "user=" + + username + + ". Sua pesquisa (tipo={}, data_inicial={}, data_final={}) retornou mais do que " + "100 impressos. Por questões de " + "performance, foram retornados " + "apenas os 100 primeiros. Caso " + "queira outros, tente fazer uma " + "pesquisa mais específica".format(tipo, data_inicial, data_final) + ) + messages.info( + self.request, + _( + "Sua pesquisa retornou mais do que " + "100 impressos. Por questões de " + "performance, foram retornados " + "apenas os 100 primeiros. Caso " + "queira outros, tente fazer uma " + "pesquisa mais específica" + ), + ) return context @@ -1630,64 +1791,80 @@ class FichaSelecionaAdmView(PermissionRequiredMixin, FormView): try: self.logger.debug( - "user=" + username + ". Tentando obter objeto DocumentoAdministrativo com id={}".format(form.data['documento'])) - documento = DocumentoAdministrativo.objects.get( - id=form.data['documento']) + "user=" + + username + + ". Tentando obter objeto DocumentoAdministrativo com id={}".format( + form.data["documento"] + ) + ) + documento = DocumentoAdministrativo.objects.get(id=form.data["documento"]) except ObjectDoesNotExist: self.logger.error( - "user=" + username + ". Este DocumentoAdministrativo não existe (id={}).".format(form.data['documento'])) - mensagem = _('Este Documento Administrativo não existe.') + "user=" + + username + + ". Este DocumentoAdministrativo não existe (id={}).".format( + form.data["documento"] + ) + ) + mensagem = _("Este Documento Administrativo não existe.") self.messages.add_message(self.request, messages.INFO, mensagem) return self.render_to_response(context) if len(documento.assunto) > 201: - documento.assunto = documento.assunto[0:200] + '[...]' - context['documento'] = documento + documento.assunto = documento.assunto[0:200] + "[...]" + context["documento"] = documento - return gerar_pdf_impressos(self.request, context, - 'materia/impressos/ficha_adm_pdf.html') + return gerar_pdf_impressos( + self.request, context, "materia/impressos/ficha_adm_pdf.html" + ) class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView): filterset_class = PrimeiraTramitacaoEmLoteAdmFilterSet - template_name = 'protocoloadm/em_lote/tramitacaoadm.html' - permission_required = ('protocoloadm.add_tramitacaoadministrativo', ) + template_name = "protocoloadm/em_lote/tramitacaoadm.html" + permission_required = ("protocoloadm.add_tramitacaoadministrativo",) primeira_tramitacao = True logger = logging.getLogger(__name__) def get_context_data(self, **kwargs): - context = super(PrimeiraTramitacaoEmLoteAdmView, - self).get_context_data(**kwargs) + context = super(PrimeiraTramitacaoEmLoteAdmView, self).get_context_data( + **kwargs + ) - context['subnav_template_name'] = 'protocoloadm/em_lote/subnav_em_lote.yaml' - context['primeira_tramitacao'] = self.primeira_tramitacao + context["subnav_template_name"] = "protocoloadm/em_lote/subnav_em_lote.yaml" + context["primeira_tramitacao"] = self.primeira_tramitacao # Verifica se os campos foram preenchidos if not self.filterset.form.is_valid(): return context - context['object_list'] = context['object_list'].order_by( - 'ano', 'numero') + context["object_list"] = context["object_list"].order_by("ano", "numero") qr = self.request.GET.copy() form = TramitacaoEmLoteAdmForm() - context['form'] = form + context["form"] = form if self.primeira_tramitacao: - context['title'] = _('Primeira Tramitação em Lote') + context["title"] = _("Primeira Tramitação em Lote") # Pega somente documentos que não possuem tramitação - context['object_list'] = [obj for obj in context['object_list'] - if obj.tramitacaoadministrativo_set.all().count() == 0] + context["object_list"] = [ + obj + for obj in context["object_list"] + if obj.tramitacaoadministrativo_set.all().count() == 0 + ] else: - context['title'] = _('Tramitação em Lote') - context['form'].fields['unidade_tramitacao_local'].initial = UnidadeTramitacao.objects.get( - id=qr['tramitacaoadministrativo__unidade_tramitacao_destino']) + context["title"] = _("Tramitação em Lote") + context["form"].fields[ + "unidade_tramitacao_local" + ].initial = UnidadeTramitacao.objects.get( + id=qr["tramitacaoadministrativo__unidade_tramitacao_destino"] + ) - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" - context['show_results'] = show_results_filter_set(qr) + context["show_results"] = show_results_filter_set(qr) return context @@ -1696,42 +1873,52 @@ class PrimeiraTramitacaoEmLoteAdmView(PermissionRequiredMixin, FilterView): ip = get_client_ip(request) from django.utils import timezone + ultima_edicao = timezone.now() - documentos_ids = request.POST.getlist('documentos') + documentos_ids = request.POST.getlist("documentos") if not documentos_ids: msg = _("Escolha algum Documento para ser tramitado.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) - form = TramitacaoEmLoteAdmForm(request.POST, - initial={'documentos': documentos_ids, - 'user': user, 'ip': ip, - 'ultima_edicao': ultima_edicao}) + form = TramitacaoEmLoteAdmForm( + request.POST, + initial={ + "documentos": documentos_ids, + "user": user, + "ip": ip, + "ultima_edicao": ultima_edicao, + }, + ) if form.is_valid(): form.save() - msg = _('Tramitação completa.') - self.logger.info('user=' + user.username + - '. Tramitação completa.') + msg = _("Tramitação completa.") + self.logger.info("user=" + user.username + ". Tramitação completa.") messages.add_message(request, messages.SUCCESS, msg) return self.get_success_url() return self.form_invalid(form) def get_success_url(self): - return HttpResponseRedirect(reverse('sapl.protocoloadm:primeira_tramitacao_em_lote_docadm')) + return HttpResponseRedirect( + reverse("sapl.protocoloadm:primeira_tramitacao_em_lote_docadm") + ) def form_invalid(self, form, *args, **kwargs): for key, erros in form.errors.items(): - if not key == '__all__': - [messages.add_message( - self.request, messages.ERROR, form.fields[key].label + ": " + e) for e in erros] + if not key == "__all__": + [ + messages.add_message( + self.request, messages.ERROR, form.fields[key].label + ": " + e + ) + for e in erros + ] else: - [messages.add_message(self.request, messages.ERROR, e) - for e in erros] - return self.get(self.request, kwargs, {'form': form}) + [messages.add_message(self.request, messages.ERROR, e) for e in erros] + return self.get(self.request, kwargs, {"form": form}) class TramitacaoEmLoteAdmView(PrimeiraTramitacaoEmLoteAdmView): @@ -1740,57 +1927,67 @@ class TramitacaoEmLoteAdmView(PrimeiraTramitacaoEmLoteAdmView): primeira_tramitacao = False def get_context_data(self, **kwargs): - context = super(TramitacaoEmLoteAdmView, - self).get_context_data(**kwargs) + context = super(TramitacaoEmLoteAdmView, self).get_context_data(**kwargs) qr = self.request.GET.copy() - context['primeira_tramitacao'] = self.primeira_tramitacao + context["primeira_tramitacao"] = self.primeira_tramitacao - if ('tramitacao__status' in qr and - 'tramitacao__unidade_tramitacao_destino' in qr and - qr['tramitacao__status'] and - qr['tramitacao__unidade_tramitacao_destino']): + if ( + "tramitacao__status" in qr + and "tramitacao__unidade_tramitacao_destino" in qr + and qr["tramitacao__status"] + and qr["tramitacao__unidade_tramitacao_destino"] + ): lista = self.filtra_tramitacao_destino_and_status( - qr['tramitacao__status'], - qr['tramitacao__unidade_tramitacao_destino']) - context['object_list'] = context['object_list'].filter( - id__in=lista).distinct() + qr["tramitacao__status"], qr["tramitacao__unidade_tramitacao_destino"] + ) + context["object_list"] = ( + context["object_list"].filter(id__in=lista).distinct() + ) return context def pega_ultima_tramitacao(self): - return TramitacaoAdministrativo.objects.values( - 'documento_id').annotate(data_encaminhamento=Max( - 'data_encaminhamento'), - id=Max('id')).values_list('id', flat=True) + return ( + TramitacaoAdministrativo.objects.values("documento_id") + .annotate(data_encaminhamento=Max("data_encaminhamento"), id=Max("id")) + .values_list("id", flat=True) + ) def filtra_tramitacao_status(self, status): lista = self.pega_ultima_tramitacao() - return TramitacaoAdministrativo.objects.filter( - id__in=lista, - status=status).distinct().values_list('documento_id', flat=True) + return ( + TramitacaoAdministrativo.objects.filter(id__in=lista, status=status) + .distinct() + .values_list("documento_id", flat=True) + ) def filtra_tramitacao_destino(self, destino): lista = self.pega_ultima_tramitacao() - return TramitacaoAdministrativo.objects.filter( - id__in=lista, - unidade_tramitacao_destino=destino).distinct().values_list( - 'documento_id', flat=True) + return ( + TramitacaoAdministrativo.objects.filter( + id__in=lista, unidade_tramitacao_destino=destino + ) + .distinct() + .values_list("documento_id", flat=True) + ) def filtra_tramitacao_destino_and_status(self, status, destino): lista = self.pega_ultima_tramitacao() - return TramitacaoAdministrativo.objects.filter( - id__in=lista, - status=status, - unidade_tramitacao_destino=destino).distinct().values_list( - 'documento_id', flat=True) + return ( + TramitacaoAdministrativo.objects.filter( + id__in=lista, status=status, unidade_tramitacao_destino=destino + ) + .distinct() + .values_list("documento_id", flat=True) + ) def apaga_protocolos(request, ano, numero_protocolo=None): - kwargs = {'ano__in': ano} + kwargs = {"ano__in": ano} if numero_protocolo: - kwargs.update({'numero__gte': numero_protocolo}) + kwargs.update({"numero__gte": numero_protocolo}) all_protocolos = Protocolo.objects.filter(**kwargs) @@ -1798,7 +1995,9 @@ def apaga_protocolos(request, ano, numero_protocolo=None): doc.protocolo = None doc.save() - for ml in MateriaLegislativa.objects.filter(ano__in=ano, numero_protocolo__in=all_protocolos.values_list('numero')): + for ml in MateriaLegislativa.objects.filter( + ano__in=ano, numero_protocolo__in=all_protocolos.values_list("numero") + ): ml.numero_protocolo = None ml.save() @@ -1815,40 +2014,48 @@ def apaga_protocolos(request, ano, numero_protocolo=None): def apaga_protocolos_view(request): if request.method == "GET": if Protocolo.objects.exists(): - intervalo_data = Protocolo.objects.all().distinct( - 'ano').values_list('ano', flat=True).order_by('-ano') + intervalo_data = ( + Protocolo.objects.all() + .distinct("ano") + .values_list("ano", flat=True) + .order_by("-ano") + ) else: intervalo_data = None - return render(request, "protocoloadm/deleta_todos_protocolos.html", {'intervalo_data': intervalo_data}) + return render( + request, + "protocoloadm/deleta_todos_protocolos.html", + {"intervalo_data": intervalo_data}, + ) elif request.method == "POST": - password = request.POST.get('senha') + password = request.POST.get("senha") valid = request.user.check_password(password) if valid: - anos = request.POST.getlist('ano') - numero_protocolo = request.POST.get('numero_protocolo') + anos = request.POST.getlist("ano") + numero_protocolo = request.POST.get("numero_protocolo") apaga_protocolos(request, anos, numero_protocolo) - return JsonResponse({'type': 'success', 'msg': ''}) + return JsonResponse({"type": "success", "msg": ""}) else: - return JsonResponse({'type': 'error', 'msg': 'Senha Incorreta'}) + return JsonResponse({"type": "error", "msg": "Senha Incorreta"}) class VinculoDocAdminMateriaCrud(MasterDetailCrud): model = VinculoDocAdminMateria - parent_field = 'documento' - help_topic = 'vinculodocadminmateria' + parent_field = "documento" + help_topic = "vinculodocadminmateria" public = [RP_LIST, RP_DETAIL] class BaseMixin(MasterDetailCrud.BaseMixin): - list_field_names = ['data_anexacao', ('materia', 'materia__ementa')] + list_field_names = ["data_anexacao", ("materia", "materia__ementa")] @property def verbose_name(self): - return _('Vinculo') + return _("Vinculo") @property def verbose_name_plural(self): - return _('Vinculos') + return _("Vinculos") @property def title(self): @@ -1862,113 +2069,115 @@ class VinculoDocAdminMateriaCrud(MasterDetailCrud): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['title'] = self.object.documento + context["title"] = self.object.documento return context def get_initial(self): initial = super(UpdateView, self).get_initial() - initial['tipo'] = self.object.materia.tipo.id - initial['numero'] = self.object.materia.numero - initial['ano'] = self.object.materia.ano + initial["tipo"] = self.object.materia.tipo.id + initial["numero"] = self.object.materia.numero + initial["ano"] = self.object.materia.ano return initial class DetailView(MasterDetailCrud.DetailView): - @property def layout_key(self): - return 'VinculoDocAdminMateriaDetail' + return "VinculoDocAdminMateriaDetail" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['title'] = self.object.documento.epigrafe + context["title"] = self.object.documento.epigrafe return context class VinculoDocAdminMateriaEmLoteView(PermissionRequiredMixin, FilterView): filterset_class = VinculoDocAdminMateriaEmLoteFilterSet - template_name = 'protocoloadm/em_lote/vinculodocadminmateria.html' - permission_required = ('protocoloadm.add_documentoadministrativo',) + template_name = "protocoloadm/em_lote/vinculodocadminmateria.html" + permission_required = ("protocoloadm.add_documentoadministrativo",) def get_context_data(self, **kwargs): - context = super(VinculoDocAdminMateriaEmLoteView, - self).get_context_data(**kwargs) + context = super(VinculoDocAdminMateriaEmLoteView, self).get_context_data( + **kwargs + ) - context['root_pk'] = self.kwargs['pk'] + context["root_pk"] = self.kwargs["pk"] - context['subnav_template_name'] = 'protocoloadm/subnav.yaml' + context["subnav_template_name"] = "protocoloadm/subnav.yaml" - context['title'] = _('Matérias Vinculadas em Lote') + context["title"] = _("Matérias Vinculadas em Lote") # Verifica se os campos foram preenchidos - if not self.request.GET.get('tipo', " "): - msg = _('Por favor, selecione um tipo de matéria.') + if not self.request.GET.get("tipo", " "): + msg = _("Por favor, selecione um tipo de matéria.") messages.add_message(self.request, messages.ERROR, msg) - if not self.request.GET.get('data_apresentacao_0', " ") or not self.request.GET.get('data_apresentacao_1', " "): - msg = _('Por favor, preencha as datas.') + if not self.request.GET.get( + "data_apresentacao_0", " " + ) or not self.request.GET.get("data_apresentacao_1", " "): + msg = _("Por favor, preencha as datas.") messages.add_message(self.request, messages.ERROR, msg) return context - if not self.request.GET.get('data_apresentacao_0', " ") or not self.request.GET.get('data_apresentacao_1', " "): - msg = _('Por favor, preencha as datas.') + if not self.request.GET.get( + "data_apresentacao_0", " " + ) or not self.request.GET.get("data_apresentacao_1", " "): + msg = _("Por favor, preencha as datas.") messages.add_message(self.request, messages.ERROR, msg) return context qr = self.request.GET.copy() if not len(qr): - context['object_list'] = [] + context["object_list"] = [] else: - context['object_list'] = context['object_list'].order_by( - 'numero', '-ano') - documento = DocumentoAdministrativo.objects.get( - pk=self.kwargs['pk']) - not_list = [self.kwargs['pk']] + \ - [m for m in documento.materiasvinculadas.values_list( - 'id', flat=True)] - context['object_list'] = context['object_list'].exclude( - pk__in=not_list) + context["object_list"] = context["object_list"].order_by("numero", "-ano") + documento = DocumentoAdministrativo.objects.get(pk=self.kwargs["pk"]) + not_list = [self.kwargs["pk"]] + [ + m for m in documento.materiasvinculadas.values_list("id", flat=True) + ] + context["object_list"] = context["object_list"].exclude(pk__in=not_list) - context['numero_res'] = len(context['object_list']) + context["numero_res"] = len(context["object_list"]) - context['filter_url'] = ('&' + qr.urlencode()) if len(qr) > 0 else '' + context["filter_url"] = ("&" + qr.urlencode()) if len(qr) > 0 else "" - context['show_results'] = show_results_filter_set(qr) + context["show_results"] = show_results_filter_set(qr) return context def post(self, request, *args, **kwargs): - marcadas = request.POST.getlist('materia_id') + marcadas = request.POST.getlist("materia_id") data_anexacao = datetime.strptime( - request.POST['data_anexacao'], "%d/%m/%Y").date() + request.POST["data_anexacao"], "%d/%m/%Y" + ).date() - if request.POST['data_desanexacao'] == '': + if request.POST["data_desanexacao"] == "": data_desanexacao = None v_data_desanexacao = data_anexacao else: data_desanexacao = datetime.strptime( - request.POST['data_desanexacao'], "%d/%m/%Y").date() + request.POST["data_desanexacao"], "%d/%m/%Y" + ).date() v_data_desanexacao = data_desanexacao if len(marcadas) == 0: - msg = _('Nenhuma máteria foi selecionada.') + msg = _("Nenhuma máteria foi selecionada.") messages.add_message(request, messages.ERROR, msg) if data_anexacao > v_data_desanexacao: - msg = _('Data de anexação posterior à data de desanexação.') + msg = _("Data de anexação posterior à data de desanexação.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) if data_anexacao > v_data_desanexacao: - msg = _('Data de anexação posterior à data de desanexação.') + msg = _("Data de anexação posterior à data de desanexação.") messages.add_message(request, messages.ERROR, msg) return self.get(request, self.kwargs) - documento = DocumentoAdministrativo.objects.get(pk=kwargs['pk']) + documento = DocumentoAdministrativo.objects.get(pk=kwargs["pk"]) for materia in MateriaLegislativa.objects.filter(id__in=marcadas): - v = VinculoDocAdminMateria() v.documento = documento v.materia = materia @@ -1976,9 +2185,10 @@ class VinculoDocAdminMateriaEmLoteView(PermissionRequiredMixin, FilterView): v.data_desanexacao = data_desanexacao v.save() - msg = _('Matéria(s) vinculadas(s).') + msg = _("Matéria(s) vinculadas(s).") messages.add_message(request, messages.SUCCESS, msg) - success_url = reverse('sapl.protocoloadm:vinculodocadminmateria_list', - kwargs={'pk': kwargs['pk']}) + success_url = reverse( + "sapl.protocoloadm:vinculodocadminmateria_list", kwargs={"pk": kwargs["pk"]} + ) return HttpResponseRedirect(success_url) diff --git a/sapl/redireciona_urls/apps.py b/sapl/redireciona_urls/apps.py index ae4ea82e7..28e8b1816 100644 --- a/sapl/redireciona_urls/apps.py +++ b/sapl/redireciona_urls/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.redireciona_urls' - label = 'redireciona_urls' - verbose_name = _('Redirecionador de URLs') + name = "sapl.redireciona_urls" + label = "redireciona_urls" + verbose_name = _("Redirecionador de URLs") diff --git a/sapl/redireciona_urls/exceptions.py b/sapl/redireciona_urls/exceptions.py index 0686d7953..c775a2ff2 100644 --- a/sapl/redireciona_urls/exceptions.py +++ b/sapl/redireciona_urls/exceptions.py @@ -2,7 +2,6 @@ from django.utils.translation import gettext as _ class UnknownUrlNameError(Exception): - def __init__(self, url_name): self.url_name = url_name @@ -10,4 +9,5 @@ class UnknownUrlNameError(Exception): return repr( _("Funcionalidade") + " '%s' " % (self.url_name) - + _("pode ter sido removida ou movida para outra url.")) + + _("pode ter sido removida ou movida para outra url.") + ) diff --git a/sapl/redireciona_urls/tests.py b/sapl/redireciona_urls/tests.py index 5a0e8b98f..31e2be97e 100644 --- a/sapl/redireciona_urls/tests.py +++ b/sapl/redireciona_urls/tests.py @@ -1,28 +1,26 @@ from django.test import TestCase from django.urls import reverse - MovedPermanentlyHTTPStatusCode = 301 -EMPTY_STRING = '' +EMPTY_STRING = "" class RedirecionaURLsTests(TestCase): - def test_redireciona_index_SAPL(self): - response = self.client.get(reverse( - 'sapl.redireciona_urls:redireciona_sapl_index') + response = self.client.get( + reverse("sapl.redireciona_urls:redireciona_sapl_index") ) - url_e = reverse('sapl.base:sapl_index') + url_e = reverse("sapl.base:sapl_index") self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) self.assertEqual(response.url, url_e) class RedirecionaParlamentarTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_parlamentar' + url_pattern = "sapl.redireciona_urls:redireciona_parlamentar" def test_redireciona_parlamentar_list(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.parlamentares:parlamentar_list') + url_e = reverse("sapl.parlamentares:parlamentar_list") response = self.client.get(url) self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) self.assertEqual(response.url, url_e) @@ -31,12 +29,9 @@ class RedirecionaParlamentarTests(TestCase): numero_legislatura = 123 url = reverse(self.url_pattern) - url_e = reverse('sapl.parlamentares:parlamentar_list') + url_e = reverse("sapl.parlamentares:parlamentar_list") - url = "%s%s" % ( - url, - "?hdn_num_legislatura=%s" % (numero_legislatura) - ) + url = "%s%s" % (url, "?hdn_num_legislatura=%s" % (numero_legislatura)) url_e = "%s%s" % (url_e, "?pk=%s" % numero_legislatura) response = self.client.get(url) @@ -49,8 +44,7 @@ class RedirecionaParlamentarTests(TestCase): pk_parlamentar = 21 url = "%s%s" % (url, "?cod_parlamentar=%s" % (pk_parlamentar)) url_e = reverse( - 'sapl.parlamentares:parlamentar_detail', - kwargs={'pk': pk_parlamentar} + "sapl.parlamentares:parlamentar_detail", kwargs={"pk": pk_parlamentar} ) response = self.client.get(url) self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) @@ -58,39 +52,34 @@ class RedirecionaParlamentarTests(TestCase): class RedirecionaComissaoTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_comissao' + url_pattern = "sapl.redireciona_urls:redireciona_comissao" def test_redireciona_comissao_detail(self): url = reverse(self.url_pattern) pk_comissao = 21 url = "%s%s" % (url, "?cod_comissao=%s" % (pk_comissao)) - url_e = reverse( - 'sapl.comissoes:comissao_detail', - kwargs={'pk': pk_comissao} - ) + url_e = reverse("sapl.comissoes:comissao_detail", kwargs={"pk": pk_comissao}) response = self.client.get(url) self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) self.assertEqual(response.url, url_e) def test_redireciona_comissao_list(self): url = reverse(self.url_pattern) - url_e = reverse( - 'sapl.comissoes:comissao_list') + url_e = reverse("sapl.comissoes:comissao_list") response = self.client.get(url) self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) self.assertEqual(response.url, url_e) class RedirecionaPautaSessaoTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_pauta_sessao_' + url_pattern = "sapl.redireciona_urls:redireciona_pauta_sessao_" def test_redireciona_pauta_sessao_detail(self): url = reverse(self.url_pattern) pk_pauta_sessao = 21 url = "%s%s" % (url, "?cod_sessao_plen=%s" % (pk_pauta_sessao)) url_e = reverse( - 'sapl.sessao:pauta_sessao_detail', - kwargs={'pk': pk_pauta_sessao} + "sapl.sessao:pauta_sessao_detail", kwargs={"pk": pk_pauta_sessao} ) response = self.client.get(url) self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) @@ -98,7 +87,7 @@ class RedirecionaPautaSessaoTests(TestCase): def test_redireciona_pauta_sessao_list(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.sessao:pesquisar_pauta') + url_e = reverse("sapl.sessao:pesquisar_pauta") response = self.client.get(url) @@ -106,7 +95,6 @@ class RedirecionaPautaSessaoTests(TestCase): self.assertEqual(response.url, url_e) def test_redireciona_pauta_sessao_list_por_dat_sessao_sel(self): - url = reverse(self.url_pattern) ano_s_p = "2016" @@ -116,7 +104,7 @@ class RedirecionaPautaSessaoTests(TestCase): url = "%s%s" % (url, "?dat_sessao_sel=%s" % data_s_p) - url_e = reverse('sapl.sessao:pesquisar_pauta') + url_e = reverse("sapl.sessao:pesquisar_pauta") args_e = EMPTY_STRING args_e += "?data_inicio__year=%s" % (ano_s_p) @@ -133,11 +121,11 @@ class RedirecionaPautaSessaoTests(TestCase): class RedirecionaMesaDiretoraTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_mesa_diretora' + url_pattern = "sapl.redireciona_urls:redireciona_mesa_diretora" def test_redireciona_mesa_diretora(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.parlamentares:mesa_diretora') + url_e = reverse("sapl.parlamentares:mesa_diretora") response = self.client.get(url) @@ -146,15 +134,14 @@ class RedirecionaMesaDiretoraTests(TestCase): class RedirecionaMesaDiretoraParlamentarTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_mesa_diretora_parlamentar' + url_pattern = "sapl.redireciona_urls:redireciona_mesa_diretora_parlamentar" def test_redireciona_mesa_diretora_parlamentar(self): url = reverse(self.url_pattern) pk_parlamentar = 21 url = "%s%s" % (url, "?cod_parlamentar=%s" % (pk_parlamentar)) url_e = reverse( - 'sapl.parlamentares:parlamentar_detail', - kwargs={'pk': pk_parlamentar} + "sapl.parlamentares:parlamentar_detail", kwargs={"pk": pk_parlamentar} ) response = self.client.get(url) @@ -164,11 +151,11 @@ class RedirecionaMesaDiretoraParlamentarTests(TestCase): class RedirecionaNormasJuridicasListTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_norma_juridica_pesquisa' + url_pattern = "sapl.redireciona_urls:redireciona_norma_juridica_pesquisa" def test_redireciona_norma_juridica_pesquisa_sem_parametros(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.norma:norma_pesquisa') + url_e = reverse("sapl.norma:norma_pesquisa") tipo_norma = EMPTY_STRING numero_norma = EMPTY_STRING @@ -190,7 +177,7 @@ class RedirecionaNormasJuridicasListTests(TestCase): args += "&dt_public2=%s" % (periodo_final_publicacao) args += "&txt_assunto=%s" % (ementa_norma) args += "&lst_assunto_norma=%s" % (assuntos_norma) - args += "&salvar=%s" % ('Pesquisar') + args += "&salvar=%s" % ("Pesquisar") url = "%s%s" % (url, args) args_e = EMPTY_STRING @@ -203,7 +190,7 @@ class RedirecionaNormasJuridicasListTests(TestCase): args_e += "&data_publicacao_1=%s" % (periodo_final_publicacao) args_e += "&ementa=%s" % (ementa_norma) args_e += "&assuntos=%s" % (assuntos_norma) - args_e += "&salvar=%s" % ('Pesquisar') + args_e += "&salvar=%s" % ("Pesquisar") url_e = "%s%s" % (url_e, args_e) response = self.client.get(url) @@ -212,9 +199,9 @@ class RedirecionaNormasJuridicasListTests(TestCase): def test_redireciona_norma_juridica_pesquisa_por_tipo(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.norma:norma_pesquisa') + url_e = reverse("sapl.norma:norma_pesquisa") - tipo_norma = '4' + tipo_norma = "4" numero_norma = EMPTY_STRING ano_norma = EMPTY_STRING periodo_inicial_aprovacao = EMPTY_STRING @@ -234,7 +221,7 @@ class RedirecionaNormasJuridicasListTests(TestCase): args += "&dt_public2=%s" % (periodo_final_publicacao) args += "&txt_assunto=%s" % (ementa_norma) args += "&lst_assunto_norma=%s" % (assuntos_norma) - args += "&salvar=%s" % ('Pesquisar') + args += "&salvar=%s" % ("Pesquisar") url = "%s%s" % (url, args) args_e = EMPTY_STRING @@ -247,7 +234,7 @@ class RedirecionaNormasJuridicasListTests(TestCase): args_e += "&data_publicacao_1=%s" % (periodo_final_publicacao) args_e += "&ementa=%s" % (ementa_norma) args_e += "&assuntos=%s" % (assuntos_norma) - args_e += "&salvar=%s" % ('Pesquisar') + args_e += "&salvar=%s" % ("Pesquisar") url_e = "%s%s" % (url_e, args_e) response = self.client.get(url) @@ -256,11 +243,11 @@ class RedirecionaNormasJuridicasListTests(TestCase): def test_redireciona_norma_juridica_pesquisa_por_ano(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.norma:norma_pesquisa') + url_e = reverse("sapl.norma:norma_pesquisa") tipo_norma = EMPTY_STRING numero_norma = EMPTY_STRING - ano_norma = '2010' + ano_norma = "2010" periodo_inicial_aprovacao = EMPTY_STRING periodo_final_aprovacao = EMPTY_STRING periodo_inicial_publicacao = EMPTY_STRING @@ -278,7 +265,7 @@ class RedirecionaNormasJuridicasListTests(TestCase): args += "&dt_public2=%s" % (periodo_final_publicacao) args += "&txt_assunto=%s" % (ementa_norma) args += "&lst_assunto_norma=%s" % (assuntos_norma) - args += "&salvar=%s" % ('Pesquisar') + args += "&salvar=%s" % ("Pesquisar") url = "%s%s" % (url, args) args_e = EMPTY_STRING @@ -291,7 +278,7 @@ class RedirecionaNormasJuridicasListTests(TestCase): args_e += "&data_publicacao_1=%s" % (periodo_final_publicacao) args_e += "&ementa=%s" % (ementa_norma) args_e += "&assuntos=%s" % (assuntos_norma) - args_e += "&salvar=%s" % ('Pesquisar') + args_e += "&salvar=%s" % ("Pesquisar") url_e = "%s%s" % (url_e, args_e) response = self.client.get(url) @@ -300,7 +287,7 @@ class RedirecionaNormasJuridicasListTests(TestCase): class RedirecionaNormasJuridicasDetailTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_norma_juridica_detail' + url_pattern = "sapl.redireciona_urls:redireciona_norma_juridica_detail" def test_redireciona_norma_juridica_detail(self): url = reverse(self.url_pattern) @@ -311,11 +298,7 @@ class RedirecionaNormasJuridicasDetailTests(TestCase): args += "?cod_norma=%s" % (pk_norma) url = "%s%s" % (url, args) - url_e = reverse( - 'sapl.norma:normajuridica_detail', - kwargs={ - 'pk': pk_norma} - ) + url_e = reverse("sapl.norma:normajuridica_detail", kwargs={"pk": pk_norma}) response = self.client.get(url) self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) @@ -330,7 +313,7 @@ class RedirecionaNormasJuridicasDetailTests(TestCase): args += "?cod_norma=%s" % (pk_norma) url = "%s%s" % (url, args) - url_e = reverse('sapl.norma:norma_pesquisa') + url_e = reverse("sapl.norma:norma_pesquisa") response = self.client.get(url) self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) @@ -338,15 +321,14 @@ class RedirecionaNormasJuridicasDetailTests(TestCase): class RedirecionaSessaoPlenariaTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_sessao_plenaria_' + url_pattern = "sapl.redireciona_urls:redireciona_sessao_plenaria_" def test_redireciona_sessao_plenaria_detail(self): url = reverse(self.url_pattern) pk_sessao_plenaria = 258 url = "%s%s" % (url, "?cod_sessao_plen=%s" % (pk_sessao_plenaria)) url_e = reverse( - 'sapl.sessao:sessaoplenaria_detail', - kwargs={'pk': pk_sessao_plenaria} + "sapl.sessao:sessaoplenaria_detail", kwargs={"pk": pk_sessao_plenaria} ) response = self.client.get(url) @@ -356,7 +338,7 @@ class RedirecionaSessaoPlenariaTests(TestCase): def test_redireciona_sessao_plenaria_list_sem_parametro(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.sessao:pesquisar_sessao') + url_e = reverse("sapl.sessao:pesquisar_sessao") year = EMPTY_STRING month = EMPTY_STRING @@ -386,11 +368,11 @@ class RedirecionaSessaoPlenariaTests(TestCase): def test_redireciona_sessao_plenaria_list_sem_tipo(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.sessao:pesquisar_sessao') + url_e = reverse("sapl.sessao:pesquisar_sessao") - year = '2015' - month = '04' - day = '06' + year = "2015" + month = "04" + day = "06" tipo_sessao = EMPTY_STRING args = EMPTY_STRING @@ -416,11 +398,11 @@ class RedirecionaSessaoPlenariaTests(TestCase): def test_redireciona_sessao_plenaria_list_sem_tipo_e_ano(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.sessao:pesquisar_sessao') + url_e = reverse("sapl.sessao:pesquisar_sessao") year = EMPTY_STRING - month = '04' - day = '06' + month = "04" + day = "06" tipo_sessao = EMPTY_STRING args = EMPTY_STRING @@ -446,12 +428,12 @@ class RedirecionaSessaoPlenariaTests(TestCase): def test_redireciona_sessao_plenaria_list_sem_ano(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.sessao:pesquisar_sessao') + url_e = reverse("sapl.sessao:pesquisar_sessao") year = EMPTY_STRING - month = '04' - day = '06' - tipo_sessao = '4' + month = "04" + day = "06" + tipo_sessao = "4" args = EMPTY_STRING args += "?ano_sessao_sel=%s" % (year) @@ -475,12 +457,12 @@ class RedirecionaSessaoPlenariaTests(TestCase): def test_redireciona_sessao_plenaria_list_sem_mes_dia(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.sessao:pesquisar_sessao') + url_e = reverse("sapl.sessao:pesquisar_sessao") - year = '2015' + year = "2015" month = EMPTY_STRING day = EMPTY_STRING - tipo_sessao = '4' + tipo_sessao = "4" args = EMPTY_STRING args += "?ano_sessao_sel=%s" % (year) @@ -504,13 +486,13 @@ class RedirecionaSessaoPlenariaTests(TestCase): class RedirecionaHistoricoTramitacoesListTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_historico_tramitacoes' + url_pattern = "sapl.redireciona_urls:redireciona_historico_tramitacoes" def test_redireciona_historico_tramitacoes_sem_parametros(self): args_e = EMPTY_STRING args = EMPTY_STRING url = reverse(self.url_pattern) - url_e = reverse('sapl.base:historico_tramitacoes') + url_e = reverse("sapl.base:historico_tramitacoes") inicio_dt_tramitacao = EMPTY_STRING fim_dt_tramitacao = EMPTY_STRING @@ -523,7 +505,7 @@ class RedirecionaHistoricoTramitacoesListTests(TestCase): args += "&lst_tip_materia=%s" % (tipo_materia) args += "&lst_cod_unid_tram_dest=%s" % (unidade_local_tramitacao) args += "&lst_status=%s" % (status_tramitacao) - args += "&btn_materia_pesquisar=%s" % ('Pesquisar') + args += "&btn_materia_pesquisar=%s" % ("Pesquisar") url = "%s%s" % (url, args) # Remove zeros à esquerda @@ -534,20 +516,20 @@ class RedirecionaHistoricoTramitacoesListTests(TestCase): status_tramitacao = status_tramitacao.lstrip("0") if ( - (inicio_dt_tramitacao != EMPTY_STRING) or - (fim_dt_tramitacao != EMPTY_STRING) or - (tipo_materia != EMPTY_STRING) or - (unidade_local_tramitacao != EMPTY_STRING) or - (status_tramitacao != EMPTY_STRING)): - args_e += "?tramitacao__data_tramitacao_0=%s" % ( - inicio_dt_tramitacao) - args_e += "&tramitacao__data_tramitacao_1=%s" % ( - fim_dt_tramitacao) + (inicio_dt_tramitacao != EMPTY_STRING) + or (fim_dt_tramitacao != EMPTY_STRING) + or (tipo_materia != EMPTY_STRING) + or (unidade_local_tramitacao != EMPTY_STRING) + or (status_tramitacao != EMPTY_STRING) + ): + args_e += "?tramitacao__data_tramitacao_0=%s" % (inicio_dt_tramitacao) + args_e += "&tramitacao__data_tramitacao_1=%s" % (fim_dt_tramitacao) args_e += "&tipo=%s" % (tipo_materia) args_e += "&tramitacao__unidade_tramitacao_local=%s" % ( - unidade_local_tramitacao) + unidade_local_tramitacao + ) args_e += "&tramitacao__status=%s" % (status_tramitacao) - args_e += "&salvar=%s" % ('Pesquisar') + args_e += "&salvar=%s" % ("Pesquisar") url_e = "%s%s" % (url_e, args_e) @@ -559,20 +541,20 @@ class RedirecionaHistoricoTramitacoesListTests(TestCase): args = EMPTY_STRING args_e = EMPTY_STRING url = reverse(self.url_pattern) - url_e = reverse('sapl.base:historico_tramitacoes') + url_e = reverse("sapl.base:historico_tramitacoes") - inicio_dt_tramitacao = '12/07/2000' - fim_dt_tramitacao = '26/05/2017' - unidade_local_tramitacao = '0' - tipo_materia = '0' - status_tramitacao = '0' + inicio_dt_tramitacao = "12/07/2000" + fim_dt_tramitacao = "26/05/2017" + unidade_local_tramitacao = "0" + tipo_materia = "0" + status_tramitacao = "0" args += "?txt_dat_inicio_periodo=%s" % (inicio_dt_tramitacao) args += "&txt_dat_fim_periodo=%s" % (fim_dt_tramitacao) args += "&lst_tip_materia=%s" % (tipo_materia) args += "&lst_cod_unid_tram_dest=%s" % (unidade_local_tramitacao) args += "&lst_status=%s" % (status_tramitacao) - args += "&btn_materia_pesquisar=%s" % ('Pesquisar') + args += "&btn_materia_pesquisar=%s" % ("Pesquisar") url = "%s%s" % (url, args) # Remove zeros à esquerda @@ -583,20 +565,20 @@ class RedirecionaHistoricoTramitacoesListTests(TestCase): status_tramitacao = status_tramitacao.lstrip("0") if ( - (inicio_dt_tramitacao != EMPTY_STRING) or - (fim_dt_tramitacao != EMPTY_STRING) or - (tipo_materia != EMPTY_STRING) or - (unidade_local_tramitacao != EMPTY_STRING) or - (status_tramitacao != EMPTY_STRING)): - args_e += "?tramitacao__data_tramitacao_0=%s" % ( - inicio_dt_tramitacao) - args_e += "&tramitacao__data_tramitacao_1=%s" % ( - fim_dt_tramitacao) + (inicio_dt_tramitacao != EMPTY_STRING) + or (fim_dt_tramitacao != EMPTY_STRING) + or (tipo_materia != EMPTY_STRING) + or (unidade_local_tramitacao != EMPTY_STRING) + or (status_tramitacao != EMPTY_STRING) + ): + args_e += "?tramitacao__data_tramitacao_0=%s" % (inicio_dt_tramitacao) + args_e += "&tramitacao__data_tramitacao_1=%s" % (fim_dt_tramitacao) args_e += "&tipo=%s" % (tipo_materia) args_e += "&tramitacao__unidade_tramitacao_local=%s" % ( - unidade_local_tramitacao) + unidade_local_tramitacao + ) args_e += "&tramitacao__status=%s" % (status_tramitacao) - args_e += "&salvar=%s" % ('Pesquisar') + args_e += "&salvar=%s" % ("Pesquisar") url_e = "%s%s" % (url_e, args_e) @@ -606,32 +588,28 @@ class RedirecionaHistoricoTramitacoesListTests(TestCase): class RedirecionaPresencaParlamentaresTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_presencaparlamentar_list' + url_pattern = "sapl.redireciona_urls:redireciona_presencaparlamentar_list" def test_redireciona_presenca_list_sem_parametros(self): args_e = EMPTY_STRING args = EMPTY_STRING url = reverse(self.url_pattern) - url_e = reverse('sapl.base:presenca_sessao') + url_e = reverse("sapl.base:presenca_sessao") inicio_intervalo_presenca = EMPTY_STRING fim_intervalo_presenca = EMPTY_STRING - args += "?txt_dat_inicio=%s" % ( - inicio_intervalo_presenca) - args += "&txt_dat_fim=%s" % ( - fim_intervalo_presenca) + args += "?txt_dat_inicio=%s" % (inicio_intervalo_presenca) + args += "&txt_dat_fim=%s" % (fim_intervalo_presenca) url = "%s%s" % (url, args) # Remove zeros à esquerda inicio_intervalo_presenca = inicio_intervalo_presenca.lstrip("0") fim_intervalo_presenca = fim_intervalo_presenca.lstrip("0") - args_e += "?data_inicio_0=%s" % ( - inicio_intervalo_presenca) - args_e += "&data_inicio_1=%s" % ( - fim_intervalo_presenca) - args_e += "&salvar=%s" % ('Pesquisar') + args_e += "?data_inicio_0=%s" % (inicio_intervalo_presenca) + args_e += "&data_inicio_1=%s" % (fim_intervalo_presenca) + args_e += "&salvar=%s" % ("Pesquisar") url_e = "%s%s" % (url_e, args_e) @@ -643,26 +621,22 @@ class RedirecionaPresencaParlamentaresTests(TestCase): args_e = EMPTY_STRING args = EMPTY_STRING url = reverse(self.url_pattern) - url_e = reverse('sapl.base:presenca_sessao') + url_e = reverse("sapl.base:presenca_sessao") - inicio_intervalo_presenca = '01/02/2015' - fim_intervalo_presenca = '01/02/2017' + inicio_intervalo_presenca = "01/02/2015" + fim_intervalo_presenca = "01/02/2017" - args += "?txt_dat_inicio=%s" % ( - inicio_intervalo_presenca) - args += "&txt_dat_fim=%s" % ( - fim_intervalo_presenca) + args += "?txt_dat_inicio=%s" % (inicio_intervalo_presenca) + args += "&txt_dat_fim=%s" % (fim_intervalo_presenca) url = "%s%s" % (url, args) # Remove zeros à esquerda inicio_intervalo_presenca = inicio_intervalo_presenca.lstrip("0") fim_intervalo_presenca = fim_intervalo_presenca.lstrip("0") - args_e += "?data_inicio_0=%s" % ( - inicio_intervalo_presenca) - args_e += "&data_inicio_1=%s" % ( - fim_intervalo_presenca) - args_e += "&salvar=%s" % ('Pesquisar') + args_e += "?data_inicio_0=%s" % (inicio_intervalo_presenca) + args_e += "&data_inicio_1=%s" % (fim_intervalo_presenca) + args_e += "&salvar=%s" % ("Pesquisar") url_e = "%s%s" % (url_e, args_e) @@ -672,11 +646,11 @@ class RedirecionaPresencaParlamentaresTests(TestCase): class RedirecionaMateriasPorAutorTests(TestCase): - url_pattern = 'sapl.redireciona_urls:redireciona_materias_por_autor_list' + url_pattern = "sapl.redireciona_urls:redireciona_materias_por_autor_list" def test_redireciona_materias_por_autor_list_sem_parametros(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.base:materia_por_autor') + url_e = reverse("sapl.base:materia_por_autor") response = self.client.get(url) self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) @@ -684,12 +658,11 @@ class RedirecionaMateriasPorAutorTests(TestCase): class RedirecionaMateriasPorAnoAutorTipoTests(TestCase): - url_pattern = ( - 'sapl.redireciona_urls:redireciona_materia_por_ano_autor_tipo_list') + url_pattern = "sapl.redireciona_urls:redireciona_materia_por_ano_autor_tipo_list" def test_redireciona_materias_por_ano_autor_tipo_list_sem_parametros(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.base:materia_por_ano_autor_tipo') + url_e = reverse("sapl.base:materia_por_ano_autor_tipo") response = self.client.get(url) self.assertEqual(response.status_code, MovedPermanentlyHTTPStatusCode) @@ -697,7 +670,7 @@ class RedirecionaMateriasPorAnoAutorTipoTests(TestCase): def test_redireciona_materias_por_ano_autor_tipo_list(self): url = reverse(self.url_pattern) - url_e = reverse('sapl.base:materia_por_ano_autor_tipo') + url_e = reverse("sapl.base:materia_por_ano_autor_tipo") ano = 2017 diff --git a/sapl/redireciona_urls/urls.py b/sapl/redireciona_urls/urls.py index bf8d8e564..0404fde04 100644 --- a/sapl/redireciona_urls/urls.py +++ b/sapl/redireciona_urls/urls.py @@ -19,67 +19,105 @@ from .views import (RedirecionaAtasList, RedirecionaComissao, app_name = AppConfig.name urlpatterns = [ - path('default_index_html', + path( + "default_index_html", RedirecionaSAPLIndex.as_view(), - name='redireciona_sapl_index'), - re_path(r'^consultas/parlamentar/parlamentar_', + name="redireciona_sapl_index", + ), + re_path( + r"^consultas/parlamentar/parlamentar_", RedirecionaParlamentar.as_view(), - name='redireciona_parlamentar'), - re_path(r'^consultas/comissao/comissao_', + name="redireciona_parlamentar", + ), + re_path( + r"^consultas/comissao/comissao_", RedirecionaComissao.as_view(), - name='redireciona_comissao'), - re_path(r'^consultas/comissao/composicao/composicao_index_html', + name="redireciona_comissao", + ), + re_path( + r"^consultas/comissao/composicao/composicao_index_html", RedirecionaComposicaoComissao.as_view(), - name='redireciona_composicaio_comissao'), - re_path(r'^consultas/pauta_sessao/pauta_sessao_', + name="redireciona_composicaio_comissao", + ), + re_path( + r"^consultas/pauta_sessao/pauta_sessao_", RedirecionaPautaSessao.as_view(), - name='redireciona_pauta_sessao_'), - re_path(r'^consultas/mesa_diretora/mesa_diretora_index_html', + name="redireciona_pauta_sessao_", + ), + re_path( + r"^consultas/mesa_diretora/mesa_diretora_index_html", RedirecionaMesaDiretoraView.as_view(), - name='redireciona_mesa_diretora'), - re_path(r'^consultas/mesa_diretora/parlamentar/parlamentar_', + name="redireciona_mesa_diretora", + ), + re_path( + r"^consultas/mesa_diretora/parlamentar/parlamentar_", RedirecionaParlamentar.as_view(), - name='redireciona_mesa_diretora_parlamentar'), - re_path(r'^consultas/sessao_plenaria/', + name="redireciona_mesa_diretora_parlamentar", + ), + re_path( + r"^consultas/sessao_plenaria/", RedirecionaSessaoPlenaria.as_view(), - name='redireciona_sessao_plenaria_'), - re_path(r'^generico/norma_juridica_pesquisar_', + name="redireciona_sessao_plenaria_", + ), + re_path( + r"^generico/norma_juridica_pesquisar_", RedirecionaNormasJuridicasList.as_view(), - name='redireciona_norma_juridica_pesquisa'), - re_path(r'^consultas/norma_juridica/norma_juridica_mostrar_proc', + name="redireciona_norma_juridica_pesquisa", + ), + re_path( + r"^consultas/norma_juridica/norma_juridica_mostrar_proc", RedirecionaNormasJuridicasDetail.as_view(), - name='redireciona_norma_juridica_detail'), - re_path(r'^sapl_documentos/norma_juridica/(?P[0-9]+)_texto_integral', + name="redireciona_norma_juridica_detail", + ), + re_path( + r"^sapl_documentos/norma_juridica/(?P[0-9]+)_texto_integral", RedirecionaNormasJuridicasTextoIntegral.as_view(), - name='redireciona_norma_juridica_texto_integral'), - path('relatorios_administrativos/relatorios_administrativos_index_html', + name="redireciona_norma_juridica_texto_integral", + ), + path( + "relatorios_administrativos/relatorios_administrativos_index_html", RedirecionaRelatoriosList.as_view(), - name='redireciona_relatorios_list'), - re_path(r'tramitacaoMaterias/tramitacaoMaterias', + name="redireciona_relatorios_list", + ), + re_path( + r"tramitacaoMaterias/tramitacaoMaterias", RedirecionaRelatoriosMateriasEmTramitacaoList.as_view(), - name='redireciona_relatorio_materia_por_tramitacao'), - path('tramitacaoMaterias/materia_mostrar_proc', + name="redireciona_relatorio_materia_por_tramitacao", + ), + path( + "tramitacaoMaterias/materia_mostrar_proc", RedirecionaMateriaLegislativaDetail.as_view(), - name='redireciona_materialegislativa_detail_tramitacao'), - path('consultas/materia/materia_mostrar_proc', + name="redireciona_materialegislativa_detail_tramitacao", + ), + path( + "consultas/materia/materia_mostrar_proc", RedirecionaMateriaLegislativaDetail.as_view(), - name='redireciona_materialegislativa_detail'), - re_path(r'^generico/materia_pesquisar_', + name="redireciona_materialegislativa_detail", + ), + re_path( + r"^generico/materia_pesquisar_", RedirecionaMateriaLegislativaList.as_view(), - name='redireciona_materialegislativa_list'), - re_path(r'historicoTramitacoes/historicoTramitacoes', + name="redireciona_materialegislativa_list", + ), + re_path( + r"historicoTramitacoes/historicoTramitacoes", RedirecionaHistoricoTramitacoesList.as_view(), - name='redireciona_historico_tramitacoes'), - re_path(r'atasSessao', - RedirecionaAtasList.as_view(), - name='redireciona_atas_list'), - re_path(r'presencaSessao', + name="redireciona_historico_tramitacoes", + ), + re_path(r"atasSessao", RedirecionaAtasList.as_view(), name="redireciona_atas_list"), + re_path( + r"presencaSessao", RedirecionaPresencaParlamentares.as_view(), - name='redireciona_presencaparlamentar_list'), - re_path(r'resumoPropositurasAutor', + name="redireciona_presencaparlamentar_list", + ), + re_path( + r"resumoPropositurasAutor", RedirecionaMateriasPorAutor.as_view(), - name='redireciona_materias_por_autor_list'), - re_path(r'propositurasAnoAutorTipo', + name="redireciona_materias_por_autor_list", + ), + re_path( + r"propositurasAnoAutorTipo", RedirecionaMateriasPorAnoAutorTipo.as_view(), - name='redireciona_materia_por_ano_autor_tipo_list'), -] \ No newline at end of file + name="redireciona_materia_por_ano_autor_tipo_list", + ), +] diff --git a/sapl/redireciona_urls/views.py b/sapl/redireciona_urls/views.py index 435280b3b..589700d1e 100644 --- a/sapl/redireciona_urls/views.py +++ b/sapl/redireciona_urls/views.py @@ -11,9 +11,10 @@ from sapl.norma.apps import AppConfig as normaConfig from sapl.norma.models import NormaJuridica from sapl.parlamentares.apps import AppConfig as parlamentaresConfig from sapl.sessao.apps import AppConfig as sessaoConfig + from .exceptions import UnknownUrlNameError -EMPTY_STRING = '' +EMPTY_STRING = "" presenca_sessaoConfig = relatoriosConfig = atasConfig @@ -27,45 +28,41 @@ app_norma = normaConfig.name app_relatorios = relatoriosConfig.name app_audiencia = audienciaConfig.name -pesquisar_atas = (app_atas + ':atas') -presenca_sessao = (app_presenca_sessao + ':presenca_sessao') -parlamentar_list = (app_parlamentares + ':parlamentar_list') -parlamentar_detail = (app_parlamentares + ':parlamentar_detail') -parlamentar_mesa_diretora = (app_parlamentares + ':mesa_diretora') +pesquisar_atas = app_atas + ":atas" +presenca_sessao = app_presenca_sessao + ":presenca_sessao" +parlamentar_list = app_parlamentares + ":parlamentar_list" +parlamentar_detail = app_parlamentares + ":parlamentar_detail" +parlamentar_mesa_diretora = app_parlamentares + ":mesa_diretora" -comissao_list = (app_comissoes + ':comissao_list') -comissao_detail = (app_comissoes + ':comissao_detail') +comissao_list = app_comissoes + ":comissao_list" +comissao_detail = app_comissoes + ":comissao_detail" -audiencia = (app_audiencia + ':audiencia') -reuniao_detail = (app_comissoes + ':reuniao_detail') +audiencia = app_audiencia + ":audiencia" +reuniao_detail = app_comissoes + ":reuniao_detail" -materialegislativa_detail = (app_materia + ':materialegislativa_detail') -materialegislativa_list = (app_materia + ':pesquisar_materia') +materialegislativa_detail = app_materia + ":materialegislativa_detail" +materialegislativa_list = app_materia + ":pesquisar_materia" -pauta_sessao_list = (app_sessao + ':pesquisar_pauta') -pauta_sessao_detail = (app_sessao + ':pauta_sessao_detail') -sessao_plenaria_list = (app_sessao + ':pesquisar_sessao') -sessao_plenaria_detail = (app_sessao + ':sessaoplenaria_detail') +pauta_sessao_list = app_sessao + ":pesquisar_pauta" +pauta_sessao_detail = app_sessao + ":pauta_sessao_detail" +sessao_plenaria_list = app_sessao + ":pesquisar_sessao" +sessao_plenaria_detail = app_sessao + ":sessaoplenaria_detail" -norma_juridica_detail = (app_norma + ':normajuridica_detail') -norma_juridica_pesquisa = (app_norma + ':norma_pesquisa') +norma_juridica_detail = app_norma + ":normajuridica_detail" +norma_juridica_pesquisa = app_norma + ":norma_pesquisa" -relatorios_list = (app_relatorios + ':relatorios_list') -relatorio_materia_por_tramitacao = (app_relatorios + ':materia_por_tramitacao') -relatorio_materia_por_autor = (app_relatorios + ':materia_por_autor') -relatorio_materia_por_ano_autor_tipo = ( - app_relatorios + ':materia_por_ano_autor_tipo') -historico_tramitacoes = (app_relatorios + ':historico_tramitacoes') +relatorios_list = app_relatorios + ":relatorios_list" +relatorio_materia_por_tramitacao = app_relatorios + ":materia_por_tramitacao" +relatorio_materia_por_autor = app_relatorios + ":materia_por_autor" +relatorio_materia_por_ano_autor_tipo = app_relatorios + ":materia_por_ano_autor_tipo" +historico_tramitacoes = app_relatorios + ":historico_tramitacoes" def has_iframe(url, request): - - iframe = request.GET.get( - 'iframe', - EMPTY_STRING) + iframe = request.GET.get("iframe", EMPTY_STRING) if iframe: - iframe_qs = ("iframe=" + iframe) - url += ("&" if "?" in url else "?") + iframe_qs = "iframe=" + iframe + url += "&" if "?" in url else "?" url += iframe_qs return url @@ -76,14 +73,13 @@ class RedirecionaSAPLIndex(RedirectView): logger = logging.getLogger(__name__) def get_redirect_url(self): - url_pattern = 'sapl.base:sapl_index' + url_pattern = "sapl.base:sapl_index" username = self.request.user.username try: self.logger.info("user=" + username + ". Tentando obter url.") url = reverse(url_pattern) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(url_pattern) url = has_iframe(url, self.request) @@ -96,37 +92,33 @@ class RedirecionaParlamentar(RedirectView): logger = logging.getLogger(__name__) def get_redirect_url(self): - url = EMPTY_STRING - pk_parlamentar = self.request.GET.get( - 'cod_parlamentar', - EMPTY_STRING) + pk_parlamentar = self.request.GET.get("cod_parlamentar", EMPTY_STRING) username = self.request.user.username if pk_parlamentar: try: - kwargs = {'pk': pk_parlamentar} - self.logger.debug("user=" + username + - ". Tentando obter url correspondente.") + kwargs = {"pk": pk_parlamentar} + self.logger.debug( + "user=" + username + ". Tentando obter url correspondente." + ) url = reverse(parlamentar_detail, kwargs=kwargs) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(parlamentar_detail, kwargs=kwargs) else: try: self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(parlamentar_list) except NoReverseMatch: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(parlamentar_list) numero_legislatura = self.request.GET.get( - 'hdn_num_legislatura', - EMPTY_STRING) + "hdn_num_legislatura", EMPTY_STRING + ) if numero_legislatura: - args = '?pk=' + numero_legislatura + args = "?pk=" + numero_legislatura url = "%s%s" % (url, args) url = has_iframe(url, self.request) @@ -140,27 +132,26 @@ class RedirecionaComissao(RedirectView): def get_redirect_url(self): url = EMPTY_STRING - pk_comissao = self.request.GET.get('cod_comissao', EMPTY_STRING) + pk_comissao = self.request.GET.get("cod_comissao", EMPTY_STRING) username = self.request.user.username if pk_comissao: - kwargs = {'pk': pk_comissao} + kwargs = {"pk": pk_comissao} try: - self.logger.debug("user=" + username + - ". Tentando obter url correspondente.") + self.logger.debug( + "user=" + username + ". Tentando obter url correspondente." + ) url = reverse(comissao_detail, kwargs=kwargs) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(comissao_detail) else: try: self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(comissao_list) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(comissao_list) url = has_iframe(url, self.request) @@ -174,29 +165,27 @@ class RedirecionaComposicaoComissao(RedirectView): def get_redirect_url(self): url = EMPTY_STRING - pk_composicao = self.request.GET.get( - 'cod_periodo_comp_sel', EMPTY_STRING) - pk_comissao = self.request.GET.get('cod_comissao', EMPTY_STRING) + pk_composicao = self.request.GET.get("cod_periodo_comp_sel", EMPTY_STRING) + pk_comissao = self.request.GET.get("cod_comissao", EMPTY_STRING) username = self.request.user.username if pk_comissao: - kwargs = {'pk': pk_comissao} + kwargs = {"pk": pk_comissao} try: - self.logger.debug("user=" + username + - ". Tentando obter url correspondente.") + self.logger.debug( + "user=" + username + ". Tentando obter url correspondente." + ) url = reverse(comissao_detail, kwargs=kwargs) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(comissao_detail) else: try: self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(comissao_list) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(comissao_list) url = has_iframe(url, self.request) @@ -209,37 +198,31 @@ class RedirecionaPautaSessao(RedirectView): logger = logging.getLogger(__name__) def get_redirect_url(self): - - pk_sessao_plenaria = self.request.GET.get( - 'cod_sessao_plen', - EMPTY_STRING) + pk_sessao_plenaria = self.request.GET.get("cod_sessao_plen", EMPTY_STRING) username = self.request.user.username if pk_sessao_plenaria: - kwargs = {'pk': pk_sessao_plenaria} + kwargs = {"pk": pk_sessao_plenaria} try: - self.logger.debug("user=" + username + - ". Tentando obter url correspondente.") + self.logger.debug( + "user=" + username + ". Tentando obter url correspondente." + ) url = reverse(pauta_sessao_detail, kwargs=kwargs) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(pauta_sessao_detail) else: try: self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(pauta_sessao_list) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(pauta_sessao_list) - data_sessao_plenaria = self.request.GET.get( - 'dat_sessao_sel', - EMPTY_STRING) + data_sessao_plenaria = self.request.GET.get("dat_sessao_sel", EMPTY_STRING) if data_sessao_plenaria: - dia_s_p, mes_s_p, ano_s_p = data_sessao_plenaria.split('/') + dia_s_p, mes_s_p, ano_s_p = data_sessao_plenaria.split("/") # Remove zeros à esquerda de dia_s_p e mes_s_p dia_s_p = dia_s_p.lstrip("0") mes_s_p = mes_s_p.lstrip("0") @@ -260,20 +243,18 @@ class RedirecionaSessaoPlenaria(RedirectView): logger = logging.getLogger(__name__) def get_redirect_url(self): - pk_sessao_plenaria = self.request.GET.get( - 'cod_sessao_plen', - EMPTY_STRING) + pk_sessao_plenaria = self.request.GET.get("cod_sessao_plen", EMPTY_STRING) url = EMPTY_STRING username = self.request.user.username if pk_sessao_plenaria: - kwargs = {'pk': pk_sessao_plenaria} + kwargs = {"pk": pk_sessao_plenaria} try: - self.logger.debug("user=" + username + - ". Tentando obter url correspondente.") + self.logger.debug( + "user=" + username + ". Tentando obter url correspondente." + ) url = reverse(sessao_plenaria_detail, kwargs=kwargs) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(sessao_plenaria_detail) else: @@ -281,22 +262,13 @@ class RedirecionaSessaoPlenaria(RedirectView): self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(sessao_plenaria_list) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(sessao_plenaria_list) - year = self.request.GET.get( - 'ano_sessao_sel', - EMPTY_STRING) - month = self.request.GET.get( - 'mes_sessao_sel', - EMPTY_STRING) - day = self.request.GET.get( - 'dia_sessao_sel', - EMPTY_STRING) - tipo_sessao = self.request.GET.get( - 'tip_sessao_sel', - EMPTY_STRING) + year = self.request.GET.get("ano_sessao_sel", EMPTY_STRING) + month = self.request.GET.get("mes_sessao_sel", EMPTY_STRING) + day = self.request.GET.get("dia_sessao_sel", EMPTY_STRING) + tipo_sessao = self.request.GET.get("tip_sessao_sel", EMPTY_STRING) # Remove zeros à esquerda day = day.lstrip("0") @@ -318,15 +290,13 @@ class RedirecionaRelatoriosList(RedirectView): logger = logging.getLogger(__name__) def get_redirect_url(self): - url = EMPTY_STRING username = self.request.user.username try: self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(relatorios_list) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(relatorios_list) url = has_iframe(url, self.request) @@ -345,26 +315,17 @@ class RedirecionaRelatoriosMateriasEmTramitacaoList(RedirectView): self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(relatorio_materia_por_tramitacao) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(relatorio_materia_por_tramitacao) - year = self.request.GET.get( - 'selAno', - EMPTY_STRING) + year = self.request.GET.get("selAno", EMPTY_STRING) if year: - tramitacao_tipo = self.request.GET.get( - 'lst_tip_materia', - EMPTY_STRING) + tramitacao_tipo = self.request.GET.get("lst_tip_materia", EMPTY_STRING) tramitacao_unidade_local = self.request.GET.get( - 'lst_cod_unid_tram_dest', - EMPTY_STRING) - tramitacao_status = self.request.GET.get( - 'lst_status', - EMPTY_STRING) - salvar = self.request.GET.get( - 'btn_materia_pesquisar', - 'Pesquisar') + "lst_cod_unid_tram_dest", EMPTY_STRING + ) + tramitacao_status = self.request.GET.get("lst_status", EMPTY_STRING) + salvar = self.request.GET.get("btn_materia_pesquisar", "Pesquisar") tramitacao_tipo = tramitacao_tipo.lstrip("0") tramitacao_unidade_local = tramitacao_unidade_local.lstrip("0") @@ -374,7 +335,8 @@ class RedirecionaRelatoriosMateriasEmTramitacaoList(RedirectView): args += "?ano=%s" % (year) args += "&tipo=%s" % (tramitacao_tipo) args += "&tramitacao__unidade_tramitacao_local=%s" % ( - tramitacao_unidade_local) + tramitacao_unidade_local + ) args += "&tramitacao__status=%s" % (tramitacao_status) args += "&salvar=%s" % (salvar) url = "%s%s" % (url, args) @@ -389,10 +351,10 @@ class RedirecionaMateriaLegislativaDetail(RedirectView): def get_redirect_url(self): url = EMPTY_STRING - pk = self.request.GET.get('cod_materia', EMPTY_STRING) + pk = self.request.GET.get("cod_materia", EMPTY_STRING) if pk: - kwargs = {'pk': pk} + kwargs = {"pk": pk} url = reverse(materialegislativa_detail, kwargs=kwargs) else: url = reverse(materialegislativa_list) @@ -414,46 +376,21 @@ class RedirecionaMateriaLegislativaList(RedirectView): self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(materialegislativa_list) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(materialegislativa_list) - tipo_materia = self.request.GET.get( - 'lst_tip_materia', - EMPTY_STRING) - numero_materia = self.request.GET.get( - 'txt_numero', - EMPTY_STRING) - ano_materia = self.request.GET.get( - 'txt_ano', - EMPTY_STRING) - num_protocolo_materia = self.request.GET.get( - 'txt_num_protocolo', - EMPTY_STRING) - periodo_inicial_apresentacao = self.request.GET.get( - 'dt_apres', - EMPTY_STRING) - periodo_final_apresentacao = self.request.GET.get( - 'dt_apres2', - EMPTY_STRING) - periodo_inicial_publicacao = self.request.GET.get( - 'dt_public', - EMPTY_STRING) - periodo_final_publicacao = self.request.GET.get( - 'dt_public2', - EMPTY_STRING) - tipo_autor = self.request.GET.get( - 'lst_tip_autor', - EMPTY_STRING) - ementa_materia = self.request.GET.get( - 'txt_assunto', - EMPTY_STRING) - tramitando = self.request.GET.get( - 'rad_tramitando', - EMPTY_STRING) - status_tramitacao = self.request.GET.get( - 'lst_status', - EMPTY_STRING) + tipo_materia = self.request.GET.get("lst_tip_materia", EMPTY_STRING) + numero_materia = self.request.GET.get("txt_numero", EMPTY_STRING) + ano_materia = self.request.GET.get("txt_ano", EMPTY_STRING) + num_protocolo_materia = self.request.GET.get("txt_num_protocolo", EMPTY_STRING) + periodo_inicial_apresentacao = self.request.GET.get("dt_apres", EMPTY_STRING) + periodo_final_apresentacao = self.request.GET.get("dt_apres2", EMPTY_STRING) + periodo_inicial_publicacao = self.request.GET.get("dt_public", EMPTY_STRING) + periodo_final_publicacao = self.request.GET.get("dt_public2", EMPTY_STRING) + tipo_autor = self.request.GET.get("lst_tip_autor", EMPTY_STRING) + ementa_materia = self.request.GET.get("txt_assunto", EMPTY_STRING) + tramitando = self.request.GET.get("rad_tramitando", EMPTY_STRING) + status_tramitacao = self.request.GET.get("lst_status", EMPTY_STRING) args += "?tipo=%s" % (tipo_materia) args += "&numero=%s" % (numero_materia) @@ -473,7 +410,7 @@ class RedirecionaMateriaLegislativaList(RedirectView): args += "&o=%s" % (EMPTY_STRING) args += "&materiaassunto__assunto=%s" % (EMPTY_STRING) args += "&ementa=%s" % (ementa_materia) - args += "&salvar=%s" % ('Pesquisar') # Default in both SAPL version + args += "&salvar=%s" % ("Pesquisar") # Default in both SAPL version url = "%s%s" % (url, args) @@ -487,15 +424,13 @@ class RedirecionaMesaDiretoraView(RedirectView): logger = logging.getLogger(__name__) def get_redirect_url(self): - url = EMPTY_STRING username = self.request.user.username try: self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(parlamentar_mesa_diretora) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(parlamentar_mesa_diretora) url = has_iframe(url, self.request) @@ -508,10 +443,10 @@ class RedirecionaNormasJuridicasDetail(RedirectView): def get_redirect_url(self): url = EMPTY_STRING - pk_norma = self.request.GET.get('cod_norma', EMPTY_STRING) + pk_norma = self.request.GET.get("cod_norma", EMPTY_STRING) if pk_norma: - kwargs = {'pk': pk_norma} + kwargs = {"pk": pk_norma} url = reverse(norma_juridica_detail, kwargs=kwargs) else: url = reverse(norma_juridica_pesquisa) @@ -530,13 +465,20 @@ class RedirecionaNormasJuridicasTextoIntegral(RedirectView): username = self.request.user.username try: self.logger.debug( - "user=" + username + ". Tentando obter NormaJuridica com pk={}.".format(kwargs['norma_id'])) - norma = NormaJuridica.objects.get(pk=kwargs['norma_id']) + "user=" + + username + + ". Tentando obter NormaJuridica com pk={}.".format(kwargs["norma_id"]) + ) + norma = NormaJuridica.objects.get(pk=kwargs["norma_id"]) if norma: url = norma.texto_integral.url except Exception as e: self.logger.error( - "user=" + username + ". Erro ao obter NormaJuridica com pk={}. ".format(kwargs['norma_id']) + str(e)) + "user=" + + username + + ". Erro ao obter NormaJuridica com pk={}. ".format(kwargs["norma_id"]) + + str(e) + ) raise e url = has_iframe(url, self.request) @@ -545,7 +487,6 @@ class RedirecionaNormasJuridicasTextoIntegral(RedirectView): class RedirecionaNormasJuridicasList(RedirectView): - permanent = True logger = logging.getLogger(__name__) @@ -557,37 +498,18 @@ class RedirecionaNormasJuridicasList(RedirectView): self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(norma_juridica_pesquisa) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(norma_juridica_pesquisa) - tipo_norma = self.request.GET.get( - 'lst_tip_norma', - EMPTY_STRING) - numero_norma = self.request.GET.get( - 'txt_numero', - EMPTY_STRING) - ano_norma = self.request.GET.get( - 'txt_ano', - EMPTY_STRING) - periodo_inicial_aprovacao = self.request.GET.get( - 'dt_norma', - EMPTY_STRING) - periodo_final_aprovacao = self.request.GET.get( - 'dt_norma2', - EMPTY_STRING) - periodo_inicial_publicacao = self.request.GET.get( - 'dt_public', - EMPTY_STRING) - periodo_final_publicacao = self.request.GET.get( - 'dt_public2', - EMPTY_STRING) - ementa_norma = self.request.GET.get( - 'txt_assunto', - EMPTY_STRING) - assuntos_norma = self.request.GET.get( - 'lst_assunto_norma', - EMPTY_STRING) + tipo_norma = self.request.GET.get("lst_tip_norma", EMPTY_STRING) + numero_norma = self.request.GET.get("txt_numero", EMPTY_STRING) + ano_norma = self.request.GET.get("txt_ano", EMPTY_STRING) + periodo_inicial_aprovacao = self.request.GET.get("dt_norma", EMPTY_STRING) + periodo_final_aprovacao = self.request.GET.get("dt_norma2", EMPTY_STRING) + periodo_inicial_publicacao = self.request.GET.get("dt_public", EMPTY_STRING) + periodo_final_publicacao = self.request.GET.get("dt_public2", EMPTY_STRING) + ementa_norma = self.request.GET.get("txt_assunto", EMPTY_STRING) + assuntos_norma = self.request.GET.get("lst_assunto_norma", EMPTY_STRING) args += "?tipo=%s" % (tipo_norma) args += "&numero=%s" % (numero_norma) @@ -598,7 +520,7 @@ class RedirecionaNormasJuridicasList(RedirectView): args += "&data_publicacao_1=%s" % (periodo_final_publicacao) args += "&ementa=%s" % (ementa_norma) args += "&assuntos=%s" % (assuntos_norma) - args += "&salvar=%s" % ('Pesquisar') # Default in both SAPL version + args += "&salvar=%s" % ("Pesquisar") # Default in both SAPL version url = "%s%s" % (url, args) @@ -608,12 +530,10 @@ class RedirecionaNormasJuridicasList(RedirectView): class RedirecionaHistoricoTramitacoesList(RedirectView): - permanent = True logger = logging.getLogger(__name__) def get_redirect_url(self): - url = EMPTY_STRING args = EMPTY_STRING username = self.request.user.username @@ -621,47 +541,40 @@ class RedirecionaHistoricoTramitacoesList(RedirectView): self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(historico_tramitacoes) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(historico_tramitacoes) inicio_intervalo_data_tramitacao = self.request.GET.get( - 'txt_dat_inicio_periodo', - EMPTY_STRING + "txt_dat_inicio_periodo", EMPTY_STRING ).lstrip("0") fim_intervalo_data_tramitacao = self.request.GET.get( - 'txt_dat_fim_periodo', - EMPTY_STRING - ).lstrip("0") - tipo_materia = self.request.GET.get( - 'lst_tip_materia', - EMPTY_STRING + "txt_dat_fim_periodo", EMPTY_STRING ).lstrip("0") + tipo_materia = self.request.GET.get("lst_tip_materia", EMPTY_STRING).lstrip("0") unidade_local_tramitacao = self.request.GET.get( - 'lst_cod_unid_tram_dest', - EMPTY_STRING - ).lstrip("0") - status_tramitacao = self.request.GET.get( - 'lst_status', - EMPTY_STRING + "lst_cod_unid_tram_dest", EMPTY_STRING ).lstrip("0") + status_tramitacao = self.request.GET.get("lst_status", EMPTY_STRING).lstrip("0") if ( - (inicio_intervalo_data_tramitacao != EMPTY_STRING) or - (fim_intervalo_data_tramitacao != EMPTY_STRING) or - (tipo_materia != EMPTY_STRING) or - (unidade_local_tramitacao != EMPTY_STRING) or - (status_tramitacao != EMPTY_STRING)): - + (inicio_intervalo_data_tramitacao != EMPTY_STRING) + or (fim_intervalo_data_tramitacao != EMPTY_STRING) + or (tipo_materia != EMPTY_STRING) + or (unidade_local_tramitacao != EMPTY_STRING) + or (status_tramitacao != EMPTY_STRING) + ): args += "?tramitacao__data_tramitacao_0=%s" % ( - inicio_intervalo_data_tramitacao) + inicio_intervalo_data_tramitacao + ) args += "&tramitacao__data_tramitacao_1=%s" % ( - fim_intervalo_data_tramitacao) + fim_intervalo_data_tramitacao + ) args += "&tipo=%s" % (tipo_materia) args += "&tramitacao__unidade_tramitacao_local=%s" % ( - unidade_local_tramitacao) + unidade_local_tramitacao + ) args += "&tramitacao__status=%s" % (status_tramitacao) - args += "&salvar=%s" % ('Pesquisar') + args += "&salvar=%s" % ("Pesquisar") url = "%s%s" % (url, args) @@ -671,12 +584,10 @@ class RedirecionaHistoricoTramitacoesList(RedirectView): class RedirecionaAtasList(RedirectView): - permanent = True logger = logging.getLogger(__name__) def get_redirect_url(self): - url = EMPTY_STRING args = EMPTY_STRING username = self.request.user.username @@ -684,24 +595,19 @@ class RedirecionaAtasList(RedirectView): self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(pesquisar_atas) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(pesquisar_atas) inicio_intervalo_data_ata = self.request.GET.get( - 'txt_dat_inicio', - EMPTY_STRING + "txt_dat_inicio", EMPTY_STRING ).lstrip("0") fim_intervalo_data_ata = self.request.GET.get( - 'txt_dat_fim', - EMPTY_STRING + "txt_dat_fim", EMPTY_STRING ).lstrip("0") - args += "?data_inicio_0=%s" % ( - inicio_intervalo_data_ata) - args += "&data_inicio_1=%s" % ( - fim_intervalo_data_ata) - args += "&salvar=%s" % ('Pesquisar') + args += "?data_inicio_0=%s" % (inicio_intervalo_data_ata) + args += "&data_inicio_1=%s" % (fim_intervalo_data_ata) + args += "&salvar=%s" % ("Pesquisar") url = "%s%s" % (url, args) @@ -711,12 +617,10 @@ class RedirecionaAtasList(RedirectView): class RedirecionaPresencaParlamentares(RedirectView): - permanent = True logger = logging.getLogger(__name__) def get_redirect_url(self): - url = EMPTY_STRING args = EMPTY_STRING username = self.request.user.username @@ -724,24 +628,19 @@ class RedirecionaPresencaParlamentares(RedirectView): self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(presenca_sessao) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(presenca_sessao) inicio_intervalo_data_presenca_parlamentar = self.request.GET.get( - 'txt_dat_inicio', - EMPTY_STRING + "txt_dat_inicio", EMPTY_STRING ).lstrip("0") fim_intervalo_data_presenca_parlamentar = self.request.GET.get( - 'txt_dat_fim', - EMPTY_STRING + "txt_dat_fim", EMPTY_STRING ).lstrip("0") - args += "?data_inicio_0=%s" % ( - inicio_intervalo_data_presenca_parlamentar) - args += "&data_inicio_1=%s" % ( - fim_intervalo_data_presenca_parlamentar) - args += "&salvar=%s" % ('Pesquisar') + args += "?data_inicio_0=%s" % (inicio_intervalo_data_presenca_parlamentar) + args += "&data_inicio_1=%s" % (fim_intervalo_data_presenca_parlamentar) + args += "&salvar=%s" % ("Pesquisar") url = "%s%s" % (url, args) @@ -751,7 +650,6 @@ class RedirecionaPresencaParlamentares(RedirectView): class RedirecionaMateriasPorAutor(RedirectView): - permanent = True logger = logging.getLogger(__name__) @@ -762,8 +660,7 @@ class RedirecionaMateriasPorAutor(RedirectView): self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(relatorio_materia_por_autor) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(relatorio_materia_por_autor) url = has_iframe(url, self.request) @@ -772,26 +669,23 @@ class RedirecionaMateriasPorAutor(RedirectView): class RedirecionaMateriasPorAnoAutorTipo(RedirectView): - permanent = True logger = logging.getLogger(__name__) def get_redirect_url(self): - url = EMPTY_STRING - ano = self.request.GET.get('ano', '') + ano = self.request.GET.get("ano", "") username = self.request.user.username try: self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(relatorio_materia_por_ano_autor_tipo) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(relatorio_materia_por_ano_autor_tipo) if ano: args = "?ano=%s" % (ano) - args += "&salvar=%s" % ('Pesquisar') + args += "&salvar=%s" % ("Pesquisar") url = "%s%s" % (url, args) url = has_iframe(url, self.request) @@ -804,21 +698,22 @@ class RedirecionaReuniao(RedirectView): logger = logging.getLogger(__name__) def get_redirect_url(self): - - pk_reuniao = self.request.GET.get( - 'cod_comissao', - EMPTY_STRING) + pk_reuniao = self.request.GET.get("cod_comissao", EMPTY_STRING) url = EMPTY_STRING username = self.request.user.username if pk_reuniao: - kwargs = {'pk': pk_reuniao} + kwargs = {"pk": pk_reuniao} try: self.logger.debug( - "user=" + username + ". Tentando obter url correspondente (pk={}).".format(kwargs['pk'])) + "user=" + + username + + ". Tentando obter url correspondente (pk={}).".format( + kwargs["pk"] + ) + ) url = reverse(reuniao_detail, kwargs=kwargs) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(reuniao_detail) else: @@ -826,22 +721,13 @@ class RedirecionaReuniao(RedirectView): self.logger.debug("user=" + username + ". Tentando obter url.") url = reverse(reuniao_list) except NoReverseMatch as e: - self.logger.error("user=" + username + - ". Erro ao obter url. " + str(e)) + self.logger.error("user=" + username + ". Erro ao obter url. " + str(e)) raise UnknownUrlNameError(reuniao_list) - year = self.request.GET.get( - 'ano_reuniao', - EMPTY_STRING) - month = self.request.GET.get( - 'mes_reuniao', - EMPTY_STRING) - day = self.request.GET.get( - 'dia_reuniao', - EMPTY_STRING) - tipo_reuniao = self.request.GET.get( - 'tip_reuniao', - EMPTY_STRING) + year = self.request.GET.get("ano_reuniao", EMPTY_STRING) + month = self.request.GET.get("mes_reuniao", EMPTY_STRING) + day = self.request.GET.get("dia_reuniao", EMPTY_STRING) + tipo_reuniao = self.request.GET.get("tip_reuniao", EMPTY_STRING) # Remove zeros à esquerda day = day.lstrip("0") diff --git a/sapl/relatorios/apps.py b/sapl/relatorios/apps.py index 5a4fe84be..15a5a16cf 100644 --- a/sapl/relatorios/apps.py +++ b/sapl/relatorios/apps.py @@ -3,6 +3,6 @@ from django.utils.translation import gettext_lazy as _ class AppConfig(apps.AppConfig): - name = 'sapl.relatorios' - label = 'relatorios' - verbose_name = _('Relatórios') + name = "sapl.relatorios" + label = "relatorios" + verbose_name = _("Relatórios") diff --git a/sapl/relatorios/forms.py b/sapl/relatorios/forms.py index 9dbadf928..f55e145f8 100644 --- a/sapl/relatorios/forms.py +++ b/sapl/relatorios/forms.py @@ -1,112 +1,123 @@ import django_filters -from crispy_forms.bootstrap import (FormActions) -from crispy_forms.layout import (HTML, Button, Fieldset, - Layout, Submit) +from crispy_forms.bootstrap import FormActions +from crispy_forms.layout import HTML, Button, Fieldset, Layout, Submit from django import forms from django.utils.translation import gettext_lazy as _ from sapl.audiencia.models import AudienciaPublica from sapl.base.models import Autor from sapl.comissoes.models import Reuniao -from sapl.crispy_layout_mixin import SaplFormHelper, to_row, form_actions -from sapl.materia.models import DocumentoAcessorio, MateriaLegislativa, MateriaEmTramitacao, UnidadeTramitacao, \ - StatusTramitacao +from sapl.crispy_layout_mixin import SaplFormHelper, form_actions, to_row +from sapl.materia.models import (DocumentoAcessorio, MateriaEmTramitacao, + MateriaLegislativa, StatusTramitacao, + UnidadeTramitacao) from sapl.norma.models import NormaJuridica from sapl.protocoloadm.models import DocumentoAdministrativo from sapl.sessao.models import SessaoPlenaria -from sapl.utils import FilterOverridesMetaMixin, choice_anos_com_normas, qs_override_django_filter, \ - choice_anos_com_materias, choice_tipos_normas, autor_label, autor_modal +from sapl.utils import (FilterOverridesMetaMixin, autor_label, autor_modal, + choice_anos_com_materias, choice_anos_com_normas, + choice_tipos_normas, qs_override_django_filter) class RelatorioDocumentosAcessoriosFilterSet(django_filters.FilterSet): - @property def qs(self): parent = super(RelatorioDocumentosAcessoriosFilterSet, self).qs - return parent.distinct().order_by('-data') + return parent.distinct().order_by("-data") class Meta(FilterOverridesMetaMixin): model = DocumentoAcessorio - fields = ['tipo', 'materia__tipo', 'data'] + fields = ["tipo", "materia__tipo", "data"] def __init__(self, *args, **kwargs): - super( - RelatorioDocumentosAcessoriosFilterSet, self - ).__init__(*args, **kwargs) + super(RelatorioDocumentosAcessoriosFilterSet, self).__init__(*args, **kwargs) - self.filters['tipo'].label = 'Tipo de Documento' - self.filters['materia__tipo'].label = 'Tipo de Matéria do Documento' - self.filters['data'].label = 'Período (Data Inicial - Data Final)' + self.filters["tipo"].label = "Tipo de Documento" + self.filters["materia__tipo"].label = "Tipo de Matéria do Documento" + self.filters["data"].label = "Período (Data Inicial - Data Final)" - self.form.fields['tipo'].required = True + self.form.fields["tipo"].required = True - row0 = to_row([('tipo', 6), - ('materia__tipo', 6)]) + row0 = to_row([("tipo", 6), ("materia__tipo", 6)]) - row1 = to_row([('data', 12)]) + row1 = to_row([("data", 12)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' - self.form.helper.layout = Layout( - Fieldset(_('Pesquisa'), - row0, row1, - buttons) - ) + self.form.helper.form_method = "GET" + self.form.helper.layout = Layout(Fieldset(_("Pesquisa"), row0, row1, buttons)) class RelatorioAtasFilterSet(django_filters.FilterSet): class Meta(FilterOverridesMetaMixin): model = SessaoPlenaria - fields = ['data_inicio'] + fields = ["data_inicio"] @property def qs(self): parent = super(RelatorioAtasFilterSet, self).qs - return parent.distinct().prefetch_related('tipo').exclude( - upload_ata='').order_by('-data_inicio', 'tipo', 'numero') + return ( + parent.distinct() + .prefetch_related("tipo") + .exclude(upload_ata="") + .order_by("-data_inicio", "tipo", "numero") + ) def __init__(self, *args, **kwargs): - super(RelatorioAtasFilterSet, self).__init__( - *args, **kwargs) + super(RelatorioAtasFilterSet, self).__init__(*args, **kwargs) - self.filters['data_inicio'].label = 'Período de Abertura (Inicial - Final)' - self.form.fields['data_inicio'].required = False + self.filters["data_inicio"].label = "Período de Abertura (Inicial - Final)" + self.form.fields["data_inicio"].required = False - row1 = to_row([('data_inicio', 12)]) + row1 = to_row([("data_inicio", 12)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Atas das Sessões Plenárias'), - row1, buttons, ) + Fieldset( + _("Atas das Sessões Plenárias"), + row1, + buttons, + ) ) @@ -115,119 +126,140 @@ def ultimo_ano_com_norma(): if anos_normas: return anos_normas[0] - return '' + return "" class RelatorioNormasMesFilterSet(django_filters.FilterSet): - ano = django_filters.ChoiceFilter(required=True, - label='Ano da Norma', - choices=choice_anos_com_normas, - initial=ultimo_ano_com_norma) + ano = django_filters.ChoiceFilter( + required=True, + label="Ano da Norma", + choices=choice_anos_com_normas, + initial=ultimo_ano_com_norma, + ) - tipo = django_filters.ChoiceFilter(required=False, - label='Tipo Norma', - choices=choice_tipos_normas, - initial=0) + tipo = django_filters.ChoiceFilter( + required=False, label="Tipo Norma", choices=choice_tipos_normas, initial=0 + ) class Meta: model = NormaJuridica - fields = ['ano'] + fields = ["ano"] def __init__(self, *args, **kwargs): - super(RelatorioNormasMesFilterSet, self).__init__( - *args, **kwargs) + super(RelatorioNormasMesFilterSet, self).__init__(*args, **kwargs) - self.filters['ano'].label = 'Ano' - self.form.fields['ano'].required = True + self.filters["ano"].label = "Ano" + self.form.fields["ano"].required = True - row1 = to_row([('ano', 6), ('tipo', 6)]) + row1 = to_row([("ano", 6), ("tipo", 6)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Normas por mês do ano.'), - row1, buttons, ) + Fieldset( + _("Normas por mês do ano."), + row1, + buttons, + ) ) @property def qs(self): parent = super(RelatorioNormasMesFilterSet, self).qs - return parent.distinct().order_by('data') + return parent.distinct().order_by("data") class RelatorioPresencaSessaoFilterSet(django_filters.FilterSet): class Meta(FilterOverridesMetaMixin): model = SessaoPlenaria - fields = ['data_inicio', - 'sessao_legislativa', - 'tipo', - 'legislatura'] + fields = ["data_inicio", "sessao_legislativa", "tipo", "legislatura"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.form.fields['exibir_ordem_dia'] = forms.BooleanField( - required=False, label='Exibir presença das Ordens do Dia') - self.form.initial['exibir_ordem_dia'] = True + self.form.fields["exibir_ordem_dia"] = forms.BooleanField( + required=False, label="Exibir presença das Ordens do Dia" + ) + self.form.initial["exibir_ordem_dia"] = True - self.form.fields['exibir_somente_titular'] = forms.BooleanField( - required=False, label='Exibir somente parlamentares titulares') - self.form.initial['exibir_somente_titular'] = False + self.form.fields["exibir_somente_titular"] = forms.BooleanField( + required=False, label="Exibir somente parlamentares titulares" + ) + self.form.initial["exibir_somente_titular"] = False - self.form.fields['exibir_somente_ativo'] = forms.BooleanField( - required=False, label='Exibir somente parlamentares ativos') - self.form.initial['exibir_somente_ativo'] = False + self.form.fields["exibir_somente_ativo"] = forms.BooleanField( + required=False, label="Exibir somente parlamentares ativos" + ) + self.form.initial["exibir_somente_ativo"] = False - self.form.fields['legislatura'].required = True + self.form.fields["legislatura"].required = True - self.filters['data_inicio'].label = 'Período (Inicial - Final)' + self.filters["data_inicio"].label = "Período (Inicial - Final)" - tipo_sessao_ordinaria = self.filters['tipo'].queryset.filter( - nome='Ordinária') + tipo_sessao_ordinaria = self.filters["tipo"].queryset.filter(nome="Ordinária") if tipo_sessao_ordinaria: - self.form.initial['tipo'] = tipo_sessao_ordinaria.first() + self.form.initial["tipo"] = tipo_sessao_ordinaria.first() - row1 = to_row([('legislatura', 4), - ('sessao_legislativa', 4), - ('tipo', 4)]) - row2 = to_row([('exibir_ordem_dia', 12), - ('exibir_somente_titular', 12), - ('exibir_somente_ativo', 12)]) - row3 = to_row([('data_inicio', 12)]) + row1 = to_row([("legislatura", 4), ("sessao_legislativa", 4), ("tipo", 4)]) + row2 = to_row( + [ + ("exibir_ordem_dia", 12), + ("exibir_somente_titular", 12), + ("exibir_somente_ativo", 12), + ] + ) + row3 = to_row([("data_inicio", 12)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Presença dos parlamentares nas sessões plenárias'), - row1, row2, row3, buttons, ) + Fieldset( + _("Presença dos parlamentares nas sessões plenárias"), + row1, + row2, + row3, + buttons, + ) ) @property @@ -241,322 +273,405 @@ class RelatorioHistoricoTramitacaoFilterSet(django_filters.FilterSet): @property def qs(self): parent = super(RelatorioHistoricoTramitacaoFilterSet, self).qs - return parent.distinct().prefetch_related('tipo').order_by('-ano', 'tipo', 'numero') + return ( + parent.distinct() + .prefetch_related("tipo") + .order_by("-ano", "tipo", "numero") + ) class Meta(FilterOverridesMetaMixin): model = MateriaLegislativa - fields = ['tipo', 'tramitacao__status', 'tramitacao__data_tramitacao', - 'tramitacao__unidade_tramitacao_local', 'tramitacao__unidade_tramitacao_destino'] + fields = [ + "tipo", + "tramitacao__status", + "tramitacao__data_tramitacao", + "tramitacao__unidade_tramitacao_local", + "tramitacao__unidade_tramitacao_destino", + ] def __init__(self, *args, **kwargs): - super(RelatorioHistoricoTramitacaoFilterSet, self).__init__( - *args, **kwargs) - - self.filters['tipo'].label = 'Tipo de Matéria' - self.filters['tramitacao__status'].label = _('Status') - self.filters['tramitacao__unidade_tramitacao_local'].label = _( - 'Unidade Local (Origem)') - self.filters['tramitacao__unidade_tramitacao_destino'].label = _( - 'Unidade Destino') - - row1 = to_row([('tramitacao__data_tramitacao', 12)]) - row2 = to_row([('tramitacao__unidade_tramitacao_local', 6), - ('tramitacao__unidade_tramitacao_destino', 6)]) - row3 = to_row( - [('tipo', 6), - ('tramitacao__status', 6)]) - - row4 = to_row([ - ('autoria__autor', 0), - (Button('pesquisar', - 'Pesquisar Autor', - css_class='btn btn-primary btn-sm'), 2), - (Button('limpar', - 'Limpar Autor', - css_class='btn btn-primary btn-sm'), 2) - ]) + super(RelatorioHistoricoTramitacaoFilterSet, self).__init__(*args, **kwargs) + + self.filters["tipo"].label = "Tipo de Matéria" + self.filters["tramitacao__status"].label = _("Status") + self.filters["tramitacao__unidade_tramitacao_local"].label = _( + "Unidade Local (Origem)" + ) + self.filters["tramitacao__unidade_tramitacao_destino"].label = _( + "Unidade Destino" + ) + + row1 = to_row([("tramitacao__data_tramitacao", 12)]) + row2 = to_row( + [ + ("tramitacao__unidade_tramitacao_local", 6), + ("tramitacao__unidade_tramitacao_destino", 6), + ] + ) + row3 = to_row([("tipo", 6), ("tramitacao__status", 6)]) + + row4 = to_row( + [ + ("autoria__autor", 0), + ( + Button( + "pesquisar", + "Pesquisar Autor", + css_class="btn btn-primary btn-sm", + ), + 2, + ), + ( + Button( + "limpar", "Limpar Autor", css_class="btn btn-primary btn-sm" + ), + 2, + ), + ] + ) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisar'), - row1, row2, row3, row4, - HTML(autor_label), - HTML(autor_modal), - buttons, ) + Fieldset( + _("Pesquisar"), + row1, + row2, + row3, + row4, + HTML(autor_label), + HTML(autor_modal), + buttons, + ) ) class RelatorioDataFimPrazoTramitacaoFilterSet(django_filters.FilterSet): - materia__ano = django_filters.ChoiceFilter(required=False, - label='Ano da Matéria', - choices=choice_anos_com_materias) + materia__ano = django_filters.ChoiceFilter( + required=False, label="Ano da Matéria", choices=choice_anos_com_materias + ) # materia__autores = django_filters.CharFilter(widget=forms.HiddenInput()) materia__autores = django_filters.ModelChoiceFilter( - label='Autor da Matéria', - queryset=Autor.objects.all(), field_name='materia__autores') + label="Autor da Matéria", + queryset=Autor.objects.all(), + field_name="materia__autores", + ) @property def qs(self): parent = super(RelatorioDataFimPrazoTramitacaoFilterSet, self).qs - return parent.distinct().prefetch_related('materia__tipo').order_by('tramitacao__data_fim_prazo', 'materia__tipo', 'materia__numero') + return ( + parent.distinct() + .prefetch_related("materia__tipo") + .order_by("tramitacao__data_fim_prazo", "materia__tipo", "materia__numero") + ) class Meta(FilterOverridesMetaMixin): model = MateriaEmTramitacao - fields = ['materia__tipo', - 'tramitacao__unidade_tramitacao_local', - 'tramitacao__unidade_tramitacao_destino', - 'tramitacao__status', - 'tramitacao__data_fim_prazo', - 'materia__autores'] + fields = [ + "materia__tipo", + "tramitacao__unidade_tramitacao_local", + "tramitacao__unidade_tramitacao_destino", + "tramitacao__status", + "tramitacao__data_fim_prazo", + "materia__autores", + ] def __init__(self, *args, **kwargs): - super(RelatorioDataFimPrazoTramitacaoFilterSet, self).__init__( - *args, **kwargs) + super(RelatorioDataFimPrazoTramitacaoFilterSet, self).__init__(*args, **kwargs) - self.filters['materia__tipo'].label = 'Tipo de Matéria' + self.filters["materia__tipo"].label = "Tipo de Matéria" self.filters[ - 'tramitacao__unidade_tramitacao_local'].label = 'Unidade Local (Origem)' - self.filters['tramitacao__unidade_tramitacao_destino'].label = 'Unidade Destino' - self.filters['tramitacao__status'].label = 'Status de tramitação' - self.filters['materia__autores'].label = 'Autor da Matéria' - - row1 = to_row([('materia__ano', 12)]) - row2 = to_row([('tramitacao__data_fim_prazo', 12)]) - row3 = to_row([('tramitacao__unidade_tramitacao_local', 6), - ('tramitacao__unidade_tramitacao_destino', 6)]) - row4 = to_row( - [('materia__tipo', 6), - ('tramitacao__status', 6)]) - row5 = to_row([('materia__autores', 12)]) + "tramitacao__unidade_tramitacao_local" + ].label = "Unidade Local (Origem)" + self.filters["tramitacao__unidade_tramitacao_destino"].label = "Unidade Destino" + self.filters["tramitacao__status"].label = "Status de tramitação" + self.filters["materia__autores"].label = "Autor da Matéria" + + row1 = to_row([("materia__ano", 12)]) + row2 = to_row([("tramitacao__data_fim_prazo", 12)]) + row3 = to_row( + [ + ("tramitacao__unidade_tramitacao_local", 6), + ("tramitacao__unidade_tramitacao_destino", 6), + ] + ) + row4 = to_row([("materia__tipo", 6), ("tramitacao__status", 6)]) + row5 = to_row([("materia__autores", 12)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Tramitações'), - row1, row2, row3, row4, row5, - buttons, ) + Fieldset( + _("Tramitações"), + row1, + row2, + row3, + row4, + row5, + buttons, + ) ) class RelatorioReuniaoFilterSet(django_filters.FilterSet): - @property def qs(self): parent = super(RelatorioReuniaoFilterSet, self).qs - return parent.distinct().order_by('-data', 'comissao') + return parent.distinct().order_by("-data", "comissao") class Meta: model = Reuniao - fields = ['comissao', 'data', - 'nome', 'tema'] + fields = ["comissao", "data", "nome", "tema"] def __init__(self, *args, **kwargs): - super(RelatorioReuniaoFilterSet, self).__init__( - *args, **kwargs) + super(RelatorioReuniaoFilterSet, self).__init__(*args, **kwargs) - row1 = to_row([('data', 12)]) - row2 = to_row( - [('comissao', 4), - ('nome', 4), - ('tema', 4)]) + row1 = to_row([("data", 12)]) + row2 = to_row([("comissao", 4), ("nome", 4), ("tema", 4)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Reunião de Comissão'), - row1, row2, - buttons, ) + Fieldset( + _("Reunião de Comissão"), + row1, + row2, + buttons, + ) ) class RelatorioAudienciaFilterSet(django_filters.FilterSet): - @property def qs(self): parent = super(RelatorioAudienciaFilterSet, self).qs - return parent.distinct().order_by('-data', 'tipo') + return parent.distinct().order_by("-data", "tipo") class Meta: model = AudienciaPublica - fields = ['tipo', 'data', - 'nome'] + fields = ["tipo", "data", "nome"] def __init__(self, *args, **kwargs): - super(RelatorioAudienciaFilterSet, self).__init__( - *args, **kwargs) + super(RelatorioAudienciaFilterSet, self).__init__(*args, **kwargs) - row1 = to_row([('data', 12)]) - row2 = to_row( - [('tipo', 4), - ('nome', 4)]) + row1 = to_row([("data", 12)]) + row2 = to_row([("tipo", 4), ("nome", 4)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Audiência Pública'), - row1, row2, - buttons, ) + Fieldset( + _("Audiência Pública"), + row1, + row2, + buttons, + ) ) class RelatorioMateriasTramitacaoFilterSet(django_filters.FilterSet): - materia__ano = django_filters.ChoiceFilter(required=True, - label='Ano da Matéria', - choices=choice_anos_com_materias) + materia__ano = django_filters.ChoiceFilter( + required=True, label="Ano da Matéria", choices=choice_anos_com_materias + ) tramitacao__unidade_tramitacao_destino = django_filters.ModelChoiceFilter( - queryset=UnidadeTramitacao.objects.all(), - label=_('Unidade Atual')) + queryset=UnidadeTramitacao.objects.all(), label=_("Unidade Atual") + ) tramitacao__status = django_filters.ModelChoiceFilter( - queryset=StatusTramitacao.objects.all(), - label=_('Status Atual')) + queryset=StatusTramitacao.objects.all(), label=_("Status Atual") + ) materia__autores = django_filters.ModelChoiceFilter( - label='Autor da Matéria', - queryset=Autor.objects.all()) + label="Autor da Matéria", queryset=Autor.objects.all() + ) @property def qs(self): parent = super(RelatorioMateriasTramitacaoFilterSet, self).qs return parent.distinct().order_by( - '-materia__ano', 'materia__tipo', '-materia__numero' + "-materia__ano", "materia__tipo", "-materia__numero" ) class Meta: model = MateriaEmTramitacao - fields = ['materia__ano', 'materia__tipo', - 'tramitacao__unidade_tramitacao_destino', - 'tramitacao__status', 'materia__autores'] + fields = [ + "materia__ano", + "materia__tipo", + "tramitacao__unidade_tramitacao_destino", + "tramitacao__status", + "materia__autores", + ] def __init__(self, *args, **kwargs): - super(RelatorioMateriasTramitacaoFilterSet, self).__init__( - *args, **kwargs) + super(RelatorioMateriasTramitacaoFilterSet, self).__init__(*args, **kwargs) - self.filters['materia__tipo'].label = 'Tipo de Matéria' + self.filters["materia__tipo"].label = "Tipo de Matéria" - row1 = to_row([('materia__ano', 12)]) - row2 = to_row([('materia__tipo', 12)]) - row3 = to_row([('tramitacao__unidade_tramitacao_destino', 12)]) - row4 = to_row([('tramitacao__status', 12)]) - row5 = to_row([('materia__autores', 12)]) + row1 = to_row([("materia__ano", 12)]) + row2 = to_row([("materia__tipo", 12)]) + row3 = to_row([("tramitacao__unidade_tramitacao_destino", 12)]) + row4 = to_row([("tramitacao__status", 12)]) + row5 = to_row([("materia__autores", 12)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Matéria em Tramitação'), - row1, row2, row3, row4, row5, - buttons, ) + Fieldset( + _("Pesquisa de Matéria em Tramitação"), + row1, + row2, + row3, + row4, + row5, + buttons, + ) ) class RelatorioMateriasPorAnoAutorTipoFilterSet(django_filters.FilterSet): - ano = django_filters.ChoiceFilter(required=True, - label='Ano da Matéria', - choices=choice_anos_com_materias) + ano = django_filters.ChoiceFilter( + required=True, label="Ano da Matéria", choices=choice_anos_com_materias + ) class Meta: model = MateriaLegislativa - fields = ['ano'] + fields = ["ano"] def __init__(self, *args, **kwargs): - super(RelatorioMateriasPorAnoAutorTipoFilterSet, self).__init__( - *args, **kwargs) + super(RelatorioMateriasPorAnoAutorTipoFilterSet, self).__init__(*args, **kwargs) - row1 = to_row( - [('ano', 12)]) + row1 = to_row([("ano", 12)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Matéria por Ano Autor Tipo'), - row1, - buttons, ) + Fieldset( + _("Pesquisa de Matéria por Ano Autor Tipo"), + row1, + buttons, + ) ) @@ -566,108 +681,147 @@ class RelatorioMateriasPorAutorFilterSet(django_filters.FilterSet): @property def qs(self): parent = super().qs - return parent.distinct().order_by('-ano', '-numero', 'tipo', 'autoria__autor', '-autoria__primeiro_autor') + return parent.distinct().order_by( + "-ano", "-numero", "tipo", "autoria__autor", "-autoria__primeiro_autor" + ) class Meta(FilterOverridesMetaMixin): model = MateriaLegislativa - fields = ['tipo', 'data_apresentacao'] + fields = ["tipo", "data_apresentacao"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.filters['tipo'].label = 'Tipo de Matéria' + self.filters["tipo"].label = "Tipo de Matéria" - row1 = to_row( - [('tipo', 12)]) - row2 = to_row( - [('data_apresentacao', 12)]) + row1 = to_row([("tipo", 12)]) + row2 = to_row([("data_apresentacao", 12)]) row3 = to_row( - [('autoria__autor', 0), - (Button('pesquisar', - 'Pesquisar Autor', - css_class='btn btn-primary btn-sm'), 2), - (Button('limpar', - 'Limpar Autor', - css_class='btn btn-primary btn-sm'), 10)]) + [ + ("autoria__autor", 0), + ( + Button( + "pesquisar", + "Pesquisar Autor", + css_class="btn btn-primary btn-sm", + ), + 2, + ), + ( + Button( + "limpar", "Limpar Autor", css_class="btn btn-primary btn-sm" + ), + 10, + ), + ] + ) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisa de Matéria por Autor'), - row1, row2, - HTML(autor_label), - HTML(autor_modal), - row3, - buttons, ) + Fieldset( + _("Pesquisa de Matéria por Autor"), + row1, + row2, + HTML(autor_label), + HTML(autor_modal), + row3, + buttons, + ) ) class RelatorioHistoricoTramitacaoAdmFilterSet(django_filters.FilterSet): - @property def qs(self): parent = super(RelatorioHistoricoTramitacaoAdmFilterSet, self).qs - return parent.distinct().prefetch_related('tipo').order_by('-ano', 'tipo', 'numero') + return ( + parent.distinct() + .prefetch_related("tipo") + .order_by("-ano", "tipo", "numero") + ) class Meta(FilterOverridesMetaMixin): model = DocumentoAdministrativo - fields = ['tipo', 'tramitacaoadministrativo__status', - 'tramitacaoadministrativo__data_tramitacao', - 'tramitacaoadministrativo__unidade_tramitacao_local', - 'tramitacaoadministrativo__unidade_tramitacao_destino'] + fields = [ + "tipo", + "tramitacaoadministrativo__status", + "tramitacaoadministrativo__data_tramitacao", + "tramitacaoadministrativo__unidade_tramitacao_local", + "tramitacaoadministrativo__unidade_tramitacao_destino", + ] def __init__(self, *args, **kwargs): - super(RelatorioHistoricoTramitacaoAdmFilterSet, self).__init__( - *args, **kwargs) - - self.filters['tipo'].label = 'Tipo de Documento' - self.filters['tramitacaoadministrativo__status'].label = _('Status') - self.filters['tramitacaoadministrativo__unidade_tramitacao_local'].label = _( - 'Unidade Local (Origem)') - self.filters['tramitacaoadministrativo__unidade_tramitacao_destino'].label = _( - 'Unidade Destino') - - row1 = to_row([('tramitacaoadministrativo__data_tramitacao', 12)]) - row2 = to_row([('tramitacaoadministrativo__unidade_tramitacao_local', 6), - ('tramitacaoadministrativo__unidade_tramitacao_destino', 6)]) - row3 = to_row( - [('tipo', 6), - ('tramitacaoadministrativo__status', 6)]) + super(RelatorioHistoricoTramitacaoAdmFilterSet, self).__init__(*args, **kwargs) + + self.filters["tipo"].label = "Tipo de Documento" + self.filters["tramitacaoadministrativo__status"].label = _("Status") + self.filters["tramitacaoadministrativo__unidade_tramitacao_local"].label = _( + "Unidade Local (Origem)" + ) + self.filters["tramitacaoadministrativo__unidade_tramitacao_destino"].label = _( + "Unidade Destino" + ) + + row1 = to_row([("tramitacaoadministrativo__data_tramitacao", 12)]) + row2 = to_row( + [ + ("tramitacaoadministrativo__unidade_tramitacao_local", 6), + ("tramitacaoadministrativo__unidade_tramitacao_destino", 6), + ] + ) + row3 = to_row([("tipo", 6), ("tramitacaoadministrativo__status", 6)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_(''), - row1, row2, row3, - buttons, ) + Fieldset( + _(""), + row1, + row2, + row3, + buttons, + ) ) @@ -677,105 +831,142 @@ class RelatorioNormasPorAutorFilterSet(django_filters.FilterSet): @property def qs(self): parent = super().qs - return parent.distinct().filter(autorianorma__primeiro_autor=True) \ - .order_by('autorianorma__autor', '-autorianorma__primeiro_autor', 'tipo', '-ano', '-numero') + return ( + parent.distinct() + .filter(autorianorma__primeiro_autor=True) + .order_by( + "autorianorma__autor", + "-autorianorma__primeiro_autor", + "tipo", + "-ano", + "-numero", + ) + ) class Meta(FilterOverridesMetaMixin): model = NormaJuridica - fields = ['tipo', 'data'] + fields = ["tipo", "data"] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.filters['tipo'].label = 'Tipo de Norma' + self.filters["tipo"].label = "Tipo de Norma" - row1 = to_row( - [('tipo', 12)]) - row2 = to_row( - [('data', 12)]) + row1 = to_row([("tipo", 12)]) + row2 = to_row([("data", 12)]) row3 = to_row( - [('autorianorma__autor', 0), - (Button('pesquisar', - 'Pesquisar Autor', - css_class='btn btn-primary btn-sm'), 2), - (Button('limpar', - 'Limpar Autor', - css_class='btn btn-primary btn-sm'), 10)]) + [ + ("autorianorma__autor", 0), + ( + Button( + "pesquisar", + "Pesquisar Autor", + css_class="btn btn-primary btn-sm", + ), + 2, + ), + ( + Button( + "limpar", "Limpar Autor", css_class="btn btn-primary btn-sm" + ), + 10, + ), + ] + ) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Pesquisar'), - row1, row2, - HTML(autor_label), - HTML(autor_modal), - row3, - form_actions(label='Pesquisar')) + Fieldset( + _("Pesquisar"), + row1, + row2, + HTML(autor_label), + HTML(autor_modal), + row3, + form_actions(label="Pesquisar"), + ) ) class RelatorioNormasVigenciaFilterSet(django_filters.FilterSet): - ano = django_filters.ChoiceFilter(required=True, - label='Ano da Norma', - choices=choice_anos_com_normas, - initial=ultimo_ano_com_norma) + ano = django_filters.ChoiceFilter( + required=True, + label="Ano da Norma", + choices=choice_anos_com_normas, + initial=ultimo_ano_com_norma, + ) - tipo = django_filters.ChoiceFilter(required=False, - label='Tipo Norma', - choices=choice_tipos_normas, - initial=0) + tipo = django_filters.ChoiceFilter( + required=False, label="Tipo Norma", choices=choice_tipos_normas, initial=0 + ) vigencia = forms.ChoiceField( - label=_('Vigência'), + label=_("Vigência"), choices=[(True, "Vigente"), (False, "Não vigente")], widget=forms.RadioSelect(), required=True, - initial=True) + initial=True, + ) def __init__(self, *args, **kwargs): - super(RelatorioNormasVigenciaFilterSet, self).__init__( - *args, **kwargs) + super(RelatorioNormasVigenciaFilterSet, self).__init__(*args, **kwargs) - self.filters['ano'].label = 'Ano' - self.form.fields['ano'].required = True - self.form.fields['vigencia'] = self.vigencia + self.filters["ano"].label = "Ano" + self.form.fields["ano"].required = True + self.form.fields["vigencia"] = self.vigencia - row1 = to_row([('ano', 6), ('tipo', 6)]) - row2 = to_row([('vigencia', 12)]) + row1 = to_row([("ano", 6), ("tipo", 6)]) + row2 = to_row([("vigencia", 12)]) buttons = FormActions( *[ - HTML(''' + HTML( + """
        - ''') + """ + ) ], - Submit('pesquisar', _('Pesquisar'), css_class='float-right', - onclick='return true;'), - css_class='form-group row justify-content-between', + Submit( + "pesquisar", + _("Pesquisar"), + css_class="float-right", + onclick="return true;", + ), + css_class="form-group row justify-content-between", ) self.form.helper = SaplFormHelper() - self.form.helper.form_method = 'GET' + self.form.helper.form_method = "GET" self.form.helper.layout = Layout( - Fieldset(_('Normas por vigência.'), - row1, row2, - buttons, ) + Fieldset( + _("Normas por vigência."), + row1, + row2, + buttons, + ) ) @property diff --git a/sapl/relatorios/templates/pdf_capa_processo_gerar.py b/sapl/relatorios/templates/pdf_capa_processo_gerar.py index b64c58d7e..e362492fd 100755 --- a/sapl/relatorios/templates/pdf_capa_processo_gerar.py +++ b/sapl/relatorios/templates/pdf_capa_processo_gerar.py @@ -8,27 +8,27 @@ """ import time -from sapl.utils import xstr - from trml2pdf import parseString +from sapl.utils import xstr + def paraStyle(): """Gera o codigo rml que define o estilo dos paragrafos""" - tmp_data = '' - tmp_data += '\t\n' + tmp_data = "" + tmp_data += "\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t\n' tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" + tmp_data += "\t\t\n" tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\n' tmp_data += '\t\t\n' - tmp_data += '\t\n' + tmp_data += "\t\n" return tmp_data @@ -36,35 +36,50 @@ def paraStyle(): def protocolos(lst_protocolos): """Gera o codigo rml do conteudo da pesquisa de protocolos""" - tmp_data = '' + tmp_data = "" # inicio do bloco que contem os flowables - tmp_data += '\t\n' + tmp_data += "\t\n" for dic in lst_protocolos: # condicao para a quebra de pagina tmp_data += '\t\t\n' # protocolos - tmp_data += '\t\t' + \ - dic['titulo'] + '\n' - tmp_data += '\t\tProtocolo: ' + \ - dic['titulo'] + '\n' - tmp_data += '\t\t' + dic['data'] + '\n' - tmp_data += '\t\t' + \ - dic['numeracao'] + '\n' - tmp_data += '\t\t' + \ - dic['sgl_processo'] + ' ' + dic['ident_processo'] + \ - ' ' + dic['num_processo'] + '\n' - tmp_data += '\t\tAutor: ' + \ - dic['nom_autor'] + '\n' + tmp_data += ( + '\t\t' + + dic["titulo"] + + "\n" + ) + tmp_data += ( + '\t\tProtocolo: ' + dic["titulo"] + "\n" + ) + tmp_data += '\t\t' + dic["data"] + "\n" + tmp_data += '\t\t' + dic["numeracao"] + "\n" + tmp_data += ( + '\t\t' + + dic["sgl_processo"] + + " " + + dic["ident_processo"] + + " " + + dic["num_processo"] + + "\n" + ) + tmp_data += ( + '\t\tAutor: ' + + dic["nom_autor"] + + "\n" + ) tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' - tmp_data += '\t\tEmenta: ' + \ - xstr(dic['txt_assunto']) + '\n' - - tmp_data += '\t\n' + tmp_data += "\t\t\n" + tmp_data += ( + '\t\tEmenta: ' + + xstr(dic["txt_assunto"]) + + "\n" + ) + + tmp_data += "\t\n" return tmp_data @@ -73,24 +88,27 @@ def principal(imagem, lst_protocolos, dic_cabecalho, lst_rodape): arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp_data = '' + tmp_data = "" tmp_data += '\n' tmp_data += '\n' tmp_data += '\n' tmp_data += '\t\n' + tmp_data += "\t\t\n" + tmp_data += "\t\t\n" + tmp_data += ( + '\t\t\t\n' + ) + tmp_data += "\t\t\n" + tmp_data += "\t\n" tmp_data += paraStyle() tmp_data += protocolos(lst_protocolos) - tmp_data += '\n' + tmp_data += "\n" tmp_pdf = parseString(tmp_data) return tmp_pdf + # if hasattr(context.temp_folder,arquivoPdf): # context.temp_folder.manage_delObjects(ids=arquivoPdf) # context.temp_folder.manage_addFile(arquivoPdf) diff --git a/sapl/relatorios/templates/pdf_capa_processo_preparar_pysc.py b/sapl/relatorios/templates/pdf_capa_processo_preparar_pysc.py index 4e741e564..c54337e8b 100755 --- a/sapl/relatorios/templates/pdf_capa_processo_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_capa_processo_preparar_pysc.py @@ -4,15 +4,14 @@ request = context.REQUEST response = request.RESPONSE session = request.SESSION -data = DateTime().strftime('%d/%m/%Y') +data = DateTime().strftime("%d/%m/%Y") # Abaixo é gerada a string para o rodapé da página casa = {} aux = context.sapl_documentos.props_sapl.propertyItems() for item in aux: casa[item[0]] = item[1] -localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) +localidade = context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"]) if len(casa["num_cep"]) == 8: cep = casa["num_cep"][:4] + "-" + casa["num_cep"][5:] else: @@ -24,8 +23,7 @@ if cep != "": linha1 = linha1 + " - " linha1 = linha1 + "CEP " + cep if localidade[0].nom_localidade != "" and localidade[0].nom_localidade != None: - linha1 = linha1 + " - " + \ - localidade[0].nom_localidade + " " + localidade[0].sgl_uf + linha1 = linha1 + " - " + localidade[0].nom_localidade + " " + localidade[0].sgl_uf if casa["num_tel"] != "" and casa["num_tel"] != None: linha1 = linha1 + " Tel.: " + casa["num_tel"] @@ -49,8 +47,8 @@ cabecalho["nom_casa"] = casa["nom_casa"] cabecalho["nom_estado"] = "Estado de " + nom_estado # tenta buscar o logotipo da casa LOGO_CASA -if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl['logo_casa.gif'].absolute_url() +if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -58,92 +56,117 @@ else: protocolos = [] REQUEST = context.REQUEST -for protocolo in context.zsql.protocolo_pesquisar_zsql(tip_protocolo=REQUEST['rad_tip_protocolo'], - cod_protocolo=REQUEST['txt_num_protocolo'], ano_protocolo=REQUEST[ - 'txt_ano_protocolo'], - tip_documento=REQUEST['lst_tip_documento'], tip_processo=REQUEST[ - 'rad_tip_processo'], - tip_materia=REQUEST[ - 'lst_tip_materia'], des_assunto=REQUEST['txt_assunto'], - cod_autor=REQUEST['hdn_cod_autor'], des_interessado=REQUEST[ - 'txa_txt_interessado'], - dat_apres=REQUEST['dt_apres'], dat_apres2=REQUEST['dt_apres2']): +for protocolo in context.zsql.protocolo_pesquisar_zsql( + tip_protocolo=REQUEST["rad_tip_protocolo"], + cod_protocolo=REQUEST["txt_num_protocolo"], + ano_protocolo=REQUEST["txt_ano_protocolo"], + tip_documento=REQUEST["lst_tip_documento"], + tip_processo=REQUEST["rad_tip_processo"], + tip_materia=REQUEST["lst_tip_materia"], + des_assunto=REQUEST["txt_assunto"], + cod_autor=REQUEST["hdn_cod_autor"], + des_interessado=REQUEST["txa_txt_interessado"], + dat_apres=REQUEST["dt_apres"], + dat_apres2=REQUEST["dt_apres2"], +): dic = {} - dic['titulo'] = str(protocolo.cod_protocolo) + dic["titulo"] = str(protocolo.cod_protocolo) - dic['ano'] = str(protocolo.ano_protocolo) + dic["ano"] = str(protocolo.ano_protocolo) - dic['data'] = context.pysc.iso_to_port_pysc( - protocolo.dat_protocolo) + ' - ' + protocolo.hor_protocolo + dic["data"] = ( + context.pysc.iso_to_port_pysc(protocolo.dat_protocolo) + + " - " + + protocolo.hor_protocolo + ) - dic['txt_assunto'] = protocolo.txt_assunto_ementa + dic["txt_assunto"] = protocolo.txt_assunto_ementa - dic['txt_interessado'] = protocolo.txt_interessado + dic["txt_interessado"] = protocolo.txt_interessado - dic['nom_autor'] = " " + dic["nom_autor"] = " " if protocolo.cod_autor != None: for autor in context.zsql.autor_obter_zsql(cod_autor=protocolo.cod_autor): - if autor.des_tipo_autor == 'Parlamentar': - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=autor.cod_parlamentar): - dic['nom_autor'] = parlamentar.nom_completo - elif autor.des_tipo_autor == 'Comissao': - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=autor.cod_comissao): - dic['nom_autor'] = comissao.nom_comissao + if autor.des_tipo_autor == "Parlamentar": + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=autor.cod_parlamentar + ): + dic["nom_autor"] = parlamentar.nom_completo + elif autor.des_tipo_autor == "Comissao": + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=autor.cod_comissao + ): + dic["nom_autor"] = comissao.nom_comissao else: - dic['nom_autor'] = autor.nom_autor + dic["nom_autor"] = autor.nom_autor else: - dic['nom_autor'] = protocolo.txt_interessado + dic["nom_autor"] = protocolo.txt_interessado - dic['natureza'] = '' + dic["natureza"] = "" if protocolo.tip_processo == 0: - dic['natureza'] = 'Administrativo' + dic["natureza"] = "Administrativo" if protocolo.tip_processo == 1: - dic['natureza'] = 'Legislativo' - - dic['ident_processo'] = protocolo.des_tipo_materia or protocolo.des_tipo_documento - - dic['sgl_processo'] = protocolo.sgl_tipo_materia or protocolo.sgl_tipo_documento - - dic['num_materia'] = '' - for materia in context.zsql.materia_obter_zsql(num_protocolo=protocolo.cod_protocolo, ano_ident_basica=protocolo.ano_protocolo): - dic['num_materia'] = str(materia.num_ident_basica) + \ - '/' + str(materia.ano_ident_basica) - - dic['num_documento'] = '' - for documento in context.zsql.documento_administrativo_obter_zsql(num_protocolo=protocolo.cod_protocolo): - dic['num_documento'] = str( - documento.num_documento) + '/' + str(documento.ano_documento) - - dic['num_processo'] = dic['num_materia'] or dic['num_documento'] - - dic['numeracao'] = '' - for materia_num in context.zsql.materia_obter_zsql(num_protocolo=protocolo.cod_protocolo, ano_ident_basica=protocolo.ano_protocolo): - for numera in context.zsql.numeracao_obter_zsql(cod_materia=materia_num.cod_materia, ind_excluido=0): - dic['numeracao'] = 'PROCESSO N° ' + \ - str(numera.num_materia) + '/' + str(numera.ano_materia) - - dic['anulado'] = '' + dic["natureza"] = "Legislativo" + + dic["ident_processo"] = protocolo.des_tipo_materia or protocolo.des_tipo_documento + + dic["sgl_processo"] = protocolo.sgl_tipo_materia or protocolo.sgl_tipo_documento + + dic["num_materia"] = "" + for materia in context.zsql.materia_obter_zsql( + num_protocolo=protocolo.cod_protocolo, ano_ident_basica=protocolo.ano_protocolo + ): + dic["num_materia"] = ( + str(materia.num_ident_basica) + "/" + str(materia.ano_ident_basica) + ) + + dic["num_documento"] = "" + for documento in context.zsql.documento_administrativo_obter_zsql( + num_protocolo=protocolo.cod_protocolo + ): + dic["num_documento"] = ( + str(documento.num_documento) + "/" + str(documento.ano_documento) + ) + + dic["num_processo"] = dic["num_materia"] or dic["num_documento"] + + dic["numeracao"] = "" + for materia_num in context.zsql.materia_obter_zsql( + num_protocolo=protocolo.cod_protocolo, ano_ident_basica=protocolo.ano_protocolo + ): + for numera in context.zsql.numeracao_obter_zsql( + cod_materia=materia_num.cod_materia, ind_excluido=0 + ): + dic["numeracao"] = ( + "PROCESSO N° " + + str(numera.num_materia) + + "/" + + str(numera.ano_materia) + ) + + dic["anulado"] = "" if protocolo.ind_anulado == 1: - dic['anulado'] = 'Nulo' + dic["anulado"] = "Nulo" protocolos.append(dic) filtro = {} # Dicionário que conterá os dados do filtro # Atribuições diretas do REQUEST -filtro['numero'] = REQUEST.txt_num_protocolo -filtro['ano'] = REQUEST.txt_ano_protocolo -filtro['tipo_protocolo'] = REQUEST.rad_tip_protocolo -filtro['tipo_processo'] = REQUEST.rad_tip_processo -filtro['assunto'] = REQUEST.txt_assunto -filtro['autor'] = REQUEST.hdn_cod_autor -filtro['interessado'] = REQUEST.txa_txt_interessado +filtro["numero"] = REQUEST.txt_num_protocolo +filtro["ano"] = REQUEST.txt_ano_protocolo +filtro["tipo_protocolo"] = REQUEST.rad_tip_protocolo +filtro["tipo_processo"] = REQUEST.rad_tip_processo +filtro["assunto"] = REQUEST.txt_assunto +filtro["autor"] = REQUEST.hdn_cod_autor +filtro["interessado"] = REQUEST.txa_txt_interessado sessao = session.id caminho = context.pdf_capa_processo_gerar( - sessao, imagem, data, protocolos, cabecalho, rodape, filtro) -if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + sessao, imagem, data, protocolos, cabecalho, rodape, filtro +) +if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_detalhe_materia_gerar.py b/sapl/relatorios/templates/pdf_detalhe_materia_gerar.py index 43224d282..538214b75 100755 --- a/sapl/relatorios/templates/pdf_detalhe_materia_gerar.py +++ b/sapl/relatorios/templates/pdf_detalhe_materia_gerar.py @@ -16,23 +16,42 @@ def cabecalho(dic_inf_basicas, imagem): Função que gera o código rml do cabeçalho da página """ - tmp = '' - tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t2cm 24.5cm 19cm 24.5cm\n' - if dic_inf_basicas['nom_camara'] != "" and dic_inf_basicas['nom_camara'] != None: + tmp = "" + tmp += ( + '\t\t\t\t\n' + ) + tmp += "\t\t\t\t2cm 24.5cm 19cm 24.5cm\n" + if dic_inf_basicas["nom_camara"] != "" and dic_inf_basicas["nom_camara"] != None: tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t' + \ - dic_inf_basicas['nom_camara'] + '\n' + tmp += ( + '\t\t\t\t' + + dic_inf_basicas["nom_camara"] + + "\n" + ) tmp += '\t\t\t\t\n' tmp += '\t\t\t\tSistema de Apoio ao Processo Legislativo\n' - if str(dic_inf_basicas['nom_projeto']) != "" and str(dic_inf_basicas['nom_projeto']) != None: + if ( + str(dic_inf_basicas["nom_projeto"]) != "" + and str(dic_inf_basicas["nom_projeto"]) != None + ): tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t' + \ - str(dic_inf_basicas['nom_projeto']) + '\n' - if str(dic_inf_basicas['cod_projeto']) != "" and str(dic_inf_basicas['cod_projeto']) != None: + tmp += ( + '\t\t\t\t' + + str(dic_inf_basicas["nom_projeto"]) + + "\n" + ) + if ( + str(dic_inf_basicas["cod_projeto"]) != "" + and str(dic_inf_basicas["cod_projeto"]) != None + ): tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t' + \ - str(dic_inf_basicas['cod_projeto']) + '\n' + tmp += ( + '\t\t\t\t' + + str(dic_inf_basicas["cod_projeto"]) + + "\n" + ) return tmp @@ -41,33 +60,41 @@ def rodape(dic_rodape): Função que gera o codigo rml do rodape da pagina. """ - tmp = '' - linha1 = dic_rodape['end_casa'] - if dic_rodape['end_casa'] != "" and dic_rodape['end_casa'] != None: + tmp = "" + linha1 = dic_rodape["end_casa"] + if dic_rodape["end_casa"] != "" and dic_rodape["end_casa"] != None: linha1 = linha1 + " - " - if dic_rodape['num_cep'] != "" and dic_rodape['num_cep'] != None: - linha1 = linha1 + "CEP " + dic_rodape['num_cep'] - if dic_rodape['nom_localidade'] != "" and dic_rodape['nom_localidade'] != None: - linha1 = linha1 + " - " + dic_rodape['nom_localidade'] - if dic_rodape['sgl_uf'] != "" and dic_rodape['sgl_uf'] != None: - inha1 = linha1 + " " + dic_rodape['sgl_uf'] - if dic_rodape['num_tel'] != "" and dic_rodape['num_tel'] != None: - linha1 = linha1 + " Tel: " + dic_rodape['num_tel'] - if dic_rodape['end_web_casa'] != "" and dic_rodape['end_web_casa'] != None: - linha2 = dic_rodape['end_web_casa'] - if dic_rodape['end_email_casa'] != "" and dic_rodape['end_email_casa'] != None: - linha2 = linha2 + " - E-mail: " + dic_rodape['end_email_casa'] - if dic_rodape['data_emissao'] != "" and dic_rodape['data_emissao'] != None: - data_emissao = dic_rodape['data_emissao'] - - tmp += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + if dic_rodape["num_cep"] != "" and dic_rodape["num_cep"] != None: + linha1 = linha1 + "CEP " + dic_rodape["num_cep"] + if dic_rodape["nom_localidade"] != "" and dic_rodape["nom_localidade"] != None: + linha1 = linha1 + " - " + dic_rodape["nom_localidade"] + if dic_rodape["sgl_uf"] != "" and dic_rodape["sgl_uf"] != None: + inha1 = linha1 + " " + dic_rodape["sgl_uf"] + if dic_rodape["num_tel"] != "" and dic_rodape["num_tel"] != None: + linha1 = linha1 + " Tel: " + dic_rodape["num_tel"] + if dic_rodape["end_web_casa"] != "" and dic_rodape["end_web_casa"] != None: + linha2 = dic_rodape["end_web_casa"] + if dic_rodape["end_email_casa"] != "" and dic_rodape["end_email_casa"] != None: + linha2 = linha2 + " - E-mail: " + dic_rodape["end_email_casa"] + if dic_rodape["data_emissao"] != "" and dic_rodape["data_emissao"] != None: + data_emissao = dic_rodape["data_emissao"] + + tmp += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t' + data_emissao + '\n' - tmp += '\t\t\t\tPágina \n' - tmp += '\t\t\t\t' + \ - linha1 + '\n' - tmp += '\t\t\t\t' + \ - linha2 + '\n' + tmp += '\t\t\t\t' + data_emissao + "\n" + tmp += ( + '\t\t\t\tPágina \n' + ) + tmp += ( + '\t\t\t\t' + + linha1 + + "\n" + ) + tmp += ( + '\t\t\t\t' + + linha2 + + "\n" + ) return tmp @@ -75,21 +102,21 @@ def rodape(dic_rodape): def paraStyle(): """Função que gera o código rml que define o estilo dos parágrafos""" - tmp = '' - tmp += '\t\n' + tmp = "" + tmp += "\t\n" tmp += '\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' - tmp += '\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" + tmp += "\t\t\n" tmp += '\t\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" # titulo do parágrafo: é por default centralizado tmp += '\t\t\n' tmp += '\t\t\n' tmp += '\t\t\n' tmp += '\t\t\n' - tmp += '\t\n' + tmp += "\t\n" return tmp @@ -99,73 +126,115 @@ def inf_basicas(dic_inf_basicas): Função que gera o código rml das funções básicas do relatório """ - tmp = '' + tmp = "" # Texto do projeto - texto_projeto = str(dic_inf_basicas['texto_projeto']) + texto_projeto = str(dic_inf_basicas["texto_projeto"]) if texto_projeto != "" and texto_projeto != None: - tmp += '\t\t' + \ - texto_projeto.replace('&', '&') + '\n' + tmp += ( + '\t\t' + + texto_projeto.replace("&", "&") + + "\n" + ) # início das informações básicas tmp += '\t\tInformações Básicas\n' - if str(dic_inf_basicas['apresentada']) != "" and str(dic_inf_basicas['apresentada']) != None: - tmp += '\t\tApresentada em: ' + \ - str(dic_inf_basicas['apresentada']) + '\n' - - if str(dic_inf_basicas['formato']) != "" and str(dic_inf_basicas['formato']) != None: - tmp += '\t\tFormato: ' + \ - str(dic_inf_basicas['formato']) + '\n' - - if dic_inf_basicas['publicada'] == 0: + if ( + str(dic_inf_basicas["apresentada"]) != "" + and str(dic_inf_basicas["apresentada"]) != None + ): + tmp += ( + '\t\tApresentada em: ' + + str(dic_inf_basicas["apresentada"]) + + "\n" + ) + + if ( + str(dic_inf_basicas["formato"]) != "" + and str(dic_inf_basicas["formato"]) != None + ): + tmp += ( + '\t\tFormato: ' + + str(dic_inf_basicas["formato"]) + + "\n" + ) + + if dic_inf_basicas["publicada"] == 0: tmp += '\t\tPublicada: Não\n' else: tmp += '\t\tPublicada: Sim\n' - if str(dic_inf_basicas['objeto']) != "" and str(dic_inf_basicas['objeto']) != None: - tmp += '\t\tObjeto: ' + \ - str(dic_inf_basicas['objeto']) + '\n' + if str(dic_inf_basicas["objeto"]) != "" and str(dic_inf_basicas["objeto"]) != None: + tmp += ( + '\t\tObjeto: ' + + str(dic_inf_basicas["objeto"]) + + "\n" + ) - if dic_inf_basicas['tramitacao'] == 0: + if dic_inf_basicas["tramitacao"] == 0: tmp += '\t\tTramitação: Não\n' else: tmp += '\t\tTramitação: Sim\n' - if str(dic_inf_basicas['reg_tramitacao']) != "" and str(dic_inf_basicas['reg_tramitacao']) != None: - tmp += '\t\tRegime: ' + \ - str(dic_inf_basicas['reg_tramitacao']) + '\n' - - if str(dic_inf_basicas['prazo']) != "" and str(dic_inf_basicas['prazo']) != None: - tmp += '\t\tDias de prazo: ' + \ - str(dic_inf_basicas['prazo']) + '\n' - - if str(dic_inf_basicas['fim_prazo']) != "" and str(dic_inf_basicas['fim_prazo']) != None: - tmp += '\t\tData do fim do prazo: ' + \ - str(dic_inf_basicas['fim_prazo']) + '\n' - - if dic_inf_basicas['mat_complementar'] == 0: + if ( + str(dic_inf_basicas["reg_tramitacao"]) != "" + and str(dic_inf_basicas["reg_tramitacao"]) != None + ): + tmp += ( + '\t\tRegime: ' + + str(dic_inf_basicas["reg_tramitacao"]) + + "\n" + ) + + if str(dic_inf_basicas["prazo"]) != "" and str(dic_inf_basicas["prazo"]) != None: + tmp += ( + '\t\tDias de prazo: ' + + str(dic_inf_basicas["prazo"]) + + "\n" + ) + + if ( + str(dic_inf_basicas["fim_prazo"]) != "" + and str(dic_inf_basicas["fim_prazo"]) != None + ): + tmp += ( + '\t\tData do fim do prazo: ' + + str(dic_inf_basicas["fim_prazo"]) + + "\n" + ) + + if dic_inf_basicas["mat_complementar"] == 0: tmp += '\t\tMatéria Complementar: Não\n' else: tmp += '\t\tMatéria Complementar: Sim\n' - if dic_inf_basicas['polemica'] == 0: + if dic_inf_basicas["polemica"] == 0: tmp += '\t\tPolêmica: Não\n' else: tmp += '\t\tPolêmica: Sim\n' - apelido = dic_inf_basicas['apelido'] + apelido = dic_inf_basicas["apelido"] if apelido != "" and apelido != None: - tmp += '\t\tApelido: ' + \ - apelido.replace('&', '&') + '\n' + tmp += ( + '\t\tApelido: ' + + apelido.replace("&", "&") + + "\n" + ) - indexacao = dic_inf_basicas['indexacao'] + indexacao = dic_inf_basicas["indexacao"] if indexacao != "" and indexacao != None: - tmp += '\t\tIndexação: ' + \ - indexacao.replace('&', '&') + '\n' + tmp += ( + '\t\tIndexação: ' + + indexacao.replace("&", "&") + + "\n" + ) - observacao = dic_inf_basicas['observacao'] + observacao = dic_inf_basicas["observacao"] if observacao != "" and observacao != None: - tmp += '\t\tObservação: ' + \ - observacao.replace('&', '&') + '\n' + tmp += ( + '\t\tObservação: ' + + observacao.replace("&", "&") + + "\n" + ) return tmp @@ -175,24 +244,39 @@ def orig_externa(dic_orig_externa): Função que gera o código rml da origem externa """ - tmp = '' + tmp = "" tmp += '\t\tOrigem Externa\n' try: - if dic_orig_externa['local'] != "" and dic_orig_externa['local'] != None: - tmp += '\t\tLocal: ' + \ - dic_orig_externa['local'] + '\n' - - if dic_orig_externa['data'] != "" and dic_orig_externa['data'] != None: - tmp += '\t\tData: ' + \ - dic_orig_externa['data'] + '\n' - - if dic_orig_externa['tipo'] != "" and dic_orig_externa['tipo'] != None: - tmp += '\t\tTipo: ' + \ - dic_orig_externa['tipo'] + '\n' - - if dic_orig_externa['numero_ano'] != "" and dic_orig_externa['numero_ano'] != None: - tmp += '\t\tNúmero/Ano: ' + \ - dic_orig_externa['numero_ano'] + '\n' + if dic_orig_externa["local"] != "" and dic_orig_externa["local"] != None: + tmp += ( + '\t\tLocal: ' + + dic_orig_externa["local"] + + "\n" + ) + + if dic_orig_externa["data"] != "" and dic_orig_externa["data"] != None: + tmp += ( + '\t\tData: ' + + dic_orig_externa["data"] + + "\n" + ) + + if dic_orig_externa["tipo"] != "" and dic_orig_externa["tipo"] != None: + tmp += ( + '\t\tTipo: ' + + dic_orig_externa["tipo"] + + "\n" + ) + + if ( + dic_orig_externa["numero_ano"] != "" + and dic_orig_externa["numero_ano"] != None + ): + tmp += ( + '\t\tNúmero/Ano: ' + + dic_orig_externa["numero_ano"] + + "\n" + ) except: pass @@ -200,79 +284,114 @@ def orig_externa(dic_orig_externa): def mat_anexadas(lst_mat_anexadas): - - tmp = '' + tmp = "" tmp += '\t\tMatérias Anexadas\n' for dic_mat in lst_mat_anexadas: - if dic_mat['nom_mat'] != "" and dic_mat['nom_mat'] != None: - tmp += '\t\tNome da matéria: ' + \ - dic_mat['nom_mat'] + '\n' - tmp += '\t\tData: ' + \ - dic_mat['data'] + '\n' - tmp += '\t\tData final: ' + \ - str(dic_mat['data_fim']) + '\n' + if dic_mat["nom_mat"] != "" and dic_mat["nom_mat"] != None: + tmp += ( + '\t\tNome da matéria: ' + + dic_mat["nom_mat"] + + "\n" + ) + tmp += '\t\tData: ' + dic_mat["data"] + "\n" + tmp += ( + '\t\tData final: ' + + str(dic_mat["data_fim"]) + + "\n" + ) return tmp def autoria(lst_autoria): - - tmp = '' + tmp = "" tmp += '\t\tAutores\n' for dic_autor in lst_autoria: - if dic_autor['nom_autor'] != "" and dic_autor['nom_autor'] != None: - tmp += '\t\tNome do Autor: ' + \ - dic_autor['nom_autor'] + '\n' - - if dic_autor['nom_autor'] != "" and dic_autor['cargo'] != None: - tmp += '\t\tCargo: ' + \ - dic_autor['cargo'] + '\n' - - if dic_autor['nom_autor'] != "" and dic_autor['tipo'] != None: - tmp += '\t\tTipo: ' + \ - dic_autor['tipo'] + '\n' + if dic_autor["nom_autor"] != "" and dic_autor["nom_autor"] != None: + tmp += ( + '\t\tNome do Autor: ' + + dic_autor["nom_autor"] + + "\n" + ) + + if dic_autor["nom_autor"] != "" and dic_autor["cargo"] != None: + tmp += ( + '\t\tCargo: ' + dic_autor["cargo"] + "\n" + ) + + if dic_autor["nom_autor"] != "" and dic_autor["tipo"] != None: + tmp += ( + '\t\tTipo: ' + dic_autor["tipo"] + "\n" + ) return tmp def despachos_iniciais(lst_des_iniciais): - - tmp = '' + tmp = "" tmp += '\t\tDespachos Iniciais\n' for dic_dados in lst_des_iniciais: - if dic_dados['nom_comissao'] == None: - dic_dados['nom_comissao'] = " " - tmp += '\t\tNome da comissão: ' + \ - dic_dados['nom_comissao'] + '\n' + if dic_dados["nom_comissao"] == None: + dic_dados["nom_comissao"] = " " + tmp += ( + '\t\tNome da comissão: ' + + dic_dados["nom_comissao"] + + "\n" + ) return tmp def tramitacoes(dic_tramitacoes): - - tmp = '' + tmp = "" tmp += '\t\tÚltima Tramitação\n' try: - tmp += '\t\tData Ação: ' + \ - str(dic_tramitacoes['data']) + '\n' - tmp += '\t\tUnidade Local: ' + \ - dic_tramitacoes['unidade'] + '\n' - tmp += '\t\tEncaminhada em: ' + \ - str(dic_tramitacoes['data_enc']) + '\n' - tmp += '\t\tDestino: ' + \ - dic_tramitacoes['destino'] + '\n' - tmp += '\t\tTurno: ' + \ - dic_tramitacoes['turno'] + '\n' - tmp += '\t\tStatus: ' + \ - dic_tramitacoes['status'] + '\n' - if dic_tramitacoes['urgente'] == 0: + tmp += ( + '\t\tData Ação: ' + + str(dic_tramitacoes["data"]) + + "\n" + ) + tmp += ( + '\t\tUnidade Local: ' + + dic_tramitacoes["unidade"] + + "\n" + ) + tmp += ( + '\t\tEncaminhada em: ' + + str(dic_tramitacoes["data_enc"]) + + "\n" + ) + tmp += ( + '\t\tDestino: ' + + dic_tramitacoes["destino"] + + "\n" + ) + tmp += ( + '\t\tTurno: ' + + dic_tramitacoes["turno"] + + "\n" + ) + tmp += ( + '\t\tStatus: ' + + dic_tramitacoes["status"] + + "\n" + ) + if dic_tramitacoes["urgente"] == 0: tmp += '\t\tUrgente: Não\n' else: tmp += '\t\tUrgente: Sim\n' - tmp += '\t\tData do fim do prazo: ' + \ - str(dic_tramitacoes['data_fim']) + '\n' - if dic_tramitacoes['texto_acao'] != "" and dic_tramitacoes['texto_acao'] != None: - tmp += '\t\tTexto da Ação: ' + \ - dic_tramitacoes['texto_acao'].replace( - '&', '&') + '\n' + tmp += ( + '\t\tData do fim do prazo: ' + + str(dic_tramitacoes["data_fim"]) + + "\n" + ) + if ( + dic_tramitacoes["texto_acao"] != "" + and dic_tramitacoes["texto_acao"] != None + ): + tmp += ( + '\t\tTexto da Ação: ' + + dic_tramitacoes["texto_acao"].replace("&", "&") + + "\n" + ) except: pass @@ -280,120 +399,187 @@ def tramitacoes(dic_tramitacoes): def relatorias(lst_relatorias): - - tmp = '' + tmp = "" tmp += '\t\tRelatorias\n' for dic_comissao in lst_relatorias: - tmp += '\t\tComissão: ' + \ - dic_comissao['nom_comissao'] + '\n' - tmp += '\t\tData Designação: ' + \ - str(dic_comissao['data_desig']) + '\n' - tmp += '\t\tParlamentar: ' + \ - dic_comissao['parlamentar'] + '\n' - tmp += '\t\tData Destituição: ' + \ - str(dic_comissao['data_dest']) + '\n' - tmp += '\t\tMotivo Fim Relatoria: ' + \ - dic_comissao['motivo'] + '\n' + tmp += ( + '\t\tComissão: ' + + dic_comissao["nom_comissao"] + + "\n" + ) + tmp += ( + '\t\tData Designação: ' + + str(dic_comissao["data_desig"]) + + "\n" + ) + tmp += ( + '\t\tParlamentar: ' + + dic_comissao["parlamentar"] + + "\n" + ) + tmp += ( + '\t\tData Destituição: ' + + str(dic_comissao["data_dest"]) + + "\n" + ) + tmp += ( + '\t\tMotivo Fim Relatoria: ' + + dic_comissao["motivo"] + + "\n" + ) return tmp def numeracoes(lst_numeracoes): - - tmp = '' + tmp = "" tmp += '\t\tNumerações\n' for dic_dados in lst_numeracoes: - tmp += '\t\tNome: ' + \ - dic_dados['nome'] + '\n' - tmp += '\t\tAno: ' + \ - str(dic_dados['ano']) + '\n' + tmp += '\t\tNome: ' + dic_dados["nome"] + "\n" + tmp += '\t\tAno: ' + str(dic_dados["ano"]) + "\n" return tmp def legislacoes_citadas(lst_leg_citadas): - - tmp = '' + tmp = "" tmp += '\t\tLegislações Citadas\n' for dic_dados in lst_leg_citadas: - tmp += '\t\tTipo Norma: ' + \ - str(dic_dados['nome_lei']) + '\n' - tmp += '\t\tDisposição: ' + \ - str(dic_dados['disposicao']) + '\n' - tmp += '\t\tParte: ' + \ - str(dic_dados['parte']) + '\n' - tmp += '\t\tLivro: ' + \ - str(dic_dados['livro']) + '\n' - tmp += '\t\tTí­tulo: ' + \ - str(dic_dados['titulo']) + '\n' - tmp += '\t\tCapí­tulo: ' + \ - str(dic_dados['capitulo']) + '\n' - tmp += '\t\tSeção: ' + \ - str(dic_dados['secao']) + '\n' - tmp += '\t\tSubseção: ' + \ - str(dic_dados['subsecao']) + '\n' - tmp += '\t\tArtigo: ' + \ - str(dic_dados['artigo']) + '\n' - tmp += '\t\tParágrafo: ' + \ - str(dic_dados['paragrafo']) + '\n' - tmp += '\t\tInciso: ' + \ - str(dic_dados['inciso']) + '\n' - tmp += '\t\tAlí­nea: ' + \ - str(dic_dados['alinea']) + '\n' - tmp += '\t\tItem: ' + \ - str(dic_dados['item']) + '\n' + tmp += ( + '\t\tTipo Norma: ' + + str(dic_dados["nome_lei"]) + + "\n" + ) + tmp += ( + '\t\tDisposição: ' + + str(dic_dados["disposicao"]) + + "\n" + ) + tmp += ( + '\t\tParte: ' + + str(dic_dados["parte"]) + + "\n" + ) + tmp += ( + '\t\tLivro: ' + + str(dic_dados["livro"]) + + "\n" + ) + tmp += ( + '\t\tTí­tulo: ' + + str(dic_dados["titulo"]) + + "\n" + ) + tmp += ( + '\t\tCapí­tulo: ' + + str(dic_dados["capitulo"]) + + "\n" + ) + tmp += ( + '\t\tSeção: ' + + str(dic_dados["secao"]) + + "\n" + ) + tmp += ( + '\t\tSubseção: ' + + str(dic_dados["subsecao"]) + + "\n" + ) + tmp += ( + '\t\tArtigo: ' + + str(dic_dados["artigo"]) + + "\n" + ) + tmp += ( + '\t\tParágrafo: ' + + str(dic_dados["paragrafo"]) + + "\n" + ) + tmp += ( + '\t\tInciso: ' + + str(dic_dados["inciso"]) + + "\n" + ) + tmp += ( + '\t\tAlí­nea: ' + + str(dic_dados["alinea"]) + + "\n" + ) + tmp += ( + '\t\tItem: ' + str(dic_dados["item"]) + "\n" + ) return tmp def documentos_acessorios(lst_acessorios): - - tmp = '' + tmp = "" tmp += '\t\tDocumentos Acessórios\n' for dic_dados in lst_acessorios: - if dic_dados['tipo'] != None: - tmp += '\t\tTipo: ' + \ - dic_dados['tipo'] + '\n' - - if dic_dados['nome'] != None: - tmp += '\t\tNome: ' + \ - dic_dados['nome'] + '\n' - - tmp += '\t\tData: ' + \ - dic_dados['data'] + '\n' - if dic_dados['autor'] != None: - tmp += '\t\tAutor: ' + \ - dic_dados['autor'] + '\n' - - if dic_dados['ementa'] != None: - tmp += '\t\tEmenta: ' + \ - dic_dados['ementa'].replace('&', '&') + '\n' - if dic_dados['indexacao'] != None: - tmp += '\t\tEmenta: ' + \ - dic_dados['indexacao'].replace('&', '&') + '\n' + if dic_dados["tipo"] != None: + tmp += ( + '\t\tTipo: ' + dic_dados["tipo"] + "\n" + ) + + if dic_dados["nome"] != None: + tmp += ( + '\t\tNome: ' + dic_dados["nome"] + "\n" + ) + + tmp += '\t\tData: ' + dic_dados["data"] + "\n" + if dic_dados["autor"] != None: + tmp += ( + '\t\tAutor: ' + dic_dados["autor"] + "\n" + ) + + if dic_dados["ementa"] != None: + tmp += ( + '\t\tEmenta: ' + + dic_dados["ementa"].replace("&", "&") + + "\n" + ) + if dic_dados["indexacao"] != None: + tmp += ( + '\t\tEmenta: ' + + dic_dados["indexacao"].replace("&", "&") + + "\n" + ) return tmp -def principal(imagem, dic_rodape, dic_inf_basicas, dic_orig_externa, lst_mat_anexadas, lst_autoria, lst_des_iniciais, - dic_tramitacoes, lst_relatorias, lst_numeracoes, lst_leg_citadas, lst_acessorios, sessao=''): +def principal( + imagem, + dic_rodape, + dic_inf_basicas, + dic_orig_externa, + lst_mat_anexadas, + lst_autoria, + lst_des_iniciais, + dic_tramitacoes, + lst_relatorias, + lst_numeracoes, + lst_leg_citadas, + lst_acessorios, + sessao="", +): """ Função principal responsável por chamar as funções que irão gerar o código rml apropriado """ arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp = '' + tmp = "" tmp += '\n' tmp += '\n' tmp += '\n' tmp += '\t\n' + tmp += "\t\t\n" + tmp += "\t\n" tmp += paraStyle() - tmp += '\t\n' + tmp += "\t\n" tmp += inf_basicas(dic_inf_basicas) tmp += orig_externa(dic_orig_externa) tmp += mat_anexadas(lst_mat_anexadas) @@ -404,11 +590,13 @@ def principal(imagem, dic_rodape, dic_inf_basicas, dic_orig_externa, lst_mat_ane tmp += numeracoes(lst_numeracoes) tmp += legislacoes_citadas(lst_leg_citadas) tmp += documentos_acessorios(lst_acessorios) - tmp += '\t\n' - tmp += '\n' + tmp += "\t\n" + tmp += "\n" tmp_pdf = parseString(tmp) return tmp_pdf + + # if hasattr(context.temp_folder,arquivoPdf): # context.temp_folder.manage_delObjects(ids=arquivoPdf) # context.temp_folder.manage_addFile(arquivoPdf) diff --git a/sapl/relatorios/templates/pdf_detalhe_materia_preparar_pysc.py b/sapl/relatorios/templates/pdf_detalhe_materia_preparar_pysc.py index 19d6271bc..65c5fbc96 100644 --- a/sapl/relatorios/templates/pdf_detalhe_materia_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_detalhe_materia_preparar_pysc.py @@ -7,8 +7,8 @@ session = request.SESSION cabecalho = {} # tenta buscar o logotipo da casa LOGO_CASA -if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl['logo_casa.gif'].absolute_url() +if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -17,34 +17,40 @@ casa = {} aux = context.sapl_documentos.props_sapl.propertyItems() for item in aux: casa[item[0]] = item[1] -localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) +localidade = context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"]) data_emissao = DateTime().strftime("%d/%m/%Y") rodape = casa -rodape['data_emissao'] = data_emissao +rodape["data_emissao"] = data_emissao inf_basicas_dic = {} -inf_basicas_dic['nom_camara'] = casa['nom_casa'] +inf_basicas_dic["nom_camara"] = casa["nom_casa"] REQUEST = context.REQUEST -for local in context.zsql.localidade_obter_zsql(cod_localidade=casa['cod_localidade']): - rodape['nom_localidade'] = " " + local.nom_localidade - rodape['sgl_uf'] = local.sgl_uf +for local in context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"]): + rodape["nom_localidade"] = " " + local.nom_localidade + rodape["sgl_uf"] = local.sgl_uf orig_externa_dic = {} -for materia in context.zsql.materia_obter_zsql(cod_materia=REQUEST['cod_materia']): +for materia in context.zsql.materia_obter_zsql(cod_materia=REQUEST["cod_materia"]): # Abaixo é gerado os dados para o bloco Informações Básicas (ln 23) - inf_basicas_dic['texto_projeto'] = materia.txt_ementa - inf_basicas_dic['apresentada'] = materia.dat_apresentacao - inf_basicas_dic['formato'] = materia.tip_apresentacao - inf_basicas_dic['publicada'] = materia.dat_publicacao - inf_basicas_dic['objeto'] = materia.des_objeto - inf_basicas_dic['tramitacao'] = materia.ind_tramitacao - inf_basicas_dic['cod_projeto'] = materia.sgl_tipo_materia + " " + \ - str(materia.num_ident_basica) + " de " + str(materia.ano_ident_basica) - inf_basicas_dic['nom_projeto'] = materia.des_tipo_materia + inf_basicas_dic["texto_projeto"] = materia.txt_ementa + inf_basicas_dic["apresentada"] = materia.dat_apresentacao + inf_basicas_dic["formato"] = materia.tip_apresentacao + inf_basicas_dic["publicada"] = materia.dat_publicacao + inf_basicas_dic["objeto"] = materia.des_objeto + inf_basicas_dic["tramitacao"] = materia.ind_tramitacao + inf_basicas_dic["cod_projeto"] = ( + materia.sgl_tipo_materia + + " " + + str(materia.num_ident_basica) + + " de " + + str(materia.ano_ident_basica) + ) + inf_basicas_dic["nom_projeto"] = materia.des_tipo_materia - for tramitacao in context.zsql.regime_tramitacao_obter_zsql(cod_regime_tramitacao=materia.cod_regime_tramitacao): + for tramitacao in context.zsql.regime_tramitacao_obter_zsql( + cod_regime_tramitacao=materia.cod_regime_tramitacao + ): # """#tratando possíveis erros""" # if tramitacao.des_regime_tramitacao==None: tramitacao.des_regime_tramitacao="" # if materia.num_dias_prazo==None: materia.num_dias_prazo="" @@ -55,18 +61,19 @@ for materia in context.zsql.materia_obter_zsql(cod_materia=REQUEST['cod_materia' # if materia.txt_indexacao==None: materia.txt_indexacao="" # if materia.txt_observacao==None: materia.txt_observacao="" # """#atribuindo valores""" - inf_basicas_dic['reg_tramitacao'] = tramitacao.des_regime_tramitacao - inf_basicas_dic['prazo'] = materia.num_dias_prazo - inf_basicas_dic['fim_prazo'] = materia.dat_fim_prazo - inf_basicas_dic['mat_complementar'] = materia.ind_complementar - inf_basicas_dic['polemica'] = materia.ind_polemica - inf_basicas_dic['apelido'] = materia.nom_apelido - inf_basicas_dic['indexacao'] = materia.txt_indexacao - inf_basicas_dic['observacao'] = materia.txt_observacao + inf_basicas_dic["reg_tramitacao"] = tramitacao.des_regime_tramitacao + inf_basicas_dic["prazo"] = materia.num_dias_prazo + inf_basicas_dic["fim_prazo"] = materia.dat_fim_prazo + inf_basicas_dic["mat_complementar"] = materia.ind_complementar + inf_basicas_dic["polemica"] = materia.ind_polemica + inf_basicas_dic["apelido"] = materia.nom_apelido + inf_basicas_dic["indexacao"] = materia.txt_indexacao + inf_basicas_dic["observacao"] = materia.txt_observacao - -# #o bloco abaixo gera o dicionario da origem externa (ln 47) - for origem in context.zsql.origem_obter_zsql(cod_origem=materia.cod_local_origem_externa): + # #o bloco abaixo gera o dicionario da origem externa (ln 47) + for origem in context.zsql.origem_obter_zsql( + cod_origem=materia.cod_local_origem_externa + ): # #tratando possíveis erros # if origem.sgl_origem==None: origem.sgl_origem="" # if origem.nom_origem==None: origem.nom_origem="" @@ -75,210 +82,277 @@ for materia in context.zsql.materia_obter_zsql(cod_materia=REQUEST['cod_materia' # if materia.num_origem_externa==None: materia.num_origem_externa="" # if materia.ano_origem_externa==None: materia.ano_origem_externa="" - orig_externa_dic['local'] = origem.sgl_origem + "-" + origem.nom_origem - orig_externa_dic['tipo'] = materia.tip_origem_externa - orig_externa_dic['data'] = materia.dat_origem_externa - orig_externa_dic['numero_ano'] = str( - materia.num_origem_externa) + "/" + str(materia.ano_origem_externa) + orig_externa_dic["local"] = origem.sgl_origem + "-" + origem.nom_origem + orig_externa_dic["tipo"] = materia.tip_origem_externa + orig_externa_dic["data"] = materia.dat_origem_externa + orig_externa_dic["numero_ano"] = ( + str(materia.num_origem_externa) + "/" + str(materia.ano_origem_externa) + ) -# #o bloco abaixo gera o dicionario das materias anexadas (ln 55) + # #o bloco abaixo gera o dicionario das materias anexadas (ln 55) lst_mat_anexadas = [] dic_mat = {} - for anexada in context.zsql.anexada_obter_zsql(cod_materia_principal=materia.cod_materia): - aux1 = context.zsql.materia_obter_zsql( - cod_materia=anexada.cod_materia_anexada) + for anexada in context.zsql.anexada_obter_zsql( + cod_materia_principal=materia.cod_materia + ): + aux1 = context.zsql.materia_obter_zsql(cod_materia=anexada.cod_materia_anexada) aux2 = context.zsql.tipo_materia_legislativa_obter_zsql( - tip_materia=aux1[0].tip_id_basica) -# """#tratando possíveis erros""" -# if aux2.sgl_tipo_materia==None: aux2.sgl_tipo_materia="" -# if aux2.num_ident_basica==None: aux2.num_ident_basica="" -# if aux1.ano_ident_basica==None: aux1.ano_ident_basica="" -# if anexadas.dat_anexacao==None: anexadas.dat_anexacao="" -# if anexadas.dat_desanexacao==None: anexadas.dat_desanexacao="" -# """#""" - dic_mat['nom_mat'] = aux2[0].sgl_tipo_materia + "/" + \ - str(aux1[0].num_ident_basica) + "/" + str(aux1[0].ano_ident_basica) - dic_mat['data'] = anexada.dat_anexacao - dic_mat['data_fim'] = anexada.dat_desanexacao + tip_materia=aux1[0].tip_id_basica + ) + # """#tratando possíveis erros""" + # if aux2.sgl_tipo_materia==None: aux2.sgl_tipo_materia="" + # if aux2.num_ident_basica==None: aux2.num_ident_basica="" + # if aux1.ano_ident_basica==None: aux1.ano_ident_basica="" + # if anexadas.dat_anexacao==None: anexadas.dat_anexacao="" + # if anexadas.dat_desanexacao==None: anexadas.dat_desanexacao="" + # """#""" + dic_mat["nom_mat"] = ( + aux2[0].sgl_tipo_materia + + "/" + + str(aux1[0].num_ident_basica) + + "/" + + str(aux1[0].ano_ident_basica) + ) + dic_mat["data"] = anexada.dat_anexacao + dic_mat["data_fim"] = anexada.dat_desanexacao lst_mat_anexadas.append(dic_mat) -# #o bloco abaixo gera o dicionario dos autores(ln 66) + # #o bloco abaixo gera o dicionario dos autores(ln 66) lst_autoria = [] -# dic_autor = {} + # dic_autor = {} for autoria in context.zsql.autoria_obter_zsql(cod_materia=materia.cod_materia): dic_autor = {} if autoria.ind_primeiro_autor: - dic_autor['tipo'] = "primeiro autor" + dic_autor["tipo"] = "primeiro autor" else: - dic_autor['tipo'] = " " + dic_autor["tipo"] = " " for autor in context.zsql.autor_obter_zsql(cod_autor=autoria.cod_autor): - dic_autor['cargo'] = " " - if autor.des_tipo_autor == 'Parlamentar': - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=autor.cod_parlamentar): - dic_autor['nom_autor'] = parlamentar.nom_completo - elif autor.des_tipo_autor == 'Comissao': - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=autor.cod_comissao): - dic_autor['nom_autor'] = comissao.nom_comissao + dic_autor["cargo"] = " " + if autor.des_tipo_autor == "Parlamentar": + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=autor.cod_parlamentar + ): + dic_autor["nom_autor"] = parlamentar.nom_completo + elif autor.des_tipo_autor == "Comissao": + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=autor.cod_comissao + ): + dic_autor["nom_autor"] = comissao.nom_comissao else: - dic_autor['nom_autor'] = autor.nom_autor - dic_autor['cargo'] = autor.des_cargo + dic_autor["nom_autor"] = autor.nom_autor + dic_autor["cargo"] = autor.des_cargo lst_autoria.append(dic_autor) -# """#tratando possíveis erros""" -# if autor.nom_autor==None: autor.nom_autor="" -# if autor.des_cargo==None: autor.des_cargo="" -# """#""" -# dic_autor['nom_autor']= autor.nom_autor -# dic_autor['cargo']= autor.des_cargo -# if autoria.ind_primeiro_autor: -# dic_autor['tipo']= "primeiro autor" -# else: -# dic_autor['tipo']= " " + # """#tratando possíveis erros""" + # if autor.nom_autor==None: autor.nom_autor="" + # if autor.des_cargo==None: autor.des_cargo="" + # """#""" + # dic_autor['nom_autor']= autor.nom_autor + # dic_autor['cargo']= autor.des_cargo + # if autoria.ind_primeiro_autor: + # dic_autor['tipo']= "primeiro autor" + # else: + # dic_autor['tipo']= " " -# #o bloco abaixo gera o dicionario de despachos iniciais (ln 79) + # #o bloco abaixo gera o dicionario de despachos iniciais (ln 79) lst_des_iniciais = [] - for despacho in context.zsql.despacho_inicial_obter_zsql(cod_materia=materia.cod_materia): - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=despacho.cod_comissao_sel): + for despacho in context.zsql.despacho_inicial_obter_zsql( + cod_materia=materia.cod_materia + ): + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=despacho.cod_comissao_sel + ): dic_dados = {} if comissao.nom_comissao == None: - comissao.nom_comissao = '' + comissao.nom_comissao = "" if comissao.sgl_comissao == None: - comissao.sgl_comissao = '' - dic_dados['nom_comissao'] = comissao.nom_comissao + \ - " - " + comissao.sgl_comissao + comissao.sgl_comissao = "" + dic_dados["nom_comissao"] = ( + comissao.nom_comissao + " - " + comissao.sgl_comissao + ) lst_des_iniciais.append(dic_dados) -# #o bloco abaixo gera o dicionário de Tramitacoes(ln 87) + # #o bloco abaixo gera o dicionário de Tramitacoes(ln 87) dic_tramitacoes = {} - for tramitacao in context.zsql.tramitacao_obter_zsql(cod_materia=REQUEST['cod_materia'], ind_ult_tramitacao=1): - dic_tramitacoes['data'] = tramitacao.dat_tramitacao - dic_tramitacoes['data_enc'] = tramitacao.dat_encaminha - dic_tramitacoes['turno'] = tramitacao.sgl_turno - dic_tramitacoes['status'] = tramitacao.des_status - dic_tramitacoes['urgente'] = tramitacao.ind_urgencia - dic_tramitacoes['data_fim'] = tramitacao.dat_fim_prazo - dic_tramitacoes['texto_acao'] = tramitacao.txt_tramitacao + for tramitacao in context.zsql.tramitacao_obter_zsql( + cod_materia=REQUEST["cod_materia"], ind_ult_tramitacao=1 + ): + dic_tramitacoes["data"] = tramitacao.dat_tramitacao + dic_tramitacoes["data_enc"] = tramitacao.dat_encaminha + dic_tramitacoes["turno"] = tramitacao.sgl_turno + dic_tramitacoes["status"] = tramitacao.des_status + dic_tramitacoes["urgente"] = tramitacao.ind_urgencia + dic_tramitacoes["data_fim"] = tramitacao.dat_fim_prazo + dic_tramitacoes["texto_acao"] = tramitacao.txt_tramitacao - for unidade in context.zsql.unidade_tramitacao_obter_zsql(cod_unid_tramitacao=tramitacao.cod_unid_tram_local): - #-----------------se unidade for comissao-------------------------- + for unidade in context.zsql.unidade_tramitacao_obter_zsql( + cod_unid_tramitacao=tramitacao.cod_unid_tram_local + ): + # -----------------se unidade for comissao-------------------------- if unidade.cod_orgao == None: - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=unidade.cod_comissao): + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=unidade.cod_comissao + ): if tramitacao.cod_unid_tram_dest != None: - for unidade_dest in context.zsql.unidade_tramitacao_obter_zsql(cod_unid_tramitacao=tramitacao.cod_unid_tram_dest): + for unidade_dest in context.zsql.unidade_tramitacao_obter_zsql( + cod_unid_tramitacao=tramitacao.cod_unid_tram_dest + ): # se unidade destino for comissao if unidade_dest.cod_orgao == None: - for comissao_dest in context.zsql.comissao_obter_zsql(cod_comissao=unidade_dest.cod_comissao): - dic_tramitacoes[ - 'unidade'] = comissao.nom_comissao + for comissao_dest in context.zsql.comissao_obter_zsql( + cod_comissao=unidade_dest.cod_comissao + ): + dic_tramitacoes["unidade"] = comissao.nom_comissao dic_tramitacoes[ - 'destino'] = comissao_dest.nom_comissao + "destino" + ] = comissao_dest.nom_comissao # se unidade destino for orgao if unidade_dest.cod_comissao == None: - for orgao_dest in context.zsql.orgao_obter_zsql(cod_orgao=unidade_dest.cod_orgao): - dic_tramitacoes[ - 'unidade'] = comissao.nom_comissao - dic_tramitacoes[ - 'destino'] = orgao_dest.nom_orgao + for orgao_dest in context.zsql.orgao_obter_zsql( + cod_orgao=unidade_dest.cod_orgao + ): + dic_tramitacoes["unidade"] = comissao.nom_comissao + dic_tramitacoes["destino"] = orgao_dest.nom_orgao else: - dic_tramitacoes['unidade'] = comissao.nom_comissao - dic_tramitacoes['destino'] = "None" - #---------------se unidade for orgao------------------------------- + dic_tramitacoes["unidade"] = comissao.nom_comissao + dic_tramitacoes["destino"] = "None" + # ---------------se unidade for orgao------------------------------- if unidade.cod_comissao == None: for orgao in context.zsql.orgao_obter_zsql(cod_orgao=unidade.cod_orgao): if tramitacao.cod_unid_tram_dest != None: - for unidade_dest in context.zsql.unidade_tramitacao_obter_zsql(cod_unid_tramitacao=tramitacao.cod_unid_tram_dest): + for unidade_dest in context.zsql.unidade_tramitacao_obter_zsql( + cod_unid_tramitacao=tramitacao.cod_unid_tram_dest + ): # se unidade destino for comissao if unidade_dest.cod_orgao == None: - for comissao_dest in context.zsql.comissao_obter_zsql(cod_comissao=unidade_dest.cod_comissao): + for comissao_dest in context.zsql.comissao_obter_zsql( + cod_comissao=unidade_dest.cod_comissao + ): + dic_tramitacoes["unidade"] = orgao.nom_orgao dic_tramitacoes[ - 'unidade'] = orgao.nom_orgao - dic_tramitacoes[ - 'destino'] = comissao_dest.nom_comissao + "destino" + ] = comissao_dest.nom_comissao # se unidade destino for orgao if unidade_dest.cod_comissao == None: - for orgao_dest in context.zsql.orgao_obter_zsql(cod_orgao=unidade_dest.cod_orgao): - dic_tramitacoes[ - 'unidade'] = orgao.nom_orgao - dic_tramitacoes[ - 'destino'] = orgao_dest.nom_orgao + for orgao_dest in context.zsql.orgao_obter_zsql( + cod_orgao=unidade_dest.cod_orgao + ): + dic_tramitacoes["unidade"] = orgao.nom_orgao + dic_tramitacoes["destino"] = orgao_dest.nom_orgao else: - dic_tramitacoes['unidade'] = orgao.nom_orgao - dic_tramitacoes['destino'] = "None" + dic_tramitacoes["unidade"] = orgao.nom_orgao + dic_tramitacoes["destino"] = "None" -# #o bloco abaixo gera o dicionario de relatorias(ln 106) + # #o bloco abaixo gera o dicionario de relatorias(ln 106) lst_relatorias = [] dic_comissao = {} for relatoria in context.zsql.relatoria_obter_zsql(cod_materia=materia.cod_materia): - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=relatoria.cod_comissao): - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=relatoria.cod_parlamentar): - dic_comissao['nom_comissao'] = comissao.nom_comissao - dic_comissao['data_desig'] = relatoria.dat_desig_relator - dic_comissao['parlamentar'] = parlamentar.nom_completo - dic_comissao['data_dest'] = relatoria.dat_destit_relator - if relatoria.tip_fim_relatoria == None or relatoria.tip_fim_relatoria == '0': + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=relatoria.cod_comissao + ): + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=relatoria.cod_parlamentar + ): + dic_comissao["nom_comissao"] = comissao.nom_comissao + dic_comissao["data_desig"] = relatoria.dat_desig_relator + dic_comissao["parlamentar"] = parlamentar.nom_completo + dic_comissao["data_dest"] = relatoria.dat_destit_relator + if ( + relatoria.tip_fim_relatoria == None + or relatoria.tip_fim_relatoria == "0" + ): num = 0 - dic_comissao['motivo'] = "" + dic_comissao["motivo"] = "" else: num = relatoria.tip_fim_relatoria - for tipo_fim in context.zsql.tipo_fim_relatoria_obter_zsql(tip_fim_relatoria=num): - dic_comissao['motivo'] = tipo_fim.des_fim_relatoria + for tipo_fim in context.zsql.tipo_fim_relatoria_obter_zsql( + tip_fim_relatoria=num + ): + dic_comissao["motivo"] = tipo_fim.des_fim_relatoria lst_relatorias.append(dic_comissao) -# #o bloco abaixo gera o dicionario de Numeracoes(ln 121) + # #o bloco abaixo gera o dicionario de Numeracoes(ln 121) lst_numeracoes = [] dic_dados = {} for numeracao in context.zsql.numeracao_obter_zsql(cod_materia=materia.cod_materia): - for tipo_materia in context.zsql.tipo_materia_legislativa_obter_zsql(tip_materia=numeracao.tip_materia): - dic_dados['nome'] = tipo_materia.sgl_tipo_materia + "-" + \ - tipo_materia.des_tipo_materia + "nº" + numeracao.num_materia - dic_dados['ano'] = numeracao.ano_materia + for tipo_materia in context.zsql.tipo_materia_legislativa_obter_zsql( + tip_materia=numeracao.tip_materia + ): + dic_dados["nome"] = ( + tipo_materia.sgl_tipo_materia + + "-" + + tipo_materia.des_tipo_materia + + "nº" + + numeracao.num_materia + ) + dic_dados["ano"] = numeracao.ano_materia lst_numeracoes.append(dic_dados) - -# #o bloco abaixo gera o dicionário de legislacoes citadas(132) + # #o bloco abaixo gera o dicionário de legislacoes citadas(132) lst_legis_citadas = [] dic_dados = {} - for legislacao in context.zsql.legislacao_citada_obter_zsql(cod_materia=materia.cod_materia): + for legislacao in context.zsql.legislacao_citada_obter_zsql( + cod_materia=materia.cod_materia + ): norma = context.zsql.norma_juridica_obter_zsql( - cod_norma=legislacao.cod_norma_sel) - dic_dados['nome_lei'] = str(norma[0].tip_norma_sel) + " nº" + \ - str(norma[0].num_norma) + " de" + str(norma[0].ano_norma) - dic_dados['disposicao'] = legislacao.des_disposicoes - dic_dados['parte'] = legislacao.des_parte - dic_dados['livro'] = legislacao.des_livro - dic_dados['titulo'] = legislacao.des_titulo - dic_dados['capitulo'] = legislacao.des_capitulo - dic_dados['secao'] = legislacao.des_secao - dic_dados['subsecao'] = legislacao.des_subsecao - dic_dados['artigo'] = legislacao.des_artigo - dic_dados['paragrafo'] = legislacao.des_paragrafo - dic_dados['inciso'] = legislacao.des_inciso - dic_dados['alinea'] = legislacao.des_alinea - dic_dados['item'] = legislacao.des_item + cod_norma=legislacao.cod_norma_sel + ) + dic_dados["nome_lei"] = ( + str(norma[0].tip_norma_sel) + + " nº" + + str(norma[0].num_norma) + + " de" + + str(norma[0].ano_norma) + ) + dic_dados["disposicao"] = legislacao.des_disposicoes + dic_dados["parte"] = legislacao.des_parte + dic_dados["livro"] = legislacao.des_livro + dic_dados["titulo"] = legislacao.des_titulo + dic_dados["capitulo"] = legislacao.des_capitulo + dic_dados["secao"] = legislacao.des_secao + dic_dados["subsecao"] = legislacao.des_subsecao + dic_dados["artigo"] = legislacao.des_artigo + dic_dados["paragrafo"] = legislacao.des_paragrafo + dic_dados["inciso"] = legislacao.des_inciso + dic_dados["alinea"] = legislacao.des_alinea + dic_dados["item"] = legislacao.des_item lst_legis_citadas.append(dic_dados) - -# #o bloco abaixo gera o dicionario de Documentos Acessórios(153) + # #o bloco abaixo gera o dicionario de Documentos Acessórios(153) lst_acessorios = [] - for documento in context.zsql.documento_acessorio_obter_zsql(cod_materia=materia.cod_materia): + for documento in context.zsql.documento_acessorio_obter_zsql( + cod_materia=materia.cod_materia + ): dic_dados = {} - dic_dados['tipo'] = documento.tip_documento - dic_dados['nome'] = documento.nom_documento - dic_dados['data'] = documento.dat_documento - dic_dados['autor'] = documento.nom_autor_documento - dic_dados['ementa'] = documento.txt_ementa - dic_dados['indexacao'] = documento.txt_indexacao + dic_dados["tipo"] = documento.tip_documento + dic_dados["nome"] = documento.nom_documento + dic_dados["data"] = documento.dat_documento + dic_dados["autor"] = documento.nom_autor_documento + dic_dados["ementa"] = documento.txt_ementa + dic_dados["indexacao"] = documento.txt_indexacao lst_acessorios.append(dic_dados) -caminho = context.pdf_detalhe_materia_gerar(imagem, rodape, inf_basicas_dic, orig_externa_dic, lst_mat_anexadas, lst_autoria, - lst_des_iniciais, dic_tramitacoes, lst_relatorias, lst_numeracoes, - lst_legis_citadas, lst_acessorios, sessao=session.id) -if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') +caminho = context.pdf_detalhe_materia_gerar( + imagem, + rodape, + inf_basicas_dic, + orig_externa_dic, + lst_mat_anexadas, + lst_autoria, + lst_des_iniciais, + dic_tramitacoes, + lst_relatorias, + lst_numeracoes, + lst_legis_citadas, + lst_acessorios, + sessao=session.id, +) +if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_documento_administrativo_gerar.py b/sapl/relatorios/templates/pdf_documento_administrativo_gerar.py index 2dc8d363e..a5d096faf 100755 --- a/sapl/relatorios/templates/pdf_documento_administrativo_gerar.py +++ b/sapl/relatorios/templates/pdf_documento_administrativo_gerar.py @@ -7,22 +7,28 @@ Empresa: OpenLegis Consultoria versão: 1.0 """ -import time import os +import time from trml2pdf import parseString def cabecalho(dic_cabecalho, imagem): """Gera o codigo rml do cabecalho""" - tmp_data = '' + tmp_data = "" if os.path.isfile(imagem): - tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t2cm 25.4cm 19cm 25.4cm\n' + tmp_data += ( + '\t\t\t\t\n' + ) + tmp_data += "\t\t\t\t2cm 25.4cm 19cm 25.4cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - dic_cabecalho['nom_casa'] + '\n' + tmp_data += ( + '\t\t\t\t' + + dic_cabecalho["nom_casa"] + + "\n" + ) tmp_data += '\t\t\t\t\n' tmp_data += '\t\t\t\tSistema de Apoio ao Processo Legislativo\n' tmp_data += '\t\t\t\t\n' @@ -34,16 +40,25 @@ def cabecalho(dic_cabecalho, imagem): def rodape(lst_rodape): """Gera o codigo rml do rodape""" - tmp_data = '' - tmp_data += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + tmp_data = "" + tmp_data += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[2] + '\n' - tmp_data += '\t\t\t\tPágina \n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[0] + '\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[1] + '\n' + tmp_data += ( + '\t\t\t\t' + lst_rodape[2] + "\n" + ) + tmp_data += ( + '\t\t\t\tPágina \n' + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[0] + + "\n" + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[1] + + "\n" + ) return tmp_data @@ -51,18 +66,18 @@ def rodape(lst_rodape): def paraStyle(): """Gera o codigo rml que define o estilo dos paragrafos""" - tmp_data = '' - tmp_data += '\t\n' + tmp_data = "" + tmp_data += "\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t\n' tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" + tmp_data += "\t\t\n" tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\n' - tmp_data += '\t\n' + tmp_data += "\t\n" return tmp_data @@ -70,47 +85,59 @@ def paraStyle(): def documentos(lst_documentos): """Gera o codigo rml do conteudo da pesquisa de documentos administrativos""" - tmp_data = '' + tmp_data = "" # inicio do bloco que contem os flowables - tmp_data += '\t\n' + tmp_data += "\t\n" for dic in lst_documentos: # espaco inicial tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" # condicao para a quebra de pagina tmp_data += '\t\t\n' # materias - if dic['titulo'] != None: - tmp_data += '\t\t' + dic['titulo'] + '\n' + if dic["titulo"] != None: + tmp_data += '\t\t' + dic["titulo"] + "\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' - if dic['txt_assunto'] != None: - txt_assunto = dic['txt_assunto'].replace('&', '&') - tmp_data += '\t\t' + txt_assunto + '\n' - - if dic['txt_interessado'] != None: - tmp_data += '\t\tInteressado: ' + \ - dic['txt_interessado'] + '\n' - if dic['localizacao_atual'] != None: - tmp_data += '\t\tLocalização Atual: ' + \ - dic['localizacao_atual'] + '\n' - if dic['des_situacao'] != None: - tmp_data += '\t\tSituação: ' + \ - dic['des_situacao'] + '\n' - if dic['ultima_acao'] != None: - tmp_data += '\t\tÚltima Ação: ' + \ - dic['ultima_acao'] + '\n' - - tmp_data += '\t\n' + tmp_data += "\t\t\n" + if dic["txt_assunto"] != None: + txt_assunto = dic["txt_assunto"].replace("&", "&") + tmp_data += '\t\t' + txt_assunto + "\n" + + if dic["txt_interessado"] != None: + tmp_data += ( + '\t\tInteressado: ' + + dic["txt_interessado"] + + "\n" + ) + if dic["localizacao_atual"] != None: + tmp_data += ( + '\t\tLocalização Atual: ' + + dic["localizacao_atual"] + + "\n" + ) + if dic["des_situacao"] != None: + tmp_data += ( + '\t\tSituação: ' + + dic["des_situacao"] + + "\n" + ) + if dic["ultima_acao"] != None: + tmp_data += ( + '\t\tÚltima Ação: ' + + dic["ultima_acao"] + + "\n" + ) + + tmp_data += "\t\n" return tmp_data @@ -119,26 +146,29 @@ def principal(imagem, lst_documentos, dic_cabecalho, lst_rodape): arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp_data = '' + tmp_data = "" tmp_data += '\n' tmp_data += '\n' tmp_data += '\n' tmp_data += '\t\n' + tmp_data += "\t\t\t\n" + tmp_data += ( + '\t\t\t\n' + ) + tmp_data += "\t\t\n" + tmp_data += "\t\n" tmp_data += paraStyle() tmp_data += documentos(lst_documentos) - tmp_data += '\n' + tmp_data += "\n" tmp_pdf = parseString(tmp_data) return tmp_pdf + # if hasattr(context.temp_folder,arquivoPdf): # context.temp_folder.manage_delObjects(ids=arquivoPdf) # context.temp_folder.manage_addFile(arquivoPdf) diff --git a/sapl/relatorios/templates/pdf_documento_administrativo_preparar_pysc.py b/sapl/relatorios/templates/pdf_documento_administrativo_preparar_pysc.py index 775ad3d68..8db2fb5dc 100755 --- a/sapl/relatorios/templates/pdf_documento_administrativo_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_documento_administrativo_preparar_pysc.py @@ -4,15 +4,14 @@ request = context.REQUEST response = request.RESPONSE session = request.SESSION -data = DateTime().strftime('%d/%m/%Y') +data = DateTime().strftime("%d/%m/%Y") # Abaixo é gerada a string para o rodapé da página casa = {} aux = context.sapl_documentos.props_sapl.propertyItems() for item in aux: casa[item[0]] = item[1] -localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) +localidade = context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"]) if len(casa["num_cep"]) == 8: cep = casa["num_cep"][:4] + "-" + casa["num_cep"][5:] else: @@ -24,8 +23,7 @@ if cep != "": linha1 = linha1 + " - " linha1 = linha1 + "CEP " + cep if localidade[0].nom_localidade != "" and localidade[0].nom_localidade != None: - linha1 = linha1 + " - " + \ - localidade[0].nom_localidade + " " + localidade[0].sgl_uf + linha1 = linha1 + " - " + localidade[0].nom_localidade + " " + localidade[0].sgl_uf if casa["num_tel"] != "" and casa["num_tel"] != None: linha1 = linha1 + " Tel.: " + casa["num_tel"] @@ -49,8 +47,8 @@ cabecalho["nom_casa"] = casa["nom_casa"] cabecalho["nom_estado"] = "Estado de " + nom_estado # tenta buscar o logotipo da casa LOGO_CASA -if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl['logo_casa.gif'].absolute_url() +if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -58,78 +56,98 @@ else: documentos = [] REQUEST = context.REQUEST -for documento in context.zsql.documento_administrativo_pesquisar_zsql(tip_documento=REQUEST['lst_tip_documento'], - num_documento=REQUEST['txt_num_documento'], ano_documento=REQUEST[ - 'txt_ano_documento'], - num_protocolo=REQUEST[ - 'txt_num_protocolo'], ind_tramitacao=REQUEST['rad_tramitando'], - des_assunto=REQUEST[ - 'txa_txt_assunto'], cod_status=REQUEST['lst_status'], - txt_interessado=REQUEST[ - 'txa_txt_interessado'], dat_apres1=REQUEST['dt_apres1'], - dat_apres2=REQUEST['dt_apres2'], rd_ordem=REQUEST['rd_ordenacao']): +for documento in context.zsql.documento_administrativo_pesquisar_zsql( + tip_documento=REQUEST["lst_tip_documento"], + num_documento=REQUEST["txt_num_documento"], + ano_documento=REQUEST["txt_ano_documento"], + num_protocolo=REQUEST["txt_num_protocolo"], + ind_tramitacao=REQUEST["rad_tramitando"], + des_assunto=REQUEST["txa_txt_assunto"], + cod_status=REQUEST["lst_status"], + txt_interessado=REQUEST["txa_txt_interessado"], + dat_apres1=REQUEST["dt_apres1"], + dat_apres2=REQUEST["dt_apres2"], + rd_ordem=REQUEST["rd_ordenacao"], +): dic = {} - dic['titulo'] = documento.sgl_tipo_documento + " " + \ - str(documento.num_documento) + " " + \ - str(documento.ano_documento) + " - " + documento.des_tipo_documento - dic['txt_assunto'] = documento.txt_assunto - dic['txt_interessado'] = documento.txt_interessado - - des_status = '' - txt_tramitacao = '' - - dic['localizacao_atual'] = " " - for tramitacao in context.zsql.tramitacao_administrativo_obter_zsql(cod_documento=documento.cod_documento, ind_ult_tramitacao=1): + dic["titulo"] = ( + documento.sgl_tipo_documento + + " " + + str(documento.num_documento) + + " " + + str(documento.ano_documento) + + " - " + + documento.des_tipo_documento + ) + dic["txt_assunto"] = documento.txt_assunto + dic["txt_interessado"] = documento.txt_interessado + + des_status = "" + txt_tramitacao = "" + + dic["localizacao_atual"] = " " + for tramitacao in context.zsql.tramitacao_administrativo_obter_zsql( + cod_documento=documento.cod_documento, ind_ult_tramitacao=1 + ): if tramitacao.cod_unid_tram_dest: cod_unid_tram = tramitacao.cod_unid_tram_dest else: cod_unid_tram = tramitacao.cod_unid_tram_local - for unidade_tramitacao in context.zsql.unidade_tramitacao_obter_zsql(cod_unid_tramitacao=cod_unid_tram): + for unidade_tramitacao in context.zsql.unidade_tramitacao_obter_zsql( + cod_unid_tramitacao=cod_unid_tram + ): if unidade_tramitacao.cod_orgao: - dic['localizacao_atual'] = unidade_tramitacao.nom_orgao + dic["localizacao_atual"] = unidade_tramitacao.nom_orgao else: - dic['localizacao_atual'] = unidade_tramitacao.nom_comissao + dic["localizacao_atual"] = unidade_tramitacao.nom_comissao des_status = tramitacao.des_status txt_tramitacao = tramitacao.txt_tramitacao - dic['des_situacao'] = des_status - dic['ultima_acao'] = txt_tramitacao + dic["des_situacao"] = des_status + dic["ultima_acao"] = txt_tramitacao documentos.append(dic) filtro = {} # Dicionário que conterá os dados do filtro # Atribuições diretas do REQUEST -filtro['numero'] = REQUEST.txt_num_documento -filtro['ano'] = REQUEST.txt_ano_documento -filtro['interessado'] = REQUEST.txa_txt_interessado -filtro['assunto'] = REQUEST.txa_txt_assunto - -filtro['tipo_documento'] = '' -if REQUEST.lst_tip_documento != '': - for tipo_documento in context.zsql.tipo_documento_administrativo_obter_zsql(ind_excluido=0, tip_documento=REQUEST.lst_tip_documento): - filtro['tipo_documento'] = tipo_documento.sgl_tipo_documento + \ - ' - ' + tipo_documento.des_tipo_documento - -filtro['tramitando'] = '' -if REQUEST.rad_tramitando == '1': - filtro['tramitacao'] = 'Sim' -elif REQUEST['rad_tramitando'] == '0': - filtro['tramitacao'] = 'Não' - -filtro['situacao_atual'] = '' -if REQUEST.lst_status != '': - for status in context.zsql.status_tramitacao_administrativo_obter_zsql(ind_exluido=0, cod_status=REQUEST.lst_status): - filtro['situacao_atual'] = status.sgl_status + \ - ' - ' + status.des_status +filtro["numero"] = REQUEST.txt_num_documento +filtro["ano"] = REQUEST.txt_ano_documento +filtro["interessado"] = REQUEST.txa_txt_interessado +filtro["assunto"] = REQUEST.txa_txt_assunto + +filtro["tipo_documento"] = "" +if REQUEST.lst_tip_documento != "": + for tipo_documento in context.zsql.tipo_documento_administrativo_obter_zsql( + ind_excluido=0, tip_documento=REQUEST.lst_tip_documento + ): + filtro["tipo_documento"] = ( + tipo_documento.sgl_tipo_documento + + " - " + + tipo_documento.des_tipo_documento + ) + +filtro["tramitando"] = "" +if REQUEST.rad_tramitando == "1": + filtro["tramitacao"] = "Sim" +elif REQUEST["rad_tramitando"] == "0": + filtro["tramitacao"] = "Não" + +filtro["situacao_atual"] = "" +if REQUEST.lst_status != "": + for status in context.zsql.status_tramitacao_administrativo_obter_zsql( + ind_exluido=0, cod_status=REQUEST.lst_status + ): + filtro["situacao_atual"] = status.sgl_status + " - " + status.des_status sessao = session.id caminho = context.pdf_documento_administrativo_gerar( - sessao, imagem, data, documentos, cabecalho, rodape, filtro) -if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + sessao, imagem, data, documentos, cabecalho, rodape, filtro +) +if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_espelho_gerar.py b/sapl/relatorios/templates/pdf_espelho_gerar.py index 769d56790..59a7db864 100644 --- a/sapl/relatorios/templates/pdf_espelho_gerar.py +++ b/sapl/relatorios/templates/pdf_espelho_gerar.py @@ -6,25 +6,34 @@ Empresa: Interlegis versão: 1.0 """ -import time import os +import time from trml2pdf import parseString def cabecalho(dic_cabecalho, imagem): """Gera o codigo rml do cabecalho""" - tmp_data = '' + tmp_data = "" if os.path.isfile(imagem): - tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t2cm 25cm 19cm 25cm\n' + tmp_data += ( + '\t\t\t\t\n' + ) + tmp_data += "\t\t\t\t2cm 25cm 19cm 25cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - dic_cabecalho['nom_casa'] + '\n' + tmp_data += ( + '\t\t\t\t' + + dic_cabecalho["nom_casa"] + + "\n" + ) tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - dic_cabecalho['nom_estado'] + '\n' + tmp_data += ( + '\t\t\t\t' + + dic_cabecalho["nom_estado"] + + "\n" + ) tmp_data += '\t\t\t\t\n' tmp_data += '\t\t\t\tSECRETARIA\n' return tmp_data @@ -32,126 +41,143 @@ def cabecalho(dic_cabecalho, imagem): def rodape(lst_rodape): """Gera o codigo rml do rodape""" - tmp_data = '' - tmp_data += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + tmp_data = "" + tmp_data += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[2] + '\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[0] + '\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[1] + '\n' + tmp_data += ( + '\t\t\t\t' + lst_rodape[2] + "\n" + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[0] + + "\n" + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[1] + + "\n" + ) return tmp_data def paraStyle(): """Gera o codigo rml que define o estilo dos paragrafos""" - tmp_data = '' - tmp_data += '\t\n' + tmp_data = "" + tmp_data += "\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t\n' tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" + tmp_data += "\t\t\n" tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\n' - tmp_data += '\t\n' + tmp_data += "\t\n" return tmp_data def materias(lst_materias): """Gera o codigo rml do conteudo da pesquisa de materias""" - tmp_data = '' + tmp_data = "" # inicio do bloco que contem os flowables - tmp_data += '\t\n' + tmp_data += "\t\n" for dic in lst_materias: # espaco inicial - # tmp_data+='\t\t\n' - # tmp_data+='\t\t\t \n' - # tmp_data+='\t\t\n' - # tmp_data+='\t\t\n' - # tmp_data+='\t\t\t \n' - # tmp_data+='\t\t\n' + # tmp_data+='\t\t\n' + # tmp_data+='\t\t\t \n' + # tmp_data+='\t\t\n' + # tmp_data+='\t\t\n' + # tmp_data+='\t\t\t \n' + # tmp_data+='\t\t\n' # condicao para a quebra de pagina tmp_data += '\t\t\n' # materias -# if dic['titulo']!=None: -# tmp_data+='\t\t' + dic['titulo'] + '\n' -# tmp_data+='\t\t\n' -# tmp_data+='\t\t\t \n' -# tmp_data+='\t\t\n' + # if dic['titulo']!=None: + # tmp_data+='\t\t' + dic['titulo'] + '\n' + # tmp_data+='\t\t\n' + # tmp_data+='\t\t\t \n' + # tmp_data+='\t\t\n' - if dic['materia'] != None: + if dic["materia"] != None: tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' - tmp_data += '\t\tINDICAÇÃO: ' + \ - dic['materia'] + '\n' + tmp_data += "\t\t\n" + tmp_data += ( + '\t\tINDICAÇÃO: ' + dic["materia"] + "\n" + ) tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' - - if dic['dat_apresentacao'] != None: - tmp_data += '\t\tDATA DE ENTRADA: ' + \ - dic['dat_apresentacao'] + '\n' + tmp_data += "\t\t\n" + + if dic["dat_apresentacao"] != None: + tmp_data += ( + '\t\tDATA DE ENTRADA: ' + + dic["dat_apresentacao"] + + "\n" + ) tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" - if dic['nom_autor'] != None: - tmp_data += '\t\tAUTOR: ' + \ - dic['nom_autor'] + '\n' + if dic["nom_autor"] != None: + tmp_data += ( + '\t\tAUTOR: ' + dic["nom_autor"] + "\n" + ) tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" - if dic['txt_ementa'] != None: - txt_ementa = dic['txt_ementa'].replace('&', '&') - tmp_data += '\t\tEMENTA: ' + \ - dic['txt_ementa'] + '\n' + if dic["txt_ementa"] != None: + txt_ementa = dic["txt_ementa"].replace("&", "&") + tmp_data += ( + '\t\tEMENTA: ' + dic["txt_ementa"] + "\n" + ) tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" - tmp_data += '\t\n' + tmp_data += "\t\n" return tmp_data def principal(imagem, lst_materias, dic_cabecalho, lst_rodape): """Funcao pricipal que gera a estrutura global do arquivo rml""" -# if sessao: -# arquivoPdf=sessao+".pdf" -# else: -# arquivoPdf=str(int(time.time()*100))+".pdf" + # if sessao: + # arquivoPdf=sessao+".pdf" + # else: + # arquivoPdf=str(int(time.time()*100))+".pdf" arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp_data = '' + tmp_data = "" tmp_data += '\n' tmp_data += '\n' tmp_data += '\n' tmp_data += '\t\n' + tmp_data += "\t\t\t\n" + tmp_data += ( + '\t\t\t\n' + ) + tmp_data += "\t\t\n" + tmp_data += "\t\n" tmp_data += paraStyle() tmp_data += materias(lst_materias) - tmp_data += '\n' + tmp_data += "\n" tmp_pdf = parseString(tmp_data) return tmp_pdf + + # try: # tmp_pdf=parseString(unicode(tmp_data, 'utf-8')) # except: diff --git a/sapl/relatorios/templates/pdf_espelho_preparar_pysc.py b/sapl/relatorios/templates/pdf_espelho_preparar_pysc.py index 43fae0f7c..5b0d7e921 100644 --- a/sapl/relatorios/templates/pdf_espelho_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_espelho_preparar_pysc.py @@ -4,15 +4,14 @@ request = context.REQUEST response = request.RESPONSE session = request.SESSION -data = DateTime().strftime('%d/%m/%Y') +data = DateTime().strftime("%d/%m/%Y") # Abaixo é gerada a string para o rodapé da página casa = {} aux = context.sapl_documentos.props_sapl.propertyItems() for item in aux: casa[item[0]] = item[1] -localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) +localidade = context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"]) if len(casa["num_cep"]) == 8: cep = casa["num_cep"][:4] + "-" + casa["num_cep"][5:] else: @@ -24,8 +23,7 @@ if cep != "": linha1 = linha1 + " - " linha1 = linha1 + "CEP " + cep if localidade[0].nom_localidade != "" and localidade[0].nom_localidade != None: - linha1 = linha1 + " - " + \ - localidade[0].nom_localidade + " " + localidade[0].sgl_uf + linha1 = linha1 + " - " + localidade[0].nom_localidade + " " + localidade[0].sgl_uf if casa["num_tel"] != "" and casa["num_tel"] != None: linha1 = linha1 + " Tel.: " + casa["num_tel"] @@ -49,69 +47,91 @@ cabecalho["nom_casa"] = casa["nom_casa"] cabecalho["nom_estado"] = "Estado de " + nom_estado # tenta buscar o logotipo da casa LOGO_CASA -if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl['logo_casa.gif'].absolute_url() +if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.sapl_site.sapl_skin.imagens.absolute_url() + "/brasao_transp.gif" # Verifica o tamanho da lista das materias selecionadas vindas do form REQUEST = context.REQUEST -if REQUEST.txt_check == '1': - cod_mat = REQUEST['check_ind'] +if REQUEST.txt_check == "1": + cod_mat = REQUEST["check_ind"] materias = [] REQUEST = context.REQUEST for materia in context.zsql.materia_obter_zsql(cod_materia=cod_mat): dic = {} - dic['titulo'] = "INDICAÇÃO: " + \ - str(materia.num_ident_basica) + " " + str(materia.ano_ident_basica) - dic['materia'] = str(materia.num_ident_basica) + \ - "/" + str(materia.ano_ident_basica) - dic['dat_apresentacao'] = materia.dat_apresentacao - dic['txt_ementa'] = materia.txt_ementa - - dic['nom_autor'] = " " - for autoria in context.zsql.autoria_obter_zsql(cod_materia=materia.cod_materia, ind_primeiro_autor=1): + dic["titulo"] = ( + "INDICAÇÃO: " + + str(materia.num_ident_basica) + + " " + + str(materia.ano_ident_basica) + ) + dic["materia"] = ( + str(materia.num_ident_basica) + "/" + str(materia.ano_ident_basica) + ) + dic["dat_apresentacao"] = materia.dat_apresentacao + dic["txt_ementa"] = materia.txt_ementa + + dic["nom_autor"] = " " + for autoria in context.zsql.autoria_obter_zsql( + cod_materia=materia.cod_materia, ind_primeiro_autor=1 + ): for autor in context.zsql.autor_obter_zsql(cod_autor=autoria.cod_autor): - if autor.des_tipo_autor == 'Parlamentar': - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=autor.cod_parlamentar): - dic['nom_autor'] = parlamentar.nom_completo - elif autor.des_tipo_autor == 'Comissao': - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=autor.cod_comissao): - dic['nom_autor'] = comissao.nom_comissao + if autor.des_tipo_autor == "Parlamentar": + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=autor.cod_parlamentar + ): + dic["nom_autor"] = parlamentar.nom_completo + elif autor.des_tipo_autor == "Comissao": + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=autor.cod_comissao + ): + dic["nom_autor"] = comissao.nom_comissao else: - dic['nom_autor'] = autor.nom_autor + dic["nom_autor"] = autor.nom_autor - des_status = '' - txt_tramitacao = '' - data_ultima_acao = '' + des_status = "" + txt_tramitacao = "" + data_ultima_acao = "" - dic['localizacao_atual'] = " " - for tramitacao in context.zsql.tramitacao_obter_zsql(cod_materia=materia.cod_materia, ind_ult_tramitacao=1): + dic["localizacao_atual"] = " " + for tramitacao in context.zsql.tramitacao_obter_zsql( + cod_materia=materia.cod_materia, ind_ult_tramitacao=1 + ): if tramitacao.cod_unid_tram_dest: cod_unid_tram = tramitacao.cod_unid_tram_dest else: cod_unid_tram = tramitacao.cod_unid_tram_local - for unidade_tramitacao in context.zsql.unidade_tramitacao_obter_zsql(cod_unid_tramitacao=cod_unid_tram): + for unidade_tramitacao in context.zsql.unidade_tramitacao_obter_zsql( + cod_unid_tramitacao=cod_unid_tram + ): if unidade_tramitacao.cod_orgao: - dic['localizacao_atual'] = unidade_tramitacao.nom_orgao + dic["localizacao_atual"] = unidade_tramitacao.nom_orgao elif unidade_tramitacao.cod_parlamentar: - dic['localizacao_atual'] = unidade_tramitacao.nom_parlamentar + dic["localizacao_atual"] = unidade_tramitacao.nom_parlamentar else: - dic['localizacao_atual'] = unidade_tramitacao.nom_comissao + dic["localizacao_atual"] = unidade_tramitacao.nom_comissao des_status = tramitacao.des_status txt_tramitacao = tramitacao.txt_tramitacao data_ultima_acao = tramitacao.dat_tramitacao - dic['des_situacao'] = des_status - dic['ultima_acao'] = txt_tramitacao - dic['data_ultima_acao'] = data_ultima_acao - - dic['norma_juridica_vinculada'] = "Não há nenhuma norma jurídica vinculada" - for norma in context.zsql.materia_buscar_norma_juridica_zsql(cod_materia=materia.cod_materia): - dic['norma_juridica_vinculada'] = norma.des_norma + " " + \ - str(norma.num_norma) + "/" + str(norma.ano_norma) + dic["des_situacao"] = des_status + dic["ultima_acao"] = txt_tramitacao + dic["data_ultima_acao"] = data_ultima_acao + + dic["norma_juridica_vinculada"] = "Não há nenhuma norma jurídica vinculada" + for norma in context.zsql.materia_buscar_norma_juridica_zsql( + cod_materia=materia.cod_materia + ): + dic["norma_juridica_vinculada"] = ( + norma.des_norma + + " " + + str(norma.num_norma) + + "/" + + str(norma.ano_norma) + ) materias.append(dic) @@ -122,57 +142,78 @@ else: for cod_mat in codigo: for materia in context.zsql.materia_obter_zsql(cod_materia=cod_mat): dic = {} - dic['titulo'] = "INDICAÇÃO: " + \ - str(materia.num_ident_basica) + " " + \ - str(materia.ano_ident_basica) - dic['materia'] = str(materia.num_ident_basica) + \ - "/" + str(materia.ano_ident_basica) - dic['dat_apresentacao'] = materia.dat_apresentacao - dic['txt_ementa'] = materia.txt_ementa - - dic['nom_autor'] = " " - for autoria in context.zsql.autoria_obter_zsql(cod_materia=materia.cod_materia, ind_primeiro_autor=1): + dic["titulo"] = ( + "INDICAÇÃO: " + + str(materia.num_ident_basica) + + " " + + str(materia.ano_ident_basica) + ) + dic["materia"] = ( + str(materia.num_ident_basica) + "/" + str(materia.ano_ident_basica) + ) + dic["dat_apresentacao"] = materia.dat_apresentacao + dic["txt_ementa"] = materia.txt_ementa + + dic["nom_autor"] = " " + for autoria in context.zsql.autoria_obter_zsql( + cod_materia=materia.cod_materia, ind_primeiro_autor=1 + ): for autor in context.zsql.autor_obter_zsql(cod_autor=autoria.cod_autor): - if autor.des_tipo_autor == 'Parlamentar': - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=autor.cod_parlamentar): - dic['nom_autor'] = parlamentar.nom_completo - elif autor.des_tipo_autor == 'Comissao': - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=autor.cod_comissao): - dic['nom_autor'] = comissao.nom_comissao + if autor.des_tipo_autor == "Parlamentar": + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=autor.cod_parlamentar + ): + dic["nom_autor"] = parlamentar.nom_completo + elif autor.des_tipo_autor == "Comissao": + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=autor.cod_comissao + ): + dic["nom_autor"] = comissao.nom_comissao else: - dic['nom_autor'] = autor.nom_autor + dic["nom_autor"] = autor.nom_autor - des_status = '' - txt_tramitacao = '' - data_ultima_acao = '' + des_status = "" + txt_tramitacao = "" + data_ultima_acao = "" - dic['localizacao_atual'] = " " - for tramitacao in context.zsql.tramitacao_obter_zsql(cod_materia=materia.cod_materia, ind_ult_tramitacao=1): + dic["localizacao_atual"] = " " + for tramitacao in context.zsql.tramitacao_obter_zsql( + cod_materia=materia.cod_materia, ind_ult_tramitacao=1 + ): if tramitacao.cod_unid_tram_dest: cod_unid_tram = tramitacao.cod_unid_tram_dest else: cod_unid_tram = tramitacao.cod_unid_tram_local - for unidade_tramitacao in context.zsql.unidade_tramitacao_obter_zsql(cod_unid_tramitacao=cod_unid_tram): + for unidade_tramitacao in context.zsql.unidade_tramitacao_obter_zsql( + cod_unid_tramitacao=cod_unid_tram + ): if unidade_tramitacao.cod_orgao: - dic['localizacao_atual'] = unidade_tramitacao.nom_orgao + dic["localizacao_atual"] = unidade_tramitacao.nom_orgao elif unidade_tramitacao.cod_parlamentar: - dic['localizacao_atual'] = unidade_tramitacao.nom_parlamentar + dic["localizacao_atual"] = unidade_tramitacao.nom_parlamentar else: - dic['localizacao_atual'] = unidade_tramitacao.nom_comissao + dic["localizacao_atual"] = unidade_tramitacao.nom_comissao des_status = tramitacao.des_status txt_tramitacao = tramitacao.txt_tramitacao data_ultima_acao = tramitacao.dat_tramitacao - dic['des_situacao'] = des_status - dic['ultima_acao'] = txt_tramitacao - dic['data_ultima_acao'] = data_ultima_acao - - dic['norma_juridica_vinculada'] = "Não há nenhuma norma jurídica vinculada" - for norma in context.zsql.materia_buscar_norma_juridica_zsql(cod_materia=materia.cod_materia): - dic['norma_juridica_vinculada'] = norma.des_norma + " " + \ - str(norma.num_norma) + "/" + str(norma.ano_norma) + dic["des_situacao"] = des_status + dic["ultima_acao"] = txt_tramitacao + dic["data_ultima_acao"] = data_ultima_acao + + dic["norma_juridica_vinculada"] = "Não há nenhuma norma jurídica vinculada" + for norma in context.zsql.materia_buscar_norma_juridica_zsql( + cod_materia=materia.cod_materia + ): + dic["norma_juridica_vinculada"] = ( + norma.des_norma + + " " + + str(norma.num_norma) + + "/" + + str(norma.ano_norma) + ) materias.append(dic) @@ -203,8 +244,9 @@ filtro = {} # Dicionário que conterá os dados do filtro sessao = session.id caminho = context.pdf_espelho_gerar( - sessao, imagem, data, materias, cabecalho, rodape, filtro) -if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + sessao, imagem, data, materias, cabecalho, rodape, filtro +) +if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_etiqueta_protocolo_gerar.py b/sapl/relatorios/templates/pdf_etiqueta_protocolo_gerar.py index 027bb7f88..ae6abb8a7 100755 --- a/sapl/relatorios/templates/pdf_etiqueta_protocolo_gerar.py +++ b/sapl/relatorios/templates/pdf_etiqueta_protocolo_gerar.py @@ -13,13 +13,19 @@ from trml2pdf import parseString def cabecalho(dic_cabecalho, imagem): """Gera o codigo rml do cabecalho""" - tmp_data = '' - tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t2cm 25.4cm 19cm 25.4cm\n' + tmp_data = "" + tmp_data += ( + '\t\t\t\t\n' + ) + tmp_data += "\t\t\t\t2cm 25.4cm 19cm 25.4cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - dic_cabecalho['nom_casa'] + '\n' + tmp_data += ( + '\t\t\t\t' + + dic_cabecalho["nom_casa"] + + "\n" + ) tmp_data += '\t\t\t\t\n' tmp_data += '\t\t\t\tSistema de Apoio ao Processo Legislativo\n' tmp_data += '\t\t\t\t\n' @@ -31,16 +37,25 @@ def cabecalho(dic_cabecalho, imagem): def rodape(lst_rodape): """Gera o codigo rml do rodape""" - tmp_data = '' - tmp_data += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + tmp_data = "" + tmp_data += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[2] + '\n' - tmp_data += '\t\t\t\tPágina \n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[0] + '\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[1] + '\n' + tmp_data += ( + '\t\t\t\t' + lst_rodape[2] + "\n" + ) + tmp_data += ( + '\t\t\t\tPágina \n' + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[0] + + "\n" + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[1] + + "\n" + ) return tmp_data @@ -48,18 +63,18 @@ def rodape(lst_rodape): def paraStyle(): """Gera o codigo rml que define o estilo dos paragrafos""" - tmp_data = '' - tmp_data += '\t\n' + tmp_data = "" + tmp_data += "\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t\n' tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" + tmp_data += "\t\t\n" tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\n' - tmp_data += '\t\n' + tmp_data += "\t\n" return tmp_data @@ -67,46 +82,51 @@ def paraStyle(): def protocolos(lst_protocolos, dic_cabecalho): """Gera o codigo rml do conteudo da pesquisa de protocolos""" - tmp_data = '' + tmp_data = "" # inicio do bloco que contem os flowables - tmp_data += '\t\n' + tmp_data += "\t\n" for dic in lst_protocolos: # condicao para a quebra de pagina tmp_data += '\t\t\n' # protocolos - if dic['titulo'] != None: + if dic["titulo"] != None: tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' - tmp_data += '\t\t' + \ - dic_cabecalho['nom_casa'] + '\n' + tmp_data += "\t\t\n" + tmp_data += ( + '\t\t' + dic_cabecalho["nom_casa"] + "\n" + ) tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '' - tmp_data += '' + \ - dic['titulo'] + '\n' - tmp_data += '' - tmp_data += '\t\tPROTOCOLO GERAL ' + \ - dic['titulo'] + '\n' - if dic['data'] != None: - tmp_data += '\t\t' + \ - dic['data'] + '\n' - tmp_data += '\t\t' + \ - dic['natureza'] - if dic['ident_processo']: + tmp_data += ( + '' + + dic["titulo"] + + "\n" + ) + tmp_data += "" + tmp_data += ( + '\t\tPROTOCOLO GERAL ' + + dic["titulo"] + + "\n" + ) + if dic["data"] != None: + tmp_data += '\t\t' + dic["data"] + "\n" + tmp_data += '\t\t' + dic["natureza"] + if dic["ident_processo"]: # Limita o tamanho do texto para não "explodir" as etiquetas - descricao = dic['ident_processo'][:60] - if len(dic['ident_processo']) > 60: - descricao += '...' - tmp_data += ' - ' + descricao + '\n' + descricao = dic["ident_processo"][:60] + if len(dic["ident_processo"]) > 60: + descricao += "..." + tmp_data += " - " + descricao + "\n" else: - tmp_data += '\n' + tmp_data += "\n" - tmp_data += '\t\n' + tmp_data += "\t\n" return tmp_data @@ -115,23 +135,27 @@ def principal(imagem, lst_protocolos, dic_cabecalho, lst_rodape): arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp_data = '' + tmp_data = "" tmp_data += '\n' tmp_data += '\n' tmp_data += '\n' tmp_data += '\t\n' + tmp_data += "\t\t\t\n" + tmp_data += ( + '\t\t\t\n' + ) + tmp_data += "\t\t\t\n" + tmp_data += "\t\t\n" + tmp_data += "\t\n" tmp_data += paraStyle() tmp_data += protocolos(lst_protocolos, dic_cabecalho) - tmp_data += '\n' + tmp_data += "\n" tmp_pdf = parseString(tmp_data) return tmp_pdf + + # if hasattr(context.temp_folder,arquivoPdf): # context.temp_folder.manage_delObjects(ids=arquivoPdf) # context.temp_folder.manage_addFile(arquivoPdf) diff --git a/sapl/relatorios/templates/pdf_etiqueta_protocolo_preparar_pysc.py b/sapl/relatorios/templates/pdf_etiqueta_protocolo_preparar_pysc.py index 29ce497b3..d12f9b53b 100755 --- a/sapl/relatorios/templates/pdf_etiqueta_protocolo_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_etiqueta_protocolo_preparar_pysc.py @@ -4,15 +4,14 @@ request = context.REQUEST response = request.RESPONSE session = request.SESSION -data = DateTime().strftime('%d/%m/%Y') +data = DateTime().strftime("%d/%m/%Y") # Abaixo é gerada a string para o rodapé da página casa = {} aux = context.sapl_documentos.props_sapl.propertyItems() for item in aux: casa[item[0]] = item[1] -localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) +localidade = context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"]) if len(casa["num_cep"]) == 8: cep = casa["num_cep"][:4] + "-" + casa["num_cep"][5:] else: @@ -24,8 +23,7 @@ if cep != "": linha1 = linha1 + " - " linha1 = linha1 + "CEP " + cep if localidade[0].nom_localidade != "" and localidade[0].nom_localidade != None: - linha1 = linha1 + " - " + \ - localidade[0].nom_localidade + " " + localidade[0].sgl_uf + linha1 = linha1 + " - " + localidade[0].nom_localidade + " " + localidade[0].sgl_uf if casa["num_tel"] != "" and casa["num_tel"] != None: linha1 = linha1 + " Tel.: " + casa["num_tel"] @@ -49,8 +47,8 @@ cabecalho["nom_casa"] = casa["nom_casa"] cabecalho["nom_estado"] = "Estado de " + nom_estado # tenta buscar o logotipo da casa LOGO_CASA -if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl['logo_casa.gif'].absolute_url() +if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -58,80 +56,108 @@ else: protocolos = [] REQUEST = context.REQUEST -for protocolo in context.zsql.protocolo_pesquisar_zsql(tip_protocolo=REQUEST['rad_tip_protocolo'], - cod_protocolo=REQUEST['txt_num_protocolo'], ano_protocolo=REQUEST[ - 'txt_ano_protocolo'], - tip_documento=REQUEST['lst_tip_documento'], tip_processo=REQUEST[ - 'rad_tip_processo'], - tip_materia=REQUEST[ - 'lst_tip_materia'], des_assunto=REQUEST['txt_assunto'], - cod_autor=REQUEST['hdn_cod_autor'], des_interessado=REQUEST[ - 'txa_txt_interessado'], - dat_apres=REQUEST['dt_apres'], dat_apres2=REQUEST['dt_apres2']): +for protocolo in context.zsql.protocolo_pesquisar_zsql( + tip_protocolo=REQUEST["rad_tip_protocolo"], + cod_protocolo=REQUEST["txt_num_protocolo"], + ano_protocolo=REQUEST["txt_ano_protocolo"], + tip_documento=REQUEST["lst_tip_documento"], + tip_processo=REQUEST["rad_tip_processo"], + tip_materia=REQUEST["lst_tip_materia"], + des_assunto=REQUEST["txt_assunto"], + cod_autor=REQUEST["hdn_cod_autor"], + des_interessado=REQUEST["txa_txt_interessado"], + dat_apres=REQUEST["dt_apres"], + dat_apres2=REQUEST["dt_apres2"], +): dic = {} - dic['titulo'] = str(protocolo.cod_protocolo) + dic["titulo"] = str(protocolo.cod_protocolo) - dic['data'] = 'Data: ' + context.pysc.iso_to_port_pysc( - protocolo.dat_protocolo) + ' Horário: ' + protocolo.hor_protocolo[0:2] + ':' + protocolo.hor_protocolo[3:5] + dic["data"] = ( + "Data: " + + context.pysc.iso_to_port_pysc(protocolo.dat_protocolo) + + " Horário: " + + protocolo.hor_protocolo[0:2] + + ":" + + protocolo.hor_protocolo[3:5] + ) - dic['txt_assunto'] = protocolo.txt_assunto_ementa + dic["txt_assunto"] = protocolo.txt_assunto_ementa - dic['txt_interessado'] = protocolo.txt_interessado + dic["txt_interessado"] = protocolo.txt_interessado - dic['nom_autor'] = " " + dic["nom_autor"] = " " if protocolo.cod_autor != None: for autor in context.zsql.autor_obter_zsql(cod_autor=protocolo.cod_autor): - if autor.des_tipo_autor == 'Parlamentar': - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=autor.cod_parlamentar): - dic['nom_autor'] = parlamentar.nom_completo - elif autor.des_tipo_autor == 'Comissao': - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=autor.cod_comissao): - dic['nom_autor'] = comissao.nom_comissao + if autor.des_tipo_autor == "Parlamentar": + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=autor.cod_parlamentar + ): + dic["nom_autor"] = parlamentar.nom_completo + elif autor.des_tipo_autor == "Comissao": + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=autor.cod_comissao + ): + dic["nom_autor"] = comissao.nom_comissao else: - dic['nom_autor'] = autor.nom_autor + dic["nom_autor"] = autor.nom_autor - dic['natureza'] = '' + dic["natureza"] = "" if protocolo.tip_processo == 0: - dic['natureza'] = 'Administrativo' + dic["natureza"] = "Administrativo" if protocolo.tip_processo == 1: - dic['natureza'] = 'Legislativo' - - dic['num_materia'] = '' - for materia in context.zsql.materia_obter_zsql(num_protocolo=protocolo.cod_protocolo, ano_ident_basica=protocolo.ano_protocolo): - dic['num_materia'] = materia.sgl_tipo_materia + ' ' + \ - str(materia.num_ident_basica) + '/' + str(materia.ano_ident_basica) - - dic['num_documento'] = '' - for documento in context.zsql.documento_administrativo_obter_zsql(num_protocolo=protocolo.cod_protocolo): - dic['num_documento'] = documento.sgl_tipo_documento + ' ' + \ - str(documento.num_documento) + '/' + str(documento.ano_documento) - - dic['ident_processo'] = dic['num_materia'] or dic['num_documento'] - - dic['processo'] = protocolo.des_tipo_materia or protocolo.des_tipo_documento - - dic['anulado'] = '' + dic["natureza"] = "Legislativo" + + dic["num_materia"] = "" + for materia in context.zsql.materia_obter_zsql( + num_protocolo=protocolo.cod_protocolo, ano_ident_basica=protocolo.ano_protocolo + ): + dic["num_materia"] = ( + materia.sgl_tipo_materia + + " " + + str(materia.num_ident_basica) + + "/" + + str(materia.ano_ident_basica) + ) + + dic["num_documento"] = "" + for documento in context.zsql.documento_administrativo_obter_zsql( + num_protocolo=protocolo.cod_protocolo + ): + dic["num_documento"] = ( + documento.sgl_tipo_documento + + " " + + str(documento.num_documento) + + "/" + + str(documento.ano_documento) + ) + + dic["ident_processo"] = dic["num_materia"] or dic["num_documento"] + + dic["processo"] = protocolo.des_tipo_materia or protocolo.des_tipo_documento + + dic["anulado"] = "" if protocolo.ind_anulado == 1: - dic['anulado'] = 'Nulo' + dic["anulado"] = "Nulo" protocolos.append(dic) filtro = {} # Dicionário que conterá os dados do filtro # Atribuições diretas do REQUEST -filtro['numero'] = REQUEST.txt_num_protocolo -filtro['ano'] = REQUEST.txt_ano_protocolo -filtro['tipo_protocolo'] = REQUEST.rad_tip_protocolo -filtro['tipo_processo'] = REQUEST.rad_tip_processo -filtro['assunto'] = REQUEST.txt_assunto -filtro['autor'] = REQUEST.hdn_cod_autor -filtro['interessado'] = REQUEST.txa_txt_interessado +filtro["numero"] = REQUEST.txt_num_protocolo +filtro["ano"] = REQUEST.txt_ano_protocolo +filtro["tipo_protocolo"] = REQUEST.rad_tip_protocolo +filtro["tipo_processo"] = REQUEST.rad_tip_processo +filtro["assunto"] = REQUEST.txt_assunto +filtro["autor"] = REQUEST.hdn_cod_autor +filtro["interessado"] = REQUEST.txa_txt_interessado sessao = session.id caminho = context.pdf_etiqueta_protocolo_gerar( - sessao, imagem, data, protocolos, cabecalho, rodape, filtro) -if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + sessao, imagem, data, protocolos, cabecalho, rodape, filtro +) +if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_materia_gerar.py b/sapl/relatorios/templates/pdf_materia_gerar.py index cadc6501c..496084cfa 100755 --- a/sapl/relatorios/templates/pdf_materia_gerar.py +++ b/sapl/relatorios/templates/pdf_materia_gerar.py @@ -6,24 +6,34 @@ Empresa: Interlegis versão: 1.0 """ -import time import os +import time from trml2pdf import parseString def cabecalho(dic_cabecalho, imagem): """Gera o codigo rml do cabecalho""" - tmp_data = '' + tmp_data = "" if os.path.isfile(imagem): - tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t2cm 25cm 19cm 25cm\n' + tmp_data += ( + '\t\t\t\t\n' + ) + tmp_data += "\t\t\t\t2cm 25cm 19cm 25cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - dic_cabecalho['nom_casa'] + '\n' + tmp_data += ( + '\t\t\t\t' + + dic_cabecalho["nom_casa"] + + "\n" + ) tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - dic_cabecalho['nom_estado'] + '\n' + tmp_data += ( + '\t\t\t\t' + + dic_cabecalho["nom_estado"] + + "\n" + ) tmp_data += '\t\t\t\t\n' tmp_data += '\t\t\t\tRelatório de Matérias Legislativas\n' @@ -33,16 +43,25 @@ def cabecalho(dic_cabecalho, imagem): def rodape(lst_rodape): """Gera o codigo rml do rodape""" - tmp_data = '' - tmp_data += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + tmp_data = "" + tmp_data += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[2] + '\n' - tmp_data += '\t\t\t\tPágina \n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[0] + '\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[1] + '\n' + tmp_data += ( + '\t\t\t\t' + lst_rodape[2] + "\n" + ) + tmp_data += ( + '\t\t\t\tPágina \n' + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[0] + + "\n" + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[1] + + "\n" + ) return tmp_data @@ -50,18 +69,18 @@ def rodape(lst_rodape): def paraStyle(): """Gera o codigo rml que define o estilo dos paragrafos""" - tmp_data = '' - tmp_data += '\t\n' + tmp_data = "" + tmp_data += "\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t\n' tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" + tmp_data += "\t\t\n" tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\n' - tmp_data += '\t\n' + tmp_data += "\t\n" return tmp_data @@ -69,32 +88,40 @@ def paraStyle(): def materias(lst_materias): """Gera o codigo rml do conteudo da pesquisa de materias""" - tmp_data = '' + tmp_data = "" # inicio do bloco que contem os flowables - tmp_data += '\t\n' + tmp_data += "\t\n" for dic in lst_materias: # espaco inicial tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" # condicao para a quebra de pagina tmp_data += '\t\t\n' # materias - tmp_data += '\t\t ' + \ - dic['titulo'] + ' - Autor: ' + \ - dic['nom_autor'] + ' \n' - if dic['txt_ementa'] != None: - txt_ementa = dic['txt_ementa'].replace('&', '&') - tmp_data += '\t\t ' + txt_ementa + ' \n' - tmp_data += '\t\tSituação: ' + \ - dic['des_situacao'] + '/ Norma Jurídica Vinculada: ' + \ - dic['norma_vinculada'] + '\n' - - tmp_data += '\t\n' + tmp_data += ( + '\t\t ' + + dic["titulo"] + + " - Autor: " + + dic["nom_autor"] + + " \n" + ) + if dic["txt_ementa"] != None: + txt_ementa = dic["txt_ementa"].replace("&", "&") + tmp_data += '\t\t ' + txt_ementa + " \n" + tmp_data += ( + '\t\tSituação: ' + + dic["des_situacao"] + + "/ Norma Jurídica Vinculada: " + + dic["norma_vinculada"] + + "\n" + ) + + tmp_data += "\t\n" return tmp_data @@ -103,26 +130,29 @@ def principal(imagem, lst_materias, dic_cabecalho, lst_rodape): arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp_data = '' + tmp_data = "" tmp_data += '\n' tmp_data += '\n' tmp_data += '\n' tmp_data += '\t\n' + tmp_data += "\t\t\t\n" + tmp_data += ( + '\t\t\t\n' + ) + tmp_data += "\t\t\n" + tmp_data += "\t\n" tmp_data += paraStyle() tmp_data += materias(lst_materias) - tmp_data += '\n' + tmp_data += "\n" tmp_pdf = parseString(tmp_data) return tmp_pdf + # if hasattr(context.temp_folder,arquivoPdf): # context.temp_folder.manage_delObjects(ids=arquivoPdf) # context.temp_folder.manage_addFile(arquivoPdf) diff --git a/sapl/relatorios/templates/pdf_materia_preparar_pysc.py b/sapl/relatorios/templates/pdf_materia_preparar_pysc.py index 95a0b6192..af4cbdc96 100644 --- a/sapl/relatorios/templates/pdf_materia_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_materia_preparar_pysc.py @@ -6,15 +6,14 @@ request = context.REQUEST response = request.RESPONSE session = request.SESSION -data = DateTime().strftime('%d/%m/%Y') +data = DateTime().strftime("%d/%m/%Y") # Abaixo é gerada a string para o rodapé da página casa = {} aux = context.sapl_documentos.props_sapl.propertyItems() for item in aux: casa[item[0]] = item[1] -localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) +localidade = context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"]) if len(casa["num_cep"]) == 8: cep = casa["num_cep"][:4] + "-" + casa["num_cep"][5:] else: @@ -26,8 +25,7 @@ if cep != "": linha1 = linha1 + " - " linha1 = linha1 + "CEP " + cep if localidade[0].nom_localidade != "" and localidade[0].nom_localidade != None: - linha1 = linha1 + " - " + \ - localidade[0].nom_localidade + " " + localidade[0].sgl_uf + linha1 = linha1 + " - " + localidade[0].nom_localidade + " " + localidade[0].sgl_uf if casa["num_tel"] != "" and casa["num_tel"] != None: linha1 = linha1 + " Tel.: " + casa["num_tel"] @@ -51,8 +49,8 @@ cabecalho["nom_casa"] = casa["nom_casa"] cabecalho["nom_estado"] = "Estado de " + nom_estado # tenta buscar o logotipo da casa LOGO_CASA -if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl['logo_casa.gif'].absolute_url() +if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -60,110 +58,140 @@ else: materias = [] REQUEST = context.REQUEST -for materia in context.zsql.materia_pesquisar_zsql(tip_id_basica=REQUEST['lst_tip_materia'], num_ident_basica=REQUEST['txt_numero'], - ano_ident_basica=REQUEST[ - 'txt_ano'], ind_tramitacao=REQUEST['rad_tramitando'], - des_assunto=REQUEST[ - 'txt_assunto'], nom_relator=REQUEST['txt_relator'], - cod_status=REQUEST['lst_status'], des_tipo_autor=REQUEST[ - 'lst_tip_autor'], - dat_apresentacao=REQUEST[ - 'dt_apres'], dat_apresentacao2=REQUEST['dt_apres2'], - dat_publicacao=REQUEST[ - 'dt_public'], dat_publicacao2=REQUEST['dt_public2'], - cod_partido=REQUEST['lst_cod_partido'], cod_autor=REQUEST[ - 'hdn_cod_autor'], - rd_ordem=REQUEST['rd_ordenacao'], rd_ordem_td=REQUEST['rd_ordem_td']): - +for materia in context.zsql.materia_pesquisar_zsql( + tip_id_basica=REQUEST["lst_tip_materia"], + num_ident_basica=REQUEST["txt_numero"], + ano_ident_basica=REQUEST["txt_ano"], + ind_tramitacao=REQUEST["rad_tramitando"], + des_assunto=REQUEST["txt_assunto"], + nom_relator=REQUEST["txt_relator"], + cod_status=REQUEST["lst_status"], + des_tipo_autor=REQUEST["lst_tip_autor"], + dat_apresentacao=REQUEST["dt_apres"], + dat_apresentacao2=REQUEST["dt_apres2"], + dat_publicacao=REQUEST["dt_public"], + dat_publicacao2=REQUEST["dt_public2"], + cod_partido=REQUEST["lst_cod_partido"], + cod_autor=REQUEST["hdn_cod_autor"], + rd_ordem=REQUEST["rd_ordenacao"], + rd_ordem_td=REQUEST["rd_ordem_td"], +): dic = {} - dic['titulo'] = materia.sgl_tipo_materia + " " + materia.des_tipo_materia + \ - " " + str(materia.num_ident_basica) + "/" + \ - str(materia.ano_ident_basica) - dic['txt_ementa'] = materia.txt_ementa - dic['nom_autor'] = " " + dic["titulo"] = ( + materia.sgl_tipo_materia + + " " + + materia.des_tipo_materia + + " " + + str(materia.num_ident_basica) + + "/" + + str(materia.ano_ident_basica) + ) + dic["txt_ementa"] = materia.txt_ementa + dic["nom_autor"] = " " for autoria in context.zsql.autoria_obter_zsql(cod_materia=materia.cod_materia): for autor in context.zsql.autor_obter_zsql(cod_autor=autoria.cod_autor): - if autor.des_tipo_autor == 'Parlamentar': - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=autor.cod_parlamentar): - dic['nom_autor'] = parlamentar.nom_completo - elif autor.des_tipo_autor == 'Comissao': - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=autor.cod_comissao): - dic['nom_autor'] = comissao.nom_comissao + if autor.des_tipo_autor == "Parlamentar": + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=autor.cod_parlamentar + ): + dic["nom_autor"] = parlamentar.nom_completo + elif autor.des_tipo_autor == "Comissao": + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=autor.cod_comissao + ): + dic["nom_autor"] = comissao.nom_comissao else: - dic['nom_autor'] = autor.nom_autor + dic["nom_autor"] = autor.nom_autor - des_status = '' - txt_tramitacao = '' + des_status = "" + txt_tramitacao = "" - dic['localizacao_atual'] = " " - for tramitacao in context.zsql.tramitacao_obter_zsql(cod_materia=materia.cod_materia, ind_ult_tramitacao=1): + dic["localizacao_atual"] = " " + for tramitacao in context.zsql.tramitacao_obter_zsql( + cod_materia=materia.cod_materia, ind_ult_tramitacao=1 + ): if tramitacao.cod_unid_tram_dest: cod_unid_tram = tramitacao.cod_unid_tram_dest else: cod_unid_tram = tramitacao.cod_unid_tram_local - for unidade_tramitacao in context.zsql.unidade_tramitacao_obter_zsql(cod_unid_tramitacao=cod_unid_tram): + for unidade_tramitacao in context.zsql.unidade_tramitacao_obter_zsql( + cod_unid_tramitacao=cod_unid_tram + ): if unidade_tramitacao.cod_orgao: - dic['localizacao_atual'] = unidade_tramitacao.nom_orgao + dic["localizacao_atual"] = unidade_tramitacao.nom_orgao else: - dic['localizacao_atual'] = unidade_tramitacao.nom_comissao + dic["localizacao_atual"] = unidade_tramitacao.nom_comissao des_status = tramitacao.des_status txt_tramitacao = tramitacao.txt_tramitacao - dic['des_situacao'] = des_status - dic['ultima_acao'] = txt_tramitacao - - dic['norma_vinculada'] = " " - for norma_vinculada in context.zsql.materia_buscar_norma_juridica_zsql(cod_materia=materia.cod_materia): - dic['norma_vinculada'] = norma_vinculada.des_norma + " " + \ - str(norma_vinculada.num_norma) + "/" + \ - str(norma_vinculada.ano_norma) + dic["des_situacao"] = des_status + dic["ultima_acao"] = txt_tramitacao + + dic["norma_vinculada"] = " " + for norma_vinculada in context.zsql.materia_buscar_norma_juridica_zsql( + cod_materia=materia.cod_materia + ): + dic["norma_vinculada"] = ( + norma_vinculada.des_norma + + " " + + str(norma_vinculada.num_norma) + + "/" + + str(norma_vinculada.ano_norma) + ) materias.append(dic) filtro = {} # Dicionário que conterá os dados do filtro # Atribuições diretas do REQUEST -filtro['numero'] = REQUEST.txt_numero -filtro['ano'] = REQUEST.txt_ano -filtro['autor'] = REQUEST.hdn_txt_autor -filtro['tipo_autor'] = REQUEST.lst_tip_autor -filtro['relator'] = REQUEST.txt_relator -filtro['assunto'] = REQUEST.txt_assunto +filtro["numero"] = REQUEST.txt_numero +filtro["ano"] = REQUEST.txt_ano +filtro["autor"] = REQUEST.hdn_txt_autor +filtro["tipo_autor"] = REQUEST.lst_tip_autor +filtro["relator"] = REQUEST.txt_relator +filtro["assunto"] = REQUEST.txt_assunto # Atribuição do restante dos dados que precisam de processamento -if REQUEST.hdn_txt_autor == ' ': # Corrige bug do Netscape - filtro['autor'] = '' - -filtro['tipo_materia'] = '' -if REQUEST.lst_tip_materia != '': - for tipo_materia in context.zsql.tipo_materia_legislativa_obter_zsql(ind_excluido=0, tip_materia=REQUEST.lst_tip_materia): - filtro['tipo_materia'] = tipo_materia.sgl_tipo_materia + \ - ' - ' + tipo_materia.des_tipo_materia - -filtro['partido'] = '' -if REQUEST.lst_cod_partido != '': - for partido in context.zsql.partido_obter_zsql(ind_excluido=0, cod_partido=REQUEST.lst_cod_partido): - filtro['partido'] = partido.sgl_partido + ' - ' + partido.nom_partido - -filtro['tramitando'] = '' -if REQUEST.rad_tramitando == '1': - filtro['tramitacao'] = 'Sim' -elif REQUEST['rad_tramitando'] == '0': - filtro['tramitacao'] = 'Não' - -filtro['situacao_atual'] = '' -if REQUEST.lst_status != '': - for status in context.zsql.status_tramitacao_obter_zsql(ind_excluido=0, cod_status=REQUEST.lst_status): - filtro['situacao_atual'] = status.sgl_status + \ - ' - ' + status.des_status +if REQUEST.hdn_txt_autor == " ": # Corrige bug do Netscape + filtro["autor"] = "" + +filtro["tipo_materia"] = "" +if REQUEST.lst_tip_materia != "": + for tipo_materia in context.zsql.tipo_materia_legislativa_obter_zsql( + ind_excluido=0, tip_materia=REQUEST.lst_tip_materia + ): + filtro["tipo_materia"] = ( + tipo_materia.sgl_tipo_materia + " - " + tipo_materia.des_tipo_materia + ) + +filtro["partido"] = "" +if REQUEST.lst_cod_partido != "": + for partido in context.zsql.partido_obter_zsql( + ind_excluido=0, cod_partido=REQUEST.lst_cod_partido + ): + filtro["partido"] = partido.sgl_partido + " - " + partido.nom_partido + +filtro["tramitando"] = "" +if REQUEST.rad_tramitando == "1": + filtro["tramitacao"] = "Sim" +elif REQUEST["rad_tramitando"] == "0": + filtro["tramitacao"] = "Não" + +filtro["situacao_atual"] = "" +if REQUEST.lst_status != "": + for status in context.zsql.status_tramitacao_obter_zsql( + ind_excluido=0, cod_status=REQUEST.lst_status + ): + filtro["situacao_atual"] = status.sgl_status + " - " + status.des_status sessao = session.id caminho = context.pdf_materia_gerar( - sessao, imagem, data, materias, cabecalho, rodape, filtro) -if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + sessao, imagem, data, materias, cabecalho, rodape, filtro +) +if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_norma_gerar.py b/sapl/relatorios/templates/pdf_norma_gerar.py index 036169190..f0c5a02c7 100755 --- a/sapl/relatorios/templates/pdf_norma_gerar.py +++ b/sapl/relatorios/templates/pdf_norma_gerar.py @@ -13,12 +13,19 @@ from trml2pdf import parseString def cabecalho(inf_basicas_dic, imagem): """Gera o codigo rml do cabecalho""" - tmp_data = '' - tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t2cm 25.4cm 19cm 25.4cm\n' + tmp_data = "" + tmp_data += ( + '\t\t\t\t\n' + ) + tmp_data += "\t\t\t\t2cm 25.4cm 19cm 25.4cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - dic_cabecalho['nom_casa'] + '\n' + tmp_data += ( + '\t\t\t\t' + + dic_cabecalho["nom_casa"] + + "\n" + ) tmp_data += '\t\t\t\t\n' tmp_data += '\t\t\t\tSistema de Apoio ao Processo Legislativo\n' tmp_data += '\t\t\t\t\n' @@ -30,16 +37,25 @@ def cabecalho(inf_basicas_dic, imagem): def rodape(lst_rodape): """Gera o codigo rml do rodape""" - tmp_data = '' - tmp_data += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + tmp_data = "" + tmp_data += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[2] + '\n' - tmp_data += '\t\t\t\tPágina \n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[0] + '\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[1] + '\n' + tmp_data += ( + '\t\t\t\t' + lst_rodape[2] + "\n" + ) + tmp_data += ( + '\t\t\t\tPágina \n' + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[0] + + "\n" + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[1] + + "\n" + ) return tmp_data @@ -47,18 +63,18 @@ def rodape(lst_rodape): def paraStyle(): """Gera o codigo rml que define o estilo dos paragrafos""" - tmp_data = '' - tmp_data += '\t\n' + tmp_data = "" + tmp_data += "\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t\n' tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" + tmp_data += "\t\t\n" tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\n' - tmp_data += '\t\n' + tmp_data += "\t\n" return tmp_data @@ -66,37 +82,40 @@ def paraStyle(): def normas(lst_normas): """Gera o codigo rml do conteudo da pesquisa de normas""" - tmp_data = '' + tmp_data = "" # inicio do bloco que contem os flowables - tmp_data += '\t\n' + tmp_data += "\t\n" for dic in lst_normas: # espaco inicial tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" # condicao para a quebra de pagina tmp_data += '\t\t\n' # normas - if dic['titulo'] != None: - tmp_data += '\t\t' + dic['titulo'] + '\n' + if dic["titulo"] != None: + tmp_data += '\t\t' + dic["titulo"] + "\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' - if dic['txt_ementa'] != None: - txt_ementa = dic['txt_ementa'].replace('&', '&') - tmp_data += '\t\t' + txt_ementa + '\n' - if dic['materia_vinculada'] != None: - tmp_data += '\t\tMatéria Legislativa: ' + \ - dic['materia_vinculada'] + '\n' - - tmp_data += '\t\n' + tmp_data += "\t\t\n" + if dic["txt_ementa"] != None: + txt_ementa = dic["txt_ementa"].replace("&", "&") + tmp_data += '\t\t' + txt_ementa + "\n" + if dic["materia_vinculada"] != None: + tmp_data += ( + '\t\tMatéria Legislativa: ' + + dic["materia_vinculada"] + + "\n" + ) + + tmp_data += "\t\n" return tmp_data @@ -105,26 +124,29 @@ def principal(imagem, lst_normas, dic_cabecalho, lst_rodape): arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp_data = '' + tmp_data = "" tmp_data += '\n' tmp_data += '\n' tmp_data += '\n' tmp_data += '\t\n' + tmp_data += "\t\t\t\n" + tmp_data += ( + '\t\t\t\n' + ) + tmp_data += "\t\t\n" + tmp_data += "\t\n" tmp_data += paraStyle() tmp_data += normas(lst_normas) - tmp_data += '\n' + tmp_data += "\n" tmp_pdf = parseString(tmp_data) return tmp_pdf + # if hasattr(context.temp_folder,arquivoPdf): # context.temp_folder.manage_delObjects(ids=arquivoPdf) # context.temp_folder.manage_addFile(arquivoPdf) diff --git a/sapl/relatorios/templates/pdf_norma_preparar_pysc.py b/sapl/relatorios/templates/pdf_norma_preparar_pysc.py index 047f04e21..56264dcd9 100755 --- a/sapl/relatorios/templates/pdf_norma_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_norma_preparar_pysc.py @@ -4,15 +4,14 @@ request = context.REQUEST response = request.RESPONSE session = request.SESSION -data = DateTime().strftime('%d/%m/%Y') +data = DateTime().strftime("%d/%m/%Y") # Abaixo é gerada a string para o rodapé da página casa = {} aux = context.sapl_documentos.props_sapl.propertyItems() for item in aux: casa[item[0]] = item[1] -localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) +localidade = context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"]) if len(casa["num_cep"]) == 8: cep = casa["num_cep"][:4] + "-" + casa["num_cep"][5:] else: @@ -24,8 +23,7 @@ if cep != "": linha1 = linha1 + " - " linha1 = linha1 + "CEP " + cep if localidade[0].nom_localidade != "" and localidade[0].nom_localidade != None: - linha1 = linha1 + " - " + \ - localidade[0].nom_localidade + " " + localidade[0].sgl_uf + linha1 = linha1 + " - " + localidade[0].nom_localidade + " " + localidade[0].sgl_uf if casa["num_tel"] != "" and casa["num_tel"] != None: linha1 = linha1 + " Tel.: " + casa["num_tel"] @@ -49,8 +47,8 @@ cabecalho["nom_casa"] = casa["nom_casa"] cabecalho["nom_estado"] = "Estado de " + nom_estado # tenta buscar o logotipo da casa LOGO_CASA -if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl['logo_casa.gif'].absolute_url() +if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -58,48 +56,67 @@ else: normas = [] REQUEST = context.REQUEST -for norma in context.zsql.norma_juridica_obter_zsql(tip_norma=REQUEST['lst_tip_norma'], num_norma=REQUEST['txt_numero'], - ano_norma=REQUEST['txt_ano'], des_assunto=REQUEST[ - 'txt_assunto'], - cod_assunto=REQUEST[ - 'lst_assunto_norma'], dat_norma=REQUEST['dt_norma'], - dat_norma2=REQUEST[ - 'dt_norma2'], dat_publicacao=REQUEST['dt_public'], - dat_publicacao2=REQUEST['dt_public2'], rd_ordem=REQUEST['rd_ordenacao']): - +for norma in context.zsql.norma_juridica_obter_zsql( + tip_norma=REQUEST["lst_tip_norma"], + num_norma=REQUEST["txt_numero"], + ano_norma=REQUEST["txt_ano"], + des_assunto=REQUEST["txt_assunto"], + cod_assunto=REQUEST["lst_assunto_norma"], + dat_norma=REQUEST["dt_norma"], + dat_norma2=REQUEST["dt_norma2"], + dat_publicacao=REQUEST["dt_public"], + dat_publicacao2=REQUEST["dt_public2"], + rd_ordem=REQUEST["rd_ordenacao"], +): dic = {} - dic['titulo'] = norma.sgl_tipo_norma + " Nº " + \ - str(norma.num_norma) + " de " + \ - str(norma.dat_norma) + " - " + norma.des_tipo_norma - dic['txt_ementa'] = norma.txt_ementa - - dic['materia_vinculada'] = " " + dic["titulo"] = ( + norma.sgl_tipo_norma + + " Nº " + + str(norma.num_norma) + + " de " + + str(norma.dat_norma) + + " - " + + norma.des_tipo_norma + ) + dic["txt_ementa"] = norma.txt_ementa + + dic["materia_vinculada"] = " " if norma.cod_materia != None: - for materia_vinculada in context.zsql.materia_obter_zsql(cod_materia=str(norma.cod_materia)): - dic['materia_vinculada'] = materia_vinculada.sgl_tipo_materia + " " + \ - str(materia_vinculada.num_ident_basica) + "/" + \ - str(materia_vinculada.ano_ident_basica) + for materia_vinculada in context.zsql.materia_obter_zsql( + cod_materia=str(norma.cod_materia) + ): + dic["materia_vinculada"] = ( + materia_vinculada.sgl_tipo_materia + + " " + + str(materia_vinculada.num_ident_basica) + + "/" + + str(materia_vinculada.ano_ident_basica) + ) normas.append(dic) filtro = {} # Dicionário que conterá os dados do filtro # Atribuições diretas do REQUEST -filtro['numero'] = REQUEST.txt_numero -filtro['ano'] = REQUEST.txt_ano -filtro['assunto'] = REQUEST.txt_assunto - -filtro['tipo_norma'] = '' -if REQUEST.lst_tip_norma != '': - for tipo_norma in context.zsql.tipo_norma_juridica_obter_zsql(ind_excluido=0, tip_norma=REQUEST.lst_tip_norma): - filtro['tipo_norma'] = tipo_norma.sgl_tipo_norma + \ - ' - ' + tipo_norma.des_tipo_norma +filtro["numero"] = REQUEST.txt_numero +filtro["ano"] = REQUEST.txt_ano +filtro["assunto"] = REQUEST.txt_assunto + +filtro["tipo_norma"] = "" +if REQUEST.lst_tip_norma != "": + for tipo_norma in context.zsql.tipo_norma_juridica_obter_zsql( + ind_excluido=0, tip_norma=REQUEST.lst_tip_norma + ): + filtro["tipo_norma"] = ( + tipo_norma.sgl_tipo_norma + " - " + tipo_norma.des_tipo_norma + ) sessao = session.id caminho = context.pdf_norma_gerar( - sessao, imagem, data, normas, cabecalho, rodape, filtro) -if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + sessao, imagem, data, normas, cabecalho, rodape, filtro +) +if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_ordem_dia_gerar.py b/sapl/relatorios/templates/pdf_ordem_dia_gerar.py index 41cf8f2eb..96507d1cd 100755 --- a/sapl/relatorios/templates/pdf_ordem_dia_gerar.py +++ b/sapl/relatorios/templates/pdf_ordem_dia_gerar.py @@ -6,8 +6,8 @@ Empresa: Interlegis versão: 1.0 """ -import time import os +import time from trml2pdf import parseString @@ -15,22 +15,31 @@ from trml2pdf import parseString def cabecalho(dic_cabecalho, dat_ordem, imagem): """Gera o codigo rml do cabecalho""" - tmp = '' + tmp = "" if os.path.isfile(imagem): - tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t2cm 25cm 19cm 25cm\n' + tmp += ( + '\t\t\t\t\n' + ) + tmp += "\t\t\t\t2cm 25cm 19cm 25cm\n" tmp += '\t\t\t\t\n' - #tmp+='\t\t\t\t' + str(dic_cabecalho['nom_casa']) + '\n' - #tmp+='\t\t\t\t\n' - tmp += '\t\t\t\t' + \ - str(dic_cabecalho['nom_estado']) + '\n' + # tmp+='\t\t\t\t' + str(dic_cabecalho['nom_casa']) + '\n' + # tmp+='\t\t\t\t\n' + tmp += ( + '\t\t\t\t' + + str(dic_cabecalho["nom_estado"]) + + "\n" + ) tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t' + \ - str(dic_cabecalho['nom_casa']) + '\n' + tmp += ( + '\t\t\t\t' + + str(dic_cabecalho["nom_casa"]) + + "\n" + ) tmp += '\t\t\t\t\n' - #tmp+='\t\t\t\t' + "Palacio 11 de Outubro" + '\n' - #tmp+='\t\t\t\t\n' + # tmp+='\t\t\t\t' + "Palacio 11 de Outubro" + '\n' + # tmp+='\t\t\t\t\n' tmp += '\t\t\t\tRelatório da Ordem do Dia\n' @@ -38,143 +47,166 @@ def cabecalho(dic_cabecalho, dat_ordem, imagem): def rodape(lst_rodape): - """ Gera o codigo rml do rodape""" + """Gera o codigo rml do rodape""" - tmp = '' - tmp += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + tmp = "" + tmp += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t' + \ - lst_rodape[2] + '\n' - tmp += '\t\t\t\tPágina \n' - tmp += '\t\t\t\t' + \ - lst_rodape[0] + '\n' - tmp += '\t\t\t\t' + \ - lst_rodape[1] + '\n' + tmp += '\t\t\t\t' + lst_rodape[2] + "\n" + tmp += ( + '\t\t\t\tPágina \n' + ) + tmp += ( + '\t\t\t\t' + + lst_rodape[0] + + "\n" + ) + tmp += ( + '\t\t\t\t' + + lst_rodape[1] + + "\n" + ) return tmp def paraStyle(): - """ Gera o codigo rml que define o estilo dos paragrafos""" + """Gera o codigo rml que define o estilo dos paragrafos""" - tmp = '' - tmp += '\t\n' + tmp = "" + tmp += "\t\n" tmp += '\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' - tmp += '\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" + tmp += "\t\t\n" tmp += '\t\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\t\t\n' tmp += '\t\t\n' tmp += '\t\t\n' - tmp += '\t\n' + tmp += "\t\n" return tmp + # def splen(lst_splen): def pauta(lst_splen, lst_pauta): - """ Funcao que gera o codigo rml da sessao plenaria """ + """Funcao que gera o codigo rml da sessao plenaria""" - tmp = '' + tmp = "" # inicio do bloco - tmp += '\t\n' + tmp += "\t\n" for dicsp in lst_splen: # espaço inicial tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" # condicao para a quebra de pagina tmp += '\t\t\n' # sessao plenaria - if dicsp['sessao'] != None: - tmp += '\t\t' + \ - dicsp['sessao'].replace('&', '&') + '\n' + if dicsp["sessao"] != None: + tmp += ( + '\t\t' + + dicsp["sessao"].replace("&", "&") + + "\n" + ) tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' - - if dicsp['datasessao'] != None: - tmp += '\t\t' + \ - dicsp['datasessao'].replace('&', '&') + '\n' + tmp += "\t\t\n" + + if dicsp["datasessao"] != None: + tmp += ( + '\t\t' + + dicsp["datasessao"].replace("&", "&") + + "\n" + ) tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" -# tmp+='\t\n' -# return tmp -# -# def pauta(lst_pauta): -# """ Funcao que gera o codigo rml da pauta da ordem do dia""" + # tmp+='\t\n' + # return tmp + # + # def pauta(lst_pauta): + # """ Funcao que gera o codigo rml da pauta da ordem do dia""" -# tmp='' + # tmp='' # inicio do bloco que contem os flowables -# tmp+='\t\n' + # tmp+='\t\n' for dic in lst_pauta: # espaco inicial tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" # condicao para a quebra de pagina tmp += '\t\t\n' # pauta - if dic['num_ordem'] != None: - tmp += '\t\tItem nº ' + \ - str(dic['num_ordem']) + '' - if dic['id_materia'] != None: - tmp += '\t\t' + dic['id_materia'] + '\n' + if dic["num_ordem"] != None: + tmp += '\t\tItem nº ' + str(dic["num_ordem"]) + "" + if dic["id_materia"] != None: + tmp += '\t\t' + dic["id_materia"] + "\n" tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' - if dic['txt_ementa'] != None: - tmp += '\t\t' + \ - dic['txt_ementa'].replace('&', '&') + '\n' + tmp += "\t\t\n" + if dic["txt_ementa"] != None: + tmp += ( + '\t\t' + + dic["txt_ementa"].replace("&", "&") + + "\n" + ) tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' - if dic['des_numeracao'] != None: - tmp += '\t\tProcesso: ' + \ - dic['des_numeracao'] + '\n' - if dic['des_turno'] != None: - tmp += '\t\tTurno: ' + \ - dic['des_turno'] + '\n' - if dic['nom_autor'] != None: - tmp += '\t\tAutor: ' + \ - dic['nom_autor'] + '\n' - if dic['des_situacao'] != None: - tmp += '\t\tSituação: ' + \ - dic['des_situacao'] + '\n' -# if dic['des_numeracao']!=None: -# tmp+='\t\tProcesso Nº: ' + dic['des_numeracao'] + '\n' - - -# indice = 0 -# for relator in dic['lst_relator']: -# indice = indice + 1 -# if (relator != None): -# if (indice < 2): -# tmp+='\t\tRelator: ' + relator + '\n' -# else: -# tmp+='\t\t
                      ' + relator + '
        \n' - - tmp += '\t
        \n' + tmp += "\t\t\n" + if dic["des_numeracao"] != None: + tmp += ( + '\t\tProcesso: ' + + dic["des_numeracao"] + + "\n" + ) + if dic["des_turno"] != None: + tmp += ( + '\t\tTurno: ' + dic["des_turno"] + "\n" + ) + if dic["nom_autor"] != None: + tmp += ( + '\t\tAutor: ' + dic["nom_autor"] + "\n" + ) + if dic["des_situacao"] != None: + tmp += ( + '\t\tSituação: ' + + dic["des_situacao"] + + "\n" + ) + # if dic['des_numeracao']!=None: + # tmp+='\t\tProcesso Nº: ' + dic['des_numeracao'] + '\n' + + # indice = 0 + # for relator in dic['lst_relator']: + # indice = indice + 1 + # if (relator != None): + # if (indice < 2): + # tmp+='\t\tRelator: ' + relator + '\n' + # else: + # tmp+='\t\t
                      ' + relator + '
        \n' + + tmp += "\t
        \n" return tmp @@ -192,27 +224,28 @@ def principal(imagem, lst_splen, lst_pauta, dic_cabecalho, lst_rodape): arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp = '' + tmp = "" tmp += '\n' tmp += '\n' tmp += '\n' tmp += '\t\n' + tmp += "\t\t\n" + tmp += "\t\n" tmp += paraStyle() -# tmp+=splen(lst_splen) + # tmp+=splen(lst_splen) tmp += pauta(lst_splen, lst_pauta) - tmp += '\n' + tmp += "\n" tmp_pdf = parseString(tmp) return tmp_pdf + # try: # tmp_pdf=parseString(unicode(tmp, 'utf-8')) # except: diff --git a/sapl/relatorios/templates/pdf_ordem_dia_preparar_pysc.py b/sapl/relatorios/templates/pdf_ordem_dia_preparar_pysc.py index 79281beed..5adf29d2a 100644 --- a/sapl/relatorios/templates/pdf_ordem_dia_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_ordem_dia_preparar_pysc.py @@ -3,56 +3,83 @@ import os request = context.REQUEST response = request.RESPONSE session = request.SESSION -if context.REQUEST['cod_sessao_plen'] != '': - cod_sessao_plen = context.REQUEST['cod_sessao_plen'] +if context.REQUEST["cod_sessao_plen"] != "": + cod_sessao_plen = context.REQUEST["cod_sessao_plen"] splen = [] # lista contendo as sessões plenárias na data indicada pauta = [] # lista contendo a pauta da ordem do dia a ser impressa data = "" - for dat_sessao in context.zsql.sessao_plenaria_obter_zsql(cod_sessao_plen=cod_sessao_plen, ind_excluido=0): + for dat_sessao in context.zsql.sessao_plenaria_obter_zsql( + cod_sessao_plen=cod_sessao_plen, ind_excluido=0 + ): # converte data para formato yyyy/mm/dd data = context.pysc.data_converter_pysc(dat_sessao.dat_inicio_sessao) dat_ordem = context.pysc.data_converter_pysc( - dat_sessao.dat_inicio_sessao) # converte data para formato yyyy/mm/dd + dat_sessao.dat_inicio_sessao + ) # converte data para formato yyyy/mm/dd # seleciona dados da sessão plenária - for sp in context.zsql.sessao_plenaria_obter_zsql(dat_inicio_sessao=data, ind_excluido=0): - dicsp = {} # dicionário que armazenará os dados a serem impressos de uma sessão plenária - ts = context.zsql.tipo_sessao_plenaria_obter_zsql( - tip_sessao=sp.tip_sessao)[0] - dicsp["sessao"] = str(sp.num_sessao_plen) + "ª Sessao " + ts.nom_sessao + " da " + str( - sp.num_sessao_leg) + "ª Sessao Legislativa da " + str(sp.num_legislatura) + "ª Legislatura" - dia = context.pysc.data_converter_por_extenso_pysc( - data=sp.dat_inicio_sessao) + for sp in context.zsql.sessao_plenaria_obter_zsql( + dat_inicio_sessao=data, ind_excluido=0 + ): + dicsp = ( + {} + ) # dicionário que armazenará os dados a serem impressos de uma sessão plenária + ts = context.zsql.tipo_sessao_plenaria_obter_zsql(tip_sessao=sp.tip_sessao)[0] + dicsp["sessao"] = ( + str(sp.num_sessao_plen) + + "ª Sessao " + + ts.nom_sessao + + " da " + + str(sp.num_sessao_leg) + + "ª Sessao Legislativa da " + + str(sp.num_legislatura) + + "ª Legislatura" + ) + dia = context.pysc.data_converter_por_extenso_pysc(data=sp.dat_inicio_sessao) hora = context.pysc.hora_formatar_pysc(hora=sp.hr_inicio_sessao) - dicsp["datasessao"] = "Dia " + \ - str(dia) + " (" + str(sp.dia_sessao) + ") - Inicio as " + hora + dicsp["datasessao"] = ( + "Dia " + str(dia) + " (" + str(sp.dia_sessao) + ") - Inicio as " + hora + ) splen.append(dicsp) # seleciona as matérias que compõem a pauta na data escolhida for ordem in context.zsql.ordem_dia_obter_zsql(dat_ordem=data, ind_excluido=0): # seleciona os detalhes de uma matéria - materia = context.zsql.materia_obter_zsql( - cod_materia=ordem.cod_materia)[0] + materia = context.zsql.materia_obter_zsql(cod_materia=ordem.cod_materia)[0] dic = {} # dicionário que armazenará os dados a serem impressos de uma matéria dic["num_ordem"] = ordem.num_ordem - dic["id_materia"] = materia.des_tipo_materia + " - Nº " + \ - str(materia.num_ident_basica) + "/" + str(materia.ano_ident_basica) + dic["id_materia"] = ( + materia.des_tipo_materia + + " - Nº " + + str(materia.num_ident_basica) + + "/" + + str(materia.ano_ident_basica) + ) # dic["id_materia"] = materia.sgl_tipo_materia+" - "+str(materia.num_ident_basica)+"/"+str(materia.ano_ident_basica)+" - "+materia.des_tipo_materia dic["txt_ementa"] = ordem.txt_observacao # numeracao do processo 26/02/2011 dic["des_numeracao"] = "" - numeracao = context.zsql.numeracao_obter_zsql( - cod_materia=ordem.cod_materia) + numeracao = context.zsql.numeracao_obter_zsql(cod_materia=ordem.cod_materia) if len(numeracao): numeracao = numeracao[0] - dic["des_numeracao"] = str( - numeracao.num_materia) + "/" + str(numeracao.ano_materia) + dic["des_numeracao"] = ( + str(numeracao.num_materia) + "/" + str(numeracao.ano_materia) + ) dic["des_turno"] = "" dic["des_situacao"] = "" tramitacao = context.zsql.tramitacao_obter_zsql( - cod_materia=ordem.cod_materia, ind_ult_tramitacao=1) + cod_materia=ordem.cod_materia, ind_ult_tramitacao=1 + ) if len(tramitacao): tramitacao = tramitacao[0] if tramitacao.sgl_turno != "": - for turno in [("P", "Primeiro"), ("S", "Segundo"), ("U", "Único"), ("L", "Suplementar"), ("A", "Votação Única em Regime de Urgência"), ("B", "1ª Votação"), ("C", "2ª e 3ª Votações")]: + for turno in [ + ("P", "Primeiro"), + ("S", "Segundo"), + ("U", "Único"), + ("L", "Suplementar"), + ("A", "Votação Única em Regime de Urgência"), + ("B", "1ª Votação"), + ("C", "2ª e 3ª Votações"), + ]: if tramitacao.sgl_turno == turno[0]: dic["des_turno"] = turno[1] @@ -60,9 +87,10 @@ if context.REQUEST['cod_sessao_plen'] != '': if dic["des_situacao"] == None: dic["des_situacao"] = " " - dic["nom_autor"] = '' + dic["nom_autor"] = "" autoria = context.zsql.autoria_obter_zsql( - cod_materia=ordem.cod_materia, ind_primeiro_autor=1) + cod_materia=ordem.cod_materia, ind_primeiro_autor=1 + ) if len(autoria): # se existe autor autoria = autoria[0] try: @@ -72,27 +100,34 @@ if context.REQUEST['cod_sessao_plen'] != '': if autor.des_tipo_autor == "Parlamentar": parlamentar = context.zsql.parlamentar_obter_zsql( - cod_parlamentar=autor.cod_parlamentar)[0] + cod_parlamentar=autor.cod_parlamentar + )[0] dic["nom_autor"] = parlamentar.nom_parlamentar elif autor.des_tipo_autor == "Comissao": comissao = context.zsql.comissao_obter_zsql( - cod_comissao=autor.cod_comissao)[0] + cod_comissao=autor.cod_comissao + )[0] dic["nom_autor"] = comissao.nom_comissao else: dic["nom_autor"] = autor.nom_autor except: pass lst_relator = [] # lista contendo os relatores da matéria - for relatoria in context.zsql.relatoria_obter_zsql(cod_materia=ordem.cod_materia): + for relatoria in context.zsql.relatoria_obter_zsql( + cod_materia=ordem.cod_materia + ): parlamentar = context.zsql.parlamentar_obter_zsql( - cod_parlamentar=relatoria.cod_parlamentar)[0] + cod_parlamentar=relatoria.cod_parlamentar + )[0] comissao = context.zsql.comissao_obter_zsql( - cod_comissao=relatoria.cod_comissao)[0] - lst_relator.append(parlamentar.nom_parlamentar + - " - " + comissao.nom_comissao) + cod_comissao=relatoria.cod_comissao + )[0] + lst_relator.append( + parlamentar.nom_parlamentar + " - " + comissao.nom_comissao + ) if not len(lst_relator): - lst_relator = [''] + lst_relator = [""] dic["lst_relator"] = lst_relator # adiciona o dicionário na pauta @@ -107,7 +142,8 @@ if context.REQUEST['cod_sessao_plen'] != '': # obtém a localidade localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) + cod_localidade=casa["cod_localidade"] + ) # monta o cabeçalho da página cabecalho = {} @@ -121,9 +157,8 @@ if context.REQUEST['cod_sessao_plen'] != '': cabecalho["nom_estado"] = "Estado do " + nom_estado # tenta buscar o logotipo da casa LOGO_CASA - if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl[ - 'logo_casa.gif'].absolute_url() + if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -138,8 +173,9 @@ if context.REQUEST['cod_sessao_plen'] != '': linha1 = linha1 + " " linha1 = linha1 + " CEP: " + num_cep if localidade[0].nom_localidade != None and localidade[0].nom_localidade != "": - linha1 = linha1 + " " + \ - localidade[0].nom_localidade + " - " + localidade[0].sgl_uf + linha1 = ( + linha1 + " " + localidade[0].nom_localidade + " - " + localidade[0].sgl_uf + ) if casa["num_tel"] != None and casa["num_tel"] != "": linha1 = linha1 + " Tel.: " + casa["num_tel"] @@ -153,8 +189,9 @@ if context.REQUEST['cod_sessao_plen'] != '': sessao = session.id caminho = context.pdf_ordem_dia_gerar( - sessao, imagem, dat_ordem, splen, pauta, cabecalho, rodape) - if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + sessao, imagem, dat_ordem, splen, pauta, cabecalho, rodape + ) + if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_pauta_sessao_gerar.py b/sapl/relatorios/templates/pdf_pauta_sessao_gerar.py index 7d43e5f9b..f5ee48fb0 100755 --- a/sapl/relatorios/templates/pdf_pauta_sessao_gerar.py +++ b/sapl/relatorios/templates/pdf_pauta_sessao_gerar.py @@ -3,53 +3,73 @@ Autor Luciano De Fázio - 06/11/2012 versão: 1.0 """ -import time import os +import time from trml2pdf import parseString def cabecalho(inf_basicas_dic, imagem): - """ - """ - tmp = '' + """ """ + tmp = "" if os.path.isfile(imagem): - tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t2cm 25.4cm 19cm 25.4cm\n' + tmp += ( + '\t\t\t\t\n' + ) + tmp += "\t\t\t\t2cm 25.4cm 19cm 25.4cm\n" tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t' + \ - str(inf_basicas_dic["nom_camara"]) + '\n' + tmp += ( + '\t\t\t\t' + + str(inf_basicas_dic["nom_camara"]) + + "\n" + ) tmp += '\t\t\t\t\n' tmp += '\t\t\t\tSistema de Apoio ao Processo Legislativo\n' tmp += '\t\t\t\t\n' - tmp += '\t\t\t\tPauta da ' + str(inf_basicas_dic['num_sessao_plen']) + 'ª Reunião ' + str(inf_basicas_dic['nom_sessao']) + ' da ' + str( - inf_basicas_dic['num_sessao_leg']) + 'ª Sessão Legislativa da \n' - tmp += '\t\t\t\t' + \ - str(inf_basicas_dic['num_legislatura']) + \ - ' Legislatura \n' + tmp += ( + '\t\t\t\tPauta da ' + + str(inf_basicas_dic["num_sessao_plen"]) + + "ª Reunião " + + str(inf_basicas_dic["nom_sessao"]) + + " da " + + str(inf_basicas_dic["num_sessao_leg"]) + + "ª Sessão Legislativa da \n" + ) + tmp += ( + '\t\t\t\t' + + str(inf_basicas_dic["num_legislatura"]) + + " Legislatura \n" + ) return tmp def rodape(lst_rodape): """Gera o codigo rml do rodape""" - tmp_data = '' - tmp_data += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + tmp_data = "" + tmp_data += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[2] + '\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[0] + '\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[1] + '\n' + tmp_data += ( + '\t\t\t\t' + lst_rodape[2] + "\n" + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[0] + + "\n" + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[1] + + "\n" + ) return tmp_data def paraStyle(): - """ - """ - tmp = '' - tmp += '\t\n' + """ """ + tmp = "" + tmp += "\t\n" tmp += '\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' @@ -57,12 +77,12 @@ def paraStyle(): tmp += '\t\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' - tmp += '\t\t\t\n' + tmp += "\t\t\t\n" tmp += '\t\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\t\t\n' tmp += '\t\t\t\n' @@ -71,10 +91,10 @@ def paraStyle(): tmp += '\t\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' - tmp += '\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" + tmp += "\t\t\n" tmp += '\t\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\t\t\n' tmp += '\t\t\n' tmp += '\t\t\n' @@ -82,16 +102,15 @@ def paraStyle(): tmp += '\t\t\n' tmp += '\t\t\n' tmp += '\t\t\n' - tmp += '\t\n' + tmp += "\t\n" return tmp def inf_basicas(inf_basicas_dic): - """ - """ + """ """ tmp = "" - nom_sessao = inf_basicas_dic['nom_sessao'] + nom_sessao = inf_basicas_dic["nom_sessao"] num_sessao_plen = inf_basicas_dic["num_sessao_plen"] num_sessao_leg = inf_basicas_dic["num_sessao_leg"] num_legislatura = inf_basicas_dic["num_legislatura"] @@ -103,113 +122,174 @@ def inf_basicas(inf_basicas_dic): tmp += '\t\tInformações Básicas\n' tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' - tmp += '\t\tTipo da Sessão: ' + \ - nom_sessao + '\n' - tmp += '\t\tAbertura: ' + \ - dat_inicio_sessao.strftime( - "%d/%m/%Y") + ' - ' + hr_inicio_sessao + '\n' + tmp += "\t\t\n" + tmp += ( + '\t\tTipo da Sessão: ' + + nom_sessao + + "\n" + ) + tmp += ( + '\t\tAbertura: ' + + dat_inicio_sessao.strftime("%d/%m/%Y") + + " - " + + hr_inicio_sessao + + "\n" + ) return tmp + def build_expedientes(expedientes): - """ - """ + """ """ tmp = "" tmp += '\t\tExpedientes\n' for e in expedientes: - tmp += '\t\t\t{}:'.format(e['tipo']) - tmp += '\t\t\t

        {}

        '.format(e['conteudo']) - + tmp += '\t\t\t{}:'.format( + e["tipo"] + ) + tmp += '\t\t\t

        {}

        '.format( + e["conteudo"] + ) + return tmp def expediente_materia(lst_expediente_materia): - """ - """ - tmp = '' + """ """ + tmp = "" tmp += 'Matérias do Expediente\n\n' tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\n' - tmp += 'MatériaEmentaSituação\n' + tmp += "MatériaEmentaSituação\n" for expediente_materia in lst_expediente_materia: - tmp += '' + str(expediente_materia['num_ordem']) + ' - ' + \ - expediente_materia["tipo_materia"] + ' No. ' + \ - expediente_materia['id_materia'] + '\n' + '' + expediente_materia['num_autores'] + ': ' + \ - expediente_materia['nom_autor'] + '\n' - txt_ementa = expediente_materia['txt_ementa'].replace('&', '&') + tmp += ( + '' + + str(expediente_materia["num_ordem"]) + + " - " + + expediente_materia["tipo_materia"] + + " No. " + + expediente_materia["id_materia"] + + "\n" + + '' + + expediente_materia["num_autores"] + + ": " + + expediente_materia["nom_autor"] + + "\n" + ) + txt_ementa = expediente_materia["txt_ementa"].replace("&", "&") if len(txt_ementa) > 1000: txt_ementa = txt_ementa[:1000] + "..." - tmp += '' + txt_ementa + '' + '' + expediente_materia['ordem_observacao'] + '\n' - tmp += '' + \ - str(expediente_materia['des_situacao']) + '\n' + tmp += ( + '' + + txt_ementa + + "" + + '' + + expediente_materia["ordem_observacao"] + + "\n" + ) + tmp += ( + '' + + str(expediente_materia["des_situacao"]) + + "\n" + ) - tmp += '\t\t\n' + tmp += "\t\t\n" return tmp def votacao(lst_votacao): - """ - """ + """ """ - tmp = '' + tmp = "" tmp += 'Matérias da Ordem do Dia\n\n' tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\n' - tmp += 'MatériaEmentaSituação\n' + tmp += "MatériaEmentaSituação\n" for votacao in lst_votacao: - tmp += '' + str(votacao['num_ordem']) + ' - ' + \ - votacao["tipo_materia"] + ' No. ' + \ - str(votacao['id_materia']) + '\n' + 'Processo: ' + \ - str(votacao['des_numeracao']) + '\n' + 'Turno: ' + \ - str(votacao['des_turno']) + '\n' + ''+votacao['num_autores']+': ' + \ - str(votacao['nom_autor']) + '\n' - txt_ementa = votacao['txt_ementa'].replace('&', '&') + tmp += ( + '' + + str(votacao["num_ordem"]) + + " - " + + votacao["tipo_materia"] + + " No. " + + str(votacao["id_materia"]) + + "\n" + + 'Processo: ' + + str(votacao["des_numeracao"]) + + "\n" + + 'Turno: ' + + str(votacao["des_turno"]) + + "\n" + + '' + + votacao["num_autores"] + + ": " + + str(votacao["nom_autor"]) + + "\n" + ) + txt_ementa = votacao["txt_ementa"].replace("&", "&") if len(txt_ementa) > 1000: txt_ementa = txt_ementa[:1000] + "..." - tmp += '' + txt_ementa + '' + '' + votacao['ordem_observacao'] + '\n' - tmp += '' + \ - str(votacao['des_situacao']) + '\n' + tmp += ( + '' + + txt_ementa + + "" + + '' + + votacao["ordem_observacao"] + + "\n" + ) + tmp += ( + '' + + str(votacao["des_situacao"]) + + "\n" + ) - tmp += '\t\t\n' + tmp += "\t\t\n" return tmp -def principal(rodape_dic, imagem, inf_basicas_dic, lst_expediente_materia, lst_votacao, expedientes): - """ - """ +def principal( + rodape_dic, + imagem, + inf_basicas_dic, + lst_expediente_materia, + lst_votacao, + expedientes, +): + """ """ arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp = '' + tmp = "" tmp += '\n' tmp += '\n' tmp += '\n' tmp += '\t\n' + tmp += "\t\t\n" + tmp += "\t\n" tmp += paraStyle() - tmp += '\t\n' + tmp += "\t\n" tmp += inf_basicas(inf_basicas_dic) tmp += build_expedientes(expedientes) tmp += expediente_materia(lst_expediente_materia) tmp += votacao(lst_votacao) - tmp += '\t\n' - tmp += '\n' + tmp += "\t\n" + tmp += "\n" tmp_pdf = parseString(tmp) return tmp_pdf + + # if hasattr(context.temp_folder,arquivoPdf): # context.temp_folder.manage_delObjects(ids=arquivoPdf) # context.temp_folder.manage_addFile(arquivoPdf) diff --git a/sapl/relatorios/templates/pdf_pauta_sessao_preparar_pysc.py b/sapl/relatorios/templates/pdf_pauta_sessao_preparar_pysc.py index 67f0c774b..7afab8534 100755 --- a/sapl/relatorios/templates/pdf_pauta_sessao_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_pauta_sessao_preparar_pysc.py @@ -4,19 +4,24 @@ request = context.REQUEST response = request.RESPONSE session = request.SESSION -if context.REQUEST['data'] != '': - dat_inicio_sessao = context.REQUEST['data'] +if context.REQUEST["data"] != "": + dat_inicio_sessao = context.REQUEST["data"] pauta = [] # lista contendo a pauta da ordem do dia a ser impressa # converte data para formato yyyy/mm/dd data = context.pysc.data_converter_pysc(dat_inicio_sessao) - codigo = context.REQUEST['cod_sessao_plen'] + codigo = context.REQUEST["cod_sessao_plen"] # seleciona as matérias que compõem a pauta na data escolhida - for sessao in context.zsql.sessao_plenaria_obter_zsql(dat_inicio_sessao=data, cod_sessao_plen=codigo, ind_excluido=0): - inf_basicas_dic = {} # dicionário que armazenará as informacoes basicas da sessao plenaria + for sessao in context.zsql.sessao_plenaria_obter_zsql( + dat_inicio_sessao=data, cod_sessao_plen=codigo, ind_excluido=0 + ): + inf_basicas_dic = ( + {} + ) # dicionário que armazenará as informacoes basicas da sessao plenaria # seleciona o tipo da sessao plenaria tipo_sessao = context.zsql.tipo_sessao_plenaria_obter_zsql( - tip_sessao=sessao.tip_sessao, ind_excluido=0)[0] + tip_sessao=sessao.tip_sessao, ind_excluido=0 + )[0] inf_basicas_dic["nom_sessao"] = tipo_sessao.nom_sessao inf_basicas_dic["num_sessao_plen"] = sessao.num_sessao_plen inf_basicas_dic["nom_sessao"] = tipo_sessao.nom_sessao @@ -29,47 +34,59 @@ if context.REQUEST['data'] != '': # Lista das matérias do Expediente, incluindo o status da tramitação lst_expediente_materia = [] - for expediente_materia in context.zsql.votacao_expediente_materia_obter_zsql(dat_ordem=data, cod_sessao_plen=codigo, ind_excluido=0): - + for expediente_materia in context.zsql.votacao_expediente_materia_obter_zsql( + dat_ordem=data, cod_sessao_plen=codigo, ind_excluido=0 + ): # seleciona os detalhes de uma matéria materia = context.zsql.materia_obter_zsql( - cod_materia=expediente_materia.cod_materia)[0] + cod_materia=expediente_materia.cod_materia + )[0] dic_expediente_materia = {} dic_expediente_materia["num_ordem"] = expediente_materia.num_ordem - dic_expediente_materia["id_materia"] = materia.sgl_tipo_materia + " - " + materia.des_tipo_materia + \ - " No. " + str(materia.num_ident_basica) + "/" + \ - str(materia.ano_ident_basica) + dic_expediente_materia["id_materia"] = ( + materia.sgl_tipo_materia + + " - " + + materia.des_tipo_materia + + " No. " + + str(materia.num_ident_basica) + + "/" + + str(materia.ano_ident_basica) + ) dic_expediente_materia["txt_ementa"] = materia.txt_ementa dic_expediente_materia[ - "ordem_observacao"] = expediente_materia.ordem_observacao + "ordem_observacao" + ] = expediente_materia.ordem_observacao dic_expediente_materia["des_numeracao"] = "" numeracao = context.zsql.numeracao_obter_zsql( - cod_materia=expediente_materia.cod_materia) + cod_materia=expediente_materia.cod_materia + ) if len(numeracao): numeracao = numeracao[0] - dic_expediente_materia["des_numeracao"] = str( - numeracao.num_materia) + "/" + str(numeracao.ano_materia) + dic_expediente_materia["des_numeracao"] = ( + str(numeracao.num_materia) + "/" + str(numeracao.ano_materia) + ) - dic_expediente_materia["nom_autor"] = '' + dic_expediente_materia["nom_autor"] = "" autoria = context.zsql.autoria_obter_zsql( - cod_materia=expediente_materia.cod_materia, ind_primeiro_autor=1) + cod_materia=expediente_materia.cod_materia, ind_primeiro_autor=1 + ) if len(autoria) > 0: # se existe autor autoria = autoria[0] - autor = context.zsql.autor_obter_zsql( - cod_autor=autoria.cod_autor) + autor = context.zsql.autor_obter_zsql(cod_autor=autoria.cod_autor) if len(autor) > 0: autor = autor[0] if autor.des_tipo_autor == "Parlamentar": parlamentar = context.zsql.parlamentar_obter_zsql( - cod_parlamentar=autor.cod_parlamentar)[0] - dic_expediente_materia[ - "nom_autor"] = parlamentar.nom_parlamentar + cod_parlamentar=autor.cod_parlamentar + )[0] + dic_expediente_materia["nom_autor"] = parlamentar.nom_parlamentar elif autor.des_tipo_autor == "Comissao": comissao = context.zsql.comissao_obter_zsql( - cod_comissao=autor.cod_comissao)[0] + cod_comissao=autor.cod_comissao + )[0] dic_expediente_materia["nom_autor"] = comissao.nom_comissao else: dic_expediente_materia["nom_autor"] = autor.nom_autor @@ -77,11 +94,21 @@ if context.REQUEST['data'] != '': dic_expediente_materia["des_turno"] = "" dic_expediente_materia["des_situacao"] = "" tramitacao = context.zsql.tramitacao_obter_zsql( - cod_materia=expediente_materia.cod_materia, ind_ult_tramitacao=1) + cod_materia=expediente_materia.cod_materia, ind_ult_tramitacao=1 + ) if len(tramitacao): tramitacao = tramitacao[0] if tramitacao.sgl_turno != "": - for turno in [("P", "Primeiro"), ("S", "Segundo"), ("U", "Único"), ("F", "Final"), ("L", "Suplementar"), ("A", "Votação Única em Regime de Urgência"), ("B", "1ª Votação"), ("C", "2ª e 3ª Votações")]: + for turno in [ + ("P", "Primeiro"), + ("S", "Segundo"), + ("U", "Único"), + ("F", "Final"), + ("L", "Suplementar"), + ("A", "Votação Única em Regime de Urgência"), + ("B", "1ª Votação"), + ("C", "2ª e 3ª Votações"), + ]: if tramitacao.sgl_turno == turno[0]: dic_expediente_materia["des_turno"] = turno[1] @@ -92,46 +119,58 @@ if context.REQUEST['data'] != '': # Lista das matérias da Ordem do Dia, incluindo o status da tramitação lst_votacao = [] - for votacao in context.zsql.votacao_ordem_dia_obter_zsql(dat_ordem=data, cod_sessao_plen=codigo, ind_excluido=0): - + for votacao in context.zsql.votacao_ordem_dia_obter_zsql( + dat_ordem=data, cod_sessao_plen=codigo, ind_excluido=0 + ): # seleciona os detalhes de uma matéria - materia = context.zsql.materia_obter_zsql( - cod_materia=votacao.cod_materia)[0] + materia = context.zsql.materia_obter_zsql(cod_materia=votacao.cod_materia)[ + 0 + ] dic_votacao = {} dic_votacao["num_ordem"] = votacao.num_ordem - dic_votacao["id_materia"] = materia.sgl_tipo_materia + " - " + materia.des_tipo_materia + \ - " No. " + str(materia.num_ident_basica) + "/" + \ - str(materia.ano_ident_basica) + dic_votacao["id_materia"] = ( + materia.sgl_tipo_materia + + " - " + + materia.des_tipo_materia + + " No. " + + str(materia.num_ident_basica) + + "/" + + str(materia.ano_ident_basica) + ) dic_votacao["txt_ementa"] = materia.txt_ementa dic_votacao["ordem_observacao"] = votacao.ordem_observacao dic_votacao["des_numeracao"] = "" numeracao = context.zsql.numeracao_obter_zsql( - cod_materia=votacao.cod_materia) + cod_materia=votacao.cod_materia + ) if len(numeracao): numeracao = numeracao[0] - dic_votacao["des_numeracao"] = str( - numeracao.num_materia) + "/" + str(numeracao.ano_materia) + dic_votacao["des_numeracao"] = ( + str(numeracao.num_materia) + "/" + str(numeracao.ano_materia) + ) - dic_votacao["nom_autor"] = '' + dic_votacao["nom_autor"] = "" autoria = context.zsql.autoria_obter_zsql( - cod_materia=votacao.cod_materia, ind_primeiro_autor=1) + cod_materia=votacao.cod_materia, ind_primeiro_autor=1 + ) if len(autoria) > 0: # se existe autor autoria = autoria[0] - autor = context.zsql.autor_obter_zsql( - cod_autor=autoria.cod_autor) - + autor = context.zsql.autor_obter_zsql(cod_autor=autoria.cod_autor) + if len(autor) > 0: autor = autor[0] if autor.des_tipo_autor == "Parlamentar": parlamentar = context.zsql.parlamentar_obter_zsql( - cod_parlamentar=autor.cod_parlamentar)[0] + cod_parlamentar=autor.cod_parlamentar + )[0] dic_votacao["nom_autor"] = parlamentar.nom_parlamentar elif autor.des_tipo_autor == "Comissao": comissao = context.zsql.comissao_obter_zsql( - cod_comissao=autor.cod_comissao)[0] + cod_comissao=autor.cod_comissao + )[0] dic_votacao["nom_autor"] = comissao.nom_comissao else: dic_votacao["nom_autor"] = autor.nom_autor @@ -139,11 +178,20 @@ if context.REQUEST['data'] != '': dic_votacao["des_turno"] = "" dic_votacao["des_situacao"] = "" tramitacao = context.zsql.tramitacao_obter_zsql( - cod_materia=votacao.cod_materia, ind_ult_tramitacao=1) + cod_materia=votacao.cod_materia, ind_ult_tramitacao=1 + ) if len(tramitacao): tramitacao = tramitacao[0] if tramitacao.sgl_turno != "": - for turno in [("P", "Primeiro"), ("S", "Segundo"), ("U", "Único"), ("L", "Suplementar"), ("A", "Votação Única em Regime de Urgência"), ("B", "1ª Votação"), ("C", "2ª e 3ª Votações")]: + for turno in [ + ("P", "Primeiro"), + ("S", "Segundo"), + ("U", "Único"), + ("L", "Suplementar"), + ("A", "Votação Única em Regime de Urgência"), + ("B", "1ª Votação"), + ("C", "2ª e 3ª Votações"), + ]: if tramitacao.sgl_turno == turno[0]: dic_votacao["des_turno"] = turno[1] @@ -157,9 +205,8 @@ if context.REQUEST['data'] != '': cabecalho = {} # tenta buscar o logotipo da casa LOGO_CASA - if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl[ - 'logo_casa.gif'].absolute_url() + if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -169,22 +216,26 @@ if context.REQUEST['data'] != '': for item in aux: casa[item[0]] = item[1] localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) + cod_localidade=casa["cod_localidade"] + ) data_emissao = DateTime().strftime("%d/%m/%Y") rodape = casa - rodape['data_emissao'] = data_emissao + rodape["data_emissao"] = data_emissao - inf_basicas_dic['nom_camara'] = casa['nom_casa'] + inf_basicas_dic["nom_camara"] = casa["nom_casa"] REQUEST = context.REQUEST - for local in context.zsql.localidade_obter_zsql(cod_localidade=casa['cod_localidade']): - rodape['nom_localidade'] = " " + local.nom_localidade - rodape['sgl_uf'] = local.sgl_uf + for local in context.zsql.localidade_obter_zsql( + cod_localidade=casa["cod_localidade"] + ): + rodape["nom_localidade"] = " " + local.nom_localidade + rodape["sgl_uf"] = local.sgl_uf -# return lst_votacao + # return lst_votacao sessao = session.id caminho = context.pdf_pauta_sessao_gerar( - rodape, sessao, imagem, inf_basicas_dic, lst_votacao, lst_expediente_materia) - if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + rodape, sessao, imagem, inf_basicas_dic, lst_votacao, lst_expediente_materia + ) + if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_protocolo_gerar.py b/sapl/relatorios/templates/pdf_protocolo_gerar.py index 752f19c9a..809bcd8b6 100755 --- a/sapl/relatorios/templates/pdf_protocolo_gerar.py +++ b/sapl/relatorios/templates/pdf_protocolo_gerar.py @@ -6,21 +6,28 @@ Empresa: OpenLegis Consultoria versão: 1.0 """ -import time import os +import time from trml2pdf import parseString def cabecalho(dic_cabecalho, imagem): """Gera o codigo rml do cabecalho""" - tmp_data = '' + tmp_data = "" if os.path.isfile(imagem): - tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t2cm 25.4cm 19cm 25.4cm\n' + tmp_data += ( + '\t\t\t\t\n' + ) + tmp_data += "\t\t\t\t2cm 25.4cm 19cm 25.4cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - dic_cabecalho['nom_casa'] + '\n' + tmp_data += ( + '\t\t\t\t' + + dic_cabecalho["nom_casa"] + + "\n" + ) tmp_data += '\t\t\t\t\n' tmp_data += '\t\t\t\tSistema de Apoio ao Processo Legislativo\n' tmp_data += '\t\t\t\t\n' @@ -32,16 +39,25 @@ def cabecalho(dic_cabecalho, imagem): def rodape(lst_rodape): """Gera o codigo rml do rodape""" - tmp_data = '' - tmp_data += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + tmp_data = "" + tmp_data += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp_data += '\t\t\t\t\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[2] + '\n' - tmp_data += '\t\t\t\tPágina \n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[0] + '\n' - tmp_data += '\t\t\t\t' + \ - lst_rodape[1] + '\n' + tmp_data += ( + '\t\t\t\t' + lst_rodape[2] + "\n" + ) + tmp_data += ( + '\t\t\t\tPágina \n' + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[0] + + "\n" + ) + tmp_data += ( + '\t\t\t\t' + + lst_rodape[1] + + "\n" + ) return tmp_data @@ -49,18 +65,18 @@ def rodape(lst_rodape): def paraStyle(): """Gera o codigo rml que define o estilo dos paragrafos""" - tmp_data = '' - tmp_data += '\t\n' + tmp_data = "" + tmp_data += "\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t\n' tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" + tmp_data += "\t\t\n" tmp_data += '\t\t\t\n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\n' - tmp_data += '\t\n' + tmp_data += "\t\n" return tmp_data @@ -68,52 +84,66 @@ def paraStyle(): def protocolos(lst_protocolos): """Gera o codigo rml do conteudo da pesquisa de protocolos""" - tmp_data = '' + tmp_data = "" # inicio do bloco que contem os flowables - tmp_data += '\t\n' + tmp_data += "\t\n" for dic in lst_protocolos: # espaco inicial tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' + tmp_data += "\t\t\n" # condicao para a quebra de pagina tmp_data += '\t\t\n' # protocolos - if dic['titulo'] != None: - tmp_data += '\t\tProtocolo ' + \ - dic['titulo'] + '\n' + if dic["titulo"] != None: + tmp_data += '\t\tProtocolo ' + dic["titulo"] + "\n" tmp_data += '\t\t\n' tmp_data += '\t\t\t \n' - tmp_data += '\t\t\n' - if dic['txt_assunto'] != None: - txt_assunto = dic['txt_assunto'].replace('&', '&') - tmp_data += '\t\t' + txt_assunto + '\n' - if dic['txt_interessado'] != None: - tmp_data += '\t\tInteressado: ' + \ - dic['txt_interessado'] + '\n' - elif dic['nom_autor'] != None: - tmp_data += '\t\tAutor: ' + \ - dic['nom_autor'] + '\n' - if dic['natureza'] != None: - tmp_data += '\t\tNatureza Processo: ' + \ - dic['natureza'] + '\n' - if dic['processo'] != None: - tmp_data += '\t\tClassificação: ' + \ - dic['processo'] + '\n' - if dic['data'] != None: - tmp_data += '\t\tData Protocolo: ' + \ - dic['data'] + '\n' - if dic['anulado'] != "": - tmp_data += '\t\t** PROTOCOLO ANULADO ** ' '\n' - - tmp_data += '\t\n' + tmp_data += "\t\t\n" + if dic["txt_assunto"] != None: + txt_assunto = dic["txt_assunto"].replace("&", "&") + tmp_data += '\t\t' + txt_assunto + "\n" + if dic["txt_interessado"] != None: + tmp_data += ( + '\t\tInteressado: ' + + dic["txt_interessado"] + + "\n" + ) + elif dic["nom_autor"] != None: + tmp_data += ( + '\t\tAutor: ' + dic["nom_autor"] + "\n" + ) + if dic["natureza"] != None: + tmp_data += ( + '\t\tNatureza Processo: ' + + dic["natureza"] + + "\n" + ) + if dic["processo"] != None: + tmp_data += ( + '\t\tClassificação: ' + + dic["processo"] + + "\n" + ) + if dic["data"] != None: + tmp_data += ( + '\t\tData Protocolo: ' + + dic["data"] + + "\n" + ) + if dic["anulado"] != "": + tmp_data += ( + '\t\t** PROTOCOLO ANULADO ** ' "\n" + ) + + tmp_data += "\t\n" return tmp_data @@ -122,26 +152,29 @@ def principal(imagem, lst_protocolos, dic_cabecalho, lst_rodape): arquivoPdf = str(int(time.time() * 100)) + ".pdf" - tmp_data = '' + tmp_data = "" tmp_data += '\n' tmp_data += '\n' tmp_data += '\n' tmp_data += '\t\n' + tmp_data += "\t\t\t\n" + tmp_data += ( + '\t\t\t\n' + ) + tmp_data += "\t\t\n" + tmp_data += "\t\n" tmp_data += paraStyle() tmp_data += protocolos(lst_protocolos) - tmp_data += '\n' + tmp_data += "\n" tmp_pdf = parseString(tmp_data) return tmp_pdf + # if hasattr(context.temp_folder,arquivoPdf): # context.temp_folder.manage_delObjects(ids=arquivoPdf) # context.temp_folder.manage_addFile(arquivoPdf) diff --git a/sapl/relatorios/templates/pdf_protocolo_preparar_pysc.py b/sapl/relatorios/templates/pdf_protocolo_preparar_pysc.py index 4a1593184..2ea9e63dc 100755 --- a/sapl/relatorios/templates/pdf_protocolo_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_protocolo_preparar_pysc.py @@ -4,15 +4,14 @@ request = context.REQUEST response = request.RESPONSE session = request.SESSION -data = DateTime().strftime('%d/%m/%Y') +data = DateTime().strftime("%d/%m/%Y") # Abaixo é gerada a string para o rodapé da página casa = {} aux = context.sapl_documentos.props_sapl.propertyItems() for item in aux: casa[item[0]] = item[1] -localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) +localidade = context.zsql.localidade_obter_zsql(cod_localidade=casa["cod_localidade"]) if len(casa["num_cep"]) == 8: cep = casa["num_cep"][:4] + "-" + casa["num_cep"][5:] else: @@ -24,8 +23,7 @@ if cep != "": linha1 = linha1 + " - " linha1 = linha1 + "CEP " + cep if localidade[0].nom_localidade != "" and localidade[0].nom_localidade != None: - linha1 = linha1 + " - " + \ - localidade[0].nom_localidade + " " + localidade[0].sgl_uf + linha1 = linha1 + " - " + localidade[0].nom_localidade + " " + localidade[0].sgl_uf if casa["num_tel"] != "" and casa["num_tel"] != None: linha1 = linha1 + " Tel.: " + casa["num_tel"] @@ -49,8 +47,8 @@ cabecalho["nom_casa"] = casa["nom_casa"] cabecalho["nom_estado"] = "Estado de " + nom_estado # tenta buscar o logotipo da casa LOGO_CASA -if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl['logo_casa.gif'].absolute_url() +if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -58,69 +56,79 @@ else: protocolos = [] REQUEST = context.REQUEST -for protocolo in context.zsql.protocolo_pesquisar_zsql(tip_protocolo=REQUEST['rad_tip_protocolo'], - cod_protocolo=REQUEST['txt_num_protocolo'], ano_protocolo=REQUEST[ - 'txt_ano_protocolo'], - tip_documento=REQUEST['lst_tip_documento'], tip_processo=REQUEST[ - 'rad_tip_processo'], - tip_materia=REQUEST[ - 'lst_tip_materia'], des_assunto=REQUEST['txt_assunto'], - cod_autor=REQUEST['hdn_cod_autor'], des_interessado=REQUEST[ - 'txa_txt_interessado'], - dat_apres=REQUEST['dt_apres'], dat_apres2=REQUEST['dt_apres2']): +for protocolo in context.zsql.protocolo_pesquisar_zsql( + tip_protocolo=REQUEST["rad_tip_protocolo"], + cod_protocolo=REQUEST["txt_num_protocolo"], + ano_protocolo=REQUEST["txt_ano_protocolo"], + tip_documento=REQUEST["lst_tip_documento"], + tip_processo=REQUEST["rad_tip_processo"], + tip_materia=REQUEST["lst_tip_materia"], + des_assunto=REQUEST["txt_assunto"], + cod_autor=REQUEST["hdn_cod_autor"], + des_interessado=REQUEST["txa_txt_interessado"], + dat_apres=REQUEST["dt_apres"], + dat_apres2=REQUEST["dt_apres2"], +): dic = {} - dic['titulo'] = str(protocolo.cod_protocolo) + '/' + \ - str(protocolo.ano_protocolo) + dic["titulo"] = str(protocolo.cod_protocolo) + "/" + str(protocolo.ano_protocolo) - dic['data'] = context.pysc.iso_to_port_pysc( - protocolo.dat_protocolo) + ' - Horário:' + protocolo.hor_protocolo + dic["data"] = ( + context.pysc.iso_to_port_pysc(protocolo.dat_protocolo) + + " - Horário:" + + protocolo.hor_protocolo + ) - dic['txt_assunto'] = protocolo.txt_assunto_ementa + dic["txt_assunto"] = protocolo.txt_assunto_ementa - dic['txt_interessado'] = protocolo.txt_interessado + dic["txt_interessado"] = protocolo.txt_interessado - dic['nom_autor'] = " " + dic["nom_autor"] = " " if protocolo.cod_autor != None: for autor in context.zsql.autor_obter_zsql(cod_autor=protocolo.cod_autor): - if autor.des_tipo_autor == 'Parlamentar': - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=autor.cod_parlamentar): - dic['nom_autor'] = parlamentar.nom_completo - elif autor.des_tipo_autor == 'Comissao': - for comissao in context.zsql.comissao_obter_zsql(cod_comissao=autor.cod_comissao): - dic['nom_autor'] = comissao.nom_comissao + if autor.des_tipo_autor == "Parlamentar": + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=autor.cod_parlamentar + ): + dic["nom_autor"] = parlamentar.nom_completo + elif autor.des_tipo_autor == "Comissao": + for comissao in context.zsql.comissao_obter_zsql( + cod_comissao=autor.cod_comissao + ): + dic["nom_autor"] = comissao.nom_comissao else: - dic['nom_autor'] = autor.nom_autor + dic["nom_autor"] = autor.nom_autor - dic['natureza'] = '' + dic["natureza"] = "" if protocolo.tip_processo == 0: - dic['natureza'] = 'Administrativo' + dic["natureza"] = "Administrativo" if protocolo.tip_processo == 1: - dic['natureza'] = 'Legislativo' + dic["natureza"] = "Legislativo" - dic['processo'] = protocolo.des_tipo_materia or protocolo.des_tipo_documento + dic["processo"] = protocolo.des_tipo_materia or protocolo.des_tipo_documento - dic['anulado'] = '' + dic["anulado"] = "" if protocolo.ind_anulado == 1: - dic['anulado'] = 'Nulo' + dic["anulado"] = "Nulo" protocolos.append(dic) filtro = {} # Dicionário que conterá os dados do filtro # Atribuições diretas do REQUEST -filtro['numero'] = REQUEST.txt_num_protocolo -filtro['ano'] = REQUEST.txt_ano_protocolo -filtro['tipo_protocolo'] = REQUEST.rad_tip_protocolo -filtro['tipo_processo'] = REQUEST.rad_tip_processo -filtro['assunto'] = REQUEST.txt_assunto -filtro['autor'] = REQUEST.hdn_cod_autor -filtro['interessado'] = REQUEST.txa_txt_interessado +filtro["numero"] = REQUEST.txt_num_protocolo +filtro["ano"] = REQUEST.txt_ano_protocolo +filtro["tipo_protocolo"] = REQUEST.rad_tip_protocolo +filtro["tipo_processo"] = REQUEST.rad_tip_processo +filtro["assunto"] = REQUEST.txt_assunto +filtro["autor"] = REQUEST.hdn_cod_autor +filtro["interessado"] = REQUEST.txa_txt_interessado sessao = session.id caminho = context.pdf_protocolo_gerar( - sessao, imagem, data, protocolos, cabecalho, rodape, filtro) -if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + sessao, imagem, data, protocolos, cabecalho, rodape, filtro +) +if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py index 5d3f259b0..2f0b52db6 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_gerar.py @@ -4,9 +4,10 @@ Atualizado por Luciano De Fázio - 22/03/2012 versão: 1.0 """ +import logging import os import time -import logging + from django.template.defaultfilters import safe from django.utils.html import strip_tags from trml2pdf import parseString @@ -15,47 +16,67 @@ from sapl.sessao.models import ResumoOrdenacao def cabecalho(inf_basicas_dic, imagem): - """ - """ - tmp = '' - + """ """ + tmp = "" + if os.path.isfile(imagem): - tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t2cm 25.4cm 19cm 25.4cm\n' + tmp += ( + '\t\t\t\t\n' + ) + tmp += "\t\t\t\t2cm 25.4cm 19cm 25.4cm\n" tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t' + \ - str(inf_basicas_dic["nom_camara"]) + '\n' + tmp += ( + '\t\t\t\t' + + str(inf_basicas_dic["nom_camara"]) + + "\n" + ) tmp += '\t\t\t\t\n' tmp += '\t\t\t\tSistema de Apoio ao Processo Legislativo\n' tmp += '\t\t\t\t\n' - tmp += '\t\t\t\tResumo da ' + str(inf_basicas_dic['num_sessao_plen']) + 'ª Reunião ' + str(inf_basicas_dic['nom_sessao']) + ' da ' + str( - inf_basicas_dic['num_sessao_leg']) + 'ª Sessão Legislativa da \n' - tmp += '\t\t\t\t' + \ - str(inf_basicas_dic['num_legislatura']) + \ - ' Legislatura \n' + tmp += ( + '\t\t\t\tResumo da ' + + str(inf_basicas_dic["num_sessao_plen"]) + + "ª Reunião " + + str(inf_basicas_dic["nom_sessao"]) + + " da " + + str(inf_basicas_dic["num_sessao_leg"]) + + "ª Sessão Legislativa da \n" + ) + tmp += ( + '\t\t\t\t' + + str(inf_basicas_dic["num_legislatura"]) + + " Legislatura \n" + ) return tmp def rodape(rodape_dic): - tmp = '' - tmp += '\t\t\t\t2cm 3.2cm 19cm 3.2cm\n' + tmp = "" + tmp += "\t\t\t\t2cm 3.2cm 19cm 3.2cm\n" tmp += '\t\t\t\t\n' - tmp += '\t\t\t\t' + \ - rodape_dic[2] + '\n' - tmp += '\t\t\t\tPágina \n' - tmp += '\t\t\t\t' + \ - rodape_dic[0] + '\n' - tmp += '\t\t\t\t' + \ - rodape_dic[1] + '\n' + tmp += '\t\t\t\t' + rodape_dic[2] + "\n" + tmp += ( + '\t\t\t\tPágina \n' + ) + tmp += ( + '\t\t\t\t' + + rodape_dic[0] + + "\n" + ) + tmp += ( + '\t\t\t\t' + + rodape_dic[1] + + "\n" + ) return tmp def paraStyle(): - """ - """ - tmp = '' - tmp += '\t\n' + """ """ + tmp = "" + tmp += "\t\n" tmp += '\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' @@ -63,12 +84,12 @@ def paraStyle(): tmp += '\t\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' - tmp += '\t\t\t\n' + tmp += "\t\t\t\n" tmp += '\t\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\t\t\n' tmp += '\t\t\t\n' @@ -76,16 +97,16 @@ def paraStyle(): tmp += '\t\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\t\t\n' tmp += '\t\t\t\n' tmp += '\t\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\t\t\t\n' - tmp += '\t\t\n' + tmp += "\t\t\n" tmp += '\t\t\n' tmp += '\t\t\n' tmp += '\t\t\n' @@ -93,16 +114,15 @@ def paraStyle(): tmp += '\t\t\n' tmp += '\t\t\n' tmp += '\t\t\n' - tmp += '\t\n' + tmp += "\t\n" return tmp def inf_basicas(inf_basicas_dic): - """ - """ + """ """ tmp = "" - nom_sessao = inf_basicas_dic['nom_sessao'] + nom_sessao = inf_basicas_dic["nom_sessao"] # num_sessao_plen = inf_basicas_dic["num_sessao_plen"] # num_sessao_leg = inf_basicas_dic["num_sessao_leg"] # num_legislatura = inf_basicas_dic["num_legislatura"] @@ -111,351 +131,510 @@ def inf_basicas(inf_basicas_dic): dat_fim_sessao = inf_basicas_dic["dat_fim_sessao"] hr_fim_sessao = inf_basicas_dic["hr_fim_sessao"] if hr_fim_sessao is None: - hr_fim_sessao = '' - - if nom_sessao or dat_inicio_sessao or hr_inicio_sessao \ - or dat_fim_sessao or hr_fim_sessao: + hr_fim_sessao = "" + + if ( + nom_sessao + or dat_inicio_sessao + or hr_inicio_sessao + or dat_fim_sessao + or hr_fim_sessao + ): tmp += '\t\tInformações Básicas\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" if nom_sessao: - tmp += '\t\tTipo da Sessão: ' + \ - nom_sessao + '\n' + tmp += ( + '\t\tTipo da Sessão: ' + + nom_sessao + + "\n" + ) if hr_inicio_sessao: - tmp += '\t\tAbertura: ' + \ - dat_inicio_sessao + ' - ' + hr_inicio_sessao + '\n' + tmp += ( + '\t\tAbertura: ' + + dat_inicio_sessao + + " - " + + hr_inicio_sessao + + "\n" + ) if dat_fim_sessao or hr_fim_sessao: - tmp += '\t\tEncerramento: ' + \ - dat_fim_sessao + ' - ' + hr_fim_sessao + '\n' - if inf_basicas_dic.get('tema_solene'): - tmp += '\t\tTema da Sessão Solene: ' + \ - inf_basicas_dic['tema_solene'] + '\n' + tmp += ( + '\t\tEncerramento: ' + + dat_fim_sessao + + " - " + + hr_fim_sessao + + "\n" + ) + if inf_basicas_dic.get("tema_solene"): + tmp += ( + '\t\tTema da Sessão Solene: ' + + inf_basicas_dic["tema_solene"] + + "\n" + ) return tmp def multimidia(cont_mult_dic): - """ - """ + """ """ tmp = "" - - mul_audio = cont_mult_dic['multimidia_audio'] - mul_video = cont_mult_dic['multimidia_video'] + + mul_audio = cont_mult_dic["multimidia_audio"] + mul_video = cont_mult_dic["multimidia_video"] if mul_audio or mul_video: tmp += '\t\tConteúdo Multimídia\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" if mul_audio: - tmp += '\t\tAudio: ' + mul_audio + '\n' + tmp += ( + '\t\tAudio: ' + + mul_audio + + "\n" + ) if mul_video: - tmp += '\t\tVideo: ' + mul_video + '\n' + tmp += ( + '\t\tVideo: ' + + mul_video + + "\n" + ) return tmp def mesa(lst_mesa): - tmp = '' + tmp = "" if lst_mesa: tmp += '\t\tMesa Diretora\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" for mesa in lst_mesa: - tmp += '\t\t' + \ - str(mesa['des_cargo']) + ': ' + str(mesa['nom_parlamentar'] - ) + '/' + str(mesa['sgl_partido']) + '\n' + tmp += ( + '\t\t' + + str(mesa["des_cargo"]) + + ": " + + str(mesa["nom_parlamentar"]) + + "/" + + str(mesa["sgl_partido"]) + + "\n" + ) return tmp def presenca(lst_presenca_sessao, lst_ausencia_sessao): - tmp = '' + tmp = "" if lst_presenca_sessao or lst_ausencia_sessao: if lst_ausencia_sessao: tmp += '\t\tLista de Presença da Sessão\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" for presenca in lst_presenca_sessao: - tmp += '\t\t' + \ - str(presenca['nom_parlamentar']) + '/' + \ - str(presenca['sgl_partido']) + '\n' + tmp += ( + '\t\t' + + str(presenca["nom_parlamentar"]) + + "/" + + str(presenca["sgl_partido"]) + + "\n" + ) if lst_ausencia_sessao: tmp += '\t\tJustificativas de Ausência da Sessão\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" tmp += '\n' - tmp += 'ParlamentarJustificativaAusente em\n' + tmp += "ParlamentarJustificativaAusente em\n" for ausencia in lst_ausencia_sessao: - tmp += '' + \ - str(ausencia['parlamentar']) + ' ' + \ - str(ausencia['justificativa']) + '' + \ - str(ausencia['tipo']) + '\n' - tmp += '' + tmp += ( + "" + + str(ausencia["parlamentar"]) + + " " + + str(ausencia["justificativa"]) + + "" + + str(ausencia["tipo"]) + + "\n" + ) + tmp += "" return tmp def expedientes(lst_expedientes): - tmp = '' + tmp = "" if lst_expedientes: tmp += '\t\tExpedientes\n' tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" for expediente in lst_expedientes: - if expediente['txt_expediente']: - tmp += '\t\t' + '
        ' + \ - expediente['nom_expediente'] + ':
        \n' + \ - '' + \ - expediente['txt_expediente'] + '\n' + if expediente["txt_expediente"]: + tmp += ( + '\t\t' + + "
        " + + expediente["nom_expediente"] + + ":
        \n" + + '' + + expediente["txt_expediente"] + + "\n" + ) tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" return tmp def expediente_materia(lst_expediente_materia): - tmp = '' + tmp = "" if lst_expediente_materia: tmp += '\t\tMatérias do Expediente\n\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" tmp += '>\n' - tmp += 'MatériaEmentaResultado da Votação\n' + tmp += ( + "MatériaEmentaResultado da Votação\n" + ) for expediente_materia in lst_expediente_materia: - tmp += '' + str(expediente_materia['num_ordem']) + ' - ' + expediente_materia['id_materia'] + '\n' + 'Turno: ' + expediente_materia[ - 'des_turno'] + '\n' + '' + expediente_materia['num_autores'] + ': ' + str(expediente_materia['nom_autor']) + '\n' - - txt_ementa = expediente_materia['txt_ementa'].replace('&', '&') - + tmp += ( + '' + + str(expediente_materia["num_ordem"]) + + " - " + + expediente_materia["id_materia"] + + "\n" + + 'Turno: ' + + expediente_materia["des_turno"] + + "\n" + + '' + + expediente_materia["num_autores"] + + ": " + + str(expediente_materia["nom_autor"]) + + "\n" + ) + + txt_ementa = expediente_materia["txt_ementa"].replace("&", "&") + # txt_ementa = dont_break_out(expediente_materia['txt_ementa']) - + # if len(txt_ementa) > 800: # txt_ementa = txt_ementa[:800] + "..." - tmp += '' + txt_ementa + '' + '' + expediente_materia['ordem_observacao'] + '\n' - tmp += '' + \ - str(expediente_materia['nom_resultado']) + \ - '\n' + '' - if expediente_materia['votacao_observacao'] != txt_ementa: - tmp += str(expediente_materia['votacao_observacao']) + tmp += ( + '' + + txt_ementa + + "" + + '' + + expediente_materia["ordem_observacao"] + + "\n" + ) + tmp += ( + '' + + str(expediente_materia["nom_resultado"]) + + "\n" + + '' + ) + if expediente_materia["votacao_observacao"] != txt_ementa: + tmp += str(expediente_materia["votacao_observacao"]) else: - tmp += ' ' - tmp += '\n' + tmp += " " + tmp += "\n" - tmp += '\t\t\n' + tmp += "\t\t\n" return tmp def expediente_materia_vot_nom(lst_expediente_materia_vot_nom): - tmp = '' + tmp = "" if lst_expediente_materia_vot_nom: - tmp += '\t\tVotações Nominais - Matérias do Expediente\n\n' + tmp += ( + '\t\tVotações Nominais - Matérias do Expediente\n\n' + ) tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" tmp += '\n' - tmp += 'MatériaVotos\n' + tmp += "MatériaVotos\n" for expediente_materia_vot_nom in lst_expediente_materia_vot_nom: - tmp += '' + str(expediente_materia_vot_nom['titulo']) + '' - if expediente_materia_vot_nom['votos']: - tmp += '' - for v in expediente_materia_vot_nom['votos']: - tmp += '' + str(v.parlamentar) + ' - ' + v.voto + '' - tmp += '' - else: + tmp += ( + '' + + str(expediente_materia_vot_nom["titulo"]) + + "" + ) + if expediente_materia_vot_nom["votos"]: + tmp += "" + for v in expediente_materia_vot_nom["votos"]: + tmp += ( + '' + + str(v.parlamentar) + + " - " + + v.voto + + "" + ) + tmp += "" + else: tmp += 'Matéria não votada' - tmp += '\n' - tmp += '\t\t\n' + tmp += "\n" + tmp += "\t\t\n" return tmp def oradores_expediente(lst_oradores_expediente): - tmp = '' + tmp = "" if lst_oradores_expediente: tmp += '\t\tOradores do Expediente\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" for orador_expediente in lst_oradores_expediente: - tmp += '\t\t' + str(orador_expediente[ - 'num_ordem']) + ' - ' + orador_expediente[ - 'nom_parlamentar'] + '/' + str(orador_expediente[ - 'sgl_partido']) + ' - ' + str(orador_expediente[ - 'observacao']) + '\n' + tmp += ( + '\t\t' + + str(orador_expediente["num_ordem"]) + + " - " + + orador_expediente["nom_parlamentar"] + + "/" + + str(orador_expediente["sgl_partido"]) + + " - " + + str(orador_expediente["observacao"]) + + "\n" + ) return tmp def presenca_ordem_dia(lst_presenca_ordem_dia): - tmp = '' + tmp = "" if lst_presenca_ordem_dia: tmp += '\t\tLista de Presença da Ordem do Dia\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" for presenca_ordem_dia in lst_presenca_ordem_dia: - tmp += '\t\t' + \ - str(presenca_ordem_dia['nom_parlamentar']) + '/' + \ - str(presenca_ordem_dia['sgl_partido']) + '\n' + tmp += ( + '\t\t' + + str(presenca_ordem_dia["nom_parlamentar"]) + + "/" + + str(presenca_ordem_dia["sgl_partido"]) + + "\n" + ) return tmp def votacao(lst_votacao): - tmp = '' + tmp = "" if lst_votacao: tmp += 'Matérias da Ordem do Dia\n\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" tmp += '\n' - tmp += 'MatériaEmentaResultado da Votação\n' + tmp += ( + "MatériaEmentaResultado da Votação\n" + ) for votacao in lst_votacao: - tmp += '' + str(votacao['num_ordem']) + ' - ' + votacao['id_materia'] + '\n' + 'Turno: ' + votacao[ - 'des_turno'] + '\n' + '' + votacao['num_autores'] + ': ' + str(votacao['nom_autor']) + '\n' - txt_ementa = votacao['txt_ementa'].replace('&', '&') + tmp += ( + '' + + str(votacao["num_ordem"]) + + " - " + + votacao["id_materia"] + + "\n" + + 'Turno: ' + + votacao["des_turno"] + + "\n" + + '' + + votacao["num_autores"] + + ": " + + str(votacao["nom_autor"]) + + "\n" + ) + txt_ementa = votacao["txt_ementa"].replace("&", "&") if len(txt_ementa) > 1000: txt_ementa = txt_ementa[:1000] + "..." - tmp += '' + txt_ementa + '' + '' + votacao['ordem_observacao'] + '\n' - tmp += '' + \ - str(votacao['nom_resultado']) + \ - '\n' + '' - if votacao['votacao_observacao'] != txt_ementa: - tmp += str(votacao['votacao_observacao']) + tmp += ( + '' + + txt_ementa + + "" + + '' + + votacao["ordem_observacao"] + + "\n" + ) + tmp += ( + '' + + str(votacao["nom_resultado"]) + + "\n" + + '' + ) + if votacao["votacao_observacao"] != txt_ementa: + tmp += str(votacao["votacao_observacao"]) else: - tmp += ' ' - tmp += '\n' - tmp += '\t\t\n' + tmp += " " + tmp += "\n" + tmp += "\t\t\n" return tmp def votacao_vot_nom(lst_votacao_vot_nom): - tmp = '' + tmp = "" if lst_votacao_vot_nom: tmp += '\t\tVotações Nominais - Matérias da Ordem do Dia\n\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" tmp += '\n' - tmp += 'MatériaVotos\n' + tmp += "MatériaVotos\n" for votacao_vot_nom in lst_votacao_vot_nom: - tmp += '' + str(votacao_vot_nom['titulo']) + '' - if votacao_vot_nom['votos']: - tmp += '' - for v in votacao_vot_nom['votos']: - tmp += '' + str(v.parlamentar) + ' - ' + v.voto + '' - tmp += '' - else: + tmp += ( + '' + + str(votacao_vot_nom["titulo"]) + + "" + ) + if votacao_vot_nom["votos"]: + tmp += "" + for v in votacao_vot_nom["votos"]: + tmp += ( + '' + + str(v.parlamentar) + + " - " + + v.voto + + "" + ) + tmp += "" + else: tmp += 'Matéria não votada' - tmp += '\n' - tmp += '\t\t\n' + tmp += "\n" + tmp += "\t\t\n" return tmp def oradores_ordemdia(lst_oradores_ordemdia): - tmp = '' + tmp = "" if lst_oradores_ordemdia: tmp += '\t\tOradores da Ordem do Dia\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" for orador_ordemdia in lst_oradores_ordemdia: - tmp += '\t\t' + \ - str(orador_ordemdia['num_ordem']) + ' - ' + \ - orador_ordemdia['nome_parlamentar'] + '/' + \ - str(orador_ordemdia['sigla']) + ' - ' + \ - str(orador_ordemdia['observacao']) + '\n' + tmp += ( + '\t\t' + + str(orador_ordemdia["num_ordem"]) + + " - " + + orador_ordemdia["nome_parlamentar"] + + "/" + + str(orador_ordemdia["sigla"]) + + " - " + + str(orador_ordemdia["observacao"]) + + "\n" + ) return tmp def oradores(lst_oradores): - tmp = '' + tmp = "" if lst_oradores: tmp += '\t\tOradores das Explicações Pessoais\n' tmp += '\t\t\n' tmp += '\t\t\t
        \n' - tmp += '\t\t
        \n' + tmp += "\t\t\n" for orador in lst_oradores: - tmp += '\t\t' + \ - str(orador['num_ordem']) + ' - ' + orador['nom_parlamentar'] + \ - '/' + str(orador['sgl_partido']) + '\n' + tmp += ( + '\t\t' + + str(orador["num_ordem"]) + + " - " + + orador["nom_parlamentar"] + + "/" + + str(orador["sgl_partido"]) + + "\n" + ) return tmp def ocorrencias(lst_ocorrencias): - tmp = '' + tmp = "" if lst_ocorrencias: tmp += '\t\tOcorrências da Sessão\n' tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" for ocorrencia in lst_ocorrencias: - tmp += '\t\t' + \ - str(ocorrencia.conteudo) + '\n' + tmp += '\t\t' + str(ocorrencia.conteudo) + "\n" tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" return tmp + def consideracoes(lst_consideracoes): - tmp = '' + tmp = "" if lst_consideracoes: tmp += '\t\tConsideracoes Finais\n' tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" for consideracoes in lst_consideracoes: - tmp += '\t\t' + \ - str(consideracoes.conteudo) + '\n' + tmp += '\t\t' + str(consideracoes.conteudo) + "\n" tmp += '\t\t\n' tmp += '\t\t\t \n' - tmp += '\t\t\n' + tmp += "\t\t\n" return tmp -def principal(rodape_dic, imagem, inf_basicas_dic, cont_mult_dic, lst_mesa, lst_presenca_sessao, lst_ausencia_sessao, lst_expedientes, lst_expediente_materia, lst_expediente_materia_vot_nom, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_votacao_vot_nom, lst_oradores_ordemdia, lst_oradores, lst_ocorrencias, lst_consideracoes): - """ - """ +def principal( + rodape_dic, + imagem, + inf_basicas_dic, + cont_mult_dic, + lst_mesa, + lst_presenca_sessao, + lst_ausencia_sessao, + lst_expedientes, + lst_expediente_materia, + lst_expediente_materia_vot_nom, + lst_oradores_expediente, + lst_presenca_ordem_dia, + lst_votacao, + lst_votacao_vot_nom, + lst_oradores_ordemdia, + lst_oradores, + lst_ocorrencias, + lst_consideracoes, +): + """ """ arquivoPdf = str(int(time.time() * 100)) + ".pdf" logger = logging.getLogger(__name__) - tmp = '' + tmp = "" tmp += '\n' tmp += '\n' tmp += '\n' tmp += '\t\n' + tmp += "\t\t\n" + tmp += "\t\n" tmp += paraStyle() - tmp += '\t\n' + tmp += "\t\n" ordenacao = ResumoOrdenacao.objects.first() dict_ord_template = { - 'cont_mult': multimidia(cont_mult_dic), - 'exp': expedientes(lst_expedientes), - 'id_basica': inf_basicas(inf_basicas_dic), - 'lista_p': presenca(lst_presenca_sessao, lst_ausencia_sessao), - 'lista_p_o_d': presenca_ordem_dia(lst_presenca_ordem_dia), - 'mat_exp': expediente_materia(lst_expediente_materia), - 'v_n_mat_exp': expediente_materia_vot_nom(lst_expediente_materia_vot_nom), - 'mat_o_d': votacao(lst_votacao), - 'v_n_mat_o_d': votacao_vot_nom(lst_votacao_vot_nom), - 'mesa_d': mesa(lst_mesa), - 'oradores_exped': oradores_expediente(lst_oradores_expediente), - 'oradores_o_d': oradores_ordemdia(lst_oradores_ordemdia), - 'oradores_expli': oradores(lst_oradores), - 'ocorr_sessao': ocorrencias(lst_ocorrencias), - 'cons_finais': consideracoes(lst_consideracoes) + "cont_mult": multimidia(cont_mult_dic), + "exp": expedientes(lst_expedientes), + "id_basica": inf_basicas(inf_basicas_dic), + "lista_p": presenca(lst_presenca_sessao, lst_ausencia_sessao), + "lista_p_o_d": presenca_ordem_dia(lst_presenca_ordem_dia), + "mat_exp": expediente_materia(lst_expediente_materia), + "v_n_mat_exp": expediente_materia_vot_nom(lst_expediente_materia_vot_nom), + "mat_o_d": votacao(lst_votacao), + "v_n_mat_o_d": votacao_vot_nom(lst_votacao_vot_nom), + "mesa_d": mesa(lst_mesa), + "oradores_exped": oradores_expediente(lst_oradores_expediente), + "oradores_o_d": oradores_ordemdia(lst_oradores_ordemdia), + "oradores_expli": oradores(lst_oradores), + "ocorr_sessao": ocorrencias(lst_ocorrencias), + "cons_finais": consideracoes(lst_consideracoes), } - + if ordenacao: try: tmp += dict_ord_template[ordenacao.primeiro] @@ -474,8 +653,10 @@ def principal(rodape_dic, imagem, inf_basicas_dic, cont_mult_dic, lst_mesa, lst_ tmp += dict_ord_template[ordenacao.decimo_quarto] tmp += dict_ord_template[ordenacao.decimo_quinto] except KeyError as e: - logger.error("KeyError: " + str(e) + ". Erro ao tentar utilizar " - "configuração de ordenação. Utilizando ordenação padrão.") + logger.error( + "KeyError: " + str(e) + ". Erro ao tentar utilizar " + "configuração de ordenação. Utilizando ordenação padrão." + ) tmp += inf_basicas(inf_basicas_dic) tmp += multimidia(cont_mult_dic) tmp += mesa(lst_mesa) @@ -509,11 +690,13 @@ def principal(rodape_dic, imagem, inf_basicas_dic, cont_mult_dic, lst_mesa, lst_ tmp += ocorrencias(lst_ocorrencias) tmp += consideracoes(lst_consideracoes) - tmp += '\t\n' - tmp += '\n' + tmp += "\t\n" + tmp += "\n" tmp_pdf = parseString(tmp) return tmp_pdf + + # if hasattr(context.temp_folder,arquivoPdf): # context.temp_folder.manage_delObjects(ids=arquivoPdf) # context.temp_folder.manage_addFile(arquivoPdf) diff --git a/sapl/relatorios/templates/pdf_sessao_plenaria_preparar_pysc.py b/sapl/relatorios/templates/pdf_sessao_plenaria_preparar_pysc.py index 9315d5429..836461eea 100644 --- a/sapl/relatorios/templates/pdf_sessao_plenaria_preparar_pysc.py +++ b/sapl/relatorios/templates/pdf_sessao_plenaria_preparar_pysc.py @@ -4,19 +4,24 @@ request = context.REQUEST response = request.RESPONSE session = request.SESSION -if context.REQUEST['data'] != '': - dat_inicio_sessao = context.REQUEST['data'] +if context.REQUEST["data"] != "": + dat_inicio_sessao = context.REQUEST["data"] pauta = [] # lista contendo a pauta da ordem do dia a ser impressa # converte data para formato yyyy/mm/dd data = context.pysc.data_converter_pysc(dat_inicio_sessao) - codigo = context.REQUEST['cod_sessao_plen'] + codigo = context.REQUEST["cod_sessao_plen"] # seleciona as matérias que compõem a pauta na data escolhida - for sessao in context.zsql.sessao_plenaria_obter_zsql(dat_inicio_sessao=data, cod_sessao_plen=codigo, ind_excluido=0): - inf_basicas_dic = {} # dicionário que armazenará as informacoes basicas da sessao plenaria + for sessao in context.zsql.sessao_plenaria_obter_zsql( + dat_inicio_sessao=data, cod_sessao_plen=codigo, ind_excluido=0 + ): + inf_basicas_dic = ( + {} + ) # dicionário que armazenará as informacoes basicas da sessao plenaria # seleciona o tipo da sessao plenaria tipo_sessao = context.zsql.tipo_sessao_plenaria_obter_zsql( - tip_sessao=sessao.tip_sessao, ind_excluido=0)[0] + tip_sessao=sessao.tip_sessao, ind_excluido=0 + )[0] inf_basicas_dic["num_sessao_plen"] = sessao.num_sessao_plen inf_basicas_dic["nom_sessao"] = tipo_sessao.nom_sessao inf_basicas_dic["num_legislatura"] = sessao.num_legislatura @@ -28,32 +33,45 @@ if context.REQUEST['data'] != '': # Lista da composicao da mesa diretora lst_mesa = [] - for composicao in context.zsql.composicao_mesa_sessao_obter_zsql(cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0): - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=composicao.cod_parlamentar, ind_excluido=0): - for cargo in context.zsql.cargo_mesa_obter_zsql(cod_cargo=composicao.cod_cargo, ind_excluido=0): + for composicao in context.zsql.composicao_mesa_sessao_obter_zsql( + cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0 + ): + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=composicao.cod_parlamentar, ind_excluido=0 + ): + for cargo in context.zsql.cargo_mesa_obter_zsql( + cod_cargo=composicao.cod_cargo, ind_excluido=0 + ): dic_mesa = {} - dic_mesa['nom_parlamentar'] = parlamentar.nom_parlamentar - dic_mesa['sgl_partido'] = parlamentar.sgl_partido - dic_mesa['des_cargo'] = cargo.des_cargo + dic_mesa["nom_parlamentar"] = parlamentar.nom_parlamentar + dic_mesa["sgl_partido"] = parlamentar.sgl_partido + dic_mesa["des_cargo"] = cargo.des_cargo lst_mesa.append(dic_mesa) # Lista de presença na sessão lst_presenca_sessao = [] - for presenca in context.zsql.presenca_sessao_obter_zsql(cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0): - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=presenca.cod_parlamentar, ind_excluido=0): + for presenca in context.zsql.presenca_sessao_obter_zsql( + cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0 + ): + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=presenca.cod_parlamentar, ind_excluido=0 + ): dic_presenca = {} dic_presenca["nom_parlamentar"] = parlamentar.nom_parlamentar - dic_presenca['sgl_partido'] = parlamentar.sgl_partido + dic_presenca["sgl_partido"] = parlamentar.sgl_partido lst_presenca_sessao.append(dic_presenca) # Exibe os Expedientes lst_expedientes = [] dic_expedientes = None for tip_expediente in context.zsql.tipo_expediente_obter_zsql(): - for expediente in context.zsql.expediente_obter_zsql(cod_sessao_plen=sessao.cod_sessao_plen, cod_expediente=tip_expediente.cod_expediente, ind_excluido=0): + for expediente in context.zsql.expediente_obter_zsql( + cod_sessao_plen=sessao.cod_sessao_plen, + cod_expediente=tip_expediente.cod_expediente, + ind_excluido=0, + ): dic_expedientes = {} - dic_expedientes[ - "nom_expediente"] = tip_expediente.nom_expediente + dic_expedientes["nom_expediente"] = tip_expediente.nom_expediente dic_expedientes["txt_expediente"] = expediente.txt_expediente if dic_expedientes: @@ -61,77 +79,101 @@ if context.REQUEST['data'] != '': # Lista das matérias do Expediente, incluindo o resultado das votacoes lst_expediente_materia = [] - for expediente_materia in context.zsql.votacao_expediente_materia_obter_zsql(dat_ordem=data, cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0): - + for expediente_materia in context.zsql.votacao_expediente_materia_obter_zsql( + dat_ordem=data, cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0 + ): # seleciona os detalhes de uma matéria materia = context.zsql.materia_obter_zsql( - cod_materia=expediente_materia.cod_materia)[0] + cod_materia=expediente_materia.cod_materia + )[0] dic_expediente_materia = {} dic_expediente_materia["num_ordem"] = expediente_materia.num_ordem - dic_expediente_materia["id_materia"] = materia.sgl_tipo_materia + " " + materia.des_tipo_materia + \ - " " + str(materia.num_ident_basica) + "/" + \ - str(materia.ano_ident_basica) + dic_expediente_materia["id_materia"] = ( + materia.sgl_tipo_materia + + " " + + materia.des_tipo_materia + + " " + + str(materia.num_ident_basica) + + "/" + + str(materia.ano_ident_basica) + ) dic_expediente_materia["des_numeracao"] = "" numeracao = context.zsql.numeracao_obter_zsql( - cod_materia=expediente_materia.cod_materia) + cod_materia=expediente_materia.cod_materia + ) if len(numeracao): numeracao = numeracao[0] - dic_expediente_materia["des_numeracao"] = str( - numeracao.num_materia) + "/" + str(numeracao.ano_materia) + dic_expediente_materia["des_numeracao"] = ( + str(numeracao.num_materia) + "/" + str(numeracao.ano_materia) + ) tram = context.zsql.tramitacao_turno_obter_zsql( - cod_materia=materia.cod_materia, dat_inicio_sessao=data) + cod_materia=materia.cod_materia, dat_inicio_sessao=data + ) dic_expediente_materia["des_turno"] = "" if len(tram): tram_turno = tram[0] if tram_turno.sgl_turno != "": - for turno in [("P", "Primeiro"), ("S", "Segundo"), ("U", "Único"), ("L", "Suplementar"), ("A", "Votação Única em Regime de Urgência"), ("B", "1ª Votação"), ("C", "2ª e 3ª Votações"), ("F", "Final")]: + for turno in [ + ("P", "Primeiro"), + ("S", "Segundo"), + ("U", "Único"), + ("L", "Suplementar"), + ("A", "Votação Única em Regime de Urgência"), + ("B", "1ª Votação"), + ("C", "2ª e 3ª Votações"), + ("F", "Final"), + ]: if tram_turno.sgl_turno == turno[0]: dic_expediente_materia["des_turno"] = turno[1] dic_expediente_materia["txt_ementa"] = materia.txt_ementa dic_expediente_materia[ - "ordem_observacao"] = expediente_materia.ordem_observacao + "ordem_observacao" + ] = expediente_materia.ordem_observacao dic_expediente_materia["nom_autor"] = "" autoria = context.zsql.autoria_obter_zsql( - cod_materia=expediente_materia.cod_materia, ind_primeiro_autor=1) + cod_materia=expediente_materia.cod_materia, ind_primeiro_autor=1 + ) if len(autoria) > 0: # se existe autor autoria = autoria[0] - autor = context.zsql.autor_obter_zsql( - cod_autor=autoria.cod_autor) + autor = context.zsql.autor_obter_zsql(cod_autor=autoria.cod_autor) if len(autor) > 0: autor = autor[0] try: if autor.des_tipo_autor == "Parlamentar": parlamentar = context.zsql.parlamentar_obter_zsql( - cod_parlamentar=autor.cod_parlamentar)[0] + cod_parlamentar=autor.cod_parlamentar + )[0] dic_expediente_materia[ - "nom_autor"] = parlamentar.nom_parlamentar + "nom_autor" + ] = parlamentar.nom_parlamentar elif autor.des_tipo_autor == "Comissao": comissao = context.zsql.comissao_obter_zsql( - cod_comissao=autor.cod_comissao)[0] - dic_expediente_materia[ - "nom_autor"] = comissao.nom_comissao + cod_comissao=autor.cod_comissao + )[0] + dic_expediente_materia["nom_autor"] = comissao.nom_comissao elif autor.nom_autor != "": - dic_expediente_materia[ - "nom_autor"] = autor.nom_autor + dic_expediente_materia["nom_autor"] = autor.nom_autor else: - dic_expediente_materia[ - "nom_autor"] = autor.des_tipo_autor + dic_expediente_materia["nom_autor"] = autor.des_tipo_autor except: dic_expediente_materia["nom_autor"] = "NC-em" dic_expediente_materia["votacao_observacao"] = "" if expediente_materia.tip_resultado_votacao: resultado = context.zsql.tipo_resultado_votacao_obter_zsql( - tip_resultado_votacao=expediente_materia.tip_resultado_votacao, ind_excluido=0) + tip_resultado_votacao=expediente_materia.tip_resultado_votacao, + ind_excluido=0, + ) for i in resultado: dic_expediente_materia["nom_resultado"] = i.nom_resultado if expediente_materia.votacao_observacao: dic_expediente_materia[ - "votacao_observacao"] = expediente_materia.votacao_observacao + "votacao_observacao" + ] = expediente_materia.votacao_observacao else: dic_expediente_materia["nom_resultado"] = "Matéria não votada" dic_expediente_materia["votacao_observacao"] = "Vazio" @@ -139,81 +181,107 @@ if context.REQUEST['data'] != '': # Lista dos oradores do Expediente lst_oradores_expediente = [] - for orador_expediente in context.zsql.oradores_expediente_obter_zsql(cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0): - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=orador_expediente.cod_parlamentar, ind_excluido=0): + for orador_expediente in context.zsql.oradores_expediente_obter_zsql( + cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0 + ): + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=orador_expediente.cod_parlamentar, ind_excluido=0 + ): dic_oradores_expediente = {} - dic_oradores_expediente[ - "num_ordem"] = orador_expediente.num_ordem - dic_oradores_expediente[ - "nom_parlamentar"] = parlamentar.nom_parlamentar - dic_oradores_expediente[ - 'sgl_partido'] = parlamentar.sgl_partido + dic_oradores_expediente["num_ordem"] = orador_expediente.num_ordem + dic_oradores_expediente["nom_parlamentar"] = parlamentar.nom_parlamentar + dic_oradores_expediente["sgl_partido"] = parlamentar.sgl_partido lst_oradores_expediente.append(dic_oradores_expediente) # Lista presença na ordem do dia lst_presenca_ordem_dia = [] - for presenca_ordem_dia in context.zsql.presenca_ordem_dia_obter_zsql(cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0): - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=presenca_ordem_dia.cod_parlamentar, ind_excluido=0): + for presenca_ordem_dia in context.zsql.presenca_ordem_dia_obter_zsql( + cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0 + ): + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=presenca_ordem_dia.cod_parlamentar, ind_excluido=0 + ): dic_presenca_ordem_dia = {} - dic_presenca_ordem_dia[ - 'nom_parlamentar'] = parlamentar.nom_parlamentar - dic_presenca_ordem_dia['sgl_partido'] = parlamentar.sgl_partido + dic_presenca_ordem_dia["nom_parlamentar"] = parlamentar.nom_parlamentar + dic_presenca_ordem_dia["sgl_partido"] = parlamentar.sgl_partido lst_presenca_ordem_dia.append(dic_presenca_ordem_dia) # Lista das matérias da Ordem do Dia, incluindo o resultado das # votacoes lst_votacao = [] - for votacao in context.zsql.votacao_ordem_dia_obter_zsql(dat_ordem=data, cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0): - + for votacao in context.zsql.votacao_ordem_dia_obter_zsql( + dat_ordem=data, cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0 + ): # seleciona os detalhes de uma matéria - materia = context.zsql.materia_obter_zsql( - cod_materia=votacao.cod_materia)[0] + materia = context.zsql.materia_obter_zsql(cod_materia=votacao.cod_materia)[ + 0 + ] dic_votacao = {} dic_votacao["num_ordem"] = votacao.num_ordem - dic_votacao["id_materia"] = materia.sgl_tipo_materia + " " + materia.des_tipo_materia + \ - " " + str(materia.num_ident_basica) + "/" + \ - str(materia.ano_ident_basica) + dic_votacao["id_materia"] = ( + materia.sgl_tipo_materia + + " " + + materia.des_tipo_materia + + " " + + str(materia.num_ident_basica) + + "/" + + str(materia.ano_ident_basica) + ) dic_votacao["des_numeracao"] = "" numeracao = context.zsql.numeracao_obter_zsql( - cod_materia=votacao.cod_materia) + cod_materia=votacao.cod_materia + ) if len(numeracao): numeracao = numeracao[0] - dic_votacao["des_numeracao"] = str( - numeracao.num_materia) + "/" + str(numeracao.ano_materia) + dic_votacao["des_numeracao"] = ( + str(numeracao.num_materia) + "/" + str(numeracao.ano_materia) + ) dic_votacao["des_turno"] = "" tramitacao = context.zsql.tramitacao_obter_zsql( - cod_materia=materia.cod_materia, ind_ult_tramitacao=1) + cod_materia=materia.cod_materia, ind_ult_tramitacao=1 + ) if len(tramitacao): tramitacao = tramitacao[0] tram = context.zsql.tramitacao_turno_obter_zsql( - cod_materia=materia.cod_materia, dat_inicio_sessao=data) + cod_materia=materia.cod_materia, dat_inicio_sessao=data + ) if len(tram): tram_turno = tram[0] if tram_turno.sgl_turno != "": - for turno in [("P", "Primeiro"), ("S", "Segundo"), ("U", "Único"), ("L", "Suplementar"), ("F", "Final"), ("A", "Votação Única em Regime de Urgência"), ("B", "1ª Votação"), ("C", "2ª e 3ª Votações")]: + for turno in [ + ("P", "Primeiro"), + ("S", "Segundo"), + ("U", "Único"), + ("L", "Suplementar"), + ("F", "Final"), + ("A", "Votação Única em Regime de Urgência"), + ("B", "1ª Votação"), + ("C", "2ª e 3ª Votações"), + ]: if tram_turno.sgl_turno == turno[0]: dic_votacao["des_turno"] = turno[1] dic_votacao["txt_ementa"] = materia.txt_ementa dic_votacao["ordem_observacao"] = votacao.ordem_observacao dic_votacao["nom_autor"] = "" autoria = context.zsql.autoria_obter_zsql( - cod_materia=votacao.cod_materia, ind_primeiro_autor=1) + cod_materia=votacao.cod_materia, ind_primeiro_autor=1 + ) if len(autoria) > 0: # se existe autor autoria = autoria[0] - autor = context.zsql.autor_obter_zsql( - cod_autor=autoria.cod_autor) + autor = context.zsql.autor_obter_zsql(cod_autor=autoria.cod_autor) if len(autor) > 0: autor = autor[0] try: if autor.des_tipo_autor == "Parlamentar": parlamentar = context.zsql.parlamentar_obter_zsql( - cod_parlamentar=autor.cod_parlamentar)[0] - dic_votacao[ - "nom_autor"] = parlamentar.nom_parlamentar + cod_parlamentar=autor.cod_parlamentar + )[0] + dic_votacao["nom_autor"] = parlamentar.nom_parlamentar elif autor.des_tipo_autor == "Comissao": comissao = context.zsql.comissao_obter_zsql( - cod_comissao=autor.cod_comissao)[0] + cod_comissao=autor.cod_comissao + )[0] dic_votacao["nom_autor"] = comissao.nom_comissao elif autor.nom_autor != "": dic_votacao["nom_autor"] = autor.nom_autor @@ -225,12 +293,12 @@ if context.REQUEST['data'] != '': dic_votacao["votacao_observacao"] = "" if votacao.tip_resultado_votacao: resultado = context.zsql.tipo_resultado_votacao_obter_zsql( - tip_resultado_votacao=votacao.tip_resultado_votacao, ind_excluido=0) + tip_resultado_votacao=votacao.tip_resultado_votacao, ind_excluido=0 + ) for i in resultado: dic_votacao["nom_resultado"] = i.nom_resultado if votacao.votacao_observacao: - dic_votacao[ - "votacao_observacao"] = votacao.votacao_observacao + dic_votacao["votacao_observacao"] = votacao.votacao_observacao else: dic_votacao["nom_resultado"] = "Matéria não votada" dic_votacao["votacao_observacao"] = "Vazio" @@ -238,12 +306,16 @@ if context.REQUEST['data'] != '': # Lista dos oradores nas Explicações Pessoais lst_oradores = [] - for orador in context.zsql.oradores_obter_zsql(cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0): - for parlamentar in context.zsql.parlamentar_obter_zsql(cod_parlamentar=orador.cod_parlamentar, ind_excluido=0): + for orador in context.zsql.oradores_obter_zsql( + cod_sessao_plen=sessao.cod_sessao_plen, ind_excluido=0 + ): + for parlamentar in context.zsql.parlamentar_obter_zsql( + cod_parlamentar=orador.cod_parlamentar, ind_excluido=0 + ): dic_oradores = {} dic_oradores["num_ordem"] = orador.num_ordem dic_oradores["nom_parlamentar"] = parlamentar.nom_parlamentar - dic_oradores['sgl_partido'] = parlamentar.sgl_partido + dic_oradores["sgl_partido"] = parlamentar.sgl_partido lst_oradores.append(dic_oradores) # obtém as propriedades da casa legislativa para montar o cabeçalho e o @@ -251,9 +323,8 @@ if context.REQUEST['data'] != '': cabecalho = {} # tenta buscar o logotipo da casa LOGO_CASA - if hasattr(context.sapl_documentos.props_sapl, 'logo_casa.gif'): - imagem = context.sapl_documentos.props_sapl[ - 'logo_casa.gif'].absolute_url() + if hasattr(context.sapl_documentos.props_sapl, "logo_casa.gif"): + imagem = context.sapl_documentos.props_sapl["logo_casa.gif"].absolute_url() else: imagem = context.imagens.absolute_url() + "/brasao_transp.gif" @@ -263,22 +334,39 @@ if context.REQUEST['data'] != '': for item in aux: casa[item[0]] = item[1] localidade = context.zsql.localidade_obter_zsql( - cod_localidade=casa["cod_localidade"]) + cod_localidade=casa["cod_localidade"] + ) data_emissao = DateTime().strftime("%d/%m/%Y") rodape = casa - rodape['data_emissao'] = data_emissao + rodape["data_emissao"] = data_emissao - inf_basicas_dic['nom_camara'] = casa['nom_casa'] + inf_basicas_dic["nom_camara"] = casa["nom_casa"] REQUEST = context.REQUEST - for local in context.zsql.localidade_obter_zsql(cod_localidade=casa['cod_localidade']): - rodape['nom_localidade'] = " " + local.nom_localidade - rodape['sgl_uf'] = local.sgl_uf + for local in context.zsql.localidade_obter_zsql( + cod_localidade=casa["cod_localidade"] + ): + rodape["nom_localidade"] = " " + local.nom_localidade + rodape["sgl_uf"] = local.sgl_uf -# return lst_votacao + # return lst_votacao sessao = session.id - caminho = context.pdf_sessao_plenaria_gerar(rodape, sessao, imagem, inf_basicas_dic, lst_mesa, lst_presenca_sessao, - lst_expedientes, lst_expediente_materia, lst_oradores_expediente, lst_presenca_ordem_dia, lst_votacao, lst_oradores, lst_ocorrencias, lst_consideracoes) - if caminho == 'aviso': - response.redirect('mensagem_emitir_proc') + caminho = context.pdf_sessao_plenaria_gerar( + rodape, + sessao, + imagem, + inf_basicas_dic, + lst_mesa, + lst_presenca_sessao, + lst_expedientes, + lst_expediente_materia, + lst_oradores_expediente, + lst_presenca_ordem_dia, + lst_votacao, + lst_oradores, + lst_ocorrencias, + lst_consideracoes, + ) + if caminho == "aviso": + response.redirect("mensagem_emitir_proc") else: response.redirect(caminho) diff --git a/sapl/relatorios/urls.py b/sapl/relatorios/urls.py index f6287de8c..1fea63fd2 100644 --- a/sapl/relatorios/urls.py +++ b/sapl/relatorios/urls.py @@ -1,100 +1,146 @@ from django.urls import path +from ..base.views import EstatisticasAcessoNormas from .apps import AppConfig -from .views import (relatorio_capa_processo, +from .views import (RelatorioAtasView, RelatorioAudienciaView, + RelatorioDataFimPrazoTramitacaoView, + RelatorioDocumentosAcessoriosView, + RelatorioHistoricoTramitacaoAdmView, + RelatorioHistoricoTramitacaoView, + RelatorioMateriaAnoAssuntoView, + RelatorioMateriasPorAnoAutorTipoView, + RelatorioMateriasPorAutorView, + RelatorioMateriasTramitacaoView, + RelatorioNormasPorAutorView, + RelatorioNormasPublicadasMesView, + RelatorioNormasVigenciaView, RelatorioPresencaSessaoView, + RelatorioReuniaoView, RelatoriosListView, + etiqueta_materia_legislativa, relatorio_capa_processo, relatorio_documento_administrativo, relatorio_espelho, relatorio_etiqueta_protocolo, relatorio_materia, - relatorio_ordem_dia, relatorio_protocolo, relatorio_sessao_plenaria, - resumo_ata_pdf, relatorio_sessao_plenaria_pdf, etiqueta_materia_legislativa, - relatorio_materia_tramitacao, RelatoriosListView, RelatorioMateriasPorAutorView, - RelatorioNormasPublicadasMesView, RelatorioNormasVigenciaView, RelatorioMateriasPorAnoAutorTipoView, - RelatorioMateriasTramitacaoView, RelatorioMateriaAnoAssuntoView, RelatorioHistoricoTramitacaoView, - RelatorioDataFimPrazoTramitacaoView, RelatorioPresencaSessaoView, RelatorioAtasView, - RelatorioReuniaoView, RelatorioAudienciaView, RelatorioHistoricoTramitacaoAdmView, - RelatorioDocumentosAcessoriosView, RelatorioNormasPorAutorView) -from ..base.views import EstatisticasAcessoNormas + relatorio_materia_tramitacao, relatorio_ordem_dia, + relatorio_protocolo, relatorio_sessao_plenaria, + relatorio_sessao_plenaria_pdf, resumo_ata_pdf) app_name = AppConfig.name urlpatterns = [ - path('relatorios/materia', relatorio_materia, name='relatorio_materia'), - path('relatorios/capa-processo', - relatorio_capa_processo, name='relatorio_capa_processo'), - path('relatorios/ordem-dia', relatorio_ordem_dia, - name='relatorio_ordem_dia'), - path('relatorios/relatorio-documento-administrativo', + path("relatorios/materia", relatorio_materia, name="relatorio_materia"), + path( + "relatorios/capa-processo", + relatorio_capa_processo, + name="relatorio_capa_processo", + ), + path("relatorios/ordem-dia", relatorio_ordem_dia, name="relatorio_ordem_dia"), + path( + "relatorios/relatorio-documento-administrativo", relatorio_documento_administrativo, - name='relatorio_documento_administrativo'), - path('relatorios/espelho', relatorio_espelho, - name='relatorio_espelho'), - + name="relatorio_documento_administrativo", + ), + path("relatorios/espelho", relatorio_espelho, name="relatorio_espelho"), # Url utilizada no arquivo: templates/sessao/pauta_sessao_list.html - path('relatorios//sessao-plenaria', - relatorio_sessao_plenaria, name='relatorio_sessao_plenaria'), - - path('relatorios/protocolo', - relatorio_protocolo, name='relatorio_protocolo'), - path('relatorios///etiqueta-protocolo', - relatorio_etiqueta_protocolo, name='relatorio_etiqueta_protocolo'), - + path( + "relatorios//sessao-plenaria", + relatorio_sessao_plenaria, + name="relatorio_sessao_plenaria", + ), + path("relatorios/protocolo", relatorio_protocolo, name="relatorio_protocolo"), + path( + "relatorios///etiqueta-protocolo", + relatorio_etiqueta_protocolo, + name="relatorio_etiqueta_protocolo", + ), # # Url utilizada no arquivo: templates/sessao/pauta_sessao_filter.html # url(r'^relatorios/pauta-sessao/(?P\d+)/$', # relatorio_pauta_sessao, name='relatorio_pauta_sessao'), - - path('relatorios//resumo_ata', - resumo_ata_pdf, name='resumo_ata_pdf'), - path('relatorios//sessao-plenaria-pdf', - relatorio_sessao_plenaria_pdf, name='relatorio_sessao_plenaria_pdf'), - path('relatorios//etiqueta-materia-legislativa', - etiqueta_materia_legislativa, name='etiqueta_materia_legislativa'), - - path('relatorios//materia-tramitacao', - relatorio_materia_tramitacao, name='relatorio_materia_tramitacao'), - + path("relatorios//resumo_ata", resumo_ata_pdf, name="resumo_ata_pdf"), + path( + "relatorios//sessao-plenaria-pdf", + relatorio_sessao_plenaria_pdf, + name="relatorio_sessao_plenaria_pdf", + ), + path( + "relatorios//etiqueta-materia-legislativa", + etiqueta_materia_legislativa, + name="etiqueta_materia_legislativa", + ), + path( + "relatorios//materia-tramitacao", + relatorio_materia_tramitacao, + name="relatorio_materia_tramitacao", + ), # TODO mover estas telas para a app 'relatorios' - path('sistema/relatorios/', - RelatoriosListView.as_view(), name='relatorios_list'), - path('sistema/relatorios/materia-por-autor', - RelatorioMateriasPorAutorView.as_view(), name='materia_por_autor'), - path('sistema/relatorios/relatorio-por-mes', - RelatorioNormasPublicadasMesView.as_view(), name='normas_por_mes'), - path('sistema/relatorios/relatorio-por-vigencia', - RelatorioNormasVigenciaView.as_view(), name='normas_por_vigencia'), - path('sistema/relatorios/estatisticas-acesso', - EstatisticasAcessoNormas.as_view(), name='estatisticas_acesso'), - path('sistema/relatorios/materia-por-ano-autor-tipo', + path("sistema/relatorios/", RelatoriosListView.as_view(), name="relatorios_list"), + path( + "sistema/relatorios/materia-por-autor", + RelatorioMateriasPorAutorView.as_view(), + name="materia_por_autor", + ), + path( + "sistema/relatorios/relatorio-por-mes", + RelatorioNormasPublicadasMesView.as_view(), + name="normas_por_mes", + ), + path( + "sistema/relatorios/relatorio-por-vigencia", + RelatorioNormasVigenciaView.as_view(), + name="normas_por_vigencia", + ), + path( + "sistema/relatorios/estatisticas-acesso", + EstatisticasAcessoNormas.as_view(), + name="estatisticas_acesso", + ), + path( + "sistema/relatorios/materia-por-ano-autor-tipo", RelatorioMateriasPorAnoAutorTipoView.as_view(), - name='materia_por_ano_autor_tipo'), - path('sistema/relatorios/materia-por-tramitacao', + name="materia_por_ano_autor_tipo", + ), + path( + "sistema/relatorios/materia-por-tramitacao", RelatorioMateriasTramitacaoView.as_view(), - name='materia_por_tramitacao'), - path('sistema/relatorios/materia-por-assunto', + name="materia_por_tramitacao", + ), + path( + "sistema/relatorios/materia-por-assunto", RelatorioMateriaAnoAssuntoView.as_view(), - name='materia_por_ano_assunto'), - path('sistema/relatorios/historico-tramitacoes', + name="materia_por_ano_assunto", + ), + path( + "sistema/relatorios/historico-tramitacoes", RelatorioHistoricoTramitacaoView.as_view(), - name='historico_tramitacoes'), - path('sistema/relatorios/data-fim-prazo-tramitacoes', + name="historico_tramitacoes", + ), + path( + "sistema/relatorios/data-fim-prazo-tramitacoes", RelatorioDataFimPrazoTramitacaoView.as_view(), - name='data_fim_prazo_tramitacoes'), - path('sistema/relatorios/presenca', + name="data_fim_prazo_tramitacoes", + ), + path( + "sistema/relatorios/presenca", RelatorioPresencaSessaoView.as_view(), - name='presenca_sessao'), - path('sistema/relatorios/atas', - RelatorioAtasView.as_view(), - name='atas'), - path('sistema/relatorios/reuniao', - RelatorioReuniaoView.as_view(), - name='reuniao'), - path('sistema/relatorios/audiencia', + name="presenca_sessao", + ), + path("sistema/relatorios/atas", RelatorioAtasView.as_view(), name="atas"), + path("sistema/relatorios/reuniao", RelatorioReuniaoView.as_view(), name="reuniao"), + path( + "sistema/relatorios/audiencia", RelatorioAudienciaView.as_view(), - name='audiencia'), - path('sistema/relatorios/historico-tramitacoesadm', + name="audiencia", + ), + path( + "sistema/relatorios/historico-tramitacoesadm", RelatorioHistoricoTramitacaoAdmView.as_view(), - name='historico_tramitacoes_adm'), - path('sistema/relatorios/documentos_acessorios', + name="historico_tramitacoes_adm", + ), + path( + "sistema/relatorios/documentos_acessorios", RelatorioDocumentosAcessoriosView.as_view(), - name='relatorio_documentos_acessorios'), - path('sistema/relatorios/normas-por-autor', - RelatorioNormasPorAutorView.as_view(), name='normas_por_autor'), -] \ No newline at end of file + name="relatorio_documentos_acessorios", + ), + path( + "sistema/relatorios/normas-por-autor", + RelatorioNormasPorAutorView.as_view(), + name="normas_por_autor", + ), +] diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index 5fe054557..d66d565e2 100755 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -2,67 +2,87 @@ import collections import html import logging import re -from datetime import datetime as dt, datetime +from datetime import datetime +from datetime import datetime as dt import unidecode from django.core.exceptions import ObjectDoesNotExist -from django.db.models import Count, Q, F +from django.db.models import Count, F, Q from django.http import Http404, HttpResponse from django.template.loader import render_to_string from django.utils import timezone from django.utils.translation import gettext_lazy as _ -from django.views.generic import TemplateView, ListView +from django.views.generic import ListView, TemplateView from django_filters.views import FilterView -from weasyprint import HTML, CSS +from weasyprint import CSS, HTML -from sapl.audiencia.models import TipoAudienciaPublica, AudienciaPublica -from sapl.base.models import Autor, CasaLegislativa, AppConfig as SaplAppConfig, AppConfig +from sapl.audiencia.models import AudienciaPublica, TipoAudienciaPublica +from sapl.base.models import AppConfig +from sapl.base.models import AppConfig as SaplAppConfig +from sapl.base.models import Autor, CasaLegislativa from sapl.comissoes.models import Comissao, Reuniao -from sapl.materia.models import (Autoria, MateriaLegislativa, Numeracao, - Tramitacao, UnidadeTramitacao, ConfigEtiquetaMateriaLegislativa, MateriaAssunto, - TipoMateriaLegislativa, MateriaEmTramitacao, DocumentoAcessorio, TipoDocumento, - StatusTramitacao) -from sapl.norma.models import TipoNormaJuridica, NormaJuridica -from sapl.parlamentares.models import Filiacao, Parlamentar, SessaoLegislativa, Legislatura +from sapl.crud.base import make_pagination +from sapl.materia.models import (Autoria, ConfigEtiquetaMateriaLegislativa, + DocumentoAcessorio, MateriaAssunto, + MateriaEmTramitacao, MateriaLegislativa, + Numeracao, StatusTramitacao, TipoDocumento, + TipoMateriaLegislativa, Tramitacao, + UnidadeTramitacao) +from sapl.norma.models import NormaJuridica, TipoNormaJuridica +from sapl.parlamentares.models import (Filiacao, Legislatura, Parlamentar, + SessaoLegislativa) from sapl.protocoloadm.models import (DocumentoAdministrativo, Protocolo, - TramitacaoAdministrativo, StatusTramitacaoAdministrativo, - TipoDocumentoAdministrativo) -from sapl.relatorios.forms import RelatorioNormasPorAutorFilterSet, RelatorioHistoricoTramitacaoAdmFilterSet, \ - RelatorioNormasVigenciaFilterSet, RelatorioNormasMesFilterSet, RelatorioMateriasPorAutorFilterSet, \ - RelatorioMateriasPorAnoAutorTipoFilterSet, RelatorioMateriasTramitacaoFilterSet, RelatorioAudienciaFilterSet, \ - RelatorioReuniaoFilterSet, RelatorioDataFimPrazoTramitacaoFilterSet, RelatorioHistoricoTramitacaoFilterSet, \ - RelatorioPresencaSessaoFilterSet, RelatorioAtasFilterSet, RelatorioDocumentosAcessoriosFilterSet -from sapl.sessao.models import (ExpedienteMateria, ExpedienteSessao, - IntegranteMesa, JustificativaAusencia, - Orador, OradorExpediente, - OrdemDia, PresencaOrdemDia, SessaoPlenaria, - SessaoPlenariaPresenca, OcorrenciaSessao, - RegistroVotacao, VotoParlamentar, OradorOrdemDia, - ConsideracoesFinais, ResumoOrdenacao, TipoSessaoPlenaria) -from sapl.sessao.views import (get_identificacao_basica, get_mesa_diretora, - get_presenca_sessao, get_expedientes, - get_materias_expediente, get_oradores_expediente, - get_presenca_ordem_do_dia, get_materias_ordem_do_dia, + StatusTramitacaoAdministrativo, + TipoDocumentoAdministrativo, + TramitacaoAdministrativo) +from sapl.relatorios.forms import (RelatorioAtasFilterSet, + RelatorioAudienciaFilterSet, + RelatorioDataFimPrazoTramitacaoFilterSet, + RelatorioDocumentosAcessoriosFilterSet, + RelatorioHistoricoTramitacaoAdmFilterSet, + RelatorioHistoricoTramitacaoFilterSet, + RelatorioMateriasPorAnoAutorTipoFilterSet, + RelatorioMateriasPorAutorFilterSet, + RelatorioMateriasTramitacaoFilterSet, + RelatorioNormasMesFilterSet, + RelatorioNormasPorAutorFilterSet, + RelatorioNormasVigenciaFilterSet, + RelatorioPresencaSessaoFilterSet, + RelatorioReuniaoFilterSet) +from sapl.sessao.models import (ConsideracoesFinais, ExpedienteMateria, + ExpedienteSessao, IntegranteMesa, + JustificativaAusencia, OcorrenciaSessao, + Orador, OradorExpediente, OradorOrdemDia, + OrdemDia, PresencaOrdemDia, RegistroVotacao, + ResumoOrdenacao, SessaoPlenaria, + SessaoPlenariaPresenca, TipoSessaoPlenaria, + VotoParlamentar) +from sapl.sessao.views import (get_assinaturas, get_consideracoes_finais, + get_correspondencias, get_expedientes, + get_identificacao_basica, + get_materias_expediente, + get_materias_ordem_do_dia, get_mesa_diretora, + get_ocorrencias_da_sessao, + get_oradores_expediente, + get_oradores_explicacoes_pessoais, get_oradores_ordemdia, - get_oradores_explicacoes_pessoais, get_consideracoes_finais, - get_ocorrencias_da_sessao, get_assinaturas, - get_correspondencias) -from sapl.settings import MEDIA_URL -from sapl.settings import STATIC_ROOT -from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data, create_barcode, show_results_filter_set, \ - num_materias_por_tipo, parlamentares_ativos + get_presenca_ordem_do_dia, get_presenca_sessao) +from sapl.settings import MEDIA_URL, STATIC_ROOT +from sapl.utils import (LISTA_DE_UFS, TrocaTag, create_barcode, filiacao_data, + num_materias_por_tipo, parlamentares_ativos, + show_results_filter_set) + from .templates import (pdf_capa_processo_gerar, pdf_documento_administrativo_gerar, pdf_espelho_gerar, pdf_etiqueta_protocolo_gerar, pdf_materia_gerar, pdf_ordem_dia_gerar, pdf_pauta_sessao_gerar, pdf_protocolo_gerar, pdf_sessao_plenaria_gerar) -from sapl.crud.base import make_pagination def get_kwargs_params(request, fields): kwargs = {} for i in fields: - if '__icontains' in i: + if "__icontains" in i: x = i[:-11] # remove '__icontains' else: x = i @@ -83,7 +103,7 @@ def get_cabecalho(casa): def get_imagem(casa): if casa.logotipo: return casa.logotipo.path - return STATIC_ROOT + '/img/brasao_transp.gif' + return STATIC_ROOT + "/img/brasao_transp.gif" def get_rodape(casa): @@ -125,21 +145,27 @@ def get_materias(mats): materias = [] for materia in mats: dic = {} - dic['titulo'] = materia.tipo.sigla + " " + materia.tipo.descricao \ - + " " + str(materia.numero) + "/" + str(materia.ano) - dic['txt_ementa'] = materia.ementa + dic["titulo"] = ( + materia.tipo.sigla + + " " + + materia.tipo.descricao + + " " + + str(materia.numero) + + "/" + + str(materia.ano) + ) + dic["txt_ementa"] = materia.ementa - dic['nom_autor'] = ', '.join( - [str(autor) for autor in materia.autores.all()]) + dic["nom_autor"] = ", ".join([str(autor) for autor in materia.autores.all()]) - des_status = '' - txt_tramitacao = '' + des_status = "" + txt_tramitacao = "" - dic['localizacao_atual'] = " " + dic["localizacao_atual"] = " " tramitacoes = Tramitacao.objects.filter( - unidade_tramitacao_destino__isnull=True).order_by( - '-data_tramitacao', '-id') + unidade_tramitacao_destino__isnull=True + ).order_by("-data_tramitacao", "-id") for tramitacao in tramitacoes: des_status = tramitacao.status.descricao @@ -163,10 +189,10 @@ def get_materias(mats): # des_status=tramitacao.des_status # txt_tramitacao=tramitacao.txt_tramitacao - dic['des_situacao'] = des_status - dic['ultima_acao'] = txt_tramitacao + dic["des_situacao"] = des_status + dic["ultima_acao"] = txt_tramitacao - dic['norma_vinculada'] = " " + dic["norma_vinculada"] = " " # for norma_vinculada in context.zsql # .materia_buscar_norma_juridica_zsql(cod_materia=materia.cod_materia): # dic['norma_vinculada']= @@ -179,13 +205,12 @@ def get_materias(mats): def relatorio_materia(request): - ''' - pdf_materia_gerar.py - ''' + """ + pdf_materia_gerar.py + """ - response = HttpResponse(content_type='application/pdf') - response['Content-Disposition'] = ( - 'inline; filename="relatorio_materia.pdf"') + response = HttpResponse(content_type="application/pdf") + response["Content-Disposition"] = 'inline; filename="relatorio_materia.pdf"' casa = CasaLegislativa.objects.first() @@ -193,22 +218,16 @@ def relatorio_materia(request): rodape = get_rodape(casa) imagem = get_imagem(casa) - kwargs = get_kwargs_params(request, ['numero', - 'ano', - 'autor', - 'tipo_autor', - 'relator', - 'interessado__icontains' - ]) + kwargs = get_kwargs_params( + request, + ["numero", "ano", "autor", "tipo_autor", "relator", "interessado__icontains"], + ) mats = MateriaLegislativa.objects.filter(**kwargs) materias = get_materias(mats) - pdf = pdf_materia_gerar.principal(imagem, - materias, - cabecalho, - rodape) + pdf = pdf_materia_gerar.principal(imagem, materias, cabecalho, rodape) response.write(pdf) @@ -219,65 +238,65 @@ def get_capa_processo(prot): protocolos = [] for p in prot: dic = {} - dic['numero'] = str(p.numero) - dic['ano'] = str(p.ano) - dic['data'] = str(p.data) + ' - ' + str(p.hora) - dic['txt_assunto'] = p.assunto_ementa - dic['txt_interessado'] = p.interessado - dic['nom_autor'] = " " - dic['titulo'] = " " + dic["numero"] = str(p.numero) + dic["ano"] = str(p.ano) + dic["data"] = str(p.data) + " - " + str(p.hora) + dic["txt_assunto"] = p.assunto_ementa + dic["txt_interessado"] = p.interessado + dic["nom_autor"] = " " + dic["titulo"] = " " if p.autor: - dic['nom_autor'] = str(p.autor or ' ') + dic["nom_autor"] = str(p.autor or " ") else: - dic['nom_autor'] = p.interessado + dic["nom_autor"] = p.interessado - dic['natureza'] = '' + dic["natureza"] = "" if p.tipo_processo == 0: - dic['natureza'] = 'Administrativo' + dic["natureza"] = "Administrativo" if p.tipo_processo == 1: - dic['natureza'] = 'Legislativo' + dic["natureza"] = "Legislativo" - dic['ident_processo'] = str(p.tipo_materia) or str(p.tipo_documento) + dic["ident_processo"] = str(p.tipo_materia) or str(p.tipo_documento) - dic['sgl_processo'] = str(p.tipo_materia) or str(p.tipo_documento) + dic["sgl_processo"] = str(p.tipo_materia) or str(p.tipo_documento) - dic['num_materia'] = '' + dic["num_materia"] = "" for materia in MateriaLegislativa.objects.filter( - numero_protocolo=p.numero, ano=p.ano): - dic['num_materia'] = str(materia.numero) + '/' + str(materia.ano) + numero_protocolo=p.numero, ano=p.ano + ): + dic["num_materia"] = str(materia.numero) + "/" + str(materia.ano) - dic['num_documento'] = '' - for documento in DocumentoAdministrativo.objects.filter( - numero=p.numero): - dic['num_documento'] = str( - documento.numero) + '/' + str(documento.ano) + dic["num_documento"] = "" + for documento in DocumentoAdministrativo.objects.filter(numero=p.numero): + dic["num_documento"] = str(documento.numero) + "/" + str(documento.ano) - dic['num_processo'] = dic['num_materia'] or dic['num_documento'] + dic["num_processo"] = dic["num_materia"] or dic["num_documento"] - dic['numeracao'] = '' + dic["numeracao"] = "" for materia_num in MateriaLegislativa.objects.filter( - numero_protocolo=p.numero, ano=p.ano): + numero_protocolo=p.numero, ano=p.ano + ): for numera in Numeracao.objects.filter(materia=materia_num): # FIXME i18n - dic['numeracao'] = 'PROCESSO N° ' + \ - str(numera.numero) + '/' + str(numera.ano) - dic['anulado'] = '' + dic["numeracao"] = ( + "PROCESSO N° " + str(numera.numero) + "/" + str(numera.ano) + ) + dic["anulado"] = "" if p.anulado == 1: - dic['anulado'] = 'Nulo' + dic["anulado"] = "Nulo" protocolos.append(dic) return protocolos def relatorio_capa_processo(request): - ''' - pdf_capa_processo_gerar.py - ''' + """ + pdf_capa_processo_gerar.py + """ - response = HttpResponse(content_type='application/pdf') - response[ - 'Content-Disposition'] = ('inline; filename="relatorio_processo.pdf"') + response = HttpResponse(content_type="application/pdf") + response["Content-Disposition"] = 'inline; filename="relatorio_processo.pdf"' casa = CasaLegislativa.objects.first() @@ -285,19 +304,20 @@ def relatorio_capa_processo(request): rodape = get_rodape(casa) imagem = get_imagem(casa) - kwargs = get_kwargs_params(request, ['numero', - 'ano', - 'tipo_protocolo', - 'tipo_processo', - 'assunto__icontains', - # 'interessado__icontains' - ]) + kwargs = get_kwargs_params( + request, + [ + "numero", + "ano", + "tipo_protocolo", + "tipo_processo", + "assunto__icontains", + # 'interessado__icontains' + ], + ) protocolos = Protocolo.objects.filter(**kwargs) protocolos_pdf = get_capa_processo(protocolos) - pdf = pdf_capa_processo_gerar.principal(imagem, - protocolos_pdf, - cabecalho, - rodape) + pdf = pdf_capa_processo_gerar.principal(imagem, protocolos_pdf, cabecalho, rodape) response.write(pdf) @@ -310,14 +330,13 @@ def get_ordem_dia(ordem, sessao): def relatorio_ordem_dia(request): - ''' - pdf_ordem_dia_gerar.py - ''' + """ + pdf_ordem_dia_gerar.py + """ - response = HttpResponse(content_type='application/pdf') + response = HttpResponse(content_type="application/pdf") - response['Content-Disposition'] = ( - 'inline; filename="relatorio_ordem_dia.pdf"') + response["Content-Disposition"] = 'inline; filename="relatorio_ordem_dia.pdf"' casa = CasaLegislativa.objects.first() @@ -325,17 +344,14 @@ def relatorio_ordem_dia(request): rodape = get_rodape(casa) imagem = get_imagem(casa) - kwargs = get_kwargs_params(request, ['numero_ordem']) + kwargs = get_kwargs_params(request, ["numero_ordem"]) ordem = OrdemDia.objects.filter(**kwargs) sessao = SessaoPlenaria.objects.first() ordem_pdf = get_ordem_dia(ordem, sessao) - pdf = pdf_ordem_dia_gerar.principal(imagem, - ordem_pdf, - cabecalho, - rodape) + pdf = pdf_ordem_dia_gerar.principal(imagem, ordem_pdf, cabecalho, rodape) response.write(pdf) @@ -343,13 +359,14 @@ def relatorio_ordem_dia(request): def relatorio_documento_administrativo(request): - ''' - pdf_documento_administrativo_gerar.py - ''' + """ + pdf_documento_administrativo_gerar.py + """ - response = HttpResponse(content_type='application/pdf') - response['Content-Disposition'] = ( - 'inline; filename="relatorio_documento_administrativo.pdf"') + response = HttpResponse(content_type="application/pdf") + response[ + "Content-Disposition" + ] = 'inline; filename="relatorio_documento_administrativo.pdf"' casa = CasaLegislativa.objects.first() @@ -361,10 +378,8 @@ def relatorio_documento_administrativo(request): doc_pdf = get_documento_administrativo(docs) pdf = pdf_documento_administrativo_gerar.principal( - imagem, - doc_pdf, - cabecalho, - rodape) + imagem, doc_pdf, cabecalho, rodape + ) response.write(pdf) return response @@ -374,47 +389,46 @@ def get_documento_administrativo(docs): documentos = [] for d in docs: dic = {} - dic['titulo'] = str(d) - dic['txt_assunto'] = d.assunto - dic['txt_interessado'] = d.interessado + dic["titulo"] = str(d) + dic["txt_assunto"] = d.assunto + dic["txt_interessado"] = d.interessado - des_status = '' - txt_tramitacao = '' + des_status = "" + txt_tramitacao = "" - dic['localizacao_atual'] = ' ' + dic["localizacao_atual"] = " " # Será removido o 'última'? - for t in TramitacaoAdministrativo.objects.filter( - documento=d, ultima=True): + for t in TramitacaoAdministrativo.objects.filter(documento=d, ultima=True): if t.unidade_tramitacao_destino: cod_unid_tram = t.unidade_tramitacao_destino else: cod_unid_tram = t.unidade_tramitacao_destino for unidade_tramitacao in UnidadeTramitacao.objects.filter( - id=cod_unid_tram): + id=cod_unid_tram + ): if unidade_tramitacao.orgao: - dic['localizacao_atual'] = unidade_tramitacao.orgao + dic["localizacao_atual"] = unidade_tramitacao.orgao else: - dic['localizacao_atual'] = unidade_tramitacao.comissao + dic["localizacao_atual"] = unidade_tramitacao.comissao des_status = t.status.descricao txt_tramitacao = t.texto - dic['des_situacao'] = des_status - dic['ultima_acao'] = txt_tramitacao + dic["des_situacao"] = des_status + dic["ultima_acao"] = txt_tramitacao documentos.append(dic) return documentos def relatorio_espelho(request): - ''' - pdf_espelho_gerar.py - ''' + """ + pdf_espelho_gerar.py + """ - response = HttpResponse(content_type='application/pdf') - response['Content-Disposition'] = ( - 'inline; filename="relatorio_espelho.pdf"') + response = HttpResponse(content_type="application/pdf") + response["Content-Disposition"] = 'inline; filename="relatorio_espelho.pdf"' casa = CasaLegislativa.objects.first() @@ -425,11 +439,7 @@ def relatorio_espelho(request): mats = MateriaLegislativa.objects.all()[:50] mat_pdf = get_espelho(mats) - pdf = pdf_espelho_gerar.principal( - imagem, - mat_pdf, - cabecalho, - rodape) + pdf = pdf_espelho_gerar.principal(imagem, mat_pdf, cabecalho, rodape) response.write(pdf) return response @@ -439,22 +449,22 @@ def get_espelho(mats): materias = [] for m in mats: dic = {} - dic['titulo'] = str(m) - dic['materia'] = str(m.numero) + '/' + str(m.ano) - dic['dat_apresentacao'] = str(m.data_apresentacao) - dic['txt_ementa'] = m.ementa + dic["titulo"] = str(m) + dic["materia"] = str(m.numero) + "/" + str(m.ano) + dic["dat_apresentacao"] = str(m.data_apresentacao) + dic["txt_ementa"] = m.ementa - dic['nom_autor'] = [] + dic["nom_autor"] = [] for autoria in Autoria.objects.filter(materia=m, primeiro_autor=True): - dic['nom_autor'].append(str(autoria.autor)) + dic["nom_autor"].append(str(autoria.autor)) - dic['nom_autor'] = ', '.join(dic['nom_autor']) + dic["nom_autor"] = ", ".join(dic["nom_autor"]) - des_status = '' - txt_tramitacao = '' - data_ultima_acao = '' + des_status = "" + txt_tramitacao = "" + data_ultima_acao = "" - dic['localizacao_atual'] = " " + dic["localizacao_atual"] = " " for tramitacao in Tramitacao.objects.filter(materia=m): if tramitacao.unidade_tramitacao_destino: cod_unid_tram = tramitacao.unidade_tramitacao_destino @@ -462,24 +472,29 @@ def get_espelho(mats): cod_unid_tram = tramitacao.unidade_tramitacao_local for unidade_tramitacao in UnidadeTramitacao.objects.filter( - id=cod_unid_tram.id): + id=cod_unid_tram.id + ): if unidade_tramitacao.orgao: - dic['localizacao_atual'] = unidade_tramitacao.orgao + dic["localizacao_atual"] = unidade_tramitacao.orgao elif unidade_tramitacao.parlamentar: - dic['localizacao_atual'] = unidade_tramitacao.parlamentar + dic["localizacao_atual"] = unidade_tramitacao.parlamentar else: - dic['localizacao_atual'] = unidade_tramitacao.comissao + dic["localizacao_atual"] = unidade_tramitacao.comissao des_status = tramitacao.status txt_tramitacao = tramitacao.texto data_ultima_acao = tramitacao.data_tramitacao - dic['des_situacao'] = des_status - dic['ultima_acao'] = txt_tramitacao - dic['data_ultima_acao'] = data_ultima_acao + dic["des_situacao"] = des_status + dic["ultima_acao"] = txt_tramitacao + dic["data_ultima_acao"] = data_ultima_acao - dic['norma_juridica_vinculada'] = str(_('Não há nenhuma \ - norma jurídica vinculada')) + dic["norma_juridica_vinculada"] = str( + _( + "Não há nenhuma \ + norma jurídica vinculada" + ) + ) # TODO # for norma in context.zsql.materia_buscar_norma_juridica_zsql( # cod_materia=materia.cod_materia): @@ -498,15 +513,15 @@ def remove_html_comments(text): :return: """ clean_text = text - start = clean_text.find('') + 2 + end = clean_text.find("-->") + 2 output_text = [] for idx, i in enumerate(clean_text): if not start <= idx <= end: output_text.append(i) - clean_text = ''.join(output_text) - start = clean_text.find('