Controle de faturas e bloqueio de usuários para o sistema de lojas web
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

317 lines
12 KiB

from datetime import datetime
from django.contrib.auth.models import AbstractUser
from django.core.validators import MinValueValidator
from django.db.models import CASCADE, PROTECT, Q, BooleanField, CharField, DateField, DateTimeField, DecimalField, FileField, ForeignKey, IntegerField, ManyToManyField, Model, PositiveIntegerField, TextField
from django.utils.translation import ugettext_lazy as _
import os
from django.core.exceptions import PermissionDenied
def get_upload_path(instance, filename):
return os.path.join(str(type(instance).__name__), filename)
class User(AbstractUser):
def delete(self):
if self.pk != 1:
self.delete()
else:
raise PermissionDenied
class Estado(Model):
nome = CharField(_('nome'), max_length=60)
sigla = CharField(_('sigla'), max_length=2)
class Meta:
verbose_name = _('Estado')
verbose_name_plural = _('Estados')
ordering = ['nome']
def __str__(self):
return self.nome
class Cidade(Model):
nome = CharField(_('nome'), max_length=60)
estado = ForeignKey(Estado, verbose_name=_('estado'),
related_name='cidades', on_delete=PROTECT)
ibge = CharField(_(u'código IBGE'), max_length=7)
class Meta:
verbose_name = _('Cidade')
verbose_name_plural = _('Cidades')
ordering = ['nome']
@property
def label(self):
return u'{city}-{state}'.format(
city=self.nome,
state=self.estado.sigla
)
def __str__(self):
return self.label
class Pessoa(Model):
SITUACAO = (
("A", "Ativo"),
("I", "Inativo"),
)
nome = CharField(_(u'nome'), max_length=255)
cpf = CharField('CPF', max_length=14, unique=True, blank=True, null=True)
data_nascimento = DateField(_('data de nascimento'), blank=True, null=True)
ativo = BooleanField(_("ativo"), default=True)
situacao = CharField(_(u'situação'), max_length=1,
choices=SITUACAO, default='A')
criado = DateTimeField(auto_now_add=True, editable=False,
verbose_name=_('cadastrado em'), null=True)
modificado = DateTimeField(
auto_now=True, editable=False, verbose_name=_('alterado em'), null=True)
class Meta:
verbose_name = _('Pessoa')
verbose_name_plural = _('Pessoas')
ordering = ['nome']
def __str__(self):
return self.nome
@property
def label(self):
return u'{nome} - {cpf}'.format(
nome=self.nome,
cpf=self.cpf
)
class Endereco(Model):
pessoa = ForeignKey(Pessoa, related_name='enderecos', on_delete=CASCADE)
endereco = CharField(_(u'endereço'), max_length=60, blank=True, null=True)
numero = IntegerField(_(u'número'), blank=True, null=True)
complemento = CharField(
_('complemento'), max_length=20, blank=True, null=True)
bairro = CharField(_('bairro'), max_length=60, blank=True, null=True)
cep = CharField(_('CEP'), max_length=9, blank=True, null=True)
cidade = ForeignKey(Cidade, verbose_name=_('cidade'), on_delete=PROTECT,
related_name='pessoa_%(class)ss', blank=True, null=True)
criado = DateTimeField(auto_now_add=True, editable=False,
verbose_name=_('cadastrado em'), null=True)
modificado = DateTimeField(
auto_now=True, editable=False, verbose_name=_('alterado em'), null=True)
class Meta:
verbose_name = _('Endereço')
verbose_name_plural = _('Endereços')
ordering = ['endereco']
class Telefone(Model):
TYPES = (
('F', _('Fixo')),
('M', _('Celular')),
('C', _('Comercial')),
)
ddd = CharField(_('DDD'), max_length=2)
numero = CharField(_('número'), max_length=10)
tipo = CharField(_('tipo'), max_length=1, choices=TYPES, blank=True)
principal = BooleanField(_('principal'), default=False)
pessoa = ForeignKey(Pessoa, related_name='telefones', on_delete=CASCADE)
telegram = BooleanField(default=False)
whatsapp = BooleanField(default=False)
criado = DateTimeField(auto_now_add=True, editable=False,
verbose_name=_('cadastrado em'), null=True)
modificado = DateTimeField(
auto_now=True, editable=False, verbose_name=_('alterado em'), null=True)
class Meta:
verbose_name = _('Telefone')
verbose_name_plural = _('Telefones')
ordering = ['tipo']
def __str__(self):
return f'({self.ddd}) {self.numero}'
class Email(Model):
email = CharField(_('email'), max_length=255)
pessoa = ForeignKey(Pessoa, related_name='emails', on_delete=CASCADE)
criado = DateTimeField(auto_now_add=True, editable=False,
verbose_name=_('cadastrado em'), null=True)
modificado = DateTimeField(
auto_now=True, editable=False, verbose_name=_('alterado em'), null=True)
class Meta:
verbose_name = _('Email')
verbose_name_plural = _('Emails')
ordering = ['email']
class Notas(Model):
nota = TextField(_('nota'))
pessoa = ForeignKey(Pessoa, related_name='notas', on_delete=CASCADE)
criado = DateTimeField(auto_now_add=True, editable=False,
verbose_name=_('cadastrado em'), null=True)
modificado = DateTimeField(
auto_now=True, editable=False, verbose_name=_('alterado em'), null=True)
class Meta:
verbose_name = _('Nota')
verbose_name_plural = _('Notas')
ordering = ['modificado']
class Cliente(Model):
SITUACAO = (
('E', 'Em dia'),
('A', 'Atrasado'),
('I', 'Inadimplente'),
)
DESCONTOS = (
('P', 'Porcentagem'),
('V', 'Valor Fixo'),
)
PERIODICIDADE = (
("1", u'Diário'),
("7", 'Semanal'),
("30", 'Mensal'),
("60", 'Bimestral'),
("90", 'Trimestral'),
("120", 'Semestral'),
("360", 'Anual'),
)
razao_social = CharField(_(u'razão social'), max_length=255)
nome_fantasia = CharField(_(u'nome fantasia'), max_length=255)
cnpj = CharField('CNPJ', max_length=18, unique=True, blank=True, null=True)
ie = CharField('inscrição estadual', max_length=20,
unique=True, blank=True, null=True)
im = CharField('inscrição municipal', max_length=20,
unique=True, blank=True, null=True)
ativo = BooleanField(_("ativo"), default=True)
situacao = CharField(_(u'situação'), max_length=1,
choices=SITUACAO, default='E')
endereco = CharField(_(u'endereço matriz'),
max_length=60, blank=True, null=True)
numero = IntegerField(_(u'nº matriz'), blank=True, null=True)
complemento = CharField(
_('complemento matriz'), max_length=20, blank=True, null=True)
bairro = CharField(_('bairro matriz'), max_length=60,
blank=True, null=True)
cep = CharField(_('CEP matriz'), max_length=9, blank=True, null=True)
cidade = ForeignKey(Cidade, verbose_name=_('cidade matriz'), on_delete=PROTECT,
related_name='cliente_%(class)ss', blank=True, null=True)
responsaveis = ManyToManyField(Pessoa, verbose_name=_(
'responsaveis'), related_name='eh_responsavel')
socios = ManyToManyField(Pessoa, verbose_name=_(
'socios'), related_name='eh_socio')
retaguarda = CharField(_(u'endereço da retaguarda'), max_length=255)
nome_banco_dados = CharField(_(u'nome do banco de dados'), max_length=255)
contrato = FileField(_('contrato'), upload_to=get_upload_path)
data_adesao = DateField(verbose_name=_('data de adesão'))
data_de_vencimento = DateField(verbose_name=_('data do vencimento'))
valor_base_contrato = DecimalField(
_('valor base do contrato'), max_digits=25, decimal_places=2)
indice_reajuste = DecimalField(
_(u'índice de reajuste'), max_digits=8, decimal_places=4)
qtd_pdvs = IntegerField(_(u'nº de pdvs'),
validators=[MinValueValidator(1)])
tipo_desconto = CharField(_(u'tipo de desconto'), max_length=1,
choices=DESCONTOS, default='P')
carencia = BooleanField(_(u'carência'), default=False)
periodo_carencia = PositiveIntegerField(
_(u'período de carência (em meses)'), default=0,
validators=[MinValueValidator(0)], blank=True, null=True)
valor_carencia = DecimalField(
_('valor da carência'), default=0,
max_digits=25, decimal_places=2, blank=True, null=True)
porcentagem_carencia = DecimalField(
_('porcentagem da carência'), default=0,
max_digits=8, decimal_places=4, blank=True, null=True)
periodicidade_boletos = CharField(
_(u'periodicidade dos boletos'), default="30",
choices=PERIODICIDADE, max_length=3)
usuarios_bloqueados = BooleanField(
_(u"usuários bloqueados?"), default=False)
criado = DateTimeField(auto_now_add=True, editable=False,
verbose_name=_('cadastrado em'), null=True)
modificado = DateTimeField(
auto_now=True, editable=False, verbose_name=_('alterado em'), null=True)
class Meta:
verbose_name = _('Cliente')
verbose_name_plural = _('Cliente')
ordering = ['razao_social']
def __str__(self):
return f'{self.razao_social[0:20]} - {self.cnpj}'
@property
def atrasado(self):
return self.boletos.filter(Q(situacao='A'), Q(data_vencimento__lt=datetime.today().date())).count() > 0
class TelefoneCliente(Model):
TYPES = (
('F', _('Fixo')),
('M', _('Celular')),
('C', _('Comercial')),
)
ddd = CharField(_('DDD'), max_length=2)
numero = CharField(_('número'), max_length=10)
tipo = CharField(_('tipo'), max_length=1, choices=TYPES, blank=True)
principal = BooleanField(_('principal'), default=False)
cliente = ForeignKey(Cliente, related_name='telefones', on_delete=CASCADE)
telegram = BooleanField(default=False)
whatsapp = BooleanField(default=False)
criado = DateTimeField(auto_now_add=True, editable=False,
verbose_name=_('cadastrado em'), null=True)
modificado = DateTimeField(
auto_now=True, editable=False, verbose_name=_('alterado em'), null=True)
class Meta:
verbose_name = _('Telefone')
verbose_name_plural = _('Telefones')
ordering = ['tipo']
def __str__(self):
return f'({self.ddd}) {self.numero}'
class Boleto(Model):
SITUACAO = (
('A', 'Aberto'),
('B', 'Baixado'),
)
cliente = ForeignKey(Cliente, related_name='boletos', on_delete=CASCADE)
nosso_numero = CharField(
_(u'nosso número'), max_length=255, blank=True, null=True)
numero_boleto = CharField(_(u'número do boleto'), max_length=255)
data_vencimento = DateField(_('data de vencimento'))
data_geracao = DateField(_(u'data de geração'))
situacao = CharField(_(u'situação'), max_length=1,
choices=SITUACAO, default='A', blank=True)
valor = DecimalField(
_('valor do boleto'), max_digits=25, decimal_places=2)
criado = DateTimeField(auto_now_add=True, editable=False,
verbose_name=_('cadastrado em'), null=True)
modificado = DateTimeField(
auto_now=True, editable=False, verbose_name=_('alterado em'), null=True)
class Meta:
verbose_name = _('Boleto')
verbose_name_plural = _('Boletos')
ordering = ['numero_boleto']
@property
def atrasado(self):
return self.data_vencimento < datetime.today().date()
def save(self, *args, **kwargs):
super(Boleto, self).save(*args, **kwargs)
if not self.cliente.atrasado:
self.cliente.situacao = 'E'
self.cliente.save()