hatio-core 0.0.6

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 (93) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +28 -0
  4. data/Rakefile +6 -0
  5. data/lib/generators/hatio/bundle/USAGE +68 -0
  6. data/lib/generators/hatio/bundle/bundle_generator.rb +100 -0
  7. data/lib/generators/hatio/bundle/templates/04_seed_entities.rb +9 -0
  8. data/lib/generators/hatio/bundle/templates/05_seed_common_codes.rb +8 -0
  9. data/lib/generators/hatio/bundle/templates/06_seed_menus.rb +6 -0
  10. data/lib/generators/hatio/bundle/templates/Controller.js +24 -0
  11. data/lib/generators/hatio/bundle/templates/Gemfile +4 -0
  12. data/lib/generators/hatio/bundle/templates/LICENSE.txt +22 -0
  13. data/lib/generators/hatio/bundle/templates/README.md +29 -0
  14. data/lib/generators/hatio/bundle/templates/Rakefile +1 -0
  15. data/lib/generators/hatio/bundle/templates/engine.rb +7 -0
  16. data/lib/generators/hatio/bundle/templates/gemspec +19 -0
  17. data/lib/generators/hatio/bundle/templates/index.js +14 -0
  18. data/lib/generators/hatio/bundle/templates/init.rb +1 -0
  19. data/lib/generators/hatio/bundle/templates/lib_bundle.rb +12 -0
  20. data/lib/generators/hatio/bundle/templates/locale.js +13 -0
  21. data/lib/generators/hatio/bundle/templates/locales.yml +27 -0
  22. data/lib/generators/hatio/bundle/templates/pluggable_spot.rb +3 -0
  23. data/lib/generators/hatio/bundle/templates/routes.rb +3 -0
  24. data/lib/generators/hatio/bundle/templates/seeds.rb +4 -0
  25. data/lib/generators/hatio/bundle/templates/task.rake +4 -0
  26. data/lib/generators/hatio/bundle/templates/test.rb +8 -0
  27. data/lib/generators/hatio/bundle/templates/test_helper.rb +3 -0
  28. data/lib/generators/hatio/bundle/templates/version.rb +3 -0
  29. data/lib/generators/hatio/resource_api/resource_api_generator.rb +92 -0
  30. data/lib/generators/hatio/resource_api/templates/controller.rb +7 -0
  31. data/lib/generators/hatio/resource_api/templates/create.json.jbuilder +1 -0
  32. data/lib/generators/hatio/resource_api/templates/destroy.json.jbuilder +1 -0
  33. data/lib/generators/hatio/resource_api/templates/index.json.jbuilder +1 -0
  34. data/lib/generators/hatio/resource_api/templates/migration.rb +1 -0
  35. data/lib/generators/hatio/resource_api/templates/model.rb +3 -0
  36. data/lib/generators/hatio/resource_api/templates/show.json.jbuilder +3 -0
  37. data/lib/generators/hatio/resource_api/templates/update.json.jbuilder +2 -0
  38. data/lib/generators/hatio/resource_model/resource_model_generator.rb +52 -0
  39. data/lib/generators/hatio/resource_model/templates/migration.rb +1 -0
  40. data/lib/generators/hatio/resource_model/templates/model.rb +3 -0
  41. data/lib/generators/hatio/resource_view/USAGE +16 -0
  42. data/lib/generators/hatio/resource_view/resource_view_generator.rb +154 -0
  43. data/lib/generators/hatio/resource_view/templates/Model.js +19 -0
  44. data/lib/generators/hatio/resource_view/templates/Store.js +34 -0
  45. data/lib/generators/hatio/resource_view/templates/detail/Controller.js +81 -0
  46. data/lib/generators/hatio/resource_view/templates/detail/DetailForm.js +17 -0
  47. data/lib/generators/hatio/resource_view/templates/detail/DetailMain.js +26 -0
  48. data/lib/generators/hatio/resource_view/templates/detail/DetailPopup.js +25 -0
  49. data/lib/generators/hatio/resource_view/templates/detail/PopupController.js +90 -0
  50. data/lib/generators/hatio/resource_view/templates/detail/ViewController.js +78 -0
  51. data/lib/generators/hatio/resource_view/templates/item/Controller.js +81 -0
  52. data/lib/generators/hatio/resource_view/templates/item/ItemForm.js +19 -0
  53. data/lib/generators/hatio/resource_view/templates/item/ItemMain.js +18 -0
  54. data/lib/generators/hatio/resource_view/templates/item/ItemPopup.js +25 -0
  55. data/lib/generators/hatio/resource_view/templates/item/PopupController.js +90 -0
  56. data/lib/generators/hatio/resource_view/templates/item/ViewController.js +47 -0
  57. data/lib/generators/hatio/resource_view/templates/list/Controller.js +36 -0
  58. data/lib/generators/hatio/resource_view/templates/list/ListGrid.js +10 -0
  59. data/lib/generators/hatio/resource_view/templates/list/ListMain.js +20 -0
  60. data/lib/generators/hatio/resource_view/templates/list/ListSearch.js +9 -0
  61. data/lib/generators/hatio/resource_view/templates/report/Controller.js +53 -0
  62. data/lib/generators/hatio/resource_view/templates/report/ReportList.js +27 -0
  63. data/lib/generators/hatio/resource_view/templates/report/ReportMain.js +18 -0
  64. data/lib/generators/hatio/resource_view/templates/report/ReportSearch.js +9 -0
  65. data/lib/generators/hatio/util/api_util.rb +97 -0
  66. data/lib/generators/hatio/util/migration_util.rb +178 -0
  67. data/lib/generators/hatio/util/model_util.rb +77 -0
  68. data/lib/generators/hatio/util/report_view_util.rb +32 -0
  69. data/lib/generators/hatio/util/resource_view_util.rb +383 -0
  70. data/lib/generators/hatio/util/view_util.rb +214 -0
  71. data/lib/hatio-core.rb +33 -0
  72. data/lib/hatio-core/action_controller/search_helper.rb +332 -0
  73. data/lib/hatio-core/active_record/extension_logic.rb +36 -0
  74. data/lib/hatio-core/active_record/rem_tracker.rb +35 -0
  75. data/lib/hatio-core/active_record/stringified_id.rb +75 -0
  76. data/lib/hatio-core/active_record/stripper.rb +37 -0
  77. data/lib/hatio-core/active_record/userstamp.rb +48 -0
  78. data/lib/hatio-core/birt/birt_report.rb +42 -0
  79. data/lib/hatio-core/bundle/hatio_bundle.rb +37 -0
  80. data/lib/hatio-core/engine.rb +5 -0
  81. data/lib/hatio-core/exception/exceptions.rb +33 -0
  82. data/lib/hatio-core/patch/actionpack_hatio_patch.rb +28 -0
  83. data/lib/hatio-core/patch/date.rb +11 -0
  84. data/lib/hatio-core/patch/string_key.rb +56 -0
  85. data/lib/hatio-core/pluggable/pluggable_spot.rb +22 -0
  86. data/lib/hatio-core/util/hatio_util.rb +106 -0
  87. data/lib/hatio-core/version.rb +3 -0
  88. data/lib/tasks/hatiocore_tasks.rake +75 -0
  89. data/lib/utils/detect_invalid_js_format.rb +0 -0
  90. data/lib/utils/detect_mismatch_tags.rb +57 -0
  91. data/lib/utils/update_license.rb +5 -0
  92. data/lib/utils/upload_locale.rb +67 -0
  93. metadata +148 -0
@@ -0,0 +1,178 @@
1
+ module Hatio
2
+ module Generators
3
+ class MigrationUtil
4
+
5
+ #
6
+ # 입력한 attributes들로 부터 GeneratedAttribute를 생성하여 array로 리턴
7
+ #
8
+ def self.generated_attributes(model_attributes)
9
+ attrs = []
10
+ model_attributes.each do |attribute|
11
+ attrs << Rails::Generators::GeneratedAttribute.new(*attribute.split(":")) if attribute.include?(":")
12
+ end
13
+ return attrs
14
+ end
15
+
16
+ #
17
+ # generate db migration file number
18
+ #
19
+ def self.next_migration_number
20
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
21
+ end
22
+
23
+ #
24
+ # id option str
25
+ #
26
+ def self.id_option_str(id_type)
27
+ if(id_type == 'auto-increment')
28
+ return ''
29
+ elsif(id_type == 'none')
30
+ return ",:id => false"
31
+ else
32
+ return ",:id => :#{id_type}"
33
+ end
34
+ end
35
+
36
+ #
37
+ # 입력된 attributes로 부터 migration fields를 추가
38
+ #
39
+ def self.add_migration_fields(attributes)
40
+ output, userstampable, timestampable = "", false, false
41
+
42
+ attributes.each do |attr|
43
+ if (attr.name == 'id')
44
+ elsif(attr.name == 'domain_id')
45
+ output << "\t\t\tt.references :domain, :null => false\n"
46
+ elsif(attr.name == 'creator_id' || attr.name == 'updater_id')
47
+ userstampable = true
48
+ elsif(attr.name == 'created_at' || attr.name == 'updated_at')
49
+ timestampable = true
50
+ elsif(attr.name == 'name')
51
+ output << "\t\t\tt.references :name, :null => false, :limit => 64\n"
52
+ else
53
+ begin
54
+ output << "\t\t\tt.#{attr.type} :#{attr.name}\n"
55
+ rescue
56
+ output << "\t\t\tt.#{attr.col_type} :#{attr.name}\n"
57
+ end
58
+ end
59
+ end
60
+
61
+ output << "\t\t\tt.userstamps\n" if userstampable
62
+ output << "\t\t\tt.timestamps\n" if timestampable
63
+ output
64
+ end
65
+
66
+ #
67
+ # add migration index
68
+ #
69
+ def self.add_migration_index(table_name, attributes)
70
+ output, index_seq = "", 0
71
+ domain_id_attr = attributes.find { |attr| attr.name == 'domain_id' }
72
+ name_attr = attributes.find { |attr| attr.name == 'name' }
73
+ updated_at_attr = attributes.find { |attr| attr.name == 'updated_at' }
74
+
75
+ uniq_cols = attributes.select { |col| col.uniq_rank > 0 }.sort_by(&:uniq_rank)
76
+ if(!uniq_cols.empty?)
77
+ uniq_col_names = uniq_cols.map { |col| ":#{col.name}" }.join(",")
78
+ output << "\t\tadd_index :#{table_name}, [#{uniq_col_names}], :unique => true, :name => :ix_#{table_name}_#{index_seq}\n"
79
+ index_seq += 1
80
+ end
81
+
82
+ if(domain_id_attr && updated_at_attr)
83
+ output << "\t\tadd_index :#{table_name}, [:domain_id, :updated_at], :name => :ix_#{table_name}_#{index_seq}\n"
84
+ index_seq += 1
85
+ elsif(updated_at_attr)
86
+ output << "\t\tadd_index :#{table_name}, [:updated_at], :name => :ix_#{table_name}_#{index_seq}\n"
87
+ index_seq += 1
88
+ end
89
+
90
+ output
91
+ end
92
+
93
+ #
94
+ # remove migration index
95
+ #
96
+ def self.remove_migration_index(table_name, attributes)
97
+ output, index_seq = "", 0
98
+ domain_id_attr = attributes.find { |attr| attr.name == 'domain_id' }
99
+ name_attr = attributes.find { |attr| attr.name == 'name' }
100
+ updated_at_attr = attributes.find { |attr| attr.name == 'updated_at' }
101
+
102
+ uniq_cols = attributes.select { |col| col.uniq_rank > 0 }.sort_by(&:uniq_rank)
103
+ if(!uniq_cols.empty?)
104
+ uniq_col_names = uniq_cols.map { |col| ":#{col.name}" }.join(",")
105
+ output << "\t\tremove_index :#{table_name}, [#{uniq_col_names}], :unique => true, :name => :ix_#{table_name}_#{index_seq}\n"
106
+ index_seq += 1
107
+ end
108
+
109
+ if(domain_id_attr && updated_at_attr)
110
+ output << "\t\tremove_index :#{table_name}, [:domain_id, :updated_at], :name => :ix_#{table_name}_#{index_seq}\n"
111
+ index_seq += 1
112
+ elsif(updated_at_attr)
113
+ output << "\t\tremove_index :#{table_name}, [:updated_at], :name => :ix_#{table_name}_#{index_seq}\n"
114
+ index_seq += 1
115
+ end
116
+
117
+ output
118
+ end
119
+
120
+ #
121
+ # table migration 내용 생성
122
+ #
123
+ def self.create_table_migration(class_name, table_name, attributes, options, pk_col_name)
124
+ id_option = self.id_option_str(options.id_type)
125
+ id_option = ":id => false" if(pk_col_name && pk_col_name != 'id')
126
+
127
+ output = "class Create#{class_name.pluralize} < ActiveRecord::Migration\n\n"
128
+ output << "\tdef change\n"
129
+ output << "\t\tcreate_table #{table_name.to_sym.inspect} #{id_option} do |t|\n"
130
+ output << "#{Hatio::Generators::MigrationUtil.add_migration_columns(attributes, pk_col_name)}"
131
+ output << "\t\tend\n\n"
132
+
133
+ output << "#{MigrationUtil.add_migration_index(table_name, attributes)}"
134
+
135
+ output << "\tend\n\n"
136
+ output << "end\n"
137
+ output
138
+ end
139
+
140
+ #
141
+ # 입력된 attributes로 부터 migration fields를 추가, columns는 Entity의 Entity Columns
142
+ #
143
+ def self.add_migration_columns(columns, pk_col_name)
144
+ output = ""
145
+ userstampable, timestampable = false, false
146
+
147
+ columns.each do |column|
148
+ if(column.name == 'id')
149
+ elsif(column.name == 'domain_id')
150
+ output << "\t\t\tt.references :domain, :null => false\n"
151
+ elsif(column.name == 'created_at' || column.name == 'updated_at')
152
+ timestampable = true
153
+ elsif(column.name == 'creator_id' || column.name == 'updater_id')
154
+ userstampable = true
155
+ elsif(column.ref_type == "Entity")
156
+ if(column.name.ends_with?("_id"))
157
+ ref_name = column.name[0 .. column.name.rindex('_') - 1]
158
+ output << "\t\t\tt.references :#{ref_name}\n"
159
+ else
160
+ output << "\t\t\tt.#{column.col_type} :#{column.name}\n"
161
+ end
162
+ else
163
+ output << "\t\t\tt.#{column.col_type} :#{column.name}"
164
+ output << ", :null => false" if(!column.nullable.nil? && !column.nullable)
165
+ output << ", :limit => #{column.col_size}" if(column.col_type == 'string' && column.col_size && column.col_size > 0)
166
+ output << ", :default => #{column.def_val}" if(column.def_val && !column.def_val.empty?)
167
+ output << "\n"
168
+ end
169
+ end
170
+
171
+ output << "\t\t\tt.userstamps\n" if userstampable
172
+ output << "\t\t\tt.timestamps\n" if timestampable
173
+ output
174
+ end
175
+
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,77 @@
1
+ module Hatio
2
+ module Generators
3
+ class ModelUtil
4
+
5
+ #
6
+ # 모델 정보를 생성하여 리턴
7
+ #
8
+ def self.generate_model(options, attributes, biz_attrs)
9
+ output, creator_flag, updater_flag, created_at_flag, updated_at_flag, name_flag, domain_flag = "\n", false, false, false, false, false, false
10
+ attributes.each do |attr|
11
+ case attr.name
12
+ when 'name'
13
+ name_flag = true
14
+ when 'domain_id'
15
+ domain_flag = true
16
+ when 'creator_id'
17
+ creator_flag = true
18
+ when 'updater_id'
19
+ updater_flag = true
20
+ when 'created_at'
21
+ created_at_flag = true
22
+ when 'updated_at'
23
+ updated_at_flag = true
24
+ else
25
+ end
26
+ end
27
+
28
+ output << "\tinclude Multitenant\n\n" if(domain_flag)
29
+ output << "\tinclude Attachable\n\n" if(options.use_attachment == 'y')
30
+ output << "\tinclude PropertyKeepable\n\n" if(options.use_ext_prop == 'y')
31
+ output << "\tstampable\n\n" if(created_at_flag || creator_flag)
32
+ output << "\tremoving_trackable\n\n" if(options.del_trace == 'y')
33
+
34
+ trim_cols = biz_attrs.select { |attr| attr.trimable }
35
+ if(!trim_cols.empty?)
36
+ trim_names = trim_cols.map { |col| ":#{col.name}" }.join(",")
37
+ output << "\tstrip_cols [#{trim_names}]\n\n"
38
+ end
39
+
40
+ # output << "meaningful_id [:domain_id, :name]\n\t" if(options.id_type == 'meaningful' && domain_flag && name_flag)
41
+ # output << "universal_unique_id\n\t" if(options.id_type == 'uuid')
42
+
43
+ presence_cols = biz_attrs.find_all { |col| col.nullable.nil? || !col.nullable }
44
+ presence_col_names = presence_cols.empty? ? "" : presence_cols.collect { |col| ":#{col.name}" }.join(",")
45
+ output << "\tvalidates_presence_of #{presence_col_names}, :strict => true\n\n" unless(presence_col_names.empty?)
46
+
47
+ biz_attrs.each do |col|
48
+ output << "\tvalidates :#{col.name}, length: { maximum: #{col.col_size} }, :strict => true\n\n" if(col.col_type == 'string' && col.col_size && col.col_size > 0)
49
+ end
50
+
51
+ uniq_cols = attributes.select { |col| col.uniq_rank > 0 }.sort_by(&:uniq_rank)
52
+ if(!uniq_cols.empty?)
53
+ uniq_name = uniq_cols.pop.name
54
+ uniq_output = "\tvalidates_uniqueness_of :#{uniq_name}, :strict => true"
55
+ if(!uniq_cols.empty?)
56
+ scope_name = uniq_cols.map { |col| ":#{col.name}" }.join(",")
57
+ uniq_output << ", :scope => [#{scope_name}]\n\n"
58
+ end
59
+ output << uniq_output
60
+ end
61
+
62
+ # console에서 명령 내린 경우가 아니면 ...
63
+ if(attributes[0].class.name != "Rails::Generators::GeneratedAttribute")
64
+ belong_to_arr = biz_attrs.find_all { |attr| attr.ref_type == :Entity.to_s && attr.ref_name }
65
+ belong_to_arr.each do |belongs_to|
66
+ entity_name = belongs_to.ref_name
67
+ entity_class = entity_name.constantize
68
+ output << "\tbelongs_to :#{entity_name.underscore}\n"
69
+ end
70
+ end
71
+
72
+ output
73
+ end
74
+
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,32 @@
1
+ module Hatio
2
+ module Generators
3
+ class ReportViewUtil
4
+
5
+ def self.generateStore(domain, out_params)
6
+ output = "fields : [\n\t\t\t"
7
+ columnList = out_params.collect { |column| "{ name : '#{column.name}', type : 'string' }" }
8
+ output << columnList.join(",\n\t\t\t")
9
+ output << "\n\t\t]"
10
+ output
11
+ end
12
+
13
+ def self.generateColumns(domain, out_params)
14
+ output = "columns : [\n\t\t"
15
+ columnList = out_params.collect { |column| "{ header : T('label.#{column.name}'), dataIndex : '#{column.name}' }" }
16
+ output << columnList.join(",\n\t\t")
17
+ output << "\n\t]"
18
+ output
19
+ end
20
+
21
+ def self.generate_search_items(domain, in_params)
22
+ output = "items : [\n\t\t"
23
+ columnList = in_params.collect { |column| "{ name : '#{column.name}', fieldLabel : T('label.#{column.name}') }" }
24
+ output << columnList.join(",\n\t\t")
25
+ output << "\n\t]"
26
+ output
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,383 @@
1
+ module Hatio
2
+ module Generators
3
+ class ResourceViewUtil
4
+
5
+ DATA_TYPE_NUMBER = ['integer', 'float', 'long', 'double', 'decimal']
6
+ DATA_TYPE_DATE = ['date', 'datetime', 'timestamp']
7
+ DATA_TYPE_TEXT = ['string', 'text']
8
+ SKIP_COLUMN_NAME = ['id', 'domain_id', 'creator_id', 'updater_id', 'created_at', 'updated_at', 'deleted_at', 'version']
9
+
10
+ #
11
+ # columns 정보로 부터 그리드를 생성
12
+ #
13
+ def self.generate_grid(domain, singular_name, columns, options, indent)
14
+ output = "columns : [\n"
15
+ indent = "\t\t" unless indent
16
+
17
+ if('y' == options.use_ext_prop)
18
+ output << "#{indent}{ xtype : 'actioncolumn', icon : 'assets/std/iconSlideshow.png', itemId : 'slideshow', width : 30, align : 'center' },\n"
19
+ end
20
+
21
+ columns.each do |col|
22
+ col_info = ""
23
+
24
+ if(col.name == 'id')
25
+ col_info = "{ header : T('label.id'), dataIndex : 'id', hidden : true }"
26
+ elsif(col.name == 'domain_id')
27
+ next
28
+ else
29
+ # list_rank가 0보다 큰 경우만 grid에 표시
30
+ if((col.list_rank && col.list_rank > 0) || (col.sort_rank && col.sort_rank > 0))
31
+ # 기본 생성, 수정시간 필드는 무조건 disabled 처리
32
+ if(col.name == 'created_at' || col.name == 'updated_at')
33
+ col_info = "{ header : T('label.#{col.name}'), dataIndex : '#{col.name}', xtype : 'datecolumn', format : T('format.datetime'), width : 120 }"
34
+ # reference 인 경우는 해당 reference에 맞게 처리
35
+ elsif(col.ref_type && !col.ref_type.empty?)
36
+ col_info = self.get_grid_column_by_ref(domain, col)
37
+ # 일반적인 필드인 경우
38
+ else
39
+ col_info = self.get_grid_column(domain, col)
40
+ end
41
+ end
42
+ end
43
+
44
+ output << "#{indent}#{col_info},\n" unless(col_info.empty?)
45
+ end
46
+
47
+ output << "\t],"
48
+ output
49
+ end
50
+
51
+ #
52
+ # grid column 정보에 sort option을 추가한다.
53
+ #
54
+ def self.grid_sort_option(columns, indent)
55
+ sort_columns = columns.select{ |f| f.sort_rank && f.sort_rank > 0 }.sort_by(&:sort_rank)
56
+ column_info = ""
57
+
58
+ if(!sort_columns.empty?)
59
+ column_info << "#{indent}sorters : [\n"
60
+ sort_columns.each do |scol|
61
+ dir = scol.reverse_sort ? 'desc' : 'asc'
62
+ column_info << "#{indent}\t{ property : '#{scol.name}', direction : '#{dir}' },\n"
63
+ end
64
+ column_info << "#{indent}],"
65
+ end
66
+
67
+ column_info
68
+ end
69
+
70
+ #
71
+ # column의 reference type정보로 부터 grid column 정보를 얻는다.
72
+ #
73
+ def self.get_grid_column_by_ref(domain, column)
74
+ columnInfo = ""
75
+ if(column.ref_type == 'CommonCode')
76
+ columnInfo << "{ header : T('label.#{column.name}'), dataIndex : '#{column.name}'"
77
+ columnInfo << ", editor : { xtype : 'codecombo', commonCode : '#{column.ref_name}' }" if(column.editable)
78
+ columnInfo << " }"
79
+ elsif(column.ref_type == 'Entity')
80
+ if(column.name.end_with?('_id') && column.ref_name)
81
+ data_index = column.name[0 .. column.name.rindex('_') - 1]
82
+ storeName = find_store_name(domain, column, data_index)
83
+ columnInfo << "{ header : #{storeName[0]}, dataIndex : '#{data_index}', xtype : 'entitycolumn'"
84
+ columnInfo << ", editor : { xtype : 'entitycolumneditor', storeClass : '#{storeName[1]}' }" if(column.editable)
85
+ columnInfo << " }"
86
+ else
87
+ columnInfo << get_grid_column(domain, column)
88
+ end
89
+ else
90
+ columnInfo << get_grid_column(domain, column)
91
+ end
92
+ columnInfo
93
+ end
94
+
95
+ #
96
+ # entity name으로 store명을 추출
97
+ #
98
+ def self.find_store_name(domain, column, data_index)
99
+ entity = Entity.find_by_name(column.ref_name);
100
+
101
+ if(SKIP_COLUMN_NAME.include?(column.name))
102
+ title = "T('label.#{data_index ? data_index : column.name}')"
103
+ else
104
+ title = data_index ? "T('label.#{data_index}')" : "T('label.#{column.name}')";
105
+ end
106
+
107
+ ["#{title}", "#{entity.bundle.camelcase}.store.#{entity.name}"]
108
+ end
109
+
110
+ #
111
+ # column으로 부터 grid column 정보를 얻는다.
112
+ #
113
+ def self.get_grid_column(domain, col)
114
+ output, col_type = "", col.col_type
115
+
116
+ if(col_type == 'string')
117
+ output = "{ header : T('label.#{col.name}'), dataIndex : '#{col.name}' "
118
+ output << grid_column_editor(col) if(col.editable)
119
+ output << " }"
120
+ elsif(col_type == 'text')
121
+ output = "{ header : T('label.#{col.name}'), dataIndex : '#{col.name}' "
122
+ output << grid_column_editor(col) if(col.editable)
123
+ output << " }"
124
+ elsif(col_type == 'boolean')
125
+ output = "{ header : T('label.#{col.name}'), dataIndex : '#{col.name}' "
126
+ output << ", xtype : 'checkcolumn' "
127
+ output << " }"
128
+ elsif(col_type == 'date')
129
+ if(col.editable)
130
+ output = grid_column_editor(col) if(col.editable)
131
+ else
132
+ output = "{ header : T('label.#{col.name}'), dataIndex : '#{col.name}', xtype : 'datecolumn', format : T('format.date') }"
133
+ end
134
+ elsif(col_type == 'datetime' || col_type == 'timestamp')
135
+ if(col.editable)
136
+ output = grid_column_editor(col) if(col.editable)
137
+ else
138
+ output = "{ header : T('label.#{col.name}'), dataIndex : '#{col.name}', xtype : 'datecolumn', format : T('format.datetime') }"
139
+ end
140
+ elsif(checkNumberColumn(col_type))
141
+ output = "{ header : T('label.#{col.name}'), dataIndex : '#{col.name}', align : 'right' "
142
+ output << grid_column_editor(col) if(col.editable)
143
+ output << " }"
144
+ end
145
+
146
+ return output
147
+ end
148
+
149
+ def self.grid_column_editor(col)
150
+ col_type, output = col.col_type, ""
151
+
152
+ if(col_type == 'string' || col_type == 'text')
153
+ output << ", editor : { xtype : 'textfield' "
154
+ elsif(col_type == 'date')
155
+ output = "{ header : T('label.#{col.name}'), dataIndex : '#{col.name}', xtype : 'datecolumn', format : T('format.date'), editor : { xtype : 'datefield', format : T('format.date') } }"
156
+ elsif(col_type == 'datetime' || col_type == 'timestamp')
157
+ output = "{ header : T('label.#{col.name}'), dataIndex : '#{col.name}', editor : { xtype : 'datefield', format : T('format.datetime') } }"
158
+ elsif(checkNumberColumn(col_type))
159
+ output << ", editor : { xtype : 'numberfield' "
160
+ end
161
+
162
+ if(col_type == 'string' || col_type == 'text')
163
+ output << ", maxLength : #{col.col_size} " if(col.col_size > 0)
164
+ end
165
+
166
+ if(checkNumberColumn(col_type))
167
+ output << ", minValue : #{col.min} " if(!col.min.nil?)
168
+ output << ", maxValue : #{col.max} " if(!col.max.nil?)
169
+ end
170
+
171
+ output << "}" if(col_type == 'string' || col_type == 'text')
172
+ output << "}" if(checkNumberColumn(col_type))
173
+ output
174
+ end
175
+
176
+ #
177
+ # resource의 columns로 부터 form 정보를 생성하여 리턴
178
+ #
179
+ def self.generate_form(domain, resourceName, columns, options, indent)
180
+ output = "items : [\n\t"
181
+ indent = "\t" unless indent
182
+
183
+ columns.each do |col|
184
+ columnInfo = ""
185
+ if(col.name == 'id')
186
+ columnInfo = "{ name : '#{col.name}', fieldLabel : T('label.#{col.name}'), hidden : true }"
187
+ elsif(col.name == 'domain_id')
188
+ elsif(col.name == 'creator_id' || col.name == 'updater_id' || col.name == 'created_at' || col.name == 'updated_at')
189
+ elsif(col.ref_type && !col.ref_type.empty?)
190
+ columnInfo = self.get_form_column_by_ref(domain, col)
191
+ else
192
+ columnInfo = self.get_form_column(domain, col)
193
+ end
194
+ output << "\t#{columnInfo},\n\t" if columnInfo && !columnInfo.empty?
195
+ end
196
+
197
+ output << "\t{ xtype : 'timestamp' }\n\t]"
198
+ output
199
+ end
200
+
201
+ #
202
+ # column의 reference type정보로 부터 form column 정보를 얻는다.
203
+ #
204
+ def self.get_form_column_by_ref(domain, col)
205
+ if(col.ref_type == 'CommonCode')
206
+ return "{ name : '#{col.name}', fieldLabel : T('label.#{col.name}'), xtype : 'codefield', commonCode : '#{col.ref_name}' }"
207
+ elsif(col.ref_type == 'Entity')
208
+ entity_name = col.name[0 .. col.name.rindex('_') - 1]
209
+ storeName = find_store_name(domain, col, entity_name)
210
+ return "{ name : '#{entity_name}', fieldLabel : #{storeName[0]}, xtype : 'entityfield', storeClass : '#{storeName[1]}' }"
211
+ else
212
+ return ""
213
+ end
214
+ end
215
+
216
+ #
217
+ # column으로 부터 form column 정보를 얻는다.
218
+ #
219
+ def self.get_form_column(domain, col)
220
+ col_type = col.col_type
221
+ if(col_type == 'string')
222
+ allow_blank_str = (!col.nullable.nil? && !col.nullable) ? ", allowBlank : false" : ""
223
+ col_size_str = (col.col_size && col.col_size > 0) ? ", maxLength : #{col.col_size}" : ""
224
+ "{ name : '#{col.name}', fieldLabel : T('label.#{col.name}')#{allow_blank_str}#{col_size_str} }"
225
+ elsif(col_type == 'text')
226
+ allow_blank_str = (!col.nullable.nil? && !col.nullable) ? ", allowBlank : false" : ""
227
+ col_size_str = (col.col_size && col.col_size > 0) ? ", maxLength : #{col.col_size}" : ""
228
+ "{ name : '#{col.name}', fieldLabel : T('label.#{col.name}'), xtype : 'textareafield'#{allow_blank_str}#{col_size_str} }"
229
+ elsif(col_type == 'boolean')
230
+ "{ name : '#{col.name}', fieldLabel : T('label.#{col.name}'), xtype : 'checkboxfield', inputValue : true }"
231
+ elsif(col_type == 'date')
232
+ "{ name : '#{col.name}', fieldLabel : T('label.#{col.name}'), xtype : 'datefield', format : T('format.date'), submitFormat : T('format.submitDate') }"
233
+ elsif(col_type == 'datetime' || col_type == 'timestamp')
234
+ "{ name : '#{col.name}', fieldLabel : T('label.#{col.name}'), xtype : 'datefield', format : T('format.datetime') }"
235
+ elsif(checkNumberColumn(col_type))
236
+ min_val_str = col.min.nil? ? "" : ", minValue : #{col.min}"
237
+ max_val_str = col.max.nil? ? "" : ", maxValue : #{col.max}"
238
+ "{ name : '#{col.name}', fieldLabel : T('label.#{col.name}'), xtype : 'numberfield'#{min_val_str}#{max_val_str} }"
239
+ else
240
+ ""
241
+ end
242
+ end
243
+
244
+ #
245
+ # columns 정보로 부터 search condition items를 생성
246
+ #
247
+ def self.generate_search_items(domain, resourceName, columns, options, indent)
248
+ output = "items : [\n"
249
+ indent = "\t\t" unless indent
250
+ search_columns = columns.select { |c| c.search_rank && c.search_rank > 0 }.sort_by(&:search_rank)
251
+
252
+ search_columns.each do |col|
253
+ if(!self.checkSkipColumn(col))
254
+ if(col.ref_type && !col.ref_type.empty?)
255
+ columnInfo = self.get_search_form_column_by_ref(domain, col)
256
+ else
257
+ columnInfo = self.get_search_form_column(domain, col)
258
+ end
259
+ output << "#{indent}\t#{columnInfo},\n" if columnInfo && !columnInfo.empty?
260
+ end
261
+ end
262
+
263
+ output << "#{indent}]"
264
+ output
265
+ end
266
+
267
+ #
268
+ # column의 reference type정보로 부터 search form column 정보를 얻는다.
269
+ #
270
+ def self.get_search_form_column_by_ref(domain, col)
271
+ if(col.ref_type == 'CommonCode')
272
+ return "{ name : '#{col.name}-eq', fieldLabel : T('label.#{col.name}'), xtype : 'codesearchcombo', commonCode : '#{col.ref_name}', valueField : 'name', displayField : 'name' }"
273
+ elsif(col.ref_type == 'Entity')
274
+ data_label = col.name[0 .. col.name.rindex('_') - 1]
275
+ storeName = find_store_name(domain, col, data_label)
276
+ return "{ name : '#{data_label}.name-eq', fieldLabel : #{storeName[0]}, xtype : 'entitysearchcombo', storeClass : '#{storeName[1]}', valueField : 'name' }"
277
+ else
278
+ return ""
279
+ end
280
+ end
281
+
282
+ #
283
+ # column의 정보로 부터 search form column 정보를 얻는다.
284
+ #
285
+ def self.get_search_form_column(domain, col)
286
+ col_type = col.col_type
287
+ if(col.name.end_with?('_yn'))
288
+ return "{ name : '#{col.name}-eq', fieldLabel : T('label.#{col.name}'), xtype : 'yesnopicker' }"
289
+ elsif(checkTextColumn(col_type))
290
+ return "{ name : '#{col.name}-like', fieldLabel : T('label.#{col.name}')}"
291
+ elsif(col_type == 'boolean')
292
+ return "{ name : '#{col.name}-eq', fieldLabel : T('label.#{col.name}'), xtype : 'checkboxfield', inputValue : true }"
293
+ elsif(col_type == 'date')
294
+ return "{ name : '#{col.name}-eq', fieldLabel : T('label.date'), xtype : 'datefield', format : T('format.date'), submitFormat : T('format.submitDate') }"
295
+ elsif(col_type == 'datetime' || col_type == 'timestamp')
296
+ output = "{ name : '#{col.name}-gte', fieldLabel : T('label.#{col.name}_from'), xtype : 'datefield', format : T('format.datetime') },\n"
297
+ output << "{ name : '#{col.name}-lte', fieldLabel : T('label.#{col.name}_to'), xtype : 'datefield', format : T('format.datetime') }"
298
+ return output
299
+ elsif(checkNumberColumn(col_type))
300
+ return "{ name : '#{col.name}-eq', fieldLabel : T('label.#{col.name}'), xtype : 'numberfield' }"
301
+ else
302
+ return ""
303
+ end
304
+ end
305
+
306
+ #
307
+ # columns 정보로 부터 model fields 정보를 설정
308
+ #
309
+ def self.generate_model_fields(options, columns, indent)
310
+ indent = "\t\t" unless indent
311
+ validations, output = [], "fields : [\n"
312
+
313
+ columns.each do |col|
314
+ next if(col.name == 'domain_id')
315
+ output << "#{indent}{ name : '#{col.name}', type : '"
316
+ output << ((col.col_type == 'datetime' || col.col_type == 'timestamp') ? 'date' : col.col_type)
317
+ output << "' },\n"
318
+
319
+ # ref_type이 Entity이고 ref_name이 _id로 끝나면 ....
320
+ if(col.ref_type && col.ref_type == 'Entity' && col.ref_name)
321
+ if(col.name == 'creator_id')
322
+ output << "#{indent}{ name : 'creator', type : 'auto' },\n"
323
+ elsif(col.name == 'updater_id')
324
+ output << "#{indent}{ name : 'updater', type : 'auto' },\n"
325
+ else
326
+ output << "#{indent}{ name : '#{col.ref_name.underscore}', type : 'auto' },\n"
327
+ end
328
+ end
329
+
330
+ unless(SKIP_COLUMN_NAME.include?(col.name))
331
+ if(!col.nullable.nil? && !col.nullable)
332
+ validations << "#{indent}{ type : 'presence', field : '#{col.name}' },\n"
333
+ end
334
+
335
+ if(col.col_type && (col.col_size && col.col_size > 0))
336
+ validations << "#{indent}{ type : 'length', field : '#{col.name}', max : #{col.col_size} },\n"
337
+ end
338
+ end
339
+ end
340
+
341
+ output << "#{indent}{ name : 'properties_attributes', type : 'auto', defaultValue : [] },\n" if('y' == options.use_ext_prop)
342
+ output << "#{indent}{ name : '_cud_flag_', type : 'string' }\n\t]"
343
+
344
+ unless(validations.empty?)
345
+ output << ",\n\n\tvalidations : [\n"
346
+ validations.each { |val| output << val }
347
+ output << "\t]"
348
+ end
349
+
350
+ output
351
+ end
352
+
353
+ #
354
+ # 처리를 skip할 columns 정보인지 체크
355
+ #
356
+ def self.checkSkipColumn(col)
357
+ return SKIP_COLUMN_NAME.include?(col.name) ? true : false
358
+ end
359
+
360
+ #
361
+ # number형 컬럼인지 체크
362
+ #
363
+ def self.checkNumberColumn(col_type)
364
+ return DATA_TYPE_NUMBER.include?(col_type) ? true : false
365
+ end
366
+
367
+ #
368
+ # 문자형 컬럼인지 체크
369
+ #
370
+ def self.checkTextColumn(col_type)
371
+ return DATA_TYPE_TEXT.include?(col_type) ? true : false
372
+ end
373
+
374
+ #
375
+ # 날짜형 컬럼인지 체크
376
+ #
377
+ def self.checkDateColumn(col_type)
378
+ return DATA_TYPE_DATE.include?(col_type) ? true : false
379
+ end
380
+ end
381
+
382
+ end
383
+ end