class Profile(models.Model): GENDERS = (('male', 'Male'), ('female', 'Female'), ('other', 'Other')) user = models.OneToOneField(settings.AUTH_USER_MODEL, default=-1, primary_key=True, on_delete=models.CASCADE) birth_date = models.DateField(null=True, blank=True, verbose_name='Date of birth') gender = models.CharField(max_length=10, choices=GENDERS, blank=True) phone_number = models.CharField(max_length=15, null=True, blank=True) dietary_restrictions = models.ManyToManyField(DietaryRestriction, blank=True) other_dietary_restrictions = models.CharField(max_length=75, blank=True, null=True) no_dietary_restrictions = models.BooleanField( null=False, blank=False) # required if no dietary_restrictions are selected programme = models.ForeignKey(Programme, null=True, blank=True, on_delete=models.CASCADE, verbose_name='Program') registration_year = models.IntegerField(null=True, blank=True) planned_graduation = models.IntegerField(null=True, blank=True) linkedin_url = models.URLField(null=True, blank=True, verbose_name='Linkedin URL') token = models.CharField(max_length=255, null=True, blank=False, default=uuid.uuid4) slack_id = models.CharField(max_length=255, null=True, blank=True, verbose_name='Slack ID') preferred_language = models.ForeignKey(Language, null=True, blank=True, on_delete=models.CASCADE) kth_synchronize = models.BooleanField( null=False, blank=False, default=True, verbose_name='Synchronize account data with KTH') picture_original = models.ImageField(upload_to=UploadToDirUUID( 'profiles', 'picture_original'), blank=True) picture = models.ImageField(upload_to=UploadToDir('profiles', 'picture'), blank=True) def __str__(self): return self.user.get_full_name() class Meta: db_table = 'profile' permissions = [('base', 'People')]
class Banquet(models.Model): fair = models.ForeignKey(Fair, on_delete=models.CASCADE) name = models.CharField(max_length=75, blank=False, null=False) date = models.DateTimeField() location = models.CharField(max_length=75, blank=True, null=True) dress_code = models.CharField(max_length=255, blank=True, null=True) caption_phone_number = models.CharField( max_length=255, blank=True, null=True, verbose_name='Caption for the phone number field') caption_dietary_restrictions = models.CharField( max_length=255, blank=True, null=True, verbose_name='Caption for dietary restrictions') product = models.ForeignKey( Product, null=True, blank=True, on_delete=models.CASCADE, verbose_name='Product to link the banquet with') background = models.ImageField(upload_to=UploadToDirUUID( 'banquets', 'map'), blank=True, null=True) point_size = models.DecimalField(blank=True, null=True, max_digits=11, decimal_places=10) def __str__(self): return self.name
class Partner(models.Model): name = models.CharField(max_length=50) fair = models.ForeignKey(Fair, on_delete=models.CASCADE) logo = models.ImageField(upload_to=UploadToDirUUID('partners', 'logo')) url = models.CharField(max_length=300) main_partner = models.BooleanField() def __str__(self): return self.name
class Profile(models.Model): # defining shirt sizes SHIRT_SIZES = ( ('WXS', 'Woman X-Small'), ('WS', 'Woman Small'), ('WM', 'Woman Medium'), ('WL', 'Woman Large'), ('WXL', 'Woman X-Large'), ('MXS', 'Man X-Small'), ('MS', 'Man Small'), ('MM', 'Man Medium'), ('ML', 'Man Large'), ('MXL', 'Man X-Large'), ) GENDERS = (('male', 'Male'), ('female', 'Female'), ('other', 'Other')) user = models.OneToOneField(settings.AUTH_USER_MODEL, default=-1, primary_key=True) birth_date = models.DateField(null=True, blank=True) gender = models.CharField(max_length=10, choices=GENDERS, blank=True) shirt_size = models.CharField(max_length=3, choices=SHIRT_SIZES, blank=True) phone_number = models.CharField(max_length=15, null=True, blank=True) drivers_license = models.CharField(max_length=10, null=True, blank=True) allergy = models.CharField(max_length=30, null=True, blank=True) programme = models.ForeignKey(Programme, null=True, blank=True) registration_year = models.IntegerField(null=True, blank=True) planned_graduation = models.IntegerField(null=True, blank=True) linkedin_url = models.URLField(null=True, blank=True) picture_original = models.ImageField( upload_to=UploadToDirUUID('profiles', 'picture_original'), blank=True, ) picture = models.ImageField( upload_to=UploadToDir('profiles', 'picture'), blank=True, ) def __str__(self): return '%s' % (self.user.get_full_name()) def save(self, *args, **kwargs): super(Profile, self).save(*args, **kwargs) self.picture = update_image_field(self.picture_original, self.picture, 480, 640, 'jpg') super(Profile, self).save(*args, **kwargs) class Meta: db_table = 'profile' permissions = (('view_people', 'View people'), )
class NewsArticle(models.Model): title = models.CharField(max_length=150) html_article_text = models.CharField(default="", max_length=5000) publication_date = models.DateTimeField() image = models.ImageField( upload_to=UploadToDirUUID('news', 'image'), blank=True, ) def __str__(self): return self.title objects = models.Manager() # keep the default manager public_articles = NewsArticleManager() # add custom manager
class Location(models.Model): fair = models.ForeignKey(Fair, on_delete=models.CASCADE) parent = models.ForeignKey('exhibitors.Location', on_delete=models.CASCADE, null=True, blank=True) name = models.CharField(blank=False, null=False, max_length=255) background = models.ImageField(upload_to=UploadToDirUUID('locations'), null=True, blank=True) people_count_enabled = models.BooleanField(default=False) people_count = models.IntegerField(null=True, blank=True) class Meta: ordering = ['fair', 'parent__name', 'name'] unique_together = [['fair', 'name']] def __str__(self): return ((str(self.parent) + ' -> ') if self.parent else '') + self.name
class Event(models.Model): fair = models.ForeignKey(Fair, on_delete=models.CASCADE) name = models.CharField(max_length=75, blank=False, null=False) description = models.TextField(blank=True, null=True) date_start = models.DateTimeField() date_end = models.DateTimeField() location = models.CharField(max_length=75, blank=True, null=True) food = models.CharField(max_length=75, blank=True, null=True) signup_cr = models.BooleanField( blank=False, null=False, verbose_name='Let company representatives sign up') signup_s = models.BooleanField(blank=False, null=False, verbose_name='Let students sign up') open_for_signup = models.BooleanField( blank=False, null=False, verbose_name='Event is currently open for sign up') company_product = models.ForeignKey( Product, null=True, blank=True, on_delete=models.CASCADE, verbose_name='Product to link the event with') teams_create_cr = models.BooleanField( blank=False, null=False, verbose_name='Let company representatives create teams') teams_create_s = models.BooleanField( blank=False, null=False, verbose_name='Let students create teams') teams_participate_cr = models.BooleanField( blank=False, null=False, verbose_name='Let company representatives join or leave teams') teams_participate_s = models.BooleanField( blank=False, null=False, verbose_name='Let students join or leave teams') teams_default_max_capacity = models.PositiveIntegerField( blank=True, null=True, verbose_name='Default max number of team members') # None => no limit fee_s = models.PositiveIntegerField( default=0, blank=False, null=False, verbose_name='Sign-up fee for students') published = models.BooleanField( blank=False, null=False, verbose_name='The event is published on the website') requires_invitation = models.BooleanField( blank=False, null=False, verbose_name='Participants need an invitation to sign up') contact_person = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE) external_event_link = models.CharField(max_length=255, blank=True, null=True) picture = models.ImageField(upload_to=UploadToDirUUID( 'events', 'pictures'), blank=True, null=True) class Meta: ordering = ['date_start', 'name'] def __str__(self): return self.name @property def is_future(self): return timezone.now() < self.date_start @property def is_past(self): return timezone.now() > self.date_end
class Event(models.Model): # Add event attendence per model fair = models.ForeignKey(Fair) name = models.CharField(max_length=75) event_start = models.DateTimeField() event_end = models.DateTimeField() capacity = models.PositiveSmallIntegerField(default=0, blank=True) description = models.TextField(blank=True) description_short = models.TextField(blank=True) location = models.CharField(max_length=75, blank=True) attendence_description = models.TextField( blank=True, help_text="This is a text only shown in the attendence form, example \ 'To be accepted to this event you need to pay the event fee of \ 500 SEK'") attendence_approvement_required = models.BooleanField( default=True, help_text="If this is checked all users that attends the event needs to \ be accepted by an admin.") external_signup_url = models.URLField(blank=True) registration_required = models.BooleanField(default=True) registration_start = models.DateTimeField() registration_end = models.DateTimeField() registration_last_day_cancel = models.DateTimeField( null=True, help_text="Last day a user can cancel the attendence to the event") public_registration = models.BooleanField( default=False, help_text="If users without an account should be able to sign up for \ this event.") published = models.BooleanField( default=False, help_text= "If the event should be published in the apps and on the website.") allowed_groups = models.ManyToManyField( Group, blank=True, help_text="Choose which groups in armada should be able to see and \ attend this event. NOTE: No groups make the event accesible to all \ ais-users.") send_submission_mail = models.BooleanField( default=False, help_text="If checked an email will be sent when a user attends \ the event") submission_mail_subject = models.CharField(max_length=78, blank=True) submission_mail_body = models.TextField(blank=True) confirmation_mail_subject = models.CharField(max_length=78, blank=True) confirmation_mail_body = models.TextField(blank=True) rejection_mail_subject = models.CharField(max_length=78, blank=True) rejection_mail_body = models.TextField(blank=True) image_original = models.ImageField(upload_to=UploadToDirUUID( 'events', 'image_original'), blank=True) image = models.ImageField(upload_to=UploadToDir('events', 'image'), blank=True) tags = models.ManyToManyField(Tag, blank=True) extra_field = models.ForeignKey(ExtraField, blank=True, null=True) def __str__(self): return '%s: %s' % (self.fair, self.name) def save(self, *args, **kwargs): super(Event, self).save(*args, **kwargs) if not self.extra_field: self.extra_field = ExtraField.objects.create() self.image = update_image_field(self.image_original, self.image, 1000, 1000, 'jpg') super(Event, self).save(*args, **kwargs)
class CatalogInfo(models.Model): exhibitor = models.OneToOneField( Exhibitor, on_delete=models.CASCADE, ) display_name = models.CharField(max_length=200) slug = models.SlugField(db_index=False, blank=True) short_description = models.CharField(max_length=200, blank=True) description = models.TextField() employees_sweden = models.IntegerField(default=0) employees_world = models.IntegerField(default=0) countries = models.IntegerField(default=0) website_url = models.CharField(max_length=300, blank=True) facebook_url = models.CharField(max_length=300, blank=True) twitter_url = models.CharField(max_length=300, blank=True) linkedin_url = models.CharField(max_length=300, blank=True) # Image fields # Field with name ending with original serves as the original uploaded # image and should be the only image uploaded, # the others are auto generated logo_original = models.ImageField( upload_to=UploadToDirUUID('exhibitors', 'logo_original'), blank=True, ) logo_small = models.ImageField(upload_to=UploadToDir( 'exhibitors', 'logo_small'), blank=True) logo = models.ImageField(upload_to=UploadToDir('exhibitors', 'logo'), blank=True) ad_original = models.ImageField(upload_to=UploadToDirUUID( 'exhibitors', 'ad_original'), blank=True) ad = models.ImageField(upload_to=UploadToDir('exhibitors', 'ad'), blank=True) location_at_fair_original = models.ImageField(upload_to=UploadToDirUUID( 'exhibitors', 'location_at_fair_original'), blank=True) location_at_fair = models.ImageField(upload_to=UploadToDir( 'exhibitors', 'location_at_fair'), blank=True) # ManyToMany relationships programs = models.ManyToManyField('people.Programme', blank=True) main_work_field = models.ForeignKey(WorkField, blank=True, null=True, related_name='+') work_fields = models.ManyToManyField(WorkField, blank=True, related_name='+') job_types = models.ManyToManyField(JobType, blank=True) continents = models.ManyToManyField(Continent, blank=True) values = models.ManyToManyField(Value, blank=True) tags = models.ManyToManyField('fair.Tag', blank=True) def __str__(self): return self.display_name # Override default save method to automatically generate associated images # if the original has been changed def save(self, *args, **kwargs): if self.pk is None: self.slug = slugify(self.display_name[:50]) super(CatalogInfo, self).save(*args, **kwargs) self.logo = update_image_field(self.logo_original, self.logo, 400, 400, 'png') self.logo_small = update_image_field(self.logo_original, self.logo_small, 200, 200, 'png') self.ad = update_image_field(self.ad_original, self.ad, 640, 480, 'jpg') self.location_at_fair = update_image_field( self.location_at_fair_original, self.location_at_fair, 1000, 1000, 'png') super(CatalogInfo, self).save(*args, **kwargs)
class Exhibitor(models.Model): company = models.ForeignKey('companies.Company', on_delete=models.CASCADE) fair = models.ForeignKey('fair.Fair', on_delete=models.CASCADE) hosts = models.ManyToManyField(User, blank=True) contact = models.ForeignKey('companies.CompanyContact', null=True, blank=True, on_delete=models.CASCADE) location = models.ForeignKey(Location, null=True, blank=True, on_delete=models.CASCADE) booth_number = models.IntegerField(blank=True, null=True) fair_location = models.OneToOneField('locations.Location', blank=True, null=True, on_delete=models.CASCADE) about_text = models.TextField(blank=True) facts_text = models.TextField(blank=True) accept_terms = models.BooleanField(default=False) booth_height = models.PositiveIntegerField( blank=True, null=True, verbose_name='Height of the booth (cm)') electricity_total_power = models.PositiveIntegerField( blank=True, null=True, verbose_name='Estimated power consumption (W)') electricity_socket_count = models.PositiveIntegerField( blank=True, null=True, verbose_name='Number of sockets') electricity_equipment = models.TextField( blank=True, null=True, verbose_name='Description of equipment') catalogue_about = models.TextField(blank=True, null=True, max_length=600) catalogue_purpose = models.TextField(blank=True, null=True, max_length=600) catalogue_logo_squared = models.ImageField(upload_to=UploadToDirUUID( 'exhibitors', 'catalogue_logo_squared'), blank=True) catalogue_logo_freesize = models.ImageField(upload_to=UploadToDirUUID( 'exhibitors', 'catalogue_logo_freesize'), blank=True) catalogue_contact_name = models.CharField( blank=True, null=True, max_length=255, verbose_name='Contact person\'s name') catalogue_contact_email_address = models.CharField( blank=True, null=True, max_length=255, verbose_name='Contact person\'s e-mail address') catalogue_contact_phone_number = models.CharField( blank=True, null=True, max_length=255, verbose_name='Contact person\'s phone number') catalogue_industries = models.ManyToManyField(CatalogueIndustry, blank=True) catalogue_values = models.ManyToManyField(CatalogueValue, blank=True) catalogue_employments = models.ManyToManyField(CatalogueEmployment, blank=True) catalogue_locations = models.ManyToManyField(CatalogueLocation, blank=True) catalogue_benefits = models.ManyToManyField(CatalogueBenefit, blank=True) catalogue_average_age = models.PositiveIntegerField( blank=True, null=True, verbose_name='Average age of employees') catalogue_founded = models.PositiveIntegerField(blank=True, null=True) placement_wishes = [ ('MIXED', 'Mixed with companies from other industries'), ('SIMILAR', 'Next to similar companies'), ] placement_wish = models.CharField(choices=placement_wishes, blank=True, null=True, max_length=255) placement_comment = models.TextField( blank=True, null=True, verbose_name='Additional wishes regarding placement at the fair') # For the logistics team comment = models.TextField(blank=True) statuses = [ ('accepted', 'Accepted'), ('registered', 'Registered'), ('complete_registration', 'Completed Registration'), ('complete_registration_submit', 'CR - Submitted'), ('complete_registration_start', 'CR - In Progress'), ('complete_registration_terms', 'CR - Accepted Terms'), ('contacted_by_host', 'Contacted by host'), ('confirmed', 'Confirmed'), ('checked_in', 'Checked in'), ('checked_out', 'Checked out'), ('withdrawn', 'Withdrawn'), ] status = models.CharField(choices=statuses, null=True, blank=True, max_length=30) logo = models.ImageField(upload_to=UploadToDirUUID('exhibitors', 'logo_original'), blank=True) location_at_fair = models.ImageField(upload_to=UploadToDirUUID( 'exhibitors', 'location_at_fair'), blank=True) inbound_transportation = models.ForeignKey( TransportationAlternative, on_delete=models.SET_NULL, null=True, blank=True, related_name='inbound_transportation', verbose_name='Transportation to the fair') outbound_transportation = models.ForeignKey( TransportationAlternative, on_delete=models.SET_NULL, null=True, blank=True, related_name='outbound_transportation', verbose_name='Transportation from the fair') pickup_order = models.ForeignKey(TransportationOrder, on_delete=models.SET_NULL, null=True, blank=True, related_name='pickup_order') delivery_order = models.ForeignKey(TransportationOrder, on_delete=models.SET_NULL, null=True, blank=True, related_name='delivery_order') tags = models.ManyToManyField('fair.Tag', blank=True) job_types = models.ManyToManyField(JobType, blank=True) def total_cost(self): return sum([order.price() for order in self.order_set.all()]) def superiors(self): accepted_applications = [ RecruitmentApplication.objects.filter(status='accepted', user=host).first() for host in self.hosts.all() ] return [ application.superior_user for application in accepted_applications if application and application.superior_user ] def __str__(self): return '%s at %s' % (self.company.name, self.fair.name) class Meta: permissions = (('base', 'Exhibitors'), )
class Exhibitor(models.Model): company = models.ForeignKey('companies.Company', on_delete=models.CASCADE) fair = models.ForeignKey('fair.Fair', on_delete=models.CASCADE) contact_persons = models.ManyToManyField(User, blank=True) contact = models.ForeignKey('companies.CompanyContact', null=True, blank=True, on_delete=models.CASCADE) booth_height = models.PositiveIntegerField( blank=True, null=True, verbose_name='Height of the booth (cm)') electricity_total_power = models.PositiveIntegerField( blank=True, null=True, verbose_name='Estimated power consumption (W)') electricity_socket_count = models.PositiveIntegerField( blank=True, null=True, verbose_name='Number of sockets') electricity_equipment = models.TextField( blank=True, null=True, verbose_name='Description of equipment') check_in_timestamp = models.DateTimeField(blank=True, null=True) check_in_comment = models.TextField(blank=True, null=True) check_in_user = models.ForeignKey(User, blank=True, null=True, related_name='check_in_user', on_delete=models.SET_NULL) catalogue_about = models.TextField(blank=True, null=True, max_length=600) catalogue_purpose = models.TextField(blank=True, null=True, max_length=600) catalogue_logo_squared = models.ImageField(upload_to=UploadToDirUUID( 'exhibitors', 'catalogue_logo_squared'), blank=True) catalogue_logo_freesize = models.ImageField(upload_to=UploadToDirUUID( 'exhibitors', 'catalogue_logo_freesize'), blank=True) catalogue_contact_name = models.CharField( blank=True, null=True, max_length=255, verbose_name='Contact person\'s name') catalogue_contact_email_address = models.CharField( blank=True, null=True, max_length=255, verbose_name='Contact person\'s e-mail address') catalogue_contact_phone_number = models.CharField( blank=True, null=True, max_length=255, verbose_name='Contact person\'s phone number') catalogue_industries = models.ManyToManyField(CatalogueIndustry, blank=True) catalogue_values = models.ManyToManyField(CatalogueValue, blank=True) catalogue_employments = models.ManyToManyField(CatalogueEmployment, blank=True) catalogue_benefits = models.ManyToManyField(CatalogueBenefit, blank=True) catalogue_competences = models.ManyToManyField(CatalogueCompetence, blank=True) catalogue_locations = models.ManyToManyField(CatalogueLocation, blank=True) catalogue_cities = models.TextField(blank=True, null=True, max_length=400) catalogue_average_age = models.PositiveIntegerField( blank=True, null=True, verbose_name='Average age of employees') catalogue_founded = models.PositiveIntegerField(blank=True, null=True) fair_location = models.ForeignKey(Location, blank=True, null=True, on_delete=models.SET_NULL) vyer_position = models.CharField(blank=True, null=True, max_length=255) flyer = models.FileField(upload_to='exhibitors/flyers/%Y%m%d/', default=None, blank=True, null=True) deadline_complete_registration = models.DateTimeField( blank=True, null=True, verbose_name='Deviating deadline for complete registration') placement_wishes = [ (None, 'No preference'), ('MIXED', 'Mixed with companies from other industries'), ('SIMILAR', 'Next to similar companies'), ] placement_wish = models.CharField(choices=placement_wishes, blank=True, null=True, max_length=255) placement_comment = models.TextField( blank=True, null=True, verbose_name='Additional wishes regarding placement at the fair') transport_to_statuses = [('NOT_BOOKED', 'Not booked'), ('BOOKED', 'Booked'), ('ARKAD', 'Transported by Arkad'), ('NOT_APPLICABLE', 'Not applicable'), ('EXCEPTION', 'Exception'), ('IN_CONTACT', 'In contact'), ('IN_CONTACT_ARMADA', 'In contact by Armada'), ('STURE', 'Sture'), ('BY_HAND', 'Carried by hand')] transport_to = models.CharField(choices=transport_to_statuses, null=False, blank=False, default='NOT_BOOKED', max_length=30) transport_from_statuses = [('NOT_BOOKED', 'Not booked'), ('BOOKED', 'Booked'), ('NOT_APPLICABLE', 'Not applicable'), ('EXCEPTION', 'Exception'), ('IN_CONTACT', 'In contact'), ('STURE', 'Sture'), ('BY_HAND', 'Carried by hand')] transport_from = models.CharField(choices=transport_from_statuses, null=False, blank=False, default='NOT_BOOKED', max_length=30) transport_comment = models.TextField(blank=True, null=True) @property def count_lunch_tickets(self): count_ordered = 0 for order in Order.objects.filter( purchasing_company=self.company, product=self.fair.product_lunch_ticket): count_ordered += order.quantity count_created = LunchTicket.objects.filter( company=self.company).count() return {'ordered': count_ordered, 'created': count_created} @property def count_banquet_tickets(self): count_ordered = 0 count_created = 0 for banquet in Banquet.objects.filter(fair=self.fair): if banquet.product is not None: for order in Order.objects.filter( purchasing_company=self.company, product=banquet.product): count_ordered += order.quantity count_created += Participant.objects.filter( banquet=banquet, company=self.company).count() return {'ordered': count_ordered, 'created': count_created} @property def fair_location_special(self): for locationSpecial in FairLocationSpecial.objects.filter( fair=self.fair): allExhibitors = locationSpecial.exhibitors.all() for exh in allExhibitors: if (exh == self): return locationSpecial return None @property def climate_compensation(self): for order in Order.objects.filter( purchasing_company=self.company, product__name="Climate compensation"): return True return False def __str__(self): return '%s at %s' % (self.company.name, self.fair.name) class Meta: default_permissions = [] ordering = ['company__name'] permissions = [('base', 'View the Exhibitors tab'), ('view_all', 'Always view all exhibitors'), ('create', 'Create new exhibitors'), ('modify_contact_persons', 'Modify contact persons'), ('modify_transport', 'Modify transport details'), ('modify_check_in', 'Modify check in'), ('modify_details', 'Modify details'), ('modify_booths', 'Modify booths'), ('people_count', 'Count people in locations')]