class InfoModel(db.Model): __tablename__ = 'info' # one to one user_id = db.Column(db.String(32), db.ForeignKey('user.user_id', ondelete='CASCADE', onupdate='CASCADE'), primary_key=True) name = db.Column(db.String(20), nullable=False, default="") sex = db.Column(db.Enum(SexChoice), nullable=True) birth = db.Column(db.Date, nullable=False) my_tel = db.Column(db.String(15), nullable=False, default="") parent_name = db.Column(db.String(20), nullable=False, default="") parent_tel = db.Column(db.String(15), nullable=False, default="") address_base = db.Column(db.String(100), nullable=False, default="") address_detail = db.Column(db.String(50), nullable=False, default="") zip_code = db.Column(db.String(5), nullable=False, default="") img_path = db.Column(db.String(50), unique=True, nullable=True) created_at = db.Column(db.DateTime, nullable=False) updated_at = db.Column(db.DateTime, nullable=False)
class UserDetail(db.Model): __tablename__ = "user_detail" id = db.Column(db.Integer, primary_key=True) firstname = db.Column(db.String) lastname = db.Column(db.String) details = db.Column(db.String) avatar = db.Column(db.String) contact = db.Column(db.String) facebook = db.Column(db.String) twitter = db.Column(db.String) instagram = db.Column(db.String) google = db.Column(db.String) avatar_uploaded = db.Column(db.String) thumbnail = db.Column(db.String) small = db.Column(db.String) icon = db.Column(db.String) user_id = db.Column(db.Integer, db.ForeignKey('user.id', ondelete='CASCADE')) def __init__(self, firstname=None, lastname=None, avatar=None, contact=None, user_id=None, facebook=None, twitter=None, instagram=None, google=None, thumbnail=None, small=None, icon=None, avatar_uploaded=None): self.avatar = avatar self.contact = contact self.user_id = user_id self.firstname = firstname self.lastname = lastname self.facebook = facebook self.twitter = twitter self.instagram = instagram self.google = google self.thumbnail = thumbnail self.small = small self.icon = icon self.avatar_uploaded = avatar_uploaded def __repr__(self): return '<UserDetail %r>' % self.id def __str__(self): return unicode(self).encode('utf-8') def __unicode__(self): return self.fullname def __setattr__(self, name, value): if name == 'details': super(UserDetail, self).__setattr__(name, clean_html(clean_up_string(value))) else: super(UserDetail, self).__setattr__(name, value) @property def fullname(self): firstname = self.firstname if self.firstname else '' lastname = self.lastname if self.lastname else '' if firstname and lastname: return u'{} {}'.format(firstname, lastname) else: return '' @property def serialize(self): """Return object data in easily serializeable format""" return { 'id': self.id, 'fullname': self.fullname, 'avatar': self.avatar, 'contact': self.contact, 'facebook': self.facebook, 'twitter': self.twitter, 'instagram': self.instagram, 'google': self.google, 'thumbnail': self.thumbnail, 'small': self.small, 'icon': self.icon, 'avatar_uploaded': self.avatar_uploaded }
class Event(SoftDeletionModel): """Event object table""" __tablename__ = 'events' __versioned__ = { 'exclude': ['schedule_published_on', 'created_at'] } id = db.Column(db.Integer, primary_key=True) identifier = db.Column(db.String) name = db.Column(db.String, nullable=False) external_event_url = db.Column(db.String) logo_url = db.Column(db.String) starts_at = db.Column(db.DateTime(timezone=True), nullable=False) ends_at = db.Column(db.DateTime(timezone=True), nullable=False) timezone = db.Column(db.String, nullable=False, default="UTC") is_event_online = db.Column(db.Boolean, default=False) latitude = db.Column(db.Float) longitude = db.Column(db.Float) location_name = db.Column(db.String) searchable_location_name = db.Column(db.String) is_featured = db.Column(db.Boolean, default=False, nullable=False) description = db.Column(db.Text) original_image_url = db.Column(db.String) thumbnail_image_url = db.Column(db.String) large_image_url = db.Column(db.String) show_remaining_tickets = db.Column(db.Boolean, default=False, nullable=False) icon_image_url = db.Column(db.String) owner_name = db.Column(db.String) is_map_shown = db.Column(db.Boolean) has_owner_info = db.Column(db.Boolean) owner_description = db.Column(db.String) is_sessions_speakers_enabled = db.Column(db.Boolean, default=False) track = db.relationship('Track', backref="event") microlocation = db.relationship('Microlocation', backref="event") session = db.relationship('Session', backref="event") speaker = db.relationship('Speaker', backref="event") sponsor = db.relationship('Sponsor', backref="event") tickets = db.relationship('Ticket', backref="event_") tags = db.relationship('TicketTag', backref='events') roles = db.relationship("UsersEventsRoles", backref="event") role_invites = db.relationship('RoleInvite', back_populates='event') custom_form = db.relationship('CustomForms', backref="event") faqs = db.relationship('Faq', backref="event") feedbacks = db.relationship('Feedback', backref="event") attendees = db.relationship('TicketHolder', backref="event") privacy = db.Column(db.String, default="public") state = db.Column(db.String, default="Draft") event_type_id = db.Column(db.Integer, db.ForeignKey('event_types.id', ondelete='CASCADE')) event_topic_id = db.Column(db.Integer, db.ForeignKey('event_topics.id', ondelete='CASCADE')) event_sub_topic_id = db.Column(db.Integer, db.ForeignKey( 'event_sub_topics.id', ondelete='CASCADE')) events_orga_id = db.Column(db.Integer, db.ForeignKey( 'events_orga.id', ondelete='CASCADE')) ticket_url = db.Column(db.String) db.UniqueConstraint('track.name') code_of_conduct = db.Column(db.String) schedule_published_on = db.Column(db.DateTime(timezone=True)) is_ticketing_enabled = db.Column(db.Boolean, default=False) is_donation_enabled = db.Column(db.Boolean, default=False) is_ticket_form_enabled = db.Column(db.Boolean, default=True, nullable=False) payment_country = db.Column(db.String) payment_currency = db.Column(db.String) paypal_email = db.Column(db.String) is_tax_enabled = db.Column(db.Boolean, default=False) is_billing_info_mandatory = db.Column(db.Boolean, default=False, nullable=False) can_pay_by_paypal = db.Column(db.Boolean, default=False, nullable=False) can_pay_by_stripe = db.Column(db.Boolean, default=False, nullable=False) can_pay_by_cheque = db.Column(db.Boolean, default=False, nullable=False) can_pay_by_bank = db.Column(db.Boolean, default=False, nullable=False) can_pay_onsite = db.Column(db.Boolean, default=False, nullable=False) can_pay_by_omise = db.Column(db.Boolean, default=False, nullable=False) can_pay_by_alipay = db.Column(db.Boolean, default=False, nullable=False) can_pay_by_paytm = db.Column(db.Boolean, default=False, nullable=False) cheque_details = db.Column(db.String) bank_details = db.Column(db.String) onsite_details = db.Column(db.String) created_at = db.Column(db.DateTime(timezone=True)) pentabarf_url = db.Column(db.String) ical_url = db.Column(db.String) xcal_url = db.Column(db.String) is_sponsors_enabled = db.Column(db.Boolean, default=False) refund_policy = db.Column(db.String, default='All sales are final. No refunds shall be issued in any case.') is_stripe_linked = db.Column(db.Boolean, default=False) discount_code_id = db.Column(db.Integer, db.ForeignKey( 'discount_codes.id', ondelete='CASCADE')) discount_code = db.relationship('DiscountCode', backref='events', foreign_keys=[discount_code_id]) event_type = db.relationship('EventType', backref='event', foreign_keys=[event_type_id]) event_topic = db.relationship('EventTopic', backref='event', foreign_keys=[event_topic_id]) event_sub_topic = db.relationship( 'EventSubTopic', backref='event', foreign_keys=[event_sub_topic_id]) events_orga = db.relationship( 'EventOrgaModel', backref='event', foreign_keys=[events_orga_id]) owner = db.relationship('User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "owner"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='owner_events', uselist=False) organizers = db.relationship('User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "organizer"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='organizer_events') coorganizers = db.relationship('User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "coorganizer"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='coorganizer_events') track_organizers = db.relationship('User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id,' ' Role.name == "track_organizer"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='track_organizer_events') registrars = db.relationship('User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "registrar"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='registrar_events') moderators = db.relationship('User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "moderator"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='moderator_events') # staff users = db.relationship('User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name != "attendee"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='events') def __init__(self, name=None, logo_url=None, starts_at=None, ends_at=None, timezone='UTC', is_event_online=False, latitude=None, longitude=None, location_name=None, description=None, external_event_url=None, original_image_url=None, thumbnail_image_url=None, large_image_url=None, icon_image_url=None, owner_name=None, owner_description=None, state=None, event_type_id=None, privacy=None, event_topic_id=None, event_sub_topic_id=None, events_orga_id=None, ticket_url=None, copyright=None, code_of_conduct=None, schedule_published_on=None, is_sessions_speakers_enabled=False, show_remaining_tickets=False, is_ticket_form_enabled=True, is_donation_enabled=False, is_map_shown=False, has_owner_info=False, searchable_location_name=None, is_ticketing_enabled=None, deleted_at=None, payment_country=None, payment_currency=None, paypal_email=None, speakers_call=None, can_pay_by_paypal=False, can_pay_by_stripe=False, can_pay_by_cheque=False, can_pay_by_omise=False, can_pay_by_alipay=False, can_pay_by_paytm=False, identifier=None, can_pay_by_bank=False, is_featured=False, can_pay_onsite=False, cheque_details=None, bank_details=None, pentabarf_url=None, ical_url=None, xcal_url=None, discount_code_id=None, onsite_details=None, is_tax_enabled=None, is_billing_info_mandatory=False, is_sponsors_enabled=None, stripe_authorization=None, tax=None, refund_policy='All sales are final. No refunds shall be issued in any case.', is_stripe_linked=False): self.name = name self.logo_url = logo_url self.starts_at = starts_at self.ends_at = ends_at self.timezone = timezone self.is_event_online = is_event_online self.latitude = latitude self.longitude = longitude self.location_name = location_name self.description = clean_up_string(description) self.external_event_url = external_event_url self.original_image_url = original_image_url self.original_image_url = self.set_default_event_image(event_topic_id) if original_image_url is None \ else original_image_url self.thumbnail_image_url = thumbnail_image_url self.large_image_url = large_image_url self.icon_image_url = icon_image_url self.owner_name = owner_name self.owner_description = clean_up_string(owner_description) self.state = state self.is_map_shown = is_map_shown self.has_owner_info = has_owner_info self.privacy = privacy self.event_type_id = event_type_id self.event_topic_id = event_topic_id self.show_remaining_tickets = show_remaining_tickets self.copyright = copyright self.event_sub_topic_id = event_sub_topic_id self.events_orga_id = events_orga_id self.ticket_url = ticket_url self.code_of_conduct = code_of_conduct self.schedule_published_on = schedule_published_on self.is_sessions_speakers_enabled = is_sessions_speakers_enabled self.searchable_location_name = searchable_location_name self.is_ticketing_enabled = is_ticketing_enabled self.deleted_at = deleted_at self.payment_country = payment_country self.payment_currency = payment_currency self.paypal_email = paypal_email self.speakers_call = speakers_call self.can_pay_by_paypal = can_pay_by_paypal self.can_pay_by_stripe = can_pay_by_stripe self.can_pay_by_cheque = can_pay_by_cheque self.can_pay_by_bank = can_pay_by_bank self.can_pay_onsite = can_pay_onsite self.can_pay_by_omise = can_pay_by_omise self.can_pay_by_alipay = can_pay_by_alipay self.can_pay_by_paytm = can_pay_by_paytm self.is_donation_enabled = is_donation_enabled self.is_featured = is_featured self.is_ticket_form_enabled = is_ticket_form_enabled self.identifier = get_new_event_identifier() self.cheque_details = cheque_details self.bank_details = bank_details self.pentabarf_url = pentabarf_url self.ical_url = ical_url self.xcal_url = xcal_url self.onsite_details = onsite_details self.discount_code_id = discount_code_id self.created_at = datetime.now(pytz.utc) self.is_tax_enabled = is_tax_enabled self.is_billing_info_mandatory = is_billing_info_mandatory self.is_sponsors_enabled = is_sponsors_enabled self.stripe_authorization = stripe_authorization self.tax = tax self.refund_policy = refund_policy self.is_stripe_linked = is_stripe_linked def __repr__(self): return '<Event %r>' % self.name def __str__(self): return self.__repr__() def __setattr__(self, name, value): if name == 'owner_description' or name == 'description' or name == 'code_of_conduct': super(Event, self).__setattr__(name, clean_html(clean_up_string(value))) else: super(Event, self).__setattr__(name, value) @classmethod def set_default_event_image(self, event_topic_id): if event_topic_id is None: return None else: event_topic = EventTopic.query.filter_by( id=event_topic_id).first() return event_topic.system_image_url @property def fee(self): """ Returns the fee as a percentage from 0 to 100 for this event """ return get_fee(self.payment_country, self.payment_currency) @property def maximum_fee(self): """ Returns the maximum fee for this event """ return get_maximum_fee(self.payment_country, self.payment_currency) def notification_settings(self, user_id): try: return EmailNotification.query.filter_by( user_id=(login.current_user.id if not user_id else int(user_id))). \ filter_by(event_id=self.id).first() except: return None def get_average_rating(self): avg = db.session.query(func.avg(Feedback.rating)).filter_by(event_id=self.id).scalar() if avg is not None: avg = round(avg, 2) return avg def is_payment_enabled(self): return self.can_pay_by_paypal or self.can_pay_by_stripe or self.can_pay_by_omise or self.can_pay_by_alipay \ or self.can_pay_by_cheque or self.can_pay_by_bank or self.can_pay_onsite or self.can_pay_by_paytm @property def average_rating(self): return self.get_average_rating() def get_organizer(self): """returns organizer of an event""" for role in self.roles: if role.role.name == ORGANIZER: return role.user return None def get_owner(self): """returns owner of an event""" for role in self.roles: if role.role.name == OWNER: return role.user return None def has_staff_access(self, user_id): """does user have role other than attendee""" for _ in self.roles: if _.user_id == (login.current_user.id if not user_id else int(user_id)): if _.role.name != ATTENDEE: return True return False def get_staff_roles(self): """returns only roles which are staff i.e. not attendee""" return [role for role in self.roles if role.role.name != ATTENDEE] def as_dict(self): return {c.name: getattr(self, c.name) for c in self.__table__.columns} @property def tickets_sold_object(self): obj = db.session.query(Order.event_id).filter_by(event_id=self.id, status='completed').join(TicketHolder) return obj def calc_tickets_sold_count(self): """Calculate total number of tickets sold for the event""" return self.tickets_sold_object.count() def calc_tickets_sold_prev_month(self): """Calculate tickets sold in the previous month""" previous_month = datetime.datetime.now().month - 1 return self.tickets_sold_object.filter_by(completed_at=previous_month).count() def calc_total_tickets_count(self): """Calculate total available tickets for all types of tickets""" total_available = db.session.query(func.sum(Ticket.quantity)).filter_by(event_id=self.id).scalar() if total_available is None: total_available = 0 return total_available def calc_revenue(self): """Returns total revenues of all completed orders for the given event""" revenue = db.session.query(func.sum(Order.amount)).filter_by(event_id=self.id, status='completed').scalar() if revenue is None: revenue = 0 return revenue def calc_monthly_revenue(self): """Returns revenue of current month. Invoice sent every 1st of the month for the previous month""" previous_month = datetime.now().month - 1 orders = Order.query.filter_by(event_id=self.id, status='completed').all() monthly_revenue = sum([o.amount for o in orders if o.completed_at and o.completed_at.month == previous_month]) return monthly_revenue @property def tickets_available(self): return self.calc_total_tickets_count() @property def tickets_sold(self): return self.calc_tickets_sold_count() @property def revenue(self): return self.calc_revenue() @property def has_sessions(self): return Session.query.filter_by(event_id=self.id).count() > 0 @property def has_speakers(self): return Speaker.query.filter_by(event_id=self.id).count() > 0
class Project(db.Model): __tablename__ = 'projects' name = db.Column(db.String(255), nullable=False) users = db.relationship('User', backref='projects', lazy='dynamic', passive_deletes=True)
class Order(SoftDeletionModel): __tablename__ = "orders" id = db.Column(db.Integer, primary_key=True) identifier = db.Column(db.String, unique=True, default=get_new_order_identifier) amount = db.Column(db.Float, nullable=False, default=0) address = db.Column(db.String) city = db.Column(db.String) state = db.Column(db.String) country = db.Column(db.String) zipcode = db.Column(db.String) company = db.Column(db.String) tax_business_info = db.Column(db.String) user_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='SET NULL')) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='SET NULL')) marketer_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='SET NULL')) created_at = db.Column(db.DateTime(timezone=True), default=func.now()) completed_at = db.Column(db.DateTime(timezone=True), nullable=True, default=None) trashed_at = db.Column(db.DateTime(timezone=True), nullable=True, default=None) transaction_id = db.Column(db.String) paid_via = db.Column(db.String) payment_mode = db.Column(db.String) is_billing_enabled = db.Column(db.Boolean, nullable=False, default=False) brand = db.Column(db.String) exp_month = db.Column(db.Integer) exp_year = db.Column(db.Integer) last4 = db.Column(db.String) stripe_token = db.Column(db.String) paypal_token = db.Column(db.String) status = db.Column(db.String, default='initializing') cancel_note = db.Column(db.String, nullable=True) order_notes = db.Column(db.String) tickets_pdf_url = db.Column(db.String) discount_code_id = db.Column( db.Integer, db.ForeignKey('discount_codes.id', ondelete='SET NULL'), nullable=True, default=None, ) discount_code = db.relationship('DiscountCode', backref='orders') event = db.relationship('Event', backref='orders') user = db.relationship('User', backref='orders', foreign_keys=[user_id]) invoices = db.relationship("EventInvoice", backref='invoice_order') marketer = db.relationship( 'User', backref='marketed_orders', foreign_keys=[marketer_id] ) tickets = db.relationship("Ticket", secondary='orders_tickets', backref='order') order_tickets = db.relationship("OrderTicket", backref='order') def __repr__(self): return '<Order %r>' % self.id def get_invoice_number(self): return ( 'O' + str(int(time.mktime(self.created_at.timetuple()))) + '-' + str(self.id) ) @property def invoice_number(self): return self.get_invoice_number() @property def tickets_count(self): return sum(t.quantity for t in self.order_tickets) @property def is_free(self): return self.payment_mode == 'free' def get_revenue(self): if self.amount: return self.amount - min( self.amount * (self.event.fee / 100.0), self.event.maximum_fee ) else: return 0.0 # Saves the order and generates and sends appropriate # documents and notifications def populate_and_save(self): from app.api.orders import save_order save_order(self)
class Setting(db.Model): __tablename__ = 'settings' id = db.Column(db.Integer, primary_key=True) # # General # app_environment = db.Column(db.String, default=Environment.PRODUCTION) # Name of the application. (Eg. Event Yay!, Open Event) app_name = db.Column(db.String) # Tagline for the application. (Eg. Event Management and Ticketing, Home) tagline = db.Column(db.String) # Static domain static_domain = db.Column(db.String) # Order Expiry Time in Minutes order_expiry_time = db.Column(db.Integer, default=15, nullable=False) # Maximum number of complex custom fields allowed for a given form max_complex_custom_fields = db.Column(db.Integer, default=30, nullable=False) # # STORAGE # # storage place, local, s3, .. can be more in future storage_place = db.Column(db.String) # S3 aws_key = db.Column(db.String) aws_secret = db.Column(db.String) aws_bucket_name = db.Column(db.String) aws_region = db.Column(db.String) # Google Storage gs_key = db.Column(db.String) gs_secret = db.Column(db.String) gs_bucket_name = db.Column(db.String) # # CAPTCHA # # Google reCAPTCHA is_google_recaptcha_enabled = db.Column(db.Boolean, default=False, nullable=False) google_recaptcha_site = db.Column(db.String) google_recaptcha_secret = db.Column(db.String) # # Social Login # # Google Auth google_client_id = db.Column(db.String) google_client_secret = db.Column(db.String) # FB fb_client_id = db.Column(db.String) fb_client_secret = db.Column(db.String) # Twitter tw_consumer_key = db.Column(db.String) tw_consumer_secret = db.Column(db.String) # Instagram in_client_id = db.Column(db.String) in_client_secret = db.Column(db.String) # # Payment Gateway # # Stripe Keys stripe_client_id = db.Column(db.String) stripe_secret_key = db.Column(db.String) stripe_publishable_key = db.Column(db.String) stripe_test_client_id = db.Column(db.String) stripe_test_secret_key = db.Column(db.String) stripe_test_publishable_key = db.Column(db.String) # AliPay Keys - Stripe Sources alipay_secret_key = db.Column(db.String) alipay_publishable_key = db.Column(db.String) # Paypal credentials paypal_mode = db.Column(db.String) paypal_client = db.Column(db.String) paypal_secret = db.Column(db.String) paypal_sandbox_client = db.Column(db.String) paypal_sandbox_secret = db.Column(db.String) # Omise credentials omise_mode = db.Column(db.String) omise_live_public = db.Column(db.String) omise_live_secret = db.Column(db.String) omise_test_public = db.Column(db.String) omise_test_secret = db.Column(db.String) # payTM credentials is_paytm_activated = db.Column(db.Boolean, default=False, nullable=False) paytm_mode = db.Column(db.String) paytm_live_merchant = db.Column(db.String) paytm_live_secret = db.Column(db.String) paytm_sandbox_merchant = db.Column(db.String) paytm_sandbox_secret = db.Column(db.String) # # EMAIL # # Email service. (sendgrid,smtp) email_service = db.Column(db.String) email_from = db.Column(db.String) email_from_name = db.Column(db.String) # Sendgrid sendgrid_key = db.Column(db.String) # SMTP smtp_host = db.Column(db.String) smtp_username = db.Column(db.String) smtp_password = db.Column(db.String) smtp_port = db.Column(db.Integer) smtp_encryption = db.Column(db.String) # Can be tls, ssl, none # Google Analytics analytics_key = db.Column(db.String) # # Social links # google_url = db.Column(db.String) github_url = db.Column(db.String) twitter_url = db.Column(db.String) support_url = db.Column(db.String) facebook_url = db.Column(db.String) instagram_url = db.Column(db.String) patreon_url = db.Column(db.String) gitter_url = db.Column(db.String) telegram_url = db.Column(db.String) youtube_url = db.Column(db.String) weblate_url = db.Column(db.String) # # Event Invoices settings # invoice_sending_day = db.Column(db.Integer, nullable=False, default=1) invoice_sending_timezone = db.Column(db.String, nullable=False, default="UTC") # # Admin Invoice Details # admin_billing_contact_name = db.Column(db.String) admin_billing_phone = db.Column(db.String) admin_billing_email = db.Column(db.String) admin_billing_country = db.Column(db.String) admin_billing_state = db.Column(db.String) admin_billing_tax_info = db.Column(db.String) admin_company = db.Column(db.String) admin_billing_address = db.Column(db.String) admin_billing_city = db.Column(db.String) admin_billing_zip = db.Column(db.String) admin_billing_additional_info = db.Column(db.String) admin_billing_paypal_email = db.Column(db.String) # # Generators # android_app_url = db.Column(db.String) web_app_url = db.Column(db.String) frontend_url = db.Column(db.String, default="http://eventyay.com") # # Cookie Policy # cookie_policy = db.Column( db.String, default= "This website, and certain approved third parties, use functional, " "analytical and tracking cookies (or similar technologies) to understand your " "event preferences and provide you with a customized experience. " "By closing this banner or by continuing to use the site, you agree. " "For more information please review our cookie policy.", ) cookie_policy_link = db.Column( db.String, default="https://next.eventyay.com/cookie-policy") @hybrid_property def is_paypal_activated(self): if (self.paypal_mode == 'sandbox' and self.paypal_sandbox_client and self.paypal_sandbox_secret): return True if self.paypal_client and self.paypal_secret: return True return False @hybrid_property def is_stripe_activated(self): return self.stripe_client_id is not None def __repr__(self): return 'Settings' @hybrid_property def is_alipay_activated(self): return bool(self.alipay_publishable_key and self.alipay_secret_key) @hybrid_property def is_omise_activated(self): if (self.omise_mode == 'test' and self.omise_test_public and self.omise_test_secret): return True if self.omise_live_public and self.omise_live_secret: return True return False @property def is_billing_paypal_activated(self): return self.admin_billing_paypal_email is not None def get_full_billing_address(self, sep: str = '\n') -> str: return sep.join( filter( None, [ self.admin_billing_address, self.admin_billing_city, self.admin_billing_state, self.admin_billing_zip, self.admin_billing_country, ], )) full_billing_address = property(get_full_billing_address)
class TicketHolder(SoftDeletionModel): __tablename__ = "ticket_holders" id = db.Column(db.Integer, primary_key=True) firstname = db.Column(db.String, nullable=False) lastname = db.Column(db.String, nullable=False) email = db.Column(db.String) address = db.Column(db.String) city = db.Column(db.String) state = db.Column(db.String) country = db.Column(db.String) job_title = db.Column(db.String) phone = db.Column(db.String) tax_business_info = db.Column(db.String) billing_address = db.Column(db.String) home_address = db.Column(db.String) shipping_address = db.Column(db.String) company = db.Column(db.String) work_address = db.Column(db.String) work_phone = db.Column(db.String) website = db.Column(db.String) blog = db.Column(db.String) twitter = db.Column(db.String) facebook = db.Column(db.String) github = db.Column(db.String) gender = db.Column(db.String) birth_date = db.Column(db.DateTime(timezone=True)) pdf_url = db.Column(db.String) ticket_id = db.Column(db.Integer, db.ForeignKey('tickets.id', ondelete='CASCADE')) order_id = db.Column(db.Integer, db.ForeignKey('orders.id', ondelete='CASCADE')) order = db.relationship('Order', backref='ticket_holders') ticket = db.relationship('Ticket', backref='ticket_holders') is_checked_in = db.Column(db.Boolean, default=False) is_checked_out = db.Column(db.Boolean, default=False) device_name_checkin = db.Column(db.String) checkin_times = db.Column(db.String) checkout_times = db.Column(db.String) attendee_notes = db.Column(db.String) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) user = db.relationship('User', foreign_keys=[email], primaryjoin='User.email == TicketHolder.email', viewonly=True, backref='attendees') def __init__(self, firstname=None, lastname=None, email=None, address=None, city=None, state=None, country=None, job_title=None, phone=None, tax_business_info=None, billing_address=None, home_address=None, shipping_address=None, company=None, work_address=None, work_phone=None, website=None, blog=None, twitter=None, facebook=None, github=None, gender=None, birth_date=None, ticket_id=None, is_checked_in=False, checkin_times=None, checkout_times=None, is_checked_out=False, device_name_checkin=None, attendee_notes=None, order_id=None, pdf_url=None, event_id=None, deleted_at=None): self.firstname = firstname self.lastname = lastname self.email = email self.city = city self.address = address self.state = state self.ticket_id = ticket_id self.country = country self.job_title = job_title self.phone = phone self.tax_business_info = tax_business_info self.billing_address = billing_address self.home_address = home_address self.shipping_address = shipping_address self.company = company self.work_address = work_address self.work_phone = work_phone self.website = website self.blog = blog self.twitter = twitter self.facebook = facebook self.github = github self.gender = gender self.birth_date = birth_date self.order_id = order_id self.is_checked_in = is_checked_in self.checkin_times = checkin_times self.checkout_times = checkout_times self.is_checked_out = is_checked_out self.device_name_checkin = device_name_checkin self.attendee_notes = attendee_notes self.pdf_url = pdf_url self.event_id = event_id self.deleted_at = deleted_at def __repr__(self): return '<TicketHolder %r>' % self.id def __str__(self): return self.__repr__() @property def name(self): firstname = self.firstname if self.firstname else '' lastname = self.lastname if self.lastname else '' if firstname and lastname: return u'{} {}'.format(firstname, lastname) else: return '' @property def qr_code(self): qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=0, ) qr.add_data(self.order.identifier + "-" + str(self.id)) qr.make(fit=True) img = qr.make_image() buffer = BytesIO() img.save(buffer, format="JPEG") img_str = str(base64.b64encode(buffer.getvalue()), 'utf-8') return img_str @property def serialize(self): """Return object data in easily serializable format""" return {'id': self.id, 'firstname': self.firstname, 'lastname': self.lastname, 'email': self.email, 'city': self.city, 'address': self.address, 'state': self.state, 'country': self.country, 'company': self.company, 'taxBusinessInfo': self.tax_business_info}
title = db.Column(db.String, nullable=False) content = db.Column(db.Text, nullable=True) type = db.Column(db.Integer, nullable=False) is_top = db.Column(db.Integer, nullable=False, default=0) create_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now) delete_at = db.Column(db.DateTime, nullable=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True) # 关注关系 app_user_user = db.Table( 'app_user_user', db.Column('app_user_id', db.Integer, db.ForeignKey('app_user.id'), primary_key=True), db.Column('user_id', db.Integer, db.ForeignKey('user.id'), primary_key=True), db.Column('create_at', db.DateTime, default=datetime.datetime.now)) # 用户点赞关系 thumb = db.Table( 'thumb', db.Column('app_user_id', db.Integer, db.ForeignKey('app_user.id'), primary_key=True), db.Column('recommend_id',
class User(db.Model): """ 用户数据模型 """ id = db.Column(db.Integer, autoincrement=True, primary_key=True) username = db.Column(db.String, nullable=False) password = db.Column(db.String, nullable=False) nickname = db.Column(db.String, nullable=True) sex = db.Column(db.Integer, nullable=True, default=1) email = db.Column(db.String, nullable=True) phone = db.Column(db.String, nullable=True) # 1:root、2:管理员、3:设计师 role = db.Column(db.Integer, nullable=False) parent_id = db.Column(db.Integer, nullable=False) create_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now) delete_at = db.Column(db.DateTime, nullable=True) avatar = db.relationship('Avatar', backref='user', lazy=True) notice = db.relationship('Notice', backref='user', lazy=True) recommend = db.relationship('Recommend', backref='user', lazy=True) images = db.relationship('Img', backref='user', lazy=True)
class Exhibitor(db.Model, Timestamp): class Status: PENDING = 'pending' ACCEPTED = 'accepted' STATUSES = [PENDING, ACCEPTED] __tablename__ = 'exhibitors' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False) status = db.Column(db.String, nullable=False, default=Status.PENDING, server_default=Status.PENDING) description = db.Column(db.String) url = db.Column(db.String) position = db.Column(db.Integer, nullable=False, default=0, server_default='0') logo_url = db.Column(db.String) banner_url = db.Column(db.String) thumbnail_image_url = db.Column(db.String) video_url = db.Column(db.String) slides_url = db.Column(db.String) contact_email = db.Column(db.String) contact_link = db.Column(db.String) enable_video_room = db.Column(db.Boolean, default=False, nullable=False, server_default='False') social_links = db.Column(db.JSON) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE'), nullable=False) sessions = db.relationship( 'Session', secondary=exhibitors_sessions, backref=db.backref('exhibitors', lazy='dynamic'), ) def __setattr__(self, name, value): if name == 'description': super().__setattr__(name, clean_html(clean_up_string(value))) else: super().__setattr__(name, value)
class Event(SoftDeletionModel): """Event object table""" class State: PUBLISHED = 'published' DRAFT = 'draft' class Privacy: PUBLIC = 'public' PRIVATE = 'private' __tablename__ = 'events' __versioned__ = {'exclude': ['schedule_published_on', 'created_at']} id = db.Column(db.Integer, primary_key=True) identifier = db.Column(db.String, default=get_new_event_identifier, nullable=False, unique=True) name = db.Column(db.String, nullable=False) external_event_url = db.Column(db.String) logo_url = db.Column(db.String) starts_at = db.Column(db.DateTime(timezone=True), nullable=False) ends_at = db.Column(db.DateTime(timezone=True), nullable=False) timezone = db.Column(db.String, nullable=False, default="UTC") online = db.Column(db.Boolean, nullable=False, default=False, server_default='False') latitude = db.Column(db.Float) longitude = db.Column(db.Float) location_name = db.Column(db.String) searchable_location_name = db.Column(db.String) is_featured = db.Column(db.Boolean, default=False, nullable=False) is_promoted = db.Column(db.Boolean, default=False, nullable=False) is_demoted = db.Column(db.Boolean, default=False, nullable=False) is_chat_enabled = db.Column(db.Boolean, default=False, nullable=False) is_videoroom_enabled = db.Column(db.Boolean, default=False, nullable=False) is_document_enabled = db.Column(db.Boolean, default=False, nullable=False) document_links = db.Column(JSONB) chat_room_id = db.Column(db.String) description = db.Column(db.Text) after_order_message = db.Column(db.Text) original_image_url = db.Column(db.String) thumbnail_image_url = db.Column(db.String) large_image_url = db.Column(db.String) show_remaining_tickets = db.Column(db.Boolean, default=False, nullable=False) icon_image_url = db.Column(db.String) owner_name = db.Column(db.String) is_map_shown = db.Column(db.Boolean) is_oneclick_signup_enabled = db.Column(db.Boolean) has_owner_info = db.Column(db.Boolean) owner_description = db.Column(db.String) is_sessions_speakers_enabled = db.Column(db.Boolean, default=False) is_cfs_enabled = db.Column(db.Boolean, default=False, nullable=False, server_default='False') track = db.relationship('Track', backref="event") microlocation = db.relationship('Microlocation', backref="event") session = db.relationship('Session', backref="event") speaker = db.relationship('Speaker', backref="event") sponsor = db.relationship('Sponsor', backref="event") exhibitors = db.relationship('Exhibitor', backref="event") tickets = db.relationship('Ticket', backref="event_") tags = db.relationship('TicketTag', backref='events') roles = db.relationship("UsersEventsRoles", backref="event") role_invites = db.relationship('RoleInvite', back_populates='event') custom_form = db.relationship('CustomForms', backref="event") faqs = db.relationship('Faq', backref="event") feedbacks = db.relationship('Feedback', backref="event") attendees = db.relationship('TicketHolder', backref="event") privacy = db.Column(db.String, default="public") state = db.Column(db.String, default="draft") event_type_id = db.Column( db.Integer, db.ForeignKey('event_types.id', ondelete='CASCADE')) event_topic_id = db.Column( db.Integer, db.ForeignKey('event_topics.id', ondelete='CASCADE')) event_sub_topic_id = db.Column( db.Integer, db.ForeignKey('event_sub_topics.id', ondelete='CASCADE')) group_id = db.Column(db.Integer, db.ForeignKey('groups.id', ondelete='SET NULL')) is_announced = db.Column(db.Boolean, default=False, nullable=False, server_default='False') ticket_url = db.Column(db.String) db.UniqueConstraint('track.name') code_of_conduct = db.Column(db.String) schedule_published_on = db.Column(db.DateTime(timezone=True)) is_ticketing_enabled = db.Column(db.Boolean, default=False) is_donation_enabled = db.Column(db.Boolean, default=False) is_ticket_form_enabled = db.Column(db.Boolean, default=True, nullable=False) payment_country = db.Column(db.String) payment_currency = db.Column(db.String) paypal_email = db.Column(db.String) is_tax_enabled = db.Column(db.Boolean, default=False) is_billing_info_mandatory = db.Column(db.Boolean, default=False, nullable=False) can_pay_by_paypal = db.Column(db.Boolean, default=False, nullable=False, server_default='False') can_pay_by_stripe = db.Column(db.Boolean, default=False, nullable=False, server_default='False') can_pay_by_cheque = db.Column(db.Boolean, default=False, nullable=False, server_default='False') can_pay_by_bank = db.Column(db.Boolean, default=False, nullable=False, server_default='False') can_pay_by_invoice = db.Column(db.Boolean, default=False, nullable=False, server_default='False') can_pay_onsite = db.Column(db.Boolean, default=False, nullable=False, server_default='False') can_pay_by_omise = db.Column(db.Boolean, default=False, nullable=False, server_default='False') can_pay_by_alipay = db.Column(db.Boolean, default=False, nullable=False, server_default='False') can_pay_by_paytm = db.Column(db.Boolean, default=False, nullable=False, server_default='False') cheque_details = db.Column(db.String) bank_details = db.Column(db.String) onsite_details = db.Column(db.String) invoice_details = db.Column(db.String) created_at = db.Column(db.DateTime(timezone=True), default=func.now()) pentabarf_url = db.Column(db.String) ical_url = db.Column(db.String) xcal_url = db.Column(db.String) is_sponsors_enabled = db.Column(db.Boolean, default=False) refund_policy = db.Column(db.String) is_stripe_linked = db.Column(db.Boolean, default=False) completed_order_sales = db.Column(db.Integer) placed_order_sales = db.Column(db.Integer) pending_order_sales = db.Column(db.Integer) completed_order_tickets = db.Column(db.Integer) placed_order_tickets = db.Column(db.Integer) pending_order_tickets = db.Column(db.Integer) discount_code_id = db.Column( db.Integer, db.ForeignKey('discount_codes.id', ondelete='CASCADE')) discount_code = db.relationship('DiscountCode', backref='events', foreign_keys=[discount_code_id]) event_type = db.relationship('EventType', backref='event', foreign_keys=[event_type_id]) event_topic = db.relationship('EventTopic', backref='event', foreign_keys=[event_topic_id]) event_sub_topic = db.relationship('EventSubTopic', backref='event', foreign_keys=[event_sub_topic_id]) group = db.relationship('Group', backref='events', foreign_keys=[group_id]) owner = db.relationship( 'User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "owner"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='owner_events', sync_backref=False, uselist=False, ) organizers = db.relationship( 'User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "organizer"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='organizer_events', sync_backref=False, ) coorganizers = db.relationship( 'User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "coorganizer"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='coorganizer_events', sync_backref=False, ) track_organizers = db.relationship( 'User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id,' ' Role.name == "track_organizer"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='track_organizer_events', sync_backref=False, ) registrars = db.relationship( 'User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "registrar"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='registrar_events', sync_backref=False, ) moderators = db.relationship( 'User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id, Role.name == "moderator"))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='moderator_events', sync_backref=False, ) # staff users = db.relationship( 'User', viewonly=True, secondary='join(UsersEventsRoles, Role,' ' and_(Role.id == UsersEventsRoles.role_id))', primaryjoin='UsersEventsRoles.event_id == Event.id', secondaryjoin='User.id == UsersEventsRoles.user_id', backref='events', sync_backref=False, ) def __init__(self, **kwargs): super().__init__(**kwargs) original_image_url = kwargs.get('original_image_url') self.original_image_url = (self.set_default_event_image( kwargs.get('event_topic_id')) if original_image_url is None else original_image_url) # TODO(Areeb): Test for cleaning up of these on __init__ self.description = clean_up_string(kwargs.get('description')) self.owner_description = clean_up_string( kwargs.get('owner_description')) self.code_of_conduct = clean_up_string(kwargs.get('code_of_conduct')) self.after_order_message = clean_up_string( kwargs.get('after_order_message')) def __repr__(self): return '<Event %r>' % self.name def __setattr__(self, name, value): allow_link = name == 'description' or 'owner_description' or 'after_order_message' if (name == 'owner_description' or name == 'description' or name == 'code_of_conduct' or name == 'after_order_message'): super().__setattr__( name, clean_html(clean_up_string(value), allow_link=allow_link)) else: super().__setattr__(name, value) @classmethod def set_default_event_image(cls, event_topic_id): if event_topic_id is None: return None event_topic = EventTopic.query.filter_by(id=event_topic_id).first() return event_topic.system_image_url @property def fee(self): """ Returns the fee as a percentage from 0 to 100 for this event """ return get_fee(self.payment_country, self.payment_currency) @property def maximum_fee(self): """ Returns the maximum fee for this event """ return get_maximum_fee(self.payment_country, self.payment_currency) def notification_settings(self, user_id): try: return (EmailNotification.query.filter_by( user_id=(login.current_user.id if not user_id else int(user_id) )).filter_by(event_id=self.id).first()) except: return None def get_average_rating(self): avg = (db.session.query(func.avg( Feedback.rating)).filter_by(event_id=self.id).scalar()) if avg is not None: avg = round(avg, 2) return avg def is_payment_enabled(self): return (self.can_pay_by_paypal or self.can_pay_by_stripe or self.can_pay_by_omise or self.can_pay_by_alipay or self.can_pay_by_cheque or self.can_pay_by_bank or self.can_pay_onsite or self.can_pay_by_paytm or self.can_pay_by_invoice) @property def average_rating(self): return self.get_average_rating() def get_owner(self): """returns owner of an event""" for role in self.roles: if role.role.name == Role.OWNER: return role.user return None def as_dict(self): return {c.name: getattr(self, c.name) for c in self.__table__.columns} @property def tickets_sold_object(self): obj = (db.session.query(Order.event_id).filter_by( event_id=self.id, status='completed').join(TicketHolder)) return obj def calc_tickets_sold_count(self): """Calculate total number of tickets sold for the event""" return self.tickets_sold_object.count() def calc_tickets_sold_prev_month(self): """Calculate tickets sold in the previous month""" previous_month = datetime.now().month - 1 return self.tickets_sold_object.filter_by( completed_at=previous_month).count() def calc_total_tickets_count(self): """Calculate total available tickets for all types of tickets""" total_available = (db.session.query(func.sum( Ticket.quantity)).filter_by(event_id=self.id).scalar()) if total_available is None: total_available = 0 return total_available def get_orders_query(self, start=None, end=None): query = Order.query.filter_by(event_id=self.id, status='completed') if start: query = query.filter(Order.completed_at > start) if end: query = query.filter(Order.completed_at < end) return query def calc_revenue(self, start=None, end=None): """Returns total revenues of all completed orders for the given event""" return (self.get_orders_query(start=start, end=end).with_entities( func.sum(Order.amount)).scalar() or 0) @property def chat_room_name(self): return re.sub('[^0-9a-zA-Z!]', '-', self.name) + '-' + self.identifier @property def tickets_available(self): return self.calc_total_tickets_count() @property def tickets_sold(self): return self.calc_tickets_sold_count() @property def revenue(self): return self.calc_revenue() @property def has_sessions(self): return Session.query.filter_by(event_id=self.id).count() > 0 @property def has_speakers(self): return Speaker.query.filter_by(event_id=self.id).count() > 0 @property def order_statistics(self): return Namespace(id=self.id) @property def general_statistics(self): return Namespace(id=self.id) @property def site_link(self): frontend_url = get_settings()['frontend_url'] return f"{frontend_url}/e/{self.identifier}" @property def organizer_site_link(self): frontend_url = get_settings()['frontend_url'] return f"{frontend_url}/events/{self.identifier}" @property def starts_at_tz(self): return self.starts_at.astimezone(pytz.timezone(self.timezone)) @property def ends_at_tz(self): return self.ends_at.astimezone(pytz.timezone(self.timezone)) @property def normalized_location(self): if self.location_name: return self.location_name elif self.online: return self.site_link return 'Location Not Announced' @property def event_location_status(self): if self.online: return 'Online (Please login to the platform to access the video room on the event page)' elif self.location_name: return self.location_name else: return 'Location Not Announced' @property def has_coordinates(self): return self.latitude and self.longitude @property def safe_video_stream(self): """Conditionally return video stream after applying access control""" stream = self.video_stream if stream and stream.user_can_access: return stream return None @property def notify_staff(self): """Who receive notifications about event""" return self.organizers + [self.owner]
from sqlalchemy_utils import generic_repr from app.models import db from app.models.helpers.timestamp import Timestamp from app.models.helpers.versioning import clean_html, clean_up_string exhibitors_sessions = db.Table( 'exhibitors_sessions', db.Column('session_id', db.Integer, db.ForeignKey('sessions.id', ondelete='CASCADE')), db.Column('exhibitor_id', db.Integer, db.ForeignKey('exhibitors.id', ondelete='CASCADE')), db.PrimaryKeyConstraint('session_id', 'exhibitor_id'), ) @generic_repr class Exhibitor(db.Model, Timestamp): class Status: PENDING = 'pending' ACCEPTED = 'accepted' STATUSES = [PENDING, ACCEPTED] __tablename__ = 'exhibitors' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False) status = db.Column(db.String, nullable=False, default=Status.PENDING,
class Session(SoftDeletionModel): """Session model class""" __tablename__ = 'sessions' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String, nullable=False) subtitle = db.Column(db.String) short_abstract = db.Column(db.Text, default='') long_abstract = db.Column(db.Text, default='') comments = db.Column(db.Text) language = db.Column(db.String) level = db.Column(db.String) starts_at = db.Column(db.DateTime(timezone=True)) ends_at = db.Column(db.DateTime(timezone=True)) track_id = db.Column(db.Integer, db.ForeignKey('tracks.id', ondelete='CASCADE')) microlocation_id = db.Column( db.Integer, db.ForeignKey('microlocations.id', ondelete='CASCADE')) session_type_id = db.Column( db.Integer, db.ForeignKey('session_types.id', ondelete='CASCADE')) speakers = db.relationship( 'Speaker', secondary=speakers_sessions, backref=db.backref('sessions', lazy='dynamic'), ) feedbacks = db.relationship('Feedback', backref="session") slides_url = db.Column(db.String) video_url = db.Column(db.String) audio_url = db.Column(db.String) signup_url = db.Column(db.String) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) creator_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE')) state = db.Column(db.String, default="pending") created_at = db.Column(db.DateTime(timezone=True), default=sql_func.now()) submitted_at = db.Column(db.DateTime(timezone=True)) submission_modifier = db.Column(db.String) is_mail_sent = db.Column(db.Boolean, default=False) last_modified_at = db.Column(db.DateTime(timezone=True), default=func.now()) send_email = db.Column(db.Boolean, nullable=True) is_locked = db.Column(db.Boolean, default=False, nullable=False) complex_field_values = db.Column(db.JSON) @staticmethod def get_service_name(): return 'session' @property def is_accepted(self): return self.state == "accepted" def get_average_rating(self): avg = (db.session.query(func.avg( Feedback.rating)).filter_by(session_id=self.id).scalar()) if avg is not None: avg = round(avg, 2) return avg @property def average_rating(self): return self.get_average_rating() @property def site_link(self): return self.event.site_link + f"/session/{self.id}" def __repr__(self): return '<Session %r>' % self.title def __setattr__(self, name, value): if name == 'short_abstract' or name == 'long_abstract' or name == 'comments': super().__setattr__(name, clean_html(clean_up_string(value))) else: super().__setattr__(name, value)
import datetime import pytz from sqlalchemy import event, func from sqlalchemy.sql import func as sql_func from app.models import db from app.models.base import SoftDeletionModel from app.models.feedback import Feedback from app.models.helpers.versioning import clean_html, clean_up_string speakers_sessions = db.Table( 'speakers_sessions', db.Column('speaker_id', db.Integer, db.ForeignKey('speaker.id', ondelete='CASCADE')), db.Column('session_id', db.Integer, db.ForeignKey('sessions.id', ondelete='CASCADE')), db.PrimaryKeyConstraint('speaker_id', 'session_id'), ) class Session(SoftDeletionModel): """Session model class""" __tablename__ = 'sessions' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String, nullable=False) subtitle = db.Column(db.String) short_abstract = db.Column(db.Text, default='') long_abstract = db.Column(db.Text, default='') comments = db.Column(db.Text)
class DiscountCode(db.Model): __tablename__ = "discount_codes" id = db.Column(db.Integer, primary_key=True) code = db.Column(db.String, nullable=False) discount_url = db.Column(db.String) value = db.Column(db.Float, nullable=False) type = db.Column(db.String, nullable=False) is_active = db.Column(db.Boolean, default=True) tickets_number = db.Column(db.Integer) min_quantity = db.Column(db.Integer, default=1) max_quantity = db.Column(db.Integer, default=100) valid_from = db.Column(db.DateTime(timezone=True), nullable=True) valid_till = db.Column(db.DateTime(timezone=True), nullable=True) tickets = db.Column(db.String) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) event = db.relationship('Event', backref='discount_codes', foreign_keys=[event_id]) created_at = db.Column(db.DateTime(timezone=True)) marketer_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE')) marketer = db.relationship('User', backref='discount_codes_') used_for = db.Column(db.String, nullable=False) def __init__(self, code=None, discount_url=None, value=None, type=None, tickets_number=None, min_quantity=None, max_quantity=None, valid_from=None, valid_till=None, is_active=True, used_for=None, event_id=None, tickets=None, user_id=None): self.code = code self.discount_url = discount_url self.type = type self.value = value self.tickets_number = tickets_number self.min_quantity = min_quantity self.max_quantity = max_quantity self.valid_from = valid_from self.valid_till = valid_till self.event_id = event_id self.is_active = is_active self.created_at = datetime.utcnow() self.used_for = used_for self.tickets = tickets self.marketer_id = user_id @staticmethod def get_service_name(): return 'discount_code' def __repr__(self): return '<DiscountCode %r>' % self.id def __str__(self): return unicode(self).encode('utf-8') def __unicode__(self): return self.code @property def serialize(self): """Return object data in easily serializable format""" return { 'id': self.id, 'code': self.code, 'discount_url': self.discount_url, 'value': self.value, 'type': self.type, 'tickets_number': self.tickets_number, 'min_quantity': self.min_quantity, 'max_quantity': self.max_quantity, 'used_for': self.used_for, 'valid_from': self.valid_from, 'valid_till': self.valid_till, 'event_id': self.event_id, 'is_active': self.is_active }
class Client(db.Model): __tablename__ = 'clients' client_id = db.Column(db.Integer, primary_key=True) passport_number = db.Column(db.Integer, nullable=False) passport_series = db.Column(db.Integer, nullable=False) first_name = db.Column(db.String(32), nullable=False) last_name = db.Column(db.String(32), nullable=False) middle_name = db.Column(db.String(32), nullable=True) email = db.Column(db.String(32), nullable=True) phone = db.Column(db.String(11), nullable=False) """ Список контрактов у клиента многие-ко-одному """ contracts = db.relationship('Contract', backref='client', lazy='dynamic') fields = { 'passport_number': not None, 'passport_series': not None, 'last_name': not None, 'first_name': not None, 'middle_name': None, 'email': None, 'phone': not None } # Преобразование объекта Client в словарь def to_dict(self): data = { 'id': self.client_id, 'attributes': { 'passport_number': self.passport_number, 'passport_series': self.passport_series, 'last_name': self.last_name, 'first_name': self.first_name, 'middle_name': self.middle_name or None, 'email': self.email or None, 'phone': self.phone, 'name': ' '.join([self.last_name, self.first_name, self.middle_name or '']) } } return data # Преобразование списка объектов типа Client в список словарей @staticmethod def to_dict_list(list_data): new_data = [ { 'id': data.client_id, 'attributes': { 'passport_number': data.passport_number, 'passport_series': data.passport_series, 'last_name': data.last_name, 'first_name': data.first_name, 'middle_name': data.middle_name or None, 'email': data.email or None, 'phone': data.phone, 'name': ' '.join([data.last_name, data.first_name, data.middle_name or '']) } } for data in list_data] return new_data # Извлечение доступных not null данных из словаря в объект типа Client def from_dict(self, data): for field in self.fields: # Пихаем значение, если оно не None и относиться к нашим полям, либо если оно None и поле может быть таким if field in data: if data[field] is not None: setattr(self, field, data[field]) elif data[field] is None and self.fields[field] is None: setattr(self, field, data[field]) def __repr__(self): return "<Client № {}>".format(self.client_id)
from app.models import db roles_panels = db.Table( 'roles_panels', db.Column('role_id', db.Integer, db.ForeignKey('custom_sys_roles.id', ondelete='CASCADE')), db.Column( 'panel_permission_id', db.Integer, db.ForeignKey('panel_permissions.id', ondelete='CASCADE'), ), ) class PanelPermission(db.Model): """Super-Admin Panel Permissions """ __tablename__ = 'panel_permissions' id = db.Column(db.Integer, primary_key=True) # Super Admin panel name panel_name = db.Column(db.String) # Custom System Role custom_system_roles = db.relationship( 'CustomSysRole', secondary=roles_panels, backref=db.backref('panel_permissions', lazy='dynamic'), ) can_access = db.Column(db.Boolean)
class User(SoftDeletionModel): """User model class""" __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True, autoincrement=True) _email = db.Column(db.String(120), unique=True, nullable=False) _password = db.Column(db.String(128), nullable=False) facebook_id = db.Column(db.BigInteger, unique=True, nullable=True, name='facebook_id') facebook_login_hash = db.Column(db.String, nullable=True) reset_password = db.Column(db.String(128)) salt = db.Column(db.String(128)) avatar_url = db.Column(db.String) tokens = db.Column(db.Text) first_name = db.Column(db.String, nullable=True) last_name = db.Column(db.String, nullable=True) details = db.Column(db.String) contact = db.Column(db.String) facebook_url = db.Column(db.String) twitter_url = db.Column(db.String) instagram_url = db.Column(db.String) google_plus_url = db.Column(db.String) original_image_url = db.Column(db.String, nullable=True, default=None) thumbnail_image_url = db.Column(db.String) small_image_url = db.Column(db.String) icon_image_url = db.Column(db.String) is_super_admin = db.Column(db.Boolean, default=False) is_admin = db.Column(db.Boolean, default=False) is_sales_admin = db.Column(db.Boolean, default=False) is_marketer = db.Column(db.Boolean, default=False) is_verified = db.Column(db.Boolean, default=False) was_registered_with_order = db.Column(db.Boolean, default=False) last_accessed_at = db.Column(db.DateTime(timezone=True)) created_at = db.Column(db.DateTime(timezone=True), default=func.now()) speaker = db.relationship('Speaker', backref="user") favourite_events = db.relationship('UserFavouriteEvent', backref="user") session = db.relationship('Session', backref="user") feedback = db.relationship('Feedback', backref="user") access_codes = db.relationship('AccessCode', backref="user") discount_codes = db.relationship('DiscountCode', backref="user") marketer_events = db.relationship( 'Event', viewonly=True, secondary='join(UserSystemRole, CustomSysRole,' ' and_(CustomSysRole.id == UserSystemRole.role_id, CustomSysRole.name == "Marketer"))', primaryjoin='UserSystemRole.user_id == User.id', secondaryjoin='Event.id == UserSystemRole.event_id' ) sales_admin_events = db.relationship( 'Event', viewonly=True, secondary='join(UserSystemRole, CustomSysRole,' ' and_(CustomSysRole.id == UserSystemRole.role_id, CustomSysRole.name == "Sales Admin"))', primaryjoin='UserSystemRole.user_id == User.id', secondaryjoin='Event.id == UserSystemRole.event_id') @hybrid_property def password(self): """ Hybrid property for password :return: """ return self._password @password.setter def password(self, password): """ Setter for _password, saves hashed password, salt and reset_password string :param password: :return: """ salt = str(generate_random_salt(), 'utf-8') self._password = str(generate_password_hash(password, salt), 'utf-8') hash_ = random.getrandbits(128) self.reset_password = str(hash_) self.salt = salt @hybrid_property def email(self): """ Hybrid property for email :return: """ return self._email @email.setter def email(self, email): """ Setter for _email, set user to 'not verified' if email is updated :param email: :return: """ if self._email != email: self._email = email self.is_verified = False # User Permissions def can_publish_event(self): """ Checks if User can publish an event """ perm = UserPermission.query.filter_by(name='publish_event').first() if not perm: return self.is_verified if self.is_verified is False: return perm.unverified_user return True def can_create_event(self): """ Checks if User can create an event """ perm = UserPermission.query.filter_by(name='create_event').first() if not perm: return self.is_verified if self.is_verified is False: return perm.unverified_user return True def has_role(self, event_id): """ Checks if user has any of the Roles at an Event. Exclude Attendee Role. """ attendee_role = Role.query.filter_by(name=ATTENDEE).first() uer = UER.query.filter(UER.user == self, UER.event_id == event_id, UER.role != attendee_role).first() if uer is None: return False else: return True def _is_role(self, role_name, event_id=None): """ Checks if a user has a particular Role at an Event. """ role = Role.query.filter_by(name=role_name).first() if event_id: uer = UER.query.filter_by(user=self, event_id=event_id, role=role).first() else: uer = UER.query.filter_by(user=self, role=role).first() if not uer: return False else: return True def is_organizer(self, event_id): # type: (object) -> object return self._is_role(ORGANIZER, event_id) def is_coorganizer(self, event_id): return self._is_role(COORGANIZER, event_id) def is_track_organizer(self, event_id): return self._is_role(TRACK_ORGANIZER, event_id) def is_moderator(self, event_id): return self._is_role(MODERATOR, event_id) def is_registrar(self, event_id): return self._is_role(REGISTRAR, event_id) def is_attendee(self, event_id): return self._is_role(ATTENDEE, event_id) @hybrid_property def is_user_organizer(self): # type: (object) -> object return self._is_role(ORGANIZER) @hybrid_property def is_user_coorganizer(self): return self._is_role(COORGANIZER) @hybrid_property def is_user_track_organizer(self): return self._is_role(TRACK_ORGANIZER) @hybrid_property def is_user_moderator(self): return self._is_role(MODERATOR) @hybrid_property def is_user_registrar(self): return self._is_role(REGISTRAR) @hybrid_property def is_user_attendee(self): return self._is_role(ATTENDEE) def _has_perm(self, operation, service_class, event_id): # Operation names and their corresponding permission in `Permissions` operations = { 'create': 'can_create', 'read': 'can_read', 'update': 'can_update', 'delete': 'can_delete', } if operation not in list(operations.keys()): raise ValueError('No such operation defined') try: service_name = service_class.get_service_name() except AttributeError: # If `service_class` does not have `get_service_name()` return False if self.is_super_admin: return True service = Service.query.filter_by(name=service_name).first() uer_querylist = UER.query.filter_by(user=self, event_id=event_id) for uer in uer_querylist: role = uer.role perm = Permission.query.filter_by(role=role, service=service).first() if getattr(perm, operations[operation]): return True return False def can_create(self, service_class, event_id): return self._has_perm('create', service_class, event_id) def can_read(self, service_class, event_id): return self._has_perm('read', service_class, event_id) def can_update(self, service_class, event_id): return self._has_perm('update', service_class, event_id) def can_delete(self, service_class, event_id): return self._has_perm('delete', service_class, event_id) def is_speaker_at_session(self, session_id): try: session = Session.query.filter(Session.speakers.any(Speaker.user_id == self.id)).filter( Session.id == session_id).one() if session: return True else: return False except MultipleResultsFound: return False except NoResultFound: return False def is_speaker_at_event(self, event_id): try: session = Session.query.filter(Session.speakers.any(Speaker.user_id == self.id)).filter( Session.event_id == event_id).first() if session: return True else: return False except MultipleResultsFound: return False except NoResultFound: return False # Flask-Login integration def is_authenticated(self): return True def is_active(self): return True def is_anonymous(self): return False def get_id(self): return self.id def is_correct_password(self, password): salt = self.salt password = str(generate_password_hash(password, salt), 'utf-8') if password == self._password: return True return False @property def is_staff(self): return self.is_super_admin or self.is_admin def is_sys_role(self, role_id): """ Check if a user has a Custom System Role assigned. `role_id` is id of a `CustomSysRole` instance. """ role = UserSystemRole.query.filter_by(user=self, role_id=role_id).first() return bool(role) def first_access_panel(self): """ Check if the user is assigned a Custom Role or not This checks if there is an entry containing the current user in the `user_system_roles` table returns panel name if exists otherwise false """ custom_role = UserSystemRole.query.filter_by(user=self).first() if not custom_role: return False perm = PanelPermission.query.filter(PanelPermission.custom_system_roles.any(id=custom_role.role_id)).first() if not perm: return False return perm.panel_name def can_download_tickets(self, order): permissible_users = [holder.id for holder in order.ticket_holders] + [order.user.id] if self.is_staff or self.is_organizer(order.event.id) or self.id in permissible_users: return True return False def can_access_panel(self, panel_name): """ Check if user can access an Admin Panel """ if self.is_staff: return True custom_sys_roles = UserSystemRole.query.filter_by(user=self) for custom_role in custom_sys_roles: if custom_role.role.can_access(panel_name): return True return False def get_unread_notif_count(self): return get_count(Notification.query.filter_by(user=self, is_read=False)) def get_unread_notifs(self): """ Get unread notifications with titles, humanized receiving time and Mark-as-read links. """ notifs = [] unread_notifs = Notification.query.filter_by(user=self, is_read=False).order_by( desc(Notification.received_at)) for notif in unread_notifs: notifs.append({ 'title': notif.title, 'received_at': humanize.naturaltime(datetime.now(pytz.utc) - notif.received_at), 'mark_read': url_for('notifications.mark_as_read', notification_id=notif.id) }) return notifs # update last access time def update_lat(self): self.last_accessed_at = datetime.now(pytz.utc) @property def fullname(self): firstname = self.first_name if self.first_name else '' lastname = self.last_name if self.last_name else '' if firstname and lastname: return '{} {}'.format(firstname, lastname) else: return '' def __repr__(self): return '<User %r>' % self.email def __str__(self): return self.__repr__() def __setattr__(self, name, value): if name == 'details': super(User, self).__setattr__(name, clean_html(clean_up_string(value))) else: super(User, self).__setattr__(name, value)
class AppUpdate(db.Model): class Type(IntEnum): GRAY = 1 NORMAL = 2 app_id = db.Column(db.Integer, nullable=False, index=True) app_version_id = db.Column(db.Integer, nullable=False, index=True) is_force = db.Column(db.Boolean, nullable=False, default=0) # selector condtions # car_id in ["1", "2", "3"] or region_name == "shanghai" conditions = db.Column(db.String(2048), nullable=True) type = db.Column(db.SmallInteger, nullable=False, default=Type.NORMAL) app_version = db.relationship( AppVersion, uselist=False, primaryjoin="foreign(AppUpdate.app_version_id) == remote(AppVersion.id)", back_populates="updates", ) def to_dict(self, params): result = { "is_force": self.is_force, "need_update": True, "version": self.app_version.version, "version_code": str(self.app_version.version_code), "update_type": self.type, } if params.get("lang") == Language.CN.value: update_text_json = self.app_version.update_text else: update_text_json = self.app_version.update_text_en update_text = json.loads(update_text_json) result.update(update_text) if self.app_version.is_patch: result["patch_url"] = self.app_version.package_url result["patch_md5"] = self.app_version.package_md5 result["patch_size"] = self.app_version.package_size else: result["update_url"] = self.app_version.package_url result["package_md5"] = self.app_version.package_md5 result["package_size"] = self.app_version.package_size # misc result["pacakge_id"] = 0 result["version_id"] = 0 if self.is_force: result["update_type"] = 3 return result def can_update(self, query: dict) -> bool: """Determine if the update suitable for this query.""" version = self.app_version # Currently we check the version_code only # later there will be more conditions, such as car_id, region. if version.version_code <= query["version_code"]: return False return True
class CustomForms(db.Model): """custom form model class""" __tablename__ = 'custom_forms' __table_args__ = (UniqueConstraint('event_id', 'field_identifier', 'form', name='custom_form_identifier'), ) id = db.Column(db.Integer, primary_key=True) field_identifier = db.Column(db.String, nullable=False) form = db.Column(db.String, nullable=False) type = db.Column(db.String, nullable=False) name = db.Column(db.String, nullable=False) description = db.Column(db.String, nullable=True) is_required = db.Column(db.Boolean, default=False) is_included = db.Column(db.Boolean, default=False) is_fixed = db.Column(db.Boolean, default=False) is_complex = db.Column(db.Boolean, nullable=False, default=False) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) custom_form_options = db.relationship('CustomFormOptions', backref="custom_form") @property def identifier(self): return to_snake_case(self.field_identifier) def __repr__(self): return f'<CustomForm {self.id!r} {self.identifier!r}>'
class Tax(db.Model): """ Copyright Information about an event. """ __tablename__ = 'tax' id = db.Column(db.Integer, primary_key=True) country = db.Column(db.String) name = db.Column(db.String, nullable=False) rate = db.Column(db.Float, nullable=False) tax_id = db.Column(db.String, nullable=False) should_send_invoice = db.Column(db.Boolean, default=False) registered_company = db.Column(db.String) address = db.Column(db.String) city = db.Column(db.String) state = db.Column(db.String) zip = db.Column(db.Integer) invoice_footer = db.Column(db.String) is_tax_included_in_price = db.Column(db.Boolean, default=False) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) event = db.relationship('Event', backref=backref('tax', uselist=False)) def __init__(self, country=None, name=None, rate=None, tax_id=None, should_send_invoice=None, registered_company=None, address=None, city=None, state=None, zip=None, invoice_footer=None, is_tax_included_in_price=None, event_id=None): self.country = country self.name = name self.rate = rate self.tax_id = tax_id self.should_send_invoice = should_send_invoice self.registered_company = registered_company self.address = address self.city = city self.state = state self.zip = zip self.invoice_footer = invoice_footer self.is_tax_included_in_price = is_tax_included_in_price self.event_id = event_id def __repr__(self): return '<Tax %r>' % self.name def __str__(self): return unicode(self).encode('utf-8') def __unicode__(self): return self.name @property def serialize(self): """Return object data in easily serializable format""" return { 'id': self.id, 'country': self.country, 'name': self.name, 'rate': self.rate, 'tax_id': self.tax_id, 'should_send_invoice': self.should_send_invoice, 'registered_company': self.registered_company, 'address': self.address, 'city': self.city, 'state': self.state, 'zip': self.zip, 'invoice_footer': self.invoice_footer, 'is_tax_included_in_price': self.is_tax_included_in_price }
class MessageSettings(db.Model): __tablename__ = 'message_settings' id = db.Column(db.Integer, primary_key=True) action = db.Column(db.String) mail_status = db.Column(db.Boolean, default=False) notification_status = db.Column(db.Boolean, default=False) user_control_status = db.Column(db.Boolean, default=False) sent_at = db.Column(db.DateTime(timezone=True)) def __init__(self, action=None, mail_status=None, notification_status=None, user_control_status=None): self.action = action self.mail_status = mail_status self.notification_status = notification_status self.user_control_status = user_control_status self.sent_at = datetime.now(pytz.utc) def __repr__(self): return '<Message Setting %r >' % self.action def __str__(self): return self.__repr__() @classmethod def _email_message(self, action, attr=None): message = {} if action in [INVITE_PAPERS, NEW_SESSION, USER_CONFIRM, USER_REGISTER, PASSWORD_RESET, EVENT_ROLE, SESSION_ACCEPT_REJECT, SESSION_SCHEDULE, NEXT_EVENT, EVENT_PUBLISH, AFTER_EVENT, USER_CHANGE_EMAIL, USER_REGISTER_WITH_PASSWORD, TICKET_PURCHASED, EVENT_EXPORTED, EVENT_EXPORT_FAIL, MAIL_TO_EXPIRED_ORDERS, MONTHLY_PAYMENT_EMAIL, MONTHLY_PAYMENT_FOLLOWUP_EMAIL, EVENT_IMPORTED, EVENT_IMPORT_FAIL, TICKET_PURCHASED_ORGANIZER, TICKET_CANCELLED, TICKET_PURCHASED_ATTENDEE, PASSWORD_CHANGE]: message = MAILS[action] else: message = MAILS.__dict__[action] message = str(message.get(attr)) return message @hybrid_property def email_message(self): message = self._email_message(self.action, attr='message') return message @hybrid_property def recipient(self): message = self._email_message(self.action, attr='recipient') return message @hybrid_property def email_subject(self): message = self._email_message(self.action, attr='subject') return message @classmethod def _notification_message(self, action, attr=None): message = {} if action in [EVENT_ROLE, NEW_SESSION, SESSION_SCHEDULE, NEXT_EVENT, SESSION_ACCEPT_REJECT, INVITE_PAPERS, AFTER_EVENT, EVENT_PUBLISH, USER_CHANGE_EMAIL, PASSWORD_CHANGE, TICKET_PURCHASED, TICKET_RESEND_ORGANIZER, EVENT_EXPORT_FAIL, EVENT_EXPORTED, EVENT_IMPORT_FAIL, EVENT_IMPORTED, MONTHLY_PAYMENT_NOTIF, MONTHLY_PAYMENT_FOLLOWUP_NOTIF, TICKET_PURCHASED_ORGANIZER, TICKET_PURCHASED_ATTENDEE, TICKET_CANCELLED, TICKET_CANCELLED_ORGANIZER]: message = NOTIFS[action] else: message = NOTIFS.__dict__[action] message = str(message.get(attr)) return message @hybrid_property def notification_message(self): message = self._notification_message(self.action, attr='message') return message @hybrid_property def notification_title(self): message = self._notification_message(self.action, attr='title') return message @property def serialize(self): """Return object data in easily serializable format""" return {'id': self.id, 'action': self.action, 'mail_status': self.mail_status, 'notification_status': self.notification_status, 'user_control_status': self.user_control_status}
class TicketHolder(SoftDeletionModel): __tablename__ = "ticket_holders" id: int = db.Column(db.Integer, primary_key=True) firstname: str = db.Column(db.String, nullable=False) lastname: str = db.Column(db.String, nullable=False) email: str = db.Column(db.String) address: str = db.Column(db.String) city: str = db.Column(db.String) state: str = db.Column(db.String) country: str = db.Column(db.String) job_title: str = db.Column(db.String) phone: str = db.Column(db.String) tax_business_info: str = db.Column(db.String) billing_address: str = db.Column(db.String) home_address: str = db.Column(db.String) shipping_address: str = db.Column(db.String) company: str = db.Column(db.String) work_address: str = db.Column(db.String) work_phone: str = db.Column(db.String) website: str = db.Column(db.String) blog: str = db.Column(db.String) twitter: str = db.Column(db.String) facebook: str = db.Column(db.String) github: str = db.Column(db.String) gender: str = db.Column(db.String) age_group: str = db.Column(db.String) birth_date: datetime = db.Column(db.DateTime(timezone=True)) pdf_url: str = db.Column(db.String) ticket_id: int = db.Column(db.Integer, db.ForeignKey('tickets.id', ondelete='CASCADE'), nullable=False) order_id: int = db.Column(db.Integer, db.ForeignKey('orders.id', ondelete='CASCADE')) is_checked_in: bool = db.Column(db.Boolean, default=False) is_checked_out: bool = db.Column(db.Boolean, default=False) device_name_checkin: str = db.Column(db.String) checkin_times: str = db.Column(db.String) checkout_times: str = db.Column(db.String) attendee_notes: str = db.Column(db.String) event_id: int = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE'), nullable=False) created_at: datetime = db.Column(db.DateTime(timezone=True), default=datetime.utcnow) modified_at: datetime = db.Column(db.DateTime(timezone=True), default=datetime.utcnow, onupdate=datetime.utcnow) complex_field_values: str = db.Column(db.JSON) user = db.relationship( 'User', foreign_keys=[email], primaryjoin='User.email == TicketHolder.email', viewonly=True, backref='attendees', ) order = db.relationship('Order', backref='ticket_holders') ticket = db.relationship('Ticket', backref='ticket_holders') @property def name(self): firstname = self.firstname if self.firstname else '' lastname = self.lastname if self.lastname else '' if firstname and lastname: return u'{} {}'.format(firstname, lastname) else: return '' @property def qr_code(self): qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=0, ) qr.add_data(self.order.identifier + "-" + str(self.id)) qr.make(fit=True) img = qr.make_image() buffer = BytesIO() img.save(buffer, format="JPEG") img_str = str(base64.b64encode(buffer.getvalue()), 'utf-8') return img_str @property def serialize(self): """Return object data in easily serializable format""" return { 'id': self.id, 'firstname': self.firstname, 'lastname': self.lastname, 'email': self.email, 'city': self.city, 'address': self.address, 'state': self.state, 'country': self.country, 'company': self.company, 'taxBusinessInfo': self.tax_business_info, }
class Tax(SoftDeletionModel): """ Tax Information about an event. """ id = db.Column(db.Integer, primary_key=True) country = db.Column(db.String) name = db.Column(db.String, nullable=False) rate = db.Column(db.Float, nullable=False) tax_id = db.Column(db.String, nullable=False) should_send_invoice = db.Column(db.Boolean, default=False) registered_company = db.Column(db.String) contact_name = db.Column(db.String) phone = db.Column(db.String) email = db.Column(db.String) address = db.Column(db.String) city = db.Column(db.String) state = db.Column(db.String) zip = db.Column(db.String) invoice_footer = db.Column(db.String) is_tax_included_in_price = db.Column(db.Boolean, default=False) is_invoice_sent = db.Column(db.Boolean, default=False) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) event = db.relationship('Event', backref=backref('tax', uselist=False)) def __repr__(self): return '<Tax %r>' % self.name
class AccessCode(SoftDeletionModel): __tablename__ = "access_codes" id = db.Column(db.Integer, primary_key=True) code = db.Column(db.String) access_url = db.Column(db.String) is_active = db.Column(db.Boolean) tickets_number = db.Column( db.Integer) # For event level access this holds the max. uses min_quantity = db.Column(db.Integer) max_quantity = db.Column( db.Integer ) # For event level access this holds the months for which it is valid valid_from = db.Column(db.DateTime(timezone=True), nullable=True) valid_till = db.Column(db.DateTime(timezone=True), nullable=True) ticket_id = db.Column(db.Integer, db.ForeignKey('tickets.id', ondelete='CASCADE')) ticket = db.relationship('Ticket', backref='access_code', foreign_keys=[ticket_id]) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) event = db.relationship('Event', backref='access_codes', foreign_keys=[event_id]) created_at = db.Column(db.DateTime(timezone=True)) marketer_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE')) marketer = db.relationship('User', backref='access_codes_') def __init__(self, code=None, access_url=None, tickets_number=None, min_quantity=None, max_quantity=None, valid_from=None, valid_till=None, is_active=True, used_for=None, event_id=None, user_id=None, deleted_at=None): self.code = code self.access_url = access_url self.tickets_number = tickets_number self.min_quantity = min_quantity self.max_quantity = max_quantity self.valid_from = valid_from self.valid_till = valid_till self.event_id = event_id self.is_active = is_active self.created_at = datetime.utcnow() self.used_for = used_for self.marketer_id = user_id self.deleted_at = deleted_at @staticmethod def get_service_name(): return 'access_code' def __repr__(self): return '<AccessCode %r>' % self.code def __str__(self): return self.__repr__() @property def serialize(self): """Return object data in easily serializable format""" return { 'id': self.id, 'code': self.code, 'access_url': self.access_url, 'tickets_number': self.tickets_number, 'min_quantity': self.min_quantity, 'max_quantity': self.max_quantity, 'used_for': self.used_for, 'valid_from': self.valid_from, 'valid_till': self.valid_till, 'event_id': self.event_id, 'is_active': self.is_active }
from app.models import db from app.models.base import SoftDeletionModel from app.models.order import OrderTicket, Order access_codes_tickets = db.Table('access_codes_tickets', db.Column('access_code_id', db.Integer, db.ForeignKey( 'access_codes.id', ondelete='CASCADE')), db.Column('ticket_id', db.Integer, db.ForeignKey('tickets.id', ondelete='CASCADE')), db.PrimaryKeyConstraint('access_code_id', 'ticket_id')) discount_codes_tickets = db.Table( 'discount_codes_tickets', db.Column('discount_code_id', db.Integer, db.ForeignKey('discount_codes.id', ondelete='CASCADE')), db.Column('ticket_id', db.Integer, db.ForeignKey('tickets.id', ondelete='CASCADE')), db.PrimaryKeyConstraint('discount_code_id', 'ticket_id')) ticket_tags_table = db.Table('association', db.Model.metadata, db.Column('ticket_id', db.Integer, db.ForeignKey('tickets.id', ondelete='CASCADE')), db.Column('ticket_tag_id', db.Integer, db.ForeignKey('ticket_tag.id', ondelete='CASCADE')) ) class Ticket(SoftDeletionModel): __tablename__ = 'tickets' __table_args__ = (db.UniqueConstraint('name', 'event_id', name='name_event_uc'),) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False) description = db.Column(db.String) is_description_visible = db.Column(db.Boolean) type = db.Column(db.String, nullable=False)
class AccessCode(SoftDeletionModel): __tablename__ = "access_codes" id: int = db.Column(db.Integer, primary_key=True) code: str = db.Column(db.String) access_url: str = db.Column(db.String) is_active: bool = db.Column(db.Boolean) tickets_number: int = db.Column( db.Integer ) # For event level access this holds the max. uses min_quantity: int = db.Column(db.Integer) max_quantity: int = db.Column( db.Integer ) # For event level access this holds the months for which it is valid valid_from: datetime = db.Column(db.DateTime(timezone=True), nullable=True) valid_till: datetime = db.Column(db.DateTime(timezone=True), nullable=True) ticket_id: int = db.Column( db.Integer, db.ForeignKey('tickets.id', ondelete='CASCADE') ) event_id: int = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) created_at: datetime = db.Column(db.DateTime(timezone=True), default=func.now()) marketer_id: int = db.Column( db.Integer, db.ForeignKey('users.id', ondelete='CASCADE') ) marketer = db.relationship('User', backref='access_codes_') ticket = db.relationship('Ticket', backref='access_code', foreign_keys=[ticket_id]) event = db.relationship('Event', backref='access_codes', foreign_keys=[event_id]) @staticmethod def get_service_name(): return 'access_code'
class Ticket(SoftDeletionModel): __tablename__ = 'tickets' __table_args__ = (db.UniqueConstraint('name', 'event_id', name='name_event_uc'),) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False) description = db.Column(db.String) is_description_visible = db.Column(db.Boolean) type = db.Column(db.String, nullable=False) quantity = db.Column(db.Integer) position = db.Column(db.Integer) price = db.Column(db.Float) min_price = db.Column(db.Float, default=0, nullable=False) max_price = db.Column(db.Float) is_fee_absorbed = db.Column(db.Boolean) sales_starts_at = db.Column(db.DateTime(timezone=True), nullable=False) sales_ends_at = db.Column(db.DateTime(timezone=True), nullable=False) is_hidden = db.Column(db.Boolean) min_order = db.Column(db.Integer) max_order = db.Column(db.Integer) is_checkin_restricted = db.Column(db.Boolean) auto_checkin_enabled = db.Column(db.Boolean) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) event = db.relationship('Event', backref='tickets_') tags = db.relationship('TicketTag', secondary=ticket_tags_table, backref='tickets') order_ticket = db.relationship('OrderTicket', backref="ticket", passive_deletes=True) access_codes = db.relationship('AccessCode', secondary=access_codes_tickets, backref='tickets') discount_codes = db.relationship('DiscountCode', secondary=discount_codes_tickets, backref="tickets") def __init__(self, name=None, event_id=None, type=None, sales_starts_at=None, sales_ends_at=None, is_hidden=False, description=None, is_description_visible=True, is_checkin_restricted=True, auto_checkin_enabled=False, quantity=100, position=1, price=0, min_order=1, max_order=10, min_price=0, max_price=0, is_fee_absorbed=False, tags=[], access_codes=[], discount_codes=[]): self.name = name self.quantity = quantity self.position = position self.type = type self.event_id = event_id self.description = description self.is_description_visible = is_description_visible self.is_checkin_restricted = is_checkin_restricted self.auto_checkin_enabled = auto_checkin_enabled self.price = price self.min_price = min_price self.max_price = max_price self.sales_starts_at = sales_starts_at self.sales_ends_at = sales_ends_at self.is_hidden = is_hidden self.min_order = min_order self.max_order = max_order self.tags = tags self.is_fee_absorbed = is_fee_absorbed self.access_codes = access_codes self.discount_codes = discount_codes def has_order_tickets(self): """Returns True if ticket has already placed orders. Else False. """ from app.api.helpers.db import get_count orders = Order.id.in_(OrderTicket.query.with_entities(OrderTicket.order_id).filter_by(ticket_id=self.id).all()) count = get_count(Order.query.filter(orders).filter(Order.status != 'deleted')) # Count is zero if no completed orders are present return bool(count > 0) def has_completed_order_tickets(self): """Returns True if ticket has already placed orders. Else False. """ order_tickets = OrderTicket.query.filter_by(ticket_id=self.id) count = 0 for order_ticket in order_tickets: order = Order.query.filter_by(id=order_ticket.order_id).first() if order.status == "completed" or order.status == "placed": count += 1 return bool(count > 0) def tags_csv(self): """Return list of Tags in CSV. """ tag_names = [tag.name for tag in self.tags] return ','.join(tag_names) def __repr__(self): return '<Ticket %r>' % self.name def __str__(self): return self.__repr__() @property def serialize(self): """Return object data in easily serializable format""" data = { 'id': self.id, 'name': self.name, 'quantity': self.quantity, 'position': self.position, 'type': self.type, 'description_visibility': self.is_description_visible, 'description': self.description, 'price': self.price, 'sales_start_date': self.sales_starts_at.strftime('%m/%d/%Y') if self.sales_starts_at else '', 'sales_starts_at': self.sales_starts_at.strftime('%H:%M') if self.sales_starts_at else '', 'sales_end_date': self.sales_ends_at.strftime('%m/%d/%Y') if self.sales_ends_at else '', 'sales_ends_at': self.sales_ends_at.strftime('%H:%M') if self.sales_ends_at else '', 'ticket_visibility': self.hide, 'min_order': self.min_order, 'max_order': self.max_order, 'tags_string': '', 'has_orders': self.has_order_tickets(), 'has_completed_orders': self.has_completed_order_tickets(), 'is_fee_absorbed': self.is_fee_absorbed } tags = [] for tag in self.tags: tags.append(tag.name) data['tags'] = ",".join(tags) return data
class HeatDensityLauModel(db.Model): __tablename__ = 'heat_tot_curr_density_tif_lau' __table_args__ = ( db.ForeignKeyConstraint(['fk_lau_gid'], ['public.lau.gid']), {"schema": 'stat'} ) CRS = 3035 id = db.Column(db.Integer, primary_key=True) comm_id = db.Column(db.String(14)) count = db.Column(db.BigInteger) sum = db.Column(db.Numeric(precision=30, scale=10)) mean = db.Column(db.Numeric(precision=30, scale=10)) median = db.Column(db.Numeric(precision=30, scale=10)) min = db.Column(db.Numeric(precision=30, scale=10)) max = db.Column(db.Numeric(precision=30, scale=10)) std = db.Column(db.Numeric(precision=30, scale=10)) variance = db.Column(db.Numeric(precision=30, scale=10)) range = db.Column(db.Numeric(precision=30, scale=10)) fk_lau_gid = db.Column(db.BigInteger) #fk_time_id = db.Column(db.BigInteger) lau = db.relationship("Lau") #time = db.relationship("Time") def __repr__(self): return "<HeatDensityLau(comm_id='%s', year='%s', sum='%d', lau='%s')>" % \ (self.comm_id, self.time.year, self.sum, str(self.lau))
from app.models import db store_workingday = db.Table( 'store_workingday', db.Column('store_id', db.Integer, db.ForeignKey('store.id'), primary_key=True), db.Column('workingday_id', db.Integer, db.ForeignKey('workingday.id'), primary_key=True))