1+ const userprofile = require ( '../models/userProfile' ) ;
2+
3+ const formController = function ( Form , formResponse ) {
4+ // creating a new form
5+ const createForm = async function ( req , res ) {
6+ try {
7+ const { formName, questions, createdBy } = req . body ;
8+
9+ // Check if required fields are present
10+ if ( ! formName || ! questions || questions . length === 0 ) {
11+ return res . status ( 400 ) . json ( { message : 'Form name and questions are required.' } ) ;
12+ }
13+
14+ // check if form already exists or not
15+ let form_temp = await Form . find ( { formName :formName } )
16+ if ( form_temp . length > 0 ) { return res . status ( 400 ) . json ( { message :"Form already exists with that name" } ) }
17+ // Create a new form with the provided structure
18+ const newForm = new Form ( {
19+ formName,
20+ questions,
21+ createdBy,
22+ } ) ;
23+
24+ // Save the form in the database
25+ const savedForm = await newForm . save ( ) ;
26+
27+ // Generate a unique link to the form
28+ const formLink = `/forms/${ savedForm . formID } ` ;
29+
30+ return res . status ( 201 ) . json ( {
31+ message : 'Form created successfully' ,
32+ formID : savedForm . formID ,
33+ id :savedForm . _id ,
34+ formLink : "hostname" + formLink ,
35+ } ) ;
36+ } catch ( error ) {
37+ console . error ( 'Error creating form:' , error ) ;
38+ return res . status ( 500 ) . json ( { message : 'Server error, could not create form.' } ) ;
39+ }
40+ }
41+
42+ const editFormFormat = async function ( req , res ) {
43+ try {
44+ const { id, userId, formName, formQuestions } = req . body ;
45+
46+ // Fetch the existing form
47+ const existingForm = await Form . findById ( id ) ;
48+ if ( ! existingForm ) {
49+ return res . status ( 400 ) . json ( { message : "Invalid Form ID" } ) ;
50+ }
51+
52+ // Check if user exists and is active
53+ const user_temp = await userprofile . findById ( userId ) ;
54+ if ( ! user_temp || user_temp . isActive === false ) {
55+ return res . status ( 400 ) . json ( { message : "Invalid or inactive user ID" } ) ;
56+ }
57+
58+ let updateData = { } ;
59+
60+ // Check if the form name is actually changing
61+ if ( formName && formName !== existingForm . formName ) {
62+ updateData . formName = formName ;
63+ }
64+
65+ // Validate and compare formQuestions before updating
66+ if ( formQuestions ) {
67+ if ( ! Array . isArray ( formQuestions ) || formQuestions . length === 0 ) {
68+ return res . status ( 400 ) . json ( { message : "Questions must be a non-empty array" } ) ;
69+ }
70+
71+ let isDifferent = false ;
72+ let newQuestions = [ ] ;
73+
74+ for ( let question of formQuestions ) {
75+ if ( ! question . label || typeof question . label !== "string" ) {
76+ return res . status ( 400 ) . json ( { message : "Each question must have a valid 'label' of type string" } ) ;
77+ }
78+
79+ if ( ! question . type || typeof question . type !== "string" ) {
80+ return res . status ( 400 ) . json ( { message : "Each question must have a valid 'type' of type string" } ) ;
81+ }
82+
83+ if ( [ "radio" , "checkbox" ] . includes ( question . type ) ) {
84+ if ( ! Array . isArray ( question . options ) || question . options . length === 0 ) {
85+ return res . status ( 400 ) . json ( { message : `Question of type '${ question . type } ' must have a non-empty options array` } ) ;
86+ }
87+
88+ for ( let option of question . options ) {
89+ if ( typeof option !== "string" || option . trim ( ) === "" ) {
90+ return res . status ( 400 ) . json ( { message : "Each option must be a valid non-empty string" } ) ;
91+ }
92+ }
93+ }
94+
95+ // Check if this question already exists in the database
96+ let existingQuestion = existingForm . questions . find ( q => q . label === question . label ) ;
97+
98+ if ( ! existingQuestion || JSON . stringify ( existingQuestion . options ) !== JSON . stringify ( question . options ) ) {
99+ isDifferent = true ; // Mark as different if any question changes
100+ }
101+
102+ newQuestions . push ( question ) ;
103+ }
104+
105+ // Only update if something actually changed
106+ if ( isDifferent ) {
107+ updateData . questions = newQuestions ;
108+ }
109+ }
110+
111+ // If there's nothing to update, return early
112+ if ( Object . keys ( updateData ) . length === 0 ) {
113+ return res . status ( 200 ) . json ( { message : "No changes detected" } ) ;
114+ }
115+
116+ // Update the form
117+ await Form . updateOne ( { _id : id } , { $set : updateData } ) ;
118+
119+ return res . status ( 200 ) . json ( { message : "Form Updated Successfully" } ) ;
120+
121+ } catch ( err ) {
122+ console . error ( "Error updating form:" , err ) ;
123+ return res . status ( 500 ) . json ( { message : "Internal Server Error" , error : err . message } ) ;
124+ }
125+ } ;
126+
127+ const deleteFormFormat = async function ( req , res ) {
128+ try {
129+ // here id is the record Id of the form.
130+ const { id} = req . body ;
131+ let result = await Form . deleteOne ( { _id : id } ) ;
132+ // Check if the form was actually deleted
133+ if ( result . deletedCount === 0 ) {
134+ return res . status ( 400 ) . json ( { message : 'Error removing Form.' } ) ;
135+ }
136+ return res . status ( 200 ) . json ( { message :"Form Deleted Successfully" } )
137+ } catch ( error ) {
138+ return res . status ( 400 ) . json ( { message :"Error removing Form." } )
139+ }
140+ }
141+
142+ // check if a user has already responded to a form or not.
143+ const checkForResponse = async function ( req , res ) {
144+ try {
145+ const { formID, userID} = req . query ;
146+ let result = await formResponse . find ( { formID :formID , submittedBy :userID } )
147+ if ( result . length == 0 ) {
148+ return res . status ( 400 ) . json ( { message :"No records Found" } ) ;
149+ }
150+ return res . status ( 200 ) . json ( { message :result } )
151+ } catch ( error ) {
152+ return res . status ( 404 ) . json ( { message :"Error Searching for Recods" } )
153+ }
154+ }
155+
156+ const getFormData = async function ( req , res ) {
157+ try {
158+ const formID = req . query . formID ;
159+ // Check if formID is provided
160+ if ( ! formID ) {
161+ return res . status ( 400 ) . json ( { message : 'Form ID is required.' } ) ;
162+ }
163+
164+ // Check if the form exists
165+ const form = await Form . findOne ( { formID } ) ;
166+ if ( ! form || form . length === 0 ) {
167+ return res . status ( 404 ) . json ( { message : 'Form not found.' } ) ;
168+ }
169+
170+ // Fetch all responses associated with the formID
171+ const responses = await formResponse . find ( { formID } ) ;
172+
173+ // If no responses found, return a message
174+ if ( responses . length === 0 ) {
175+ return res . status ( 404 ) . json ( { message : 'No responses found for this form.' } ) ;
176+ }
177+
178+ return res . status ( 200 ) . json ( {
179+ message : 'Responses retrieved successfully' ,
180+ formID : formID ,
181+ formName : form . formName ,
182+ responses : responses ,
183+ } ) ;
184+
185+ } catch ( error ) {
186+ console . error ( 'Error fetching form responses:' , error ) ;
187+ return res . status ( 500 ) . json ( { message : 'Server error, could not fetch form responses.' } ) ;
188+ }
189+ }
190+
191+ const addDataToForm = async function ( req , res ) {
192+ try {
193+ const { formID, responses, submittedBy } = req . body ;
194+
195+ // Ensure all required fields are present
196+ if ( ! formID || ! responses || responses . length === 0 ) {
197+ return res . status ( 400 ) . json ( { message : 'Form ID and responses are required.' } ) ;
198+ }
199+ if ( ! submittedBy ) {
200+ return res . status ( 400 ) . json ( { message : 'User ID is required to submit this form.' } ) ;
201+ }
202+
203+ // Check if the form exists
204+ const form = await Form . findOne ( { formID } ) ;
205+ if ( ! form ) {
206+ return res . status ( 404 ) . json ( { message : 'Form not found.' } ) ;
207+ }
208+
209+ // Check if user exists and is active
210+ const user = await userprofile . findById ( submittedBy ) ;
211+ if ( ! user || user . isActive === false ) {
212+ return res . status ( 400 ) . json ( { message : 'Invalid or inactive user.' } ) ;
213+ }
214+
215+ // Validate responses against the form questions
216+ if ( ! Array . isArray ( responses ) ) {
217+ return res . status ( 400 ) . json ( { message : 'Responses must be an array.' } ) ;
218+ }
219+
220+ const formQuestions = form . questions ;
221+ if ( responses . length !== formQuestions . length ) {
222+ return res . status ( 400 ) . json ( { message : 'Number of responses does not match the number of form questions.' } ) ;
223+ }
224+
225+ const validatedResponses = [ ] ;
226+
227+ for ( let i = 0 ; i < responses . length ; i ++ ) {
228+ const question = formQuestions [ i ] ;
229+ const response = responses [ i ] ;
230+
231+ // Ensure response has the required label and value
232+ if ( ! response . questionLabel || response . answer === undefined ) {
233+ return res . status ( 400 ) . json ( { message : `Response for question "${ question . label } " is incomplete.` } ) ;
234+ }
235+
236+ // Ensure response label matches the expected question label
237+ if ( response . questionLabel !== question . label ) {
238+ return res . status ( 400 ) . json ( { message : `Invalid question label: Expected "${ question . label } ", got "${ response . questionLabel } ".` } ) ;
239+ }
240+
241+ // Validate response based on question type
242+ if ( question . type === 'radio' ) {
243+ if ( typeof response . answer !== 'string' ) {
244+ return res . status ( 400 ) . json ( { message : `Response for "${ question . label } " must be a single string value.` } ) ;
245+ }
246+ if ( ! question . options . includes ( response . answer ) ) {
247+ return res . status ( 400 ) . json ( { message : `Invalid response for "${ question . label } ". Expected one of: ${ question . options . join ( ', ' ) } ` } ) ;
248+ }
249+ } else if ( question . type === 'checkbox' ) {
250+ if ( ! Array . isArray ( response . answer ) ) {
251+ return res . status ( 400 ) . json ( { message : `Response for "${ question . label } " must be an array of selected options.` } ) ;
252+ }
253+ if ( response . answer . length === 0 ) {
254+ return res . status ( 400 ) . json ( { message : `At least one option must be selected for "${ question . label } ".` } ) ;
255+ }
256+ const invalidOptions = response . answer . filter ( option => ! question . options . includes ( option ) ) ;
257+ if ( invalidOptions . length > 0 ) {
258+ return res . status ( 400 ) . json ( { message : `Invalid options selected for "${ question . label } ": ${ invalidOptions . join ( ', ' ) } ` } ) ;
259+ }
260+ } else if ( question . type === 'text' ) {
261+ if ( typeof response . answer !== 'string' || response . answer . trim ( ) === '' ) {
262+ return res . status ( 400 ) . json ( { message : `Response for "${ question . label } " must be a non-empty text string.` } ) ;
263+ }
264+ } else {
265+ return res . status ( 400 ) . json ( { message : `Invalid question type: "${ question . type } "` } ) ;
266+ }
267+
268+ // Push the validated response into the validatedResponses array
269+ validatedResponses . push ( {
270+ questionLabel : response . questionLabel ,
271+ answer : response . answer ,
272+ } ) ;
273+ }
274+
275+ // Create and save the valid response
276+ const formResp = new formResponse ( {
277+ formID,
278+ responses : validatedResponses ,
279+ submittedBy,
280+ } ) ;
281+
282+ const savedResponse = await formResp . save ( ) ;
283+
284+ return res . status ( 201 ) . json ( {
285+ message : 'Form response submitted successfully' ,
286+ responseID : savedResponse . _id ,
287+ } ) ;
288+
289+ } catch ( error ) {
290+ console . error ( 'Error submitting form response:' , error ) ;
291+ return res . status ( 500 ) . json ( { message : 'Server error, could not submit form response.' } ) ;
292+ }
293+ } ;
294+
295+
296+ const getAllForms = async ( req , res ) => {
297+ try {
298+ const result = await Form . find ( { } )
299+ return res . status ( 200 ) . json ( { data :result } )
300+ } catch ( err ) {
301+ return res . status ( 404 ) . json ( { error :err } )
302+ }
303+ }
304+
305+ const getFormFormat = async ( req , res ) => {
306+ try {
307+ // const formID=req.params.id;
308+ const { formID, userId} = req . body ;
309+ console . log ( formID )
310+ console . log ( userId ) ;
311+ const result = await Form . find ( { formID} )
312+ console . log ( result )
313+ if ( ! result || result . length === 0 ) {
314+ return res . status ( 404 ) . json ( { message : 'Form not found.' } ) ;
315+ }
316+
317+ let user = await userprofile . find ( { _id :userId } )
318+ if ( user [ 0 ] . isActive === false || user === undefined || user === null || user . length === 0 ) {
319+ return res . status ( 400 ) . json ( { message : 'Invalid User' } ) ;
320+ }
321+ return res . status ( 200 ) . json ( { data :result } )
322+ } catch ( err ) {
323+ return res . status ( 404 ) . json ( { data :err } )
324+ }
325+ }
326+ return {
327+ createForm,
328+ getFormData,
329+ addDataToForm,
330+ getAllForms,
331+ getFormFormat,
332+ editFormFormat,
333+ deleteFormFormat,
334+ checkForResponse
335+ }
336+ } ;
337+
338+ module . exports = formController ;
0 commit comments