smartkiosk-client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/Gemfile +5 -0
  2. data/Gemfile.lock +176 -0
  3. data/Rakefile +4 -0
  4. data/app/controllers/banners.rb +14 -0
  5. data/app/controllers/collections.rb +10 -0
  6. data/app/controllers/config.rb +23 -0
  7. data/app/controllers/payments.rb +30 -0
  8. data/app/controllers/receipts.rb +13 -0
  9. data/app/controllers/terminal.rb +104 -0
  10. data/app/models/admin.rb +3 -0
  11. data/app/models/banner.rb +5 -0
  12. data/app/models/collection.rb +53 -0
  13. data/app/models/customer.rb +3 -0
  14. data/app/models/group.rb +37 -0
  15. data/app/models/order.rb +25 -0
  16. data/app/models/payment.rb +80 -0
  17. data/app/models/phone_range.rb +3 -0
  18. data/app/models/promotion.rb +11 -0
  19. data/app/models/provider.rb +42 -0
  20. data/app/models/receipt.rb +21 -0
  21. data/app/models/receipt_template.rb +5 -0
  22. data/app/models/terminal.rb +152 -0
  23. data/app/uploaders/icon_uploader.rb +9 -0
  24. data/app/views/banners.haml +50 -0
  25. data/app/workers/orders/acknowledge_worker.rb +22 -0
  26. data/app/workers/orders/complete_worker.rb +20 -0
  27. data/app/workers/orders/disable_worker.rb +16 -0
  28. data/app/workers/orders/enable_worker.rb +16 -0
  29. data/app/workers/orders/reboot_worker.rb +18 -0
  30. data/app/workers/orders/reload_worker.rb +18 -0
  31. data/app/workers/orders/upgrade_worker.rb +108 -0
  32. data/app/workers/payments/check_worker.rb +35 -0
  33. data/app/workers/payments/collect_worker.rb +23 -0
  34. data/app/workers/payments/pay_worker.rb +21 -0
  35. data/app/workers/ping_worker.rb +180 -0
  36. data/app/workers/startup_worker.rb +11 -0
  37. data/app/workers/sync/icons_worker.rb +20 -0
  38. data/app/workers/sync/receipt_templates_worker.rb +27 -0
  39. data/config/boot.rb +104 -0
  40. data/config/services/application.yml +4 -0
  41. data/config/services/database.yml +17 -0
  42. data/config/services/database.yml.sample +33 -0
  43. data/config/services/smartware.yml +28 -0
  44. data/config/services/smartware.yml.sample +13 -0
  45. data/config/sidekiq.yml +12 -0
  46. data/db/development.sqlite3 +0 -0
  47. data/db/migrate/20121230080152_create_customers.rb +8 -0
  48. data/db/migrate/20121230080159_create_admins.rb +11 -0
  49. data/db/migrate/20130106150707_create_orders.rb +14 -0
  50. data/db/migrate/20130106155321_create_providers.rb +19 -0
  51. data/db/migrate/20130106160834_create_groups.rb +11 -0
  52. data/db/migrate/20130106181512_create_receipt_templates.rb +9 -0
  53. data/db/migrate/20130106181548_create_payments.rb +26 -0
  54. data/db/migrate/20130106181729_create_collections.rb +10 -0
  55. data/db/migrate/20130106181803_create_receipts.rb +15 -0
  56. data/db/migrate/20130106181844_create_phone_ranges.rb +14 -0
  57. data/db/migrate/20130108110546_create_promotions.rb +9 -0
  58. data/db/migrate/20130110025256_create_banners.rb +12 -0
  59. data/init.rb +1 -0
  60. data/lib/pinger.rb +22 -0
  61. data/lib/sidekiq.rb +20 -0
  62. data/lib/smartkiosk/client/version.rb +7 -0
  63. data/lib/smartkiosk/client.rb +1 -0
  64. data/lib/smartkiosk/config/chunk.rb +7 -0
  65. data/lib/smartkiosk/config/yaml.rb +26 -0
  66. data/lib/tasks/db.rb +15 -0
  67. data/lib/tasks/pack.rb +27 -0
  68. data/lib/tasks/scheduler.rb +27 -0
  69. data/lib/tasks/services.rb +20 -0
  70. data/server.rb +11 -0
  71. data/smartkiosk-client.gemspec +55 -0
  72. data/tmp/pids/.gitkeep +0 -0
  73. data/tmp/pids/sidekiq.pid +1 -0
  74. data/vendor/assets/javascripts/jquery.js +9555 -0
  75. metadata +444 -0
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'pry'
data/Gemfile.lock ADDED
@@ -0,0 +1,176 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ smartkiosk-client (0.0.1)
5
+ activesupport (= 3.2.11)
6
+ amqp (= 0.9.8)
7
+ carrierwave (= 0.7.1)
8
+ file-tail (= 1.0.12)
9
+ haml (= 3.1.7)
10
+ liquid (= 2.4.1)
11
+ pg (= 0.14.1)
12
+ pry (= 0.9.10)
13
+ rake (= 10.0.3)
14
+ recursive-open-struct (= 0.2.1)
15
+ redis (= 3.0.2)
16
+ redis-objects (= 0.6.1)
17
+ rest-client (= 1.6.7)
18
+ rubyzip (= 0.9.9)
19
+ rufus-scheduler (= 2.0.17)
20
+ sass (= 3.2.5)
21
+ sidekiq (= 2.6.5)
22
+ sinatra (= 1.3.4)
23
+ sinatra-activerecord (= 1.2.1)
24
+ sinatra-contrib (= 1.3.2)
25
+ slim (= 1.3.4)
26
+ smartguard (= 0.3.8)
27
+ smartkiosk-common (= 0.0.2)
28
+ smartware (= 0.2.8)
29
+ sprockets (= 2.8.2)
30
+ sprockets-helpers (= 0.8.0)
31
+ sprockets-sass (= 0.9.1)
32
+ sqlite3 (= 1.3.6)
33
+ thin (= 1.5.0)
34
+
35
+ GEM
36
+ remote: https://rubygems.org/
37
+ specs:
38
+ activemodel (3.2.11)
39
+ activesupport (= 3.2.11)
40
+ builder (~> 3.0.0)
41
+ activerecord (3.2.11)
42
+ activemodel (= 3.2.11)
43
+ activesupport (= 3.2.11)
44
+ arel (~> 3.0.2)
45
+ tzinfo (~> 0.3.29)
46
+ activesupport (3.2.11)
47
+ i18n (~> 0.6)
48
+ multi_json (~> 1.0)
49
+ amq-client (0.9.11)
50
+ amq-protocol (>= 1.0.1)
51
+ eventmachine
52
+ amq-protocol (1.1.0)
53
+ amqp (0.9.8)
54
+ amq-client (~> 0.9.5)
55
+ amq-protocol (>= 0.9.4)
56
+ eventmachine
57
+ arel (3.0.2)
58
+ backports (2.7.1)
59
+ builder (3.0.4)
60
+ carrierwave (0.7.1)
61
+ activemodel (>= 3.2.0)
62
+ activesupport (>= 3.2.0)
63
+ celluloid (0.12.4)
64
+ facter (>= 1.6.12)
65
+ timers (>= 1.0.0)
66
+ cmux (0.0.2)
67
+ ffi
68
+ coderay (1.0.8)
69
+ colored (1.2)
70
+ connection_pool (1.0.0)
71
+ daemons (1.1.9)
72
+ digest-crc (0.3.0)
73
+ eventmachine (1.0.0)
74
+ facter (1.6.17)
75
+ ffi (1.3.1)
76
+ file-tail (1.0.12)
77
+ tins (~> 0.5)
78
+ haml (3.1.7)
79
+ hike (1.2.1)
80
+ i18n (0.6.1)
81
+ liquid (2.4.1)
82
+ method_source (0.8.1)
83
+ mime-types (1.19)
84
+ multi_json (1.5.0)
85
+ pg (0.14.1)
86
+ pry (0.9.10)
87
+ coderay (~> 1.0.5)
88
+ method_source (~> 0.8)
89
+ slop (~> 3.3.1)
90
+ rack (1.5.1)
91
+ rack-protection (1.3.2)
92
+ rack
93
+ rack-test (0.6.2)
94
+ rack (>= 1.0)
95
+ rake (10.0.3)
96
+ recursive-open-struct (0.2.1)
97
+ redcarpet (2.2.2)
98
+ redis (3.0.2)
99
+ redis-namespace (1.2.1)
100
+ redis (~> 3.0.0)
101
+ redis-objects (0.6.1)
102
+ redis (>= 3.0.2)
103
+ rest-client (1.6.7)
104
+ mime-types (>= 1.16)
105
+ rubyzip (0.9.9)
106
+ rufus-scheduler (2.0.17)
107
+ tzinfo (>= 0.3.23)
108
+ sass (3.2.5)
109
+ serialport (1.1.0)
110
+ sidekiq (2.6.5)
111
+ celluloid (~> 0.12.0)
112
+ connection_pool (~> 1.0)
113
+ multi_json (~> 1)
114
+ redis (~> 3)
115
+ redis-namespace
116
+ sinatra (1.3.4)
117
+ rack (~> 1.4)
118
+ rack-protection (~> 1.3)
119
+ tilt (~> 1.3, >= 1.3.3)
120
+ sinatra-activerecord (1.2.1)
121
+ activerecord (~> 3.0)
122
+ sinatra (~> 1.0)
123
+ sinatra-contrib (1.3.2)
124
+ backports (>= 2.0)
125
+ eventmachine
126
+ rack-protection
127
+ rack-test
128
+ sinatra (~> 1.3.0)
129
+ tilt (~> 1.3)
130
+ slim (1.3.4)
131
+ temple (~> 0.5.5)
132
+ tilt (~> 1.3.3)
133
+ slop (3.3.3)
134
+ smartguard (0.3.8)
135
+ activesupport
136
+ colored
137
+ i18n
138
+ smartkiosk-common
139
+ trollop
140
+ smartkiosk-common (0.0.2)
141
+ smartware (0.2.8)
142
+ activesupport
143
+ cmux (>= 0.0.2)
144
+ digest-crc
145
+ redcarpet
146
+ serialport
147
+ smartkiosk-common (>= 0.0.2)
148
+ trollop
149
+ sprockets (2.8.2)
150
+ hike (~> 1.2)
151
+ multi_json (~> 1.0)
152
+ rack (~> 1.0)
153
+ tilt (~> 1.1, != 1.3.0)
154
+ sprockets-helpers (0.8.0)
155
+ sprockets (~> 2.0)
156
+ sprockets-sass (0.9.1)
157
+ sprockets (~> 2.0)
158
+ tilt (~> 1.1)
159
+ sqlite3 (1.3.6)
160
+ temple (0.5.5)
161
+ thin (1.5.0)
162
+ daemons (>= 1.0.9)
163
+ eventmachine (>= 0.12.6)
164
+ rack (>= 1.0.0)
165
+ tilt (1.3.3)
166
+ timers (1.1.0)
167
+ tins (0.6.0)
168
+ trollop (2.0)
169
+ tzinfo (0.3.35)
170
+
171
+ PLATFORMS
172
+ ruby
173
+
174
+ DEPENDENCIES
175
+ pry
176
+ smartkiosk-client!
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'bundler/gem_tasks'
2
+ require_relative 'config/boot'
3
+
4
+ Application.load_tasks!
@@ -0,0 +1,14 @@
1
+ require 'haml'
2
+
3
+ class Application
4
+ get '/banners' do
5
+ haml :banners
6
+ end
7
+
8
+ get '/banners/playlist' do
9
+ banner = Banner.where('playorder > ?', (params[:prev]||0).to_f).first
10
+ banner = Banner.first unless banner
11
+
12
+ json banner
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ class Application
2
+ post '/collections' do
3
+ if collection = Collection.collect!
4
+ collection.report
5
+ collection.receipt.print
6
+ end
7
+
8
+ json collection
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ class Application
2
+ def configs
3
+ @configs ||= {
4
+ :application => Terminal.config,
5
+ :smartware => Smartkiosk::Config::YAML.new(Application.root.join 'config/services/smartware.yml')
6
+ }
7
+ end
8
+
9
+ get '/config' do
10
+ json Hash[*configs.map{|k,v| [k, v.marshal_dump]}.flatten]
11
+ end
12
+
13
+ post '/config' do
14
+ params['smartware']['interfaces'] = params['smartware']['interfaces'].values
15
+
16
+ configs.each do |key, value|
17
+ value.marshal_load params[key] unless params[key].blank?
18
+ value.save!
19
+ end
20
+
21
+ json Hash[*configs.map{|k,v| [k, v.marshal_dump]}.flatten]
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ class Application
2
+ post '/payments' do
3
+ payment = Payment.create! params[:payment]
4
+ json (payment.check ? payment.as_json : false)
5
+ end
6
+
7
+ post '/payments/open/:id' do
8
+ payment = Payment.find(params[:id])
9
+ Smartware.cash_acceptor.open(payment.limit.try('[]', :min), payment.limit.try('[]', :max))
10
+ json (Smartware.cash_acceptor.error.blank? ? true : false)
11
+ end
12
+
13
+ post '/payments/pay/:id' do
14
+ payment = Payment.find(params[:id])
15
+ Smartware.cash_acceptor.close
16
+ payment.update_attributes :banknotes => Smartware.cash_acceptor.banknotes
17
+ payment.receipt.print
18
+ payment.pay
19
+ nil
20
+ end
21
+
22
+ get '/payments/cash' do
23
+ json Smartware.cash_acceptor.sum.to_json
24
+ end
25
+
26
+ get '/payments/reset' do
27
+ Smartware.cash_acceptor.close
28
+ nil
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ class Application
2
+ get '/receipts' do
3
+ json Receipt.recent.includes(:document).as_json(
4
+ :only => [:id, :printer, :keyword, :created_at, :printed], :methods => :document_title
5
+ )
6
+ end
7
+
8
+ post '/receipts/print' do
9
+ receipts = Receipt.where(:printed => false)
10
+ receipts.each{|x| x.print}
11
+ json receipts.as_json(:only => [:id, :printed])
12
+ end
13
+ end
@@ -0,0 +1,104 @@
1
+ require 'uri'
2
+
3
+ Application.load 'lib/pinger'
4
+
5
+ class Application
6
+ get '/terminal' do
7
+ Terminal.payment_in_progress = params[:payment_in_progress] == 'true'
8
+
9
+ result = {
10
+ :enabled => Terminal.enabled?,
11
+ :started_at => Terminal.started_at.value
12
+ }
13
+
14
+ modified_at = Terminal.actual_modified_at.change(:usec => 0)
15
+
16
+ if params[:modified_at] && (modified_at > DateTime.parse(params[:modified_at]))
17
+ result[:terminal] = Terminal.as_json
18
+ end
19
+
20
+ json result
21
+ end
22
+
23
+ get '/terminal/condition' do
24
+ json Terminal.condition.merge(:keyword => Terminal.keyword)
25
+ end
26
+
27
+ get '/terminal/logs' do
28
+ files = {
29
+ :smartguard => '/var/log/smartguard.log',
30
+ :front => Application.root.join('log/production.log'),
31
+ :sidekiq => Application.root.join('log/sidekiq.log'),
32
+ :smartware => Application.root.join('log/smartware.log')
33
+ }
34
+
35
+ files.keys.each do |entry|
36
+ path = files[entry]
37
+ files[entry] = []
38
+
39
+ File.open(path) do |f|
40
+ f.extend(File::Tail)
41
+ f.backward(1000)
42
+ 1000.times{ files[entry] << f.readline } rescue nil
43
+ end if File.exist?(path)
44
+ end
45
+
46
+ json files
47
+ end
48
+
49
+ post '/terminal/enable' do
50
+ Terminal.enable
51
+ json(:state => Terminal.actual_state)
52
+ end
53
+
54
+ post '/terminal/disable' do
55
+ Terminal.disable
56
+ json(:state => Terminal.actual_state)
57
+ end
58
+
59
+ post '/terminal/reload' do
60
+ Terminal.reload
61
+ json(:state => Terminal.actual_state)
62
+ end
63
+
64
+ post '/terminal/reboot' do
65
+ Terminal.reboot
66
+ json(:state => Terminal.actual_state)
67
+ end
68
+
69
+ get '/terminal/test_connection' do
70
+ begin
71
+ uri = URI.parse(Terminal.config.host)
72
+
73
+ json(
74
+ :server_http => Pinger.http(Terminal.config.host),
75
+ :server_ping => Pinger.external(uri.host),
76
+ :google_ping => Pinger.external('google.com')
77
+ )
78
+ rescue
79
+ json {}
80
+ end
81
+ end
82
+
83
+ get '/terminal/test_printer' do
84
+ Smartware.printer.test
85
+ nil
86
+ end
87
+
88
+ get '/terminal/print_balance' do
89
+ period_start = Collection.order('created_at DESC').first.try(:created_at)
90
+ period_start ||= Payment.order(:created_at).first.try(:created_at)
91
+ period_start ||= Date.civil(0, 1, 1)
92
+
93
+ receipt = Receipt.create :template => ReceiptTemplate.read('balance'),
94
+ :keyword => 'balance',
95
+ :fields => {
96
+ :balance => Payment.merge_cash,
97
+ :period_start => I18n.l(period_start),
98
+ :period_end => I18n.l(Time.now)
99
+ }
100
+
101
+ receipt.print
102
+ nil
103
+ end
104
+ end
@@ -0,0 +1,3 @@
1
+ class Admin < ActiveRecord::Base
2
+ # attr_accessible :title, :body
3
+ end
@@ -0,0 +1,5 @@
1
+ class Banner < ActiveRecord::Base
2
+
3
+ default_scope where(:visible => true).order('playorder ASC')
4
+
5
+ end
@@ -0,0 +1,53 @@
1
+ class Collection < ActiveRecord::Base
2
+ has_one :receipt, :as => :document, :dependent => :destroy
3
+
4
+ serialize :banknotes
5
+ serialize :payment_ids
6
+
7
+ after_save do
8
+ period_start = Collection.where("id != ?", self.id).order('created_at DESC').first.try(:created_at)
9
+ period_start ||= Payment.order(:created_at).first.try(:created_at)
10
+ period_start ||= Date.civil(0, 1, 1)
11
+
12
+ r = Receipt.find_or_create_by_document_id_and_document_type(id, self.class.name)
13
+ r.update_attributes :template => ReceiptTemplate.read('collection'),
14
+ :keyword => 'collection',
15
+ :fields => {
16
+ :period_start => I18n.l(period_start),
17
+ :period_end => I18n.l(created_at),
18
+ :amount => amount,
19
+ :banknotes => Hash[banknotes.sort].inject([]){|arr, (nom, cnt)| arr << {'nominal' => nom, 'count' => cnt, 'product' => nom.to_i*cnt.to_i} }
20
+ }
21
+ end
22
+
23
+ def self.collect!
24
+ payments = Payment.uncollected.complete.all
25
+
26
+ return false if payments.blank?
27
+
28
+ self.transaction do
29
+ collection = self.create!(
30
+ :banknotes => Payment.merge_banknotes(payments),
31
+ :payment_ids => payments.map(&:id)
32
+ )
33
+
34
+ payments.each{|x| x.update_attribute :collection_id, collection.id}
35
+
36
+ return collection
37
+ end
38
+
39
+ return false
40
+ end
41
+
42
+ def title
43
+ amount
44
+ end
45
+
46
+ def report
47
+ Payments::CollectWorker.perform_async(id)
48
+ end
49
+
50
+ def amount
51
+ banknotes.inject(0){|sum, (nominal, count)| sum + nominal.to_i*count.to_i }
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+ class Customer < ActiveRecord::Base
2
+ # attr_accessible :title, :body
3
+ end
@@ -0,0 +1,37 @@
1
+ require 'carrierwave/orm/activerecord'
2
+
3
+ class Group < ActiveRecord::Base
4
+ has_many :providers
5
+ has_many :groups
6
+
7
+ default_scope order(:priority)
8
+
9
+ mount_uploader :icon, IconUploader
10
+
11
+ attr_accessor :foreign_id
12
+
13
+ before_create do
14
+ self.id = self.foreign_id unless foreign_id.blank?
15
+ end
16
+
17
+ after_save do
18
+ Terminal.modified_at = DateTime.now
19
+ end
20
+
21
+ after_destroy do
22
+ Terminal.modified_at = DateTime.now
23
+ end
24
+
25
+ def icon_url
26
+ icon.url
27
+ end
28
+
29
+ def as_json
30
+ {
31
+ :id => id,
32
+ :title => title,
33
+ :icon => icon.url,
34
+ :parent => group_id
35
+ }
36
+ end
37
+ end
@@ -0,0 +1,25 @@
1
+ class Order < ActiveRecord::Base
2
+
3
+ serialize :args
4
+ #
5
+ # METHODS
6
+ #
7
+ def acknowledge
8
+ Orders::AcknowledgeWorker.perform_async id
9
+ end
10
+
11
+ def acknowledged!
12
+ update_attribute(:acknowledged, true)
13
+ end
14
+
15
+ def complete
16
+ return if complete?
17
+
18
+ update_attribute(:complete, true)
19
+ Orders::CompleteWorker.perform_async id
20
+ end
21
+
22
+ def perform
23
+ "orders/#{keyword}_worker".camelize.constantize.perform_async(id)
24
+ end
25
+ end
@@ -0,0 +1,80 @@
1
+ class Payment < ActiveRecord::Base
2
+ belongs_to :provider
3
+ has_one :receipt, :as => :document, :dependent => :destroy
4
+
5
+ default_scope includes(:provider)
6
+
7
+ scope :complete, where(:processed => true)
8
+ scope :uncollected, where(:collection_id => nil)
9
+
10
+ serialize :fields
11
+ serialize :limits
12
+ serialize :commissions
13
+ serialize :banknotes
14
+
15
+ validates :provider, :presence => true
16
+
17
+ before_save do
18
+ if banknotes
19
+ self.paid_amount = banknotes.inject(0){|sum, (nominal, count)| sum + nominal.to_i*count.to_i }
20
+ self.commission_amount = commission_for(self.paid_amount)
21
+ end
22
+ end
23
+
24
+ after_save do
25
+ if checked?
26
+ r = Receipt.find_or_create_by_document_id_and_document_type(id, self.class.name)
27
+ r.update_attributes :template => self.receipt_template,
28
+ :keyword => 'payment',
29
+ :fields => {
30
+ :recipient => provider.title,
31
+ :account => account,
32
+ :payment_paid_amount => paid_amount || 0,
33
+ :payment_enrolled_amount => ((paid_amount || 0) - (commission_amount || 0)).round(2),
34
+ :payment_commission_amount => commission_amount || 0,
35
+ :payment_paid_at => I18n.l(updated_at)
36
+ }
37
+ end
38
+ end
39
+
40
+ def self.merge_banknotes(payments=nil)
41
+ payments ||= self.all
42
+ payments.reject{|l| l.banknotes.nil? }.map(&:banknotes).reduce({}) do |result, entry|
43
+ result.merge(entry) {|key, left, right| left.to_i+right.to_i }
44
+ end
45
+ end
46
+
47
+ def self.merge_cash(payments=nil)
48
+ payments ||= self.all
49
+ payments.map(&:paid_amount).compact.sum
50
+ end
51
+
52
+ def title
53
+ provider.title
54
+ end
55
+
56
+ def commission_for(amount)
57
+ return 0 if commissions.blank?
58
+
59
+ commission = commissions.select{|x| x.max >= amount && amount >= x.min }.
60
+ sort_by{|x| x[:weight]}.first
61
+
62
+ return 0 if commission.blank?
63
+
64
+ static = commission['static_fee'] || 0
65
+ percent = ((commission['percent_fee'] || 0)/100*amount).round(2)
66
+
67
+ static+percent
68
+ end
69
+
70
+ def check
71
+ Payments::CheckWorker.new.perform(id)
72
+ reload
73
+
74
+ checked?
75
+ end
76
+
77
+ def pay
78
+ Payments::PayWorker.perform_async(id)
79
+ end
80
+ end
@@ -0,0 +1,3 @@
1
+ class PhoneRange < ActiveRecord::Base
2
+ scope :by_range, lambda {|query| where(PhoneRange.arel_table[:start].lteq(query.ljust(10, '0').to_i)).where(PhoneRange.arel_table[:end].gteq(query.ljust(10, '0').to_i)) }
3
+ end
@@ -0,0 +1,11 @@
1
+ class Promotion < ActiveRecord::Base
2
+ belongs_to :provider
3
+
4
+ after_save do
5
+ Terminal.modified_at = DateTime.now
6
+ end
7
+
8
+ after_destroy do
9
+ Terminal.modified_at = DateTime.now
10
+ end
11
+ end
@@ -0,0 +1,42 @@
1
+ require 'carrierwave/orm/activerecord'
2
+
3
+ class Provider < ActiveRecord::Base
4
+ belongs_to :group
5
+ serialize :fields
6
+
7
+ mount_uploader :icon, IconUploader
8
+
9
+ scope :active, where(arel_table[:fields_count].gt 0)
10
+
11
+ before_save do
12
+ self.fields_count = fields.length
13
+ end
14
+
15
+ after_save do
16
+ Terminal.modified_at = DateTime.now
17
+ end
18
+
19
+ after_destroy do
20
+ Terminal.modified_at = DateTime.now
21
+ end
22
+
23
+ def as_json
24
+ {
25
+ :id => id,
26
+ :group => group_id,
27
+ :keyword => keyword,
28
+ :title => title,
29
+ :icon => icon.url,
30
+ :fields => fields
31
+ }
32
+ end
33
+
34
+ def self.to_hash(column, entries=false, options={})
35
+ scope = Provider.select([:id, column])
36
+ scope = scope.where(column => entries) if entries
37
+ scope = scope.map{|x| [x.id, x.send(column)]} if options[:invert].blank?
38
+ scope = scope.map{|x| [x.send(column), x.id]} if options[:invert]
39
+
40
+ Hash[*scope.flatten]
41
+ end
42
+ end
@@ -0,0 +1,21 @@
1
+ require 'liquid'
2
+
3
+ class Receipt < ActiveRecord::Base
4
+ belongs_to :document, :polymorphic => true
5
+ serialize :fields
6
+
7
+ scope :recent, where(
8
+ arel_table[:created_at].gt(Date.today-1.month).or(arel_table[:printed].eq(false))
9
+ ).order(arel_table[:id].desc)
10
+
11
+ def print
12
+ data = fields.merge(:id => id, :keyword => Terminal.config.keyword)
13
+ result = Liquid::Template.parse(template).render data.with_indifferent_access
14
+ update_attributes(:printed => true) if Smartware.printer.print_text(result)
15
+ end
16
+
17
+ def document_title
18
+ document.blank? ? '' : document.title
19
+ end
20
+
21
+ end
@@ -0,0 +1,5 @@
1
+ class ReceiptTemplate < ActiveRecord::Base
2
+ def self.read(keyword)
3
+ find_by_keyword(keyword).try(:template) || "!!! Template not found !!!"
4
+ end
5
+ end