Repository: fossasia/open-event-server

Issue:
Inconsistent Model and API docs for Access code.
**Describe the bug**
The defined model and the API docs differ for Access code.

##### API docs
Parameter | Description | Type | Required
-- | -- | -- | --
code | Access Code | string | -
access-url | URL of the access code | string | -
type | Amount or Percentage | string | -
is-active | If the access code is active | boolean | -
tickets-number | Tickets Number for Access Code | integer (>=0) | -
min-quantity | Minimum number of tickets for Access Code | integer (>=0) | -
max-quantity | Maximum number of tickets for Access Code | integer (>=0) | -
valid-from | Access Code valid from | ISO 8601 (tz-aware) | -
valid-till | Access Code valid till | ISO 8601 (tz-aware) | -
created-at | Access Code created at | ISO 8601 (tz-aware) | -
tickets | Event or Ticket | String | -
used-for | Access Code used for | String | -


##### Server
``` Python
    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)
    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_')

    used_for = db.Column(db.String)
```
1. ```type```: Mentioned in the API docs but absent in the model.
2. ```tickets``` is also absent in the model. Moreover it's use is not very clear.

**Expected behavior**
There shouldn't be differences.


Discussion:
Yes, 
`type` is in API docs but neither in Access Code Schema nor Model.
`tickets` relationship is there in Schema but not model.
Should I add it ?
you can add the tickets in the model but i am not sure about why we need ```type``` in the access_code. I think the docs for Access code were copied from Discount code and type which should have been deleted, wasn't. 
@poush @niranjan94 @SaptakS Why do we need a ```type```("amount" or "percentage") in access_code ?
@srv-twry Yes, your point is right
@srv-twry 
> you can add the tickets in the model 

Even that is not required 
> tickets is also absent in the model. Moreover it's use is not very clear.

Use is Required as Access Code is having One to many relationship to Tickets. 
See this file : https://github.com/fossasia/open-event-server/blob/development/app/models/ticket.py#LC42
`tickets` should be added in the model as their use is not ambiguous now.
@schedutron @bhaveshAn @mayank8318 What is ```tickets-number``` ? Any idea ?
Asking this because an access-code can be related to more than one ticket.

Update: Got it. 
> Use is Required as Access Code is having One to many relationship to Tickets.

Actually it's a many to many relationship(http://flask-sqlalchemy.pocoo.org/2.3/models/#many-to-many-relationships) but fair point.

Resolving patch:
diff --git a/app/api/schema/access_codes.py b/app/api/schema/access_codes.py
--- a/app/api/schema/access_codes.py
+++ b/app/api/schema/access_codes.py
@@ -5,8 +5,10 @@
 from app.api.helpers.exceptions import UnprocessableEntity
 from app.api.helpers.utilities import dasherize
 from app.models.access_code import AccessCode
+from utils.common import use_defaults
 
 
+@use_defaults()
 class AccessCodeSchema(Schema):
     """
     Api schema for Access Code Model
@@ -61,7 +63,7 @@ def validate_order_quantity(self, data, original_data):
                                           "tickets-number should be greater than max-quantity")
 
     id = fields.Integer(dump_ony=True)
-    code = fields.Str(allow_none=True)
+    code = fields.Str(required=True)
     access_url = fields.Url(allow_none=True)
     is_active = fields.Boolean(default=False)
 
@@ -72,7 +74,6 @@ def validate_order_quantity(self, data, original_data):
     max_quantity = fields.Integer(validate=lambda n: n >= 0, allow_none=True)
     valid_from = fields.DateTime(required=True)
     valid_till = fields.DateTime(required=True)
-    used_for = fields.Str(allow_none=True)
     event = Relationship(attribute='event',
                          self_view='v1.access_code_event',
                          self_view_kwargs={'id': '<id>'},
diff --git a/app/models/access_code.py b/app/models/access_code.py
--- a/app/models/access_code.py
+++ b/app/models/access_code.py
@@ -24,8 +24,6 @@ class AccessCode(db.Model):
     marketer_id = db.Column(db.Integer, db.ForeignKey('users.id', ondelete='CASCADE'))
     marketer = db.relationship('User', backref='access_codes_')
 
-    used_for = db.Column(db.String)
-
     def __init__(self,
                  code=None,
                  access_url=None,
diff --git a/migrations/versions/caf96244e10b_.py b/migrations/versions/caf96244e10b_.py
new file mode 100644
--- /dev/null
+++ b/migrations/versions/caf96244e10b_.py
@@ -0,0 +1,28 @@
+"""empty message
+
+Revision ID: caf96244e10b
+Revises: 4cac94c86047
+Create Date: 2018-05-24 22:52:38.381505
+
+"""
+
+from alembic import op
+import sqlalchemy as sa
+import sqlalchemy_utils
+
+
+# revision identifiers, used by Alembic.
+revision = 'caf96244e10b'
+down_revision = '4cac94c86047'
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_column('access_codes', 'used_for')
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.add_column('access_codes', sa.Column('used_for', sa.VARCHAR(), autoincrement=False, nullable=True))
+    # ### end Alembic commands ###


Test patch: