erp_tech_svcs 3.0.3 → 3.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +15 -0
- data/app/controllers/erp_tech_svcs/session_controller.rb +8 -0
- data/app/controllers/erp_tech_svcs/user_controller.rb +1 -1
- data/app/models/audit_log.rb +1 -0
- data/app/models/file_asset.rb +15 -8
- data/config/initializers/erp_tech_svcs.rb +1 -0
- data/lib/erp_tech_svcs/config.rb +5 -2
- data/lib/erp_tech_svcs/erp_tech_svcs_audit_log.rb +27 -0
- data/lib/erp_tech_svcs/extensions/active_record/has_relational_dynamic_attributes.rb +37 -13
- data/lib/erp_tech_svcs/file_support/railties/s3_resolver.rb +10 -11
- data/lib/erp_tech_svcs/file_support/s3_manager.rb +20 -16
- data/lib/erp_tech_svcs/utils/compass_logger.rb +2 -9
- data/lib/erp_tech_svcs/utils/default_nested_set_methods.rb +24 -3
- data/lib/erp_tech_svcs/version.rb +1 -1
- data/lib/erp_tech_svcs.rb +1 -0
- data/spec/models/file_asset_spec.rb +2 -2
- data/spec/spec_helper.rb +7 -7
- metadata +18 -17
data/README.md
CHANGED
@@ -22,6 +22,20 @@ This engine is implemented with the premise that services like logging, tracing
|
|
22
22
|
- file\_storage
|
23
23
|
- File storage to use either s3 or filesystem.
|
24
24
|
- Default : :filesystem
|
25
|
+
- s3\_url\_expires\_in_seconds
|
26
|
+
- Set expiration in seconds on an S3 url to a secure file
|
27
|
+
- Default : 60
|
28
|
+
- s3\_protocol
|
29
|
+
- Protocol for S3 URLs
|
30
|
+
- 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
|
+
- session\_expires\_in_hours
|
35
|
+
- Used by DeleteExpiredSessionsJob to purge inaactive sessions from database.
|
36
|
+
- Default : 12
|
37
|
+
- compass\_logger\_path
|
38
|
+
- Default : Rails.root/log
|
25
39
|
|
26
40
|
### Override Initializer
|
27
41
|
|
@@ -38,6 +52,7 @@ To override these settings simple create a erp_tech_svcs.rb file in your initial
|
|
38
52
|
config.file_storage = :filesystem # Can be either :s3 or :filesystem
|
39
53
|
config.s3_cache_expires_in_minutes = 60
|
40
54
|
config.session_expires_in_hours = 12 # this is used by DeleteExpiredSessionsJob to purge inaactive sessions from database
|
55
|
+
config.compass_logger_path = "#{Rails.root}/log"
|
41
56
|
end
|
42
57
|
Rails.application.config.erp_tech_svcs.configure!
|
43
58
|
|
@@ -5,6 +5,9 @@ module ErpTechSvcs
|
|
5
5
|
potential_user = User.where('username = ? or email = ?', params[:login], params[:login]).first
|
6
6
|
last_login_at = potential_user.last_login_at unless potential_user.nil?
|
7
7
|
if login(params[:login],params[:password])
|
8
|
+
#log when someone logs in
|
9
|
+
ErpTechSvcs::ErpTechSvcsAuditLog.successful_login(current_user)
|
10
|
+
|
8
11
|
login_to = last_login_at.nil? ? params[:first_login_to] : params[:login_to]
|
9
12
|
login_to = login_to || params[:login_to]
|
10
13
|
request.xhr? ? (render :json => {:success => true, :login_to => login_to}) : (redirect_to login_to)
|
@@ -16,7 +19,12 @@ module ErpTechSvcs
|
|
16
19
|
end
|
17
20
|
|
18
21
|
def destroy
|
22
|
+
logged_out_user = current_user
|
19
23
|
logout
|
24
|
+
|
25
|
+
#log when someone logs out
|
26
|
+
ErpTechSvcs::ErpTechSvcsAuditLog.successful_logout(logged_out_user)
|
27
|
+
|
20
28
|
login_url = params[:login_url].blank? ? ErpTechSvcs::Config.login_url : params[:login_url]
|
21
29
|
redirect_to login_url, :notice => "You have successfully logged out."
|
22
30
|
end
|
data/app/models/audit_log.rb
CHANGED
data/app/models/file_asset.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
|
3
3
|
Paperclip.interpolates(:file_path){|data, style|
|
4
|
-
case
|
4
|
+
case ErpTechSvcs::Config.file_storage
|
5
5
|
when :filesystem
|
6
6
|
file_support = ErpTechSvcs::FileSupport::Base.new
|
7
7
|
File.join(file_support.root,data.instance.directory,data.instance.name)
|
@@ -12,7 +12,7 @@ Paperclip.interpolates(:file_path){|data, style|
|
|
12
12
|
|
13
13
|
Paperclip.interpolates(:file_url){|data, style|
|
14
14
|
url = File.join(data.instance.directory, data.instance.name)
|
15
|
-
case
|
15
|
+
case ErpTechSvcs::Config.file_storage
|
16
16
|
when :filesystem
|
17
17
|
#if public is at the front of this path and we are using file_system remove it
|
18
18
|
dir_pieces = url.split('/')
|
@@ -48,8 +48,8 @@ class FileAsset < ActiveRecord::Base
|
|
48
48
|
|
49
49
|
#paperclip
|
50
50
|
has_attached_file :data,
|
51
|
-
:storage =>
|
52
|
-
:s3_protocol =>
|
51
|
+
:storage => ErpTechSvcs::Config.file_storage,
|
52
|
+
:s3_protocol => ErpTechSvcs::Config.s3_protocol,
|
53
53
|
:s3_permissions => :public_read,
|
54
54
|
:s3_credentials => "#{Rails.root}/config/s3.yml",
|
55
55
|
:path => ":file_path",
|
@@ -59,7 +59,7 @@ class FileAsset < ActiveRecord::Base
|
|
59
59
|
before_post_process :set_content_type
|
60
60
|
|
61
61
|
validates_attachment_presence :data
|
62
|
-
validates_attachment_size :data, :less_than =>
|
62
|
+
validates_attachment_size :data, :less_than => ErpTechSvcs::Config.max_file_size_in_mb.megabytes
|
63
63
|
|
64
64
|
validates :name, :presence => {:message => 'Name can not be blank'}
|
65
65
|
validates_uniqueness_of :name, :scope => [:directory]
|
@@ -150,13 +150,20 @@ class FileAsset < ActiveRecord::Base
|
|
150
150
|
end
|
151
151
|
|
152
152
|
def get_contents
|
153
|
-
file_support = ErpTechSvcs::FileSupport::Base.new(:storage =>
|
153
|
+
file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)
|
154
154
|
file_support.get_contents(File.join(self.directory,self.data_file_name))
|
155
155
|
end
|
156
156
|
|
157
157
|
def move(new_parent_path)
|
158
|
-
file_support = ErpTechSvcs::FileSupport::Base.new(:storage =>
|
159
|
-
|
158
|
+
file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)
|
159
|
+
|
160
|
+
if ErpTechSvcs::Config.file_storage == :filesystem and !self.directory.include?(Rails.root.to_s)
|
161
|
+
old_path = File.join(Rails.root, self.directory, self.name)
|
162
|
+
else
|
163
|
+
old_path = File.join(self.directory, self.name)
|
164
|
+
end
|
165
|
+
|
166
|
+
result, message = file_support.save_move(old_path, new_parent_path)
|
160
167
|
if result
|
161
168
|
self.directory = new_parent_path.gsub(Regexp.new(Rails.root.to_s), '') # strip rails root from new_parent_path, we want relative path
|
162
169
|
self.save
|
@@ -9,5 +9,6 @@ Rails.application.config.erp_tech_svcs.configure do |config|
|
|
9
9
|
config.file_storage = :filesystem # Can be either :s3 or :filesystem
|
10
10
|
config.s3_cache_expires_in_minutes = 60
|
11
11
|
config.session_expires_in_hours = 12 # this is used by DeleteExpiredSessionsJob to purge inaactive sessions from database
|
12
|
+
config.compass_logger_path = "#{Rails.root}/log"
|
12
13
|
end
|
13
14
|
Rails.application.config.erp_tech_svcs.configure!
|
data/lib/erp_tech_svcs/config.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module ErpTechSvcs
|
2
2
|
module Config
|
3
3
|
class << self
|
4
|
+
|
4
5
|
attr_accessor :max_file_size_in_mb,
|
5
6
|
:installation_domain,
|
6
7
|
:login_url,
|
@@ -10,7 +11,8 @@ module ErpTechSvcs
|
|
10
11
|
:s3_protocol,
|
11
12
|
:file_storage,
|
12
13
|
:s3_cache_expires_in_minutes,
|
13
|
-
:session_expires_in_hours
|
14
|
+
:session_expires_in_hours,
|
15
|
+
:compass_logger_path
|
14
16
|
|
15
17
|
def init!
|
16
18
|
@defaults = {
|
@@ -23,7 +25,8 @@ module ErpTechSvcs
|
|
23
25
|
:@s3_protocol => 'https', # Can be either 'http' or 'https'
|
24
26
|
:@file_storage => :filesystem, # Can be either :s3 or :filesystem
|
25
27
|
:@s3_cache_expires_in_minutes => 60,
|
26
|
-
:@session_expires_in_hours => 12 # this is used by DeleteExpiredSessionsJob to purge inactive sessions from database
|
28
|
+
:@session_expires_in_hours => 12, # this is used by DeleteExpiredSessionsJob to purge inactive sessions from database
|
29
|
+
:@compass_logger_path => "#{Rails.root}/log"
|
27
30
|
}
|
28
31
|
end
|
29
32
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ErpTechSvcs
|
2
|
+
class ErpTechSvcsAuditLog
|
3
|
+
class << self
|
4
|
+
|
5
|
+
#log when a user logs out
|
6
|
+
def successful_logout(user)
|
7
|
+
AuditLog.create(
|
8
|
+
:party_id => user.party.id,
|
9
|
+
:event_record => user,
|
10
|
+
:audit_log_type => AuditLogType.find_by_type_and_subtype_iid('application','successful_logout'),
|
11
|
+
:description => "User #{user.username} successfully logged out."
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
#log when a user logs out
|
16
|
+
def successful_login(user)
|
17
|
+
AuditLog.create(
|
18
|
+
:party_id => user.party.id,
|
19
|
+
:event_record => user,
|
20
|
+
:audit_log_type => AuditLogType.find_by_type_and_subtype_iid('application','successful_login'),
|
21
|
+
:description => "User #{user.username} successfully logged in."
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
end #class << self
|
26
|
+
end #ErpTechSvcsAuditLog
|
27
|
+
end #ErpTechSvcs
|
@@ -24,17 +24,41 @@ module ErpTechSvcs
|
|
24
24
|
arel_query = AttributeValue.where('attributed_record_type = ?', self.name)
|
25
25
|
.where(AttributeValue.arel_table[:value].matches("%#{value}%"))
|
26
26
|
|
27
|
+
#if included_type_iids then find where types is equal to given types
|
27
28
|
or_clauses = nil
|
28
|
-
options[:
|
29
|
-
type = AttributeType.where('description = ? or internal_identifier = ?',type_iid,type_iid).first
|
29
|
+
options[:included_type_iids].each do |type_iid|
|
30
|
+
type = AttributeType.where('description = ? or internal_identifier = ?', type_iid, type_iid).first
|
30
31
|
raise "Attribute Type '#{type_iid}' does not exist" if type.nil?
|
31
|
-
or_clauses = or_clauses.nil?
|
32
|
-
|
33
|
-
|
32
|
+
or_clauses = if or_clauses.nil?
|
33
|
+
AttributeValue.arel_table[:attribute_type_id].eq(type.id)
|
34
|
+
else
|
35
|
+
or_clauses.or(AttributeValue.arel_table[:attribute_type_id].eq(type.id))
|
36
|
+
end
|
37
|
+
end if options[:included_type_iids]
|
38
|
+
|
39
|
+
#if excluded_type_iids then find where types is not equal to
|
40
|
+
or_clauses = nil
|
41
|
+
options[:excluded_type_iids].each do |type_iid|
|
42
|
+
type = AttributeType.where('description = ? or internal_identifier = ?', type_iid, type_iid).first
|
43
|
+
raise "Attribute Type '#{type_iid}' does not exist" if type.nil?
|
44
|
+
or_clauses = if or_clauses.nil?
|
45
|
+
AttributeValue.arel_table[:attribute_type_id].eq(type.id).not
|
46
|
+
else
|
47
|
+
or_clauses.or(AttributeValue.arel_table[:attribute_type_id].eq(type.id).not)
|
48
|
+
end
|
49
|
+
end if options[:excluded_type_iids]
|
50
|
+
|
34
51
|
arel_query = arel_query.where(or_clauses) if or_clauses
|
52
|
+
|
53
|
+
#get total_count if we need to return it
|
54
|
+
total_count = arel_query.count('attributed_record_id') if options[:return_total_count]
|
55
|
+
|
35
56
|
arel_query = arel_query.limit(options[:limit]) if options[:limit]
|
36
57
|
arel_query = arel_query.offset(options[:offset]) if options[:offset]
|
37
|
-
arel_query.all.collect(&:attributed_record)
|
58
|
+
records = arel_query.all.collect(&:attributed_record)
|
59
|
+
|
60
|
+
#return total_count if option passed
|
61
|
+
options[:return_total_count] ? (return records, total_count) : records
|
38
62
|
end
|
39
63
|
end
|
40
64
|
|
@@ -71,7 +95,7 @@ module ErpTechSvcs
|
|
71
95
|
attribute_value = self.attribute_values.includes(:attribute_type).where('attribute_types.internal_identifier = ? or attribute_types.description = ?', attribute_type_iid.to_s, attribute_type_iid.to_s).first
|
72
96
|
attribute_value.nil? ? nil : attribute_value
|
73
97
|
end
|
74
|
-
|
98
|
+
|
75
99
|
def assign_dynamic_attribute_on_save
|
76
100
|
#template method overridden in implementing class
|
77
101
|
end
|
@@ -83,7 +107,7 @@ module ErpTechSvcs
|
|
83
107
|
def destroy_dynamic_attribute_of_type (attribute_type_iid)
|
84
108
|
self.attribute_values.includes(:attribute_type).destroy_all("attribute_types.internal_identifier = #{attribute_type_iid.to_s} or attribute_types.description = #{attribute_type_iid.to_s}")
|
85
109
|
end
|
86
|
-
|
110
|
+
|
87
111
|
def add_dynamic_attribute(value, type, data_type)
|
88
112
|
attribute_type = AttributeType.where('description = ? or internal_identifier = ?', type, type).first
|
89
113
|
attribute_type = AttributeType.create(:description => type, :data_type => data_type) unless attribute_type
|
@@ -97,8 +121,8 @@ module ErpTechSvcs
|
|
97
121
|
end
|
98
122
|
|
99
123
|
end
|
100
|
-
|
101
|
-
end#HasRelationalDynamicAttributes
|
102
|
-
end#ActiveRecord
|
103
|
-
end#Extensions
|
104
|
-
end#ErpTechSvcs
|
124
|
+
|
125
|
+
end #HasRelationalDynamicAttributes
|
126
|
+
end #ActiveRecord
|
127
|
+
end #Extensions
|
128
|
+
end #ErpTechSvcs
|
@@ -26,15 +26,10 @@ module ActionView
|
|
26
26
|
@cached[key][name][prefix][partial][locals] = decorate(yield, path_info, details, locals)
|
27
27
|
else
|
28
28
|
@cached[key][name][prefix][partial][locals].each do |template|
|
29
|
+
@cached[key][name][prefix][partial][locals].delete_if{|item| item.identifier == template.identifier}
|
29
30
|
#check if the file still exists
|
30
31
|
if file_support.exists? template.identifier
|
31
|
-
|
32
|
-
if last_update > template.updated_at
|
33
|
-
@cached[key][name][prefix][partial][locals].delete_if{|item| item.identifier == template.identifier}
|
34
|
-
@cached[key][name][prefix][partial][locals] << build_template(template.identifier, template.virtual_path, (details[:formats] || [:html] if template.formats.empty?), file_support, template.locals)
|
35
|
-
end
|
36
|
-
else
|
37
|
-
@cached[key][name][prefix][partial][locals].delete_if{|item| item.identifier == template.identifier}
|
32
|
+
@cached[key][name][prefix][partial][locals] << build_template(template.identifier, template.virtual_path, (details[:formats] || [:html] if template.formats.empty?), file_support, template.locals)
|
38
33
|
end
|
39
34
|
end
|
40
35
|
@cached[key][name][prefix][partial][locals]
|
@@ -74,18 +69,22 @@ module ActionView
|
|
74
69
|
end
|
75
70
|
|
76
71
|
protected
|
77
|
-
|
72
|
+
|
73
|
+
def cache_key(path)
|
74
|
+
path.sub!(%r{^/},'')
|
75
|
+
Thread.current[:tenant_id].nil? ? path : "tenant_#{Thread.current[:tenant_id]}_#{path}"
|
76
|
+
end
|
77
|
+
|
78
78
|
def cache_template(path, file_support)
|
79
79
|
contents, message = file_support.get_contents(path)
|
80
|
-
path = path.sub(%r{^/},'')
|
81
80
|
#Rails.logger.info "creating cache with key: #{path}"
|
82
|
-
Rails.cache.write(path, contents, :expires_in => ErpTechSvcs::Config.s3_cache_expires_in_minutes.minutes)
|
81
|
+
Rails.cache.write(cache_key(path), contents, :expires_in => ErpTechSvcs::Config.s3_cache_expires_in_minutes.minutes)
|
83
82
|
return contents, message
|
84
83
|
end
|
85
84
|
|
86
85
|
def build_template(p, virtual_path, formats, file_support, locals=nil)
|
87
86
|
handler, format = extract_handler_and_format(p, formats)
|
88
|
-
contents = Rails.cache.read(p
|
87
|
+
contents = Rails.cache.read(cache_key(p))
|
89
88
|
if contents.nil?
|
90
89
|
contents, message = cache_template(p, file_support)
|
91
90
|
else
|
@@ -22,7 +22,6 @@ module ErpTechSvcs
|
|
22
22
|
)
|
23
23
|
|
24
24
|
@@s3_bucket = @@s3_connection.buckets[@@configuration['bucket'].to_sym]
|
25
|
-
build_node_tree(true)
|
26
25
|
end
|
27
26
|
|
28
27
|
def reload
|
@@ -30,7 +29,7 @@ module ErpTechSvcs
|
|
30
29
|
end
|
31
30
|
|
32
31
|
def cache_key
|
33
|
-
|
32
|
+
Thread.current[:tenant_id].nil? ? 'node_tree' : "tenant_#{Thread.current[:tenant_id]}_node_tree"
|
34
33
|
end
|
35
34
|
|
36
35
|
def cache_node_tree(node_tree)
|
@@ -50,7 +49,9 @@ module ErpTechSvcs
|
|
50
49
|
:children => []
|
51
50
|
}
|
52
51
|
child_hash = add_children(child_hash, child) unless child.leaf?
|
53
|
-
parent_hash[:
|
52
|
+
unless child_hash[:id].gsub(/\/$/,'') == parent_hash[:id].gsub(/\/$/,'') # resolves s3 issue where empty dir contains itself
|
53
|
+
parent_hash[:children] << child_hash unless child_hash[:downloadPath] == '/.'
|
54
|
+
end
|
54
55
|
end
|
55
56
|
|
56
57
|
parent_hash
|
@@ -97,21 +98,26 @@ module ErpTechSvcs
|
|
97
98
|
end
|
98
99
|
|
99
100
|
def update_file(path, content)
|
101
|
+
file = FileAsset.where(:name => ::File.basename(path)).where(:directory => ::File.dirname(path)).first
|
102
|
+
acl = (file.has_capabilities? ? :private : :public_read) unless file.nil?
|
103
|
+
options = (file.nil? ? {} : {:acl => acl})
|
100
104
|
path = path.sub(%r{^/},'')
|
101
|
-
bucket.objects[path].write(content)
|
105
|
+
bucket.objects[path].write(content, options)
|
102
106
|
clear_cache(path)
|
103
107
|
end
|
104
108
|
|
105
109
|
def create_file(path, name, content)
|
106
110
|
path = path.sub(%r{^/},'')
|
107
|
-
|
111
|
+
full_filename = (path.blank? ? name : File.join(path, name))
|
112
|
+
bucket.objects[full_filename].write(content, { :acl => :public_read })
|
108
113
|
clear_cache(path)
|
109
114
|
end
|
110
115
|
|
111
116
|
def create_folder(path, name)
|
112
117
|
path = path.sub(%r{^/},'')
|
113
|
-
|
114
|
-
|
118
|
+
full_filename = (path.blank? ? name : File.join(path, name))
|
119
|
+
folder = full_filename + "/"
|
120
|
+
bucket.objects[folder].write('', { :acl => :public_read })
|
115
121
|
clear_cache(path)
|
116
122
|
end
|
117
123
|
|
@@ -174,13 +180,12 @@ module ErpTechSvcs
|
|
174
180
|
end
|
175
181
|
|
176
182
|
def delete_file(path, options={})
|
183
|
+
is_directory = !path.match(/\/$/).nil?
|
177
184
|
path = path.sub(%r{^/},'')
|
178
185
|
result = false
|
179
186
|
message = nil
|
180
|
-
|
181
187
|
begin
|
182
|
-
|
183
|
-
if options[:force] or bucket.as_tree(:prefix => path).children.count == 0
|
188
|
+
if options[:force] or bucket.as_tree(:prefix => path).children.count <= 1 # aws-sdk includes the folder itself as a child (like . is current dir), this needs revisited as <= 1 is scary
|
184
189
|
bucket.objects.with_prefix(path).delete_all
|
185
190
|
message = "File was deleted successfully"
|
186
191
|
result = true
|
@@ -189,8 +194,8 @@ module ErpTechSvcs
|
|
189
194
|
message = FOLDER_IS_NOT_EMPTY
|
190
195
|
end
|
191
196
|
rescue Exception => e
|
192
|
-
|
193
|
-
|
197
|
+
result = false
|
198
|
+
message = e
|
194
199
|
end
|
195
200
|
|
196
201
|
return result, message, is_directory
|
@@ -199,7 +204,7 @@ module ErpTechSvcs
|
|
199
204
|
def exists?(path)
|
200
205
|
begin
|
201
206
|
path = path.sub(%r{^/},'')
|
202
|
-
|
207
|
+
return bucket.objects[path].exists?
|
203
208
|
rescue AWS::S3::Errors::NoSuchKey
|
204
209
|
return false
|
205
210
|
end
|
@@ -212,18 +217,17 @@ module ErpTechSvcs
|
|
212
217
|
path = path.sub(%r{^/},'')
|
213
218
|
begin
|
214
219
|
object = bucket.objects[path]
|
220
|
+
contents = object.read
|
215
221
|
rescue AWS::S3::Errors::NoSuchKey => error
|
222
|
+
contents = ''
|
216
223
|
message = FILE_DOES_NOT_EXIST
|
217
224
|
end
|
218
225
|
|
219
|
-
contents = object.read if message.nil?
|
220
|
-
|
221
226
|
return contents, message
|
222
227
|
end
|
223
228
|
|
224
229
|
def build_tree(starting_path, options={})
|
225
230
|
starting_path = "/" + starting_path unless starting_path.first == "/"
|
226
|
-
#ErpTechSvcs::FileSupport::S3Manager.reload
|
227
231
|
node_tree = find_node(starting_path, options)
|
228
232
|
node_tree.nil? ? [] : node_tree
|
229
233
|
end
|
@@ -67,10 +67,7 @@ module ErpTechSvcs
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def CompassLogger.app_logger()
|
70
|
-
path = "#{Rails.
|
71
|
-
unless RUBY_PLATFORM =~ /(:?mswin|mingw|darwin)/
|
72
|
-
path = "/var/log/rails/#{Rails.env rescue 'rake'}.log"
|
73
|
-
end
|
70
|
+
path = File.join(ErpTechSvcs::Config.compass_logger_path, "#{Rails.env rescue 'rake'}.log")
|
74
71
|
unless @@writers.has_key?("app_logger")
|
75
72
|
logger = Logger.new(path)
|
76
73
|
logger.level = CompassLogger.log_level()
|
@@ -83,11 +80,7 @@ module ErpTechSvcs
|
|
83
80
|
end
|
84
81
|
|
85
82
|
def CompassLogger.log_path(method)
|
86
|
-
|
87
|
-
return "#{Rails.root}/log/#{Rails.env rescue ''}_#{method}.log"
|
88
|
-
else
|
89
|
-
return "/var/log/rails/#{Rails.env rescue ''}_#{method}.log"
|
90
|
-
end
|
83
|
+
File.join(ErpTechSvcs::Config.compass_logger_path, "#{Rails.env rescue ''}_#{method}.log")
|
91
84
|
end
|
92
85
|
end
|
93
86
|
end
|
@@ -38,9 +38,30 @@ module ErpTechSvcs
|
|
38
38
|
def find_children(parent_id = nil)
|
39
39
|
parent_id.to_i == 0 ? self.roots : find(parent_id).children
|
40
40
|
end
|
41
|
+
|
42
|
+
# find_by_ancestor_iids
|
43
|
+
# allows you to find a nested set element by the internal_identifiers in its ancestry
|
44
|
+
# for example, to find a GlAccount whose internal_identifier is “site_4”, and whose parent’s internal_identifier is “nightly_room_charge”
|
45
|
+
# and whose grandparent’s internal_identifier is “charge”, you would make this call:
|
46
|
+
# gl_account = GlAccount.find_by_iids(['charge', 'nightly_room_charge', "site_4"])
|
47
|
+
def find_by_ancestor_iids(iids)
|
48
|
+
return nil unless iids.is_a? Array
|
49
|
+
|
50
|
+
node = nil
|
51
|
+
iids.each do |iid|
|
52
|
+
if (iid == iids.first)
|
53
|
+
node = where("parent_id is null and internal_identifier = ?",iid).first
|
54
|
+
else
|
55
|
+
node = where("parent_id = ? and internal_identifier = ?",node.id,iid).first
|
56
|
+
end
|
57
|
+
return nil if node.nil?
|
58
|
+
end
|
59
|
+
return node
|
60
|
+
end
|
61
|
+
|
41
62
|
end
|
42
63
|
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
64
|
+
end #DefaultNestedSetMethods
|
65
|
+
end #Utils
|
66
|
+
end #ErpTechSvcs
|
46
67
|
|
data/lib/erp_tech_svcs.rb
CHANGED
@@ -18,6 +18,7 @@ require "erp_tech_svcs/config"
|
|
18
18
|
require "erp_tech_svcs/engine"
|
19
19
|
require 'erp_tech_svcs/sessions/delete_expired_sessions_job'
|
20
20
|
require 'erp_tech_svcs/sessions/delete_expired_sessions_service'
|
21
|
+
require 'erp_tech_svcs/erp_tech_svcs_audit_log'
|
21
22
|
|
22
23
|
module ErpTechSvcs
|
23
24
|
end
|
@@ -28,7 +28,7 @@ describe FileAsset do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should have method to get all valid extensions for all subclasses" do
|
31
|
-
FileAsset.all_valid_extensions.should eq [".jpg", ".jpeg", ".gif", ".png", ".ico", ".PNG", ".JPEG", ".JPG", ".txt", ".text", ".js", ".css", ".erb", ".haml", ".liquid", ".builder", ".html", ".pdf"]
|
31
|
+
FileAsset.all_valid_extensions.should eq [".jpg", ".jpeg", ".gif", ".png", ".ico", ".PNG", ".JPEG", ".JPG", ".txt", ".text", ".js", ".css", ".erb", ".haml", ".liquid", ".builder", ".html", ".pdf", ".swf"]
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should be able to lookup subclass based on extension" do
|
@@ -60,7 +60,7 @@ describe FileAsset do
|
|
60
60
|
new_path = File.join(Rails.root.to_s, 'move_test_tmp')
|
61
61
|
|
62
62
|
File.exists?(@base_path).should eq true
|
63
|
-
|
63
|
+
|
64
64
|
result, message = @file_asset.move(new_path)
|
65
65
|
result.should eq true
|
66
66
|
File.exists?(@base_path).should eq false
|
data/spec/spec_helper.rb
CHANGED
@@ -39,15 +39,15 @@ end
|
|
39
39
|
|
40
40
|
Spork.each_run do
|
41
41
|
#We have to execute the migrations from dummy app directory
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
Dir.chdir DUMMY_APP_ROOT
|
43
|
+
`rake db:drop`
|
44
|
+
Dir.chdir ENGINE_RAILS_ROOT
|
45
45
|
|
46
46
|
#We have to execute the migrations from dummy app directory
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
Dir.chdir DUMMY_APP_ROOT
|
48
|
+
`rake db:migrate`
|
49
|
+
`rake db:migrate_data`
|
50
|
+
Dir.chdir ENGINE_RAILS_ROOT
|
51
51
|
|
52
52
|
ErpDevSvcs::FactorySupport.load_engine_factories
|
53
53
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: erp_tech_svcs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: erp_base_erp_svcs
|
16
|
-
requirement: &
|
16
|
+
requirement: &70358048882360 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70358048882360
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: erp_dev_svcs
|
27
|
-
requirement: &
|
27
|
+
requirement: &70358048879120 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '3.0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70358048879120
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: aws-sdk
|
38
|
-
requirement: &
|
38
|
+
requirement: &70358048933700 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - =
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.5.2
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70358048933700
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: delayed_job_active_record
|
49
|
-
requirement: &
|
49
|
+
requirement: &70358048932000 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - =
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 0.3.2
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70358048932000
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: paperclip
|
60
|
-
requirement: &
|
60
|
+
requirement: &70358048930880 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - =
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 3.0.2
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70358048930880
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: pdfkit
|
71
|
-
requirement: &
|
71
|
+
requirement: &70358048929460 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - =
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 0.4.6
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70358048929460
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: sorcery
|
82
|
-
requirement: &
|
82
|
+
requirement: &70358048927460 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - =
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: 0.7.7
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70358048927460
|
91
91
|
description: This engine is implemented with the premise that services like logging,
|
92
92
|
tracing and encryption would likely already exist in many organizations, so they
|
93
93
|
are factored here so they can easily be re-implemented. There are default implementations
|
@@ -149,6 +149,7 @@ files:
|
|
149
149
|
- lib/erp_tech_svcs/application_installer.rb
|
150
150
|
- lib/erp_tech_svcs/config.rb
|
151
151
|
- lib/erp_tech_svcs/engine.rb
|
152
|
+
- lib/erp_tech_svcs/erp_tech_svcs_audit_log.rb
|
152
153
|
- lib/erp_tech_svcs/extensions/active_record/acts_as_versioned.rb
|
153
154
|
- lib/erp_tech_svcs/extensions/active_record/has_capabilities.rb
|
154
155
|
- lib/erp_tech_svcs/extensions/active_record/has_file_assets.rb
|
@@ -239,7 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
239
240
|
version: '0'
|
240
241
|
requirements: []
|
241
242
|
rubyforge_project:
|
242
|
-
rubygems_version: 1.8.
|
243
|
+
rubygems_version: 1.8.11
|
243
244
|
signing_key:
|
244
245
|
specification_version: 3
|
245
246
|
summary: This engine is implemented with the premise that services like logging, tracing
|