class Contrato(models.Model): """ Uma instância dessa classe representa um contrato. (Ex. Instituto Uniemp e Telefônica) """ numero = models.CharField(_(u'Número'), max_length=20) descricao = models.TextField(_(u'Descrição'), blank=True) data_inicio = NARADateField(_(u'Início')) auto_renova = models.BooleanField(_(u'Auto renovação?'), default=False) limite_rescisao = NARADateField(_(u'término'), null=True, blank=True) entidade = models.ForeignKey('identificacao.Entidade') anterior = models.ForeignKey('outorga.Contrato', verbose_name=_('Contrato anterior'), null=True, blank=True) arquivo = models.FileField(upload_to='contrato') # Retorna a entidade e a data de ínicio do Contrato. def __unicode__(self): inicio = self.data_inicio.strftime("%d/%m/%Y") return u"%s - %s" % (self.entidade, inicio) # Retorna um ícone se o contrato tiver anexo. def existe_arquivo(self): if self.arquivo and self.arquivo.name.find('/') >= 0: a = '<center><a href="%s"><img src="%simg/arquivo.png" /></a></center>'\ % (self.arquivo.url, settings.STATIC_URL) return a return ' ' existe_arquivo.allow_tags = True existe_arquivo.short_description = _(u'Arquivo')
class ControleFerias(models.Model): """ Controle efetivo das férias, com as datas reais de saída e retorno """ ferias = models.ForeignKey('membro.Ferias') inicio = NARADateField() termino = NARADateField() oficial = models.BooleanField(_(u'Oficial?'), default=False) obs = models.TextField(null=True, blank=True) vendeu10 = models.BooleanField(_(u'Vendeu 10 dias?'), default=False) antecipa13 = models.BooleanField(_(u'Antecipação de 13º salário?'), default=False) dias_uteis_fato = models.IntegerField(_(u'Dias úteis tirados de fato')) dias_uteis_aberto = models.IntegerField(_(u'Dias úteis em aberto')) arquivo_oficial = models.FileField(upload_to='controleferias__arquivooficial', null=True, blank=True) def dia_ferias(self, dia): # verifica se tem algum período de férias com dias úteis tirados de fato # não deve entrar na conta se forem período de férias com venda de dias, ou somente marcação de vencimento # de férias is_ferias = False if self.dias_uteis_fato > 0: is_ferias = is_ferias or (self.inicio <= dia <= self.termino) return is_ferias def __unicode__(self): return u"%s - %s" % (self.inicio, self.termino) class Meta: verbose_name = _(u'Controle de férias') verbose_name_plural = _(u'Controles de férias')
class Outorga(models.Model): """ Uma instância dessa classe representa um pedido de concessão. O método '__unicode__' Retorna o termo e a categoria do pedido de concessão. O método 'inicio' Retorna a data de início do termo. O método 'mostra_categoria' Retorna o nome da categoria. O método 'mostra_termo' Retorna o termo. O método 'existe_arquivo' Retorna um ícone com link para consulta dos arquivos anexados. A class 'Meta' Define a descrição do modelo (singular e plural) e a ordenação dos dados pela data de solicitação. """ categoria = models.ForeignKey('outorga.Categoria', verbose_name=_(u'Categoria')) termo = models.ForeignKey('outorga.Termo', verbose_name=_(u'Termo')) termino = NARADateField(_(u'Término'), help_text=_(u'Término da vigência do processo')) obs = models.TextField(_(u'Observação'), blank=True) data_presta_contas = NARADateField(_(u'Prest. Contas'), blank=True, null=True, help_text=_(u'Data de Prestação de Contas')) data_solicitacao = NARADateField(_(u'Solicitação'), help_text=_(u'Data de Solicitação do Pedido de Concessão')) arquivo = models.FileField(upload_to=upload_dir, null=True, blank=True) protocolo = models.FileField(upload_to=upload_dir, null=True, blank=True) # Retorna o termo e a categoria. def __unicode__(self): return u'%s - %s' % (self.termo.num_processo, self.categoria.nome) # Início do processo @ property def inicio(self): return self.termo.inicio.strftime("%d/%m/%Y") # inicio.short_description = _(u'Início') # Retorna a categoria. def mostra_categoria(self): return self.categoria.nome mostra_categoria.short_description = _(u'Categoria') # Retorna o termo. def mostra_termo(self): return self.termo.num_processo mostra_termo.short_description = _(u'Termo') # Retorna um ícone se o pedido de concessão tiver arquivos. def existe_arquivo(self): a = '<center><a href="%s?outorga__id__exact=%s">' \ '<img src="%simg/arquivo.png" /></a></center>' \ % (urlresolvers.reverse('admin:outorga_arquivo_changelist'), self.id, settings.STATIC_URL) if self.arquivo: return a return ' ' existe_arquivo.allow_tags = True existe_arquivo.short_description = _(u'Arquivo') # Define a descrição do modelo e a ordenação dos dados pelo termo. class Meta: verbose_name = _(u'Concessão') verbose_name_plural = _(u'Histórico de Concessões') ordering = ('data_solicitacao', )
class OrdemDeServico(models.Model): """ Uma instância dessa classe representa uma ordem de serviço de um Contrato. arquivos: related_name para ArquivoOS """ numero = models.CharField(_(u'Número'), max_length=20) tipo = models.ForeignKey('outorga.TipoContrato') acordo = models.ForeignKey('outorga.Acordo') contrato = models.ForeignKey('outorga.Contrato') data_inicio = NARADateField(_(u'Início')) data_rescisao = NARADateField(_(u'Término'), null=True, blank=True) antes_rescisao = models.IntegerField(_(u'Prazo p/ solicitar rescisão (dias)'), null=True, blank=True) descricao = models.TextField(_(u'Descrição')) # arquivo = models.FileField(upload_to='OS', null=True, blank=True) estado = models.ForeignKey('outorga.EstadoOS') pergunta = models.ManyToManyField('memorando.Pergunta', null=True, blank=True) substituicoes = models.TextField(null=True, blank=True) # Retorna a descrição. def __unicode__(self): return u"%s %s" % (self.tipo, self.numero) # Retorna o prazo para solicitar recisão (campo 'antes_rescisao'). def mostra_prazo(self): if self.antes_rescisao < 1: return '-' if self.antes_rescisao > 1: return u'%s dias' % self.antes_rescisao return u'%s dias' % self.antes_rescisao mostra_prazo.short_description = _(u'Prazo p/ rescisão') def entidade(self): return self.contrato.entidade def primeiro_arquivo(self): if self.arquivos.all().exists(): osf = self.arquivos.all()[:1].get() return osf.arquivo return None class Meta: verbose_name = _(u'Alteração de contrato (OS)') verbose_name_plural = _(u'Alteração de contratos (OS)') ordering = ('tipo', 'numero')
class ExtratoPatrocinio(models.Model): localiza = models.ForeignKey('financeiro.LocalizaPatrocinio', verbose_name=_(u'Localização do patrocínio')) data_oper = NARADateField(_(u'Data da operação')) cod_oper = models.IntegerField( _(u'Código da operação'), validators=[MinValueValidator(0), MaxValueValidator(999999999)], help_text=u'Código com máximo de 9 dígitos.') valor = models.DecimalField(max_digits=12, decimal_places=2) historico = models.CharField(max_length=30) obs = models.TextField() class Meta: verbose_name = _(u'Extrato do patrocínio') verbose_name_plural = _(u'Extratos dos patrocínios') def __unicode__(self): return u'%s - %s - %s' % (self.localiza.consignado, self.data_oper, self.valor)
class Membro(models.Model): CACHE_KEY__CARGO_ATUAL = 'model_membro__cargo_atual_%d' """ Uma instância dessa classe representa um membro de uma equipe. O método '__unicode__' Retorna os campos 'nome' e 'cargo'. O método 'existe_ramal' Retorna o campo 'ramal' se estiver preenchido. O método 'existe_curriculo' Retorna um ícone com link para o currículo lattes se o campo 'url_lattes' se estiver preenchido. A class 'Meta' Define a ordenação dos dados pelos campos 'equipe' e 'membro' e define que um membro deve ser único pelos campos 'equipe', 'nome' e 'funcao'. """ nome = models.CharField(_(u'Nome'), max_length=50, help_text=_(u'ex. Caio Andrade')) rg = models.CharField(_(u'RG'), max_length=12, help_text=_(u'ex. 00.000.000-0'), blank=True, null=True) cpf = CPFField(_(u'CPF'), blank=True, null=True, help_text=_(u'ex. 000.000.000-00')) email = models.CharField(_(u'E-mail'), max_length=50, blank=True, help_text=_(u'ex. [email protected]')) ramal = models.IntegerField(_(u'Ramal'), blank=True, null=True) obs = models.TextField(_(u'Observação'), blank=True) url_lattes = models.URLField(_(u'Currículo Lattes'), blank=True, help_text=_(u'URL do Currículo Lattes')) foto = models.ImageField(upload_to='membro', blank=True, null=True) data_nascimento = NARADateField(_(u'Nascimento'), help_text=_(u'Data de nascimento'), blank=True, null=True) site = models.BooleanField(_(u'Exibir no site?'), default=False) contato = models.ForeignKey('identificacao.Contato', null=True, blank=True) # Retorna o nome e o cargo. def __unicode__(self): cargo = self.cargo_atual if cargo: return u'%s (%s)' % (self.nome, cargo) return u'%s' % self.nome # Verifica se o campo ramal está preenchido. def existe_ramal(self): if self.ramal: return self.ramal return '' existe_ramal.short_description = _(u'Ramal') # Retorna um ícone com o link para o currículo lattes. def existe_curriculo(self): if self.url_lattes: a = '<center><a href="%s">%s</a></center>' % (self.url_lattes, self.url_lattes) return a return '' existe_curriculo.allow_tags = True existe_curriculo.short_description = _(u'Currículo Lattes') # cargo atual do membro, caso exista, a partir do histórico @property def cargo_atual(self): retorno = cache.get(Membro.CACHE_KEY__CARGO_ATUAL % self.id) if retorno is None: cargos = [] for h in self.historico_set.all(): if h.termino is None: cargos.append(h.cargo.nome) retorno = ' - '.join(cargos) cache.set(Membro.CACHE_KEY__CARGO_ATUAL % self.id, retorno, 600) return retorno # se o membro é atualmente funcionario @property def funcionario(self): return Historico.ativos.filter(membro=self, funcionario=True).count() > 0 @property def ativo(self): return Historico.ativos.filter(membro=self).count() > 0 @cached_property def data_inicio(self): return Historico.objects.filter(membro=self).order_by('inicio').values_list('inicio')[0][0] @property def carga_horaria(self): return Historico.objects.filter(membro=self).order_by('inicio').values_list('carga_horaria')[0][0] # Define a ordenação e unicidade dos dados. class Meta: ordering = ('nome', )
class DispensaLegal(models.Model): """ Dispensas legais, como por exemplo dispensa médica, para trabalho em eleição, luto, casamento, etc """ membro = models.ForeignKey('membro.Membro', verbose_name=_(u'Membro'), limit_choices_to=Q(historico__funcionario=True) & Q(historico__termino__isnull=True)) tipo = models.ForeignKey('membro.TipoDispensa', verbose_name=_('Tipo de dispensa')) justificativa = models.TextField() inicio_direito = NARADateField(_(u'Início do direito')) dias_uteis = models.IntegerField(_(u'Dias úteis.'), help_text='*mover para dias corridos', null=True, default=0) inicio_realizada = NARADateField(_(u'Início da realização da dispensa'), blank=True, null=True) realizada = models.BooleanField(_(u'Já realizada?'), default=False) atestado = models.BooleanField(_(u'Há atestado?'), default=False) arquivo = models.FileField(upload_to='dispensas/', null=True, blank=True) dias_corridos = models.IntegerField(_(u'Duração em dias corridos'), null=True, default=0) horas = models.IntegerField(_(u'Horas'), null=True, default=0) minutos = models.IntegerField(_(u'Minutos'), null=True, default=0) def __unicode__(self): return u"%s - %s" % (self.membro, self.justificativa) @cached_property def termino_realizada(self): """ Calcula a data de termino da dispensa, descontado o sábado e o domingo Leva em conta os feriados. """ soma_dias = 0 if self.realizada and self.inicio_realizada: if self.dias_corridos: soma_dias += self.dias_corridos if self.horas: soma_dias += self.horas / 8.0 if self.minutos: soma_dias += self.minutos / 60.0 if self.dias_corridos >= 1: return self.inicio_realizada + timedelta(soma_dias - 1) return self.inicio_realizada def dia_dispensa(self, dia): is_dispensa = False horas_dispensa = 0 if self.realizada and self.inicio_realizada: is_dispensa = self.inicio_realizada <= dia <= self.termino_realizada if is_dispensa: if self.termino_realizada == dia: if self.horas or self.minutos: if self.horas: horas_dispensa += self.horas % self.membro.carga_horaria if self.minutos: horas_dispensa += (self.minutos % 60.0)/60 elif self.dias_corridos: horas_dispensa = self.membro.carga_horaria elif dia < self.termino_realizada: horas_dispensa = self.membro.carga_horaria elif dia > self.termino_realizada: horas_dispensa = 0 return {'is_dispensa': is_dispensa, 'horas': horas_dispensa} class Meta: verbose_name = _(u'Dispensa') verbose_name_plural = _(u'Dispensas')
class Ferias(models.Model): """ Controle de período aquisitivo para as férias """ membro = models.ForeignKey('membro.Membro', verbose_name=_(u'Membro'), limit_choices_to=Q(historico__funcionario=True) & Q(historico__termino__isnull=True)) inicio = NARADateField(_(u'Início do período aquisitivo'), help_text=_(u'Início do período de trabalho')) realizado = models.BooleanField(_(u'Férias já tiradas?'), default=False) def save(self, *args, **kwargs): self.inicio_ferias = self.inicio + timedelta(365) self.fim_ferias = self.inicio_ferias + timedelta(365) super(Ferias, self).save(*args, **kwargs) # Retorna o membro e o período de férias. def __unicode__(self): if self.inicio: inicio = self.inicio.strftime('%d/%m/%Y') else: inicio = '' return u'%s | Início período: %s' % (self.membro, inicio) def inicio_ferias(self): if self.inicio is not None: return (self.inicio + timedelta(365)).strftime('%d/%m/%Y') return '' inicio_ferias.short_description = u'Início do período para férias' def fim_ferias(self): if self.inicio is not None: return (self.inicio + timedelta(730)).strftime('%d/%m/%Y') return '' fim_ferias.short_description = u'Final do período para férias' def link_edit(self): if not self.id: return '' return '<a href="%s?" target="_blank">Detalhes</a>' % reverse('admin:membro_ferias_change', args=[self.id]) link_edit.allow_tags = True link_edit.short_description = u'Detalhes do período de férias' @property def trab_termino(self): return self.trab_inicio+timedelta(365) # Retorna quantos dias de férias foi solicitado. def qtde_dias(self): if self.periodo_escolha_inic and self.periodo_escolha_term: dias = self.periodo_escolha_term - self.periodo_escolha_inic dias = dias.days + 1 return '%s dias' % dias return '' qtde_dias.short_description = _(u'Dias solicitados') # Diz se o prazo de aquisição das férias já foi completado def completo(self): umano = date(self.inicio.year+1, self.inicio.month, self.inicio.day) return umano <= datetime.now().date() completo.boolean = True @classmethod def total_dias_uteis_aberto(self, membro_id): # Retorna o total de dias em aberto para o membro, em segundos total_dias_uteis_aberto = 0 ferias = Ferias.objects.filter(membro=membro_id) membro = Membro.objects.get(id=membro_id) for f in ferias: controles = ControleFerias.objects.filter(ferias=f).select_related().order_by('inicio') for c in controles: if c.dias_uteis_aberto and c.dias_uteis_aberto > 0: total_dias_uteis_aberto = total_dias_uteis_aberto + c.dias_uteis_aberto if c.dias_uteis_fato: total_dias_uteis_aberto = total_dias_uteis_aberto - c.dias_uteis_fato return total_dias_uteis_aberto * membro.carga_horaria * 60 * 60 # Define a descrição do modelo, ordenação e a unicidade dos dados. class Meta: verbose_name = _(u'Férias') verbose_name_plural = _(u'Férias') unique_together = (('membro', 'inicio'),) ordering = ('inicio',)
class Patrimonio(models.Model): U_TO_PX = 19 U_TO_PT = 15.0 U_TO_EM = 2.0 """ Uma instância dessa classe representa um item do patrimônio. """ patrimonio = models.ForeignKey('patrimonio.Patrimonio', null=True, blank=True, verbose_name=_(u'Contido em'), related_name='contido') pagamento = models.ForeignKey('financeiro.Pagamento', null=True, blank=True) ns = models.CharField(_(u'Número de série'), null=True, blank=True, max_length=50) complemento = models.CharField('Compl', max_length=100, null=True, blank=True) valor = models.DecimalField(u'Vl unit', max_digits=12, decimal_places=2, null=True, blank=True) # procedencia = models.CharField(_(u'Procedência'), null=True, blank=True, max_length=100) obs = models.TextField(null=True, blank=True) agilis = models.BooleanField(_(u'Agilis?'), default=True) equipamento = models.ForeignKey('patrimonio.Equipamento', null=True, blank=True) checado = models.BooleanField(default=False) apelido = models.CharField(max_length=30, null=True, blank=True) descricao = models.TextField(_(u'Descrição NF')) tem_numero_fmusp = models.BooleanField('Tem nº de patrimônio oficial?', default=False) numero_fmusp = models.IntegerField('Nº de patrimônio oficial', null=True, blank=True) entidade_procedencia = models.ForeignKey('identificacao.Entidade', verbose_name=_(u'Procedência'), null=True, blank=True, help_text=u"Representa a Entidade que fornece este patrimônio.") # Campos duplicados que existem no Model de Equipamento tipo = models.ForeignKey('patrimonio.Tipo') descricao_tecnica = models.TextField(u'Descrição técnica', null=True, blank=True) imagem = models.ImageField(upload_to='patrimonio', null=True, blank=True) isbn = models.CharField(_(u'ISBN'), null=True, blank=True, max_length=20) titulo_autor = models.CharField(_(u'Título e autor'), null=True, blank=True, max_length=100) especificacao = models.FileField(u'Especificação', upload_to='patrimonio', null=True, blank=True) tamanho = models.DecimalField(u'Tamanho (em U)', max_digits=5, decimal_places=2, blank=True, null=True) revision = models.CharField(u'Revision', null=True, blank=True, max_length=30) version = models.CharField(u'Version', null=True, blank=True, max_length=30) garantia_termino = NARADateField(_(u'Data de término da garantia'), null=True, blank=True) def __unicode__(self): if self.pagamento_id: return u'%s - %s - %s - %s' % (self.pagamento.protocolo.num_documento, self.apelido, self.ns, self.descricao) else: return u'%s - %s - %s' % (self.apelido, self.ns, self.descricao) @property def procedencia(self): if self.entidade_procedencia_id: return self.entidade_procedencia.sigla return '' def save(self, *args, **kwargs): super(Patrimonio, self).save(*args, **kwargs) # ROGERIO: COMENTANDO O CODIGO DE SALVAMENTO DE HISTORICOS NO FILHO # DEVIDO A INCONCISTENCIA NO CASO DE UPDATE DO HISTORICO ATUAL DO PATRIMONIO # # fazendo a busca do historico atual, pois está em cache # # e esta requisição pode ter mudado este valor # ht = self.historicolocal_set.order_by('-data', '-id') # if not ht: return None # self_historico_atual = ht[0] # # Rogerio: após salvar o patrimonio, verifica se os patrimonios filhos estão # # no mesmo endereço e posição. # # Se não estiverem, cria um novo histórico de endereço para todos os filhos # if Patrimonio.objects.filter(patrimonio=self).exists(): # filhos = Patrimonio.objects.filter(patrimonio=self) # # for filho in filhos: # # Rogerio: se não tiver endereço, não faz nada com os patrimonios filhos, # # já que não podemos remover os endereços # # # # Também não modificamos se o filho possui um histórico com data mais atual # if self_historico_atual: # if not filho.historico_atual or \ # (self_historico_atual.endereco != filho.historico_atual.endereco) or \ # (self_historico_atual.posicao != filho.historico_atual.posicao) or \ # (self_historico_atual.data > filho.historico_atual.data): # # novoHistorico = HistoricoLocal.objects.create(memorando=self_historico_atual.memorando, # patrimonio=filho, # endereco=self_historico_atual.endereco, # estado=self_historico_atual.estado, # descricao="Movimentado junto com o patrimonio %s [%s]"% # (self.id, self_historico_atual.descricao), # data=self_historico_atual.data, # posicao=self.historico_atual.posicao, # ) @property def marca(self): retorno = '' if self.equipamento and self.equipamento.entidade_fabricante and self.equipamento.entidade_fabricante.sigla: retorno = self.equipamento.entidade_fabricante.sigla return retorno @property def modelo(self): retorno = '' if self.equipamento_id: retorno = self.equipamento.modelo return retorno @property def part_number(self): retorno = '' if self.equipamento_id: retorno = self.equipamento.part_number return retorno @cached_property def historico_atual(self): """ Objeto HistoricoLocal mais recente do Patrimonio. Se ocorrer de dois históricos estarem na mesma data, retorna o objeto com ID maior. """ ht = self.historicolocal_set.order_by('-data', '-id') if not ht: return None return ht[0] @cached_property def historico_atual_prefetched(self): """ Utilizar este método ao invés de historico_atual se for feito o prefetch_related antecipadamente. Em caso de dúvida, ou se não for utilizado o prefetch, utilizar o método historico_atual, pois o tempo de execução deste método será o dobro do normal. Exemplo de utilização, com prefetch_related: from django.db.models import Prefetch Patrimonio.objects.all().prefetch_related(Prefetch('historicolocal_set', queryset=HistoricoLocal.objects.select_related('k'))) """ # ht = sorted(self.historicolocal_set.all(), key=lambda x: x.id, reverse=True) ht = sorted(self.historicolocal_set.all(), key=lambda x: x.id, reverse=True) ht = sorted(ht, key=lambda x: x.data, reverse=True) if not ht: return None return ht[0] def posicao(self): ht = self.historico_atual if not ht: return u'' return u'%s - %s' % (ht.endereco.complemento, ht.posicao) # Retorna os patrimônios de um termo. @classmethod def patrimonios_termo(cls, t): return cls.objects.filter(pagamento__protocolo__termo=t) # retorna o número do documento fiscal de compra do equipamento def nf(self): if self.pagamento is not None and self.pagamento.protocolo is not None: return u'%s' % self.pagamento.protocolo.num_documento else: return '' nf.short_description = u'NF' # retorna modalidade, parcial e pagina para exibicao no admin def auditoria(self): if not self.pagamento: return '' if not self.pagamento.origem_fapesp: return '' modalidade = self.pagamento.origem_fapesp.item_outorga.natureza_gasto.modalidade.sigla return u'%s (%s/%s)' % (modalidade, self.pagamento.parcial(), self.pagamento.pagina()) auditoria.short_description = u'Material (par/pág)' def altura_em_px(self): if self.tamanho: tamanho = self.tamanho else: tamanho = 0 # calculando a altura em furos tam = int(round(tamanho * 3)) return tam * self.U_TO_PX / 3.0 def altura_em_pt(self): if self.tamanho: tamanho = self.tamanho else: tamanho = 0 # calculando a altura em furos tam = int(round(tamanho * 3)) return tam * self.U_TO_PT / 3.0 # Retorna a posição Y em pixels. def eixoy_em_px(self): eixoY = 0 # Este patrimonio precisa estar contido em um Rack para definirmos a posição if self.patrimonio_id is not None and self.patrimonio.equipamento_id and self.patrimonio.equipamento.tipo_id\ and self.patrimonio.equipamento.tipo.nome == 'Rack': rack = self.patrimonio if rack.tamanho: rack_altura = int(rack.tamanho) * 3 else: # ISSO É UM PROBLEMA DE DADOS INVÁLIDOS. PRECISA SER TRATADO # Configurando como 42Us ou 126 furos rack_altura = 126 pos = self.historico_atual_prefetched.posicao_furo - 1 if self.tamanho: tamanho = self.tamanho else: tamanho = 0 # calculando a altura em furos tam = int(round(tamanho * 3)) # calculando a posição em pixels eixoY = int(round(((rack_altura - pos - tam) * self.U_TO_PX) / 3.0)) - 5.0 return eixoY def eixoy_em_pt(self): return (self.eixoy_em_px() / self.U_TO_PX * self.U_TO_PT) + 5.0 # Verifica se o patrimonio está em posição traseira no rack def is_posicao_traseira(self): flag_traseiro = False if self.historico_atual_prefetched.posicao_colocacao in ('TD', 'TE', 'T', 'T01', 'T02', 'T03'): flag_traseiro = True return flag_traseiro # Verifica se o patrimonio é uma régua de tomadas lateral def is_pdu(self): if self.equipamento_id \ and self.equipamento.tipo_id \ and 'tomada' in self.equipamento.tipo.nome \ and self.historico_atual_prefetched.posicao_colocacao in ('TD', 'TE', 'lD', 'lE', 'LD', 'LE'): return True return False # Retorna o estado atual def estado(self): if not self.historico_atual: return None else: return self.historico_atual.estado # Define a descrição do modelo. class Meta: verbose_name = _(u'Patrimônio') verbose_name_plural = _(u'Patrimônio') ordering = ('tipo', 'descricao')
class ExtratoCC(models.Model): extrato_financeiro = models.ForeignKey( 'financeiro.ExtratoFinanceiro', verbose_name=_(u'Extrato Financeiro'), blank=True, null=True) data_oper = NARADateField(_(u'Data da operação')) cod_oper = models.IntegerField( verbose_name=_(u'Documento'), validators=[MinValueValidator(0), MaxValueValidator(9999999999)], help_text=u'Código com máximo de 10 dígitos.') despesa_caixa = models.BooleanField(_(u'Despesa de caixa?'), default=False) valor = models.DecimalField(_(u'Valor'), max_digits=12, decimal_places=2) historico = models.CharField(_(u'Histórico'), max_length=30) cartao = models.BooleanField(_(u'Cartão?'), default=False) data_extrato = NARADateField(_(u'Data do extrato'), null=True, blank=True) imagem = models.ImageField( _(u'Imagem do cheque'), upload_to='extratocc', null=True, blank=True, help_text=u'Somente imagem .jpeg', validators=[ RegexValidator( regex=".+((\.jpg)|.+(\.jpeg))$", message="Enviar somente imagem jpeg. A proporção da " "largura / altura deve ser maior que 2."), ]) capa = models.TextField(null=True, blank=True) obs = models.TextField(null=True, blank=True) class Meta: verbose_name = _(u'Extrato de Conta corrente') verbose_name_plural = _(u'Extratos de Conta corrente') ordering = ('-data_oper', ) def __unicode__(self): return u'%s - %s - %s - %s' % (self.data_oper, self.cod_oper, self.historico, self.valor) @property def saldo(self): s = ExtratoCC.objects.filter(data_oper__lte=self.data_oper).aggregate( Sum('valor')) return s['valor__sum'] @property def saldo_anterior(self): s = ExtratoCC.objects.filter(data_oper__lt=self.data_oper).aggregate( Sum('valor')) return s['valor__sum'] def parciais(self): mods = {} for p in self.pagamento_set.all()\ .select_related('origem_fapesp', 'origem_fapesp__item_outorga__natureza_gasto__modalidade'): if p.origem_fapesp: modalidade = p.origem_fapesp.item_outorga.natureza_gasto.modalidade.sigla if modalidade not in mods.keys(): mods[modalidade] = {} for a in p.auditoria_set.all(): if a.parcial not in mods[modalidade].keys(): mods[modalidade][a.parcial] = [] if a.pagina not in mods[modalidade][a.parcial]: mods[modalidade][a.parcial].append(a.pagina) parc = '' for modalidade in mods.keys(): parc += '%s [parcial ' % modalidade for p in mods[modalidade].keys(): pags = mods[modalidade][p] pags.sort() parc += '%s (%s)' % (p, ','.join([str(k) for k in pags])) parc += '] ' return parc
class ExtratoFinanceiro(models.Model): entrada_extrato_cc = models.ForeignKey( 'financeiro.ExtratoCC', on_delete=models.SET_NULL, null=True, blank=True) # referencia a uma entrada no ExtratoCC termo = models.ForeignKey('outorga.Termo', verbose_name=_(u'Termo de outorga')) data_libera = NARADateField(_(u'Data')) cod = models.CharField(_(u'Código'), max_length=4, choices=CODIGO_FINANCEIRO) historico = models.CharField(_(u'Histórico'), max_length=40) valor = models.DecimalField(_(u'Valor'), max_digits=12, decimal_places=2) comprovante = models.FileField(_(u'Comprovante da operação'), upload_to='extratofinanceiro', null=True, blank=True) tipo_comprovante = models.ForeignKey( 'financeiro.TipoComprovanteFinanceiro', null=True, blank=True) parcial = models.IntegerField( null=False, blank=False, default=0, validators=[MinValueValidator(0), MaxValueValidator(999999999)]) taxas = models.IntegerField(default=0) class Meta: verbose_name = _(u'Extrato do Financeiro') verbose_name_plural = _(u'Extratos do Financeiro') ordering = ('-data_libera', ) def __unicode__(self): return u'%s - %s - %s - %s' % (self.data_libera, self.cod, self.historico, self.valor) def save(self, *args, **kwargs): for (cod, hist) in CODIGO_FINANCEIRO: if self.cod == cod: self.historico = hist break super(ExtratoFinanceiro, self).save(*args, **kwargs) @property def despesa_caixa(self): try: return self.tipo_comprovante == TipoComprovanteFinanceiro.objects.get( nome=u'Despesa de caixa') except: return False @staticmethod def _insere_extrato_cc(extratoFinanceiro): """ Rotina para inserir no extrato de conta corrente a liberação do financeiro para o Cartão Pesquisa BB. Deve receber um objeto ExtratoFinanceiro. if (retorno == 1) { "Extrato de conta corrente inserido com sucesso." } else if (retorno == 2) { "Extrato de conta corrente já existente." } else { "Extrato de conta corrente não inserido." } """ retorno = -1 ef = extratoFinanceiro if ef.entrada_extrato_cc: retorno = 2 else: ecc1 = ExtratoCC.objects.create( data_oper=ef.data_libera, historico=u'Liberação de verba MP', valor=-ef.valor, cod_oper=ef.data_libera.strftime('%Y%m%d9')) # atribuindo a referencia de entrada no extratoCC # o save() deve ser disparado por quem chamou este método ef.entrada_extrato_cc = ecc1 if ef.taxas > 0: ecc2 = ExtratoCC.objects.create( data_oper=ef.data_libera, historico=u'Liberação de verba TX', valor=ef.taxas * Decimal('1.00'), cod_oper=ef.data_libera.strftime('%Y%m%d9')) ecc3 = ExtratoCC.objects.create( data_oper=ef.data_libera, historico=u'Pagamento TX', valor=ef.taxas * Decimal('-1.00'), cod_oper=ef.data_libera.strftime('%Y%m%d9')) if not ecc2 or not ecc3: retorno = -2 if not ecc1: retorno = -3 else: retorno = 1 return retorno
class Termo(models.Model): """ Uma instância dessa classe representa um Termo de Outorga. O método '__unicode__' Retorna o número completo do processo no formato 'ano/número-digito'. O método 'mostra_membro' Retorna o nome do outorgado. O método 'save' Não permite que o número do termo de ortorga seja alterado. O atributo 'real' Calcula a concessão total em reais de um termo somando os totalizadores das naturezas de gasto considerando todos os pedidos de concessão. O método 'termo_real' Formata o atributo 'real' em formato moeda. O atributo 'dolar' Calcula a concessão total em dolares de um termo somando os totalizadores das naturezas de gasto considerando todos os pedidos pedidos de concessão. O método 'termo_dolar' Formata o atributo 'dolar' em formato moeda. O método 'duracao_meses' Calcula em meses a vigência do termo de outorga a partir das informações dos pedidos de concessão. O atributo 'total_realizado_real' Calcula o total das despesas realizadas em reais de um termo somando os totalizadores das naturezas de gasto considerando todos os pedidos de concessão. O método 'formata_realizado_real' Formata o atributo 'total_realizado_real' em formato moeda. O atributo 'total_realizado_dolar' Calcula o total das despesas realizadas em dolares de um termo somando os totalizadores das naturezas de gasto considerando todos os pedidos de concessão. O método 'formata_realizado_dolar' Formata o atributo 'total_realizado_dolar' em formato moeda. O atributo 'vigencia' Foi criado para retornar o método 'duracao_meses'. O atributo 'num_processo' Foi criado para retornar o método '__unicode__'. A classmethod 'termos_auditoria_fapesp_em_aberto' Retorna os termos que possuem fontes pagadoras (fapesp) que ainda não possuem registro no modelo Auditoria FAPESP. A classmethod 'termos_auditoria_interna_em_aberto' Retorna os termos que possuem fontes pagadoras (interna) que ainda não possuem registro no modelo Auditoria Interna. A 'class Meta' Define a descrição do modelo (singular e plural) e a ordenação dos dados pelo ano. """ ano = models.IntegerField(_(u'Ano'), help_text=_(u'ex. 2008'), default=0) #processo = models.IntegerField(_(u'Processo'), help_text=_(u'ex. 52885'), default=0) processo = models.CharField(_(u'Processo'), max_length=15, help_text=_(u'ex. 52885'), default='0', validators=[RegexValidator(r'^[0-9]+$', u'Somente digitos são permitidos.')]) digito = models.IntegerField(_(u'Dígito'), help_text=_(u'ex. 8'), default=0) inicio = NARADateField(_(u'Início'), help_text=_(u'Data de início do processo'), null=True, blank=True) estado = models.ForeignKey('outorga.Estado', verbose_name=_(u'Estado')) modalidade = models.ManyToManyField('outorga.Modalidade', through='Natureza_gasto', verbose_name=_(u'Pasta')) parecer = models.FileField(u'Parecer inicial', upload_to='termo', blank=True, null=True) parecer_final = models.FileField(u'Parecer final', upload_to='termo', blank=True, null=True) projeto = models.FileField(u'Projeto', upload_to='termo', blank=True, null=True) orcamento = models.FileField(_(u'Orçamento'), upload_to='termo', blank=True, null=True) quitacao = models.FileField(_(u'Quitação'), upload_to='termo', blank=True, null=True) doacao = models.FileField(_(u'Doação'), upload_to='termo', blank=True, null=True) extrato_financeiro = models.FileField(upload_to='termo', blank=True, null=True) relatorio_final = models.FileField(_(u'Relatório Final'), upload_to='termo', blank=True, null=True) # flag para indicar se o termo deve aparecer no relatório gerencial progressivo exibe_rel_ger_progressivo = models.BooleanField(_(u'Exibe o processo no Relatório Gerencial Progressivo?'), default=True) # membro = models.ForeignKey('membro.Membro', verbose_name=_(u'Outorga')) # Retorna o número completo do processo (ano, número e dígito). def __unicode__(self): ano = str(self.ano)[2:] return '%s/%s-%s' % (ano, self.processo, self.digito) # Não permite fazer alteração no número do processo. def save(self, *args, **kwargs): pk = self.pk try: antigo = Termo.objects.get(pk=pk) except Termo.DoesNotExist: antigo = None if antigo and (antigo.ano != 0 or antigo.processo != 0 or antigo.digito != 0): self.ano = antigo.ano self.processo = antigo.processo self.digito = antigo.digito super(Termo, self).save(*args, **kwargs) # Retorna a soma das naturezas (moeda nacional) de um termo. @property def real(self): # for ng in self.natureza_gasto_set.all(): # if ng.modalidade.moeda_nacional == True and ng.modalidade.sigla != 'REI': # total += ng.valor_concedido soma = Natureza_gasto.objects.filter(termo_id=self.id) \ .filter(modalidade__moeda_nacional=True) \ .filter(~Q(modalidade__sigla='REI')) \ .aggregate(Sum('valor_concedido')) total = soma['valor_concedido__sum'] or Decimal('0.00') return total # Formata o valor do atributo real. def termo_real(self): if self.real > 0: return '<b>R$ %s</b>' % (formata_moeda(self.real, ',')) return '-' termo_real.allow_tags = True termo_real.short_description = _(u'Concessão sem REI') # Retorna a soma das naturezas (dolar) de um termo. @property def dolar(self): # for ng in self.natureza_gasto_set.all(): # if ng.modalidade.moeda_nacional == False: # total += ng.valor_concedido soma = Natureza_gasto.objects.filter(termo_id=self.id) \ .filter(modalidade__moeda_nacional=False) \ .aggregate(Sum('valor_concedido')) total = soma['valor_concedido__sum'] or Decimal('0.00') return total # Formata o valor do atributo tdolar. def termo_dolar(self): if self.dolar > 0: return '$ %s' % (formata_moeda(self.dolar, '.')) return '-' termo_dolar.short_description = _(u'Concessão') @cached_property def termino(self): termino = datetime.date.min for pedido in self.outorga_set.all(): if pedido.termino > termino: termino = pedido.termino return termino # Duracao do termo como um 'timedelta' def duracao(self): if self.termino is not None and self.inicio is not None: return self.termino - self.inicio else: return None # Calcula os meses de duração do processo a partir dos dados do modelo Outorga def duracao_meses(self): dif = self.duracao() if dif is not None: meses = dif.days / 30 if dif.days % 30 >= 28: meses += 1 if meses > 0: if meses > 1: return u"%s meses" % meses return u"%s mês" % meses return u'-' else: return u'-' duracao_meses.short_description = _(u'Vigência') # Calcula total de despesas (R$) realizadas durante a outorga @property def total_realizado_real(self): from financeiro.models import Pagamento total = Pagamento.objects.filter(origem_fapesp__item_outorga__natureza_gasto__modalidade__moeda_nacional=True, origem_fapesp__item_outorga__natureza_gasto__termo=self)\ .aggregate(Sum('valor_fapesp')) return total['valor_fapesp__sum'] or Decimal('0.0') # Retorna o total de despesas (R$) em formato moeda. def formata_realizado_real(self): if not self.total_realizado_real: return '-' valor = formata_moeda(self.total_realizado_real, ',') if self.real < self.total_realizado_real: return '<span style="color: red"><b>R$ %s</b></span>' % valor return '<b>R$ %s</b>' % valor formata_realizado_real.allow_tags = True formata_realizado_real.short_description = _(u'Realizado') # Calcula total de despesas ($) realizadas durante o termo. @property def total_realizado_dolar(self): total = Decimal('0.00') for n in self.natureza_gasto_set.all().select_related('modalidade'): if not n.modalidade.moeda_nacional: total += n.total_realizado return total # Retorna o total de despesas ($) em formato moeda. def formata_realizado_dolar(self): if not self.total_realizado_dolar: return '-' valor = formata_moeda(self.total_realizado_dolar, '.') if self.dolar < self.total_realizado_dolar: return '<span style="color: red">$ %s</span>' % valor return '$ %s' % valor formata_realizado_dolar.allow_tags = True formata_realizado_dolar.short_description = _(u'Realizado') def saldo_real(self): return self.real - self.total_realizado_real def saldo_dolar(self): return self.dolar - self.total_realizado_dolar def formata_saldo_real(self): return '<b>R$ %s</b>' % formata_moeda(self.saldo_real(), ',') formata_saldo_real.allow_tags = True formata_saldo_real.short_description = _(u'Saldo') def formata_saldo_dolar(self): return '$ %s' % formata_moeda(self.saldo_dolar(), '.') formata_saldo_dolar.short_description = _(u'Saldo') # Define atributos. vigencia = property(duracao_meses) num_processo = property(__unicode__) # Define a descrição do modelo (singular e plural), a ordenação dos dados pelo ano. class Meta: verbose_name = _(u'Termo de Outorga') verbose_name_plural = _(u'Termos de Outorga') ordering = ("-ano", "-processo") @classmethod def termo_ativo(cls): hoje = datetime.datetime.now().date() for t in Termo.objects.order_by('-inicio'): if t.inicio <= hoje <= t.termino: return t return None def insere_itens_rt(self): for irt in TemplateRT.objects.all(): (p, b) = Natureza_gasto.objects.get_or_create(termo=self, modalidade=irt.modalidade, defaults={'valor_concedido': 0.0}) item = Item() item.natureza_gasto = p item.descricao = irt.descricao item.justificativa = ' ' item.valor = 0.0 item.quantidade = 1 item.rt = True item.save()
class Carga_inventario(models.Model): # [0] local = models.CharField(_(u'local'), null=True, blank=True, max_length=100) # [1] Patrimonio modelo model_number = models.CharField(_(u'model_number'), null=True, blank=True, max_length=100) # [2] Patrimonio part_number part_number = models.CharField(_(u'part_number'), null=True, blank=True, max_length=50) # [3] revision = models.CharField(_(u'revision'), null=True, blank=True, max_length=50) # [4] version = models.CharField(_(u'version'), null=True, blank=True, max_length=50) # [5] Patrimonio ean ean = models.CharField(_(u'EAN'), max_length=45, null=True, blank=True) # [6] Patrimonio ns serial_number = models.CharField(_(u'Número de série'), null=True, blank=True, max_length=50) # [7] service_tag = models.CharField(_(u'Service tag'), null=True, blank=True, max_length=50) # [8] Patrimonio marca fabricante = models.CharField(_(u'Marca/Editora'), null=True, blank=True, max_length=100) # [9] Protocolo num_documento nota_fiscal = models.CharField(_(u'Número'), null=True, max_length=50, blank=True) # [10] data = NARADateField(_(u'Data'), null=True, blank=True) # [11] Patrimonio ncm ncm_sh = models.CharField(_(u'NCM/SH'), null=True, blank=True, max_length=30) # [12] o_cst = models.CharField(_(u'o_cst'), null=True, blank=True, max_length=30) # [13] cfop = models.CharField(_(u'cfop'), null=True, blank=True, max_length=30) # [14] unidade = models.CharField(_(u'Unidade'), null=True, blank=True, max_length=10) # [15] quantidade = models.DecimalField(_(u'quantidade'), max_digits=6, decimal_places=0, null=True, blank=True) # [16] volume = models.CharField(_(u'Volume'), null=True, blank=True, max_length=50) # [17] processo_fapesp = models.CharField(_(u'Processo Fapesp'), null=True, max_length=50) # [18] garantia = models.CharField(_(u'Garantia'), null=True, blank=True, max_length=50) # [19] termino_garantia = models.CharField(_(u'Termino de Garantia'), null=True, blank=True, max_length=50) # [20] Patrimonio descricao descricao = models.TextField(_(u'Descrição NF'), null=True, blank=True, max_length=350) # [21] propriedade = models.TextField(_(u'propriedade'), null=True, blank=True) # [22] patrimonio = models.TextField(_(u'patrimonio'), null=True, blank=True) # [23] estado = models.CharField(_(u'estado'), null=True, blank=True, max_length=20) # [24] enviado = models.CharField(_(u'enviado'), null=True, blank=True, max_length=30) # [25] instalado = models.CharField(_(u'instalado'), null=True, blank=True, max_length=40) # [26] site = models.CharField(_(u'site - localizacao'), null=True, blank=True, max_length=50) # [27] Patrimonio localizacao = models.CharField(_(u'localizacao'), null=True, blank=True, max_length=100) # [28] cage = models.CharField(_(u'cage'), null=True, blank=True, max_length=30) # [29] rack = models.CharField(_(u'rack'), null=True, blank=True, max_length=10) # [30] furo = models.CharField(_(u'furo'), null=True, blank=True, max_length=10) # [31] posicao = models.CharField(_(u'posicao'), null=True, blank=True, max_length=10) # [32] inventariado = NARADateField(_(u'inventariado'), null=True, blank=True) # [33] observacao = models.CharField(_(u'observacao'), null=True, blank=True, max_length=350) # [34] atualizado = NARADateField(_(u'atualizado'), null=True, blank=True) # [35] # id do patrimonio # [36] # id do patrimonio pai # [37] url_equipamento = models.CharField(_(u'url_equipamento'), null=True, blank=True, max_length=200) # website_part_number = models.CharField(u'website_part_number', null=True, blank=True, max_length=200) # # [36] # website_fabricante = models.CharField(u'website_fabricante', null=True, blank=True, max_length=200) planilha_aba = models.CharField(_(u'planilha_aba'), null=True, blank=True, max_length=50) planilha_linha = models.DecimalField(_(u'planilha_linha'), max_digits=5, decimal_places=0, null=True, blank=True) # [35] patrimonio_model = models.ForeignKey('patrimonio.Patrimonio', null=True, blank=True) equipamento_model = models.ForeignKey('patrimonio.Equipamento', null=True, blank=True) # chk_posicao = models.BooleanField(_(u'Posicao ok?'), null=True, blank=True) # chk_sn = models.BooleanField(_(u'Serial ok?'), null=True, blank=True) # chk_pn = models.BooleanField(_(u'Part Number ok?'), null=True, blank=True) # chk_model = models.BooleanField(_(u'Modelo ok?'), null=True, blank=True) tipo_carga = models.DecimalField(_(u'tipo_carga'), max_digits=2, decimal_places=0, null=True, blank=True) def __unicode__(self): if self.serial_number: return self.serial_number else: return u''