source: publico/il.spdo/trunk/il/spdo/db.py @ 5450

Última Alteração nesse arquivo desde 5450 foi 5450, incluída por fabianosantos, 9 anos atrás

Adicionado suporte a versionamento no modelo do banco de dados.

File size: 18.9 KB
Linha 
1# -*- coding: utf-8 -*-
2
3from zope.interface import implements
4from sqlalchemy import create_engine, Table, Column, Integer, String, DateTime, Text, Boolean, ForeignKey, func
5from sqlalchemy.orm import relationship, backref, sessionmaker
6from sqlalchemy.ext.declarative import declarative_base
7from il.spdo.config import DEFAULT_DSN, TABLE_ARGS, CREATE_ALL_TABLES, CREATE_SAMPLES, Session
8from il.spdo.interfaces import IArea, IUF, IPessoa, IResponsavel, ITipoDocumento, ISituacao, IProtocolo, IAddTramite, ITipoEntrega, IEntrega
9from il.spdo.history_meta import VersionedMeta, VersionedListener
10from random import choice
11import datetime
12import string
13import math
14import sys
15
16Base = declarative_base(metaclass=VersionedMeta)
17
18if __name__ == '__main__':
19    engine = create_engine(DEFAULT_DSN)
20    Session = sessionmaker(bind=engine, extension=VersionedListener())
21
22class Area(Base):
23    implements(IArea)
24    __tablename__ = 'area'
25    __table_args__ = TABLE_ARGS
26    id = Column(Integer, primary_key=True)
27    sigla = Column(String(20), unique=True, nullable=False)
28    nome = Column(String(100), unique=True, nullable=False)
29    chefia_id = Column(Integer, ForeignKey('area.id'))
30    chefia = relationship("Area", backref=backref('area', remote_side=id))
31
32class UF(Base):
33    implements(IUF)
34    __tablename__ = 'uf'
35    __table_args__ = TABLE_ARGS
36    id = Column(Integer, primary_key=True)
37    sigla = Column(String(2), unique=True, nullable=False)
38    nome = Column(String(40), unique=True, nullable=False)
39
40def geraSenha(tamanho):
41    chars = string.letters + string.digits
42    s = ""
43    for i in range(tamanho):
44        s += choice(chars)
45    return s
46
47class Pessoa(Base):
48    implements(IPessoa)
49    __tablename__ = 'pessoa'
50    __table_args__ = TABLE_ARGS
51    id = Column(Integer, primary_key=True)
52    nome = Column(String(100), nullable=False)
53    email = Column(String(50), unique=True, nullable=False)
54    endereco = Column(String(100))
55    bairro = Column(String(30))
56    cep = Column(String(8))
57    cidade = Column(String(50))
58    uf_id = Column(Integer, ForeignKey('uf.id'))
59    uf = relationship("UF", backref="pessoa")
60    telefone = Column(String(30))
61    cpf_cnpj = Column(String(20))
62    tipopessoa = Column(String(1), nullable=False)
63    contato = Column(String(100))
64    area_id = Column(Integer, ForeignKey('area.id'))
65    area = relationship("Area", backref="pessoa")
66    senha = Column(String(20), nullable=False)
67   
68    def __init__(self, nome, email, endereco=None, bairro=None, cep=None, cidade=None, uf_id=None,
69                 telefone=None, cpf_cnpj=None, tipopessoa='F', contato=None, area_id=None):
70        self.nome = nome
71        self.email = email
72        self.endereco = endereco
73        self.bairro = bairro
74        self.cep = cep
75        self.cidade = cidade
76        self.uf_id = uf_id
77        self.telefone = telefone
78        self.cpf_cnpj = cpf_cnpj
79        self.tipopessoa = tipopessoa
80        self.contato = contato
81        self.area_id = area_id
82        self.senha = geraSenha(8)
83
84    def __repr__(self):
85        return "<Pessoa:%s>" % self.email
86
87class Responsavel(Base):
88    implements(IResponsavel)
89    __tablename__ = 'responsavel'
90    __table_args__ = TABLE_ARGS
91    id = Column(Integer, primary_key=True)
92    area_id = Column(Integer, ForeignKey('area.id'))
93    area = relationship("Area", backref="resposavel")
94    pessoa_id = Column(Integer, ForeignKey('pessoa.id'))
95    pessoa = relationship("Pessoa", backref="responsavel")
96    data = Column(DateTime(), default=datetime.date.today(), nullable=False)
97
98class TipoDocumento(Base):
99    implements(ITipoDocumento)
100    __tablename__ = 'tipodocumento'
101    __table_args__ = TABLE_ARGS
102    id = Column(Integer, primary_key=True)
103    nome = Column(String(40), unique=True, nullable=False)
104
105class Situacao(Base):
106    implements(ISituacao)
107    __tablename__ = 'situacao'
108    __table_args__ = TABLE_ARGS
109    id = Column(Integer, primary_key=True)
110    nome = Column(String(40), unique=True, nullable=False)
111    inicial = Column(Boolean(), default=False)
112    final = Column(Boolean(), default=False)
113
114class PessoaOrigem(Base):
115    __tablename__ = 'pessoa_origem'
116    __table_args__ = TABLE_ARGS
117    protocolo_id = Column(Integer, ForeignKey('protocolo.id'), primary_key=True)
118    pessoa_id = Column(Integer, ForeignKey('pessoa.id'), primary_key=True)
119    pessoa = relationship("Pessoa", backref="pessoa_origem")
120
121class TipoEntrega(Base):
122    implements(ITipoEntrega)
123    __tablename__ = 'tipoentrega'
124    __table_args__ = TABLE_ARGS
125    id = Column(Integer, primary_key=True)
126    nome = Column(String(40), unique=True, nullable=False)
127
128class PessoaDestino(Base):
129    implements(IEntrega)
130    __tablename__ = 'pessoa_destino'
131    __table_args__ = TABLE_ARGS
132    protocolo_id = Column(Integer, ForeignKey('protocolo.id'), primary_key=True)
133    pessoa_id = Column(Integer, ForeignKey('pessoa.id'), primary_key=True)
134    pessoa = relationship("Pessoa", backref="pessoa_destino")
135    tipoentrega_id = Column(Integer, ForeignKey('tipoentrega.id'))
136    tipoentrega = relationship("TipoEntrega", backref="pessoa_destino")
137    data_entrega = Column(DateTime())
138    objeto_correios = Column(String(20))
139   
140class Permissao(Base):
141    __tablename__ = 'permissao'
142    __table_args__ = TABLE_ARGS
143    id = Column(Integer, primary_key=True)
144    protocolo_id = Column(Integer, ForeignKey('protocolo.id'))
145    area_id = Column(Integer, ForeignKey('area.id'))
146    area = relationship("Area", backref="permissao")
147    leitura = Column(Boolean(), default=False)
148    escrita = Column(Boolean(), default=False)
149   
150class Notificacao(Base):
151    __tablename__ = 'notificacao'
152    __table_args__ = TABLE_ARGS
153    protocolo_id = Column(Integer, ForeignKey('protocolo.id'), primary_key=True)
154    pessoa_id = Column(Integer, ForeignKey('pessoa.id'), primary_key=True)
155    pessoa = relationship("Pessoa", backref="notificacao")
156
157class Observacao(Base):
158    __tablename__ = 'observacao'
159    __table_args__ = TABLE_ARGS
160    id = Column(Integer, primary_key=True)
161    protocolo_id = Column(Integer, ForeignKey('protocolo.id'))
162    data = Column(DateTime(), default=datetime.datetime.now(), nullable=False)
163    texto = Column(Text(), nullable=False)
164
165class Anexo(Base):
166    __tablename__ = 'anexo'
167    __table_args__ = TABLE_ARGS
168    id = Column(Integer, primary_key=True)
169    protocolo_id = Column(Integer, ForeignKey('protocolo.id'))
170    arquivo = Column(Text(), nullable=False)
171    tamanho = Column(Integer(), nullable=False)
172    data = Column(DateTime(), default=datetime.datetime.now(), nullable=False)
173
174class Tramite(Base):
175    implements(IAddTramite)
176    __tablename__ = 'tramite'
177    __table_args__ = TABLE_ARGS
178    id = Column(Integer, primary_key=True)
179    protocolo_id = Column(Integer, ForeignKey('protocolo.id'))
180    area_id = Column(Integer, ForeignKey('area.id'))
181    area = relationship("Area", backref="tramite")
182    data_disponibilizacao = Column(DateTime())
183    data_recebimento = Column(DateTime())
184    acao = Column(Text())
185    copia = Column(Boolean(), default=False)
186    responsavel_id = Column(Integer, ForeignKey('responsavel.id'))
187    responsavel = relationship("Responsavel", backref="tramite")
188
189    # TODO: apesar de correta, essa logica deve ser movida para a API
190    def __init__(self, protocolo_id, area_id, data_disponibilizacao, data_recebimento, acao, copia=False):
191        self.protocolo_id = protocolo_id
192        self.area_id = area_id
193        self.data_disponibilizacao = data_disponibilizacao
194        self.data_recebimento = data_recebimento
195        self.acao = acao
196        self.copia = copia
197        session = Session()
198
199        #atribui o responsavel atual da área de destino do tramite
200        query = session.query(Responsavel.id).filter(Responsavel.area_id==area_id)
201        self.responsavel_id = query.order_by(Responsavel.id).all()[-1][0]
202
203        #testa se existe alguma permissão definida para o protocolo.
204        query = session.query(Permissao).filter(Permissao.protocolo_id==protocolo_id)
205        permissoes = query.all()
206
207        #na criacao do protocolo não existem permissoes
208        if not permissoes:
209            escrita = True
210        else:
211            #nas demais, deve-se desativar a escrita da permissao do tramite anterior
212            escrita = False
213            permissao_anterior = permissoes[-1]
214            permissao_anterior.escrita = False
215
216        permissao = Permissao(
217                    protocolo_id=protocolo_id,
218                    area_id=area_id,
219                    leitura=True,
220                    escrita=escrita,
221                    )
222        session.add(permissao)
223
224def calculaDigitoVerificador(seq, ano):
225    return int(math.log(seq + ano) * 10000) % 100
226
227class Protocolo(Base):
228    implements(IProtocolo)
229    __tablename__ = 'protocolo'
230    __table_args__ = TABLE_ARGS
231    id = Column(Integer, primary_key=True)
232    tipoprotocolo = Column(String(1), nullable=False)
233    seq = Column(Integer, nullable=False)
234    ano = Column(Integer, nullable=False)
235    dv = Column(Integer, nullable=False)
236    numero = Column(String(20), unique=True, nullable=False)
237    data = Column(DateTime(), default=datetime.datetime.now(), nullable=False)
238    tipodocumento_id = Column(Integer, ForeignKey('tipodocumento.id'))
239    tipodocumento = relationship("TipoDocumento", backref="protocolo")
240    numero_documento = Column(String(20))
241    data_emissao = Column(DateTime())
242    assunto = Column(String(100), nullable=False)
243    situacao_id = Column(Integer, ForeignKey('situacao.id'))
244    situacao = relationship("Situacao", backref="protocolo")
245    apenso_id = Column(Integer, ForeignKey('protocolo.id'))
246    apenso = relationship("Protocolo", backref=backref('apensado', remote_side=id))
247    pessoa_origem = relationship("PessoaOrigem", backref="pessoa_origem")
248    pessoa_destino = relationship("PessoaDestino", backref="pessoa_destino")
249    permissao = relationship("Permissao", backref="protocolo")
250    notificacao = relationship("Notificacao", backref="protocolo")
251    observacao = relationship("Observacao", backref="protocolo")
252    anexo = relationship("Anexo", backref="protocolo")
253    tramite = relationship("Tramite", backref="protocolo")
254   
255    def __init__(self, tipoprotocolo, tipodocumento_id, numero_documento, data_emissao, assunto, situacao_id):
256        self.tipoprotocolo = tipoprotocolo
257        self.tipodocumento_id = tipodocumento_id
258        self.numero_documento = numero_documento
259        self.data_emissao = data_emissao
260        self.assunto = assunto
261        self.situacao_id = situacao_id
262        session = Session()
263
264        # TODO: isso não pode ser feito dessa maneira, pois desconsidera o session e requer um commit ao invez de um flush
265        self.ano = datetime.datetime.now().year
266        max_seq = session.bind.execute('SELECT max(p.seq) from protocolo p where p.ano = %d' % self.ano).fetchone()[0]
267        self.seq = max_seq is None and 1 or max_seq + 1
268        self.dv = calculaDigitoVerificador(self.seq, self.ano)
269        self.numero = "%s-%08d/%04d-%02d" % (tipoprotocolo, self.seq, self.ano, self.dv)
270
271    def __repr__(self):
272        return "<Protocolo:%s>" % self.numero
273
274class Referencia(Base):
275    __tablename__ = 'referencia'
276    __table_args__ = TABLE_ARGS
277    id = Column(Integer, primary_key=True)
278    protocolo_id = Column(Integer, ForeignKey('protocolo.id'))
279    protocolo = relationship("Protocolo", primaryjoin=(protocolo_id==Protocolo.id), backref="protocolo")
280    referencia_id = Column(Integer, ForeignKey('protocolo.id'))
281    referencia = relationship("Protocolo", primaryjoin=(referencia_id==Protocolo.id), backref="referencia")
282
283class Transicao(Base):
284    __tablename__ = 'transicao'
285    __table_args__ = TABLE_ARGS
286    id = Column(Integer, primary_key=True)
287    fluxo_id = Column(Integer, ForeignKey('fluxo.id'))
288    passo = Column(Integer, default=1, nullable=False)     
289    area_origem_id = Column(Integer, ForeignKey('area.id'))
290    area_origem = relationship("Area", primaryjoin=(area_origem_id==Area.id), backref="area_origem")
291    area_destino_id = Column(Integer, ForeignKey('area.id'))
292    area_destino = relationship("Area", primaryjoin=(area_destino_id==Area.id), backref="area_destino")
293
294class Fluxo(Base):
295    __tablename__ = 'fluxo'
296    __table_args__ = TABLE_ARGS
297    id = Column(Integer, primary_key=True)
298    nome = Column(String(40), unique=True, nullable=False)
299    tipodocumento_id = Column(Integer, ForeignKey('tipodocumento.id'))
300    tipodocumento = relationship("TipoDocumento", backref="fluxo")
301    flexivel = Column(Boolean(), default=False)
302    transicao = relationship("Transicao", backref="fluxo")
303
304class LogUtilizacao(Base):
305    __tablename__ = 'logutilizacao'
306    __table_args__ = TABLE_ARGS
307    id = Column(Integer, primary_key=True)
308    data = Column(DateTime(), default=datetime.datetime.now(), nullable=False)
309    usuario = Column(String(50))
310    url = Column(Text(), nullable=False)
311
312class LogModificacao(Base):
313    __tablename__ = 'logmodificacao'
314    __table_args__ = TABLE_ARGS
315    id = Column(Integer, primary_key=True)
316    data = Column(DateTime(), default=datetime.datetime.now(), nullable=False)
317    usuario = Column(String(50), nullable=False)
318    protocolo_id = Column(Integer, ForeignKey('protocolo.id'))
319    protocolo = relationship("Protocolo", backref="log")
320    anexo_id = Column(Integer, ForeignKey('anexo.id'))
321    anexo = relationship("Anexo", backref="log")
322    observacao_id = Column(Integer, ForeignKey('observacao.id'))
323    observacao = relationship("Observacao", backref="log")
324    tramite_id = Column(Integer, ForeignKey('tramite.id'))
325    tramite = relationship("Tramite", backref="log")
326    detalhes = Column(Text(), nullable=False)
327
328if __name__ == '__main__':
329
330    if CREATE_ALL_TABLES:
331        metadata = Base.metadata
332        metadata.drop_all(engine)
333        metadata.create_all(engine)
334
335    if not CREATE_SAMPLES:
336        sys.exit()
337
338    session = Session()
339
340    # TipoDocumento
341    td1 = TipoDocumento(nome='Projeto')
342    session.add(td1)
343    td2 = TipoDocumento(nome='Parecer')
344    session.add(td2)
345    td3 = TipoDocumento(nome='Carta')
346    session.add(td3)
347
348    # Situacao
349    st1 = Situacao(nome='Tramitando', inicial = True)
350    session.add(st1)
351    st2 = Situacao(nome='Em Análise')
352    session.add(st2)
353    st3 = Situacao(nome='Arquivado', final = True)
354    session.add(st3)
355
356    # TipoEntrega
357    te1 = TipoEntrega(nome='Pessoalmente')
358    session.add(te1)
359    te2 = TipoEntrega(nome='SEDEX')
360    session.add(te2)
361    te3 = TipoEntrega(nome='email')
362    session.add(te3)
363
364    session.flush()
365
366    # Area
367    a1 = Area(sigla='t1', nome='Teste1')
368    session.add(a1)
369    session.flush()
370    a2 = Area(sigla='t2', nome='Teste2', chefia_id=a1.id)
371    session.add(a2)
372    session.flush()
373    a3 = Area(sigla='t3', nome='Teste3', chefia_id=a2.id)
374    session.add(a3)
375    session.flush()
376
377    # UF
378    UFs = """
379          AC Acre
380          AL Alagoas
381          AP Amapá
382          AM Amazonas
383          BA Bahia
384          CE Ceará
385          DF Distrito Federal
386          ES Espirito Santo
387          GO Goiás
388          MA Maranhão
389          MT Mato Grosso
390          MS Mato Grosso do Sul
391          MG Minas Gerais
392          PA Pará
393          PB Paraíba
394          PR Paraná
395          PE Pernanbuco
396          PI Piauí
397          RJ Rio de Janeiro
398          RN Rio Grande do Norte
399          RS Rio Grande do Sul
400          RO Rondônia
401          RR Roraima
402          SC Santa Catarina
403          SP São Paulo
404          SE Sergipe
405          TO Tocantins
406          """
407    UFs = [{'sigla':uf.strip().split()[0],
408            'nome':" ".join(uf.strip().split()[1:])} \
409            for uf in UFs.split('\n') if uf.strip()]
410    for uf in UFs:
411        uf1 = UF(sigla=uf['sigla'], nome=uf['nome'])
412        session.add(uf1)
413
414    # Pessoa
415    ps1 = Pessoa(u'Xiru', u'xiru@xiru.org', area_id=a1.id)
416    session.add(ps1)
417    ps2 = Pessoa(u'Tião Macalé', u'tiao@macale.net', area_id=a2.id)
418    session.add(ps2)
419    ps3 = Pessoa(u'ZÉ Pequeno', u'john@small.org', 'Rua dos bobos, 0', 'Centro', 95096000,
420                 'Caxias do Sul', 1, '54 3226.1234', '12312312312', 'F', 'Baiano', a3.id)
421    session.add(ps3)
422    ps4 = Pessoa(u'BOPE', 'cpt.nascimento@bope.gov.br', 'Morro dos Caveiras, 100', u'Favela do Alemão', 12312000,
423                 'Rio de Janeiro', 1, '11 1212.1234', '12312312312', 'O', u'Capitão Nascimento', a3.id)
424    session.add(ps4)
425    session.flush()
426
427    # Responsavel
428    re1 = Responsavel(area_id=a1.id, pessoa_id=ps2.id)
429    session.add(re1)
430    re2 = Responsavel(area_id=a2.id, pessoa_id=ps3.id)
431    session.add(re2)
432    re3 = Responsavel(area_id=a3.id, pessoa_id=ps1.id)
433    session.add(re3)
434    re4 = Responsavel(area_id=a1.id, pessoa_id=ps3.id)
435    session.add(re4)
436    re5 = Responsavel(area_id=a2.id, pessoa_id=ps1.id)
437    session.add(re5)
438    re6 = Responsavel(area_id=a3.id, pessoa_id=ps2.id)
439    session.add(re6)
440
441    session.flush()
442
443    # Protocolo
444    pt1 = Protocolo('I', td1.id, None, None, 'Assunto 1...', st1.id)
445    session.add(pt1)
446    session.commit()
447    pt2 = Protocolo('R', td2.id, '123', None, 'Assunto 2...', st2.id)
448    session.add(pt2)
449    session.commit()
450    pt3 = Protocolo('E', td3.id, '456-X', datetime.datetime.now(), 'Assunto 3...', st3.id)
451    session.add(pt3)
452    session.commit()
453
454    # Pessoa de Origem
455    po1 = PessoaOrigem(protocolo_id=pt1.id, pessoa_id=ps1.id)
456    session.add(po1)
457    po2 = PessoaOrigem(protocolo_id=pt2.id, pessoa_id=ps2.id)
458    session.add(po2)
459    po3 = PessoaOrigem(protocolo_id=pt3.id, pessoa_id=ps3.id)
460    session.add(po3)
461    po4 = PessoaOrigem(protocolo_id=pt3.id, pessoa_id=ps4.id)
462    session.add(po4)
463
464    # Pessoa de Destino
465    pd1 = PessoaDestino(protocolo_id=pt1.id, pessoa_id=ps4.id)
466    session.add(pd1)
467    pd2 = PessoaDestino(protocolo_id=pt2.id, pessoa_id=ps4.id)
468    session.add(pd2)
469    pd3 = PessoaDestino(protocolo_id=pt3.id, pessoa_id=ps1.id, tipoentrega_id=te2.id, objeto_correios='RM283505565BR')
470    session.add(pd3)
471    pd4 = PessoaDestino(protocolo_id=pt3.id, pessoa_id=ps2.id, tipoentrega_id=te3.id, data_entrega=datetime.datetime.now())
472    session.add(pd4)
473   
474    # Notificacao
475    nt1 = Notificacao(protocolo_id=pt1.id, pessoa_id=ps1.id)
476    session.add(nt1)
477    nt2 = Notificacao(protocolo_id=pt3.id, pessoa_id=ps3.id)
478    session.add(nt2)
479    nt3 = Notificacao(protocolo_id=pt3.id, pessoa_id=ps4.id)
480    session.add(nt3)
481   
482    # Observacao
483    ob1 = Observacao(protocolo_id=pt1.id, texto='Texto 1')
484    session.add(ob1)
485    ob2 = Observacao(protocolo_id=pt1.id, texto='Texto 2')
486    session.add(ob2)
487    ob3 = Observacao(protocolo_id=pt3.id, texto='Texto 3')
488    session.add(ob3)
489    ob4 = Observacao(protocolo_id=pt3.id, texto='Texto 4')
490    session.add(ob4)
491   
492    # Anexo
493    an1 = Anexo(protocolo_id=pt1.id, arquivo='documento.txt', tamanho=1200)
494    session.add(an1)
495    an2 = Anexo(protocolo_id=pt3.id, arquivo='documento2.doc', tamanho=2300)
496    session.add(an2)
497    an3 = Anexo(protocolo_id=pt3.id, arquivo='apresent.ppt', tamanho=2500)
498    session.add(an3)
499   
500    # Tramite
501    data = datetime.datetime.now()
502    tr1 = Tramite(pt1.id, a1.id, None, data,'',False)
503    session.add(tr1)
504    tr2 = Tramite(pt1.id, a2.id, None, data, 'Revisar...')
505    session.add(tr2)
506    tr3 = Tramite(pt1.id, a3.id, None, data, 'Verificar...')
507    session.add(tr3)
508    session.flush()
509
510    session.commit()
Note: Veja TracBrowser para ajuda no uso do navegador do trac.
 

The contents and data of this website are published under license:
Creative Commons 4.0 Brasil - Atribuir Fonte - Compartilhar Igual.