class Pet(models.Model): """ This model represents a pet registered in a unit. """ pet_type = models.CharField( max_length=30, verbose_name=_('tipo de mascota'), help_text=_('perro, gato, etc.'), ) breed = models.CharField( max_length=30, verbose_name=_('raza'), ) name = models.CharField( max_length=30, verbose_name=_('nombre'), ) color = models.CharField( max_length=50, verbose_name=_('color'), ) picture = models.ImageField( max_length=255, blank=True, help_text='150x150', validators=[FileSizeValidator(4000)], ) unit = models.ForeignKey( 'buildings.Unit', on_delete=models.CASCADE, verbose_name=_('unidad'), ) def get_absolute_url(self): return reverse('buildings:pet_detail', args=[self.unit.building.id, self.unit.id, self.id]) def __str__(self): return '{0} | {1} - {2}'.format( self.unit, self.pet_type, self.name, ) class Meta: verbose_name = _('mascota') verbose_name_plural = _('mascotas') ordering = ('name', )
class EconomicActivitiesForm(forms.Form): """ Form to upload excel file with economic activities. """ excel_file = forms.FileField( label=_('archivo de excel'), help_text=_('Debe seleccionar un archivo con extensión .xlsx o xls.'), validators=[FileSizeValidator(4000)], ) def clean_excel_file(self): # Validation to the coefficient field. It must # be a value between 0 and 100. value = self.cleaned_data['excel_file'] extension = value.name.split('.')[1] if extension not in ('xls', 'xlsx'): raise forms.ValidationError( _('Solo se aceptan archivos con extensión xlsx, .xls.')) return value
class FormBulkForm(forms.Form): """ Form to upload excel file with cities list by country. """ country_code = forms.CharField(label=_('country code'), ) excel_file = forms.FileField( help_text=_('.xlsx o xls.'), validators=[FileSizeValidator(4000)], ) def clean_excel_file(self): # Validation to the coefficient field. It must # be a value between 0 and 100. value = self.cleaned_data['excel_file'] extension = value.name.split('.')[1] if extension not in ('xls', 'xlsx'): raise forms.ValidationError( _('Only files with .xlsx, .xls are accepeted.')) return value
class Venture(models.Model): status = models.PositiveSmallIntegerField( choices=VENTURE_STATUS_CHOICES, default=VENTURE_STATUS_ACTIVE, verbose_name=_('status'), ) status_tracker = FieldTracker(fields=['status']) name = models.CharField( max_length=50, verbose_name=_('name'), ) logo = models.ImageField( max_length=255, blank=True, help_text='150x150', validators=[FileSizeValidator(4000)], ) description_es = models.TextField( blank=True, null=True, verbose_name=_('spanish description'), ) description_en = models.TextField( blank=True, null=True, verbose_name=_('english description'), ) industry_categories = models.ManyToManyField('account.IndustryCategory', ) country = models.ForeignKey( 'place.Country', verbose_name=_('country'), ) state = models.ForeignKey( 'place.State', verbose_name=_('state'), ) city = models.ForeignKey( 'place.City', verbose_name=_('city'), ) address = models.CharField( max_length=50, blank=True, verbose_name=_('address'), ) email = models.EmailField( null=True, blank=True, verbose_name=_('contact email'), ) phone_number = models.CharField( null=True, blank=True, max_length=50, verbose_name=_('contact phone'), ) url = models.URLField( blank=True, verbose_name=_('webpage'), ) facebook_url = models.URLField( blank=True, verbose_name=_('Facebook url'), ) twitter_url = models.URLField( blank=True, verbose_name=_('Twitter url'), ) instagram_url = models.URLField( blank=True, verbose_name=_('Instagram url'), ) linkedin_url = models.URLField( blank=True, verbose_name=_('Linkedin url'), ) googleplus_url = models.URLField( blank=True, verbose_name=_('Google plus url'), ) owner = models.ForeignKey( 'account.ProfessionalProfile', verbose_name=_('created by'), ) shared_on_twitter = models.BooleanField( default=False, verbose_name=_('shared on twitter'), ) created_at = models.DateTimeField(auto_now_add=True, ) slug = models.SlugField() has_new_messages = models.BooleanField( default=False, verbose_name=_('has new messages'), ) def clean(self): if not self.status_tracker.has_changed('status') or not self.id: return msg = 'Invalid previous status for {0}' previous = self.status_tracker.previous('status') if (self.status == VENTURE_STATUS_INACTIVE and previous != VENTURE_STATUS_HIDDEN): raise ValidationError( {'status': msg.format('VENTURE_STATUS_INACTIVE')}) elif (self.status == VENTURE_STATUS_HIDDEN and previous != VENTURE_STATUS_INACTIVE): raise ValidationError( {'status': msg.format('VENTURE_STATUS_HIDDEN')}) @property def is_active(self): return self.status == VENTURE_STATUS_ACTIVE @property def is_inactive(self): return self.status == VENTURE_STATUS_INACTIVE @property def is_hidden(self): return self.status == VENTURE_STATUS_HIDDEN @property def get_logo(self): logo = '/static/img/venture_default_logo.svg' if self.logo: logo = self.logo.url return logo @property def get_score(self): user_scores = CompanyScore.objects.filter(company=self) total_score = 0 if user_scores: for user_score in user_scores.all(): total_score += user_score.score return total_score / user_scores.count() return total_score @property def get_votes_quantity(self): return CompanyScore.objects.filter(company=self).count() @property def get_active_administrator_ids(self): active_memberships = self.administratormembership_set.filter( status=ACTIVE_MEMBERSHIP, ) active_administrators = [] for membership in active_memberships: active_administrators.append(membership.admin.id) return active_administrators def get_absolute_url(self): return reverse( 'venture_detail', args=[self.slug], ) def __str__(self): return '{0}'.format(self.name)
class User(AbstractBaseUser, PermissionsMixin): """ User model. It inherits the basic structure of the Django user model. The username field is overwiritten with the email value. This model manage basic user iformation and legal items status. """ USERNAME_FIELD = 'email' avatar = models.ImageField( verbose_name=_('profile image'), max_length=255, blank=True, validators=[FileSizeValidator(4000)], ) first_name = models.CharField( verbose_name=_('name'), max_length=128, blank=False, validators=[ MinLengthValidator(3), ], error_messages={ 'min_length': 'El campo "Nombre" debe tener al menos %(limit_value)d ' 'caracteres (actualmente tiene %(show_value)d).' }) last_name = models.CharField( verbose_name=_('last name'), max_length=128, blank=False, validators=[ MinLengthValidator(3), ], error_messages={ 'min_length': 'El campo "Apellidos" debe tener al menos %(limit_value)d ' 'caracteres (actualmente tiene %(show_value)d).' }) email = models.EmailField( verbose_name=_('email'), unique=True, blank=False, ) is_staff = models.BooleanField( 'staff status', default=False, ) is_active = models.BooleanField( 'Activo', default=True, ) country = models.ForeignKey( 'place.Country', null=True, verbose_name=_('country'), ) state = models.ForeignKey( 'place.State', null=True, verbose_name=_('state'), ) city = models.ForeignKey( 'place.City', null=True, verbose_name=_('city'), ) address = models.CharField( verbose_name=_('address'), max_length=80, null=True, blank=True, ) date_joined = models.DateTimeField( verbose_name=_('created at'), default=timezone.now, ) accepted_terms = models.BooleanField( verbose_name=_('accepted user agreement'), default=True, ) accepted_terms_date = models.DateField( verbose_name=_('accepted user agreement date'), null=True, blank=True, ) accepted_privacy_policy = models.BooleanField( verbose_name=_('accepted privacy policy'), default=True, ) accepted_privacy_policy_date = models.DateField( verbose_name=_('accepted privacy policy date'), null=True, blank=True, ) objects = UserManager() def get_short_name(self): return self.first_name if self.first_name else self.email.split('@')[0] @property def get_avatar(self): avatar = '/static/img/profile_default_avatar.svg' if self.avatar: avatar = self.avatar.url return avatar @property def get_country(self): country = None if self.country: country = self.country.country return country @property def get_full_name(self): full_name = '{0} {1}'.format(self.first_name, self.last_name) return full_name.strip() def __str__(self): return self.get_full_name class Meta: verbose_name = _('user') verbose_name_plural = _('users') ordering = ('email', )
class RequestComplaint(models.Model): type_complaint = models.PositiveSmallIntegerField( choices=data.TYPE_COMPLAINT_CHOICES, verbose_name='¿la denuncia se realizará de manera anónima?', default=data.ANONYMOUS_CHOICE, ) full_name = models.CharField( max_length=80, verbose_name='nombres y apellidos', blank=True ) email = models.EmailField( verbose_name='correo electrónico', help_text='Máximo 100 caracteres', max_length=60, blank=True ) phone_number = models.CharField( max_length=10, verbose_name='Número de contacto', blank=True, validators=[ RegexValidator(r'^[0-9]*$', message='Ingresa solo números'), MinLengthValidator( settings.PHONE_NUMBER_LENGTH, message='Asegurate que tenga al menos {} caracteres'.format( settings.PHONE_NUMBER_LENGTH ) ), ], ) company_relation = models.CharField( max_length=100, verbose_name='vínculo con la compañía' ) purpose = models.CharField( max_length=100, verbose_name='objeto de la denuncia' ) date = models.DateField( verbose_name='fecha de los hechos' ) place = models.CharField( max_length=100, verbose_name='lugar de los hechos' ) acts = models.TextField( verbose_name='hechos de la denuncia', help_text='Identificar si los hechos están por suceder' ) people_complaint = ArrayField( models.CharField(max_length=80), verbose_name='persona(s) denunciada(s)' ) document = models.FileField( upload_to=get_upload_path, verbose_name='documento adjunto', validators=[FileSizeValidator(2000)], help_text='máximo 2MB', blank=True, null=True, ) created_at = models.DateTimeField( auto_now_add=True, verbose_name='fecha de creación', ) def is_anonymous(self): return self.type_complaint == data.ANONYMOUS_CHOICE def get_people_complaint(self): return ', '.join(self.people_complaint) def __str__(self): return self.purpose class Meta: ordering = ['-id'] verbose_name = 'queja' verbose_name_plural = 'quejas y reclamos'
class Building(models.Model): """ This model represents a building, condo or coproperty. a condo is a type of real estate divided into several units that are each separately owned, surrounded by common areas jointly owned. """ name = models.CharField( max_length=100, verbose_name=_('nombre'), ) document_type = models.PositiveSmallIntegerField( choices=BUILDING_DOCUMENT_TYPE_CHOICES, verbose_name=_('tipo de documento'), ) document_number = models.CharField( max_length=32, unique=True, verbose_name=_('documento/Nit'), ) logo = models.ImageField( max_length=255, blank=True, help_text='150x150', validators=[FileSizeValidator(4000)], ) city = models.ForeignKey( 'place.City', verbose_name=_('ciudad'), on_delete=models.DO_NOTHING, ) address = models.CharField( max_length=50, blank=True, verbose_name=_('dirección'), ) email = models.EmailField( null=True, blank=True, verbose_name=_('correo electrónico'), ) mobile_phone = models.CharField( max_length=32, verbose_name=_('número celular'), default='', blank=True, help_text=_('Si desea ingresar más de un número celular, ' 'estos deben ir separados por coma (,).'), validators=[ RegexValidator( '^[0-9 ,]*$', message=_('El dato no es válido, sólo debe ingresar números. ' 'Si desea ingresar más de un número celular, estos ' 'deben estar separados por coma (,).')), MinLengthValidator(10), ], error_messages={ 'min_length': 'Ingrese al menos %(limit_value)d caracteres,' ' (actualmente tiene %(show_value)d).' }) phone_number = models.CharField( max_length=32, verbose_name=_('número telefónico'), help_text=_('Si desea ingresar más de un número telefónico,' 'estos deben ir separados por coma (,).'), blank=True, validators=[ RegexValidator( '^[0-9 ,]*$', message=_('El dato no es válido, sólo debe ingresar números. ' 'Si desea ingresar más de un número celular, estos ' 'deben estar separados por coma (,).')), MinLengthValidator(6), ], error_messages={ 'min_length': 'El campo "Número telefónico" debe tener al menos ' '%(limit_value)d dígitos (actualmente tiene %(show_value)d).' }) initial_period = models.DateField( blank=True, null=True, verbose_name=_('periodo inicial'), ) activity_log = models.TextField( blank=True, verbose_name=_('registro de actividad'), ) created_by = models.ForeignKey( 'accounts.User', on_delete=models.CASCADE, verbose_name=_('creado por'), ) created_at = models.DateTimeField(auto_now_add=True, ) def get_absolute_url(self): return reverse('buildings:building_detail', args=[self.id]) def __str__(self): return '{0} - {1}'.format( self.name, self.document_number, ) class Meta: verbose_name = _('copropiedad') verbose_name_plural = _('copropiedades') ordering = ('created_at', )