Class: SatisfactionsController

Inherits:
ApplicationController show all
Defined in:
app/controllers/satisfactions_controller.rb

Overview

Manage satisfactions creation within the sharebox site
A satisfaction is a form intended for the client to express his satisfaction

Instance Method Summary collapse

Methods inherited from ApplicationController

#check_lang, #prepare_attached_docs_request

Instance Method Details

#arrange(polls, satisfactions) ⇒ Object (private)

arrange the satisfaction feedbacks in a human way



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# File 'app/controllers/satisfactions_controller.rb', line 473

def arrange(polls,satisfactions)
  open={}
  closed={}
  polls.each do |p|
    open["#{p.id}"]=p.hash_open
    closed["#{p.id}"]=p.hash_closed
  end
  results=[]
  satisfactions.each_with_index do |s,i|
    results[i]={}
    results[i]["id"]=s.id
    results[i]["date"]=s.created_at
    results[i]["affaire"]=s.get_meta_i18n
    results[i]["folder_id"]=s.folder_id
    results[i]["poll_id"]=s.poll_id
    results[i]["collected_by"]=s.email
    for j in 1..open["#{s.poll_id}"].length
      results[i][open["#{s.poll_id}"]["open#{j}"]]=s["open#{j}"]
    end
    for j in 1..closed["#{s.poll_id}"].length
      results[i][closed["#{s.poll_id}"]["closed#{j}"]]=s["closed#{j}"]
    end
  end
  results
end

#createObject

Save a satisfaction answer
2 scenarios :
1) folder_id is <0, there is no link with an existing folder - the survey is independent

in that case and at this stage (only), the absolute value of folder_id is temporary equal to survey_id<br>

2) folder_id is >0 and it is a classic satisfaction survey associated to an existing folder



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'app/controllers/satisfactions_controller.rb', line 281

def create
  if params[:satisfaction][:folder_id].to_i < 0
    @satisfaction = Satisfaction.new(satisfaction_params)
    survey=Survey.find_by_id(@satisfaction.folder_id.abs)
    if !survey
      render plain: "#{t('sb.inexisting')} \n #{t('sb.survey')} #{t('sb.id')} #{@satisfaction.folder_id.abs}"
    else
      poll=Poll.find_by_id(params[:satisfaction][:poll_id])
      if !poll
        render plain: "#{t('sb.inexisting')} \n #{t('sb.poll')} #{t('sb.id')} #{params[:satisfaction][:poll_id]}" 
      else
        if poll.id != survey.poll_id
          render plain: t('sb.mismatch_poll_ids')
        else
          client_mel=survey.client_mel
          @satisfaction.case_number= gentitle(survey.description,survey.client_mel,survey.by)
          if Rails.configuration.sharebox["downcase_email_search_autocomplete"]
            client= Client.where("LOWER(mel) = ?",client_mel.downcase)[0]
          else
            client=Client.find_by_mel(client_mel)
          end
          if client
            # everything should be fine at this stage - we can fix things
            # folder_id will contain (-1)*client_id
            # user_id will be the user id of the registered user who launched the interaction
            puts("#{client.mel} already recorded on id #{client.id}!!!")
            @satisfaction.user_id = survey.user_id
            @satisfaction.folder_id = -client.id
            message=save_free_sat(@satisfaction, survey)
            render plain: message              
          else
            # client is not in the base
            # we save the client without fixing the organisation - it can be done further in the clients controller if needed
            puts("new record going to be created with email #{client_mel}")
            client=Client.new
            client.mel=survey.client_mel
            if client.save
              @satisfaction.user_id = survey.user_id
              @satisfaction.folder_id = -client.id
              message=save_free_sat(@satisfaction, survey)
              render plain: message
            else
              render plain: t('sb.new_client_not_saved')
            end
          end
        end
      end
    end
  else
    authenticate_user!
    @satisfaction = Satisfaction.new(satisfaction_params)
    @current_folder = Folder.find_by_id(params[:satisfaction][:folder_id])
    @satisfaction.user_id = current_user.id
    meta=@satisfaction.calc_meta(@current_folder,@current_user)
    @satisfaction.case_number = meta.join("")
    if @satisfaction.save
      flash[:notice] = t('sb.user_thank_for_feedback')
      @poll = Poll.all.find_by_id(@satisfaction.poll_id)
      @current_folder.lists=@current_folder.calc_meta
      unless @current_folder.save
        flash[:notice] = "#{flash[:notice]} #{t('sb.folder_metas')} #{@current_folder.name} - #{t('sb.id')} #{@current_folder.id}<br>"
        flash[:notice] = "#{flash[:notice]} #{t('sb.not_updated')}"
      end
    else
      flash[:notice] =t('sb.satisfaction_error')
    end
    render 'new'
  end
end

#destroyObject

Destroy a specific satisfaction
The show form of the poll_controller includes a delete button



354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'app/controllers/satisfactions_controller.rb', line 354

def destroy
  authenticate_user!
  @satisfaction = Satisfaction.find_by_id(params[:id])
  folder_id=@satisfaction.folder_id
  @poll = Poll.find_by_id(@satisfaction.poll_id)
  unless current_user.is_admin?
    flash[:notice] = t('sb.no_permission')
  else
    if @satisfaction.destroy
      flash[:notice] = t('sb.deleted')
      if folder = Folder.find_by_id(folder_id)
        folder.lists=folder.calc_meta
        unless folder.save
          flash[:notice] = "#{flash[:notice]} #{t('sb.folder_metas_not_recorded')}<br>"
        end
      end
    else
      flash[:notice] = t('sb.not_deleted')
    end
  end
  redirect_to poll_path(@poll)
end

#editObject

give the ability to an admin to edit a feedback



11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'app/controllers/satisfactions_controller.rb', line 11

def edit
  unless current_user.is_admin?
    flash[:notice] = t('sb.no_permission')
    redirect_to root_url
  else
    unless @satisfaction=Satisfaction.find_by_id(params[:id])
      flash[:notice] = "#{t('sb.inexisting_satisfaction')} #{params[:id]}"
      redirect_to root_url
    else
      @poll = Poll.find_by_id(@satisfaction.poll_id)
    end
  end
end

#feedback_metasObject

show / update meta datas on satisfactions to upgrade from deprecated versions of colibri (v0 or v1)



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/controllers/satisfactions_controller.rb', line 50

def feedback_metas
  unless current_user.is_admin?
    log="you do not have the permission to update satisfactions metadatas"
  else
    unless params[:update]
      log="checking metadatas on satisfaction records based on the folders'system...\n"
      satisfactions=Satisfaction.where("folder_id > ?",0)
      satisfactions.each do |sat|
        log="#{log} -> satisfaction #{sat.id} on folder (#{sat.folder_id}) metadatas are #{sat.case_number}\n"
      end
    else
      log="updating metadatas on satisfaction records based on the folders'system...\n"
      satisfactions=Satisfaction.where("folder_id > ?",0)
      satisfactions.each do |sat|
        meta=sat.calc_meta
        sat.case_number=meta.join("")
        unless sat.save
          log="#{log} -> satisfaction #{sat.id} on folder (#{sat.folder_id}) updating metadatas failed\n"
        else
          log="#{log} -> satisfaction #{sat.id} on folder (#{sat.folder_id}) updating metadatas OK : #{sat.case_number}\n"
        end
      end
    end
  end
  @log=log
end

#freelistObject

to retrieve for a given registered user all ids for the satisfaction answers collected out of the folders/assets system retieve also, if it exists, the case_number field for a nicer html output



145
146
147
148
149
150
151
152
# File 'app/controllers/satisfactions_controller.rb', line 145

def freelist
    authenticate_user!
    freesats=current_user.satisfactions.where("folder_id < ?",0).map {|x| {id: x.id, case_number: x.case_number}}
    freesats.each_with_index do |s,i|
       freesats[i][:case_number]=Validations.project_id_reg_exp.match(s[:case_number]).to_s
    end
    render json: freesats
end

#freenewObject

Show the new form in order to retrieve satisfactions from users not registered in the Colibri
WEAK LOGIC PROCESS 2019
please note we temporary use the folder_id field to store (-1)*@survey id
when satisfaction will be recorded in the database, folder_id field will be recycled to store the client id



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'app/controllers/satisfactions_controller.rb', line 159

def freenew
    @satisfaction=Satisfaction.new
    @survey=Survey.find_by_id(params[:id])
    if !@survey
      render plain: "#{t('sb.inexisting')} \n #{t('sb.survey')} #{t('sb.id')} #{params[:id]}"
    else
      if @survey.token != params[:md5]
        render plain: t('sb.incorrect_md5_token')
      else
        @poll=Poll.find_by_id(@survey.poll_id)
        @satisfaction.folder_id=-@survey.id
        @satisfaction.poll_id=@poll.id
        render 'freenew'
      end
    end
end

#gentitle(title, client, owner) ⇒ Object (private)

format the title of the feedback
used during creation process



400
401
402
# File 'app/controllers/satisfactions_controller.rb', line 400

def gentitle(title,client,owner)
  "#{title} - #{Validations.client_pattern}: #{client} - #{Validations.project_manager_pattern}: #{owner}"
end

#indexObject

render a json view of ALL satisfactions answers



133
134
135
136
137
138
139
140
# File 'app/controllers/satisfactions_controller.rb', line 133

def index
  authenticate_user!
  all={}
  satisfactions= Satisfaction.all.joins(:user).select("satisfactions.*,users.email as email")
  polls= Poll.all
  all["satisfactions"]=arrange(polls,satisfactions)
  render json: all
end

#jsonObject

render a json output of a given satisfaction
used in the surveys view



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'app/controllers/satisfactions_controller.rb', line 216

def json
  results={}
  satisfaction = Satisfaction.find_by_id(params[:id])
  unless satisfaction
      results["affaire"]=t('sb.inexisting_satisfaction')  
  else
      if satisfaction.folder_id > 0
          folder=Folder.find_by_id(satisfaction.folder_id)
          if folder
            results["affaire"]=folder.name
            if folder.case_number.length>0
              results["affaire"]="#{results["affaire"]} (#{folder.case_number})"
            end
          end
          user=User.find_by_id(satisfaction.user_id)
          if user
            results["affaire"]="#{results["affaire"]}<br>#{t('sb.client')}: #{user.email}"
          end
      else
          results["affaire"]=satisfaction.get_meta_i18n
      end
      results["date"]=satisfaction.created_at
      poll=Poll.find_by_id(satisfaction.poll_id)
      open=poll.hash_open
      closed=poll.hash_closed
      for j in 1..open.length
        results[open["open#{j}"]]=satisfaction["open#{j}"]
      end
      for j in 1..closed.length
        if satisfaction["closed#{j}"]
          results[closed["closed#{j}"]]=satisfaction["closed#{j}"]
        else 
          results[closed["closed#{j}"]]=0
        end
      end
  end
  render json: results
end

#newObject

Show the new form in order for public users to express their satisfaction
A public user will access to the form if :

  • he has a shared access on the folder

  • the folder is polled

  • he has not already answered to the form

Both types of questions, open and closed, are not required fields



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'app/controllers/satisfactions_controller.rb', line 183

def new
  authenticate_user!
  @current_folder = Folder.find_by_id(params[:id])
  if !@current_folder
    flash[:notice] = t('sb.inexisting_folder')
    redirect_to root_url
  else
    if current_user.has_ownership?(@current_folder) || current_user.belongs_to_team?
      flash[:notice] = t('sb.team_member_or_folder_owner')
      redirect_to folder_path(@current_folder) and return
    end
    unless current_user.has_shared_access?(@current_folder)
      flash[:notice] = t('sb.unshared_folder')
      redirect_to root_url and return
    end
    unless @current_folder.is_polled?
      flash[:notice] = t('sb.unpolled_folder')
      redirect_to folder_path(@current_folder) and return
    end
    if current_user.has_completed_satisfaction?(@current_folder)
      flash[:notice] = t('sb.already_answered')
      redirect_to folder_path(@current_folder) and return
    end
    @satisfaction = Satisfaction.new
    @satisfaction.folder_id = @current_folder.id 
    @satisfaction.poll_id = @current_folder.poll_id
    @poll = Poll.find_by_id(@current_folder.poll_id)
  end
end

#prepare(params, closed_names_number, request_type_nbr) ⇒ Object (private)

prepare a SQL request in the satisfactions table
implement a jointure on the users and/or folders table
params must at least include the poll number
possible params are start+end, groups fragment, ncap to track insatisfactions, email



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
# File 'app/controllers/satisfactions_controller.rb', line 409

def prepare(params,closed_names_number,request_type_nbr)

  common="SELECT satisfactions.*,users.email as email, users.groups as groups FROM satisfactions"
  #type 1 gives satisfactions on folder
  type=[]
  type[1]=common
  type[1]="#{type[1]} INNER JOIN folders ON folders.id = satisfactions.folder_id" 
  type[1]="#{type[1]} INNER JOIN users ON users.id = folders.user_id WHERE "
  #type 2 gives satisfactions out of the folders/files system
  type[2]=common 
  type[2]="#{type[2]} INNER JOIN users ON users.id = satisfactions.user_id WHERE satisfactions.folder_id < 0 and "
  #type 3 gives all types of feedbacks but you cannot really filter on groups
  type[3]=common 
  type[3]="#{type[3]} INNER JOIN users ON users.id = satisfactions.user_id WHERE "
  
  request=[]
  tab=[]
  tab[0]=type[request_type_nbr]
  if params[:poll_id]
    request.push("satisfactions.poll_id = ?")
    tab.push(params[:poll_id])
  end
  puts("------SQL preparation function------------we have the following date range [#{params[:start]} ; #{params[:end]}]")
  if Validations.date_reg_exp.match(params[:start]) && Validations.date_reg_exp.match(params[:end])
      time_start = Validations.date_reg_exp.match(params[:start])[0]
      time_end = Validations.date_reg_exp.match(params[:end])[0]
      request.push("(satisfactions.created_at BETWEEN ? AND ?)")
      tab.push("#{time_start}")
      tab.push("#{time_end}")
  end
  if params[:groups]
    unless params[:groups].include?("!")
      request.push("users.groups like ?")
      tab.push("%#{params[:groups]}%")
    else
      request.push("(users.groups is null or users.groups not like ?)")
      tab.push("%#{params[:groups].gsub("!","")}%")
    end
  end
  if params[:ncap]
    ncap=[]
    for i in (1..closed_names_number)
      ncap.push("satisfactions.closed#{i} <= ?")
      tab.push(params[:ncap].to_i)
    end
    ncapstring=ncap.join(" or ")
    request.push("(#{ncapstring})")
  end
  if params[:email]
    if Rails.configuration.sharebox["downcase_email_search_autocomplete"]
      request.push("LOWER(satisfactions.case_number) like ?")
      str="#{Validations.project_manager_pattern.downcase}: #{params[:email].downcase}"
    else
      request.push("satisfactions.case_number like ?")
      str="#{Validations.project_manager_pattern}: #{params[:email]}"
    end
    tab.push("%#{str}%")
  end
  tab[0]=tab[0]+request.join(" and ")
  tab
end

#runObject

run a filter on the results of a specific poll route is /satisfactions/run/:poll_id



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'app/controllers/satisfactions_controller.rb', line 80

def run
  #authenticate_user!
  polls=[]
  all={}
  poll=Poll.find_by_id(params[:poll_id])
  if poll
    polls.push(poll)
    all["poll_id"]=params[:poll_id]
    all["poll_name"]=poll.name
    unless params[:groups]
      tab=prepare(params,poll.closed_names_number,3)
      satisfactions=Satisfaction.find_by_sql(tab)
    else
      tab=prepare(params,poll.closed_names_number,1)
      satisfactions=Satisfaction.find_by_sql(tab)
      tab=prepare(params,poll.closed_names_number,2)
      satisfactions+=Satisfaction.find_by_sql(tab)
      all["groups"]=params[:groups]
    end
    if params[:start] && params[:end]
      all["from"]=params[:start]
      all["to"]=params[:end]
    end
    if params[:ncap]
      all["ncap"]="#{t('sb.ncap')} #{params[:ncap]}"
    end
    if params[:email]
      all["email"]="#{t('sb.project_manager_feedbacks')} #{params[:email]}"
    end
    # evaluation of sent surveys only if user did not ask for csv export, ncap exploitation or filtering on a specific email
    unless params[:csv] || params[:ncap] || params[:email]
      puts("**************parameters for count_sent_surveys (poll model) [#{all["from"]},#{all["to"]},#{all["groups"]}]")
      nb=poll.count_sent_surveys(all["from"],all["to"],all["groups"])
      all["sent"]=nb
    end
    unless params[:csv]
      if satisfactions.length>0
        stats=poll.stats(satisfactions)
        all["stats"]=stats
      end
      all["satisfactions"]=arrange(polls,satisfactions)
      render json: all
    else
      csv = poll.csv(satisfactions)
      send_data csv, filename: "polls-#{Time.zone.today}.csv"
    end
  else
    render json: {"message": "#{t('sb.inexisting')} - #{t('sb.poll')} #{t('sb.id')} #{params[:poll_id]}"}
  end
end

#satisfaction_paramsObject (private)



499
500
501
# File 'app/controllers/satisfactions_controller.rb', line 499

def satisfaction_params
  params.require(:satisfaction).permit(:folder_id, :poll_id, :case_number, :closed1, :closed2, :closed3, :closed4, :closed5, :closed6, :closed7, :closed8, :closed9, :closed10, :closed11, :closed12, :closed13, :closed14, :closed15, :closed16, :closed17, :closed18, :closed19, :closed20, :open1, :open2, :open3, :open4, :open5, :open6, :open7, :open8, :open9, :open10, :open11, :open12, :open13, :open14, :open15, :open16, :open17, :open18, :open19, :open20)
end

#save_free_sat(satisfaction, survey) ⇒ Object (private)

save a free feedback, ie out of the folders/files system



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'app/controllers/satisfactions_controller.rb', line 381

def save_free_sat(satisfaction, survey)
  if satisfaction.save
    survey.token="disabled#{satisfaction.id}"
    if survey.destroy
      message=t('sb.user_thank_for_feedback')
    else
      #survey.token="disabled#{satisfaction.id}"
      survey.save
      message="#{t('sb.user_thank_for_feedback')} #{t('sb.fmd5_disabled')}"
    end
  else 
    message=t('sb.satisfaction_error')
  end
  message
end

#showObject

Show satisfaction answer given a specific id
for admins and users with shared access on the folder related to the satisfaction



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'app/controllers/satisfactions_controller.rb', line 258

def show
  authenticate_user!
  @satisfaction = Satisfaction.find_by_id(params[:id])
  if !@satisfaction
    flash[:notice] = t('sb.inexisting_satisfaction')
    redirect_to root_url
  else
    @current_folder = Folder.find_by_id(@satisfaction.folder_id)
    unless ( current_user.has_shared_access?(@current_folder) || current_user.is_admin? )
      flash[:notice] = t('sb.no_permission')
      redirect_to root_url and return
    end
    @poll = Poll.find_by_id(@satisfaction.poll_id)
    render 'new'
  end
end

#updateObject

proceed to the update following an admin order



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'app/controllers/satisfactions_controller.rb', line 27

def update
  unless current_user.is_admin?
    flash[:notice] = t('sb.no_permission')
    redirect_to root_url
  else
    unless @satisfaction=Satisfaction.find_by_id(params[:id])
      flash[:notice] = "#{t('sb.inexisting_satisfaction')} #{params[:id]}"
      redirect_to root_url
    else
      if @satisfaction.update(satisfaction_params)
        flash[:notice]=t('sb.updated')
      else
        flash[:notice]=t('sb.not_updated')
      end
      @poll = Poll.find_by_id(@satisfaction.poll_id)
      render 'edit'
    end
  end
end