erp_tech_svcs 3.1.8 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +6 -14
  2. data/README.md +15 -9
  3. data/app/controllers/erp_tech_svcs/session_controller.rb +21 -8
  4. data/app/controllers/erp_tech_svcs/user_controller.rb +15 -10
  5. data/app/mailers/user_mailer.rb +3 -0
  6. data/app/models/audit_log.rb +0 -2
  7. data/app/models/extensions/note.rb +1 -2
  8. data/app/models/extensions/party.rb +6 -1
  9. data/app/models/file_asset.rb +80 -38
  10. data/app/models/group.rb +1 -1
  11. data/app/models/notification.rb +49 -0
  12. data/app/models/notification_type.rb +5 -0
  13. data/app/models/user.rb +2 -2
  14. data/app/models/user_defined_data.rb +6 -0
  15. data/app/models/user_defined_field.rb +8 -0
  16. data/app/views/user_mailer/activation_needed_email.html.erb +17 -7
  17. data/config/initializers/file_support.rb +2 -2
  18. data/config/routes.rb +2 -1
  19. data/db/migrate/20130610163240_create_notifications.rb +37 -0
  20. data/db/migrate/20131113213843_add_audit_log_item_old_value.rb +13 -0
  21. data/db/migrate/20131113213844_add_erp_tech_svcs_missing_indexes.rb +31 -0
  22. data/db/migrate/20131129203603_add_user_defined_fields.rb +43 -0
  23. data/db/migrate/20141013060204_add_custom_fields_to_notifications.rb +12 -0
  24. data/db/migrate/20141108182427_add_scoped_by_to_file_assets.rb +14 -0
  25. data/lib/erp_tech_svcs.rb +4 -1
  26. data/lib/erp_tech_svcs/config.rb +5 -2
  27. data/lib/erp_tech_svcs/engine.rb +3 -1
  28. data/lib/erp_tech_svcs/extensions.rb +3 -1
  29. data/lib/erp_tech_svcs/extensions/active_record/has_user_defined_data.rb +147 -0
  30. data/lib/erp_tech_svcs/extensions/active_record/is_json.rb +55 -0
  31. data/lib/erp_tech_svcs/extensions/active_record/scoped_by.rb +64 -0
  32. data/lib/erp_tech_svcs/file_support/file_system_manager.rb +7 -0
  33. data/lib/erp_tech_svcs/file_support/manager.rb +1 -1
  34. data/lib/erp_tech_svcs/file_support/s3_manager.rb +13 -6
  35. data/lib/erp_tech_svcs/utils/default_nested_set_methods.rb +3 -5
  36. data/lib/erp_tech_svcs/version.rb +7 -3
  37. data/lib/tasks/erp_tech_svcs_tasks.rake +23 -4
  38. data/spec/lib/erp_tech_svcs/extensions/active_record/is_json_spec.rb +13 -0
  39. metadata +109 -78
  40. data/app/assets/javascripts/erp_tech_svcs/application.js +0 -9
  41. data/app/assets/stylesheets/erp_tech_svcs/application.css +0 -7
  42. data/app/helpers/erp_tech_svcs/application_helper.rb +0 -4
  43. data/app/views/layouts/application.html.erb +0 -14
  44. data/app/views/layouts/erp_tech_svcs/application.html.erb +0 -14
  45. data/config/initializers/erp_tech_svcs.rb +0 -16
  46. data/db/migrate/20111117183144_create_has_attribute_tables.rb +0 -38
  47. data/lib/erp_tech_svcs/extensions/active_record/has_relational_dynamic_attributes.rb +0 -128
  48. data/spec/dummy/db/data_migrations/20130220143304_add_usd_currency.erp_base_erp_svcs.rb +0 -12
  49. data/spec/dummy/db/data_migrations/20130220143305_add_iso_codes.erp_base_erp_svcs.rb +0 -19
  50. data/spec/dummy/db/data_migrations/20130220143306_setup_compass_ae_instance.erp_base_erp_svcs.rb +0 -21
  51. data/spec/dummy/db/data_migrations/20130220143307_upgrade_compass_ae_instances_data.erp_base_erp_svcs.rb +0 -19
  52. data/spec/dummy/db/data_migrations/20130220143308_create_capability_scope_types.erp_tech_svcs.rb +0 -15
  53. data/spec/dummy/db/data_migrations/20130220143309_schedule_delete_expired_sessions_job.erp_tech_svcs.rb +0 -16
  54. data/spec/dummy/db/data_migrations/20130220143310_setup_audit_log_types.erp_tech_svcs.rb +0 -22
  55. data/spec/dummy/db/data_migrations/20130220143311_create_group_relationship_and_role_types.erp_tech_svcs.rb +0 -20
  56. data/spec/dummy/db/data_migrations/20130220143312_note_capabilities.erp_tech_svcs.rb +0 -24
  57. data/spec/dummy/db/data_migrations/20130422151256_add_guid_to_instances.erp_base_erp_svcs.rb +0 -10
  58. data/spec/dummy/db/migrate/20130220143259_base_erp_services.erp_base_erp_svcs.rb +0 -486
  59. data/spec/dummy/db/migrate/20130220143260_add_txn_status.erp_base_erp_svcs.rb +0 -37
  60. data/spec/dummy/db/migrate/20130220143261_upgrade_compass_ae_instances.erp_base_erp_svcs.rb +0 -34
  61. data/spec/dummy/db/migrate/20130220143262_base_tech_services.erp_tech_svcs.rb +0 -271
  62. data/spec/dummy/db/migrate/20130220143263_create_has_attribute_tables.erp_tech_svcs.rb +0 -39
  63. data/spec/dummy/db/migrate/20130220143264_create_groups.erp_tech_svcs.rb +0 -19
  64. data/spec/dummy/db/migrate/20130220143265_upgrade_security.erp_tech_svcs.rb +0 -54
  65. data/spec/dummy/db/migrate/20130220143266_upgrade_security2.erp_tech_svcs.rb +0 -275
  66. data/spec/dummy/db/migrate/20130422151250_add_uuid_compass_ae_instance.erp_base_erp_svcs.rb +0 -17
  67. data/spec/dummy/db/migrate/20130422151251_add_long_lat_to_address.erp_base_erp_svcs.rb +0 -16
  68. data/spec/dummy/db/migrate/20130422151252_add_queue_to_delayed_jobs.erp_tech_svcs.rb +0 -14
  69. data/spec/dummy/db/schema.rb +0 -665
  70. data/spec/dummy/db/spec.sqlite3 +0 -0
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YzA2YjkzOTY3NTA1ZjU4NjdmZDc5Mjk1YmVkMTJkNTZiYTkzNzQzNQ==
5
- data.tar.gz: !binary |-
6
- NTE3NWRlNjZlZTg2ODRiMDlmMzExOTZmZWZiYTAwN2Y2YjQ5ZTRhZg==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- YTE0MDZhZjFhNjM0YjcwOTFjZGVjMmI5YzE3N2YxNzk4MmZmNzZiNDFmZTEw
10
- MzZiMjE3Y2I0OTBhYzU1MzNlYTU1MmJlZmQ4M2YxNTQ2MDEzYmI2MTczZGJj
11
- NGI5Zjk2OTYwZjczNjdmMGMwZGE3M2JjZTFmZjZhNTMxYjE1ZTU=
12
- data.tar.gz: !binary |-
13
- Y2I3MjlkZTMwYTJjYTAwYTg1NDZkMDIxZDkyZmJhMmUyNzY0NTA1NTJmODJl
14
- NTE3YzljNWY1YmM2MWUyMzc4ODNlNWM4YzI0ZjZlZjJkZjAzYThiM2UzODI2
15
- NTNhYjE4NTdkMWVlOGI2ODlmMmZlNmM2NWM2NDgwMGU4MGQzYWM=
2
+ SHA1:
3
+ metadata.gz: 7bc1ac2673d51f0305cefdda4751e83b2e5c9c8b
4
+ data.tar.gz: 8cd8163998ed18e9830e422bb8b711cb7444aba5
5
+ SHA512:
6
+ metadata.gz: b05a87fbda29e7a21d9ce740a2bad21ced5ff359cdc99685bdb4538516beae0eabc30733621d9e1c5919109ad1fa84559a4b2f00ea97bca455d1148ff01d6218
7
+ data.tar.gz: 0a6bb2c5cbb497360561bb79b16c36cc71e52251721ce3adf604ad8fe9e4409c222f969a33e166abd5692ee9e26aa237a0a07776657adb0c86e870bc24da4de3
data/README.md CHANGED
@@ -13,24 +13,30 @@ This engine is implemented with the premise that services like logging, tracing
13
13
  - email\_notifications\_from
14
14
  - From address for email notifications.
15
15
  - Default : 'notifications@noreply.com'
16
+ - email_regex
17
+ - Email validation regex
18
+ - Default : ^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$
16
19
  - max\_file\_size\_in\_mb
17
20
  - Max allowed file upload size in mega bytes.
18
21
  - Default : 5
22
+ - file_upload_types
23
+ - Allowed file upload types
24
+ - Default : 'txt,pdf,zip,tgz,gz,rar,jpg,jpeg,gif,png,tif,tiff,bmp,csv,xls,xlsx,doc,docx,ppt,pptx,psd,ai,css,js,mp3,mp4,m4a,m4v,mov,wav,wmv'
19
25
  - file\_assets\_location
20
26
  - Where you want file_assets to be saved to.
21
27
  - Default : file_assets
22
28
  - file\_storage
23
29
  - File storage to use either s3 or filesystem.
24
30
  - Default : :filesystem
31
+ - file\_protocol
32
+ - Protocol for file urls
33
+ - Default : http
25
34
  - s3\_url\_expires\_in_seconds
26
35
  - Set expiration in seconds on an S3 url to a secure file
27
36
  - Default : 60
28
37
  - s3\_protocol
29
38
  - Protocol for S3 URLs
30
39
  - Default : https
31
- - s3\_cache\_expires\_in\_minutes
32
- - S3 assets are cached for performance. Set expiration lifetime here in minutes.
33
- - Default : 60
34
40
  - session\_expires\_in_hours
35
41
  - Used by DeleteExpiredSessionsJob to purge inaactive sessions from database.
36
42
  - Default : 12
@@ -46,13 +52,13 @@ To override these settings simple create a erp_tech_svcs.rb file in your initial
46
52
  config.login_url = '/erp_app/login'
47
53
  config.email_notifications_from = 'notifications@noreply.com'
48
54
  config.max_file_size_in_mb = 5
49
- config.file_assets_location = 'file_assets' # relative to Rails.root/
50
- config.s3_url_expires_in_seconds = 60
51
- config.s3_protocol = 'https' # Can be either 'http' or 'https'
52
- config.file_storage = :filesystem # Can be either :s3 or :filesystem
53
- config.s3_cache_expires_in_minutes = 60
54
- config.session_expires_in_hours = 12 # this is used by DeleteExpiredSessionsJob to purge inaactive sessions from database
55
+ config.session_expires_in_hours = 12 # this is used by DeleteExpiredSessionsJob to purge inaactive sessions from database
55
56
  config.compass_logger_path = "#{Rails.root}/log"
57
+ config.file_assets_location = 'file_assets' # relative to Rails.root
58
+ config.file_protocol = 'http'
59
+ config.file_storage = :filesystem # Can be either :s3 or :filesystem
60
+ config.s3_url_expires_in_seconds = 60
61
+ config.s3_protocol = 'https' # Can be either 'http' or 'https'
56
62
  end
57
63
  Rails.application.config.erp_tech_svcs.configure!
58
64
 
@@ -1,17 +1,15 @@
1
1
  module ErpTechSvcs
2
2
  class SessionController < ActionController::Base
3
3
  def create
4
- last_login_at = nil
5
- potential_user = User.where('username = ? or email = ?', params[:login], params[:login]).first
6
- last_login_at = potential_user.last_login_at unless potential_user.nil?
7
- if login(params[:login],params[:password])
4
+ login = params[:login].strip
5
+ if login(login, params[:password])
8
6
  #log when someone logs in
9
7
  ErpTechSvcs::ErpTechSvcsAuditLog.successful_login(current_user)
10
8
 
11
9
  #set logout
12
10
  session[:logout_to] = params[:logout_to]
13
11
 
14
- login_to = session[:return_to_url].blank? ? (last_login_at.nil? ? params[:first_login_to] : params[:login_to]) : session[:return_to_url]
12
+ login_to = session[:return_to_url].blank? ? params[:login_to] : session[:return_to_url]
15
13
  request.xhr? ? (render :json => {:success => true, :login_to => login_to}) : (redirect_to login_to)
16
14
  else
17
15
  message = "Login failed. Try again"
@@ -23,7 +21,7 @@ module ErpTechSvcs
23
21
  def destroy
24
22
  message = "You have logged out."
25
23
  logged_out_user_id = current_user.id unless current_user === false
26
- logout_to = session[:logout_to]
24
+ logout_to = session[:logout_to]
27
25
 
28
26
  logout
29
27
 
@@ -41,5 +39,20 @@ module ErpTechSvcs
41
39
  def keep_alive
42
40
  render :json => {:success => true, :last_activity_at => current_user.last_activity_at}
43
41
  end
44
- end#SessionsController
45
- end#ErpTechSvcs
42
+
43
+ def is_alive
44
+ if current_user
45
+ time_since_last_activity = (Time.now - current_user.last_activity_at)
46
+
47
+ if time_since_last_activity > (ErpApp::Config.session_redirect_after * 60)
48
+ render :json => {alive: false}
49
+ else
50
+ render :json => {alive: true}
51
+ end
52
+ else
53
+ render :json => {alive: false}
54
+ end
55
+ end
56
+
57
+ end #SessionsController
58
+ end #ErpTechSvcs
@@ -31,11 +31,16 @@ module ErpTechSvcs
31
31
  def reset_password
32
32
  begin
33
33
  login_url = params[:login_url].blank? ? ErpTechSvcs::Config.login_url : params[:login_url]
34
- if user = (User.find_by_email(params[:login]))
35
- new_password = Sorcery::Model::TemporaryToken.generate_random_token
34
+ login = params[:login].strip
35
+ if user = (User.where('username = ? or email = ?', login, login)).first
36
+
37
+ # generate new password with only letters
38
+ charset = %w{ A C D E F G H J K M N P Q R T V W X Y Z }
39
+ new_password = (0...8).map{ charset.to_a[rand(charset.size)] }.join
40
+
36
41
  user.password_confirmation = new_password
37
42
  if user.change_password!(new_password)
38
- user.add_instance_attribute(:login_url,login_url)
43
+ user.add_instance_attribute(:login_url, login_url)
39
44
  user.add_instance_attribute(:domain, params[:domain])
40
45
  user.deliver_reset_password_instructions!
41
46
  message = "Password has been reset. An email has been sent with further instructions to #{user.email}."
@@ -48,14 +53,14 @@ module ErpTechSvcs
48
53
  message = "Invalid user name or email address."
49
54
  success = false
50
55
  end
51
- render :json => {:success => success,:message => message}
52
- rescue Exception=>ex
53
- logger.error ex.message
54
- logger.error ex.backtrace
55
- render :json => {:success => false,:message => 'Error sending email.'}
56
+ render :json => {:success => success, :message => message}
57
+ rescue => ex
58
+ Rails.logger.error ex.message
59
+ Rails.logger.error ex.backtrace.join("\n")
60
+ render :json => {:success => false, :message => 'Error sending email.'}
56
61
  end
57
62
  end
58
63
 
59
64
 
60
- end#UserController
61
- end#ErpTechSvcs
65
+ end #UserController
66
+ end #ErpTechSvcs
@@ -5,6 +5,9 @@ class UserMailer < ActionMailer::Base
5
5
  @user = user
6
6
  @url = "#{get_domain(user.instance_attributes[:domain])}/users/activate/#{user.activation_token}"
7
7
  @url << "?login_url=#{@user.instance_attributes[:login_url]}" unless @user.instance_attributes[:login_url].nil?
8
+
9
+ @temp_password = @user.instance_attributes[:temp_password] unless @user.instance_attributes[:temp_password].nil?
10
+
8
11
  mail(:to => user.email, :subject => "An account has been created and needs activation")
9
12
  end
10
13
 
@@ -1,8 +1,6 @@
1
1
  class AuditLog < ActiveRecord::Base
2
2
  attr_protected :created_at, :updated_at
3
3
 
4
- attr_protected :created_at, :updated_at
5
-
6
4
  validates :party_id, :presence => {:message => 'cannot be blank'}
7
5
  validates :description, :presence => {:message => 'cannot be blank'}
8
6
  validates :audit_log_type, :presence => {:message => 'cannot be blank'}
@@ -1,6 +1,5 @@
1
1
  Note.class_eval do
2
2
  def created_by_username
3
- party = Party.find(created_by.id)
4
- party.user.username
3
+ created_by.user.username rescue ''
5
4
  end
6
5
  end
@@ -1,4 +1,9 @@
1
1
  Party.class_eval do
2
2
  has_security_roles
3
- has_one :user, :dependent => :destroy
3
+ has_many :users, :dependent => :destroy
4
+
5
+ # Helper method as most parties will have only one user
6
+ def user
7
+ users.first
8
+ end
4
9
  end
@@ -1,29 +1,31 @@
1
1
  require 'fileutils'
2
2
 
3
- Paperclip.interpolates(:file_path){|data, style|
3
+ Paperclip.interpolates(:file_path) { |data, style|
4
4
  case ErpTechSvcs::Config.file_storage
5
- when :filesystem
6
- file_support = ErpTechSvcs::FileSupport::Base.new
7
- File.join(file_support.root,data.instance.directory,data.instance.name)
8
- when :s3
9
- File.join(data.instance.directory,data.instance.name)
5
+ when :filesystem
6
+ file_support = ErpTechSvcs::FileSupport::Base.new
7
+ File.join(file_support.root, data.instance.directory, data.instance.name)
8
+ when :s3
9
+ File.join(data.instance.directory, data.instance.name)
10
10
  end
11
11
  }
12
12
 
13
- Paperclip.interpolates(:file_url){|data, style|
13
+ Paperclip.interpolates(:file_url) { |data, style|
14
14
  url = File.join(data.instance.directory, data.instance.name)
15
15
  case ErpTechSvcs::Config.file_storage
16
- when :filesystem
17
- #if public is at the front of this path and we are using file_system remove it
18
- dir_pieces = url.split('/')
19
- unless dir_pieces[1] == 'public'
20
- "/download/#{data.instance.name}?path=#{dir_pieces.delete_if{|name| name == data.instance.name}.join('/')}"
21
- else
22
- dir_pieces.delete_at(1) if dir_pieces[1] == 'public'
23
- dir_pieces.join('/')
24
- end
25
- when :s3
26
- url
16
+ when :filesystem
17
+ #if public is at the front of this path and we are using file_system remove it
18
+ dir_pieces = url.split('/')
19
+ path = unless dir_pieces[1] == 'public'
20
+ "/download/#{data.instance.name}?path=#{dir_pieces.delete_if { |name| name == data.instance.name }.join('/')}"
21
+ else
22
+ dir_pieces.delete_at(1) if dir_pieces[1] == 'public'
23
+ dir_pieces.join('/')
24
+ end
25
+
26
+ "#{ErpTechSvcs::Config.file_protocol}://#{File.join(ErpTechSvcs::Config.installation_domain, path)}"
27
+ when :s3
28
+ url
27
29
  end
28
30
  }
29
31
 
@@ -40,25 +42,30 @@ class FileAsset < ActiveRecord::Base
40
42
  class_inheritable_writer :valid_extensions
41
43
  end
42
44
 
45
+ # setup scoping
46
+ add_scoped_by :scoped_by
47
+
43
48
  after_create :set_sti
49
+ # must fire after paperclip's after_save :save_attached_files
50
+ after_save :set_data_file_name, :save_dimensions
51
+ before_validation(on: :create) do
52
+ self.check_name_uniqueness
53
+ end
44
54
 
45
55
  belongs_to :file_asset_holder, :polymorphic => true
46
56
  instantiates_with_sti
47
57
 
48
58
  protected_with_capabilities
49
-
59
+
50
60
  #paperclip
51
61
  has_attached_file :data,
52
- :storage => ErpTechSvcs::Config.file_storage,
53
- :s3_protocol => ErpTechSvcs::Config.s3_protocol,
54
- :s3_permissions => :public_read,
55
- :s3_credentials => "#{Rails.root}/config/s3.yml",
56
- :path => ":file_path",
57
- :url => ":file_url",
58
- :validations => { :extension => lambda { |data, file| validate_extension(data, file) } }
59
-
60
- # must fire after paperclip's after_save :save_attached_files
61
- after_save :set_data_file_name, :save_dimensions
62
+ :storage => ErpTechSvcs::Config.file_storage,
63
+ :s3_protocol => ErpTechSvcs::Config.s3_protocol,
64
+ :s3_permissions => :public_read,
65
+ :s3_credentials => "#{Rails.root}/config/s3.yml",
66
+ :path => ":file_path",
67
+ :url => (ErpTechSvcs::Config.file_storage == :filesystem ? ":file_url" : (ErpTechSvcs::Config.s3_url || ":file_url")),
68
+ :validations => {:extension => lambda { |data, file| validate_extension(data, file) }}
62
69
 
63
70
  before_post_process :set_content_type
64
71
 
@@ -79,18 +86,18 @@ class FileAsset < ActiveRecord::Base
79
86
 
80
87
  def type_for(name)
81
88
  classes = all_subclasses.uniq
82
- classes.detect{ |k| k.acceptable?(name) }.try(:name)
89
+ classes.detect { |k| k.acceptable?(name) }.try(:name)
83
90
  end
84
91
 
85
92
  def type_by_extension(extension)
86
- klass = all_subclasses.detect{ |k| k.valid_extensions.include?(extension) }
93
+ klass = all_subclasses.detect { |k| k.valid_extensions.include?(extension) }
87
94
  klass = TextFile if klass.nil?
88
95
  klass
89
96
  end
90
97
 
91
98
  def validate_extension(data, file)
92
99
  if file.name && !file.class.valid_extensions.include?(File.extname(file.name))
93
- types = all_valid_extensions.map{ |type| type.gsub(/^\./, '') }.join(', ')
100
+ types = all_valid_extensions.map { |type| type.gsub(/^\./, '') }.join(', ')
94
101
  "#{file.name} is not a valid file type. Valid file types are #{types}."
95
102
  end
96
103
  end
@@ -118,7 +125,7 @@ class FileAsset < ActiveRecord::Base
118
125
  base_path ||= data.original_filename if data.respond_to?(:original_filename)
119
126
 
120
127
  directory, name = FileAsset.split_path(base_path) if base_path and name.blank?
121
- directory.gsub!(Rails.root.to_s,'')
128
+ directory.gsub!(Rails.root.to_s, '')
122
129
 
123
130
  @type ||= FileAsset.type_for(name) if name
124
131
  @type = "TextFile" if @type.nil?
@@ -129,10 +136,37 @@ class FileAsset < ActiveRecord::Base
129
136
  super attributes.merge(:directory => directory, :name => name, :data => data)
130
137
  end
131
138
 
139
+ def check_name_uniqueness
140
+ # check if name is already taken
141
+ unless FileAsset.where('directory = ? and name = ?', self.directory, self.name).first.nil?
142
+ # if it is keeping add incrementing by 1 until we have a good name
143
+ counter = 0
144
+ while true
145
+ counter += 1
146
+
147
+ # break after 25, we don't want in infinite loop
148
+ break if counter == 25
149
+
150
+ new_name = "#{basename}-#{counter}.#{extname}"
151
+
152
+ if FileAsset.where('directory = ? and name = ?', self.directory, new_name).first.nil?
153
+ self.name = new_name
154
+ break
155
+ end
156
+ end
157
+ end
158
+ end
159
+
132
160
  def is_secured?
133
161
  self.protected_with_capability?('download')
134
162
  end
135
163
 
164
+ def copy(path, name)
165
+ file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)
166
+
167
+ file_support.copy(self.path, path, name)
168
+ end
169
+
136
170
  # compass file download url
137
171
  def url
138
172
  "/download/#{self.name}?path=#{self.directory}"
@@ -143,7 +177,7 @@ class FileAsset < ActiveRecord::Base
143
177
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)
144
178
 
145
179
  if ErpTechSvcs::Config.file_storage == :s3
146
- file_path = File.join(self.directory,self.name).sub(%r{^/},'')
180
+ file_path = File.join(self.directory, self.name).sub(%r{^/}, '')
147
181
  options = {}
148
182
  options[:expires] = ErpTechSvcs::Config.s3_url_expires_in_seconds if self.is_secured?
149
183
  return file_support.bucket.objects[file_path].url_for(:read, options).to_s
@@ -152,7 +186,7 @@ class FileAsset < ActiveRecord::Base
152
186
  end
153
187
  end
154
188
 
155
- def save_dimensions
189
+ def save_dimensions
156
190
  if type == 'Image'
157
191
  begin
158
192
  f = Paperclip::Geometry.from_file(self.path)
@@ -160,7 +194,7 @@ class FileAsset < ActiveRecord::Base
160
194
  h = f.height.to_i
161
195
  update_attribute(:width, w) if width != w
162
196
  update_attribute(:height, h) if height != h
163
- rescue Exception=>ex
197
+ rescue => ex
164
198
  Rails.logger.error('Could not save width and height of image. Make sure Image Magick and the identify command are accessible')
165
199
  end
166
200
  end
@@ -168,11 +202,19 @@ class FileAsset < ActiveRecord::Base
168
202
  end
169
203
 
170
204
  def basename
171
- data_file_name.gsub(/\.#{extname}$/, "")
205
+ name.gsub(/\.#{extname}$/, "")
206
+ end
207
+
208
+ def trim_name(size)
209
+ if self.name.length < size
210
+ self.name
211
+ else
212
+ self.name[0..size]
213
+ end
172
214
  end
173
215
 
174
216
  def extname
175
- File.extname(self.data_file_name).gsub(/^\.+/, '')
217
+ File.extname(name).gsub(/^\.+/, '')
176
218
  end
177
219
 
178
220
  def set_sti
data/app/models/group.rb CHANGED
@@ -133,7 +133,7 @@ class Group < ActiveRecord::Base
133
133
  def remove_party(a_party)
134
134
  begin
135
135
  get_relationship(a_party).first.destroy
136
- rescue Exception => e
136
+ rescue => e
137
137
  Rails.logger.error e.message
138
138
  return nil
139
139
  end
@@ -0,0 +1,49 @@
1
+ class Notification < ActiveRecord::Base
2
+ attr_protected :created_at, :updated_at
3
+
4
+ # serialize custom attributes
5
+ is_json :custom_fields
6
+
7
+ belongs_to :notification_type
8
+ belongs_to :created_by, :foreign_key => 'created_by_id', :class_name => 'Party'
9
+
10
+ include AASM
11
+
12
+ aasm_column :current_state
13
+
14
+ aasm_initial_state :pending
15
+
16
+ aasm_state :pending
17
+ aasm_state :notification_delivered
18
+
19
+ aasm_event :delivered_notification do
20
+ transitions :to => :notification_delivered, :from => [:pending]
21
+ end
22
+
23
+ class << self
24
+
25
+ def create_notification_of_type(notification_type, dyn_attributes={}, created_by=nil)
26
+ notification_type = notification_type.class == NotificationType ? notification_type : NotificationType.find_by_internal_identifier(notification_type)
27
+
28
+ notification = self.new(
29
+ created_by: created_by,
30
+ notification_type: notification_type
31
+ )
32
+
33
+ dyn_attributes.each do |k,v|
34
+ notification.custom_fields[k] = v
35
+ end
36
+
37
+ notification.save
38
+
39
+ notification
40
+ end
41
+
42
+ end
43
+
44
+ def deliver_notification
45
+ # template method
46
+ # should be overridden in sub class
47
+ end
48
+
49
+ end