drg_cms 0.6.0.6 → 0.6.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/drg_cms/drg_cms.js +92 -36
  3. data/app/assets/stylesheets/drg_cms/drg_cms.css +141 -101
  4. data/app/assets/stylesheets/drg_cms/select-multiple.css +9 -12
  5. data/app/assets/stylesheets/drg_cms_cms.css +1 -1
  6. data/app/controllers/cmsedit_controller.rb +100 -32
  7. data/app/controllers/dc_application_controller.rb +71 -12
  8. data/app/controls/dc_report.rb +227 -0
  9. data/app/forms/all_options.yml +24 -5
  10. data/app/forms/dc_big_table.yml +1 -0
  11. data/app/forms/dc_big_table_value.yml +1 -0
  12. data/app/forms/dc_poll.yml +12 -5
  13. data/app/forms/dc_poll_item.yml +2 -1
  14. data/app/forms/dc_poll_result.yml +9 -0
  15. data/app/forms/dc_site.yml +2 -6
  16. data/app/helpers/cms_common_helper.rb +311 -0
  17. data/app/helpers/{cmsedit_edit_helper.rb → cms_edit_helper.rb} +52 -25
  18. data/app/helpers/{cmsedit_helper.rb → cms_helper.rb} +38 -31
  19. data/app/helpers/{cmsedit_index_helper.rb → cms_index_helper.rb} +152 -155
  20. data/app/helpers/dc_application_helper.rb +20 -234
  21. data/app/models/concerns/dc_site_concern.rb +12 -1
  22. data/app/models/dc_filter.rb +10 -8
  23. data/app/models/dc_permission.rb +30 -0
  24. data/app/models/dc_poll.rb +1 -0
  25. data/app/models/dc_poll_result.rb +4 -2
  26. data/app/models/dc_temp.rb +5 -2
  27. data/app/models/drgcms_form_fields.rb +12 -1
  28. data/app/models/drgcms_form_fields/date_picker.rb +4 -3
  29. data/app/models/drgcms_form_fields/datetime_picker.rb +4 -3
  30. data/app/models/drgcms_form_fields/drgcms_field.rb +18 -4
  31. data/app/models/drgcms_form_fields/embedded.rb +17 -9
  32. data/app/models/drgcms_form_fields/file_field.rb +1 -1
  33. data/app/models/drgcms_form_fields/hidden_field.rb +1 -1
  34. data/app/models/drgcms_form_fields/method.rb +65 -0
  35. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +17 -11
  36. data/app/models/drgcms_form_fields/radio.rb +10 -5
  37. data/app/models/drgcms_form_fields/readonly.rb +1 -1
  38. data/app/models/drgcms_form_fields/select.rb +49 -32
  39. data/app/models/drgcms_form_fields/text_autocomplete.rb +21 -21
  40. data/app/renderers/dc_big_menu_renderer.rb +1 -0
  41. data/app/renderers/dc_gallery_renderer.rb +1 -0
  42. data/app/renderers/dc_menu_renderer.rb +1 -0
  43. data/app/renderers/dc_page_renderer.rb +1 -0
  44. data/app/renderers/dc_part_renderer.rb +1 -0
  45. data/app/renderers/dc_piece_renderer.rb +1 -1
  46. data/app/renderers/dc_poll_renderer.rb +43 -38
  47. data/app/renderers/dc_renderer.rb +1 -0
  48. data/app/renderers/dc_simple_menu_renderer.rb +1 -0
  49. data/config/locales/drgcms_en.yml +3 -2
  50. data/config/locales/drgcms_sl.yml +5 -4
  51. data/config/locales/models_en.yml +9 -2
  52. data/config/locales/models_sl.yml +10 -3
  53. data/lib/drg_cms/version.rb +1 -1
  54. data/lib/generators/new_drg_form/new_drg_form_generator.rb +5 -3
  55. data/lib/tasks/database.rake +6 -56
  56. metadata +35 -33
  57. data/app/helpers/application_helper.rb +0 -2
@@ -28,10 +28,10 @@
28
28
  -ms-transition: border linear 0.2s, box-shadow linear 0.2s;
29
29
  -o-transition: border linear 0.2s, box-shadow linear 0.2s;
30
30
  transition: border linear 0.2s, box-shadow linear 0.2s;
31
- border: 2px solid #ddd;
32
- -webkit-border-radius: 3px;
33
- -moz-border-radius: 3px;
34
- border-radius: 3px;
31
+ border: 1px solid #ddd;
32
+ -webkit-border-radius: 1px;
33
+ -moz-border-radius: 1px;
34
+ border-radius: 1px;
35
35
  position: relative;
36
36
  height: 200px;
37
37
  padding: 0;
@@ -39,12 +39,9 @@
39
39
  }
40
40
 
41
41
  .ms-container .ms-list.ms-focus{
42
- border-color: rgba(82, 168, 236, 0.8);
43
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
44
- -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
45
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
46
- outline: 0;
47
- outline: thin dotted \9;
42
+ border: 1px solid rgba(76,154,255, 1);
43
+ outline: 1px solid rgba(76,154,255, 1);
44
+ border-radius: 1px;
48
45
  }
49
46
 
50
47
  .ms-container ul{
@@ -93,10 +90,10 @@
93
90
 
94
91
 
95
92
  .ms-container .ms-selected {
96
- font-weight: bold;
93
+ font-weight: 600;
97
94
  }
98
95
 
99
96
  .pull-right.ms-elem-selected{
100
97
  float: right;
101
- font-size: larger;
98
+ font-size: smaller;
102
99
  }
@@ -19,4 +19,4 @@
19
19
  */
20
20
 
21
21
  /* Required for link buttons to look alike */
22
- .dc-link a, .dc-link-submit input {font-weight: bold; font-size: 12px; }
22
+ .dc-link a, .dc-link-submit input {font-weight: 600; }
@@ -1,4 +1,3 @@
1
- #coding: utf-8
2
1
  #--
3
2
  # Copyright (c) 2012+ Damjan Rems
4
3
  #
@@ -432,35 +431,77 @@ end
432
431
  # Run action
433
432
  ########################################################################
434
433
  def run
434
+ # determine control file name and method
435
435
  control_name, method_name = params[:control].split('.')
436
436
  if method_name.nil?
437
437
  method_name = control_name
438
438
  control_name = params[:table]
439
439
  end
440
+ # extend with control methods
440
441
  extend_with_control_module(control_name)
441
442
  if respond_to?(method_name)
443
+ # can it be called
444
+ return return_run_error t('drgcms.not_authorized') unless can_process_run
445
+ # call method
442
446
  respond_to do |format|
443
447
  format.json { send method_name }
444
448
  format.html { send method_name }
445
449
  end
446
- else
447
- # Error message
448
- text = "Method #{method_name} not defined in #{control_name}_control"
449
- respond_to do |format|
450
- format.json { render json: {msg_error: text} }
451
- format.html { render plain: text }
452
- end
450
+ else # Error message
451
+ return_run_error "Method #{method_name} not defined in #{control_name}_control"
453
452
  end
454
-
455
453
  end
456
454
 
457
455
  protected
458
456
 
457
+ ########################################################################
458
+ # Respond with error on run action
459
+ ########################################################################
460
+ def return_run_error(text)
461
+ respond_to do |format|
462
+ format.json { render json: { msg_error: text } }
463
+ format.html { render plain: text }
464
+ end
465
+ end
466
+
467
+ ########################################################################
468
+ # Can run call be processed
469
+ ########################################################################
470
+ def can_process_run
471
+ if respond_to?(:dc_can_process)
472
+ response = send(:dc_can_process)
473
+ return response unless response.class == Array
474
+ else
475
+ response = [DcPermission::CAN_VIEW, params[:table] || 'dc_memory']
476
+ end
477
+ dc_user_can *response
478
+ end
479
+
480
+ ########################################################################
481
+ # Checks if user has permissions to perform operation on table and if not
482
+ # prepares response for not authorized message.
483
+ #
484
+ # @param [Integer] permission : Permission level defined in DcPermission constants eg. DcPermission::CAN_EDIT
485
+ # @param [String] collection_name : Table name on which user must have permission
486
+ #
487
+ # @return [Boolean] true when user has required permission otherwise false
488
+ ########################################################################
489
+ def user_has_permission?(permission, collection_name)
490
+ unless dc_user_can(permission, collection_name.to_s)
491
+ respond_to do |format|
492
+ format.json { render json: {msg_error: t('drgcms.not_authorized') } }
493
+ format.html { render plain: t('drgcms.not_authorized') }
494
+ end
495
+ return false
496
+ end
497
+ true
498
+ end
499
+
459
500
  ########################################################################
460
501
  # Merges two forms when current form extends other form. Subroutine of read_drg_cms_form.
461
502
  # With a little help of https://www.ruby-forum.com/topic/142809
462
503
  ########################################################################
463
- def forms_merge(hash1, hash2)
504
+ def forms_merge(hash1, hash2)
464
505
  target = hash1.dup
465
506
  hash2.keys.each do |key|
466
507
  if hash2[key].is_a? Hash and hash1[key].is_a? Hash
@@ -553,25 +594,38 @@ def read_drg_cms_form
553
594
  }
554
595
  end
555
596
 
597
+ ############################################################################
598
+ # Load module if available. Try not to mask errors in control module
599
+ ############################################################################
600
+ def load_controls_module(controls_string)
601
+ begin
602
+ controls_string.classify.constantize
603
+ rescue NameError => e
604
+ return nil if e.message.match('uninitialized constant') || e.message.match('wrong constant name')
605
+ # report errors when loading existing module
606
+ raise e
607
+ end
608
+ end
609
+
556
610
  ############################################################################
557
611
  # Dynamically extend cmsedit class with methods defined in controls module.
558
612
  ############################################################################
559
- def extend_with_control_module(control_name=@form['controls'])
560
- # May include embedded forms therefor ; => _
561
- controls_string = "#{control_name || params[:table].gsub(';','_')}_control"
562
- controls = "#{controls_string.classify}".constantize rescue nil
563
- # old version. Will be deprecated
564
- if controls.nil?
565
- controls_string = (control_name ? control_name : params[:table].gsub(';','_')) + '_control'
566
- controls = "DrgcmsControls::#{controls_string.classify}".constantize rescue nil
567
- dc_deprecate('Putting controls into app/controllers/drgcms_controls directory will be deprecated. Put them into app/controls instead.') if controls
568
- end
569
- # Form may be dynamically updated before processed
570
- if controls
613
+ def extend_with_control_module(control_name = @form['controls'] || @form['control'])
614
+ # May include embedded forms so ; => _
615
+ control_name ||= params[:table].gsub(';','_')
616
+ control_name += '_control' unless control_name.match(/control$|report$/i)
617
+ # p '************', control_name
618
+ controls = load_controls_module(control_name)
619
+ if controls
620
+ # extend first with dc_report when report
621
+ if control_name.match(/report$/i)
622
+ extend DcReport
623
+ init_report(control_name)
624
+ end
571
625
  extend controls
626
+ # Form may be dynamically updated before processed
572
627
  send(:dc_update_form) if respond_to?(:dc_update_form)
573
628
  end
574
-
575
629
  end
576
630
 
577
631
  ############################################################################
@@ -591,6 +645,7 @@ def check_authorization
591
645
  end
592
646
  read_drg_cms_form
593
647
  return render( plain: t('drgcms.form_error') ) if @form.nil?
648
+
594
649
  # Permissions can be also defined on form
595
650
  #TODO So far only can_view is used. Think about if using other permissions has sense
596
651
  can_view = @form.dig('permissions','can_view')
@@ -785,10 +840,10 @@ def save_data
785
840
  end
786
841
 
787
842
  ########################################################################
788
- # Will return commma separated data (field names) as hash. For usage
843
+ # Will return comma separated data (field names) as array of symbols. For usage
789
844
  # in select_fields and deny_fields
790
845
  ########################################################################
791
- def separated_to_hash(data)
846
+ def separated_to_symbols(data)
792
847
  data.chomp.split(',').inject([]) {|r,element| r << element.strip.downcase.to_sym }
793
848
  end
794
849
 
@@ -797,11 +852,11 @@ end
797
852
  ########################################################################
798
853
  def process_select_and_deny_fields
799
854
  if @form['result_set']['select_fields']
800
- @records = @records.only( separated_to_hash(@form['result_set']['select_fields']) )
855
+ @records = @records.only( separated_to_symbols(@form['result_set']['select_fields']) )
801
856
  end
802
857
  # deny fields specified
803
858
  if @form['result_set']['deny_fields']
804
- @records = @records.without( separated_to_hash(@form['result_set']['deny_fields']) )
859
+ @records = @records.without( separated_to_symbols(@form['result_set']['deny_fields']) )
805
860
  end
806
861
  end
807
862
 
@@ -839,6 +894,17 @@ def user_filter_options(model) #:nodoc:
839
894
  end
840
895
  end
841
896
 
897
+ ########################################################################
898
+ # Return current sort options for model (table)
899
+ ########################################################################
900
+ def user_sort_options(model) #:nodoc:
901
+ table_name = (model.class == String ? model : model.to_s).underscore
902
+ return nil unless session[table_name][:sort]
903
+
904
+ field, direction = session[table_name][:sort].split(' ')
905
+ { field.to_sym => direction.to_i }
906
+ end
907
+
842
908
  ########################################################################
843
909
  # Will set session[table_name][:filter] and save last filter settings to session.
844
910
  # subroutine of check_filter_options.
@@ -846,12 +912,13 @@ end
846
912
  def set_session_filter(table_name)
847
913
  # models that can not be filtered (for now)
848
914
  return if %w(dc_temp dc_memory).include?(params[:table])
849
-
850
915
  # clear filter
851
916
  if params[:filter] == 'off'
852
917
  session[table_name][:filter] = nil
853
918
  return
854
919
  end
920
+ # field_name should exist on set filter condition
921
+ return if params[:filter_oper] && params[:filter_field].blank?
855
922
 
856
923
  filter_value = if params[:filter_value].nil?
857
924
  # NIL indicates that no filtering is needed
@@ -946,9 +1013,10 @@ def process_collections #:nodoc
946
1013
  check_sort_options()
947
1014
  end
948
1015
  # result set is defined by filter method in control object
949
- if @form['result_set']['filter']
950
- if respond_to?(@form['result_set']['filter'])
951
- @records = send @form['result_set']['filter']
1016
+ form_filter = @form['result_set']['filter']
1017
+ if form_filter
1018
+ if respond_to?(form_filter)
1019
+ @records = send(form_filter)
952
1020
  # something went wrong. flash[] should have explanation.
953
1021
  if @records.class == FalseClass
954
1022
  @records = []
@@ -961,7 +1029,7 @@ def process_collections #:nodoc
961
1029
  per_page = (@form['result_set']['per_page'] || 30).to_i
962
1030
  @records = @records.page(params[:page]).per(per_page) if per_page > 0
963
1031
  end
964
- else
1032
+ elsif form_filter != 'dc_filter'
965
1033
  Rails.logger.error "Error: result_set:filter: #{@form['result_set']['filter']} not found in controls!"
966
1034
  end
967
1035
  else
@@ -168,7 +168,7 @@ protected
168
168
  #############################################################################
169
169
  # Add permissions. Subroutine of dc_user_can
170
170
  ############################################################################
171
- def add_permissions_for(table_name=nil) # :nodoc:
171
+ def __add_permissions_for(table_name=nil) # :nodoc:
172
172
  perm = table_name.nil? ? DcPermission.find_by(is_default: true) : DcPermission.find_by(table_name: table_name, active: true)
173
173
  (perm.dc_policy_rules.each {|p1| @permissions[p1.dc_policy_role_id] = p1.permission }) if perm
174
174
  end
@@ -185,7 +185,7 @@ end
185
185
  # @Example True when user has view permission on the table
186
186
  # if dc_user_can(DcPermission::CAN_VIEW, params[:table]) then ...
187
187
  ############################################################################
188
- def dc_user_can(permission, table=params[:table])
188
+ def __dc_user_can(permission, table=params[:table])
189
189
  if @permissions.nil?
190
190
  @permissions = {}
191
191
  add_permissions_for # default permission
@@ -201,6 +201,25 @@ def dc_user_can(permission, table=params[:table])
201
201
  false
202
202
  end
203
203
 
204
+ ###########################################################################
205
+ # Checks if user can perform (read, create, edit, delete) document in specified
206
+ # table (collection).
207
+ #
208
+ # @param [Integer] Required permission level
209
+ # @param [String] Collection (table) name for which permission is queried. Defaults to params[table].
210
+ #
211
+ # @return [Boolean] true if user's role permits (is higher or equal then required) operation on a table (collection).
212
+ #
213
+ # @Example True when user has view permission on the table
214
+ # if dc_user_can(DcPermission::CAN_VIEW, params[:table]) then ...
215
+ ############################################################################
216
+ def dc_user_can(permission, table=params[:table])
217
+ @permissions ||= DcPermission.permissions_for_table(table)
218
+ # Return true if any of the permissions user has is higher or equal to requested permission
219
+ session[:user_roles].each {|r| return true if @permissions[r] and @permissions[r] >= permission }
220
+ false
221
+ end
222
+
204
223
  ####################################################################
205
224
  # Detects if called from mobile agent according to http://detectmobilebrowsers.com/
206
225
  # and set session[:is_mobile]
@@ -218,7 +237,6 @@ def dc_set_is_mobile
218
237
  end
219
238
  end
220
239
 
221
-
222
240
  ##########################################################################
223
241
  # Merge values from parameters fields (from site, page ...) into internal @options hash.
224
242
  #
@@ -464,7 +482,7 @@ eot
464
482
  end
465
483
 
466
484
  ####################################################################
467
- # Checks if any errors exist on document and writes debug log. It can also
485
+ # Checks if any errors exist on document and writes error log. It can also
468
486
  # crash if requested. This is mostly usefull in development for debuging
469
487
  # model errors or when saving to multiple collections and where each save must be
470
488
  # checked if succesfull.
@@ -483,14 +501,7 @@ end
483
501
  #
484
502
  ####################################################################
485
503
  def dc_check_model(document, crash=false)
486
- return nil unless document.errors.any?
487
- msg = ''
488
- document.errors.each do |attribute, errors_array|
489
- msg << "#{attribute}: #{errors_array}\n"
490
- end
491
- logger.debug(msg) if msg.size > 0
492
- crash_it if crash
493
- msg
504
+ DcApplicationController.dc_check_model(document, crash=false)
494
505
  end
495
506
 
496
507
  ######################################################################
@@ -739,5 +750,53 @@ def dc_update_form_field(field_name, value, readonly=false)
739
750
  flash[:update][key_name] = value
740
751
  end
741
752
 
753
+ ####################################################################
754
+ # Checks if any errors exist on document and writes error log. It can also
755
+ # crash if requested. This is mostly usefull in development for debuging
756
+ # model errors or when updating multiple collections and each save must be
757
+ # checked if succesfull.
758
+ #
759
+ # @param [Document] Document object which will be checked
760
+ # @param [Boolean] If true method should end in runtime error. Default = false.
761
+ #
762
+ # @return [String] Error messages or empty string if everything is OK.
763
+ #
764
+ # @Example Check for error when data is saved.
765
+ # model.save
766
+ # if (msg = DcApplicationController.dc_check_model(model) ).size > 0
767
+ # p msg
768
+ # error process ......
769
+ # end
770
+ #
771
+ ####################################################################
772
+ def self.dc_check_model(document, crash=false)
773
+ return nil unless document.errors.any?
774
+ msg = ""
775
+ document.errors.each do |attribute, errors_array|
776
+ msg << "#{attribute}: #{errors_array}\n"
777
+ end
778
+ #
779
+ if crash and msg.size > 0
780
+ msg = "Validation errors in #{document.class}:\n" + msg
781
+ pp msg
782
+ Rails.logger.error(msg)
783
+ raise "Validation error. See log for more information."
784
+ end
785
+ msg
786
+ end
787
+
788
+ ########################################################################
789
+ # Will dump exception to rails log and console.
790
+ #
791
+ # Parameters:
792
+ # [exception] Object: Exception caught
793
+ #
794
+ ########################################################################
795
+ def dc_dump_exception(exception)
796
+ msg = [exception.message, *exception.backtrace].join($/)
797
+ pp msg
798
+ Rails.logger.error msg
799
+ end
800
+
742
801
 
743
802
  end
@@ -0,0 +1,227 @@
1
+ #--
2
+ # Copyright (c) 2020+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ ######################################################################
25
+ # Common methods required by reports
26
+ ######################################################################
27
+ module DcReport
28
+ attr_accessor :report_id
29
+ attr_accessor :bulk
30
+
31
+ ######################################################################
32
+ # Clear result if params[:clear] is 'yes' when form is first displayed
33
+ ######################################################################
34
+ def dc_new_record
35
+ DcTemp.clear(temp_key) unless params[:clear].to_s == 'no'
36
+ end
37
+
38
+ ######################################################################
39
+ # Check if report option is present in form and shuffle form, so it can
40
+ # be used to display result.
41
+ ######################################################################
42
+ def dc_update_form
43
+ return unless @form && @form['report'] && params[:table] = 'dc_temp'
44
+
45
+ # copy form data under report option to top
46
+ @form['report'].each { |key, data| @form[key] = data }
47
+ end
48
+
49
+ ######################################################################
50
+ # Print to PDF action
51
+ ######################################################################
52
+ def print
53
+ begin
54
+ pdf_do
55
+ rescue Exception => e
56
+ dc_dump_exception(e)
57
+ render json: { msg_error: t('drgcms.runtime_error') } and return
58
+ end
59
+
60
+ pdf_file = "tmp/dokument-#{Time.now.to_i}.pdf"
61
+ @pdf.render_file Rails.root.join('public', pdf_file)
62
+
63
+ render json: print_response(pdf_file)
64
+ end
65
+
66
+ ######################################################################
67
+ # Export data do excel action
68
+ ######################################################################
69
+ def export
70
+ export_to_excel( temp_key )
71
+ end
72
+
73
+ ######################################################################
74
+ # Default filter to select data for result.
75
+ ######################################################################
76
+ def data_filter
77
+ params['clear'].to_s == 'yes' ? DcTemp.where(key: false) : DcTemp.where(key: temp_key).order_by(order: 1)
78
+ end
79
+
80
+ private
81
+
82
+ ######################################################################
83
+ # Will create response message for print action. Response consists of
84
+ # opening pdf file in new browser tab and additional print_message if defined.
85
+ ######################################################################
86
+ def print_response(pdf_file)
87
+ response = { window: "/#{pdf_file}" }
88
+ response.merge!(report_message) if respond_to?(:report_message, true)
89
+ response
90
+ end
91
+
92
+ ######################################################################
93
+ # Temp key consists of report name and user's id. Key should be added
94
+ # to every dc_temp document and is used to define data, which belongs
95
+ # to current user.
96
+ ######################################################################
97
+ def temp_key
98
+ "#{@report_id}-#{session[:user_id]}"
99
+ end
100
+
101
+ ######################################################################
102
+ # Initialize report. Set report_id internal variable and initialize bulk
103
+ # for bulk saving data to dc_temp collection.
104
+ ######################################################################
105
+ def init_report(id)
106
+ @report_id = id
107
+ @bulk = []
108
+ end
109
+
110
+ ######################################################################
111
+ # Check if all send fields are blank.
112
+ ######################################################################
113
+ def all_blank?(*fields)
114
+ fields.each {|e| e.blank? ? true : (break false) }
115
+ end
116
+
117
+ ######################################################################
118
+ # Will write bulk data to dc_temp collection.
119
+ ######################################################################
120
+ def bulk_write(doc, the_end = false)
121
+ if doc.class == TrueClass
122
+ the_end = true
123
+ else
124
+ @bulk << doc
125
+ end
126
+
127
+ if (the_end && @bulk.size > 0) || @bulk.size > 100
128
+ DcTemp.collection.insert_many(@bulk)
129
+ @bulk = []
130
+ end
131
+ end
132
+
133
+ ######################################################################
134
+ # Export data to Excel
135
+ ######################################################################
136
+ def export_to_excel(report_id)
137
+ read_drg_cms_form if @form.blank?
138
+ # use report options if present
139
+ columns = (@form['report'] ? @form['report'] : @form)['result_set']['columns'].sort
140
+
141
+ n, workbook = 0, Spreadsheet::Workbook.new
142
+ excel = workbook.create_worksheet(name: report_id)
143
+ # header
144
+ columns.each_with_index do |column, i|
145
+ caption = column.last['caption'] || column.last['label']
146
+ label = t(caption)
147
+ excel[n, i] = label.match('translation missing') ? caption : label
148
+ end
149
+
150
+ data_filter.each do |doc|
151
+ n += 1
152
+ columns.each_with_index do |column, i|
153
+ value = doc[column.last['name']].to_s.gsub('<br>', ";")
154
+ value = value.gsub(/\<\/strong\>|\<strong\>|\<\/b\>|\<b\>/, '')
155
+ excel[n, i] = value
156
+ end
157
+ end
158
+ workbook.write Rails.root.join("public/tmp/#{report_id}.xls")
159
+ dc_render_ajax(operation: :window, value: "/tmp/#{report_id}.xls")
160
+ end
161
+
162
+ ############################################################################
163
+ # Returns html code for displaying date/time formatted by strftime. Will return '' if value is nil.
164
+ #
165
+ # Parameters:
166
+ # [value] Date/DateTime/Time.
167
+ # [format] String. strftime format mask. Defaults to locale's default format.
168
+ ############################################################################
169
+ def dc_format_date_time(value, format = nil)
170
+ return '' if value.nil?
171
+
172
+ format ||= value.class == Date ? t('date.formats.default') : t('time.formats.default')
173
+ value.strftime(format)
174
+ end
175
+
176
+ ##############################################################################
177
+ # Initialize PDF document for print
178
+ ##############################################################################
179
+ def pdf_init(opts={})
180
+ opts[:margin] ||= [30,30,30,30]
181
+ opts[:page_size] ||= 'A4'
182
+
183
+ pdf = Prawn::Document.new(opts)
184
+ pdf.font_size = opts[:font_size] if opts[:font_size]
185
+
186
+ pdf.encrypt_document( owner_password: :random,
187
+ permissions: { print_document: true,
188
+ modify_contents: false,
189
+ copy_contents: false,
190
+ modify_annotations: false })
191
+ pdf.font_families.update(
192
+ 'Arial' => { normal: Rails.root.join('public', 'arial.ttf'),
193
+ bold: Rails.root.join('public', 'arialbd.ttf') }
194
+ )
195
+ pdf.font 'Arial'
196
+ pdf
197
+ end
198
+
199
+ ################################################################################
200
+ # Prints out single text (or object) on report.
201
+ #
202
+ # @param [Object] txt : Text or object. Result of to_s method of the object is
203
+ # @param [Hash] opts
204
+ ###############################################################################
205
+ def pdf_text(txt, opts={})
206
+ box_opts = {}
207
+ ypos = @pdf.cursor
208
+ xpos = opts.delete(:atx) || 0
209
+ box_opts.merge!(single_line: (opts.delete(:single_line) || true))
210
+ box_opts.merge!(at: (opts.delete(:at) || [xpos, ypos]))
211
+ box_opts.merge!(width: opts[:width]) if opts[:width]
212
+ box_opts.merge!(align: opts[:align]) if opts[:align]
213
+ box_opts.merge!(inline_format: opts[:inline_format]) if opts[:inline_format]
214
+
215
+ @pdf.text_box(txt.to_s, box_opts)
216
+ end
217
+
218
+ ################################################################################
219
+ # Skip line on report
220
+ #
221
+ # @param [Integer] skip . Number of lines to skip. Default 1.
222
+ ###############################################################################
223
+ def pdf_skip(skip = 1)
224
+ @pdf.text('<br>' * skip, inline_format: true)
225
+ end
226
+
227
+ end