Repository: fossasia/open-event-server

Issue:
Duration fields for sessions shouldn't be mandatory
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
Currently `starts-at` and `ends-at` fields are mandatory for sessions. They shouldn't be required so that the organizer can organize their timings conveniently in scheduler and also bring sessions out from the calendar and place them in the unscheduled section.

**To Reproduce**
Steps to reproduce the behavior:
1. Try to create a session with these fields unspecified

**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
Sessions should get created without specifying these fields.

**Additional context**
<!-- Add any other context about the problem here. -->
Needed for scheduler implementation.


Discussion:

Resolving patch:
diff --git a/app/api/schema/sessions.py b/app/api/schema/sessions.py
--- a/app/api/schema/sessions.py
+++ b/app/api/schema/sessions.py
@@ -39,8 +39,10 @@ def validate_date(self, data, original_data):
             if 'event' not in data:
                 data['event'] = session.event_id
 
-        if data['starts_at'] >= data['ends_at']:
-            raise UnprocessableEntity({'pointer': '/data/attributes/ends-at'}, "ends-at should be after starts-at")
+        if data['starts_at'] and data['ends_at']:
+            if data['starts_at'] >= data['ends_at']:
+                raise UnprocessableEntity(
+                    {'pointer': '/data/attributes/ends-at'}, "ends-at should be after starts-at")
 
         if 'state' in data:
             if data['state'] is not 'draft' or not 'pending':
@@ -62,8 +64,8 @@ def validate_date(self, data, original_data):
     short_abstract = fields.Str(allow_none=True)
     long_abstract = fields.Str(allow_none=True)
     comments = fields.Str(allow_none=True)
-    starts_at = fields.DateTime(required=True)
-    ends_at = fields.DateTime(required=True)
+    starts_at = fields.DateTime(allow_none=True)
+    ends_at = fields.DateTime(allow_none=True)
     language = fields.Str(allow_none=True)
     slides_url = fields.Url(allow_none=True)
     video_url = fields.Url(allow_none=True)
diff --git a/app/models/session.py b/app/models/session.py
--- a/app/models/session.py
+++ b/app/models/session.py
@@ -28,8 +28,8 @@ class Session(SoftDeletionModel):
     comments = db.Column(db.Text)
     language = db.Column(db.String)
     level = db.Column(db.String)
-    starts_at = db.Column(db.DateTime(timezone=True), nullable=False)
-    ends_at = db.Column(db.DateTime(timezone=True), nullable=False)
+    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'))
diff --git a/migrations/versions/8a3de7c8b6d5_.py b/migrations/versions/8a3de7c8b6d5_.py
new file mode 100644
--- /dev/null
+++ b/migrations/versions/8a3de7c8b6d5_.py
@@ -0,0 +1,38 @@
+"""empty message
+
+Revision ID: 8a3de7c8b6d5
+Revises: 55fd4c6ae8b2
+Create Date: 2018-08-06 23:44:16.489323
+
+"""
+
+from alembic import op
+import sqlalchemy as sa
+import sqlalchemy_utils
+from sqlalchemy.dialects import postgresql
+
+# revision identifiers, used by Alembic.
+revision = '8a3de7c8b6d5'
+down_revision = '55fd4c6ae8b2'
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.alter_column('sessions', 'ends_at',
+               existing_type=postgresql.TIMESTAMP(timezone=True),
+               nullable=True)
+    op.alter_column('sessions', 'starts_at',
+               existing_type=postgresql.TIMESTAMP(timezone=True),
+               nullable=True)
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.alter_column('sessions', 'starts_at',
+               existing_type=postgresql.TIMESTAMP(timezone=True),
+               nullable=False)
+    op.alter_column('sessions', 'ends_at',
+               existing_type=postgresql.TIMESTAMP(timezone=True),
+               nullable=False)
+    # ### end Alembic commands ###


Test patch: