Repository: fossasia/open-event-server

Issue:
Filter upcoming events on the basis of their end date and time.
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
Currently the events are being filtered on the basis of end date only. If an event is single day event of 2hrs, then the vent will get removed from upcoming events on the next day. The event should not be shown in upcoming events if it is over.

**To Reproduce**
Steps to reproduce the behaviour:
1. Create an event.
2. Set event start time and end time for a small period.
3. After the event is over, it is still shown in upcoming events.

**Expected behaviour**
<!-- A clear and concise description of what you expected to happen. -->
Once the event is over, it should not be shown in the upcoming events or browse events.

**Screenshots**
<!-- If applicable, add screenshots to help explain your problem. -->
![Screenshot from 2019-04-15 18-05-18](https://user-images.githubusercontent.com/21174572/56133009-10f34180-5fa9-11e9-93b6-58a7cecaba9d.png)

![Screenshot from 2019-04-15 18-05-11](https://user-images.githubusercontent.com/21174572/56133010-118bd800-5fa9-11e9-9055-6c2792d89234.png)

**Additional context**
<!-- Add any other context about the problem here. -->
I am working on this issue.


Discussion:
This shouldn't even be handled on frontend, this should be provided by the server
Can I work on this issue?
Go ahead
why do we use filter, ( starts_at > current_time or ends_at > current_time) for the upcoming events, when we can only use (ends_at > current_time) as ends_at time is always greater than starts_at and ends_at is never empty in any published event?
That's better because then we'll also be showing events which  are currently happening
We can show both the future events and events which are currently happening by only checking ends_at > current_time. We don't need starts_at comparison for that.
Exactly

Resolving patch:
diff --git a/app/api/events.py b/app/api/events.py
--- a/app/api/events.py
+++ b/app/api/events.py
@@ -857,3 +857,38 @@ def clear_export_urls(event):
     event.xcal_url = None
     event.pentabarf_url = None
     save_to_db(event)
+
+
+class UpcomingEventList(EventList):
+    """
+    List Upcoming Events
+    """
+
+    def before_get(self, args, kwargs):
+        """
+        method for assigning schema based on admin access
+        :param args:
+        :param kwargs:
+        :return:
+        """
+        super().before_get(args, kwargs)
+        self.schema.self_view_many = 'v1.upcoming_event_list'
+
+    def query(self, view_kwargs):
+        """
+        query method for upcoming events list
+        :param view_kwargs:
+        :return:
+        """
+        current_time = datetime.now(pytz.utc)
+        query_ = self.session.query(Event).filter(
+            Event.ends_at > current_time,
+            Event.state == 'published',
+            Event.privacy == 'public').order_by(Event.starts_at)
+        return query_
+
+    data_layer = {
+        'session': db.session,
+        'model': Event,
+        'methods': {'query': query},
+    }
diff --git a/app/api/routes.py b/app/api/routes.py
--- a/app/api/routes.py
+++ b/app/api/routes.py
@@ -83,7 +83,7 @@
 )
 from app.api.event_topics import EventTopicDetail, EventTopicList, EventTopicRelationship
 from app.api.event_types import EventTypeDetail, EventTypeList, EventTypeRelationship
-from app.api.events import EventDetail, EventList, EventRelationship
+from app.api.events import EventDetail, EventList, EventRelationship, UpcomingEventList
 from app.api.events_role_permission import (
     EventsRolePermissionDetail,
     EventsRolePermissionList,
@@ -610,6 +610,12 @@
     '/users/<int:user_sales_admin_id>/sales-admin-events',
 )
 
+api.route(
+    UpcomingEventList,
+    'upcoming_event_list',
+    '/events/upcoming',
+)
+
 api.route(
     EventDetail,
     'event_detail',


Test patch:
diff --git a/tests/hook_main.py b/tests/hook_main.py
--- a/tests/hook_main.py
+++ b/tests/hook_main.py
@@ -361,6 +361,19 @@ def event_post(transaction):
         db.session.commit()
 
 
+@hooks.before("Events > Upcoming Events Collection > List All Upcoming Events")
+def upcoming_event_get_list(transaction):
+    """
+    GET /events/upcoming
+    :param transaction:
+    :return:
+    """
+    with stash['app'].app_context():
+        event = EventFactoryBasic(state="published")
+        db.session.add(event)
+        db.session.commit()
+
+
 @hooks.before("Events > Event Details > Event Details")
 def event_get_detail(transaction):
     """