class GalleryPhoto(models.Model): gallery = models.ForeignKey(Gallery, null=True, related_name='photos', on_delete=models.CASCADE) order = models.IntegerField(verbose_name=_('Orden'), default=0) title = models.CharField(null=True, blank=True, verbose_name=_('Título'), max_length=250) image = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('photos/'), processors=[ResizeToFit(512, 512, upscale=False)], format='JPEG') image_thumbnail = ImageSpecField( source='image', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) uploaded = models.DateTimeField(auto_now_add=True) class Meta: verbose_name = _('Foto') verbose_name_plural = _('Fotos') ordering = ['order']
class Category(models.Model): name = models.CharField(null=True, blank=True, verbose_name=_('Nombre'), max_length=250) description = models.TextField(null=True, blank=True, verbose_name=_('Descripción')) color = models.CharField( null=True, blank=True, verbose_name=_('Color de etiqueta (código hexadecimal)'), max_length=30) photo = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('momenti/'), verbose_name=_('Imagen principal'), processors=[ResizeToFit(1024, 1024, upscale=False)], format='JPEG') photo_thumbnail = ImageSpecField( source='photo', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) class Meta: verbose_name = _('Categoría') verbose_name_plural = _('Categorías') ordering = ['name'] def __unicode__(self): return self.name if self.name else ''
class IntercoopEntity(models.Model): name = models.CharField(null=True, blank=True, max_length=250, verbose_name=_('Nombre')) expiration = models.IntegerField(default=INVITE_DURATION_YEARS, verbose_name=_('Años de validez')) include_code = models.BooleanField(default=True, verbose_name=_('Incluir identificador de socia externa para validación')) code_label = models.CharField(null=True, blank=True, max_length=200, verbose_name=_('Etiqueta del identificador')) logo = ProcessedImageField(null=True, blank=True, upload_to=RandomFileName('intercoop/'), verbose_name='Logo en alta resolución', processors=[ResizeToFit(1024, 1024, upscale=False)], format='JPEG', options={'quality': 80}) description = models.TextField(null=True, blank=True, verbose_name='Descripción') slug = models.CharField(null=True, blank=True, max_length=200,verbose_name='Enlace permanente', help_text='Identificador para el enlace de alta') class Meta: verbose_name = _('Entidad de intercooperación') verbose_name_plural = _('Entidades de intercooperación') ordering = ('name',) permissions = ( ("mespermission_can_manage_entity", _("Puede gestionar entidades de intercooperación")), ("mespermission_can_add_entity", _("Puede añadir entidades de intercooperación")), ) def __str__(self): return self.name def __unicode__(self): return self.name
class SocialBalanceBadge(models.Model): year = models.SmallIntegerField(default=2019, blank=False, null=False, verbose_name=_('Año')) layout_json = models.TextField( null=True, blank=True, verbose_name=_('JSON de configuración de layout')) include_labels = models.BooleanField( default=False, verbose_name=_('Incluir etiqueta de Logro/Reto en el texto')) base_img = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('balance/badges/'), verbose_name='Plantilla para el sello de balance social', processors=[ResizeToFit(1600, 1200, upscale=False)], format='PNG') exempt_img = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('balance/badges/'), verbose_name='Imagen de exenta', processors=[ResizeToFit(900, 700, upscale=False)], format='PNG') undone_img = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('balance/badges/'), verbose_name='Imagen de no realizada', processors=[ResizeToFit(900, 700, upscale=False)], format='PNG') class Meta: verbose_name = _('Sello de balance social') verbose_name_plural = _('Sellos de balance social') permissions = ( ("mespermission_can_view_social_badges", _("Puede ver las plantillas de sellos de balance social")), ("mespermission_can_create_social_badges", _("Puede crear plantillas de sellos de balance social")), )
class Person(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) user = models.OneToOneField(User, null=False, blank=False, on_delete=CASCADE) nif = models.CharField(null=True, blank=True, verbose_name='NIF/CIF', max_length=50) email = models.CharField(null=False, blank=False, verbose_name='Email', max_length=250) name = models.CharField(null=True, blank=True, verbose_name='Nombre', max_length=250) surname = models.CharField(null=True, blank=True, verbose_name='Apellidos', max_length=250) address = models.TextField(null=True, blank=True, verbose_name='Dirección') profile_image = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('profiles/'), verbose_name='Imagen de perfil', processors=[ResizeToFit(512, 512, upscale=False)], format='JPEG') profile_thumbnail = ImageSpecField( source='profile_image', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) registered = models.DateTimeField(auto_now_add=True) fav_entities = models.ManyToManyField(Entity, blank=True, verbose_name="Favoritos") class Meta: verbose_name = 'Persona' verbose_name_plural = 'Personas' ordering = ['registered'] @property def full_name(self): return '{} {}'.format(self.name if self.name else '', self.surname if self.surname else '') def __unicode__(self): full_name = self.full_name.strip() return self.user.username if not full_name else full_name
class Hotel(models.Model): owner = models.ForeignKey(User, verbose_name=_('Responsable'), blank=True, null=True, related_name='owned_hotels') city = models.ForeignKey(City, verbose_name=_('Ciudad'), related_name='hotels') name = models.CharField(null=True, blank=True, verbose_name=_('Nombre'), max_length=250) description = models.TextField(null=True, blank=True, verbose_name=_('Descripción')) address = models.TextField(null=True, blank=True, verbose_name=_('Dirección')) latitude = models.FloatField(null=False, verbose_name=_('Latitud'), default=0) longitude = models.FloatField(null=False, verbose_name=_('Longitud'), default=0) photo = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('cities/'), verbose_name=_('Imagen principal'), processors=[ResizeToFit(1024, 1024, upscale=False)], format='JPEG') photo_thumbnail = ImageSpecField( source='photo', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) gallery = models.OneToOneField(Gallery, blank=True, null=True, on_delete=models.SET_NULL) class Meta: verbose_name = _('Hotel') verbose_name_plural = _('Hoteles') ordering = ['name'] @property def slug(self): return slugify(str(self)) def __unicode__(self): return self.city.name + ' | ' + self.name
class HotelRoute(models.Model): hotel = models.ForeignKey(Hotel, verbose_name=_('Hotel'), related_name='routes') category = models.ForeignKey(Category, verbose_name=_('Categoría'), related_name='hotel_routes') points = models.ManyToManyField(RoutePoint, verbose_name=_('Puntos de la ruta'), through='HotelRoutePoint') name = models.CharField(null=True, blank=True, verbose_name=_('Nombre'), max_length=250) description = models.TextField(null=True, blank=True, verbose_name=_('Descripción')) visible = models.BooleanField(default=True, verbose_name=_('Visible')) duration = models.IntegerField(default=0, verbose_name=_('Duración de la ruta')) distance = models.IntegerField(default=0, verbose_name=_('Distancia de la ruta')) photo = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('momenti/'), verbose_name=_('Imagen principal'), processors=[ResizeToFit(1024, 1024, upscale=False)], format='JPEG') photo_thumbnail = ImageSpecField( source='photo', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) class Meta: verbose_name = _('Momento') verbose_name_plural = _('Momentos') ordering = ['name'] def __unicode__(self): return self.name if self.name else ''
class News(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) published_by = models.ForeignKey(User, null=True) title = models.CharField(null=True, blank=True, verbose_name='Título', max_length=250) short_description = models.TextField(null=True, blank=True, verbose_name='Descripción') description = models.TextField(null=True, blank=True, verbose_name='Descripción') banner_image = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('news/'), verbose_name='Imagen principal', processors=[ResizeToFit(756, 512, upscale=False)], format='JPEG') banner_thumbnail = ImageSpecField( source='banner_image', processors=[ResizeToFill(400, 200, upscale=False)], format='JPEG', options={'quality': 70}) published_date = models.DateTimeField(auto_now_add=True) more_info_text = models.CharField(null=True, blank=True, verbose_name='Texto del botón de info', max_length=250) more_info_url = models.TextField(null=True, blank=True, verbose_name='URL con más información') class Meta: verbose_name = 'Noticia' verbose_name_plural = 'Noticias' ordering = ['-published_date'] def __unicode__(self): return self.title
class RoutePoint(models.Model): city = models.ForeignKey(City, verbose_name=_('Ciudad'), related_name='points') category = models.ForeignKey(Category, verbose_name=_('Categoría'), related_name='points') name = models.CharField(null=True, blank=True, verbose_name=_('Nombre'), max_length=250) description = models.TextField(null=True, blank=True, verbose_name=_('Descripción')) latitude = models.FloatField(null=False, verbose_name=_('Latitud'), default=0) longitude = models.FloatField(null=False, verbose_name=_('Longitud'), default=0) photo = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('momenti/'), verbose_name=_('Imagen principal'), processors=[ResizeToFit(1024, 1024, upscale=False)], format='JPEG') photo_thumbnail = ImageSpecField( source='photo', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) class Meta: verbose_name = 'Micromomento' verbose_name_plural = 'Micromomentos' ordering = ['name'] def __unicode__(self): return str(self.city) + ' | ' + self.name if self.name else ''
class City(models.Model): name = models.CharField(null=True, blank=True, verbose_name=_('Nombre'), max_length=250) description = models.TextField(null=True, blank=True, verbose_name=_('Descripción')) latitude = models.FloatField(null=False, verbose_name=_('Latitud'), default=0) longitude = models.FloatField(null=False, verbose_name=_('Longitud'), default=0) photo = ProcessedImageField(null=True, blank=True, upload_to=RandomFileName('cities/'), verbose_name=_('Imagen principal'), processors=[ResizeToFit(1024, 1024, upscale=False)], format='JPEG') photo_thumbnail = ImageSpecField(source='photo', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) gallery = models.OneToOneField(Gallery, blank=True, null=True, on_delete=models.SET_NULL) class Meta: verbose_name = _('Ciudad') verbose_name_plural = _('Ciudades') ordering = ['name'] def __unicode__(self): return self.name
class Entity(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) user = models.OneToOneField(User, null=False, blank=False, on_delete=CASCADE) cif = models.CharField(null=True, blank=True, verbose_name='NIF/CIF', max_length=50) email = models.CharField(null=False, blank=False, verbose_name='Email', max_length=250) name = models.CharField(null=True, blank=True, verbose_name='Nombre', max_length=250) description = models.TextField(null=True, blank=True, verbose_name='Descripción') short_description = models.TextField(null=True, blank=True, verbose_name='Descripción corta') phone_number = models.CharField(null=True, blank=True, verbose_name='Teléfono', max_length=25) address = models.TextField(null=True, blank=True, verbose_name='Dirección') logo = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('entities/'), verbose_name='Imagen de perfil', processors=[ResizeToFit(512, 512, upscale=False)], format='JPEG') logo_thumbnail = ImageSpecField( source='logo', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) registered = models.DateTimeField(auto_now_add=True) latitude = models.FloatField(null=False, verbose_name='Latitud', default=0) longitude = models.FloatField(null=False, verbose_name='Longitud', default=0) categories = models.ManyToManyField(Category, blank=True, verbose_name='Categorías') # Currency fields bonus_percent_entity = models.FloatField( default=0, verbose_name='Porcentaje de bonificación a entidades', validators=[MinValueValidator(0), MaxValueValidator(100)]) bonus_percent_general = models.FloatField( default=0, verbose_name='Porcentaje de bonificación general', validators=[MinValueValidator(0), MaxValueValidator(100)]) max_percent_payment = models.FloatField( default=0, verbose_name='Máximo porcentaje de pago aceptado', validators=[MinValueValidator(0), MaxValueValidator(100)]) num_workers = models.IntegerField(default=0, verbose_name='Número de trabajadores', validators=[MinValueValidator(0)]) legal_form = models.TextField(null=True, blank=True, verbose_name='Formulario legal') # Social links facebook_link = models.CharField(null=True, blank=True, verbose_name='Página de Facebook', max_length=250) webpage_link = models.CharField(null=True, blank=True, verbose_name='Página web', max_length=250) twitter_link = models.CharField(null=True, blank=True, verbose_name='Perfil de Twitter', max_length=250) telegram_link = models.CharField(null=True, blank=True, verbose_name='Canal de Telegram', max_length=250) instagram_link = models.CharField(null=True, blank=True, verbose_name='Perfil de Instagram', max_length=250) gallery = models.OneToOneField(Gallery, blank=True, null=True, on_delete=models.SET_NULL) @property def first_photo_url(self): if self.gallery and self.gallery.photos.count() > 0: image = self.gallery.photos.all().first() if image: return image.image.url return None def bonus(self, total_amount, bonusable_type=None): percent = self.bonus_percent_general if bonusable_type and bonusable_type == 'entity': percent = self.bonus_percent_entity return total_amount * (percent / 100.0) def max_accepted_currency(self, total_amount): #return total_amount * (self.max_percent_payment / 100.0) return total_amount class Meta: verbose_name = 'Entidad' verbose_name_plural = 'Entidades' ordering = ['registered'] def __unicode__(self): return self.name if self.name else 'Entidad'
class Entity(Account): name = models.CharField(null=True, blank=True, max_length=250, verbose_name=_('Nombre')) business_name = models.CharField(null=True, blank=True, max_length=250, verbose_name=_('Razón social')) categories = models.ManyToManyField(Category, verbose_name='Categorías', related_name='entities') territory = models.CharField(null=False, default=TERR_LOCAL, max_length=20, choices=TERRITORY_OPTIONS, verbose_name=_('Ámbito')) assisted_last_fair = models.BooleanField(default=False, verbose_name=_('Asistió a la última feria')) latitude = models.FloatField(null=False, verbose_name='Latitud', default=settings.INITIAL_LATITUDE) longitude = models.FloatField(null=False, verbose_name='Longitud', default=settings.INITIAL_LONGITUDE) public_address = models.TextField(null=True, blank=True, verbose_name=_('Dirección pública'), help_text='Dirección que aparece en el perfil de la entidad en la app del MES') logo = ProcessedImageField(null=True, blank=True, upload_to=RandomFileName('entities/'), verbose_name='Logo en alta resolución', processors=[ResizeToFit(1024, 1024, upscale=False)], format='JPEG', options={'quality': 80}) banner = ProcessedImageField(null=True, blank=True, upload_to=RandomFileName('entities/'), verbose_name='Banner alta resolución', processors=[ResizeToFit(1024, 1024, upscale=False)], format='JPEG', options={'quality': 80}) start_year = models.PositiveSmallIntegerField(blank=True, null=True, default=datetime.now().year, validators=[MinValueValidator(1900), MaxValueValidator(datetime.now().year)], verbose_name=_('Año de inicio del proyecto')) contact_person = models.TextField(null=True, blank=True, verbose_name=_('Persona de contacto')) description = models.TextField(null=True, blank=True, verbose_name='Descripción') short_description = models.TextField(null=True, blank=True, verbose_name='Descripción corta') bonus_percent_entity = models.FloatField(default=0, verbose_name='Porcentaje de bonificación a entidades', validators=[MinValueValidator(0), MaxValueValidator(100)]) bonus_percent_general = models.FloatField(default=0, verbose_name='Porcentaje de bonificación general', validators=[MinValueValidator(0), MaxValueValidator(100)]) max_percent_payment = models.FloatField(default=0, verbose_name='Máximo porcentaje de pago aceptado', validators=[MinValueValidator(0), MaxValueValidator(100)]) payment_conditions = models.TextField(null=True, blank=True, verbose_name=_('Condiciones uso Etics')) # Social links facebook_link = models.CharField(null=True, blank=True, verbose_name='Página de Facebook', max_length=250) webpage_link = models.CharField(null=True, blank=True, verbose_name='Página web', max_length=250) twitter_link = models.CharField(null=True, blank=True, verbose_name='Perfil de Twitter', max_length=250) telegram_link = models.CharField(null=True, blank=True, verbose_name='Canal de Telegram', max_length=250) instagram_link = models.CharField(null=True, blank=True, verbose_name='Perfil de Instagram', max_length=250) num_workers_male_partners = models.IntegerField(null=True, blank=True, verbose_name=_('Núm. hombres socios trabajadores')) num_workers_female_partners = models.IntegerField(null=True, blank=True, verbose_name=_('Núm. mujeres socias trabajadoras')) num_workers_male_non_partners = models.IntegerField(null=True, blank=True, verbose_name=_('Núm. hombres no socios trabajadores')) num_workers_female_non_partners = models.IntegerField(null=True, blank=True, verbose_name=_('Núm. mujeres no socias trabajadoras')) highest_salary = models.FloatField(null=True, blank=True, verbose_name=_('Salario bruto anual más alto')) lowest_salary = models.FloatField(null=True, blank=True, verbose_name=_('Salario bruto anual más bajo')) benefits_destination = models.TextField(blank=True, verbose_name=_('A qué se destinan los beneficios de la entidad (si los hay)')) apportations = models.TextField(blank=True, verbose_name=_('Qué trata de aportar vuestro proyecto a la transformación social')) networking = models.TextField(blank=True, verbose_name=_('Redes/organizaciones/iniciativas de transformación social de las que la entidad forma parte')) hidden_in_catalog = models.BooleanField(default=False, verbose_name=_('Oculta en el catálogo'), help_text='No mostrar esta entidad en el catálogo de la web') class Meta: verbose_name = _('Entidad') verbose_name_plural = _('Entidades') ordering = ['name'] @property def display_name(self): return self.name
class Offer(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) entity = models.ForeignKey(Entity, null=False, blank=False, related_name='offers') title = models.CharField(null=True, blank=True, verbose_name='Nombre', max_length=250) description = models.TextField(null=True, blank=True, verbose_name='Descripción') banner_image = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('offers/'), verbose_name='Imagen principal', processors=[ResizeToFit(756, 512, upscale=False)], format='JPEG') banner_thumbnail = ImageSpecField( source='banner_image', processors=[ResizeToFill(400, 200, upscale=False)], format='JPEG', options={'quality': 70}) published_date = models.DateTimeField(auto_now_add=True) discount_percent = models.FloatField( null=True, blank=True, verbose_name='Porcentaje de descuento', default=0) discounted_price = models.FloatField(null=True, blank=True, verbose_name='Precio con descuento', default=0) active = models.BooleanField(default=True, null=False, verbose_name='Activa') begin_date = models.DateField(null=True, blank=True, verbose_name='Fecha de inicio') end_date = models.DateField(null=True, blank=True, verbose_name='Fecha de fin') objects = OffersManager() @property def status(self): today = datetime.date.today() if (self.begin_date > today) or (self.begin_date <= today and self.end_date >= today and self.active == False): return 'future' elif self.begin_date <= today and self.end_date >= today and self.active: return 'current' else: return 'past' class Meta: verbose_name = 'Oferta' verbose_name_plural = 'Ofertas' ordering = ['-published_date'] def __unicode__(self): return self.title if self.title else self.pk
class Person(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) user = models.OneToOneField(User, null=False, blank=False) city = models.ForeignKey(City, null=False, blank=False) nif = models.CharField(null=True, blank=True, verbose_name='NIF/CIF', max_length=50) email = models.CharField(null=False, blank=False, verbose_name='Email', max_length=250) name = models.CharField(null=True, blank=True, verbose_name='Nombre', max_length=250) surname = models.CharField(null=True, blank=True, verbose_name='Apellidos', max_length=250) address = models.TextField(null=True, blank=True, verbose_name='Dirección') profile_image = ProcessedImageField( null=True, blank=True, upload_to=RandomFileName('profiles/'), verbose_name='Imagen de perfil', processors=[ResizeToFit(512, 512, upscale=False)], format='JPEG') profile_thumbnail = ImageSpecField( source='profile_image', processors=[ResizeToFill(150, 150, upscale=False)], format='JPEG', options={'quality': 70}) registered = models.DateTimeField(auto_now_add=True) fav_entities = models.ManyToManyField(Entity, blank=True, verbose_name="Favoritos") is_guest_account = models.BooleanField(default=False, verbose_name='Es usuario invitado') expiration_date = models.DateField(null=True, blank=True, verbose_name='Fecha de expiración') class Meta: verbose_name = 'Persona' verbose_name_plural = 'Personas' ordering = ['registered'] @property def display_name(self): return "{} {}".format(self.name, self.surname) @property def full_name(self): return '{} {}'.format(self.name if self.name else '', self.surname if self.surname else '') def __unicode__(self): return '{} {}'.format(self.name if self.name else '', self.surname if self.surname else '')