Repository: fossasia/open-event-server

Issue:
Add additional optional fields to Attendee API that can be added via custom forms.
Related issue: #3595

Following additional fields are to be added in the Attendee API. Whether the field is required or included in the frontend form can be set using the CustomForm API.
 
* [ ] Job Title
* [ ] Email Address
* [ ] Phone
* [ ] Mobile Phone
* [ ] Tax & Business Info
* [ ] Billing Address
* [ ] Home Address
* [ ] Shipping Address
* [ ] Company / Organization
* [ ] Work Address
* [ ] Work Phone
* [ ] Website
* [ ] Blog
* [ ] Twitter
* [ ] Facebook
* [ ] Main Git Repository
* [ ] Gender
* [ ] Birth Date



Discussion:

Resolving patch:
diff --git a/app/api/schema/attendees.py b/app/api/schema/attendees.py
--- a/app/api/schema/attendees.py
+++ b/app/api/schema/attendees.py
@@ -26,6 +26,23 @@ class Meta:
     city = fields.Str(allow_none=True)
     state = fields.Str(allow_none=True)
     country = fields.Str(allow_none=True)
+    job_title = fields.Str(allow_none=True)
+    phone = fields.Str(allow_none=True)
+    tax_business_info = fields.Str(allow_none=True)
+    billing_address = fields.Str(allow_none=True)
+    home_address = fields.Str(allow_none=True)
+    shipping_address = fields.Str(allow_none=True)
+    company = fields.Str(allow_none=True)
+    work_address = fields.Str(allow_none=True)
+    work_phone = fields.Str(allow_none=True)
+    website = fields.Url(allow_none=True)
+    blog = fields.Url(allow_none=True)
+    twitter = fields.Url(allow_none=True)
+    facebook = fields.Url(allow_none=True)
+    github = fields.Url(allow_none=True)
+    gender = fields.Str(allow_none=True)
+    birth_date = fields.DateTime(allow_none=True)
+
     ticket_id = fields.Str(allow_none=True)
     is_checked_in = fields.Boolean()
     pdf_url = fields.Url(required=True)
diff --git a/app/models/ticket_holder.py b/app/models/ticket_holder.py
--- a/app/models/ticket_holder.py
+++ b/app/models/ticket_holder.py
@@ -17,6 +17,22 @@ class TicketHolder(db.Model):
     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, nullable=False)
     ticket_id = db.Column(db.Integer, db.ForeignKey('tickets.id', ondelete='CASCADE'))
     order_id = db.Column(db.Integer, db.ForeignKey('orders.id', ondelete='CASCADE'))
@@ -35,6 +51,22 @@ def __init__(self,
                  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,
                  order_id=None,
@@ -48,6 +80,22 @@ def __init__(self,
         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.pdf_url = pdf_url
diff --git a/migrations/versions/b4fdb245fccd_.py b/migrations/versions/b4fdb245fccd_.py
new file mode 100644
--- /dev/null
+++ b/migrations/versions/b4fdb245fccd_.py
@@ -0,0 +1,58 @@
+"""empty message
+
+Revision ID: b4fdb245fccd
+Revises: 4c7f86bbed3d
+Create Date: 2017-08-22 13:38:37.526669
+
+"""
+
+from alembic import op
+import sqlalchemy as sa
+import sqlalchemy_utils
+
+
+# revision identifiers, used by Alembic.
+revision = 'b4fdb245fccd'
+down_revision = '4c7f86bbed3d'
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.add_column('ticket_holders', sa.Column('billing_address', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('birth_date', sa.DateTime(timezone=True), nullable=True))
+    op.add_column('ticket_holders', sa.Column('blog', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('company', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('facebook', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('gender', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('github', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('home_address', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('job_title', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('phone', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('shipping_address', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('tax_business_info', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('twitter', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('website', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('work_address', sa.String(), nullable=True))
+    op.add_column('ticket_holders', sa.Column('work_phone', sa.String(), nullable=True))
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_column('ticket_holders', 'work_phone')
+    op.drop_column('ticket_holders', 'work_address')
+    op.drop_column('ticket_holders', 'website')
+    op.drop_column('ticket_holders', 'twitter')
+    op.drop_column('ticket_holders', 'tax_business_info')
+    op.drop_column('ticket_holders', 'shipping_address')
+    op.drop_column('ticket_holders', 'phone')
+    op.drop_column('ticket_holders', 'job_title')
+    op.drop_column('ticket_holders', 'home_address')
+    op.drop_column('ticket_holders', 'github')
+    op.drop_column('ticket_holders', 'gender')
+    op.drop_column('ticket_holders', 'facebook')
+    op.drop_column('ticket_holders', 'company')
+    op.drop_column('ticket_holders', 'blog')
+    op.drop_column('ticket_holders', 'birth_date')
+    op.drop_column('ticket_holders', 'billing_address')
+    # ### end Alembic commands ###


Test patch: