kuppayam 0.1.5 → 0.1.6dev2
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.
- checksums.yaml +4 -4
- data/README.md +13 -0
- data/app/assets/images/{kuppayam/favicon.png → favicon.png} +0 -0
- data/app/assets/images/{kuppayam/logo.png → logo.png} +0 -0
- data/app/assets/javascripts/kuppayam.js +3 -0
- data/app/assets/javascripts/kuppayam/utilities.js +28 -0
- data/app/assets/stylesheets/kuppayam.css +1 -0
- data/app/assets/stylesheets/kuppayam/custom.css +4 -0
- data/app/controllers/kuppayam/base_controller.rb +14 -4
- data/app/controllers/kuppayam/documents_controller.rb +24 -0
- data/app/controllers/kuppayam/images_controller.rb +41 -1
- data/app/helpers/breadcrumbs_helper.rb +1 -1
- data/app/helpers/filter_helper.rb +9 -3
- data/app/helpers/image_helper.rb +11 -3
- data/app/helpers/kuppayam_helper.rb +2 -2
- data/app/helpers/meta_tags_helper.rb +0 -4
- data/app/helpers/notification_helper.rb +6 -6
- data/app/helpers/render_helper.rb +11 -2
- data/app/helpers/resource_helper.rb +23 -9
- data/app/models/document/base.rb +13 -15
- data/app/models/document/import_data_file.rb +14 -0
- data/app/models/document/import_report_file.rb +8 -0
- data/app/models/image/base.rb +12 -14
- data/app/models/import_data.rb +19 -2
- data/app/models/kuppayam/application_record.rb +3 -0
- data/app/uploaders/document_uploader.rb +4 -4
- data/app/uploaders/image_uploader.rb +1 -1
- data/app/uploaders/import_data_uploader.rb +15 -0
- data/app/views/kuppayam/documents/create.html.erb +1 -1
- data/app/views/kuppayam/documents/edit.js.erb +1 -1
- data/app/views/kuppayam/documents/new.js.erb +1 -1
- data/app/views/kuppayam/documents/update.html.erb +1 -1
- data/app/views/kuppayam/filters/_display_dropdown_filters.html.erb +11 -0
- data/app/views/kuppayam/filters/_display_filters.html.erb +29 -0
- data/app/views/kuppayam/http_status/404.html.erb +1 -0
- data/app/views/kuppayam/images/_form.html.erb +1 -1
- data/app/views/kuppayam/images/_index.html.erb +17 -20
- data/app/views/kuppayam/images/_show.html.erb +32 -0
- data/app/views/kuppayam/images/create.html.erb +4 -4
- data/app/views/kuppayam/images/crop.html.erb +1 -1
- data/app/views/kuppayam/images/destroy.js.erb +19 -0
- data/app/views/kuppayam/images/edit.js.erb +3 -3
- data/app/views/kuppayam/images/index.html.erb +8 -1
- data/app/views/kuppayam/images/new.js.erb +1 -1
- data/app/views/kuppayam/images/update.html.erb +5 -5
- data/app/views/kuppayam/import_data/new.js.erb +1 -1
- data/app/views/kuppayam/import_data/update.html.erb +1 -1
- data/app/views/kuppayam/workflows/parrot/create.js.erb +11 -6
- data/app/views/kuppayam/workflows/parrot/edit.js.erb +1 -1
- data/app/views/kuppayam/workflows/parrot/new.js.erb +2 -2
- data/app/views/kuppayam/workflows/parrot/row.js.erb +1 -1
- data/app/views/kuppayam/workflows/parrot/update.js.erb +10 -5
- data/app/views/kuppayam/workflows/peacock/create.js.erb +12 -7
- data/app/views/kuppayam/workflows/peacock/edit.js.erb +2 -2
- data/app/views/kuppayam/workflows/peacock/new.js.erb +2 -2
- data/app/views/kuppayam/workflows/peacock/row.js.erb +1 -1
- data/app/views/kuppayam/workflows/peacock/update.js.erb +11 -6
- data/app/views/layouts/kuppayam/_footer.html.erb +1 -0
- data/app/views/layouts/kuppayam/_head.html.erb +11 -2
- data/app/views/layouts/kuppayam/_heading.html.erb +11 -2
- data/app/views/layouts/kuppayam/_horizontal_menu.html.erb +932 -0
- data/app/views/layouts/kuppayam/_sidebar.html.erb +5 -2
- data/app/views/layouts/kuppayam/admin.html.erb +63 -6
- data/app/views/layouts/kuppayam/blank.html.erb +62 -5
- data/app/views/layouts/kuppayam/document_upload.html.erb +3 -2
- data/app/views/layouts/kuppayam/image_upload.html.erb +3 -2
- data/app/views/layouts/kuppayam/layout_horizontal_menu.html.erb +116 -0
- data/app/views/layouts/kuppayam/print_a4.html.erb +32 -0
- data/app/views/layouts/kuppayam/user.html.erb +120 -0
- data/config/initializers/importer.rb +303 -0
- data/config/initializers/validators.rb +78 -0
- data/config/locales/kuppayam/general.yml +1 -0
- data/config/routes.rb +1 -1
- data/db/migrate/20170000000000_create_images.rb +1 -0
- data/db/migrate/20170000000001_create_documents.rb +2 -1
- data/db/migrate/20170000000002_create_import_data.rb +2 -2
- data/lib/kuppayam/action_view/form_helper.rb +1 -1
- data/lib/kuppayam/action_view/theme_helper.rb +8 -2
- data/lib/kuppayam/engine.rb +2 -0
- data/lib/kuppayam/version.rb +1 -1
- data/lib/tasks/template.rake +72 -0
- data/lib/tasks/test_import.rake +40 -0
- data/vendor/assets/stylesheets/custom.css +0 -0
- metadata +76 -16
- data/app/views/kuppayam/images/_action_buttons.html.erb +0 -14
- data/app/views/layouts/kuppayam/_overlays.html.erb +0 -47
- data/config/initializers/kuppayam_validators.rb +0 -76
- data/lib/tasks/kuppayam_tasks.rake +0 -4
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# require 'axlsx'
|
|
2
|
+
require 'colorized_string'
|
|
3
|
+
# require 'roo'
|
|
4
|
+
require 'benchmark'
|
|
5
|
+
require 'iconv'
|
|
6
|
+
|
|
7
|
+
module Kuppayam
|
|
8
|
+
|
|
9
|
+
module Importer
|
|
10
|
+
|
|
11
|
+
class ErrorHash
|
|
12
|
+
|
|
13
|
+
attr_accessor :warnings,
|
|
14
|
+
:errors
|
|
15
|
+
|
|
16
|
+
def initialize
|
|
17
|
+
@warnings = []
|
|
18
|
+
@errors = []
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def warnings?
|
|
22
|
+
@warnings.any?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def errors?
|
|
26
|
+
@errors.any?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def print_dot
|
|
30
|
+
if self.warnings?
|
|
31
|
+
print ".".yellow
|
|
32
|
+
elsif self.errors?
|
|
33
|
+
print ".".red
|
|
34
|
+
else
|
|
35
|
+
print ".".green
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def print_all
|
|
40
|
+
self.warnings.each do |item|
|
|
41
|
+
puts "Summary: #{item[:summary]}".yellow
|
|
42
|
+
puts "Details: #{item[:details]}".yellow if item[:details]
|
|
43
|
+
puts "Stack Trace: #{item[:stack_trace]}".yellow if item[:stack_trace]
|
|
44
|
+
puts ""
|
|
45
|
+
end
|
|
46
|
+
self.errors.each do |item|
|
|
47
|
+
puts "Summary: #{item[:summary]}".red
|
|
48
|
+
puts "Details: #{item[:details]}".red if item[:details]
|
|
49
|
+
puts "Stack Trace: #{item[:stack_trace]}".red if item[:stack_trace]
|
|
50
|
+
puts ""
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class DataError
|
|
56
|
+
attr_accessor :errors, :columns
|
|
57
|
+
|
|
58
|
+
def initialize
|
|
59
|
+
@errors = {}
|
|
60
|
+
@columns = []
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def add_column_error(name, value, errors, row_number)
|
|
64
|
+
if @errors[row_number].blank?
|
|
65
|
+
@errors[row_number] = {
|
|
66
|
+
name => { value: value, errors: errors }
|
|
67
|
+
}
|
|
68
|
+
else
|
|
69
|
+
@errors[row_number][name] = { value: value, errors: errors }
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def generate_error_file
|
|
74
|
+
|
|
75
|
+
axlsx_package = Axlsx::Package.new
|
|
76
|
+
wb = axlsx_package.workbook
|
|
77
|
+
|
|
78
|
+
normal_cell = s.add_style :bg_color => "FFFFFF", :fg_color => "4B4B4B", :sz => 14, :alignment => { :horizontal=> :center }
|
|
79
|
+
error_cell = s.add_style :bg_color => "FFE2E2", :fg_color => "4B4B4B", :sz => 14, :alignment => { :horizontal=> :center }
|
|
80
|
+
|
|
81
|
+
wb.add_worksheet(:name => "Errors") do |sheet|
|
|
82
|
+
|
|
83
|
+
sheet.add_row self.columns
|
|
84
|
+
|
|
85
|
+
self.errors.each do |row_number, values|
|
|
86
|
+
row_data = self.columns.map{|col| values[col][:value] }
|
|
87
|
+
sheet.add_row row_data
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
axlsx_package.serialize("tmp/example.xlsx")
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def clean_string(str, label=nil)
|
|
96
|
+
begin
|
|
97
|
+
cleaned_str = str.gsub(/\r/, "").gsub(/\n/, "").squeeze(" ")
|
|
98
|
+
cleaned_str = Iconv.conv('UTF-8', 'ISO-8859-1//TRANSLIT//IGNORE', cleaned_str)
|
|
99
|
+
rescue Exception => e
|
|
100
|
+
puts "Error while cleaning #{label ? label : 'string'} '#{str}' - #{e.message}".red
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def check_file_type_and_import(path, single_transaction=true, verbose=true)
|
|
105
|
+
if File.exists?(path)
|
|
106
|
+
if File.extname(path) == ".csv"
|
|
107
|
+
puts "CSV file found at '#{path.to_s}'.".green if verbose
|
|
108
|
+
self.import_from_csv(path.to_s, single_transaction, verbose)
|
|
109
|
+
elsif File.extname(path) == ".xlsx"
|
|
110
|
+
puts "XSLX file found at '#{path.to_s}'.".green if verbose
|
|
111
|
+
self.import_from_xslx(path.to_s, single_transaction, verbose)
|
|
112
|
+
else
|
|
113
|
+
puts "Unsupported File encountered'#{path.to_s}'.".red if verbose
|
|
114
|
+
return
|
|
115
|
+
end
|
|
116
|
+
else
|
|
117
|
+
puts "Import File not found at '#{path.to_s}'.".red if verbose
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def import_from_sql(sql_path, verbose=true)
|
|
122
|
+
|
|
123
|
+
errors = []
|
|
124
|
+
|
|
125
|
+
print_memory_usage do
|
|
126
|
+
print_time_spent do
|
|
127
|
+
sum = 0
|
|
128
|
+
|
|
129
|
+
CSV.foreach(csv_path, headers: true, header_converters: :symbol) do |row|
|
|
130
|
+
obj, error_object = save_row_data(row)
|
|
131
|
+
errors << error_object if error_object
|
|
132
|
+
error_object.print_dot if error_object && verbose
|
|
133
|
+
sum += 1
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
puts "Sum: #{sum}"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
if verbose
|
|
141
|
+
puts ""
|
|
142
|
+
errors.each do |error_object|
|
|
143
|
+
error_object.print_all if error_object
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def import_from_csv(csv_path, single_transaction=true, verbose=true)
|
|
149
|
+
errors = []
|
|
150
|
+
sum = 0
|
|
151
|
+
|
|
152
|
+
# , encoding: 'windows-1251:utf-8', :row_sep => :auto
|
|
153
|
+
if single_transaction
|
|
154
|
+
ActiveRecord::Base.transaction do
|
|
155
|
+
CSV.foreach(csv_path, headers: true, header_converters: :symbol, skip_blanks: true) do |row|
|
|
156
|
+
obj, error_object = save_row_data(row)
|
|
157
|
+
errors << error_object if error_object
|
|
158
|
+
error_object.print_dot if error_object && verbose
|
|
159
|
+
sum += 1
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
else
|
|
163
|
+
CSV.foreach(csv_path, headers: true, header_converters: :symbol, skip_blanks: true) do |row|
|
|
164
|
+
obj, error_object = save_row_data(row)
|
|
165
|
+
errors << error_object if error_object
|
|
166
|
+
error_object.print_dot if error_object && verbose
|
|
167
|
+
sum += 1
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
puts "\tScanned #{sum} rows".yellow
|
|
171
|
+
|
|
172
|
+
if verbose
|
|
173
|
+
puts ""
|
|
174
|
+
errors.each do |error_object|
|
|
175
|
+
error_object.print_all if error_object
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def import_from_xslx(xlsx_path, single_transaction = true, verbose=true)
|
|
181
|
+
xlsx = Roo::Spreadsheet.open(xlsx_path, extension: :xlsx)
|
|
182
|
+
sheet = xlsx.sheet(0)
|
|
183
|
+
headers = sheet.row(1)
|
|
184
|
+
|
|
185
|
+
errors = []
|
|
186
|
+
if single_transaction
|
|
187
|
+
ActiveRecord::Base.transaction do
|
|
188
|
+
2.upto(xlsx.last_row) do |line|
|
|
189
|
+
row_hash = ActiveSupport::HashWithIndifferentAccess[headers.zip(xlsx.row(line))]
|
|
190
|
+
obj, error_object = save_row_data(row_hash)
|
|
191
|
+
errors << error_object if error_object
|
|
192
|
+
error_object.print_dot if error_object && verbose
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
else
|
|
196
|
+
2.upto(xlsx.last_row) do |line|
|
|
197
|
+
row_hash = ActiveSupport::HashWithIndifferentAccess[headers.zip(xlsx.row(line))]
|
|
198
|
+
obj, error_object = save_row_data(row_hash)
|
|
199
|
+
errors << error_object if error_object
|
|
200
|
+
error_object.print_dot if error_object && verbose
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
if verbose
|
|
205
|
+
puts ""
|
|
206
|
+
errors.each do |error_object|
|
|
207
|
+
error_object.print_all if error_object
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def walk_and_import(start, single_transaction=true, verbose=true)
|
|
213
|
+
puts "Importing Files from the Folder '#{start.to_s}'".yellow if verbose
|
|
214
|
+
Dir.foreach(start) do |x|
|
|
215
|
+
next if x.starts_with?("master")
|
|
216
|
+
next unless x.ends_with?(".csv")
|
|
217
|
+
path = File.join(start, x)
|
|
218
|
+
if x == "." or x == ".."
|
|
219
|
+
next
|
|
220
|
+
elsif File.directory?(path)
|
|
221
|
+
self.walk_and_import(path, single_transaction, verbose)
|
|
222
|
+
else
|
|
223
|
+
self.check_file_type_and_import(path, single_transaction, verbose)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def import_data_recursively(path, single_transaction=true, verbose=true)
|
|
229
|
+
print_memory_usage do
|
|
230
|
+
print_time_spent do
|
|
231
|
+
if Dir.exists?(path)
|
|
232
|
+
self.walk_and_import(path, single_transaction, verbose)
|
|
233
|
+
else
|
|
234
|
+
puts "Import Folder not found: '#{path.to_s}'.".red if verbose
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def import_data_file(path, single_transaction=true, verbose=true)
|
|
241
|
+
print_memory_usage do
|
|
242
|
+
print_time_spent do
|
|
243
|
+
check_file_type_and_import(path, single_transaction, verbose)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def print_memory_usage
|
|
249
|
+
memory_before = `ps -o rss= -p #{Process.pid}`.to_i
|
|
250
|
+
yield
|
|
251
|
+
memory_after = `ps -o rss= -p #{Process.pid}`.to_i
|
|
252
|
+
|
|
253
|
+
puts "Memory: #{((memory_after - memory_before) / 1024.0).round(2)} MB"
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def print_time_spent
|
|
257
|
+
time = Benchmark.realtime do
|
|
258
|
+
yield
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
puts "Time: #{time.round(2)}"
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def csv_foreach_backup_code
|
|
265
|
+
# batch_size = 1000
|
|
266
|
+
|
|
267
|
+
# File.open(csv_path) do |file|
|
|
268
|
+
# file.lazy.drop(header_lines).each_slice(batch_size) do |lines|
|
|
269
|
+
# puts lines
|
|
270
|
+
# end
|
|
271
|
+
# end
|
|
272
|
+
|
|
273
|
+
# File.open(csv_path) do |file|
|
|
274
|
+
# binding.pry
|
|
275
|
+
# headers = file.first
|
|
276
|
+
# file.lazy.each_slice(batch_size) do |lines|
|
|
277
|
+
# csv_rows = CSV.parse(lines.join, write_headers: true, headers: headers)
|
|
278
|
+
# csv_rows.each do |row|
|
|
279
|
+
# error_object = save_row_data(row)
|
|
280
|
+
# errors << error_object if error_object
|
|
281
|
+
# error_object.print_dot if error_object
|
|
282
|
+
# sum += 1
|
|
283
|
+
# end
|
|
284
|
+
# end
|
|
285
|
+
# end
|
|
286
|
+
|
|
287
|
+
# rows = CSV.new(File.open(csv_path,'r'), headers: true, header_converters: :symbol).lazy.select do |row|
|
|
288
|
+
# end
|
|
289
|
+
|
|
290
|
+
# binding.pry
|
|
291
|
+
|
|
292
|
+
# rows.each do |row|
|
|
293
|
+
|
|
294
|
+
# error_object = save_row_data(row)
|
|
295
|
+
# errors << error_object if error_object
|
|
296
|
+
# error_object.print_dot if error_object
|
|
297
|
+
# sum += 1
|
|
298
|
+
# end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
module Kuppayam
|
|
2
|
+
module Validators
|
|
3
|
+
|
|
4
|
+
def generate_validation_options(attribute, options)
|
|
5
|
+
{a: 1}
|
|
6
|
+
reg_exp = /\A[a-zA-Z1-9\-\ \(\)\.+]*\z/i
|
|
7
|
+
options.reverse_merge!(
|
|
8
|
+
presence: true,
|
|
9
|
+
min_length: 3,
|
|
10
|
+
max_length: 256,
|
|
11
|
+
format: reg_exp,
|
|
12
|
+
uniqueness: false,
|
|
13
|
+
mandatory: false
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if options.has_key?(:condition_method) && !options[:condition_method].blank?
|
|
17
|
+
condition_proc = proc {|obj| obj.send(options[:condition_method])}
|
|
18
|
+
elsif options.has_key?(:mandatory) && options[:mandatory] == false
|
|
19
|
+
condition_proc = proc {|obj| !obj.send(attribute).blank?}
|
|
20
|
+
else
|
|
21
|
+
condition_proc = nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
voptions = {
|
|
25
|
+
presence: options[:presence],
|
|
26
|
+
length: { minimum: options[:min_length], maximum: options[:max_length]},
|
|
27
|
+
format: {:with => options[:format]}
|
|
28
|
+
}
|
|
29
|
+
voptions.merge!(uniqueness: options[:uniqueness]) if options[:uniqueness]
|
|
30
|
+
voptions.merge!(if: condition_proc) if condition_proc
|
|
31
|
+
|
|
32
|
+
voptions
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def validate_string(attribute, **options)
|
|
36
|
+
voptions = generate_validation_options(attribute, options)
|
|
37
|
+
validates attribute, **voptions
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def validate_username(attribute, **options)
|
|
41
|
+
reg_exp = /\A[a-zA-Z0-9\_\.]*\z/
|
|
42
|
+
options.merge!(mandatory: true, min_length: 3, max_length: 128, format: reg_exp, :uniqueness => {:case_sensitive => false})
|
|
43
|
+
voptions = generate_validation_options(attribute, options)
|
|
44
|
+
validates attribute, **voptions
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def validate_email(attribute, **options)
|
|
48
|
+
reg_exp = /\A(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6})\z/i
|
|
49
|
+
options.merge!(mandatory: true, format: reg_exp, :uniqueness => {:case_sensitive => false})
|
|
50
|
+
voptions = generate_validation_options(attribute, options)
|
|
51
|
+
validates attribute, **voptions
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# format can be either :us or :indian
|
|
55
|
+
def validate_phone(attribute, **options)
|
|
56
|
+
options.reverse_merge!(phone_format: :india)
|
|
57
|
+
if options[:phone_format] == :us
|
|
58
|
+
reg_exp = /\A[0-9]{3}[-][0-9]{3}[-][0-9]{4}\z/
|
|
59
|
+
length = 12
|
|
60
|
+
else
|
|
61
|
+
reg_exp = /\A[0-9]{10}\z/
|
|
62
|
+
length = 10
|
|
63
|
+
end
|
|
64
|
+
options.merge!(format: reg_exp, min_length: length, max_length: length)
|
|
65
|
+
options.reverse_merge!(numericality: true, mandatory: true, uniqueness: true)
|
|
66
|
+
voptions = generate_validation_options(attribute, options)
|
|
67
|
+
validates attribute, **voptions
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def validate_password(attribute, **options)
|
|
71
|
+
reg_exp = /\A(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9!@$#&*_\.,;:])/
|
|
72
|
+
options.merge!(mandatory: true, format: reg_exp, min_length: 7, max_length: 256)
|
|
73
|
+
voptions = generate_validation_options(attribute, options)
|
|
74
|
+
validates attribute, **voptions
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -23,6 +23,7 @@ en:
|
|
|
23
23
|
updated: "%{item} has been updated successfully."
|
|
24
24
|
deleted: "%{item} has been deleted successfully."
|
|
25
25
|
removed: "%{item} has been removed successfully."
|
|
26
|
+
uploaded: "%{item} has been uploaded successfully."
|
|
26
27
|
no_results_found: "No results found."
|
|
27
28
|
state:
|
|
28
29
|
changed: "%{item} has been %{new_state}."
|
data/config/routes.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class CreateDocuments < ActiveRecord::Migration
|
|
1
|
+
class CreateDocuments < ActiveRecord::Migration[5.0]
|
|
2
2
|
def change
|
|
3
3
|
create_table :documents do |t|
|
|
4
4
|
t.string :document
|
|
@@ -8,6 +8,7 @@ class CreateDocuments < ActiveRecord::Migration
|
|
|
8
8
|
t.timestamps
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
add_index(:documents, :document_type)
|
|
11
12
|
add_index(:documents, [ :documentable_id, :documentable_type ])
|
|
12
13
|
end
|
|
13
14
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
class CreateImportData < ActiveRecord::Migration
|
|
1
|
+
class CreateImportData < ActiveRecord::Migration[5.0]
|
|
2
2
|
def change
|
|
3
3
|
create_table :import_data do |t|
|
|
4
4
|
t.integer :importable_id
|
|
5
5
|
t.string :importable_type
|
|
6
|
-
t.string :data_type
|
|
6
|
+
t.string :data_type # CSV, XLSX, XLS
|
|
7
7
|
t.string :status, :null => false, :default=>"pending", :limit=>16
|
|
8
8
|
t.timestamps
|
|
9
9
|
end
|
|
@@ -145,7 +145,7 @@ module Kuppayam
|
|
|
145
145
|
when :text, :email, :search, :password, :date, :time, :tel, :url, :month, :number
|
|
146
146
|
text_field_tag(options[:param_name], object.send(field_name.to_s), **options[:html_options])
|
|
147
147
|
when :textarea
|
|
148
|
-
options[:html_options].
|
|
148
|
+
options[:html_options].reverse_merge!(style: "height: 140px;")
|
|
149
149
|
text_area_tag(options[:param_name], object.send(field_name.to_s), **options[:html_options])
|
|
150
150
|
when :file
|
|
151
151
|
file_field_tag(options[:param_name], **options[:html_options])
|
|
@@ -6,6 +6,8 @@ module Kuppayam
|
|
|
6
6
|
# <i class='fa fa-plus'></i>
|
|
7
7
|
# theme_fa_icon('plus', 'lg')
|
|
8
8
|
# <i class='fa fa-plus fa-lg'></i>
|
|
9
|
+
|
|
10
|
+
# TBR: To Be Removed
|
|
9
11
|
def theme_fa_icon(icon_text, size="")
|
|
10
12
|
size_class = %w{lg 2x 3x 4x 5x}.include?(size.strip) ? " fa-#{size.strip}" : ""
|
|
11
13
|
"<i class='fa fa-#{icon_text}#{size_class}'></i>"
|
|
@@ -13,8 +15,10 @@ module Kuppayam
|
|
|
13
15
|
|
|
14
16
|
# theme_button_text('New Project')
|
|
15
17
|
# <span class='btn-text'> New Project</span>
|
|
18
|
+
|
|
19
|
+
# TBR: To Be Removed
|
|
16
20
|
def theme_button_text(text)
|
|
17
|
-
"<span class='btn-text'> #{text}</span>"
|
|
21
|
+
"<span class='btn-text hidden-sm hidden-xs'> #{text}</span>"
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
# theme_button is used to create buttons which has built in classes and icons
|
|
@@ -24,6 +28,8 @@ module Kuppayam
|
|
|
24
28
|
# link_to raw("<i class='fa fa-plus mr-10'></i><span class='btn-text'> New Project</span>"), new_admin_project_path, :class=>"btn btn-primary pull-right ml-5", :remote=>true
|
|
25
29
|
# And produces the following html
|
|
26
30
|
# <a class="btn btn-primary pull-right ml-5" data-remote="true" href="/admin/projects/new"><i class="fa fa-plus mr-10"></i><span class="btn-text"> New Project</span></a>
|
|
31
|
+
|
|
32
|
+
# TBR: To Be Removed
|
|
27
33
|
def theme_button(text, icon, url, options={})
|
|
28
34
|
options.reverse_merge!(
|
|
29
35
|
method: :get,
|
|
@@ -130,7 +136,7 @@ module Kuppayam
|
|
|
130
136
|
# "No Results found"
|
|
131
137
|
# </div>
|
|
132
138
|
def theme_panel_message(message)
|
|
133
|
-
content_tag(:div, class: "panel panel-default panel-message text-color-grey p-80 text-align-center", style: "height:200px;") do
|
|
139
|
+
content_tag(:div, class: "panel panel-default panel-message text-color-grey p-80 text-align-center", style: "height:200px;width:100%;") do
|
|
134
140
|
raw(message)
|
|
135
141
|
end
|
|
136
142
|
end
|