Browse Source

Merge a61c2a735b into 673f3adff8

pull/6/merge
Edward 9 years ago
committed by GitHub
parent
commit
42ec1b6152
  1. 8
      .gitignore
  2. 66
      Dockerfile
  3. 17
      check_qa.sh
  4. 1
      conftest.py
  5. 32
      docker-compose.yml
  6. 10
      etc/migracao/migra.py
  7. 11
      fix_qa.sh
  8. 4
      moodlerouter.py
  9. 1
      prod.py
  10. 10
      requirements/dev-requirements.txt
  11. 44
      requirements/requirements.txt
  12. 16
      requirements/test-requirements.txt
  13. 15
      scripts/atendimento/criar_grupos.py
  14. 1
      scripts/casas_com_PM_e_SAPL.py
  15. 5
      scripts/casas_que_usam_LEGBR_ou_PM.py
  16. 4
      scripts/contatos_de_casas_que_usam_portalmodelo.py
  17. 2
      scripts/csv_writer.py
  18. 398
      scripts/eav_models.py
  19. 2
      scripts/importa_pesquisa.py
  20. 1
      scripts/servicos_seit_ate_2013_2014.py
  21. 1
      scripts/setgerentes/dados_gerentes.py
  22. 2
      scripts/user_from_session.py
  23. 4
      scripts/verificacao_arquivos_faltando_media.py
  24. 1
      setup.py
  25. 15
      sigi/apps/casas/admin.py
  26. 7
      sigi/apps/casas/management/commands/importa_gerentes.py
  27. 12
      sigi/apps/casas/models.py
  28. 4
      sigi/apps/casas/reports.py
  29. 3
      sigi/apps/casas/test_casas.py
  30. 41
      sigi/apps/casas/urls.py
  31. 30
      sigi/apps/casas/views.py
  32. 5
      sigi/apps/contatos/admin.py
  33. 8
      sigi/apps/contatos/management/commands/importa_mesomicro.py
  34. 20
      sigi/apps/contatos/migrations/0003_auto_20160623_0829.py
  35. 10
      sigi/apps/contatos/models.py
  36. 3
      sigi/apps/convenios/admin.py
  37. 38
      sigi/apps/convenios/migrations/0002_auto_20160616_1602.py
  38. 9
      sigi/apps/convenios/models.py
  39. 3
      sigi/apps/convenios/reports.py
  40. 2
      sigi/apps/convenios/templates/convenios/change_list.html
  41. 22
      sigi/apps/convenios/urls.py
  42. 13
      sigi/apps/convenios/views.py
  43. 176
      sigi/apps/crispy_layout_mixin.py
  44. 0
      sigi/apps/crud/__init__.py
  45. 227
      sigi/apps/crud/base.py
  46. 7
      sigi/apps/crud/urls.py
  47. 66
      sigi/apps/crud/utils.py
  48. 4
      sigi/apps/diagnosticos/admin.py
  49. 3
      sigi/apps/diagnosticos/decorators.py
  50. 10
      sigi/apps/diagnosticos/forms.py
  51. 34
      sigi/apps/diagnosticos/migrations/0002_auto_20160616_1602.py
  52. 7
      sigi/apps/diagnosticos/models.py
  53. 2
      sigi/apps/diagnosticos/templates/admin/diagnosticos/diagnostico/change_list.html
  54. 2
      sigi/apps/diagnosticos/templates/diagnosticos/diagnosticos_login.html
  55. 2
      sigi/apps/diagnosticos/templates/diagnosticos/mapa.html
  56. 1
      sigi/apps/diagnosticos/templatetags/smart_if.py
  57. 2
      sigi/apps/diagnosticos/templatetags/test_smart_if.py
  58. 57
      sigi/apps/diagnosticos/urls.py
  59. 15
      sigi/apps/diagnosticos/views.py
  60. 12
      sigi/apps/diagnosticos/widgets.py
  61. 9
      sigi/apps/eventos/admin.py
  62. 8
      sigi/apps/eventos/models.py
  63. 13
      sigi/apps/eventos/urls.py
  64. 12
      sigi/apps/eventos/views.py
  65. 7
      sigi/apps/home/templatetags/menu_conf.yaml
  66. 1
      sigi/apps/home/templatetags/menus.py
  67. 4
      sigi/apps/home/templatetags/smart_pagination.py
  68. 33
      sigi/apps/home/urls.py
  69. 21
      sigi/apps/home/views.py
  70. 12
      sigi/apps/inventario/admin.py
  71. 20
      sigi/apps/inventario/migrations/0002_auto_20160623_0829.py
  72. 6
      sigi/apps/inventario/models.py
  73. 3
      sigi/apps/mdl/models.py
  74. 3
      sigi/apps/metas/models.py
  75. 2
      sigi/apps/metas/templates/admin/metas/planodiretor/change_list.html
  76. 2
      sigi/apps/metas/templates/metas/mapa.html
  77. 1
      sigi/apps/metas/templatetags/mapa_tags.py
  78. 21
      sigi/apps/metas/urls.py
  79. 13
      sigi/apps/metas/views.py
  80. 5
      sigi/apps/ocorrencias/admin.py
  81. 16
      sigi/apps/ocorrencias/forms.py
  82. 20
      sigi/apps/ocorrencias/migrations/0003_auto_20160616_1602.py
  83. 6
      sigi/apps/ocorrencias/models.py
  84. 2
      sigi/apps/ocorrencias/templates/ocorrencias/painel.html
  85. 31
      sigi/apps/ocorrencias/urls.py
  86. 28
      sigi/apps/ocorrencias/views.py
  87. 14
      sigi/apps/parlamentares/admin.py
  88. 20
      sigi/apps/parlamentares/migrations/0002_auto_20160623_0829.py
  89. 20
      sigi/apps/parlamentares/migrations/0003_auto_20160811_1553.py
  90. 3
      sigi/apps/parlamentares/models.py
  91. 4
      sigi/apps/parlamentares/reports.py
  92. 1
      sigi/apps/parlamentares/test_parlamentares.py
  93. 19
      sigi/apps/parlamentares/urls.py
  94. 14
      sigi/apps/parlamentares/views.py
  95. 3
      sigi/apps/relatorios/reports.py
  96. 3
      sigi/apps/saberes/admin.py
  97. 7
      sigi/apps/saberes/management/commands/get_moodle_stats.py
  98. 7
      sigi/apps/saberes/models.py
  99. 19
      sigi/apps/saberes/urls.py
  100. 4
      sigi/apps/saberes/views.py

8
.gitignore

@ -47,3 +47,11 @@ db.*
.vagrant
sigi/settings/prod.py
bower/
collected_static/
eav/
geraldo/
*.bak
*~

66
Dockerfile

@ -0,0 +1,66 @@
FROM ubuntu:15.04
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
RUN mkdir /sigi
RUN apt-get update && \
apt-get install -y -f \
build-essential \
curl \
git \
graphviz-dev \
graphviz \
libz-dev \
libffi-dev \
libfreetype6-dev \
libjpeg62 \
libjpeg-dev \
libldap2-dev \
libpq-dev \
libsasl2-dev \
libssl-dev \
libxft-dev \
libxml2-dev \
libxslt1-dev \
nginx \
pkg-config \
python-dev \
python-setuptools \
software-properties-common \
npm \
nodejs
# install nodejs
RUN DEBIAN_FRONTEND=noninteractive curl -sL https://deb.nodesource.com/setup_5.x | bash -
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs
# install bower
RUN npm install -g bower
# Bower aceitar root
RUN touch /root/.bowerrc
RUN chmod 751 /root/.bowerrc
RUN echo "{ \"allow_root\": true }" >> /root/.bowerrc
ADD . /sigi
WORKDIR /sigi
RUN easy_install pip
RUN pip2 install -r requirements/dev-requirements.txt
RUN pip2 install --upgrade setuptools
RUN mkdir -p /var/log/sigi/
RUN touch /var/log/sigi/application.log
RUN chmod -x /var/log/sigi/application.log
RUN git clone https://github.com/marinho/geraldo.git
WORKDIR /sigi/geraldo/
RUN python setup.py install
RUN cp -Rfv reporting geraldo `python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"`
WORKDIR /sigi
RUN rm -rf geraldo/

17
check_qa.sh

@ -0,0 +1,17 @@
#!/bin/bash
# Check if there's some debug breakpoint in codebase
me=`basename "$0"`
stmts=`grep --exclude=$me -r -l "ipdb.set_trace()" * | wc -l`
if [ $stmts != '0' ]
then
echo "=================================================================="
echo "ERROR: ipdb.set_trace() call in codebase! Remove, please."
grep --exclude=$me -r -n "ipdb.set_trace()" *
echo "=================================================================="
fi
# QA checks: run this before every commit
./manage.py check
flake8 --exclude='ipython_log.py*,migrations,templates' .
isort --recursive --check-only --skip='migrations' --skip='templates' --skip='ipython_log.py' .

1
conftest.py

@ -2,7 +2,6 @@
import pytest
from django_webtest import DjangoTestApp, WebTestMixin
DEFAULT_MARK = object()

32
docker-compose.yml

@ -0,0 +1,32 @@
#localhost:
# image: postgres
# environment:
# POSTGRES_PASSWORD: sigi
# POSTGRES_USER: sigi
# POSTGRES_DB: sigi
# ports:
# - "5532:5432"
#web:
# build: .
# command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
# volumes:
# - .:/sigi
# ports:
# - "8000:8000"
# links:
# - localhost
osticket:
image: campbellsoftwaresolutions/osticket
ports:
- "80:80"
links:
- mysql
mysql:
image: mysql
environment:
- MYSQL_ROOT_PASSWORD=secret
- MYSQL_DATABASE=osticket
- MYSQL_USER=osticket
- MYSQL_PASSWORD=secret

10
etc/migracao/migra.py

@ -19,19 +19,21 @@ pós-instalação) para a migração dos dados. Este script não foi feito para
banco de dados em produção.
"""
import csv
from datetime import datetime
from django.core.management import setup_environ
from sigi import settings
setup_environ(settings)
import csv
from datetime import datetime
from sigi.apps.casas.models import *
from sigi.apps.contatos.models import *
from sigi.apps.convenios.models import *
from sigi.apps.inventario.models import *
from sigi.apps.parlamentares.models import *
setup_environ(settings)
ERROR_MSG_0 = ('<ERRO> %s[%s]: erro desconhecido! Possível erro de integridade '
'do banco de dados. Favor verificar e inserir manualmente caso '
'necessário.')

11
fix_qa.sh

@ -0,0 +1,11 @@
#!/bin/bash
# QA fix: Use ese script para corrigir automaticamente vários
# problemas de estilo e boas práticas no código.
#
# Sempre guarde suas mudanças de alguma forma antes de aplicar esse script,
# de modo que possa revisar cada alteração que ele fez.
# Uma forma simples de fazer isso é adicionando antes suas mudanças à
# "staging area" do git, com `git add .` e após usar o script `git diff`.
isort --recursive --skip='migrations' --skip='templates' --skip='ipython_log.py' .

4
moodlerouter.py

@ -18,7 +18,7 @@ class MoodleRouter(object):
return True
return None
def allow_migrate(self, db, model):
if model._meta.app_label == 'mdl':
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'mdl':
return False
return None

1
prod.py

@ -0,0 +1 @@
dev.py

10
requirements/dev-requirements.txt

@ -1,5 +1,7 @@
-r test-requirements.txt
django-debug-toolbar==1.2.2
ipdb==0.8
ipython==2.3.1
pygraphviz==1.2
django-debug-toolbar==1.5
ipdb==0.10.0
ipython==4.2.0
isort==4.2.5
model_mommy==1.2.6
pygraphviz==1.3.1

44
requirements/requirements.txt

@ -1,23 +1,41 @@
-e git://github.com/marinho/geraldo.git@868ebdce67176d9b6205cddc92476f642c783fff#egg=geraldo
django-bootstrap3==6.2.2
django-admin-bootstrapped==2.4.0
django-auth-ldap==1.2.7
git+git://github.com/hellpanderrr/django-admin-bootstrapped-1.9-compatible.git@master#egg=django_admin_bootstrapped
git+git://github.com/interlegis/eav-django
django-auth-ldap==1.2.8
django-autoslug==1.9.3
django-extensions==1.5.7
django-image-cropping==1.0.2
django-localflavor==1.1
Django==1.7.10
easy-thumbnails==2.2
eav-django==1.4.7
gunicorn==19.3.0
django-bootstrap3==7.0.1
django-bower==5.1.0
django-braces==1.8.1
django-compressor==2.0
django-crispy-forms==1.6.0
dj-database-url==0.4.1
django-dotenv==1.4.1
django-extensions==1.6.7
django-extra-views==0.7.1
django-filter==0.13.0
django-floppyforms==1.6.1
django-image-cropping==1.0.3
django-localflavor==1.3
django-model-utils==2.4
django-sass-processor==0.3.4
django-easy-select2==1.3.2
django-simple-captcha==0.5.1
Django==1.10.1
libsass==0.11.0
easy-thumbnails==2.3
gunicorn==19.6.0
html5lib==0.9999999
Pillow==2.9.0
Pillow==3.2.0
pisa==3.0.33
psycopg2==2.6.1
python-memcached==1.53
python-decouple==3.0
python-memcached==1.58
pytz==2016.3
PyYAML==3.11
reportlab==2.7
requests==2.8.1
requests==2.10.0
rtyaml==0.0.2
unipath==1.1
six==1.10.0
djangorestframework==2.4.8
django-ipware==1.1.6

16
requirements/test-requirements.txt

@ -1,10 +1,10 @@
-r requirements.txt
coverage==3.7.1
django-dynamic-fixture==1.8.1
django-webtest==1.7.7
git+git://github.com/paulocheque/django-dynamic-fixture/@master
coverage==4.1
django-webtest==1.7.9
pyPdf==1.13
pyquery==1.2.9
pytest-cov==1.8.1
pytest-django==2.8.0
pytest==2.6.4
WebTest==2.0.17
pyquery==1.2.13
pytest-cov==2.2.1
pytest-django==2.9.1
pytest==2.9.2
WebTest==2.0.21

15
scripts/atendimento/criar_grupos.py

@ -0,0 +1,15 @@
from django.contrib.auth.models import Group
def criar_grupos():
# COPLAF = Atestar usuário
if not Group.objects.filter(name='COPLAF').exists():
Group.objects.create(name='COPLAF')
# COADFI = Atestar convênio
if not Group.objects.filter(name='COADFI').exists():
Group.objects.create(name='COADFI')
# Já recebeu aprovação dos dois grupos de cima
if not Group.objects.filter(name='Usuario_Habilitado').exists():
Group.objects.create(name='Usuario_Habilitado')

1
scripts/casas_com_PM_e_SAPL.py

@ -1,7 +1,6 @@
from csv_writer import CsvWriter
from sigi.apps.servicos.models import Servico
ARQUIVO_CSV = '/tmp/casas_que_usam_PM_e_SAPL.csv'

5
scripts/casas_que_usam_LEGBR_ou_PM.py

@ -1,9 +1,8 @@
import cStringIO
import codecs
import cStringIO
import csv
from sigi.apps.servicos.models import TipoServico, Servico
from sigi.apps.servicos.models import Servico, TipoServico
# cria um CSV com contatos das casas legislativas que possuem portal modelo ativo
# rodar em um shell:

4
scripts/contatos_de_casas_que_usam_portalmodelo.py

@ -1,10 +1,10 @@
import cStringIO
import codecs
import cStringIO
import csv
from sigi.apps.casas.models import Funcionario
from sigi.apps.contatos.models import Telefone
from sigi.apps.servicos.models import TipoServico, Servico
from sigi.apps.servicos.models import Servico, TipoServico
# cria um CSV com contatos das casas legislativas que possuem portal modelo ativo
# rodar em um shell:

2
scripts/csv_writer.py

@ -1,5 +1,5 @@
import cStringIO
import codecs
import cStringIO
import csv

398
scripts/eav_models.py

@ -0,0 +1,398 @@
# -*- coding: utf-8 -*-
#
# EAV-Django is a reusable Django application which implements EAV data model
# Copyright © 2009—2010 Andrey Mikhaylenko
#
# This file is part of EAV-Django.
#
# EAV-Django is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# EAV-Django is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with EAV-Django. If not, see <http://gnu.org/licenses/>.
"""
Models
~~~~~~
"""
# django
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import fields
from django.db.models import (BooleanField, CharField, DateField, FloatField,
ForeignKey, IntegerField, Model, NullBooleanField,
TextField)
from django.utils.translation import ugettext_lazy as _
# 3rd-party
from autoslug.fields import AutoSlugField
from autoslug.settings import slugify
#from view_shortcuts.decorators import cached_property
# this app
from managers import BaseEntityManager
__all__ = ['BaseAttribute', 'BaseChoice', 'BaseEntity', 'BaseSchema']
def slugify_attr_name(name):
return slugify(name.replace('_', '-')).replace('-', '_')
def get_entity_lookups(entity):
ctype = ContentType.objects.get_for_model(entity)
return {'entity_type': ctype, 'entity_id': entity.pk}
class BaseSchema(Model):
"""
Metadata for an attribute.
"""
TYPE_TEXT = 'text'
TYPE_FLOAT = 'float'
TYPE_DATE = 'date'
TYPE_BOOLEAN = 'bool'
TYPE_ONE = 'one'
TYPE_MANY = 'many'
TYPE_RANGE = 'range'
DATATYPE_CHOICES = (
(TYPE_TEXT, _('text')),
(TYPE_FLOAT, _('number')),
(TYPE_DATE, _('date')),
(TYPE_BOOLEAN, _('boolean')),
(TYPE_ONE, _('choice')),
(TYPE_MANY, _('multiple choices')),
(TYPE_RANGE, _('numeric range')),
)
title = CharField(_('title'), max_length=250, help_text=_('user-friendly attribute name'))
name = AutoSlugField(_('name'), max_length=250, populate_from='title',
editable=True, blank=True, slugify=slugify_attr_name)
help_text = CharField(_('help text'), max_length=250, blank=True,
help_text=_('short description for administrator'))
datatype = CharField(_('data type'), max_length=5, choices=DATATYPE_CHOICES)
required = BooleanField(_('required'), default=False)
searched = BooleanField(_('include in search'), default=False) # i.e. full-text search? mb for text only
filtered = BooleanField(_('include in filters'), default=False)
sortable = BooleanField(_('allow sorting'), default=False)
class Meta:
abstract = True
verbose_name, verbose_name_plural = _('schema'), _('schemata')
ordering = ['title']
def __unicode__(self):
return u'%s (%s)%s' % (self.title, self.get_datatype_display(),
u' %s'%_('required') if self.required else '')
def get_choices(self):
"""
Returns a queryset of choice objects bound to this schema.
"""
return self.choices.all()
def get_attrs(self, entity):
"""
Returns available attributes for given entity instance.
Handles many-to-one relations transparently.
"""
return self.attrs.filter(**get_entity_lookups(entity))
def save_attr(self, entity, value):
"""
Saves given EAV attribute with given value for given entity.
If schema is not a choice, the value is saved to the corresponding
Attr instance (which is created or updated).
If schema is an cvhoice (one-to-one or many-to-one), the value is
processed thusly:
* if value is iterable, all Attr instances for corresponding managed choice
schemata are updated (those with names from the value list are set to
True, others to False). If a list item is not in available choices,
ValueError is raised;
* if the value is None, all corresponding Attr instances are reset to False;
* if the value is neither a list nor None, it is wrapped into a list and
processed as above (i.e. "foo" --> ["foo"]).
"""
if self.datatype in (self.TYPE_ONE, self.TYPE_MANY):
self._save_choice_attr(entity, value)
else:
self._save_single_attr(entity, value)
def _save_single_attr(self, entity, value=None, schema=None,
create_nulls=False, extra={}):
"""
Creates or updates an EAV attribute for given entity with given value.
:param schema: schema for attribute. Default it current schema instance.
:param create_nulls: boolean: if True, even attributes with value=None
are created (by default they are skipped).
:param extra: dict: additional data for Attr instance (e.g. title).
"""
# If schema is not many-to-one, the value is saved to the corresponding
# Attr instance (which is created or updated).
schema = schema or self
lookups = dict(get_entity_lookups(entity), schema=schema, **extra)
try:
attr = self.attrs.get(**lookups)
except self.attrs.model.DoesNotExist:
attr = self.attrs.model(**lookups)
if create_nulls or value != attr.value:
attr.value = value
for k,v in extra.items():
setattr(attr, k, v)
attr.save()
def _save_choice_attr(self, entity, value):
"""
Creates or updates BaseChoice(s) attribute(s) for given entity.
"""
# value can be None to reset choices from schema
if value == None:
value = []
if not hasattr(value, '__iter__'):
value = [value]
if self.datatype == self.TYPE_ONE and len(value) > 1:
raise TypeError('Cannot assign multiple values "%s" to TYPE_ONE '
'must be only one BaseChoice instance.'
% value)
if not all(isinstance(x, BaseChoice) for x in value):
raise TypeError('Cannot assign "%s": "Attr.choice" '
'must be a BaseChoice instance.'
% value)
# drop all attributes for this entity/schema pair
self.get_attrs(entity).delete()
# Attr instances for corresponding managed choice schemata are updated
for choice in value:
self._save_single_attr(
entity,
schema = self,
create_nulls = True,
extra = {'choice': choice}
)
class BaseEntity(Model):
"""
Entity, the "E" in EAV. This model is abstract and must be subclassed.
See tests for examples.
"""
objects = BaseEntityManager()
class Meta:
abstract = True
def save(self, force_eav=False, **kwargs):
"""
Saves entity instance and creates/updates related attribute instances.
:param eav: if True (default), EAV attributes are saved along with entity.
"""
# save entity
super(BaseEntity, self).save(**kwargs)
# TODO: think about use cases; are we doing it right?
#if not self.check_eav_allowed():
# import warnings
# warnings.warn('EAV attributes are going to be saved along with entity'
# ' despite %s.check_eav_allowed() returned False.'
# % type(self), RuntimeWarning)
# create/update EAV attributes
for schema in self.get_schemata():
value = getattr(self, schema.name, None)
schema.save_attr(self, value)
def __getattr__(self, name):
if not name.startswith('_'):
if name in self.get_schema_names():
schema = self.get_schema(name)
attrs = schema.get_attrs(self)
if schema.datatype == schema.TYPE_MANY:
return [a.value for a in attrs if a.value]
else:
return attrs[0].value if attrs else None
raise AttributeError('%s does not have attribute named "%s".' %
(self._meta.object_name, name))
def __iter__(self):
"Iterates over non-empty EAV attributes. Normal fields are not included."
for attr in self.attrs.select_related():
if getattr(self, attr.schema.name, None):
yield attr
@classmethod
def get_schemata_for_model(cls):
return NotImplementedError('BaseEntity subclasses must define method '
'"get_schemata_for_model" which returns a '
'QuerySet for a BaseSchema subclass.')
def get_schemata_for_instance(self, qs):
return qs
def get_schemata(self):
if hasattr(self, '_schemata_cache') and self._schemata_cache is not None:
return self._schemata_cache
all_schemata = self.get_schemata_for_model().select_related()
self._schemata_cache = self.get_schemata_for_instance(all_schemata)
self._schemata_cache_dict = dict((s.name, s) for s in self._schemata_cache)
return self._schemata_cache
def get_schema_names(self):
if not hasattr(self, '_schemata_cache_dict'):
self.get_schemata()
return self._schemata_cache_dict.keys()
def get_schema(self, name):
if not hasattr(self, '_schemata_cache_dict'):
self.get_schemata()
return self._schemata_cache_dict[name]
def get_schema_by_id(self, schema_id):
for schema in self.get_schemata():
if schema.pk == schema_id:
return schema
def check_eav_allowed(self):
"""
Returns True if entity instance allows EAV attributes to be attached.
Can be useful if some external data is required to determine available
schemata and that data may be missing. In such cases this method should
be overloaded to check whether the data is available.
"""
return True
def is_valid(self):
"Returns True if attributes and their values conform with schema."
raise NotImplementedError()
'''
schemata = self.rubric.schemata.all()
return all(x.is_valid for x in self.attributes)
# 1. check if all required attributes are present
for schema in schemata:
pass
# 2. check if all attributes have appropriate values
for schema in schemata:
pass
return True
'''
class BaseChoice(Model):
""" Base class for choices. Concrete choice class must overload the
`schema` attribute.
"""
title = CharField(max_length=100)
schema = NotImplemented
class Meta:
abstract = True
ordering = ('title',)
def __unicode__(self):
return self.title #u'%s "%s"' % (self.schema.title, self.title)
class BaseAttribute(Model):
""" Base class for choices. Concrete choice class must overload the
`schema` and `choice` attributes.
"""
entity_type = ForeignKey(ContentType)
entity_id = IntegerField()
entity = fields.GenericForeignKey(ct_field="entity_type", fk_field='entity_id')
value_text = TextField(blank=True, null=True)
value_float = FloatField(blank=True, null=True)
value_date = DateField(blank=True, null=True)
value_bool = NullBooleanField(blank=True) # TODO: ensure that form invalidates null booleans (??)
value_range_min = FloatField(blank=True, null=True)
value_range_max = FloatField(blank=True, null=True)
schema = NotImplemented # must be FK
choice = NotImplemented # must be nullable FK
class Meta:
abstract = True
verbose_name, verbose_name_plural = _('attribute'), _('attributes')
ordering = ['entity_type', 'entity_id', 'schema']
unique_together = ('entity_type', 'entity_id', 'schema', 'choice')
def __unicode__(self):
return u'%s: %s "%s"' % (self.entity, self.schema.title, self.value)
def _get_value(self):
if self.schema.datatype in (self.schema.TYPE_ONE, self.schema.TYPE_MANY):
return self.choice
if self.schema.datatype == self.schema.TYPE_RANGE:
names = ('value_range_%s' % x for x in ('min', 'max'))
value = tuple(getattr(self, x, None) for x in names)
return None if value == (None, None) else value
return getattr(self, 'value_%s' % self.schema.datatype)
def _set_value(self, new_value):
if self.schema.datatype == self.schema.TYPE_RANGE:
new_value = new_value or (None, None)
# validate range value -- expecting a tuple of two numbers
try:
validate_range_value(new_value)
except (TypeError, ValueError):
raise
for k,v in zip('min max'.split(), new_value):
v = v if v is None else float(v)
setattr(self, 'value_range_%s' % k, v)
else:
setattr(self, 'value_%s' % self.schema.datatype, new_value)
value = property(_get_value, _set_value)
def validate_range_value(value):
"""
Validates given value against `Schema.TYPE_RANGE` data type. Raises
TypeError or ValueError if something is wrong. Returns None if everything
is OK.
"""
if value == (None, None):
return
if not hasattr(value, '__iter__'):
raise TypeError('Range value must be an iterable, got "%s".' % value)
if not 2 == len(value):
raise ValueError('Range value must consist of two elements, got %d.' %
len(value))
if not all(isinstance(x, (int,float)) for x in value):
raise TypeError('Range value must consist of two numbers, got "%s" '
'and "%s" instead.' % value)
if not value[0] <= value[1]:
raise ValueError('Range must consist of min and max values (min <= '
'max) but got "%s" and "%s" instead.' % value)
return
# xxx catch signal Attr.post_save() --> update attr.item.attribute_cache (JSONField or such)

2
scripts/importa_pesquisa.py

@ -29,6 +29,7 @@ from datetime import datetime
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.servidores.models import Servidor
def importa(file_list):
''' Este script importa dados de um arquivo CSV e dá carga no model casas.CasaLegislativa
@ -128,4 +129,3 @@ def importa(file_list):
casa.save()
print 'O arquivo '+filename+'.out foi criado com os registros que nao puderam ser importados'

1
scripts/servicos_seit_ate_2013_2014.py

@ -1,4 +1,5 @@
from datetime import date
from django.db.models import Q
from sigi.apps.servicos.models import TipoServico

1
scripts/setgerentes/dados_gerentes.py

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from sigi.apps.servidores.models import Servidor
gerentes = {k: Servidor.objects.get(nome_completo=n) for k, n in (
('ADAL', u'Adalberto Alves de Oliveira'),
('janarycn', u'Janary Carvão Nunes'),

2
scripts/user_from_session.py

@ -1,5 +1,5 @@
from django.contrib.sessions.models import Session
from django.contrib.auth.models import User
from django.contrib.sessions.models import Session
def user_from_session(session_key):

4
scripts/verificacao_arquivos_faltando_media.py

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*-
from datetime import datetime
# Dependência:
# pip install terminaltables
from os.path import isfile
from datetime import datetime
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
from terminaltables import AsciiTable
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.convenios.models import Anexo as AnexoConvenios
@ -15,6 +14,7 @@ from sigi.apps.diagnosticos.models import Anexo as AnexoDiagnosticos
from sigi.apps.ocorrencias.models import Anexo as AnexoOcorrencias
from sigi.apps.parlamentares.models import Parlamentar
from sigi.apps.servidores.models import Servidor
from terminaltables import AsciiTable
def print_table(msg, relacao):

1
setup.py

@ -4,5 +4,4 @@
#
from distutils.core import setup
setup(name='sigi', version='2.x')

15
sigi/apps/casas/admin.py

@ -1,16 +1,17 @@
# -*- coding: utf-8 -*-
from django.core.urlresolvers import reverse
from django.contrib import admin
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.admin import GenericTabularInline
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext as _
from image_cropping import ImageCroppingMixin
from sigi.apps.casas.forms import CasaLegislativaForm
from sigi.apps.casas.models import CasaLegislativa, Presidente, Funcionario, TipoCasaLegislativa
from sigi.apps.casas.views import report_complete, labels_report, export_csv, \
labels_report_sem_presidente, report, \
adicionar_casas_carrinho
from sigi.apps.casas.models import (CasaLegislativa, Funcionario, Presidente,
TipoCasaLegislativa)
from sigi.apps.casas.views import (adicionar_casas_carrinho, export_csv,
labels_report, labels_report_sem_presidente,
report, report_complete)
from sigi.apps.contatos.models import Telefone
from sigi.apps.convenios.models import Convenio
from sigi.apps.diagnosticos.models import Diagnostico
@ -24,7 +25,7 @@ from sigi.apps.utils import queryset_ascii
from sigi.apps.utils.base_admin import BaseModelAdmin
class TelefonesInline(generic.GenericTabularInline):
class TelefonesInline(GenericTabularInline):
model = Telefone
readonly_fields = ('ult_alteracao',)
extra = 1

7
sigi/apps/casas/management/commands/importa_gerentes.py

@ -24,10 +24,13 @@
import csv
import os
from django.core.management.base import BaseCommand, CommandError
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.servidores.models import Servidor
from sigi.apps.contatos.models import Municipio
from sigi.apps.servidores.models import Servidor
class Command(BaseCommand):
args = u"data_file.csv"
@ -81,4 +84,4 @@ class Command(BaseCommand):
casa.gerente_contas = gerente
casa.save()
self.stdout.write(u"Importação concluída. %s erros em %s linhas" % (erros, reader.line_num,))
self.stdout.write(u"Importação concluída. %s erros em %s linhas" % (erros, reader.line_num,))

12
sigi/apps/casas/models.py

@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
import random
from datetime import datetime
from string import ascii_uppercase
from unicodedata import normalize
from datetime import datetime
from django.contrib.contenttypes import generic
from django.contrib.contenttypes import fields
from django.db import models
from image_cropping import ImageRatioField
@ -85,7 +85,7 @@ class CasaLegislativa(models.Model):
pesquisador = models.ForeignKey(Servidor, verbose_name=u"Pesquisador", null=True, blank=True)
obs_pesquisa = models.TextField(u"Observações do pesquisador", blank=True)
ult_alt_endereco = models.DateTimeField(u'Última alteração do endereço', null=True, blank=True, editable=True)
telefones = generic.GenericRelation('contatos.Telefone')
telefones = fields.GenericRelation('contatos.Telefone')
foto = models.ImageField(
upload_to='imagens/casas',
@ -243,7 +243,7 @@ class CasaLegislativa(models.Model):
return codigo
def __unicode__(self):
return self.nome
return self.nome + ' - ' + self.municipio.uf.sigla
def save(self, *args, **kwargs):
address_changed = False
@ -293,8 +293,8 @@ class Funcionario(models.Model):
sexo = models.CharField(max_length=1, choices=SEXO_CHOICES, default="M")
nota = models.CharField(max_length=70, null=True, blank=True)
email = models.CharField('e-mail', max_length=75, blank=True)
telefones = generic.GenericRelation('contatos.Telefone')
endereco = generic.GenericRelation('contatos.Endereco')
telefones = fields.GenericRelation('contatos.Telefone')
endereco = fields.GenericRelation('contatos.Endereco')
cargo = models.CharField(max_length=100, null=True, blank=True)
funcao = models.CharField(u'função', max_length=100, null=True, blank=True)
setor = models.CharField(max_length=100, choices=SETOR_CHOICES, default="outros")

4
sigi/apps/casas/reports.py

@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
from django.templatetags.static import static
from django.utils.translation import ugettext as _
from geraldo import Report, DetailBand, Label, ObjectValue, ReportGroup, ReportBand, landscape, SubReport, BAND_WIDTH, SystemField
from geraldo import (BAND_WIDTH, DetailBand, Label, ObjectValue, Report,
ReportBand, ReportGroup, SubReport, SystemField,
landscape)
from geraldo.graphics import Image
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.pagesizes import A4

3
sigi/apps/casas/test_casas.py

@ -14,4 +14,5 @@ def some_parliaments():
def parliaments_from_names(names):
return [G(CasaLegislativa, nome=name, foto=None, gerente_contas=None,) for name in names]
return [G(CasaLegislativa, nome=name, foto=None, gerente_contas=None,
pesquisador=None,) for name in names]

41
sigi/apps/casas/urls.py

@ -1,38 +1,37 @@
# coding: utf-8
from django.conf.urls import patterns, url
from django.conf.urls import url
from sigi.apps.casas import views
urlpatterns = patterns(
'sigi.apps.casas.views',
urlpatterns = [
# Informacoes de uma casa legislativa
url(r'^casalegislativa/report_complete/$', 'report_complete', name='report-complete-all'),
url(r'^casalegislativa/(?P<id>\w+)/report_complete/$', 'report_complete', name='report-complete-id'),
url(r'^casalegislativa/report_complete/$', views.report_complete, name='report-complete-all'),
url(r'^casalegislativa/(?P<id>\w+)/report_complete/$', views.report_complete, name='report-complete-id'),
# Reports Labels
url(r'^casalegislativa/labels/$', 'labels_report', name='labels-report-all'),
url(r'^casalegislativa/(?P<id>\w+)/labels/$', 'labels_report', name='labels-report-id'),
url(r'^casalegislativa/labels/$', views.labels_report, name='labels-report-all'),
url(r'^casalegislativa/(?P<id>\w+)/labels/$', views.labels_report, name='labels-report-id'),
# Reports Labels Parlamentar
url(r'^casalegislativa/labels_parlamentar/$', 'labels_report_parlamentar', name='lebels-report-parlamentar-all'),
url(r'^casalegislativa/(?P<id>\w+)/labels_parlamentar/$', 'labels_report_parlamentar', name='labels-report-parlamentar-id'),
url(r'^casalegislativa/labels_parlamentar/$', views.labels_report_parlamentar, name='lebels-report-parlamentar-all'),
url(r'^casalegislativa/(?P<id>\w+)/labels_parlamentar/$', views.labels_report_parlamentar, name='labels-report-parlamentar-id'),
# Reports labels sem presidente
url(r'^casalegislativa/labels_sem_presidente/$', 'labels_report_sem_presidente', name='labels-report-sem-presidente-all'),
url(r'^casalegislativa/(?P<id>\w+)/labels_sem_presidente/$', 'labels_report_sem_presidente', name='labels-report-sem-presidente-id'),
url(r'^casalegislativa/labels_sem_presidente/$', views.labels_report_sem_presidente, name='labels-report-sem-presidente-all'),
url(r'^casalegislativa/(?P<id>\w+)/labels_sem_presidente/$', views.labels_report_sem_presidente, name='labels-report-sem-presidente-id'),
# Reports casas sem convenio
url(r'^casalegislativa/reports/$', 'report', name='casa-report'),
url(r'^casalegislativa/casas_sem_convenio_report/$', 'casas_sem_convenio_report', name='casas-sem-convenio-report'),
url(r'^casalegislativa/reports/$', views.report, name='casa-report'),
url(r'^casalegislativa/casas_sem_convenio_report/$', views.casas_sem_convenio_report, name='casas-sem-convenio-report'),
# CSV
url(r'^casalegislativa/csv/$', 'export_csv', name='casa-export-csv'), # Error
url(r'^casalegislativa/csv/$', views.export_csv, name='casa-export-csv'), # Error
# Carrinho
url(r'^casalegislativa/carrinho/$', 'visualizar_carrinho', name='visualizar-carrinho'),
url(r'^casalegislativa/carrinho/excluir_carrinho/$', 'excluir_carrinho', name='excluir-carrinho'), # Error
url(r'^casalegislativa/carrinho/deleta_itens_carrinho$', 'deleta_itens_carrinho', name='deleta-itens-carrinho'), # Error
url(r'^portfolio/$', 'portfolio', name='casas-portfolio'),
url(r'^carteira/$', 'painel_relacionamento', name='casas-carteira'),
)
url(r'^casalegislativa/carrinho/$', views.visualizar_carrinho, name='visualizar-carrinho'),
url(r'^casalegislativa/carrinho/excluir_carrinho/$', views.excluir_carrinho, name='excluir-carrinho'), # Error
url(r'^casalegislativa/carrinho/deleta_itens_carrinho$', views.deleta_itens_carrinho, name='deleta-itens-carrinho'), # Error
url(r'^portfolio/$', views.portfolio, name='casas-portfolio'),
url(r'^carteira/$', views.painel_relacionamento, name='casas-carteira'),
]

30
sigi/apps/casas/views.py

@ -2,23 +2,29 @@
import csv
from functools import reduce
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext as _, ungettext
from django.contrib.auth.decorators import login_required
from django.core.paginator import EmptyPage, InvalidPage, Paginator
from django.db.models import Count, Q
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.http.response import JsonResponse
from django.shortcuts import get_object_or_404, render
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from geraldo.generators import PDFGenerator
from sigi.apps.casas.forms import PortfolioForm
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.casas.reports import CasasLegislativasLabels, CasasLegislativasLabelsSemPresidente, CasasLegislativasReport, CasasSemConvenioReport, InfoCasaLegislativa
from sigi.apps.casas.reports import (CasasLegislativasLabels,
CasasLegislativasLabelsSemPresidente,
CasasLegislativasReport,
CasasSemConvenioReport,
InfoCasaLegislativa)
from sigi.apps.contatos.models import (Mesorregiao, Microrregiao,
UnidadeFederativa)
from sigi.apps.ocorrencias.models import Ocorrencia
from sigi.apps.parlamentares.reports import ParlamentaresLabels
from sigi.apps.contatos.models import UnidadeFederativa, Mesorregiao, Microrregiao
from sigi.apps.casas.forms import PortfolioForm
from django.contrib.auth.decorators import login_required
from sigi.apps.servicos.models import TipoServico
from sigi.apps.servidores.models import Servidor
from sigi.apps.ocorrencias.models import Ocorrencia
from django.db.models import Count, Q
from django.http.response import JsonResponse
# @param qs: queryset
@ -678,4 +684,4 @@ def painel_relacionamento(request):
if snippet == 'resumo':
return render(request, 'casas/resumo_carteira_snippet.html', context)
return render(request, 'casas/painel.html', context)
return render(request, 'casas/painel.html', context)

5
sigi/apps/contatos/admin.py

@ -3,11 +3,12 @@ from django.contrib import admin
from django.utils.translation import ugettext as _
from sigi.apps.contatos.filters import PopulationFilter
from sigi.apps.contatos.models import (UnidadeFederativa, Mesorregiao, Microrregiao,
Municipio, Telefone, Contato)
from sigi.apps.contatos.models import (Contato, Mesorregiao, Microrregiao,
Municipio, Telefone, UnidadeFederativa)
from sigi.apps.utils import queryset_ascii
from sigi.apps.utils.base_admin import BaseModelAdmin
class MesorregiaoInline(admin.TabularInline):
model = Mesorregiao

8
sigi/apps/contatos/management/commands/importa_mesomicro.py

@ -23,8 +23,12 @@
#
import csv
import os
from django.core.management.base import BaseCommand, CommandError
from sigi.apps.contatos.models import Municipio, UnidadeFederativa, Mesorregiao, Microrregiao
from sigi.apps.contatos.models import (Mesorregiao, Microrregiao, Municipio,
UnidadeFederativa)
class Command(BaseCommand):
args = u"data_file.csv"
@ -97,4 +101,4 @@ class Command(BaseCommand):
municipio.microrregiao = micro
municipio.save()
self.stdout.write(u"Importação concluída. %s erros em %s linhas" % (erros, reader.line_num,))
self.stdout.write(u"Importação concluída. %s erros em %s linhas" % (erros, reader.line_num,))

20
sigi/apps/contatos/migrations/0003_auto_20160623_0829.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-23 08:29
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('contatos', '0002_auto_20151104_0810'),
]
operations = [
migrations.AlterField(
model_name='contato',
name='email',
field=models.EmailField(blank=True, max_length=254, verbose_name='e-mail'),
),
]

10
sigi/apps/contatos/models.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from django.contrib.contenttypes import generic
from django.contrib.contenttypes import fields
from django.contrib.contenttypes.models import ContentType
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
@ -176,7 +176,7 @@ class Telefone(models.Model):
content_type = models.ForeignKey(ContentType)
# identificador do registro na classe vinculado a esse registro
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
content_object = fields.GenericForeignKey('content_type', 'object_id')
class Meta:
ordering = ('numero',)
@ -196,7 +196,7 @@ class Contato(models.Model):
nota = models.CharField(max_length=70, blank=True)
email = models.EmailField(_(u'e-mail'), blank=True)
telefones = generic.GenericRelation(Telefone)
telefones = fields.GenericRelation(Telefone)
municipio = models.ForeignKey(
Municipio,
@ -209,7 +209,7 @@ class Contato(models.Model):
content_type = models.ForeignKey(ContentType)
# identificador do registro na classe vinculado a esse registro
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
content_object = fields.GenericForeignKey('content_type', 'object_id')
class Meta:
ordering = ('nome',)
@ -301,7 +301,7 @@ class Endereco(models.Model):
content_type = models.ForeignKey(ContentType)
# identificador do registro na classe vinculado a esse registro
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
content_object = fields.GenericForeignKey('content_type', 'object_id')
class Meta:
ordering = ('logradouro', 'numero')

3
sigi/apps/convenios/admin.py

@ -4,7 +4,8 @@ from django.http import HttpResponse, HttpResponseRedirect
from django.utils.translation import ugettext as _
from geraldo.generators import PDFGenerator
from sigi.apps.convenios.models import Projeto, Convenio, EquipamentoPrevisto, Anexo, Tramitacao
from sigi.apps.convenios.models import (Anexo, Convenio, EquipamentoPrevisto,
Projeto, Tramitacao)
from sigi.apps.convenios.reports import ConvenioReport
from sigi.apps.convenios.views import adicionar_convenios_carrinho
from sigi.apps.utils import queryset_ascii

38
sigi/apps/convenios/migrations/0002_auto_20160616_1602.py

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('convenios', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='anexo',
name='descricao',
field=models.CharField(max_length=70, verbose_name='descri\xe7\xe3o'),
preserve_default=True,
),
migrations.AlterField(
model_name='tramitacao',
name='observacao',
field=models.CharField(max_length=512, null=True, verbose_name='observa\xe7\xe3o', blank=True),
preserve_default=True,
),
migrations.AlterField(
model_name='unidadeadministrativa',
name='nome',
field=models.CharField(max_length=100),
preserve_default=True,
),
migrations.AlterField(
model_name='unidadeadministrativa',
name='sigla',
field=models.CharField(max_length=10),
preserve_default=True,
),
]

9
sigi/apps/convenios/models.py

@ -1,5 +1,6 @@
# style="list-style-type: noneo -*- coding: utf-8 -*-
from datetime import datetime
from django.db import models
from django.utils.translation import ugettext as _
@ -148,7 +149,7 @@ class Anexo(models.Model):
convenio = models.ForeignKey(Convenio, verbose_name=_(u'convênio'))
# caminho no sistema para o documento anexo
arquivo = models.FileField(upload_to='apps/convenios/anexo/arquivo', max_length=500)
descricao = models.CharField(_(u'descrição'), max_length='70')
descricao = models.CharField(_(u'descrição'), max_length=70)
data_pub = models.DateTimeField(
_(u'data da publicação do anexo'),
default=datetime.now
@ -167,8 +168,8 @@ class UnidadeAdministrativa(models.Model):
que pode ser um servivo do próprio Interlegis, assim como
uma unidade do Senado Federal
"""
sigla = models.CharField(max_length='10')
nome = models.CharField(max_length='100')
sigla = models.CharField(max_length=10)
nome = models.CharField(max_length=100)
def __unicode__(self):
return unicode(self.sigla)
@ -184,7 +185,7 @@ class Tramitacao(models.Model):
data = models.DateField()
observacao = models.CharField(
_(u'observação'),
max_length='512',
max_length=512,
null=True,
blank=True,
)

3
sigi/apps/convenios/reports.py

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from django.utils.translation import ugettext as _
from geraldo import ReportBand, ObjectValue, Label, ReportGroup, FIELD_ACTION_SUM
from geraldo import (FIELD_ACTION_SUM, Label, ObjectValue, ReportBand,
ReportGroup)
from reportlab.lib.units import cm
from sigi.apps.relatorios.reports import ReportDefault

2
sigi/apps/convenios/templates/convenios/change_list.html

@ -5,7 +5,7 @@
<div id="toolbar">
<form id="changelist-search" action="" method="get">
<div><!-- DIV needed for valid HTML -->
<label for="searchbar"><img src="/static/admin/img/icon_searchbox.png" alt="Search" /></label>
<label for="searchbar"><img src="/static/admin/img/search.svg" alt="Search" /></label>
<input type="text" size="40" name="q" value="" id="searchbar" />
<label for="data_retorno_assinatura__gte">{% trans 'Conveniadas a partir de' %}:</label>
<input type="text" size="10" name="data_retorno_assinatura__gte" value="" id="data_retorno_assinatura__gte" class="vDateField"/>

22
sigi/apps/convenios/urls.py

@ -1,14 +1,12 @@
# coding: utf-8
from django.conf.urls import patterns, url
from django.conf.urls import url
from sigi.apps.convenios import views
urlpatterns = patterns(
'sigi.apps.convenios.views',
url(r'^convenio/reports/$', 'report', name='convenios-report'),
url(r'^convenio/carrinho/$', 'visualizar_carrinho', name='visualizar-carrinho'),
url(r'^convenio/carrinho/excluir_carrinho/$', 'excluir_carrinho', name='excluir-carrinho'), # tagerror
url(r'^convenio/carrinho/deleta_itens_carrinho$', 'deleta_itens_carrinho', name='deleta-itens-carrinho'), # tagerror
url(r'^convenio/csv/$', 'export_csv', name='convenios-csv'),
url(r'^reportsRegiao/(?P<regiao>\w+)/$', 'report_regiao', name='convenios-report_regiao_pdf'),
)
urlpatterns = [
url(r'^convenio/reports/$', views.report, name='convenios-report'),
url(r'^convenio/carrinho/$', views.visualizar_carrinho, name='visualizar-carrinho'),
url(r'^convenio/carrinho/excluir_carrinho/$', views.excluir_carrinho, name='excluir-carrinho'), # tagerror
url(r'^convenio/carrinho/deleta_itens_carrinho$', views.deleta_itens_carrinho, name='deleta-itens-carrinho'), # tagerror
url(r'^convenio/csv/$', views.export_csv, name='convenios-csv'),
url(r'^reportsRegiao/(?P<regiao>\w+)/$', views.report_regiao, name='convenios-report_regiao_pdf'),
]

13
sigi/apps/convenios/views.py

@ -1,12 +1,13 @@
#-*- coding:utf-8 -*-
import csv
import datetime
import ho.pisa as pisa
from django.conf import settings
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.contrib.auth.decorators import login_required
from django.core.paginator import EmptyPage, InvalidPage, Paginator
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_list_or_404
from django.shortcuts import get_list_or_404, render
from django.template import Context, loader
from django.utils.translation import ugettext as _
from geraldo.generators import PDFGenerator
@ -14,8 +15,10 @@ from geraldo.generators import PDFGenerator
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.contatos.models import UnidadeFederativa
from sigi.apps.convenios.models import Convenio, Projeto
from sigi.apps.convenios.reports import ConvenioPorCMReport, ConvenioPorALReport, ConvenioReportSemAceiteAL, ConvenioReportSemAceiteCM
from django.contrib.auth.decorators import login_required
from sigi.apps.convenios.reports import (ConvenioPorALReport,
ConvenioPorCMReport,
ConvenioReportSemAceiteAL,
ConvenioReportSemAceiteCM)
def query_ordena(qs, o, ot):

176
sigi/apps/crispy_layout_mixin.py

@ -0,0 +1,176 @@
# -*- coding: utf-8 -*-
from math import ceil
from os.path import dirname, join
import rtyaml
from crispy_forms.bootstrap import FormActions
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit
from django.utils import formats
from django.utils.translation import ugettext as _
def heads_and_tails(list_of_lists):
for alist in list_of_lists:
yield alist[0], alist[1:]
def to_column(name_span):
fieldname, span = name_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-fluid')
def to_fieldsets(fields):
for field in fields:
if isinstance(field, list):
legend, row_specs = field[0], field[1:]
rows = [to_row(name_span_list) for name_span_list in row_specs]
yield Fieldset(legend, *rows)
else:
yield field
def form_actions(more=[], save_label=_('Salvar')):
return FormActions(
Submit('salvar', save_label, css_class='pull-right'), *more)
class FormLayout(Layout):
def __init__(self, *fields):
buttons = form_actions(more=[
HTML('<a href="{{ view.cancel_url }}"'
' class="btn btn-primary" style="background-color:black;">'
' Cancelar</a>')])
_fields = list(to_fieldsets(fields)) + [to_row([(buttons, 12)])]
super(FormLayout, self).__init__(*_fields)
def get_field_display(obj, fieldname):
field = obj._meta.get_field(fieldname)
verbose_name = str(field.verbose_name)
if field.choices:
value = getattr(obj, 'get_%s_display' % fieldname)()
else:
value = getattr(obj, fieldname)
if value is None:
display = ''
elif 'date' in str(type(value)):
display = formats.date_format(value, "SHORT_DATE_FORMAT")
elif 'bool' in str(type(value)):
display = _(u'Sim') if value else _(u'Não')
elif 'ImageFieldFile' in str(type(value)):
if value:
display = '<img src="{}" />'.format(value.url)
else:
display = ''
elif 'FieldFile' in str(type(value)):
if value:
display = '<a href="{}">{}</a>'.format(
value.url,
value.name.split('/')[-1:][0])
else:
display = ''
else:
display = str(value)
return verbose_name, display
class CrispyLayoutFormMixin(object):
@property
def layout_key(self):
if hasattr(super(CrispyLayoutFormMixin, self), 'layout_key'):
return super(CrispyLayoutFormMixin, self).layout_key
else:
return self.model.__name__
def get_layout(self):
filename = join(
dirname(self.model._meta.app_config.models_module.__file__),
'layouts.yaml')
return read_layout_from_yaml(filename, self.layout_key)
@property
def fields(self):
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]
def get_form(self, form_class=None):
try:
form = super(CrispyLayoutFormMixin, self).get_form(form_class)
except AttributeError:
# simply return None if there is no get_form on super
pass
else:
form.helper = FormHelper()
form.helper.layout = FormLayout(*self.get_layout())
return form
@property
def list_field_names(self):
'''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()[0][1:]
return [fieldname for row in rows for fieldname, __ in row]
def get_column(self, fieldname, span):
obj = self.get_object()
verbose_name, text = get_field_display(obj, fieldname)
return {
'id': fieldname,
'span': span,
'verbose_name': verbose_name,
'text': text,
}
@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())]
def read_yaml_from_file(filename):
# TODO cache this at application level
with open(filename, 'r') as yamlfile:
return rtyaml.load(yamlfile)
def read_layout_from_yaml(filename, key):
# TODO cache this at application level
yaml = read_yaml_from_file(filename)
base = yaml[key]
def line_to_namespans(line):
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]]
while nondefined:
span = ceil(remaining / len(nondefined))
namespan = nondefined.pop(0)
namespan[1] = span
remaining = remaining - span
return list(map(tuple, namespans))
return [[legend] + [line_to_namespans(l) for l in lines]
for legend, lines in base.items()]

0
sigi/apps/crud/__init__.py

227
sigi/apps/crud/base.py

@ -0,0 +1,227 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from braces.views import FormMessagesMixin
from django.conf.urls import url
from django.core.urlresolvers import reverse
from django.utils.decorators import classonlymethod
from django.utils.translation import ugettext_lazy as _
from django.views.generic import (CreateView, DeleteView, DetailView, ListView,
UpdateView)
from sigi.apps.crispy_layout_mixin import (CrispyLayoutFormMixin,
get_field_display)
from .utils import make_pagination
LIST, CREATE, DETAIL, UPDATE, DELETE = \
u'list', u'create', u'detail', u'update', u'delete'
def _form_invalid_message(msg):
return u'%s %s' % (_(u'Formulário inválido.'), msg)
FORM_MESSAGES = {CREATE: (_(u'Registro criado com sucesso!'),
_(u'O registro não foi criado.')),
UPDATE: (_(u'Registro alterado com sucesso!'),
_(u'Suas alterações não foram salvas.')),
DELETE: (_(u'Registro excluído com sucesso!'),
_(u'O registro não foi excluído.'))}
FORM_MESSAGES = dict((k, (a, _form_invalid_message(b)))
for k, (a, b) in FORM_MESSAGES.items())
class CrudBaseMixin(CrispyLayoutFormMixin):
@classmethod
def url_name(cls, suffix):
return u'%s_%s' % (cls.model._meta.model_name, suffix)
def resolve_url(self, suffix, args=None):
namespace = self.model._meta.app_label
return reverse(u'%s:%s' % (namespace, self.url_name(suffix)),
args=args)
@property
def list_url(self):
return self.resolve_url(LIST)
@property
def create_url(self):
return self.resolve_url(CREATE)
@property
def detail_url(self):
return self.resolve_url(DETAIL, args=(self.object.id,))
@property
def update_url(self):
return self.resolve_url(UPDATE, args=(self.object.id,))
@property
def delete_url(self):
return self.resolve_url(DELETE, args=(self.object.id,))
def get_template_names(self):
names = super(CrudBaseMixin, self).get_template_names()
names.append(u"crud/%s.html" %
self.template_name_suffix.lstrip(u'_'))
return names
@property
def verbose_name(self):
return self.model._meta.verbose_name
@property
def verbose_name_plural(self):
return self.model._meta.verbose_name_plural
class CrudListView(ListView):
@classmethod
def get_url_regex(cls):
return ur'^$'
paginate_by = 10
no_entries_msg = _(u'Nenhum registro encontrado.')
def get_rows(self, object_list):
return [self._as_row(obj) for obj in object_list]
def get_headers(self):
return [self.model._meta.get_field(fieldname).verbose_name
for fieldname in self.list_field_names]
def _as_row(self, obj):
return [
(get_field_display(obj, name)[1],
self.resolve_url(DETAIL, args=(obj.id,)) if i == 0 else None)
for i, name in enumerate(self.list_field_names)]
def get_context_data(self, **kwargs):
context = super(CrudListView, self).get_context_data(**kwargs)
context.setdefault(u'title', self.verbose_name_plural)
# pagination
if self.paginate_by:
page_obj = context[u'page_obj']
paginator = context[u'paginator']
context[u'page_range'] = make_pagination(
page_obj.number, paginator.num_pages)
# rows
object_list = context[u'object_list']
context[u'headers'] = self.get_headers()
context[u'rows'] = self.get_rows(object_list)
context[u'NO_ENTRIES_MSG'] = self.no_entries_msg
return context
class CrudCreateView(FormMessagesMixin, CreateView):
@classmethod
def get_url_regex(cls):
return ur'^create$'
form_valid_message, form_invalid_message = FORM_MESSAGES[CREATE]
@property
def cancel_url(self):
return '/atendimento'
def get_success_url(self):
return self.detail_url
def get_context_data(self, **kwargs):
kwargs.setdefault(u'title', _(u'Adicionar %(verbose_name)s') % {
u'verbose_name': self.verbose_name})
return super(CrudCreateView, self).get_context_data(**kwargs)
class CrudDetailView(DetailView):
@classmethod
def get_url_regex(cls):
return ur'^(?P<pk>\d+)$'
class CrudUpdateView(FormMessagesMixin, UpdateView):
@classmethod
def get_url_regex(cls):
return ur'^(?P<pk>\d+)/edit$'
form_valid_message, form_invalid_message = FORM_MESSAGES[UPDATE]
@property
def cancel_url(self):
return self.detail_url
def get_success_url(self):
return self.detail_url
class CrudDeleteView(FormMessagesMixin, DeleteView):
@classmethod
def get_url_regex(cls):
return ur'^(?P<pk>\d+)/delete$'
form_valid_message, form_invalid_message = FORM_MESSAGES[DELETE]
@property
def cancel_url(self):
return self.detail_url
def get_success_url(self):
return self.list_url
class Crud(object):
BaseMixin = CrudBaseMixin
ListView = CrudListView
CreateView = CrudCreateView
DetailView = CrudDetailView
UpdateView = CrudUpdateView
DeleteView = CrudDeleteView
help_path = u''
@classonlymethod
def get_urls(cls):
def _add_base(view):
class CrudViewWithBase(cls.BaseMixin, view):
model = cls.model
help_path = cls.help_path
crud = cls
CrudViewWithBase.__name__ = view.__name__
return CrudViewWithBase
CrudListView = _add_base(cls.ListView)
CrudCreateView = _add_base(cls.CreateView)
CrudDetailView = _add_base(cls.DetailView)
CrudUpdateView = _add_base(cls.UpdateView)
CrudDeleteView = _add_base(cls.DeleteView)
return [url(regex, view.as_view(), name=view.url_name(suffix))
for regex, view, suffix in [
(CrudListView.get_url_regex(), CrudListView, LIST),
(CrudCreateView.get_url_regex(), CrudCreateView, CREATE),
(CrudDetailView.get_url_regex(), CrudDetailView, DETAIL),
(CrudUpdateView.get_url_regex(), CrudUpdateView, UPDATE),
(CrudDeleteView.get_url_regex(), CrudDeleteView, DELETE),
]]
@classonlymethod
def build(cls, _model, _help_path):
class ModelCrud(cls):
model = _model
help_path = _help_path
ModelCrud.__name__ = u'%sCrud' % _model.__name__
return ModelCrud

7
sigi/apps/crud/urls.py

@ -0,0 +1,7 @@
from __future__ import absolute_import
from django.conf.urls import include, url
urlpatterns = [
url(ur'', include(u'stub_app.urls')),
]

66
sigi/apps/crud/utils.py

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from django.utils.translation import ugettext_lazy as _
UF = [
(u'AC', u'Acre'),
(u'AL', u'Alagoas'),
(u'AP', u'Amapá'),
(u'AM', u'Amazonas'),
(u'BA', u'Bahia'),
(u'CE', u'Ceará'),
(u'DF', u'Distrito Federal'),
(u'ES', u'Espírito Santo'),
(u'GO', u'Goiás'),
(u'MA', u'Maranhão'),
(u'MT', u'Mato Grosso'),
(u'MS', u'Mato Grosso do Sul'),
(u'MG', u'Minas Gerais'),
(u'PR', u'Paraná'),
(u'PB', u'Paraíba'),
(u'PA', u'Pará'),
(u'PE', u'Pernambuco'),
(u'PI', u'Piauí'),
(u'RJ', u'Rio de Janeiro'),
(u'RN', u'Rio Grande do Norte'),
(u'RS', u'Rio Grande do Sul'),
(u'RO', u'Rondônia'),
(u'RR', u'Roraima'),
(u'SC', u'Santa Catarina'),
(u'SE', u'Sergipe'),
(u'SP', u'São Paulo'),
(u'TO', u'Tocantins'),
(u'EX', u'Exterior'),
]
YES_NO_CHOICES = [(None, _(u'----')), (False, _(u'Não')), (True, _(u'Sim'))]
def str2bool(v):
return v in (u'Sim', u'True')
SEXO_CHOICES = [(u'M', _(u'Masculino')), (u'F', _(u'Feminino'))]
def from_to(start, end):
return range(start, end + 1)
def make_pagination(index, num_pages):
PAGINATION_LENGTH = 10
if num_pages <= PAGINATION_LENGTH:
return from_to(1, num_pages)
else:
if index - 1 <= 5:
tail = [num_pages - 1, num_pages]
head = from_to(1, PAGINATION_LENGTH - 3)
else:
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]
head = from_to(1, PAGINATION_LENGTH - len(tail) - 1)
return head + [None] + tail

4
sigi/apps/diagnosticos/admin.py

@ -1,12 +1,14 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from django.contrib import admin
from django.db.utils import OperationalError, ProgrammingError
from django.utils.translation import ugettext as _
from eav.admin import BaseEntityAdmin, BaseSchemaAdmin
from sigi.apps.diagnosticos.forms import DiagnosticoForm
from sigi.apps.diagnosticos.models import Diagnostico, Pergunta, Escolha, Equipe, Anexo, Categoria
from sigi.apps.diagnosticos.models import (Anexo, Categoria, Diagnostico,
Equipe, Escolha, Pergunta)
from sigi.apps.utils.base_admin import BaseModelAdmin

3
sigi/apps/diagnosticos/decorators.py

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
from django.template import RequestContext
from django.shortcuts import render_to_response
from django.template import RequestContext
from sigi.apps.diagnosticos.models import Diagnostico

10
sigi/apps/diagnosticos/forms.py

@ -2,10 +2,9 @@
from copy import deepcopy
from django import forms
from django.contrib.contenttypes.generic import generic_inlineformset_factory
from django.forms import (BooleanField, CharField, DateField,
FloatField, ModelChoiceField, Textarea,
ModelMultipleChoiceField)
from django.contrib.contenttypes.forms import generic_inlineformset_factory
from django.forms import (BooleanField, CharField, DateField, FloatField,
ModelChoiceField, ModelMultipleChoiceField, Textarea)
from django.forms.forms import BoundField
from django.utils.translation import ugettext as _
from eav.fields import RangeField
@ -14,7 +13,8 @@ from eav.forms import BaseDynamicEntityForm
from sigi.apps.casas.models import CasaLegislativa, Funcionario
from sigi.apps.contatos.models import Telefone
from sigi.apps.diagnosticos.models import Diagnostico
from sigi.apps.diagnosticos.widgets import EavCheckboxSelectMultiple, EavRadioSelect
from sigi.apps.diagnosticos.widgets import (EavCheckboxSelectMultiple,
EavRadioSelect)
class DiagnosticoForm(BaseDynamicEntityForm):

34
sigi/apps/diagnosticos/migrations/0002_auto_20160616_1602.py

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import autoslug.fields
import eav.models
class Migration(migrations.Migration):
dependencies = [
('diagnosticos', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='anexo',
name='descricao',
field=models.CharField(max_length=70, verbose_name='descri\xe7\xe3o'),
preserve_default=True,
),
migrations.AlterField(
model_name='escolha',
name='schema_to_open',
field=models.ForeignKey(related_name='schema_to_open_related', verbose_name='pergunta para abrir', blank=True, to='diagnosticos.Pergunta', null=True),
preserve_default=True,
),
migrations.AlterField(
model_name='pergunta',
name='name',
field=autoslug.fields.AutoSlugField(populate_from=b'title', editable=True, max_length=250, blank=True, verbose_name='name', slugify=eav.models.slugify_attr_name),
preserve_default=True,
),
]

7
sigi/apps/diagnosticos/models.py

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from django.db import models
from django.utils.translation import ugettext as _
from eav.models import BaseChoice, BaseEntity, BaseSchema, BaseAttribute
from eav.models import BaseAttribute, BaseChoice, BaseEntity, BaseSchema
from sigi.apps.utils import SearchField
from sigi.apps.utils.email import enviar_email
@ -198,7 +199,7 @@ class Escolha(BaseChoice):
"""
schema = models.ForeignKey(Pergunta,
related_name='choices', verbose_name=_(u'pergunta'))
schema_to_open = models.ForeignKey(Pergunta, related_name='',
schema_to_open = models.ForeignKey(Pergunta, related_name='schema_to_open_related',
verbose_name=_(u'pergunta para abrir'), blank=True, null=True)
ordem = models.PositiveIntegerField(blank=True, null=True)
@ -242,7 +243,7 @@ class Anexo(models.Model):
"""
diagnostico = models.ForeignKey(Diagnostico, verbose_name=u'diagnóstico')
arquivo = models.FileField(upload_to='apps/diagnostico/anexo/arquivo', max_length=500)
descricao = models.CharField(_(u'descrição'), max_length='70')
descricao = models.CharField(_(u'descrição'), max_length=70)
data_pub = models.DateTimeField(_(u'data da publicação do anexo'),
default=datetime.now)

2
sigi/apps/diagnosticos/templates/admin/diagnosticos/diagnostico/change_list.html

@ -6,7 +6,7 @@
<div id="toolbar">
<form id="changelist-search" action="" method="get">
<div><!-- DIV needed for valid HTML -->
<label for="searchbar"><img src="{% static 'admin/img/icon_searchbox.png' %}" alt="Search" /></label>
<label for="searchbar"><img src="{% static 'admin/img/search.svg' %}" alt="Search" /></label>
<input type="text" size="40" name="q" value="" id="searchbar" />
<label for="data_visita_inicio__gte">{% trans 'Visitados a partir de' %}:</label>
<input type="text" size="10" name="data_visita_inicio__gte" value="" id="data_visita_inicio__gte" class="vDateField"/>

2
sigi/apps/diagnosticos/templates/diagnosticos/diagnosticos_login.html

@ -35,7 +35,7 @@
{% endif %}
<div data-role="content">
<form action="{% url 'django.contrib.auth.views.login' %}" method="POST">
<form action="{% url 'login' %}" method="POST">
{% csrf_token %}
<div data-role="fieldcontain" class="ui-hide-label ui-body">
<label for="username">{% trans 'Usuário' %}:</label>

2
sigi/apps/diagnosticos/templates/diagnosticos/mapa.html

@ -6,7 +6,7 @@
{{ block.super }}
{% load static from staticfiles %}
<script type="text/javascript" src="{% static "admin/js/core.js" %}"></script>
<script type="text/javascript" src="{% static "admin/js/jquery.min.js" %}"></script>
<script type="text/javascript" src="{% static "admin/js/jquery-1.9.1.min.js" %}"></script>
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"> </script>
<script type="text/javascript">

1
sigi/apps/diagnosticos/templatetags/smart_if.py

@ -9,7 +9,6 @@ greater than and less than operators. Some common case examples::
"""
from django import template
register = template.Library()

2
sigi/apps/diagnosticos/templatetags/test_smart_if.py

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import pytest
from smart_if import Or, And, Equals, Greater, GreaterOrEqual, In, IfParser
from smart_if import And, Equals, Greater, GreaterOrEqual, IfParser, In, Or
class TestVar(object):

57
sigi/apps/diagnosticos/urls.py

@ -1,52 +1,57 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from django.conf.urls import url
from django.views.generic import TemplateView
from sigi.apps.diagnosticos import views as diagnosticos_views
from django.contrib.auth import views as auth_views
LOGIN_REDIRECT_URL = '/diagnosticos/mobile/login'
urlpatterns = patterns(
'sigi.apps.diagnosticos.views',
urlpatterns = [
# Lista de Diagnósticos
url(r'^mobile/$', 'lista', name='lista_diagnosticos'),
url(r'^mobile/$', diagnosticos_views.lista, name='lista_diagnosticos'),
# Lista de Categorias
url(r'^mobile/(?P<id_diagnostico>\d+)/categorias/$',
'categorias', name='lista_categorias'),
diagnosticos_views.categorias, name='lista_categorias'),
# Detalhes da Categoria da Casa Legislativa
url(r'^mobile/(?P<id_diagnostico>\d+)/categorias/1/$',
'categoria_casa_legislativa', name='detalhes_categoria_casa_legislativa'),
diagnosticos_views.categoria_casa_legislativa,
name='detalhes_categoria_casa_legislativa'),
# Detalhes da Categoria de Contatos
url(r'^mobile/(?P<id_diagnostico>\d+)/categorias/2/$',
'categoria_contatos', name='detalhes_categoria_contatos'),
diagnosticos_views.categoria_contatos,
name='detalhes_categoria_contatos'),
# Detalhes de Categorias Dinamicas
url(r'^mobile/(?P<id_diagnostico>\d+)/categorias/(?P<id_categoria>\d+)/$',
'categoria_detalhes', name='detalhes_categoria'),
diagnosticos_views.categoria_detalhes, name='detalhes_categoria'),
url(r'^mapa/$', TemplateView.as_view(template_name="diagnosticos/mapa.html"), name='template-mapa'),
url(r'^mundiagjson/$', 'municipios_diagnosticados', name='municipios-diagnosticados'),
url(r'^mapa/$',
TemplateView.as_view(template_name="diagnosticos/mapa.html"),
name='template-mapa'),
url(r'^mundiagjson/$', diagnosticos_views.municipios_diagnosticados,
name='municipios-diagnosticados'),
# Reports diagnosticos
url(r'^diagnostico/(?P<id_diagnostico>\w+).pdf$', 'diagnostico_pdf', name='diagnostico-pdf'),
url(r'^diagnostico/(?P<id_diagnostico>\w+).pdf$',
diagnosticos_views.diagnostico_pdf, name='diagnostico-pdf'),
# Graficos de perguntas
url(r'^graficos/$', 'graficos', name="diagnosticos-graficos"), # tagerror
url(r'^api/$', 'grafico_api', name="diagnosticos-grafico-api"), # tagerror
)
urlpatterns += patterns(
'django.contrib.auth.views',
url(r'^graficos/$', diagnosticos_views.graficos,
name="diagnosticos-graficos"), # tagerror
url(r'^api/$', diagnosticos_views.grafico_api,
name="diagnosticos-grafico-api"), # tagerror
]
urlpatterns += [
# Login do Diagnóstico
url(r'^mobile/login/$', 'login', {'template_name':
'diagnosticos/diagnosticos_login.html'}, name='login'),
url(r'^mobile/login/$',
auth_views.login, {'template_name':
'diagnosticos/diagnosticos_login.html'},
name='login'),
# Logout do Diagnóstico
url(r'^mobile/logout/$', 'logout',
{'next_page': LOGIN_REDIRECT_URL}, name='logout'),
)
url(r'^mobile/logout/$', auth_views.logout,
{'next_page': diagnosticos_views.LOGIN_REDIRECT_URL}, name='logout'),
]

15
sigi/apps/diagnosticos/views.py

@ -3,7 +3,7 @@ import json as simplejson # XXX trocar isso por simplesmente import json e refa
from itertools import cycle
from django.http import HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache
@ -11,13 +11,14 @@ from django.views.decorators.cache import never_cache
from sigi.apps.casas.models import Funcionario
from sigi.apps.contatos.models import Telefone
from sigi.apps.diagnosticos.decorators import validate_diagnostico
from sigi.apps.diagnosticos.forms import (DiagnosticoMobileForm,
CasaLegislativaMobileForm, FuncionariosMobileForm)
from sigi.apps.diagnosticos.models import Diagnostico, Categoria, Pergunta
from sigi.apps.diagnosticos.urls import LOGIN_REDIRECT_URL
from sigi.apps.diagnosticos.forms import (CasaLegislativaMobileForm,
DiagnosticoMobileForm,
FuncionariosMobileForm)
from sigi.apps.diagnosticos.models import Categoria, Diagnostico, Pergunta
from sigi.apps.utils.decorators import login_required
from sigi.shortcuts import render_to_pdf
LOGIN_REDIRECT_URL = '/diagnosticos/mobile/login'
@never_cache
@login_required(login_url=LOGIN_REDIRECT_URL)
@ -271,7 +272,7 @@ def diagnostico_pdf(request, id_diagnostico):
def graficos(request):
categorias = Categoria.objects.all()
sel_categoria = int(request.REQUEST.get("categoria", "3"))
sel_categoria = int(request.POST.get("categoria", "3"))
perguntas = Pergunta.objects.filter(categoria=sel_categoria).all()
context = RequestContext(request, {
@ -314,7 +315,7 @@ def grafico_api(request):
'#BB9098',
'#BDF1ED', ])
pergunta_slug = request.REQUEST.get('id', None)
pergunta_slug = request.GET.get('id', None)
pergunta = get_object_or_404(Pergunta, name=pergunta_slug)
if pergunta.datatype == 'one':

12
sigi/apps/diagnosticos/widgets.py

@ -1,8 +1,12 @@
from itertools import chain
from django.forms.widgets import CheckboxInput, CheckboxSelectMultiple, RadioSelect, RadioFieldRenderer, RadioInput
from django.utils.html import conditional_escape
from django.forms.widgets import (CheckboxInput, CheckboxSelectMultiple,
RadioChoiceInput, RadioFieldRenderer,
RadioSelect)
from django.utils.encoding import force_unicode
from django.utils.html import conditional_escape
from django.utils.safestring import mark_safe
from sigi.apps.diagnosticos.models import Escolha
@ -46,7 +50,7 @@ class EavRadioFieldRenderer(RadioFieldRenderer):
if schema_to_open:
final_attrs['schema_to_open'] = schema_to_open.name
yield RadioInput(self.name, self.value, final_attrs, choice, i)
yield RadioChoiceInput(self.name, self.value, final_attrs, choice, i)
def __getitem__(self, idx):
choice = self.choices[idx]
@ -59,7 +63,7 @@ class EavRadioFieldRenderer(RadioFieldRenderer):
if schema_to_open:
final_attrs['schema_to_open'] = schema_to_open.name
return RadioInput(self.name, self.value, final_attrs, choice, idx)
return RadioChoiceInput(self.name, self.value, final_attrs, choice, idx)
class EavRadioSelect(RadioSelect):

9
sigi/apps/eventos/admin.py

@ -18,10 +18,13 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from django.contrib import admin
from django import forms
from django.contrib import admin
from django.utils.translation import ugettext as _
from sigi.apps.eventos.models import TipoEvento, Funcao, Evento, Equipe, Convite
from sigi.apps.eventos.models import (Convite, Equipe, Evento, Funcao,
TipoEvento)
class EventoAdminForm(forms.ModelForm):
class Meta:
@ -67,5 +70,3 @@ class EventoAdmin(admin.ModelAdmin):
search_fields = ('nome', 'tipo_evento__nome', 'casa_anfitria__search_text',
'municipio__search_text', 'solicitante')
inlines = (EquipeInline, ConviteInline)

8
sigi/apps/eventos/models.py

@ -18,15 +18,17 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.functional import lazy
from django.utils.translation import ugettext as _
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.contatos.models import Municipio
from sigi.apps.mdl.models import Course
from sigi.apps.servidores.models import Servidor
from sigi.apps.utils.moodle_ws_api import get_courses
from django.core.exceptions import ValidationError
from sigi.apps.mdl.models import Course
class TipoEvento(models.Model):
nome = models.CharField(_(u"Nome"), max_length=100)
@ -138,4 +140,4 @@ class Convite(models.Model):
class Meta:
ordering = ('evento', 'casa', '-data_convite')
unique_together = ('evento', 'casa')
verbose_name, verbose_name_plural = _(u"Casa convidada"), _(u"Casas convidadas")
verbose_name, verbose_name_plural = _(u"Casa convidada"), _(u"Casas convidadas")

13
sigi/apps/eventos/urls.py

@ -1,10 +1,9 @@
# coding: utf-8
from django.conf.urls import patterns, url
from django.conf.urls import url
from sigi.apps.eventos import views
urlpatterns = patterns(
'sigi.apps.eventos.views',
urlpatterns = [
# Painel de ocorrencias
url(r'^calendario/$', 'calendario', name='eventos-calendario'),
url(r'^alocacaoequipe/$', 'alocacao_equipe', name='eventos-alocacaoequipe'),
)
url(r'^calendario/$', views.calendario, name='eventos-calendario'),
url(r'^alocacaoequipe/$', views.alocacao_equipe, name='eventos-alocacaoequipe'),
]

12
sigi/apps/eventos/views.py

@ -19,17 +19,21 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import calendar
import csv
import datetime
import locale
from django.contrib.auth.decorators import login_required
from django.http.response import HttpResponse, JsonResponse
from django.shortcuts import render
from django.utils import translation
from django.utils.translation import ungettext, ugettext as _
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from sigi.apps.eventos.models import Evento
from sigi.apps.servidores.models import Servidor
from sigi.shortcuts import render_to_pdf
import csv
from django.http.response import JsonResponse, HttpResponse
@login_required
def calendario(request):
@ -188,4 +192,4 @@ def alocacao_equipe(request):
} for d in dados]}
return JsonResponse(result)
return render(request, 'eventos/alocacao_equipe.html', data)
return render(request, 'eventos/alocacao_equipe.html', data)

7
sigi/apps/home/templatetags/menu_conf.yaml

@ -123,3 +123,10 @@ main_menu:
url: saberes/dashboard/cursos-sem-turoria/
- title: Cursos com Tutoria
url: saberes/dashboard/cursos-com-turoria/
- title: Atesto
url: '/'
children:
- title: Convênio
url: atesto/convenio
- title: Responsável
url: atesto/responsavel

1
sigi/apps/home/templatetags/menus.py

@ -3,7 +3,6 @@ from os.path import dirname
import yaml
from django import template
register = template.Library()
menus = yaml.load(open(dirname(__file__) + '/menu_conf.yaml', 'r'))

4
sigi/apps/home/templatetags/smart_pagination.py

@ -29,9 +29,9 @@ def smart_paginator(page_obj, querystring=None):
else:
querystring = '?'
page_range = page_obj.paginator.page_range
page_range = list(page_obj.paginator.page_range)
mid = len(page_range) / 2
range = list(set(page_range[:3]) | set(page_range[mid-2:mid+1]) | set(page_range[-3:]) |
set(page_range[page_obj.number-2:page_obj.number+1]))
range.sort()

33
sigi/apps/home/urls.py

@ -1,15 +1,22 @@
# coding: utf-8
from django.conf.urls import patterns, url
from django.conf.urls import url
from django.views.generic.base import TemplateView
from sigi.apps.home import views
urlpatterns = patterns('sigi.apps.home.views',
url(r'^$', 'index', name='sigi_index'),
url(r'^home/resumoconvenios/$', 'resumo_convenios', name="home_resumoconvenios"),
url(r'^home/resumoseit/$', 'resumo_seit', name="home_resumoseit"),
url(r'^home/chartseit/$', 'chart_seit', name="home_chartseit"),
url(r'^home/chartconvenios/$', 'chart_convenios', name="home_chartconvenios"),
url(r'^home/chartcarteira/$', 'chart_carteira', name="home_chartcarteira"),
url(r'^home/chartperformance/$', 'chart_performance', name="home_chartperformance"),
url(r'^home/report/semconvenio/$', 'report_sem_convenio', name="home_reportsemconvenio"),
)
urlpatterns = [
url(r'^atendimento', TemplateView.as_view(
template_name='index_atendimento.html'),
name='index_atendimento'),
url(r'^$', views.index, name='sigi_index'),
url(r'^home/resumoconvenios/$', views.resumo_convenios,
name="home_resumoconvenios"),
url(r'^home/resumoseit/$', views.resumo_seit, name="home_resumoseit"),
url(r'^home/chartseit/$', views.chart_seit, name="home_chartseit"),
url(r'^home/chartconvenios/$', views.chart_convenios,
name="home_chartconvenios"),
url(r'^home/chartcarteira/$', views.chart_carteira, name="home_chartcarteira"),
url(r'^home/chartperformance/$', views.chart_performance,
name="home_chartperformance"),
url(r'^home/report/semconvenio/$', views.report_sem_convenio,
name="home_reportsemconvenio"),
]

21
sigi/apps/home/views.py

@ -22,24 +22,27 @@
# 02110-1301, USA.
#
import datetime
import calendar
from django.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext as _
import csv
import datetime
from itertools import cycle
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.db.models import Count, Q
from django.http.response import HttpResponse, JsonResponse
from django.shortcuts import get_object_or_404, render
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.convenios.models import Convenio, Projeto
from sigi.apps.diagnosticos.models import Diagnostico
from sigi.apps.metas.models import Meta
from sigi.apps.servicos.models import TipoServico
from sigi.apps.servidores.models import Servidor
from django.views.decorators.cache import never_cache
from django.contrib.auth.decorators import login_required
from django.http.response import JsonResponse, HttpResponse
from django.core.urlresolvers import reverse
from django.db.models import Q, Count
from sigi.shortcuts import render_to_pdf
import csv
@never_cache
@login_required

12
sigi/apps/inventario/admin.py

@ -1,21 +1,21 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.admin import GenericTabularInline
from sigi.apps.contatos.models import Contato, Telefone
from sigi.apps.inventario.models import (Fornecedor, Fabricante, Equipamento,
TipoEquipamento, ModeloEquipamento,
Bem)
from sigi.apps.inventario.models import (Bem, Equipamento, Fabricante,
Fornecedor, ModeloEquipamento,
TipoEquipamento)
from sigi.apps.utils.base_admin import BaseModelAdmin
class ContatosInline(generic.GenericTabularInline):
class ContatosInline(GenericTabularInline):
model = Contato
extra = 2
raw_id_fields = ('municipio',)
class TelefonesInline(generic.GenericTabularInline):
class TelefonesInline(GenericTabularInline):
model = Telefone
extra = 2

20
sigi/apps/inventario/migrations/0002_auto_20160623_0829.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-23 08:29
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventario', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='fornecedor',
name='email',
field=models.EmailField(blank=True, max_length=254, verbose_name='e-mail'),
),
]

6
sigi/apps/inventario/models.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from django.contrib.contenttypes import generic
from django.contrib.contenttypes import fields
from django.db import models
from django.utils.translation import ugettext as _
@ -9,8 +9,8 @@ class Fornecedor(models.Model):
nome.alphabetic_filter = True
email = models.EmailField(_(u'e-mail'), blank=True)
pagina_web = models.URLField(_(u'página web'), blank=True)
telefones = generic.GenericRelation('contatos.Telefone')
contatos = generic.GenericRelation('contatos.Contato')
telefones = fields.GenericRelation('contatos.Telefone')
contatos = fields.GenericRelation('contatos.Contato')
class Meta:
ordering = ('nome',)

3
sigi/apps/mdl/models.py

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
@ -39,7 +40,7 @@ class CourseStats(models.Model):
('A', u'Aprovação'),
('I', u'Indeterminado'),)
category = models.ForeignKey('CourseCategories', db_column='categoryid', primary_key=True)
category = models.ForeignKey('CourseCategories', db_column='categoryid')
course = models.ForeignKey('Course', db_column='courseid')
completionstatus = models.CharField(max_length=1, choices=COMPLETIONSTATUS_CHOICES)
usercount = models.IntegerField()

3
sigi/apps/metas/models.py

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from datetime import date
from django.db import models
from django.utils.translation import ugettext as _
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.convenios.models import Projeto, Convenio
from sigi.apps.convenios.models import Convenio, Projeto
from sigi.apps.diagnosticos.models import Diagnostico
from sigi.apps.financeiro.models import Desembolso

2
sigi/apps/metas/templates/admin/metas/planodiretor/change_list.html

@ -6,7 +6,7 @@
<div id="toolbar">
<form id="changelist-search" action="" method="get">
<div><!-- DIV needed for valid HTML -->
<label for="searchbar"><img src="{% static 'admin/img/icon_searchbox.png' %}" alt="Search" /></label>
<label for="searchbar"><img src="{% static 'admin/img/search.svg' %}" alt="Search" /></label>
<input type="text" size="40" name="q" value="" id="searchbar" />
<label for="data_entrega__gte">{% trans 'Entregues a partir de' %}:</label>
<input type="text" size="10" name="data_entrega__gte" value="" id="data_entrega__gte" class="vDateField"/>

2
sigi/apps/metas/templates/metas/mapa.html

@ -8,7 +8,7 @@
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}" />
<script type="text/javascript" src="{% static "admin/js/core.js" %}"></script>
<script type="text/javascript" src="{% static "admin/js/jquery.min.js" %}"></script>
<script type="text/javascript" src="{% static "admin/js/jquery-1.9.1.min.js" %}"></script>
<script type="text/javascript" src="{% static "admin/js/jquery.init.js" %}"></script>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="{% static 'metas/js/mapa.js' %}" ></script>

1
sigi/apps/metas/templatetags/mapa_tags.py

@ -5,7 +5,6 @@ from django.utils.safestring import mark_safe
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.metas.views import parliament_summary
register = template.Library()

21
sigi/apps/metas/urls.py

@ -1,14 +1,13 @@
# coding: utf-8
from django.conf.urls import patterns, url
from django.conf.urls import url
from sigi.apps.metas import views
urlpatterns = patterns(
'sigi.apps.metas.views',
url(r'^$', 'dashboard', name='metas-dashboardsss'), # tagerror
url(r'^mapa/$', 'mapa', name='metas-mapa'), # tagerror
url(r'^mapdata/$', 'map_data', name='metas-map_data'),
url(r'^mapsearch/$', 'map_search', name='metas-map_search'),
url(r'^mapsum/$', 'map_sum', name='metas-map_sum'),
url(r'^maplist/$', 'map_list', name='metas-map_list'),
)
urlpatterns = [
url(r'^$', views.dashboard, name='metas-dashboardsss'), # tagerror
url(r'^mapa/$', views.mapa, name='metas-mapa'), # tagerror
url(r'^mapdata/$', views.map_data, name='metas-map_data'),
url(r'^mapsearch/$', views.map_search, name='metas-map_search'),
url(r'^mapsum/$', views.map_sum, name='metas-map_sum'),
url(r'^maplist/$', views.map_list, name='metas-map_list'),
]

13
sigi/apps/metas/views.py

@ -3,6 +3,7 @@ import csv
import json as simplejson # XXX trocar isso por simplesmente import json e refatorar o codigo
import os
import time
from collections import OrderedDict
from functools import reduce
from django.contrib.auth.decorators import login_required
@ -12,7 +13,6 @@ from django.db.models.aggregates import Sum
from django.http import HttpResponse
from django.shortcuts import render, render_to_response
from django.template import RequestContext
from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext as _
from django.views.decorators.cache import cache_page
from easy_thumbnails.templatetags.thumbnail import thumbnail_url
@ -26,7 +26,6 @@ from sigi.apps.utils import to_ascii
from sigi.settings import MEDIA_ROOT, STATIC_URL
from sigi.shortcuts import render_to_pdf
JSON_FILE_NAME = os.path.join(MEDIA_ROOT, 'apps/metas/map_data.json')
@ -36,8 +35,8 @@ def dashboard(request):
raise PermissionDenied
desembolsos_max = 0
matriz = SortedDict()
dados = SortedDict()
matriz = OrderedDict()
dados = OrderedDict()
projetos = Projeto.objects.all()
meses = Desembolso.objects.dates('data', 'month', 'DESC')[:6]
colors = ['ffff00', 'cc7900', 'ff0000', '92d050', '006600', '0097cc', '002776', 'ae78d6', 'ff00ff', '430080',
@ -137,9 +136,9 @@ def map_sum(request):
casas = filtrar_casas(**param)
# Montar registros de totalização
tot_servicos = SortedDict()
tot_projetos = SortedDict()
tot_diagnosticos = SortedDict()
tot_servicos = OrderedDict()
tot_projetos = OrderedDict()
tot_diagnosticos = OrderedDict()
for ts in TipoServico.objects.all():
tot_servicos[ts.sigla] = 0

5
sigi/apps/ocorrencias/admin.py

@ -4,7 +4,8 @@ from django.contrib.admin.views.main import ChangeList
from django.utils.translation import ugettext as _
from filters import OcorrenciaListFilter
from sigi.apps.ocorrencias.models import Ocorrencia, Comentario, Anexo, Categoria, TipoContato
from sigi.apps.ocorrencias.models import (Anexo, Categoria, Comentario,
Ocorrencia, TipoContato)
from sigi.apps.servidores.models import Servidor
from sigi.apps.utils.base_admin import BaseModelAdmin
@ -51,7 +52,7 @@ class OcorrenciaChangeList(ChangeList):
if 'grupo' in self.params:
grupo = self.params['grupo']
del self.params['grupo']
qs = super(OcorrenciaChangeList, self).get_query_set(request)
qs = super(OcorrenciaChangeList, self).get_queryset(request)
self.params = tmp_params.copy()
if grupo:
servidor = Servidor.objects.get(user=self.request.user)

16
sigi/apps/ocorrencias/forms.py

@ -21,15 +21,17 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
from django.forms import ModelForm, ModelChoiceField, HiddenInput, TextInput
from sigi.apps.ocorrencias.models import Ocorrencia, Comentario, Anexo
from sigi.apps.servidores.models import Servico
from django.core.urlresolvers import reverse_lazy
from django.forms import HiddenInput, ModelChoiceField, ModelForm, TextInput
from django.forms.utils import flatatt
from django.utils.encoding import force_text
from django.utils.html import format_html
from django.forms.utils import flatatt
from django.core.urlresolvers import reverse_lazy
from django.utils.safestring import mark_safe
from sigi.apps.ocorrencias.models import Anexo, Comentario, Ocorrencia
from sigi.apps.servidores.models import Servico
class AjaxSelect(TextInput):
url = ""
def __init__(self, url, attrs=None):
@ -68,7 +70,7 @@ class AnexoForm(ModelForm):
widgets = {'ocorrencia': HiddenInput()}
class ComentarioForm(ModelForm):
encaminhar_setor = ModelChoiceField(queryset=Servico.objects.all(), cache_choices=True)
encaminhar_setor = ModelChoiceField(queryset=Servico.objects.all())
class Meta:
model = Comentario
@ -80,4 +82,4 @@ class OcorrenciaForm(ModelForm):
model = Ocorrencia
fields = ['casa_legislativa', 'categoria', 'tipo_contato', 'assunto', 'prioridade', 'ticket',
'descricao', 'setor_responsavel',]
widgets = {'casa_legislativa': AjaxSelect(url=reverse_lazy('painel-buscacasa'), attrs={'size':100}), }
widgets = {'casa_legislativa': AjaxSelect(url=reverse_lazy('painel-buscacasa'), attrs={'size':100}), }

20
sigi/apps/ocorrencias/migrations/0003_auto_20160616_1602.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('ocorrencias', '0002_auto_20160308_0828'),
]
operations = [
migrations.AlterField(
model_name='anexo',
name='descricao',
field=models.CharField(max_length=70, verbose_name='descri\xe7\xe3o do anexo'),
preserve_default=True,
),
]

6
sigi/apps/ocorrencias/models.py

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
from django.db import models
from django.conf import settings
from django.utils.translation import ugettext as _
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
class Categoria(models.Model):
@ -105,7 +105,7 @@ class Comentario(models.Model):
class Anexo(models.Model):
ocorrencia = models.ForeignKey(Ocorrencia, verbose_name=_(u'ocorrência'))
arquivo = models.FileField(_(u'Arquivo anexado'), upload_to='apps/ocorrencia/anexo/arquivo', max_length=500)
descricao = models.CharField(_(u'descrição do anexo'), max_length='70')
descricao = models.CharField(_(u'descrição do anexo'), max_length=70)
data_pub = models.DateTimeField(_(u'data da publicação do anexo'), null=True, blank=True, auto_now_add=True)
class Meta:

2
sigi/apps/ocorrencias/templates/ocorrencias/painel.html

@ -11,7 +11,7 @@
{% block extrahead %}
{{ block.super }}
<script type="text/javascript" src="{% static 'admin/js/core.js' %}" ></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.min.js' %}" ></script>
<script type="text/javascript" src="{% static 'admin/js/jquery-1.9.1.min.js' %}" ></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}" ></script>
<script type="text/javascript" src="{% static 'ocorrencias/js/jquery-ui.min.js' %}" ></script>
{% endblock %}

31
sigi/apps/ocorrencias/urls.py

@ -1,19 +1,18 @@
# coding: utf-8
from django.conf.urls import patterns, url
from django.conf.urls import url
from sigi.apps.ocorrencias import views
urlpatterns = patterns(
'sigi.apps.ocorrencias.views',
urlpatterns = [
# Painel de ocorrencias
url(r'^painel/$', 'painel_ocorrencias', name='painel-ocorrencias'),
url(r'^painel/buscanominal/$', 'busca_nominal', {"origin": "tudo"}, name='painel-buscanominal'),
url(r'^painel/buscanominal/casa/$', 'busca_nominal', {"origin": "casa"}, name='painel-buscacasa'),
url(r'^painel/buscanominal/servidor/$', 'busca_nominal', {"origin": "servidor"}, name='painel-buscaservidor'),
url(r'^painel/buscanominal/servico/$', 'busca_nominal', {"origin": "servico"}, name='painel-buscaservico'),
url(r'^mudaprioridade/$', 'muda_prioridade', name='ocorrencia-mudaprioridade'),
url(r'^excluianexo/$', 'exclui_anexo', name='ocorrencia-excluianexo'),
url(r'^incluianexo/$', 'inclui_anexo', name='ocorrencia-incluianexo'),
url(r'^anexosnippet/$', 'anexo_snippet', name='ocorrencia-anexosnippet'),
url(r'^incluicomentario/$', 'inclui_comentario', name='ocorrencia-incluicomentario'),
url(r'^incluiocorrencia/$', 'inclui_ocorrencia', name='ocorrencia-incluiocorrencia'),
)
url(r'^painel/$', views.painel_ocorrencias, name='painel-ocorrencias'),
url(r'^painel/buscanominal/$', views.busca_nominal, {"origin": "tudo"}, name='painel-buscanominal'),
url(r'^painel/buscanominal/casa/$', views.busca_nominal, {"origin": "casa"}, name='painel-buscacasa'),
url(r'^painel/buscanominal/servidor/$', views.busca_nominal, {"origin": "servidor"}, name='painel-buscaservidor'),
url(r'^painel/buscanominal/servico/$', views.busca_nominal, {"origin": "servico"}, name='painel-buscaservico'),
url(r'^mudaprioridade/$', views.muda_prioridade, name='ocorrencia-mudaprioridade'),
url(r'^excluianexo/$', views.exclui_anexo, name='ocorrencia-excluianexo'),
url(r'^incluianexo/$', views.inclui_anexo, name='ocorrencia-incluianexo'),
url(r'^anexosnippet/$', views.anexo_snippet, name='ocorrencia-anexosnippet'),
url(r'^incluicomentario/$', views.inclui_comentario, name='ocorrencia-incluicomentario'),
url(r'^incluiocorrencia/$', views.inclui_ocorrencia, name='ocorrencia-incluiocorrencia'),
]

28
sigi/apps/ocorrencias/views.py

@ -1,19 +1,23 @@
# -*- coding: utf-8 -*-
from django.http import JsonResponse, Http404
from django.db.models import Q, Count
from django.utils.translation import ungettext, ugettext as _
from django.shortcuts import get_object_or_404, render, HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST
from django.template.loader import render_to_string
from django.db.models import Count, Q
from django.http import Http404, JsonResponse
from django.shortcuts import HttpResponse, get_object_or_404, render
from django.template import RequestContext
from sigi.apps.utils import to_ascii
from django.template.loader import render_to_string
from django.utils.html import escape
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from django.views.decorators.http import require_POST
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.contatos.models import UnidadeFederativa
from sigi.apps.servidores.models import Servidor, Servico
from sigi.apps.ocorrencias.models import Ocorrencia, Anexo
from sigi.apps.ocorrencias.forms import AnexoForm, ComentarioForm, OcorrenciaForm
from django.utils.html import escape
from sigi.apps.ocorrencias.forms import (AnexoForm, ComentarioForm,
OcorrenciaForm)
from sigi.apps.ocorrencias.models import Anexo, Ocorrencia
from sigi.apps.servidores.models import Servico, Servidor
from sigi.apps.utils import to_ascii
@login_required
def painel_ocorrencias(request):
@ -212,4 +216,4 @@ def inclui_ocorrencia(request):
{'ocorrencia_form': form},
context_instance=RequestContext(request))
return JsonResponse(data)
return JsonResponse(data)

14
sigi/apps/parlamentares/admin.py

@ -1,14 +1,16 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
from django.contrib.contenttypes import generic
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.contenttypes.admin import GenericTabularInline
from django.http import HttpResponse, HttpResponseRedirect
from django.utils.html import escape, escapejs
from django.utils.translation import ugettext as _
from sigi.apps.contatos.models import Telefone
from sigi.apps.parlamentares.models import (
Partido, Parlamentar, Mandato, Legislatura, Coligacao, ComposicaoColigacao,
SessaoLegislativa, MesaDiretora, Cargo, MembroMesaDiretora)
from sigi.apps.parlamentares.models import (Cargo, Coligacao,
ComposicaoColigacao, Legislatura,
Mandato, MembroMesaDiretora,
MesaDiretora, Parlamentar, Partido,
SessaoLegislativa)
from sigi.apps.parlamentares.views import adicionar_parlamentar_carrinho
from sigi.apps.utils.base_admin import BaseModelAdmin
from sigi.apps.utils.filters import AlphabeticFilter
@ -20,7 +22,7 @@ class MandatosInline(admin.TabularInline):
raw_id_fields = ('legislatura', 'partido')
class TelefonesInline(generic.GenericTabularInline):
class TelefonesInline(GenericTabularInline):
model = Telefone
extra = 2

20
sigi/apps/parlamentares/migrations/0002_auto_20160623_0829.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-06-23 08:29
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('parlamentares', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='parlamentar',
name='email',
field=models.EmailField(blank=True, max_length=254, verbose_name='e-mail'),
),
]

20
sigi/apps/parlamentares/migrations/0003_auto_20160811_1553.py

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.6 on 2016-08-11 15:53
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('parlamentares', '0002_auto_20160623_0829'),
]
operations = [
migrations.AlterField(
model_name='parlamentar',
name='foto',
field=models.ImageField(blank=True, height_field=b'foto_altura', null=True, upload_to=b'fotos/parlamentares', width_field=b'foto_largura'),
),
]

3
sigi/apps/parlamentares/models.py

@ -27,7 +27,8 @@ class Parlamentar(models.Model):
upload_to='fotos/parlamentares',
width_field='foto_largura',
height_field='foto_altura',
blank=True
blank=True,
null=True
)
foto_largura = models.SmallIntegerField(editable=False, null=True)
foto_altura = models.SmallIntegerField(editable=False, null=True)

4
sigi/apps/parlamentares/reports.py

@ -1,7 +1,9 @@
# -*- coding: utf-8 -*-
from django.templatetags.static import static
from django.utils.translation import ugettext as _
from geraldo import Report, DetailBand, Label, ObjectValue, ReportGroup, ReportBand, landscape, SubReport, BAND_WIDTH, SystemField
from geraldo import (BAND_WIDTH, DetailBand, Label, ObjectValue, Report,
ReportBand, ReportGroup, SubReport, SystemField,
landscape)
from geraldo.graphics import Image
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.pagesizes import A4

1
sigi/apps/parlamentares/test_parlamentares.py

@ -4,7 +4,6 @@ from django_dynamic_fixture import G
from sigi.apps.parlamentares.models import Parlamentar
pytestmark = pytest.mark.django_db

19
sigi/apps/parlamentares/urls.py

@ -1,17 +1,16 @@
# coding: utf-8
from django.conf.urls import patterns, url
urlpatterns = patterns(
'sigi.apps.parlamentares.views',
from django.conf.urls import url
from sigi.apps.parlamentares import views
urlpatterns = [
# Reports labels parlamentares
url(r'^parlamentar/labels/$', 'labels_report', name='labels-report-all'),
url(r'^parlamentar/(?P<id>\w+)/labels/$', 'labels_report', name='labels-report-id'),
url(r'^parlamentar/labels/$', views.labels_report, name='labels-report-all'),
url(r'^parlamentar/(?P<id>\w+)/labels/$', views.labels_report, name='labels-report-id'),
# Carrinho
url(r'^parlamentar/carrinho/$', 'visualizar_carrinho', name='visualizar-carrinho'),
url(r'^parlamentar/carrinho/deleta_itens_carrinho$', 'deleta_itens_carrinho', name='deleta-itens-carrinho'),
url(r'^parlamentar/carrinho/$', views.visualizar_carrinho, name='visualizar-carrinho'),
url(r'^parlamentar/carrinho/deleta_itens_carrinho$', views.deleta_itens_carrinho, name='deleta-itens-carrinho'),
# A view excluir_carrinho n existe ainda.
# url(r'^parlamentar/carrinho/exluir_carrinho$', 'excluir_carrinho', name='excluir-carrinho'),
)
# url(r'^parlamentar/carrinho/exluir_carrinho$', views.excluir_carrinho, name='excluir-carrinho'),
]

14
sigi/apps/parlamentares/views.py

@ -1,22 +1,20 @@
# coding: utf-8
import datetime
import csv
import datetime
from django.template import Context, loader
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.conf import settings
from django.shortcuts import render, get_list_or_404
from django.contrib.auth.decorators import login_required
from django.core.paginator import EmptyPage, InvalidPage, Paginator
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_list_or_404, render
from django.template import Context, RequestContext, loader
from django.views.decorators.csrf import csrf_protect
from django.template import RequestContext
from geraldo.generators import PDFGenerator
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.parlamentares.models import Parlamentar
from sigi.apps.parlamentares.reports import ParlamentaresLabels
from geraldo.generators import PDFGenerator
from django.contrib.auth.decorators import login_required
def adicionar_parlamentar_carrinho(request, queryset=None, id=None):
if request.method == 'POST':

3
sigi/apps/relatorios/reports.py

@ -3,7 +3,8 @@ import os
from django.templatetags.static import static
from django.utils.translation import ugettext as _
from geraldo import Report, ReportBand, ObjectValue, DetailBand, Label, SystemField, BAND_WIDTH, FIELD_ACTION_COUNT, Line
from geraldo import (BAND_WIDTH, FIELD_ACTION_COUNT, DetailBand, Label, Line,
ObjectValue, Report, ReportBand, SystemField)
from geraldo.graphics import Image
from reportlab.lib.colors import navy
from reportlab.lib.enums import TA_CENTER, TA_RIGHT

3
sigi/apps/saberes/admin.py

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from django.utils.translation import ugettext as _
from django.contrib import admin
from django.utils.translation import ugettext as _
from sigi.apps.saberes.models import CategoriasInteresse

7
sigi/apps/saberes/management/commands/get_moodle_stats.py

@ -21,12 +21,13 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
from django.utils.translation import ugettext as _
from django.core.management.base import BaseCommand
from django.db.models import Sum, Avg
from django.db.models import Avg, Sum
from django.utils.translation import ugettext as _
from sigi.apps.mdl.models import CourseStats, User
from sigi.apps.metas.views import gera_map_data_file
from sigi.apps.saberes.models import CategoriasInteresse, PainelItem
from sigi.apps.mdl.models import User, CourseStats
class Command(BaseCommand):

7
sigi/apps/saberes/models.py

@ -1,10 +1,13 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.utils.translation import ugettext as _
from django.db import models
from django.db.models import Q
from sigi.apps.mdl.models import Course, CourseCategories, CourseCompletions, UserEnrolments
from django.utils.translation import ugettext as _
from sigi.apps.mdl.models import (Course, CourseCategories, CourseCompletions,
UserEnrolments)
class CategoriasInteresse(models.Model):

19
sigi/apps/saberes/urls.py

@ -1,14 +1,11 @@
# coding: utf-8
from django.conf.urls import patterns, url
from django.conf.urls import url
from sigi.apps.saberes import views
from .views import cursos_sem_tutoria, cursos_com_tutoria, dashboard, pentaho_proxy
urlpatterns = patterns(
'sigi.apps.saberes.views',
url(r'^dashboard/cursos-sem-turoria/?$', cursos_sem_tutoria, name="saberes-cursos-sem-tutoria"),
url(r'^dashboard/cursos-com-turoria/?$', cursos_com_tutoria, name="saberes-cursos-com-tutoria"),
url(r'^dashboard/?$', dashboard, name="saberes-dashboard-view"),
url(r'^(?P<path>(plugin|api)/.*)$', pentaho_proxy),
)
urlpatterns = [
url(r'^dashboard/cursos-sem-turoria/?$', views.cursos_sem_tutoria, name="saberes-cursos-sem-tutoria"),
url(r'^dashboard/cursos-com-turoria/?$', views.cursos_com_tutoria, name="saberes-cursos-com-tutoria"),
url(r'^dashboard/?$', views.dashboard, name="saberes-dashboard-view"),
url(r'^(?P<path>(plugin|api)/.*)$', views.pentaho_proxy),
]

4
sigi/apps/saberes/views.py

@ -5,8 +5,8 @@ from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from requests.auth import HTTPBasicAuth
from sigi.settings import PENTAHO_SERVER, PENTAHO_DASHBOARDS, PENTAHO_USERNAME_PASSWORD
from sigi.settings import (PENTAHO_DASHBOARDS, PENTAHO_SERVER,
PENTAHO_USERNAME_PASSWORD)
PENTAHO_CDF_URL = 'http://%s/pentaho/plugin/pentaho-cdf-dd/api/renderer/' % PENTAHO_SERVER

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save