erp_tech_svcs 3.1.8 → 4.0.0

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 (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