ig3tool 0.1.0 → 0.2.0

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 (60) hide show
  1. data/bin/ig3tool +17 -21
  2. data/lib/actions/bib.rb +295 -0
  3. data/lib/actions/bitching.rb +19 -0
  4. data/lib/actions/cultuur.rb +3 -0
  5. data/lib/actions/interne.rb +98 -0
  6. data/lib/actions/kaching.rb +90 -0
  7. data/lib/actions/people.rb +178 -0
  8. data/lib/actions/printing.rb +125 -0
  9. data/lib/actions/product.rb +154 -0
  10. data/lib/bib.rb +94 -0
  11. data/lib/billing.rb +112 -0
  12. data/lib/bitching.rb +49 -0
  13. data/lib/config.rb +19 -0
  14. data/lib/glade/cola_light_small.png +0 -0
  15. data/lib/glade/cola_light_xsmall.png +0 -0
  16. data/lib/glade/cola_small.png +0 -0
  17. data/lib/glade/cola_xsmall.png +0 -0
  18. data/lib/glade/doos_small.png +0 -0
  19. data/lib/glade/doos_xsmall.png +0 -0
  20. data/lib/glade/icons/cola_light_small.png +0 -0
  21. data/lib/glade/icons/cola_light_xsmall.png +0 -0
  22. data/lib/glade/icons/cola_small.png +0 -0
  23. data/lib/glade/icons/cola_xsmall.png +0 -0
  24. data/lib/glade/icons/doos_small.png +0 -0
  25. data/lib/glade/icons/doos_xsmall.png +0 -0
  26. data/lib/glade/icons/piggy_small.png +0 -0
  27. data/lib/glade/icons/piggy_xsmall.png +0 -0
  28. data/lib/glade/money_small.png +0 -0
  29. data/lib/glade/money_xsmall.png +0 -0
  30. data/lib/glade/newinterne.glade +504 -0
  31. data/lib/glade/piggy_small.png +0 -0
  32. data/lib/glade/piggy_xsmall.png +0 -0
  33. data/lib/glade/sales.glade +89 -87
  34. data/lib/horrible_hack.rb +15 -0
  35. data/lib/interne.rb +111 -0
  36. data/lib/ldap.rb +104 -0
  37. data/lib/log.rb +25 -0
  38. data/lib/membership.rb +32 -0
  39. data/lib/mymd5.rb +95 -0
  40. data/lib/people.rb +143 -0
  41. data/lib/printing.rb +238 -0
  42. data/lib/request.rb +14 -0
  43. data/lib/sales.rb +158 -0
  44. data/lib/ui/automaatwindow.rb +2 -2
  45. data/lib/ui/bibliotheekwindow.rb +16 -17
  46. data/lib/ui/bibwindow.rb +15 -15
  47. data/lib/ui/gladehelper.rb +20 -6
  48. data/lib/ui/internewindow.rb +12 -9
  49. data/lib/ui/loginwindow.rb +2 -4
  50. data/lib/ui/memberswindow.rb +9 -9
  51. data/lib/ui/newinterne.rb +258 -0
  52. data/lib/ui/peoplewindow.rb +14 -16
  53. data/lib/ui/printenwindow.rb +11 -11
  54. data/lib/ui/printingwindow.rb +19 -20
  55. data/lib/ui/productswindow.rb +27 -15
  56. data/lib/ui/saleswindow.rb +21 -8
  57. data/lib/ui/toolwindow.rb +5 -3
  58. data/lib/utils.rb +106 -0
  59. data/lib/web.rb +98 -0
  60. metadata +48 -3
@@ -0,0 +1,90 @@
1
+ require 'sales'
2
+ require 'people'
3
+ require 'interne'
4
+
5
+ module Ig3tool
6
+ class Actions
7
+
8
+ # This one's for you, joris :P
9
+ def self.kaching_cola(params)
10
+ scribble(params.update({"items" => {"5449000000996" => 1}}))
11
+ end
12
+
13
+ # Verwacht een array van [barcode,aantal] in 'items'
14
+ # Verwacht een username in 'debugger'
15
+ # Geeft het nieuwe saldo terug
16
+ def self.scribble!(params)
17
+ name = params['debugger'] or raise Needed, "debugger"
18
+
19
+ interne = _interne(name) or raise NotADebugger, name
20
+ Product.transaction do
21
+ _kaching_log :scribble, name, params['items']
22
+ total = _kaching(params['items'], "debugger")
23
+ interne.saldo -= total
24
+ interne.save!
25
+ total
26
+ end
27
+ end
28
+
29
+ # Verwacht een hash van barcode => aantal in 'items'
30
+ # Optioneel een status in 'status'
31
+ # Geeft kost terug.
32
+ def self.kaching!(params)
33
+ Product.transaction do
34
+ total = _kaching(params['items'], params['status'] || "plebs")
35
+ _kaching_log :kaching, params['debugger'], params['items']
36
+ total
37
+ end
38
+ end
39
+
40
+ # Automaat bijvullen. 'items' zoals kaching, en 'debugger'
41
+ def self.product_restock!(params)
42
+ debugger = params['debugger']
43
+ items = params['items']
44
+
45
+ Product.transaction do
46
+ total = _kaching(items, "plebs")
47
+ _kaching_log(:restock, debugger, items)
48
+ total
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ # Verwacht een hash van barcode => aantal en een status
55
+ # Past de stock aan, en geeft de kost terug.
56
+ def self._kaching(items, status)
57
+ cost = 0
58
+ raise Needed, "items" if items.nil? or items.empty?
59
+ Product.transaction do
60
+ items.each do |barcode, amount|
61
+ p = Product.find(barcode)
62
+ p.decrement_stock(amount)
63
+ cost += p.price(status, amount)
64
+ end
65
+
66
+ cost
67
+ end
68
+ rescue ActiveRecord::RecordNotFound => e
69
+ raise ProductNotFound, e.message[/ID=(.*)/]
70
+ end
71
+
72
+ def self._kaching_log(action, naam, items)
73
+ Product.transaction do
74
+ items.each do |barcode, amount|
75
+ p = Product.find(barcode)
76
+ raise IG3Error, "You did not enter a correct amount!" unless !amount.nil? and amount.integer? and amount > 0
77
+ action_lookup = { :kaching => "sold",
78
+ :scribble => "scribbled",
79
+ :restock => "restocked automaat with" }
80
+ action_str = action_lookup[action] or raise NotFound, "action"
81
+ Logger::log :sales, action, "%s %s %d %s" %
82
+ [ naam, action_str, amount, p.name ]
83
+ end
84
+ end
85
+ rescue ActiveRecord::RecordNotFound => e
86
+ raise ProductNotFound, e.message[/ID=(.*)/]
87
+ end
88
+
89
+ end
90
+ end
@@ -0,0 +1,178 @@
1
+ module Ig3tool
2
+ class Actions
3
+
4
+ STATUSSEN = { 0 => "non-member", 1 => "member", 2 => "honorary member", 3 => "debugger", 4 => "ex-debugger"}
5
+
6
+ # Methods om alle mensen op te vragen
7
+ singleton = class << self; self; end
8
+ %w(everybody nonmembers honorarymembers members debuggers).each do |k|
9
+ body = Proc.new do |params|
10
+ Person.send(k.to_sym)
11
+ end
12
+
13
+ singleton.class_eval { define_method "person_#{k}", body}
14
+ end
15
+
16
+ # Zoekt persons op adhv attributes
17
+ # Verwacht minstens 1 key => value pair, kan meerdere mensen teruggeven.
18
+ # Mogelijke keys: username, email, first_name, last_name, rolnr, address, phone, gsm
19
+ def self.person_lookup(params)
20
+ raise Needed, "At least one search value" if params[:given_uri] < 1
21
+ raise Needed, "Even number of search values" if params[:given_uri] % 2 == 1
22
+
23
+ keys = params[:from_uri].to_h
24
+ status = keys.delete 'status'
25
+ valid_keys = %w(username email first_name last_name rolnr address phone gsm)
26
+ res = Person.hash_lookup(keys, valid_keys)
27
+
28
+ if status
29
+ return res.select {|x| x.send "#{status}?".to_sym }
30
+ else
31
+ return res
32
+ end
33
+ rescue RuntimeError => e
34
+ raise IG3Error, e.message
35
+ end
36
+
37
+ # Geeft de memberships van een persoon terug, gesorteerd op datum
38
+ # Verwacht een username.
39
+ def self.person_memberships(params)
40
+ raise Needed, "username" if params[:given_uri] != 1
41
+ Person.find(params[:from_uri].first).memberships.sort { |a,b| b.year <=> a.year }
42
+ end
43
+
44
+ # Returnt een persoon adhv een membership barcode
45
+ def self.person_member(params)
46
+ raise Needed, "memberid" if params[:given_uri] != 1
47
+ memberid = params[:from_uri].first
48
+ member = Membership.find_by_barcode(memberid)
49
+ raise NotAMember if member.nil?
50
+ Person.find(member.username) # Zoek het member, en return de persoon
51
+ end
52
+
53
+ # Verwijdert een member (indien mogelijk -> Geen openstaande leningen/niet-0-internes/...)
54
+ def self.person_remove!(params)
55
+ username = params["username"] or raise Needed, "username"
56
+
57
+ p = Person.find username
58
+
59
+ # Controleer Interne
60
+ i = p.interne
61
+ raise SaldoNotZero, "Debugger: saldo not zero!" if !i.nil? and i.saldo != 0
62
+
63
+ # Controleer leningen
64
+ p.memberships.each do |m|
65
+ unless m.nil?
66
+ loans = BibLoan.find_by_member_id m.id
67
+ raise StillHaveLoans, "Member: outstanding loans" unless loans.nil? or loans.empty?
68
+ end
69
+ end
70
+
71
+ begin
72
+ p.destroy
73
+ rescue ActiveRecord::RecordNotFound
74
+ raise NotFound, "Person"
75
+ else
76
+ :ok
77
+ end
78
+ end
79
+
80
+ # Returnt alle mogelijk statussen
81
+ def self.person_statussen(params)
82
+ STATUSSEN # Return de Hash
83
+ end
84
+
85
+ # Voegt een persoon toe
86
+ def self.person_add!(params)
87
+ p = Person.new
88
+ p.username = params['username'] or raise Needed, "Username"
89
+ p.email = params['email'] or raise Needed, "Email"
90
+ p.first_name = params['first_name'] or raise Needed, "First_name"
91
+ p.last_name = params['last_name'] or raise Needed, "Last_name"
92
+ p.rolnr = params['rolnr']
93
+ p.address = params['address']
94
+ p.phone = params['phone']
95
+ p.gsm = params['gsm']
96
+
97
+ status = params['status'] || "non-member"
98
+ memberid = params['memberid']
99
+ if status != "non-member"
100
+ m = Membership.new
101
+ m.barcode = memberid
102
+ m.username = p.username
103
+ m.status = status
104
+ m.year = Time.werkjaar
105
+ end
106
+
107
+ pu = PrintUser.new
108
+ pu.saldo = 0
109
+
110
+ Person.transaction do
111
+ # Set username as latest because it calls save!
112
+ p.save!
113
+ pu.username = p.username
114
+ pu.save!
115
+ m.save! if status != "non-member"
116
+
117
+ pu.add_credit(200) if status == "member"
118
+ "OK"
119
+ end
120
+ end
121
+
122
+ # Update een persoon (adhv een id)
123
+ def self.person_update!(params)
124
+ raise Needed, "Username" unless params['username']
125
+ p = Person.find_by_username(params['username'])
126
+ raise NotFound if p.nil?
127
+ p.email = params['email'] or raise Needed, "Email"
128
+ p.first_name = params['first_name'] or raise Needed, "First_name"
129
+ p.last_name = params['last_name'] or raise Needed, "Last_name"
130
+ p.rolnr = params['rolnr']
131
+ p.address = params['address']
132
+ p.phone = params['phone']
133
+ p.gsm = params['gsm']
134
+ p.save!
135
+ end
136
+
137
+ def self.person_isdebugger(params)
138
+ raise Needed, "Username" unless params[:from_uri].size > 0
139
+ p = Person.find_by_username(params[:from_uri].first)
140
+ raise NotFound if p.nil?
141
+ p.debugger?
142
+ end
143
+
144
+ def self.person_status(params)
145
+ raise Needed, "Username" unless params[:from_uri].size > 0
146
+ p = Person.find_by_username(params[:from_uri].first)
147
+ raise NotFound if p.nil?
148
+ if p.debugger?
149
+ "debugger"
150
+ elsif p.member?
151
+ "member"
152
+ else
153
+ "non-member"
154
+ end
155
+ end
156
+
157
+ def self.person_bugger!(params)
158
+ raise Needed, "Username" unless params['username']
159
+ p = Person.find_by_username(params['username'])
160
+ raise NotFound if p.nil?
161
+ raise NotAMember unless p.member?
162
+ raise IG3Error, "already a debugger" if p.debugger?
163
+
164
+ p.bugger!
165
+ "OK"
166
+ end
167
+
168
+ def self.person_unbugger!(params)
169
+ raise Needed, "Username" unless params['username']
170
+ p = Person.find_by_username(params['username'])
171
+ raise NotFound if p.nil?
172
+ raise NotADebugger unless p.debugger?
173
+
174
+ p.unbugger!
175
+ "OK"
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,125 @@
1
+ require 'people'
2
+ require 'interne'
3
+ require 'printing'
4
+
5
+ module Ig3tool
6
+ class Actions
7
+
8
+ def self.print_users(params)
9
+ PrintUser.find(:all, :order => "username")
10
+ end
11
+
12
+ def self.print_debuggers(params)
13
+ users = PrintUser.find(:all, :order => "username")
14
+ users.select{|user| user.debugger?}
15
+ end
16
+
17
+ def self.print_logs(params)
18
+ max_lines = (params[:given_uri] < 1 ? 50 : params[:given_uri].first)
19
+ PrintTransaction.find(:all, :limit => max_lines, :order => "time DESC")
20
+ end
21
+
22
+ def self.print_user(params)
23
+ raise Needed, "username or alias" if params[:given_uri] < 1
24
+ username = params[:from_uri].first
25
+ PrintUser.lookup(username)
26
+ end
27
+
28
+ def self.print_remove!(params)
29
+ username = params["username"] or raise Needed, "username"
30
+ PrintUser.remove(username)
31
+ end
32
+
33
+ def self.print_addcredit!(params)
34
+ username = params["username"] or raise Needed, "username"
35
+ amount = params["amount"] or raise Needed, "amount"
36
+ pu = PrintUser.lookup(username) or raise NotFound, "username"
37
+ pu.add_credit(amount)
38
+ pu
39
+ end
40
+
41
+ def self.print_errortest(params)
42
+ PrintUser.errortest
43
+ end
44
+
45
+ def self.print_update!(params)
46
+ username = params["username"] or raise Needed, "username"
47
+ firstname = params["firstname"]
48
+ lastname = params["lastname"]
49
+ email = params["email"]
50
+ raise Needed, "at least one of: username, firstname, lastname" if lastname.nil? && firstname.nil? && email.nil?
51
+ amount = params["amount"] || 0
52
+ begin
53
+ p = Person.find(username)
54
+ rescue
55
+ p = Person.new
56
+ p.username = username
57
+ raise Needed, "username, firstname and lastname" if lastname.nil? && firstname.nil? && email.nil?
58
+ end
59
+ p.first_name = firstname unless firstname.nil?
60
+ p.last_name = lastname unless lastname.nil?
61
+ p.email = email unless email.nil?
62
+ p.save!
63
+ begin
64
+ pu = PrintUser.lookup(username)
65
+ rescue NotFound => err
66
+ pu = PrintUser.new
67
+ pu.username = username
68
+ pu.save!
69
+ end
70
+ pu.add_credit(amount) if amount.to_i.to_b
71
+ pu
72
+ end
73
+
74
+ def self.print_refund!(params)
75
+ logid = params["logid"] or raise Needed, "logid"
76
+ begin
77
+ transaction = PrintTransaction.find(logid)
78
+ transaction.refund
79
+ rescue
80
+ raise TransactionNotFound, "this log id is not valid"
81
+ end
82
+ end
83
+
84
+ def self.print_print!(params)
85
+ username = params["username"] or raise Needed, "username"
86
+ job = params["job"] or raise Needed, "job"
87
+ pages = params["pages"] or raise Needed, "pages"
88
+ copies = params["copies"] or raise Needed, "copies"
89
+ host = params["host"] or raise Needed, "host"
90
+ amount = params["amount"] or raise Needed, "amount"
91
+ queue = params["queue"] or raise Needed, "queue"
92
+ message = params["message"] || ""
93
+ pu = PrintUser.lookup(username)
94
+ pu.print(job, pages, copies, host, amount, queue, message)
95
+ end
96
+
97
+ def self.print_addalias!(params)
98
+ username = params["username"] or raise Needed, "username"
99
+ nwalias = params["alias"] or raise Needed, "alias"
100
+ pu = PrintUser.find(username) # dit is eigenlijk overkill, lekker!
101
+ pa = PrintAlias.new
102
+ pa.username = username
103
+ pa.alias = nwalias
104
+ pa.save!
105
+ end
106
+
107
+ def self.print_removealias!(params)
108
+ username = params["username"] or raise Needed, "username"
109
+ a = params["alias"] or raise Needed, "alias"
110
+ pa = PrintAlias.find(a)
111
+ if pa.print_user.username == username
112
+ pa.destroy
113
+ else
114
+ raise NotFound, "wrong username"
115
+ end
116
+ end
117
+
118
+ def self.print_removealiases!(params)
119
+ username = params["username"] or raise Needed, "username"
120
+ pu = PrintUser.lookup(username).remove_aliases
121
+ pu
122
+ end
123
+
124
+ end
125
+ end
@@ -0,0 +1,154 @@
1
+ require 'sales'
2
+ module Ig3tool
3
+ class Actions
4
+
5
+ # Geeft alle categorieen terug.
6
+ def self.product_categories(params)
7
+ Category.find(:all)
8
+ end
9
+
10
+ # Geeft alle producten uit een categorie terug
11
+ def self.product_category(params)
12
+ raise Needed, "Category" if params[:given_uri] != 1
13
+ Category.find(params[:from_uri].first).products
14
+ end
15
+
16
+ # Verwacht een barcode in de URL
17
+ # Geeft het product terug
18
+ def self.product_lookup(params)
19
+ raise Needed, "Barcode" if params[:given_uri] != 1
20
+
21
+ p = params[:from_uri].first
22
+ _product(p)
23
+ end
24
+
25
+ # Verwacht geen parameters
26
+ # Geeft alle producten in de stock terug
27
+ def self.product_all(params)
28
+ #Product.find :all, :conditions => { 'stock_gt' => 0 } # Stock Greater than
29
+ Product.find :all, :include => [:purchases]
30
+ end
31
+
32
+ # Verwacht een barcode in de URL
33
+ # Geeft de stock terug
34
+ def self.product_stock(params)
35
+ raise Needed, "Barcode" if params[:given_uri] != 1
36
+
37
+ prod = _product(params[:from_uri].first)
38
+ prod.stock
39
+ end
40
+
41
+ # Verwacht een barcode en de stock in de URL
42
+ # Geeft de diff stock terug
43
+ # Verwijdert de oudste items indien newstock < oldstock
44
+ # Voegt items toe met de nieuwste prijs indien newstock > oldstock
45
+ def self.product_diff!(params)
46
+ barcode = params["barcode"] or raise Needed, "Barcode"
47
+ newstock = params["stock"] or raise Needed, "Stock"
48
+ p = _product(barcode)
49
+ oldstock = p.stock
50
+
51
+ if oldstock < newstock
52
+ # TODO XXX Set Price!
53
+ else
54
+ # TODO remove from stock!
55
+ end
56
+
57
+ Logger::log :stock, :diff, "%s stock changed from %d to %d" %
58
+ [ p.name, oldstock, p.stock ]
59
+ end
60
+
61
+ # Voegt een product toe aan de DB
62
+ # Verwacht 'barcode', 'name', 'category', 'nmprice', 'mprice' en 'dprice'
63
+ def self.product_add!(params)
64
+ notfound = []
65
+
66
+ [:barcode, :name, :category, :nmprice, :mprice, :dprice].each do |k|
67
+ notfound << k unless params.include? k.to_s and !params[k.to_s].nil?
68
+ end
69
+
70
+ raise Needed, notfound unless notfound.empty?
71
+
72
+ p = \
73
+ Product.create(:barcode => params["barcode"],
74
+ :name => params["name"],
75
+ :category => Category.find_by_name(params["category"].capitalize),
76
+ :nmprice => params["nmprice"],
77
+ :mprice => params["mprice"],
78
+ :dprice => params["dprice"],
79
+ :stock => 0) # XXX of params["amount"] ?
80
+
81
+ Logger::log :product, :add, "Added %d (%s)" % [ params["barcode"], params["name"] ]
82
+
83
+ "OK"
84
+ end
85
+
86
+ def self.product_remove!(params)
87
+ barcode = params["barcode"] or raise Needed, "Barcode"
88
+ p = _product(barcode)
89
+
90
+ raise "still in stock, won't delete!" if p.stock > 0
91
+
92
+ p.destroy
93
+
94
+ "OK"
95
+ end
96
+
97
+ # Laat een 'debugger' een aankoop ingeven, met factuurnummer 'reference'.
98
+ # Verwacht een hash barcode => [amount, cost] in 'items'.
99
+ def self.product_purchase!(params)
100
+ name = params["debugger"] or raise NeedDebugger
101
+ debugger = Person.find_by_username(name)
102
+ raise NotADebugger.new(name) unless !debugger.nil? && debugger.debugger?
103
+
104
+ notfound = []
105
+ params["items"].each do |barcode, item|
106
+ _product(barcode, false) or notfound << barcode
107
+ item[0] = item[0].to_i
108
+ item[1] = item[1].to_i
109
+ amount, cost = item
110
+ raise "You're funny." unless amount.integer?
111
+ end
112
+
113
+ raise ProductNotFound.new(notfound.join(', ')) unless notfound.empty?
114
+
115
+ Product.transaction do
116
+ params["items"].each do |barcode, data|
117
+ amount, cost = data
118
+ p = _product(barcode)
119
+ p.stock += amount
120
+ p.save
121
+
122
+ Purchase.create(:time => Time.now,
123
+ :debugger => debugger,
124
+ :product => p,
125
+ :count => amount,
126
+ :cost => cost)
127
+
128
+ Logger::log :purchase, :add, "%s purchased %d x '%s' for %0.2f" %
129
+ [ debugger.username, amount, p.name, cost ]
130
+ end
131
+ end
132
+
133
+ "OK"
134
+ end
135
+
136
+ def self.product_purchases(params)
137
+ p = params[:from_uri].first
138
+ if p.nil? or p == "all"
139
+ Purchase.find :all, :order => "product, time desc"
140
+ else
141
+ Purchase.find_all_by_barcode(p, :order => "product, time desc")
142
+ end
143
+ end
144
+
145
+ private
146
+ def self._product(barcode, complain=true)
147
+ Product.find(barcode, :include => [:purchases])
148
+ rescue
149
+ raise NotFound, "Product" if complain
150
+ nil
151
+ end
152
+
153
+ end
154
+ end