From ef65940d14fdf15cdf6400d001a6e559a11b3dd2 Mon Sep 17 00:00:00 2001 From: CosmicCoder96 Date: Wed, 21 Aug 2019 22:56:50 -0400 Subject: [PATCH] feat: create custom_form_options api --- app/api/__init__.py | 10 +++- app/api/custom_form_options.py | 46 +++++++++++++++++++ app/api/schema/custom_form_options.py | 32 +++++++++++++ app/api/schema/custom_forms.py | 2 + app/models/custom_form.py | 17 +++++-- app/models/custom_form_option.py | 23 ++++++++++ .../rev-2019-08-24-20:32:00-ebfe89366d48_.py | 38 +++++++++++++++ 7 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 app/api/custom_form_options.py create mode 100644 app/api/schema/custom_form_options.py create mode 100644 app/models/custom_form_option.py create mode 100644 migrations/versions/rev-2019-08-24-20:32:00-ebfe89366d48_.py diff --git a/app/api/__init__.py b/app/api/__init__.py index fcdc67d4db..0ba26b2fa7 100644 --- a/app/api/__init__.py +++ b/app/api/__init__.py @@ -16,6 +16,7 @@ AttendeeRelationshipRequired, AttendeeListPost from app.api.bootstrap import api from app.api.custom_forms import CustomFormList, CustomFormListPost, CustomFormDetail, CustomFormRelationshipRequired +from app.api.custom_form_options import CustomFormOptionList, CustomFormOptionDetail, CustomFormOptionRelationship from app.api.custom_placeholders import CustomPlaceholderList, CustomPlaceholderDetail, CustomPlaceholderRelationship from app.api.custom_system_roles import CustomSystemRoleList, CustomSystemRoleDetail, CustomSystemRoleRelationship from app.api.discount_codes import DiscountCodeList, DiscountCodeDetail, DiscountCodeRelationshipOptional, \ @@ -575,10 +576,17 @@ api.route(CustomFormListPost, 'custom_form_list_post', '/custom-forms') api.route(CustomFormList, 'custom_form_list', '/events//custom-forms', '/events//custom-forms') -api.route(CustomFormDetail, 'custom_form_detail', '/custom-forms/') +api.route(CustomFormDetail, 'custom_form_detail', '/custom-forms/', + '/custom-form-options//custom-form') api.route(CustomFormRelationshipRequired, 'custom_form_event', '/custom-forms//relationships/event') +# custom form options +api.route(CustomFormOptionList, 'custom_form_option_list', '/custom-forms//custom-form-options') +api.route(CustomFormOptionDetail, 'custom_form_option_detail', '/custom-form-options/') +api.route(CustomFormOptionRelationship, 'custom_form_option_form', + '/custom-form-options//relationships/custom-form') + # FAQ api.route(FaqListPost, 'faq_list_post', '/faqs') api.route(FaqList, 'faq_list', '/events//faqs', '/events//faqs', diff --git a/app/api/custom_form_options.py b/app/api/custom_form_options.py new file mode 100644 index 0000000000..53e73ff623 --- /dev/null +++ b/app/api/custom_form_options.py @@ -0,0 +1,46 @@ +from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship +from app.models import db +from app.api.schema.custom_form_options import CustomFormOptionSchema +from app.models.custom_form_option import CustomFormOptions + + +class CustomFormOptionList(ResourceList): + """ + Create and List Custom Form Options + """ + + def query(self, view_kwargs): + query_ = self.session.query(CustomFormOptions) + if view_kwargs.get('custom_form_id'): + query_ = self.session.query(CustomFormOptions).filter( + getattr(CustomFormOptions, 'custom_form_id') == view_kwargs['custom_form_id']) + return query_ + + schema = CustomFormOptionSchema + data_layer = {'session': db.session, + 'model': CustomFormOptions, + 'methods': { + 'query': query + }} + + +class CustomFormOptionDetail(ResourceDetail): + """ + CustomForm Resource + """ + + schema = CustomFormOptionSchema + data_layer = {'session': db.session, + 'model': CustomFormOptions + } + + +class CustomFormOptionRelationship(ResourceRelationship): + """ + CustomForm Resource + """ + + schema = CustomFormOptionSchema + data_layer = {'session': db.session, + 'model': CustomFormOptions + } diff --git a/app/api/schema/custom_form_options.py b/app/api/schema/custom_form_options.py new file mode 100644 index 0000000000..0b0c1d3ef2 --- /dev/null +++ b/app/api/schema/custom_form_options.py @@ -0,0 +1,32 @@ +from marshmallow_jsonapi import fields +from marshmallow_jsonapi.flask import Relationship + +from app.api.helpers.utilities import dasherize +from app.api.schema.base import SoftDeletionSchema +from utils.common import use_defaults + + +@use_defaults() +class CustomFormOptionSchema(SoftDeletionSchema): + """ + API Schema for Custom Forms database model + """ + + class Meta: + """ + Meta class for CustomForm Schema + """ + type_ = 'custom-form-option' + self_view = 'v1.custom_form_option_detail' + self_view_kwargs = {'id': ''} + inflect = dasherize + + id = fields.Integer(dump_only=True) + value = fields.Str(required=True) + custom_form = Relationship(attribute='custom_form', + self_view='v1.custom_form_option_form', + self_view_kwargs={'id': ''}, + related_view='v1.custom_form_detail', + related_view_kwargs={'custom_form_option_id': ''}, + schema='CustomFormSchema', + type_='custom_form') diff --git a/app/api/schema/custom_forms.py b/app/api/schema/custom_forms.py index 2427d69056..eba296238a 100644 --- a/app/api/schema/custom_forms.py +++ b/app/api/schema/custom_forms.py @@ -27,8 +27,10 @@ class Meta: type = fields.Str(default="text", validate=validate.OneOf( choices=["text", "checkbox", "select", "file", "image", "email", "number"])) + description = fields.Str(allow_none=True) is_required = fields.Boolean(default=False) is_included = fields.Boolean(default=False) + is_complex = fields.Boolean(default=False) is_fixed = fields.Boolean(default=False) event = Relationship(attribute='event', self_view='v1.custom_form_event', diff --git a/app/models/custom_form.py b/app/models/custom_form.py index 07e149d098..729b45074a 100644 --- a/app/models/custom_form.py +++ b/app/models/custom_form.py @@ -73,27 +73,34 @@ class CustomForms(SoftDeletionModel): field_identifier = db.Column(db.String, nullable=False) form = db.Column(db.String, nullable=False) type = db.Column(db.String, nullable=False) + description = db.Column(db.String, nullable=True) is_required = db.Column(db.Boolean) is_included = db.Column(db.Boolean) is_fixed = db.Column(db.Boolean) + is_complex = db.Column(db.Boolean) event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='CASCADE')) + custom_form_options = db.relationship('CustomFormOptions', backref="custom_form") def __init__(self, event_id=None, field_identifier=None, form=None, type=None, - is_required=None, - is_included=None, - is_fixed=None, + description=None, + is_required=False, + is_included=False, + is_fixed=False, + is_complex=False, deleted_at=None): self.event_id = event_id self.field_identifier = field_identifier self.form = form self.type = type + self.description = description self.is_required = is_required self.is_included = is_included self.is_fixed = is_fixed + self.is_complex = is_complex self.deleted_at = deleted_at def __repr__(self): @@ -111,7 +118,9 @@ def serialize(self): 'field_identifier': self.field_identifier, 'form': self.form, 'type': self.type, + 'description': self.description, 'is_required': self.is_required, 'is_included': self.is_included, - 'is_fixed': self.is_fixed + 'is_fixed': self.is_fixed, + 'is_complex': self.is_complex } diff --git a/app/models/custom_form_option.py b/app/models/custom_form_option.py new file mode 100644 index 0000000000..f9f32a21c4 --- /dev/null +++ b/app/models/custom_form_option.py @@ -0,0 +1,23 @@ +from app.models import db +from app.models.base import SoftDeletionModel + + +class CustomFormOptions(SoftDeletionModel): + __tablename__ = 'custom_form_options' + id = db.Column(db.Integer, primary_key=True) + value = db.Column(db.String, nullable=False) + custom_form_id = db.Column(db.Integer, db.ForeignKey('custom_forms.id', ondelete='CASCADE')) + + def __init__(self, + custom_form_id=None, + deleted_at=None, + value=None): + self.custom_form_id = custom_form_id + self.value = value + self.deleted_at = deleted_at + + def __repr__(self): + return '' % self.id + + def __str__(self): + return self.__repr__() diff --git a/migrations/versions/rev-2019-08-24-20:32:00-ebfe89366d48_.py b/migrations/versions/rev-2019-08-24-20:32:00-ebfe89366d48_.py new file mode 100644 index 0000000000..3c13311e3f --- /dev/null +++ b/migrations/versions/rev-2019-08-24-20:32:00-ebfe89366d48_.py @@ -0,0 +1,38 @@ +"""empty message + +Revision ID: ebfe89366d48 +Revises: 90d62fe3b5e3 +Create Date: 2019-08-24 20:32:00.535676 + +""" + +from alembic import op +import sqlalchemy as sa + +# revision identifiers, used by Alembic. +revision = 'ebfe89366d48' +down_revision = '90d62fe3b5e3' + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('custom_form_options', + sa.Column('deleted_at', sa.DateTime(timezone=True), nullable=True), + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('value', sa.String(), nullable=False), + sa.Column('custom_form_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['custom_form_id'], ['custom_forms.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + op.add_column('custom_forms', sa.Column('description', sa.String(), nullable=True)) + op.add_column('custom_forms', sa.Column('is_complex', sa.Boolean(), nullable=False, server_default='False')) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('custom_forms', 'is_complex') + op.drop_column('custom_forms', 'description') + op.drop_table('custom_form_options') + # ### end Alembic commands ###