ig3tool 0.1.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 (63) hide show
  1. data/bin/ig3tool +114 -0
  2. data/lib/glade/bib.glade +539 -0
  3. data/lib/glade/bibliotheek.glade +994 -0
  4. data/lib/glade/icons/cola.png +0 -0
  5. data/lib/glade/icons/emblem-money.png +0 -0
  6. data/lib/glade/icons/emblem-package.png +0 -0
  7. data/lib/glade/icons/emblem-penning.xpm +98 -0
  8. data/lib/glade/icons/emblem-people.png +0 -0
  9. data/lib/glade/icons/emblem-sales.png +0 -0
  10. data/lib/glade/icons/gdict.png +0 -0
  11. data/lib/glade/icons/members_klein.png +0 -0
  12. data/lib/glade/icons/members_xklein.png +0 -0
  13. data/lib/glade/icons/no.xpm +34 -0
  14. data/lib/glade/icons/stock_book.svg +338 -0
  15. data/lib/glade/icons/stock_book_klein.png +0 -0
  16. data/lib/glade/icons/stock_book_xklein.png +0 -0
  17. data/lib/glade/icons/stock_bookmark.svg +327 -0
  18. data/lib/glade/icons/stock_bookmark_klein.png +0 -0
  19. data/lib/glade/icons/stock_bookmark_xklein.png +0 -0
  20. data/lib/glade/icons/stock_print.png +0 -0
  21. data/lib/glade/interne.glade +228 -0
  22. data/lib/glade/loginwindow.glade +255 -0
  23. data/lib/glade/memberinfo.svg +411 -0
  24. data/lib/glade/memberinfo_klein.png +0 -0
  25. data/lib/glade/memberinfo_xklein.png +0 -0
  26. data/lib/glade/members.glade +596 -0
  27. data/lib/glade/members.svg +559 -0
  28. data/lib/glade/members_klein.png +0 -0
  29. data/lib/glade/members_xklein.png +0 -0
  30. data/lib/glade/penningtool.glade +731 -0
  31. data/lib/glade/people.glade +947 -0
  32. data/lib/glade/printen.glade +358 -0
  33. data/lib/glade/printer.png +0 -0
  34. data/lib/glade/printer_klein.png +0 -0
  35. data/lib/glade/printer_xklein.png +0 -0
  36. data/lib/glade/printerlog_klein.png +0 -0
  37. data/lib/glade/printerlog_xklein.png +0 -0
  38. data/lib/glade/printing.glade +841 -0
  39. data/lib/glade/products.glade +404 -0
  40. data/lib/glade/sales.glade +426 -0
  41. data/lib/glade/stock_book.svg +338 -0
  42. data/lib/glade/stock_book_klein.png +0 -0
  43. data/lib/glade/stock_book_xklein.png +0 -0
  44. data/lib/glade/stock_bookmark_klein.png +0 -0
  45. data/lib/glade/stock_bookmark_xklein.png +0 -0
  46. data/lib/glade/vendingmachine.glade +207 -0
  47. data/lib/lib/errors.rb +90 -0
  48. data/lib/lib/util.rb +89 -0
  49. data/lib/ui/automaatwindow.rb +107 -0
  50. data/lib/ui/bibliotheekwindow.rb +453 -0
  51. data/lib/ui/bibwindow.rb +537 -0
  52. data/lib/ui/gladehelper.rb +110 -0
  53. data/lib/ui/internewindow.rb +126 -0
  54. data/lib/ui/loginwindow.rb +60 -0
  55. data/lib/ui/memberswindow.rb +327 -0
  56. data/lib/ui/messagebox.rb +23 -0
  57. data/lib/ui/peoplewindow.rb +333 -0
  58. data/lib/ui/printenwindow.rb +329 -0
  59. data/lib/ui/printingwindow.rb +395 -0
  60. data/lib/ui/productswindow.rb +160 -0
  61. data/lib/ui/saleswindow.rb +207 -0
  62. data/lib/ui/toolwindow.rb +97 -0
  63. metadata +128 -0
@@ -0,0 +1,126 @@
1
+ module Ig3tool
2
+
3
+ class InterneWindow < GladeHelper
4
+
5
+ ## - Constants ----
6
+ MENU_PATH = ["Interne", "Interne"]
7
+ ICON = "emblem-money.png"
8
+
9
+
10
+ def initialize
11
+ super("interne.glade")
12
+
13
+ @debugger1 = @glade.get_widget("debugger1")
14
+ @debugger2 = @glade.get_widget("debugger2")
15
+ @saldo = @glade.get_widget("saldo")
16
+ @amount = @glade.get_widget("amount")
17
+ @list = @glade.get_widget("list")
18
+
19
+ r = Gtk::CellRendererText.new
20
+ #@list.model = Gtk::ListStore.new(String, String, Float, String)
21
+ #%w(Van Naar Aantal Mededeling).each_with_index do |str, i|
22
+ # @list.insert_column(-1, str, r, :text => i)
23
+ #end
24
+
25
+ # TIJDELIJK: Het is beter dat de debugger meer info kan zien -> Lezen uit log ipv interne_transaction
26
+ # XXX TODO IN SERVER -> changen naar interne transacties als deze dan overal ingevuld worden!
27
+ @list.model = Gtk::ListStore.new(String, String, String, String)
28
+ %w(Systeem Subsysteem Tijd Mededeling).each_with_index do |str, i|
29
+ @list.insert_column(-1, str, r, :text => i)
30
+ end
31
+
32
+ make_debugger_combo @debugger1
33
+ make_debugger_combo @debugger2
34
+
35
+ @window.show_all
36
+ end
37
+
38
+ def make_debugger_combo(combo) # kas is ook een "debugger"
39
+ super(combo)
40
+ r = combo.model.prepend
41
+ r[0] = nil
42
+ r[1] = "kas"
43
+ combo.active = 0
44
+ end
45
+
46
+ def left_clicked
47
+ amount = @amount.text.to_c
48
+ _transfer(@debugger1, @debugger2, -amount)
49
+ end
50
+
51
+ def right_clicked
52
+ amount = @amount.text.to_c
53
+ _transfer(@debugger1, @debugger2, amount)
54
+ end
55
+
56
+ def debugger1_changed
57
+ username = _get_username(@debugger1)
58
+ return if username.nil?
59
+
60
+ if username != "kas"
61
+ saldo = $global["client"].interne(username)
62
+ @saldo.text = saldo.from_c.to_s
63
+ else
64
+ @saldo.text = ""
65
+ end
66
+
67
+ m = _get_widget("list").model
68
+ m.clear
69
+
70
+ _get_widget("list").model = nil
71
+
72
+ username = nil if username == "kas"
73
+
74
+ transactions = $global["client"].interne_log(username)
75
+ transactions.each do |t|
76
+ r = m.append
77
+ r[0] = t.system
78
+ r[1] = t.subsystem
79
+ time = Time.at(t.timestamp.to_i)
80
+ r[2] = time.asctime
81
+ r[3] = t.message
82
+ end
83
+
84
+ _get_widget("list").model = m
85
+ end
86
+
87
+ def eval_amount
88
+ t = @amount.text.strip
89
+ t.gsub!(/[^\d+\/*().-]/, "")
90
+ if t =~ /[+\/*()-]/
91
+ t = begin eval(t).to_s rescue "0" end
92
+ else
93
+ t = t.to_f.to_s
94
+ end
95
+ @amount.text = t
96
+ 0
97
+ end
98
+
99
+ private
100
+ def _transfer(from_widget, to_widget, amount)
101
+ from = _get_username(from_widget)
102
+ to = _get_username(to_widget)
103
+ return if from.nil? or to.nil? or from == to or amount == 0
104
+
105
+ args = {
106
+ :from => from,
107
+ :to => to,
108
+ :amount => amount
109
+ }
110
+
111
+ new_saldo = $global["client"].interne_transfer! args
112
+ @saldo.text = $global["client"].interne(from).from_c.to_s
113
+
114
+ # Fake Debugger1 changed -> updaten log kaderke
115
+ debugger1_changed
116
+ end
117
+
118
+ def _get_username(widget)
119
+ return nil if widget.active == -1
120
+ return widget.active_iter[1]
121
+ end
122
+ end
123
+
124
+ register_window(InterneWindow)
125
+
126
+ end
@@ -0,0 +1,60 @@
1
+ module Ig3tool
2
+ class LoginWindow < GladeHelper
3
+ include GetText
4
+
5
+ MENU_PATH = ["Login", "Login"]
6
+ ICON = "stock_print.png"
7
+
8
+ attr :glade
9
+
10
+ def initialize(client, &block)
11
+ super("loginwindow.glade", "loginwindow")
12
+
13
+ @c = client
14
+
15
+ @username = @glade.get_widget("username")
16
+ @password = @glade.get_widget("password")
17
+ @apply = @glade.get_widget("apply")
18
+ @loginwin = @glade.get_widget("loginwindow")
19
+ @success = block
20
+
21
+ end
22
+
23
+ def password_activate(widget)
24
+ @apply.activate
25
+ end
26
+ def apply(widget)
27
+ h = {"username" => @username.text, "password" => @password.text}
28
+ @username.text = ""
29
+ @password.text = ""
30
+ @c.wannabe!(h)
31
+ @loginwin.hide
32
+ @success.call
33
+ rescue Token => t
34
+ puts "ERROR: #{t.message}"
35
+ error_dialog(self, t)
36
+ end
37
+ def cancel(widget)
38
+ @username.text = ""
39
+ @password.text = ""
40
+ @loginwin.hide
41
+ Gtk.main_quit
42
+ return nil
43
+ end
44
+ def destroy_event(widget, arg0)
45
+ @username.text = ""
46
+ @password.text = ""
47
+ @loginwin.hide
48
+ end
49
+ def delete_event(widget, arg0)
50
+ @username.text = ""
51
+ @password.text = ""
52
+ @loginwin.hide
53
+ end
54
+ def username_activate(widget)
55
+ @password.grab_focus
56
+ end
57
+ end
58
+
59
+ end
60
+
@@ -0,0 +1,327 @@
1
+ module Ig3tool
2
+
3
+ class MembersWindow < GladeHelper
4
+ MENU_PATH = ["Leden"]
5
+ ICON = "members_xklein.png"
6
+ FIELDS = %w(first_name last_name email username rolnr address phone)
7
+
8
+ def initialize
9
+ super("members.glade")
10
+
11
+ @people_view = _get_widget("people_view")
12
+ @people_view.model = @people_store = Gtk::ListStore.new(Object, String)
13
+ r = Gtk::CellRendererText.new
14
+ @people_view.insert_column(-1, "Naam", r, :text => 1)
15
+
16
+ past_view = _get_widget("past_view")
17
+ past_view.model = Gtk::ListStore.new(String, String, String)
18
+ past_view.insert_column(-1, "Jaar", r, :text => 0)
19
+ past_view.insert_column(-1, "Status", r, :text => 1)
20
+ past_view.insert_column(-1, "Lidnummer", r, :text => 2)
21
+ past_view.columns.last.expand = true
22
+
23
+ sg = Gtk::SizeGroup.new(Gtk::SizeGroup::BOTH)
24
+
25
+ @glade.widget_names.grep(/^slabel/).each do |n|
26
+ sg.add_widget(_get_widget(n))
27
+ end
28
+
29
+ @notification_label = _get_widget("notification_label")
30
+
31
+ _get_widget("first_name").grab_focus
32
+ statussen = $global["client"].person_statussen
33
+ make_status_combo(_get_widget("status"), statussen)
34
+
35
+ Thread.new do
36
+ _get_widget("query").active = 0 # triggers query_changed
37
+ _get_widget("status").active = 0 # triggers status_changed
38
+ end
39
+
40
+ _create_people_rightclick_menu # Instantieer een rightclick menu
41
+
42
+ @window.show
43
+ end
44
+
45
+ ## - Handlers (GUI) ----
46
+ # Rechtermuisknop op een persoon in de lijst
47
+ def people_button_press_event (widget, event)
48
+ if event.kind_of? Gdk::EventButton and event.button == 3
49
+ @people_view_menu.popup(nil, nil, event.button, event.time)
50
+ end
51
+ end
52
+
53
+ # Bij dubbel klik op een naam in de lijst
54
+ def people_view_row_activated (widget, path, column)
55
+ iter = widget.model.get_iter(path)
56
+ _show iter[0]
57
+ end
58
+
59
+ def new_clicked
60
+ _clear
61
+ end
62
+
63
+ def ok_clicked
64
+ _save
65
+ end
66
+
67
+ def delete_clicked
68
+ _delete(@selected_person)
69
+ end
70
+
71
+ def query_changed
72
+ _update_people
73
+ end
74
+
75
+ def entry_activate
76
+ lookup_clicked
77
+ end
78
+
79
+ def focus_changed
80
+ @notification_label.text = ""
81
+ false
82
+ end
83
+
84
+ def lookup_clicked
85
+ attrs = {}
86
+
87
+ FIELDS.each do |k|
88
+ v = _get_widget(k).text.strip
89
+ attrs[k] = v unless v.nil? or v.empty?
90
+ end
91
+
92
+ begin
93
+ people = $global["client"].person_lookup(attrs)
94
+ _set_people(people)
95
+ rescue Exception => e
96
+ _print_msg "Error: Lookup: #{$!}"
97
+ end
98
+ end
99
+
100
+ def status_changed (status)
101
+ sensitive = status.active > 0
102
+ _get_widget("slabel_memberid").sensitive = sensitive
103
+ _get_widget("memberid").sensitive = sensitive
104
+ end
105
+
106
+ def image_button_release_event
107
+ dialog = Gtk::FileChooserDialog.new("Open File", nil, Gtk::FileChooser::ACTION_OPEN, nil, [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],[Gtk::Stock::OPEN, Gtk::Dialog::RESPONSE_ACCEPT])
108
+ if dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
109
+ filename = dialog.filename
110
+ _get_widget("image").set = filename
111
+ # Upload filename naar server?
112
+ # Blob?
113
+ # lokaal saven in /usr/share?
114
+ # TODO!
115
+ end
116
+ dialog.destroy
117
+ end
118
+
119
+ # Private
120
+ private
121
+ def _create_people_rightclick_menu
122
+ # Creeer een menu
123
+ @people_view_menu = Gtk::Menu.new
124
+ people_view_menu_edit_item = Gtk::MenuItem.new("Edit")
125
+ people_view_menu_delete_item = Gtk::MenuItem.new("Delete")
126
+ people_view_menu_edit_item.signal_connect("activate") {
127
+ # Show selected Persoon
128
+ # Treeview heeft default Mode Gtk::SELECTION_SINGLE
129
+ @people_view.selection.selected_each { |model, path, iter| _show(iter[0]) }
130
+ }
131
+
132
+ # Delete de geselecteerde persoon
133
+ people_view_menu_delete_item.signal_connect("activate") {
134
+ @people_view.selection.selected_each { |model, path, iter|
135
+ _delete(iter[0],false)
136
+ model.remove(iter) # Verwijder uit de lijst
137
+ }
138
+ }
139
+
140
+ @people_view_menu.append(people_view_menu_edit_item)
141
+ @people_view_menu.append(people_view_menu_delete_item)
142
+ @people_view_menu.show_all
143
+ end
144
+
145
+ def _show (who)
146
+ @selected_person = who
147
+
148
+ begin
149
+ FIELDS.each {|n| _get_widget(n).text = who.send(n.to_sym).to_s }
150
+
151
+ ms = $global["client"].person_memberships(who.username)
152
+
153
+
154
+ if !ms.nil?
155
+ ms.sort! {|a, b| b.year <=> a.year }
156
+ if !ms.empty? and ms[0].year.to_i == Time.werkjaar
157
+ _get_widget("status").active = statussen.index(ms[0].status)
158
+ _get_widget("memberid").text = ms[0].barcode
159
+ ms.shift
160
+ else
161
+ _get_widget("status").active = 0
162
+ _get_widget("memberid").text = ""
163
+ end
164
+
165
+ end
166
+
167
+ model = _get_widget("past_view").model
168
+ model.clear
169
+
170
+ ms.each do |m|
171
+ row = model.append
172
+ row[0] = m.year.to_s
173
+ row[1] = m.status.to_s
174
+ row[2] = m.barcode.to_s
175
+ end
176
+ rescue Exception => e
177
+ _print_msg "Fout: Memberinfo: #{$!}"
178
+ _clear
179
+ end
180
+
181
+ end
182
+
183
+ def _delete(who, refresh = true)
184
+ begin
185
+ $global["client"].person_remove!({ :username => who.username })
186
+ _clear
187
+ _update_people if refresh
188
+ rescue Exception => e
189
+ _print_msg "Error: Delete: #{$!}"
190
+ else
191
+ _print_msg "Person deleted!"
192
+ end
193
+ end
194
+
195
+ def _clear
196
+ @selected_person = nil
197
+ (FIELDS + %w(memberid)).each {|n| _get_widget(n).text = "" }
198
+ _get_widget("status").active = 0
199
+ _get_widget("past_view").model.clear
200
+ _get_widget("first_name").grab_focus
201
+ end
202
+
203
+
204
+ def _save
205
+ data = {
206
+ :last_name => _get_widget("last_name").text,
207
+ :first_name => _get_widget("first_name").text,
208
+ :rolnr => _get_widget("rolnr").text,
209
+ :username => _get_widget("username").text,
210
+ :email => _get_widget("email").text,
211
+ :address => _get_widget("address").text,
212
+ :phone => _get_widget("phone").text,
213
+ :gsm => _get_widget("gsm").text,
214
+ :status => _get_widget("status").active_iter[1],
215
+ :memberid => _get_widget("memberid").text
216
+ }
217
+ if @selected_person.nil? or @selected_person.username != data[:username]
218
+ # Indien hij nog niet bestaat, aanmaken in de database
219
+ begin
220
+ answer = $global["client"].person_add! data
221
+ @selected_person = $global["client"].person_lookup("username" => data[:username])[0]
222
+ iter = _insert_person(@selected_person)
223
+ @people_view.selection.select_iter(iter)
224
+ rescue Exception => e
225
+ _print_msg "Fout: Toevoegen: #{$!}"
226
+ else
227
+ _print_msg "Persoon toegevoegd", answer
228
+ end
229
+
230
+ else
231
+ # Anders-> zorg voor update via people.real_id
232
+ begin
233
+ answer = $global["client"].person_update! data
234
+ @selected_person = $global["client"].person_lookup("username" => data[:username])[0]
235
+ iter = _insert_person(@selected_person)
236
+ @people_view.selection.select_iter(iter)
237
+ rescue Exception => e
238
+ _print_msg "Fout: Aanpassen: #{$!}"
239
+ else
240
+ _print_msg "Persoonsinformatie aangepast", answer
241
+ end
242
+ end
243
+ end
244
+
245
+ def _update_people(clear = true)
246
+ case _get_widget("query").active
247
+ when 1; sym = :person_debuggers
248
+ when 2; sym = :person_honorarymembers
249
+ when 3; sym = :person_members
250
+ when 4; sym = :person_nonmembers
251
+ else sym = :person_everybody
252
+ end
253
+
254
+ if clear
255
+ @people_store.clear
256
+ r = @people_store.append
257
+ r[0] = nil
258
+ r[1] = "Loading..."
259
+ end
260
+ people = $global["client"].send(sym)
261
+ _set_people(people)
262
+ end
263
+
264
+ def _set_people(people, clear = true)
265
+ people.sort! do |a,b|
266
+ x = a.last_name <=> b.last_name
267
+ x == 0 ? a.first_name <=> b.first_name : x
268
+ end
269
+
270
+ @people_view.model = nil
271
+ @people_store.clear if clear
272
+
273
+ people.each do |p|
274
+ row = @people_store.append
275
+ row[0] = p
276
+ row[1] = p.last_name + " " + p.first_name
277
+ end
278
+
279
+ @people_view.model = @people_store
280
+ end
281
+
282
+ def _print_msg (msg, extra_info = nil)
283
+ puts msg
284
+ puts " - #{extra_info}" if extra_info
285
+ @notification_label.text = msg
286
+ end
287
+
288
+ def _insert_person(person)
289
+ iter = @people_store.iter_first
290
+ while iter[0].last_name <= person.last_name and iter.next!
291
+ break if iter[0].username == person.username
292
+ 1
293
+ end
294
+
295
+ p person
296
+ if iter[0].username == person.username
297
+ new = iter
298
+ new[0] = person
299
+ new[1] = "#{person.last_name} #{person.first_name}"
300
+ @people_store.row_changed(new.path, new)
301
+ puts "replaced #{new[1]}, (#{new.path})"
302
+ else
303
+ new = @people_store.insert_before(iter)
304
+ new[0] = person
305
+ new[1] = "#{person.last_name} #{person.first_name}"
306
+ @people_store.row_changed(new.path, new)
307
+ puts "inserted #{new[1]} before #{iter[1]}, (#{new.path})"
308
+ end
309
+
310
+ new
311
+ end
312
+
313
+ def _delete_person(person)
314
+ iter = @people_store.iter_first
315
+ while iter[0].last_name <= person.last_name and iter.next!
316
+ if iter[0].username == person.username
317
+ @people_store.remove(iter)
318
+ break
319
+ end
320
+ end
321
+ end
322
+
323
+ end
324
+
325
+ register_window(MembersWindow)
326
+
327
+ end
@@ -0,0 +1,23 @@
1
+ module Ig3tool
2
+
3
+ module_function
4
+
5
+ def messagebox(title,message)
6
+
7
+ overwrite = false
8
+ dialog = Gtk::MessageDialog.new(nil,
9
+ Gtk::Dialog::DESTROY_WITH_PARENT | Gtk::Dialog::MODAL,
10
+ Gtk::MessageDialog::QUESTION,
11
+ Gtk::MessageDialog::BUTTONS_YES_NO,
12
+ message)
13
+ dialog.title = title
14
+ dialog.run do |response|
15
+ case response
16
+ when Gtk::Dialog::RESPONSE_YES
17
+ overwrite = true
18
+ end
19
+ dialog.destroy
20
+ end
21
+ overwrite # Return overwrite? boolean -> true indien 'YES'
22
+ end
23
+ end