Repository: fossasia/open-event-server

Issue:
Validate speaker and session API according to custom forms
Custom forms are used by the organizer to define which fields they want and require in their event.
The API should validate payload for sessions and speakers according to that custom form.

@SaptakS Can you please explain how form data is being stored in the customform model.



Discussion:
The format of custom forms can be seen in this commit by @niranjan94 . https://github.com/fossasia/open-event-orga-server/commit/3b6d07ab5b7b472ba751d1e9a251b1dbdf916c11

@aviaryan @SaptakS @niranjan94 Could be a good blog post topic.

@mariobehling Yes. I will write a post on it. :smile: 
Btw, this issue is not fixed yet. We now know the format in which custom forms are stored, the validation of speaker and session <strike>forms</strike> payloads still needs to be done. 

@aviaryan @mariobehling there is already a blog post on this. https://opev.wordpress.com/2016/06/17/open-event-organizers-server-custom-forms/


Resolving patch:
diff --git a/open_event/api/sessions.py b/open_event/api/sessions.py
--- a/open_event/api/sessions.py
+++ b/open_event/api/sessions.py
@@ -7,6 +7,7 @@
 from open_event.models.speaker import Speaker as SpeakerModel
 from open_event.models.session_type import SessionType as SessionTypeModel
 from open_event.helpers.data import record_activity
+from open_event.helpers.data_getter import DataGetter
 
 from .helpers.helpers import get_paginated_list, requires_auth, \
     save_db_model, get_object_in_event
@@ -15,6 +16,8 @@
 from .helpers import custom_fields as fields
 from .helpers.special_fields import SessionLanguageField, SessionStateField
 
+import json
+
 api = Namespace('sessions', description='Sessions', path='/')
 
 # Create models
@@ -133,6 +136,15 @@ def fix_payload_post(self, event_id, data):
         return data
 
     def update(self, event_id, service_id, data):
+        form = DataGetter.get_custom_form_elements(event_id).first()
+        if form:
+            session_custom = json.loads(DataGetter.get_custom_form_elements(event_id).first().session_form)
+            for key in SESSION_POST:
+                if key in session_custom:
+                    if session_custom[key]['require'] == 1:
+                        SESSION_POST[key].required = True
+                    elif session_custom[key]['require'] == 0:
+                        SESSION_POST[key].required = False
         data = self.validate(data)
         data_copy = data.copy()
         data_copy = self.fix_payload_post(event_id, data_copy)
@@ -146,6 +158,15 @@ def update(self, event_id, service_id, data):
         return obj
 
     def create(self, event_id, data, url):
+        form = DataGetter.get_custom_form_elements(event_id).first()
+        if form:
+            session_custom = json.loads(DataGetter.get_custom_form_elements(event_id).first().session_form)
+            for key in SESSION_POST:
+                if key in session_custom:
+                    if session_custom[key]['require'] == 1:
+                        SESSION_POST[key].required = True
+                    elif session_custom[key]['require'] == 0:
+                        SESSION_POST[key].required = False
         data = self.validate(data)
         payload = self.fix_payload_post(event_id, data)
         return ServiceDAO.create(self, event_id, payload, url, validate=False)
diff --git a/open_event/api/speakers.py b/open_event/api/speakers.py
--- a/open_event/api/speakers.py
+++ b/open_event/api/speakers.py
@@ -2,10 +2,13 @@
 
 from open_event.models.speaker import Speaker as SpeakerModel
 
-from .helpers.helpers import get_paginated_list, requires_auth
+from .helpers.helpers import get_paginated_list, requires_auth, save_db_model
 from .helpers.utils import PAGINATED_MODEL, PaginatedResourceBase, ServiceDAO, \
     PAGE_PARAMS, POST_RESPONSES, PUT_RESPONSES, SERVICE_RESPONSES
 from .helpers import custom_fields as fields
+from open_event.helpers.data_getter import DataGetter
+
+import json
 
 api = Namespace('speakers', description='Speakers', path='/')
 
@@ -44,7 +47,33 @@
 
 # Create DAO
 class SpeakerDAO(ServiceDAO):
-    pass
+    def update(self, event_id, service_id, data):
+        form = DataGetter.get_custom_form_elements(event_id).first()
+        if form:
+            speaker_custom = json.loads(DataGetter.get_custom_form_elements(event_id).first().speaker_form)
+            for key in SPEAKER_POST:
+                if key in speaker_custom:
+                    if speaker_custom[key]['require'] == 1:
+                        SPEAKER_POST[key].required = True
+                    elif speaker_custom[key]['require'] == 0:
+                        SPEAKER_POST[key].required = False
+        data = self.validate(data)
+        obj = ServiceDAO.update(self, event_id, service_id, data)
+        obj = save_db_model(obj, SpeakerModel.__name__, event_id)
+        return obj
+
+    def create(self, event_id, data, url):
+        form = DataGetter.get_custom_form_elements(event_id).first()
+        if form:
+            speaker_custom = json.loads(DataGetter.get_custom_form_elements(event_id).first().speaker_form)
+            for key in SPEAKER_POST:
+                if key in speaker_custom:
+                    if speaker_custom[key]['require'] == 1:
+                        SPEAKER_POST[key].required = True
+                    elif speaker_custom[key]['require'] == 0:
+                        SPEAKER_POST[key].required = False
+        data = self.validate(data)
+        return ServiceDAO.create(self, event_id, data, url, validate=False)
 
 DAO = SpeakerDAO(SpeakerModel, SPEAKER_POST)
 


Test patch: