smartkiosk-server 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (254) hide show
  1. data/.gitignore +32 -0
  2. data/.rspec +1 -0
  3. data/Capfile +4 -0
  4. data/Gemfile +71 -0
  5. data/Gemfile.lock +439 -0
  6. data/Guardfile +25 -0
  7. data/LICENSE +287 -0
  8. data/README.md +13 -0
  9. data/Rakefile +5 -0
  10. data/app/acquirers/cards_mkb_acquirer.rb +87 -0
  11. data/app/acquirers/cash_acquirer.rb +22 -0
  12. data/app/admin/agents.rb +108 -0
  13. data/app/admin/collections.rb +62 -0
  14. data/app/admin/commissions.rb +87 -0
  15. data/app/admin/gateways.rb +183 -0
  16. data/app/admin/limits.rb +82 -0
  17. data/app/admin/payments.rb +246 -0
  18. data/app/admin/provider_groups.rb +60 -0
  19. data/app/admin/provider_profiles.rb +11 -0
  20. data/app/admin/provider_receipt_templates.rb +82 -0
  21. data/app/admin/providers.rb +201 -0
  22. data/app/admin/rebates.rb +83 -0
  23. data/app/admin/report_results.rb +66 -0
  24. data/app/admin/report_templates.rb +209 -0
  25. data/app/admin/reports.rb +158 -0
  26. data/app/admin/revisions.rb +120 -0
  27. data/app/admin/system_receipt_templates.rb +76 -0
  28. data/app/admin/terminal_builds.rb +39 -0
  29. data/app/admin/terminal_profiles.rb +123 -0
  30. data/app/admin/terminals.rb +388 -0
  31. data/app/admin/users.rb +117 -0
  32. data/app/admin/versions.rb +131 -0
  33. data/app/admin/welcome.rb +64 -0
  34. data/app/assets/fonts/PT_Sans-Web-Bold.eot +0 -0
  35. data/app/assets/fonts/PT_Sans-Web-Bold.svg +6386 -0
  36. data/app/assets/fonts/PT_Sans-Web-Bold.ttf +0 -0
  37. data/app/assets/fonts/PT_Sans-Web-Bold.woff +0 -0
  38. data/app/assets/fonts/PT_Sans-Web-Regular.eot +0 -0
  39. data/app/assets/fonts/PT_Sans-Web-Regular.svg +5650 -0
  40. data/app/assets/fonts/PT_Sans-Web-Regular.ttf +0 -0
  41. data/app/assets/fonts/PT_Sans-Web-Regular.woff +0 -0
  42. data/app/assets/images/chosen-sprite.png +0 -0
  43. data/app/assets/javascripts/active_admin/chosen.js.erb.coffee +12 -0
  44. data/app/assets/javascripts/active_admin/qtip.js.coffee +22 -0
  45. data/app/assets/javascripts/active_admin/sortable_forms.js.coffee +14 -0
  46. data/app/assets/javascripts/active_admin.js.coffee +9 -0
  47. data/app/assets/javascripts/application.js +15 -0
  48. data/app/assets/javascripts/report_templates.js.coffee +10 -0
  49. data/app/assets/javascripts/terminals.js.coffee +12 -0
  50. data/app/assets/stylesheets/active_admin/PIE.css.scss +18 -0
  51. data/app/assets/stylesheets/active_admin/filter_numeric_range.css.scss +14 -0
  52. data/app/assets/stylesheets/active_admin/selectable_check_boxes.css.scss +12 -0
  53. data/app/assets/stylesheets/active_admin/sortable_forms.css.scss +11 -0
  54. data/app/assets/stylesheets/active_admin.css.scss +705 -0
  55. data/app/assets/stylesheets/fonts.css.scss +14 -0
  56. data/app/assets/stylesheets/provider_groups.css.scss +12 -0
  57. data/app/assets/stylesheets/provider_receipt_templates.css.scss +12 -0
  58. data/app/assets/stylesheets/terminals.css.scss +9 -0
  59. data/app/controllers/application_controller.rb +12 -0
  60. data/app/controllers/collections_controller.rb +10 -0
  61. data/app/controllers/payments_controller.rb +73 -0
  62. data/app/controllers/system_receipt_templates_controller.rb +10 -0
  63. data/app/controllers/terminal_builds_controller.rb +5 -0
  64. data/app/controllers/terminal_orders_controller.rb +25 -0
  65. data/app/controllers/terminal_pings_controller.rb +45 -0
  66. data/app/controllers/welcome_controller.rb +5 -0
  67. data/app/helpers/active_admin/report_templates_helper.rb +56 -0
  68. data/app/helpers/active_admin/views_helper.rb +20 -0
  69. data/app/helpers/application_helper.rb +2 -0
  70. data/app/mailers/.gitkeep +0 -0
  71. data/app/models/.gitkeep +0 -0
  72. data/app/models/ability.rb +30 -0
  73. data/app/models/agent.rb +24 -0
  74. data/app/models/collection.rb +65 -0
  75. data/app/models/commission.rb +77 -0
  76. data/app/models/commission_section.rb +75 -0
  77. data/app/models/gateway.rb +99 -0
  78. data/app/models/gateway_attachment.rb +9 -0
  79. data/app/models/gateway_setting.rb +7 -0
  80. data/app/models/gateway_switch.rb +7 -0
  81. data/app/models/limit.rb +77 -0
  82. data/app/models/limit_section.rb +58 -0
  83. data/app/models/payment.rb +322 -0
  84. data/app/models/provider.rb +59 -0
  85. data/app/models/provider_field.rb +7 -0
  86. data/app/models/provider_gateway.rb +47 -0
  87. data/app/models/provider_group.rb +45 -0
  88. data/app/models/provider_profile.rb +9 -0
  89. data/app/models/provider_rebate.rb +69 -0
  90. data/app/models/provider_receipt_template.rb +85 -0
  91. data/app/models/rebate.rb +84 -0
  92. data/app/models/report.rb +71 -0
  93. data/app/models/report_result.rb +11 -0
  94. data/app/models/report_template.rb +56 -0
  95. data/app/models/revision.rb +104 -0
  96. data/app/models/role.rb +48 -0
  97. data/app/models/system_receipt_template.rb +13 -0
  98. data/app/models/terminal.rb +126 -0
  99. data/app/models/terminal_build.rb +62 -0
  100. data/app/models/terminal_order.rb +42 -0
  101. data/app/models/terminal_ping.rb +120 -0
  102. data/app/models/terminal_profile.rb +51 -0
  103. data/app/models/terminal_profile_promotion.rb +18 -0
  104. data/app/models/terminal_profile_provider.rb +11 -0
  105. data/app/models/terminal_profile_provider_group.rb +19 -0
  106. data/app/models/user.rb +38 -0
  107. data/app/models/user_role.rb +45 -0
  108. data/app/reports/agents_report.rb +81 -0
  109. data/app/reports/collections_report.rb +151 -0
  110. data/app/reports/payments_report.rb +189 -0
  111. data/app/reports/terminals_report.rb +123 -0
  112. data/app/uploaders/file_uploader.rb +53 -0
  113. data/app/uploaders/icon_uploader.rb +15 -0
  114. data/app/uploaders/zip_uploader.rb +53 -0
  115. data/app/views/admin/gateways/providers.html.arb +10 -0
  116. data/app/views/admin/revisions/payments.html.arb +28 -0
  117. data/app/views/admin/terminal_profiles/_tree.html.haml +35 -0
  118. data/app/views/admin/terminal_profiles/sort.html.haml +21 -0
  119. data/app/views/admin/terminals/pings.html.arb +55 -0
  120. data/app/views/admin/terminals/upgrade_build.html.arb +30 -0
  121. data/app/views/layouts/application.html.erb +1 -0
  122. data/app/views/welcome/index.html.erb +25 -0
  123. data/app/workers/pay_worker.rb +11 -0
  124. data/app/workers/report_worker.rb +7 -0
  125. data/app/workers/revise_worker.rb +7 -0
  126. data/config/acquiring.yml +13 -0
  127. data/config/application.rb +75 -0
  128. data/config/boot.rb +6 -0
  129. data/config/database.yml +17 -0
  130. data/config/deploy/roundlake-passenger.rb +3 -0
  131. data/config/deploy/roundlake-trinidad.rb +3 -0
  132. data/config/deploy.rb +37 -0
  133. data/config/environment.rb +5 -0
  134. data/config/environments/development.rb +39 -0
  135. data/config/environments/production.rb +67 -0
  136. data/config/environments/test.rb +37 -0
  137. data/config/initializers/active_admin.rb +31 -0
  138. data/config/initializers/backtrace_silencers.rb +7 -0
  139. data/config/initializers/devise.rb +232 -0
  140. data/config/initializers/inflections.rb +15 -0
  141. data/config/initializers/mime_types.rb +5 -0
  142. data/config/initializers/money.rb +6 -0
  143. data/config/initializers/redis.rb +4 -0
  144. data/config/initializers/secret_token.rb +7 -0
  145. data/config/initializers/session_store.rb +8 -0
  146. data/config/initializers/setup_rack.rb +1 -0
  147. data/config/initializers/wrap_parameters.rb +14 -0
  148. data/config/locales/active_admin.ru.yml +71 -0
  149. data/config/locales/activerecord.ru.yml +645 -0
  150. data/config/locales/devise.ru.yml +57 -0
  151. data/config/locales/ru.yml +33 -0
  152. data/config/locales/smartkiosk.gateways.ru.yml +241 -0
  153. data/config/locales/smartkiosk.hardware.ru.yml +38 -0
  154. data/config/locales/smartkiosk.reports.ru.yml +56 -0
  155. data/config/locales/smartkiosk.ru.yml +163 -0
  156. data/config/nginx.conf +9 -0
  157. data/config/redis.yml +9 -0
  158. data/config/routes.rb +48 -0
  159. data/config/schedule.rb +13 -0
  160. data/config/sidekiq.yml +5 -0
  161. data/config/trinidad.yml +6 -0
  162. data/config.ru +4 -0
  163. data/db/migrate/20120825083035_create_terminals.rb +47 -0
  164. data/db/migrate/20120825083305_create_payments.rb +51 -0
  165. data/db/migrate/20120827062618_devise_create_users.rb +50 -0
  166. data/db/migrate/20120827132621_create_admin_notes.rb +17 -0
  167. data/db/migrate/20120827132622_move_admin_notes_to_comments.rb +25 -0
  168. data/db/migrate/20120903193346_create_providers.rb +24 -0
  169. data/db/migrate/20120922075345_create_collections.rb +26 -0
  170. data/db/migrate/20120922080440_create_agents.rb +29 -0
  171. data/db/migrate/20120922081104_create_commissions.rb +10 -0
  172. data/db/migrate/20120927035841_create_gateways.rb +13 -0
  173. data/db/migrate/20120927040626_create_provider_gateways.rb +13 -0
  174. data/db/migrate/20120927091849_create_limits.rb +10 -0
  175. data/db/migrate/20120927164647_create_roles.rb +14 -0
  176. data/db/migrate/20121003131522_create_report_templates.rb +18 -0
  177. data/db/migrate/20121007135652_create_reports.rb +13 -0
  178. data/db/migrate/20121008073905_create_report_results.rb +10 -0
  179. data/db/migrate/20121017114538_create_gateway_settings.rb +12 -0
  180. data/db/migrate/20121017114556_create_gateway_attachments.rb +10 -0
  181. data/db/migrate/20121019132606_create_revisions.rb +19 -0
  182. data/db/migrate/20121023073501_create_gateway_switches.rb +10 -0
  183. data/db/migrate/20121112142743_create_terminal_orders.rb +13 -0
  184. data/db/migrate/20121118191553_create_versions.rb +19 -0
  185. data/db/migrate/20121125093414_create_system_receipt_templates.rb +9 -0
  186. data/db/migrate/20121127192257_create_terminal_builds.rb +10 -0
  187. data/db/migrate/20121212053441_create_rebates.rb +15 -0
  188. data/db/migrate/20121216143855_create_provider_receipt_templates.rb +9 -0
  189. data/db/migrate/20130101091100_create_terminal_profiles.rb +13 -0
  190. data/db/migrate/20130101091734_create_provider_rebates.rb +21 -0
  191. data/db/migrate/20130102164447_create_limit_sections.rb +14 -0
  192. data/db/migrate/20130102164503_create_commission_sections.rb +17 -0
  193. data/db/migrate/20130102171743_create_provider_profiles.rb +10 -0
  194. data/db/migrate/20130103152507_create_provider_fields.rb +17 -0
  195. data/db/migrate/20130103154526_create_provider_groups.rb +10 -0
  196. data/db/migrate/20130104063628_create_terminal_profile_providers.rb +11 -0
  197. data/db/migrate/20130104090957_create_terminal_profile_provider_groups.rb +11 -0
  198. data/db/migrate/20130108091644_create_terminal_profile_promotions.rb +10 -0
  199. data/db/schema.rb +489 -0
  200. data/db/seeds/receipt_templates/payment.txt +19 -0
  201. data/db/seeds/receipt_templates/system/balance.txt +13 -0
  202. data/db/seeds/receipt_templates/system/collection.txt +17 -0
  203. data/db/seeds/receipt_templates/system/touchtest.txt +15 -0
  204. data/db/seeds.rb +18 -0
  205. data/doc/README_FOR_APP +2 -0
  206. data/init.rb +1 -0
  207. data/lib/active_admin/cancan_integration.rb +81 -0
  208. data/lib/active_admin/form_builder_fix.rb +76 -0
  209. data/lib/active_admin/inputs/filter_date_range_input_fix.rb +24 -0
  210. data/lib/active_admin/inputs/filter_multiple_select_input.rb +18 -0
  211. data/lib/active_admin/inputs/filter_numeric_range_input.rb +31 -0
  212. data/lib/active_admin/resource_controller_fix.rb +23 -0
  213. data/lib/active_admin/views/pages/base_fix.rb +13 -0
  214. data/lib/assets/.gitkeep +0 -0
  215. data/lib/blueprints.rb +79 -0
  216. data/lib/date_expander.rb +38 -0
  217. data/lib/dav4rack/build_resource.rb +59 -0
  218. data/lib/formtastic/inputs/selectable_check_boxes.rb +39 -0
  219. data/lib/paper_trail/version_fix.rb +3 -0
  220. data/lib/report_builder.rb +88 -0
  221. data/lib/seeder.rb +103 -0
  222. data/lib/smartkiosk/server/version.rb +5 -0
  223. data/lib/smartkiosk/server.rb +35 -0
  224. data/lib/string_file.rb +12 -0
  225. data/lib/tasks/.gitkeep +0 -0
  226. data/lib/tasks/db.rake +27 -0
  227. data/lib/tasks/dump.rake +53 -0
  228. data/lib/tasks/matrioshka.rake +16 -0
  229. data/log/.gitkeep +0 -0
  230. data/log/gateways/.gitkeep +0 -0
  231. data/public/404.html +26 -0
  232. data/public/422.html +26 -0
  233. data/public/500.html +25 -0
  234. data/public/robots.txt +5 -0
  235. data/script/rails +6 -0
  236. data/smartkiosk-server.gemspec +23 -0
  237. data/spec/controllers/collections_controller_spec.rb +32 -0
  238. data/spec/controllers/payments_controller_spec.rb +123 -0
  239. data/spec/controllers/system_receipt_templates_controller_spec.rb +5 -0
  240. data/spec/controllers/terminal_builds_controller_spec.rb +5 -0
  241. data/spec/controllers/terminal_orders_controller_spec.rb +32 -0
  242. data/spec/controllers/terminal_pings_controller_spec.rb +31 -0
  243. data/spec/spec_helper.rb +66 -0
  244. data/vendor/assets/javascripts/.gitkeep +0 -0
  245. data/vendor/assets/javascripts/chosen.jquery.js +1026 -0
  246. data/vendor/assets/javascripts/datepicker-ru.jquery.js +21 -0
  247. data/vendor/assets/javascripts/nestedSortable.jquery.js +429 -0
  248. data/vendor/assets/javascripts/qtip.jquery.js +3403 -0
  249. data/vendor/assets/stylesheets/.gitkeep +0 -0
  250. data/vendor/assets/stylesheets/chosen.jquery.css +397 -0
  251. data/vendor/assets/stylesheets/modules/PIE.htc +96 -0
  252. data/vendor/assets/stylesheets/qtip.jquery.css.scss +604 -0
  253. data/vendor/plugins/.gitkeep +0 -0
  254. metadata +333 -0
@@ -0,0 +1,126 @@
1
+ require_dependency 'terminal_ping'
2
+
3
+ class Terminal < ActiveRecord::Base
4
+ include Redis::Objects::RMap
5
+
6
+ HARDWARE = %w(cash_acceptor modem printer)
7
+ ORDERS = %w(reload reboot disable enable upgrade)
8
+
9
+ has_rmap({:id => lambda{|x| x.to_s}}, :keyword)
10
+ has_paper_trail :ignore => [:incomplete_orders_count]
11
+
12
+ #
13
+ # RELATIONS
14
+ #
15
+ belongs_to :terminal_profile
16
+ belongs_to :agent
17
+ has_many :collections, :order => 'id DESC'
18
+ has_many :payments, :order => 'id DESC'
19
+ has_many :terminal_orders, :order => 'id DESC'
20
+
21
+ list :pings, :marshal => true, :maxlength => 480
22
+
23
+ scope :ok, where(:condition => 'ok')
24
+ scope :warning, where(:condition => 'warning')
25
+ scope :error, where(:condition => 'error')
26
+
27
+ #
28
+ # VALIDATIONS
29
+ #
30
+ validates :terminal_profile, :presence => true
31
+ validates :title, :presence => true
32
+ validates :keyword, :presence => true, :uniqueness => true
33
+ validates :agent, :presence => true
34
+
35
+ #
36
+ # METHODS
37
+ #
38
+ def providers_dump(after=nil)
39
+ providers = Provider.includes(:provider_fields).after(after)
40
+
41
+ return [] if providers.blank?
42
+
43
+ overload = Hash[*terminal_profile.terminal_profile_providers.map{|x| [x.provider_id, x]}.flatten]
44
+
45
+ providers.map do |x|
46
+ icon = overload[x.id].icon
47
+
48
+ if icon.blank?
49
+ icon = x.icon.try(:url)
50
+ else
51
+ icon = icon.url
52
+ end
53
+
54
+ {
55
+ :id => x.id,
56
+ :title => x.title,
57
+ :keyword => x.keyword,
58
+ :icon => icon,
59
+ :priority => overload[x.id].try(:priority),
60
+ :fields => x.fields_dump,
61
+ :group_id => x.provider_group_id,
62
+ :requires_print => x.requires_print
63
+ }
64
+ end
65
+ end
66
+
67
+ def promotions_dump
68
+ terminal_profile.terminal_profile_promotions.map{|x| x.provider_id}
69
+ end
70
+
71
+ def provider_groups_dump
72
+ overload = Hash[*terminal_profile.terminal_profile_provider_groups.map{|x| [x.provider_group_id, x]}.flatten]
73
+
74
+ ProviderGroup.all.map do |x|
75
+ icon = overload[x.id].icon
76
+
77
+ if icon.blank?
78
+ icon = x.icon.try(:url)
79
+ else
80
+ icon = icon.url
81
+ end
82
+
83
+ {
84
+ :id => x.id,
85
+ :title => x.title,
86
+ :icon => icon,
87
+ :priority => overload[x.id].try(:priority),
88
+ :parent_id => x.provider_group_id
89
+ }
90
+ end
91
+ end
92
+
93
+ def title
94
+ keyword
95
+ end
96
+
97
+ def ping!(data)
98
+ raise ActiveRecord::RecordInvalid unless data.valid?
99
+ pings.unshift data
100
+
101
+ update = {
102
+ :state => data.state,
103
+ :condition => data.condition,
104
+ :notified_at => data.created_at,
105
+ :version => data.version
106
+ }
107
+
108
+ HARDWARE.each do |device|
109
+ update["#{device}_error"] = data.error(device)
110
+ end
111
+
112
+ if data.ok?
113
+ update[:issues_started_at] = nil
114
+ else
115
+ update[:issues_started_at] = DateTime.now if issues_started_at.blank?
116
+ end
117
+
118
+ self.without_versioning do
119
+ update_attributes update
120
+ end
121
+ end
122
+
123
+ def order!(keyword, *args)
124
+ TerminalOrder.create!(:terminal_id => id, :keyword => keyword, :args => args)
125
+ end
126
+ end
@@ -0,0 +1,62 @@
1
+ require 'digest/md5'
2
+
3
+ class TerminalBuild < ActiveRecord::Base
4
+ mount_uploader :source, ZipUploader
5
+
6
+ validates :source, :presence => true
7
+ serialize :hashes
8
+
9
+ validate do
10
+ errors[:base] << I18n.t('activerecord.errors.models.terminal_build.no_version') if version.blank?
11
+ end
12
+
13
+ before_validation do
14
+ self.version = read_version
15
+ end
16
+
17
+ after_create do
18
+ Zip::ZipFile.open(source.path) do |zip_file|
19
+ zip_file.each do |f|
20
+ destination = File.join(self.path, f.name)
21
+ FileUtils.mkdir_p File.dirname(destination)
22
+ zip_file.extract(f, destination) unless File.exist?(destination)
23
+ end
24
+ end
25
+
26
+ self.update_attributes :hashes => build_hashes
27
+ end
28
+
29
+ after_destroy do
30
+ FileUtils.rm_rf path
31
+ end
32
+
33
+ def path
34
+ Rails.root.join("public/builds/#{id}").to_s
35
+ end
36
+
37
+ def url
38
+ "/builds/#{id}"
39
+ end
40
+
41
+ def read_version
42
+ return unless source.present?
43
+
44
+ Zip::ZipFile.open(source.path) do |zip_file|
45
+ return zip_file.read('VERSION').strip rescue nil
46
+ end
47
+ end
48
+
49
+ def build_hashes
50
+ files = Dir.glob("#{path}/**/**", File::FNM_DOTMATCH).select{|x| File.file? x}.map!{|x| x.gsub path+'/', ''}
51
+ hashes = {}
52
+
53
+ files.each do |file|
54
+ hashes[file] = [
55
+ Digest::MD5.file("#{path}/#{file}").hexdigest,
56
+ File.size?("#{path}/#{file}")
57
+ ]
58
+ end
59
+
60
+ hashes
61
+ end
62
+ end
@@ -0,0 +1,42 @@
1
+ class TerminalOrder < ActiveRecord::Base
2
+
3
+ has_paper_trail
4
+
5
+ belongs_to :terminal
6
+
7
+ scope :unsent, where(:state => 'new')
8
+ scope :incomplete, where("state != ?", 'complete')
9
+
10
+ validates :terminal, :presence => true
11
+
12
+ serialize :args
13
+
14
+ after_save do
15
+ terminal.update_attribute :incomplete_orders_count,
16
+ terminal.terminal_orders.incomplete.count
17
+ end
18
+
19
+ def title
20
+ I18n.t "smartkiosk.terminal_orders.#{keyword}"
21
+ end
22
+
23
+ def error?
24
+ !error.blank?
25
+ end
26
+
27
+ def sent?
28
+ state == 'sent'
29
+ end
30
+
31
+ def complete?
32
+ state == 'complete'
33
+ end
34
+
35
+ def sent!(percent=nil, error=nil)
36
+ update_attributes(:state => (complete? ? 'complete' : 'sent'), :percent => [percent.to_i, self.percent.to_i].max, :error => error)
37
+ end
38
+
39
+ def complete!
40
+ update_attribute(:state, 'complete')
41
+ end
42
+ end
@@ -0,0 +1,120 @@
1
+ class TerminalPing
2
+ include ActiveAttr::Model
3
+ include ActiveModel::Translation
4
+ include ActiveModel::Callbacks
5
+ extend Machinist::Machinable
6
+
7
+ def self.i18n_scope
8
+ :activerecord
9
+ end
10
+
11
+ attribute :state, :type => String, :default => 'unknown'
12
+ attribute :condition, :type => String
13
+ attribute :version
14
+ attribute :ip, :type => String
15
+
16
+ # '100' => 1, '1000' => 5
17
+ attribute :banknotes, :default => {}
18
+
19
+ # :error => '...', :version => '...'
20
+ attribute :cash_acceptor, :default => {}
21
+
22
+ # :error => '', :version => ''
23
+ attribute :printer, :default => {}
24
+
25
+ # :error => '', :version => '', :signal_level => 4, :balance => 54.5
26
+ attribute :modem, :default => {}
27
+
28
+ # :payments => 5, :orders => 4
29
+ attribute :queues, :default => {}
30
+
31
+ attribute :created_at, :type => DateTime, :default => proc { DateTime.now }
32
+
33
+ def value(field, hardware)
34
+ source = (send(hardware) || {}) rescue {}
35
+ source[field].blank? ? nil : source[field]
36
+ end
37
+
38
+ def error(*hardware)
39
+ if hardware.count == 1
40
+ v = value('error', hardware.first)
41
+ return v.nil? ? nil : v.to_i
42
+ else
43
+ return hardware.map do |x|
44
+ v = value('error', x)
45
+ v.nil? ? nil : v.to_i
46
+ end
47
+ end
48
+ end
49
+
50
+ def valid?(*args)
51
+ codes = error(*Terminal::HARDWARE).compact
52
+
53
+ self.condition =
54
+ if codes.blank?
55
+ 'ok'
56
+ elsif codes.min >= 1000
57
+ 'warning'
58
+ else
59
+ 'error'
60
+ end
61
+
62
+ super
63
+ end
64
+
65
+ def ok?
66
+ condition == 'ok'
67
+ end
68
+
69
+ def cash_sum
70
+ banknotes.collect{|k,v| k.to_i*v.to_i}.sum
71
+ end
72
+
73
+ def cash_count
74
+ banknotes.values.map{|x| x.to_i}.sum
75
+ end
76
+
77
+ def cash_acceptor_error
78
+ error(:cash_acceptor)
79
+ end
80
+
81
+ def cash_acceptor_version
82
+ value 'version', :cash_acceptor
83
+ end
84
+
85
+ def cash_acceptor_model
86
+ value 'model', :cash_acceptor
87
+ end
88
+
89
+ def printer_error
90
+ error(:printer)
91
+ end
92
+
93
+ def printer_version
94
+ value 'version', :printer
95
+ end
96
+
97
+ def printer_model
98
+ value 'model', :printer
99
+ end
100
+
101
+ def modem_error
102
+ error(:modem)
103
+ end
104
+
105
+ def modem_version
106
+ value 'version', :modem
107
+ end
108
+
109
+ def modem_balance
110
+ modem['balance']
111
+ end
112
+
113
+ def modem_signal_level
114
+ modem['signal_level']
115
+ end
116
+
117
+ def modem_model
118
+ value 'model', :modem
119
+ end
120
+ end
@@ -0,0 +1,51 @@
1
+ class TerminalProfile < ActiveRecord::Base
2
+ include Redis::Objects::RMap
3
+
4
+ has_rmap({:id => lambda{|x| x.to_s}}, :keyword)
5
+ has_paper_trail
6
+
7
+ has_many :terminals, :conditions => "terminal_profile_id IS NOT NULL"
8
+ has_many :terminal_profile_promotions, :dependent => :destroy, :order => :priority
9
+ has_many :terminal_profile_providers, :dependent => :destroy, :order => :priority
10
+ has_many :terminal_profile_provider_groups, :dependent => :destroy, :order => :priority
11
+
12
+ mount_uploader :logo, FileUploader
13
+
14
+ accepts_nested_attributes_for :terminal_profile_promotions, :allow_destroy => true
15
+ accepts_nested_attributes_for :terminal_profile_providers
16
+ accepts_nested_attributes_for :terminal_profile_provider_groups
17
+
18
+ def terminal_profile_provider_groups(parent=false)
19
+ data = TerminalProfileProviderGroup.where(:terminal_profile_id => id).
20
+ includes(:provider_group => :provider_group).order(:priority)
21
+
22
+ data = data.where(:provider_groups => {:provider_group_id => parent}) unless parent === false
23
+ pgids = data.map{|x| x.provider_group_id}
24
+
25
+ ProviderGroup.all.each do |pg|
26
+ unless pgids.include?(pg.id)
27
+ data << TerminalProfileProviderGroup.new(:provider_group_id => pg.id, :terminal_profile_id => id)
28
+ end
29
+ end
30
+
31
+ data
32
+ end
33
+
34
+ def terminal_profile_providers(category=nil)
35
+ category = category.id if !category.blank? && category.respond_to?(:id)
36
+ search = category.nil? ? {} : {:provider_group_id => category}
37
+
38
+ data = TerminalProfileProvider.includes(:provider).
39
+ where(:terminal_profile_id => id, :providers => search).
40
+ order("terminal_profile_providers.priority")
41
+ pids = data.map{|x| x.provider_id}
42
+
43
+ Provider.where(search).all.each do |p|
44
+ unless pids.include?(p.id)
45
+ data << TerminalProfileProvider.new(:provider_id => p.id, :terminal_profile_id => id)
46
+ end
47
+ end
48
+
49
+ data
50
+ end
51
+ end
@@ -0,0 +1,18 @@
1
+ class TerminalProfilePromotion < ActiveRecord::Base
2
+ include Redis::Objects::RMap
3
+
4
+ value :timestamp, :global => true, :marshal => true
5
+
6
+ belongs_to :terminal_profile
7
+ belongs_to :provider
8
+
9
+ validates :provider, :presence => true
10
+
11
+ after_save do
12
+ self.class.timestamp = updated_at
13
+ end
14
+
15
+ after_destroy do
16
+ self.class.timestamp = DateTime.now
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ class TerminalProfileProvider < ActiveRecord::Base
2
+
3
+ mount_uploader :icon, IconUploader
4
+
5
+ belongs_to :provider
6
+ belongs_to :terminal_profile, :inverse_of => :terminal_profile_providers
7
+
8
+ validates :provider_id, :uniqueness => {:scope => :terminal_profile_id}
9
+ validates :provider, :presence => true
10
+ validates :terminal_profile, :presence => true
11
+ end
@@ -0,0 +1,19 @@
1
+ class TerminalProfileProviderGroup < ActiveRecord::Base
2
+
3
+ self.table_name = 'term_prof_provider_groups'
4
+
5
+ mount_uploader :icon, IconUploader
6
+
7
+ belongs_to :provider_group
8
+ belongs_to :terminal_profile, :inverse_of => :terminal_profile_provider_groups
9
+
10
+ validates :provider_group_id, :uniqueness => {:scope => :terminal_profile_id}
11
+ validates :provider_group, :presence => true
12
+ validates :terminal_profile, :presence => true
13
+
14
+ delegate :title, :to => :terminal_profile
15
+
16
+ def terminal_profile_providers
17
+ terminal_profile.terminal_profile_providers(provider_group_id)
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ class User < ActiveRecord::Base
2
+
3
+ has_paper_trail
4
+
5
+ devise :database_authenticatable,
6
+ :recoverable, :rememberable, :trackable, :validatable
7
+
8
+ #
9
+ # RELATIONS
10
+ #
11
+ has_many :user_roles
12
+ has_many :roles, :through => :user_roles
13
+
14
+ accepts_nested_attributes_for :user_roles, :allow_destroy => true
15
+
16
+ #
17
+ # VALIDATIONS
18
+ #
19
+ validates :full_name, :presence => true
20
+
21
+ #
22
+ # METHODS
23
+ #
24
+ def role?(role)
25
+ return true if root
26
+ return roles.map{|x| x.keyword}.include? role.to_s
27
+ end
28
+
29
+ def priveleged?(role, action)
30
+ return true if root
31
+ ur = user_roles.includes(:role).find{|x| x.role.keyword == role.to_s}
32
+ ur.blank? ? false : ur.priveleged?(action)
33
+ end
34
+
35
+ def title
36
+ email
37
+ end
38
+ end
@@ -0,0 +1,45 @@
1
+ class UserRole < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :role
4
+
5
+ serialize :priveleges
6
+
7
+ validates :role, :presence => true
8
+
9
+ def method_missing(method, *args)
10
+ method = method.to_s
11
+
12
+ if method.starts_with? 'can_'
13
+ role_keyword = method[method.index('_')+1..method.rindex('_')-1]
14
+ privelege = method[method.rindex('_')+1..-1]
15
+
16
+ self.priveleges = [] unless self.priveleges.is_a?(Array)
17
+
18
+ if method.ends_with? '='
19
+ privelege = privelege[0..-2]
20
+
21
+ if role && role.keyword == role_keyword
22
+ if args[0] && args[0] != 'false'
23
+ self.priveleges = (self.priveleges + [privelege]).uniq
24
+ else
25
+ self.priveleges = self.priveleges.select{|x| x != privelege}
26
+ end
27
+ end
28
+ else
29
+ return false if !role || role.keyword != role_keyword
30
+ self.priveleges.include?(privelege)
31
+ end
32
+ else
33
+ super(method.to_sym, *args)
34
+ end
35
+ end
36
+
37
+ def respond_to?(method, *args)
38
+ return true if method.to_s.starts_with? 'can_'
39
+ super
40
+ end
41
+
42
+ def priveleged?(privelege)
43
+ priveleges.include?(privelege.to_s)
44
+ end
45
+ end
@@ -0,0 +1,81 @@
1
+ # coding: utf-8
2
+
3
+ class AgentsReport < ReportBuilder::Base
4
+ def tables
5
+ @tables ||= {
6
+ :agent => Arel::Table.new(:agents),
7
+ :parent_agent => Arel::Table.new(:agents).alias("parent_agents")
8
+ }.with_indifferent_access
9
+ end
10
+
11
+ def context(start, finish)
12
+ context = tables[:agent]
13
+ context = context.join(tables[:parent_agent], Arel::Nodes::OuterJoin).on(tables[:agent][:agent_id].eq tables[:parent_agent][:id])
14
+ context = context.where(tables[:agent][:created_at].in(start..finish)) if !start.blank? || !finish.blank?
15
+ context
16
+ end
17
+
18
+ def groupping
19
+ %w(
20
+ agent.agent_id
21
+ )
22
+ end
23
+
24
+ def fields
25
+ {
26
+ '' => %w(
27
+ agent.title
28
+ agent.juristic_name
29
+ agent.juristic_address_city
30
+ agent.juristic_address_street
31
+ agent.juristic_address_home
32
+ agent.physical_address_city
33
+ agent.physical_address_district
34
+ agent.physical_address_subway
35
+ agent.physical_address_street
36
+ agent.physical_address_home
37
+ agent.contact_name
38
+ agent.contact_info
39
+ agent.director_name
40
+ agent.director_contact_info
41
+ agent.bookkeeper_name
42
+ agent.bookkeeper_contact_info
43
+ agent.inn
44
+ agent.support_phone
45
+ ),
46
+ 'agent.agent_id' => %w(
47
+ agent.agent_id
48
+ parent_agent.title
49
+ parent_agent.juristic_name
50
+ parent_agent.juristic_address_city
51
+ parent_agent.juristic_address_street
52
+ parent_agent.juristic_address_home
53
+ parent_agent.physical_address_city
54
+ parent_agent.physical_address_district
55
+ parent_agent.physical_address_subway
56
+ parent_agent.physical_address_street
57
+ parent_agent.physical_address_home
58
+ parent_agent.contact_name
59
+ parent_agent.contact_info
60
+ parent_agent.director_name
61
+ parent_agent.director_contact_info
62
+ parent_agent.bookkeeper_name
63
+ parent_agent.bookkeeper_contact_info
64
+ parent_agent.inn
65
+ parent_agent.support_phone
66
+ )
67
+ }
68
+ end
69
+
70
+ def calculations
71
+ {
72
+ :quantity => lambda{|q, t| t.groupping.blank? ? q : q.project('COUNT(*) AS "calculations.quantity"').where(tables[:agent][:agent_id].not_eq nil) }
73
+ }.with_indifferent_access
74
+ end
75
+
76
+ def conditions
77
+ {
78
+ 'agent.agent_id' => proc{ Agent.rmap.invert }
79
+ }
80
+ end
81
+ end