bbmb 2.0.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 (92) hide show
  1. data/History.txt +5 -0
  2. data/LICENSE.txt +339 -0
  3. data/Manifest.txt +91 -0
  4. data/README.txt +25 -0
  5. data/Rakefile +28 -0
  6. data/bin/admin +71 -0
  7. data/bin/bbmbd +61 -0
  8. data/lib/bbmb.rb +9 -0
  9. data/lib/bbmb/config.rb +106 -0
  10. data/lib/bbmb/html/state/change_password.rb +50 -0
  11. data/lib/bbmb/html/state/current_order.rb +81 -0
  12. data/lib/bbmb/html/state/customer.rb +109 -0
  13. data/lib/bbmb/html/state/customers.rb +52 -0
  14. data/lib/bbmb/html/state/favorites.rb +19 -0
  15. data/lib/bbmb/html/state/favorites_result.rb +21 -0
  16. data/lib/bbmb/html/state/global.rb +62 -0
  17. data/lib/bbmb/html/state/history.rb +95 -0
  18. data/lib/bbmb/html/state/info.rb +23 -0
  19. data/lib/bbmb/html/state/json.rb +16 -0
  20. data/lib/bbmb/html/state/login.rb +76 -0
  21. data/lib/bbmb/html/state/order.rb +21 -0
  22. data/lib/bbmb/html/state/orders.rb +19 -0
  23. data/lib/bbmb/html/state/result.rb +64 -0
  24. data/lib/bbmb/html/state/show_pass.rb +16 -0
  25. data/lib/bbmb/html/state/viral/admin.rb +41 -0
  26. data/lib/bbmb/html/state/viral/customer.rb +143 -0
  27. data/lib/bbmb/html/util/known_user.rb +51 -0
  28. data/lib/bbmb/html/util/multilingual.rb +18 -0
  29. data/lib/bbmb/html/util/session.rb +52 -0
  30. data/lib/bbmb/html/util/validator.rb +55 -0
  31. data/lib/bbmb/html/view/backorder.rb +24 -0
  32. data/lib/bbmb/html/view/change_password.rb +42 -0
  33. data/lib/bbmb/html/view/copyleft.rb +41 -0
  34. data/lib/bbmb/html/view/current_order.rb +482 -0
  35. data/lib/bbmb/html/view/customer.rb +152 -0
  36. data/lib/bbmb/html/view/customers.rb +145 -0
  37. data/lib/bbmb/html/view/favorites.rb +162 -0
  38. data/lib/bbmb/html/view/favorites_result.rb +26 -0
  39. data/lib/bbmb/html/view/foot.rb +21 -0
  40. data/lib/bbmb/html/view/head.rb +32 -0
  41. data/lib/bbmb/html/view/history.rb +60 -0
  42. data/lib/bbmb/html/view/info.rb +33 -0
  43. data/lib/bbmb/html/view/json.rb +20 -0
  44. data/lib/bbmb/html/view/list_prices.rb +51 -0
  45. data/lib/bbmb/html/view/login.rb +46 -0
  46. data/lib/bbmb/html/view/multilingual.rb +17 -0
  47. data/lib/bbmb/html/view/navigation.rb +30 -0
  48. data/lib/bbmb/html/view/order.rb +123 -0
  49. data/lib/bbmb/html/view/orders.rb +50 -0
  50. data/lib/bbmb/html/view/result.rb +107 -0
  51. data/lib/bbmb/html/view/search.rb +28 -0
  52. data/lib/bbmb/html/view/show_pass.rb +60 -0
  53. data/lib/bbmb/html/view/template.rb +61 -0
  54. data/lib/bbmb/model/customer.rb +96 -0
  55. data/lib/bbmb/model/order.rb +255 -0
  56. data/lib/bbmb/model/product.rb +99 -0
  57. data/lib/bbmb/model/promotion.rb +52 -0
  58. data/lib/bbmb/model/quota.rb +27 -0
  59. data/lib/bbmb/model/subject.rb +46 -0
  60. data/lib/bbmb/persistence/none.rb +6 -0
  61. data/lib/bbmb/persistence/odba.rb +42 -0
  62. data/lib/bbmb/persistence/odba/model/customer.rb +47 -0
  63. data/lib/bbmb/persistence/odba/model/order.rb +50 -0
  64. data/lib/bbmb/persistence/odba/model/product.rb +26 -0
  65. data/lib/bbmb/persistence/odba/model/quota.rb +12 -0
  66. data/lib/bbmb/util/invoicer.rb +126 -0
  67. data/lib/bbmb/util/mail.rb +140 -0
  68. data/lib/bbmb/util/multilingual.rb +57 -0
  69. data/lib/bbmb/util/numbers.rb +67 -0
  70. data/lib/bbmb/util/password_generator.rb +44 -0
  71. data/lib/bbmb/util/polling_manager.rb +135 -0
  72. data/lib/bbmb/util/server.rb +159 -0
  73. data/lib/bbmb/util/target_dir.rb +36 -0
  74. data/lib/bbmb/util/transfer_dat.rb +34 -0
  75. data/lib/bbmb/util/updater.rb +27 -0
  76. data/test/data/ydim.yml +2 -0
  77. data/test/model/test_customer.rb +75 -0
  78. data/test/model/test_order.rb +426 -0
  79. data/test/model/test_product.rb +238 -0
  80. data/test/model/test_promotion.rb +40 -0
  81. data/test/stub/persistence.rb +57 -0
  82. data/test/suite.rb +12 -0
  83. data/test/test_bbmb.rb +18 -0
  84. data/test/util/test_invoicer.rb +189 -0
  85. data/test/util/test_mail.rb +359 -0
  86. data/test/util/test_money.rb +71 -0
  87. data/test/util/test_password_generator.rb +27 -0
  88. data/test/util/test_polling_manager.rb +312 -0
  89. data/test/util/test_server.rb +189 -0
  90. data/test/util/test_target_dir.rb +82 -0
  91. data/test/util/test_transfer_dat.rb +45 -0
  92. metadata +190 -0
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Customer -- bbmb.ch -- 19.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/html/view/template'
5
+ require 'htmlgrid/errormessage'
6
+ require 'htmlgrid/form'
7
+ require 'htmlgrid/inputcheckbox'
8
+ require 'htmlgrid/popuplink'
9
+ require 'htmlgrid/select'
10
+
11
+ module BBMB
12
+ module Html
13
+ module View
14
+ class CustomerForm < HtmlGrid::Form
15
+ include HtmlGrid::ErrorMessage
16
+ COMPONENTS = {
17
+ [0,0] => :organisation,
18
+ [2,0] => :customer_id,
19
+ [0,1] => :ean13,
20
+ [2,1,0] => :turnover,
21
+ [3,1,0] => ' - ',
22
+ [3,1,1] => :history,
23
+ [0,2] => 'contact',
24
+ [0,3] => :title,
25
+ [2,3] => :drtitle,
26
+ [0,4] => :lastname,
27
+ [2,4] => :firstname,
28
+ [0,5] => :address1,
29
+ [0,6] => :address2,
30
+ [0,7] => :address3,
31
+ [0,8,0] => :plz,
32
+ [0,8,1] => '/',
33
+ [0,8,2] => :city,
34
+ [2,8] => :canton,
35
+ [0,9] => :email,
36
+ [2,9] => :order_confirmation,
37
+ [0,10] => :phone_business,
38
+ [2,10] => :phone_private,
39
+ [0,11] => :phone_mobile,
40
+ [2,11] => :fax,
41
+ [0,12] => :pass,
42
+ [1,12,3]=> :change_pass, # in UserView#change_pass, the third
43
+ # number here is used as the value of
44
+ # the colspan attribute
45
+ [1,12,4]=> '&nbsp;',
46
+ [1,12,5]=> :generate_pass,
47
+ [2,12] => :confirm_pass,
48
+ [1,13] => :submit,
49
+ }
50
+ CSS_ID_MAP = {
51
+ [0,8,0] => 'plz',
52
+ [0,8,2] => 'city',
53
+ }
54
+ CSS_MAP = {
55
+ [0,2,4] => 'contact',
56
+ }
57
+ DEFAULT_CLASS = HtmlGrid::InputText
58
+ EVENT = "save"
59
+ FORM_NAME = 'hospital'
60
+ LABELS = true
61
+ SYMBOL_MAP = {
62
+ :canton => HtmlGrid::Select,
63
+ :title => HtmlGrid::Select,
64
+ }
65
+ def init
66
+ super
67
+ error_message
68
+ end
69
+ def change_pass(model)
70
+ unless(set_pass?)
71
+ button = HtmlGrid::Button.new(:change_pass, model, @session, self)
72
+ form = "document.#{formname}"
73
+ button.onclick = "#{form}.event.value='change_pass';#{form}.submit();"
74
+ button.value = @lookandfeel.lookup("change_pass")
75
+ matrix = components.index(:change_pass)
76
+ @grid.set_colspan(*matrix)
77
+ button
78
+ end
79
+ end
80
+ def confirm_pass(model)
81
+ _pass(:confirm_pass, model)
82
+ end
83
+ def generate_pass(model)
84
+ unless(set_pass?)
85
+ if(@session.state.cleartext)
86
+ link = HtmlGrid::Link.new(:show_pass, model, @session, self)
87
+ link.href = 'javascript:' << popup(@lookandfeel._event_url(:show_pass),
88
+ 'password')
89
+ link
90
+ else
91
+ button = HtmlGrid::Button.new(:generate_pass, model, @session, self)
92
+ form = "document.#{formname}"
93
+ button.onclick = "#{form}.event.value='generate_pass';#{form}.submit();"
94
+ matrix = components.index(:change_pass)
95
+ @grid.set_colspan(*matrix)
96
+ button
97
+ end
98
+ end
99
+ end
100
+ def history(model)
101
+ link = HtmlGrid::Link.new(:history, model, @session, self)
102
+ link.href = @lookandfeel._event_url(:history,
103
+ :customer_id => model.customer_id)
104
+ link
105
+ end
106
+ def order_confirmation(model)
107
+ if BBMB.config.mail_confirm_reply_to
108
+ HtmlGrid::InputCheckbox.new(:order_confirmation,
109
+ model, @session, self)
110
+ end
111
+ end
112
+ def pass(model)
113
+ _pass(:pass, model)
114
+ end
115
+ def _pass(key, model)
116
+ if(set_pass?)
117
+ HtmlGrid::Pass.new(key, model, @session, self)
118
+ end
119
+ end
120
+ def popup(url, name='popup')
121
+ script = "window.open('#{url}','#{name}','resizable=yes,menubar=no,height=350,width=500').focus();"
122
+ if(self.respond_to?(:onload=))
123
+ self.onload = script
124
+ end
125
+ script
126
+ end
127
+ def set_pass?
128
+ @session.event == :change_pass \
129
+ || @session.error(:pass) || @session.error(:confirm_pass)
130
+ end
131
+ def turnover(model)
132
+ link = HtmlGrid::Link.new(:turnover, model, @session, self)
133
+ args = { :customer_id => model.customer_id }
134
+ link.href = @lookandfeel._event_url(:orders, args)
135
+ link.value = sprintf(@lookandfeel.lookup(:currency_format), model.turnover)
136
+ link.label = true
137
+ link
138
+ end
139
+ end
140
+ class CustomerComposite < HtmlGrid::DivComposite
141
+ COMPONENTS = {
142
+ [0,0] => '&nbsp;',
143
+ [0,1] => CustomerForm,
144
+ }
145
+ CSS_ID_MAP = [ 'divider' ]
146
+ end
147
+ class Customer < Template
148
+ CONTENT = CustomerComposite
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Customers -- bbmb.ch -- 18.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/html/view/template'
5
+ require 'htmlgrid/button'
6
+ require 'htmlgrid/divform'
7
+ require 'htmlgrid/list'
8
+ require 'htmlgrid/urllink'
9
+
10
+ module BBMB
11
+ module Html
12
+ module View
13
+ class Filter < HtmlGrid::DivForm
14
+ COMPONENTS = {
15
+ [0,0] => :filter,
16
+ [1,0] => :filter_button,
17
+ [2,0] => :filter_reset,
18
+ }
19
+ FORM_NAME = 'filter'
20
+ def event
21
+ @session.state.direct_event
22
+ end
23
+ def filter(model)
24
+ filter = HtmlGrid::InputText.new(:filter, model, @session, self)
25
+ filter.value = @session.event_bound_user_input(:filter)
26
+ filter
27
+ end
28
+ def filter_button(model)
29
+ button = HtmlGrid::Button.new(:filter_button, model, @session, self)
30
+ url = @lookandfeel._event_url(event, :filter => nil)
31
+ script = "document.location.href='#{url}' + encodeURIComponent(document.#{formname}.filter.value); return false;"
32
+ self.onsubmit = button.onclick = script
33
+ #button.set_attribute('value', @lookandfeel.lookup(:filter))
34
+ button
35
+ end
36
+ def filter_reset(model)
37
+ button = HtmlGrid::Button.new(:reset, model, @session, self)
38
+ url = @lookandfeel._event_url(event, :filter => "*")
39
+ button.onclick = "document.location.href='#{url}'"
40
+ button
41
+ end
42
+ end
43
+ class CustomersList < HtmlGrid::List
44
+ BACKGROUND_ROW = 'bg'
45
+ BACKGROUND_SUFFIX = ''
46
+ COMPONENTS = {
47
+ [0,0] => :customer_id,
48
+ [1,0] => :organisation,
49
+ [2,0] => :plz,
50
+ [3,0] => :city,
51
+ [4,0] => :email,
52
+ [5,0] => :communication,
53
+ [6,0] => :valid,
54
+ [7,0] => :last_login,
55
+ }
56
+ CSS_CLASS = 'list'
57
+ CSS_MAP = {
58
+ [1,0] => 'big',
59
+ }
60
+ SORT_DEFAULT = nil
61
+ SYMBOL_MAP = {
62
+ :email => HtmlGrid::MailLink,
63
+ }
64
+ def customer_id(model)
65
+ link = HtmlGrid::Link.new(:customer_id, model, @session, self)
66
+ link.value = model.customer_id
67
+ link.href = @lookandfeel._event_url(:customer,
68
+ {:customer_id => model.customer_id})
69
+ link
70
+ end
71
+ def organisation(model)
72
+ link = HtmlGrid::Link.new(:organisation, model, @session, self)
73
+ link.value = model.organisation
74
+ link.href = @lookandfeel._event_url(:customer,
75
+ {:customer_id => model.customer_id})
76
+ link
77
+ end
78
+ =begin
79
+ def email(model)
80
+ if(mail = model.email)
81
+ link = HtmlGrid::Link.new(:email, model, @session, self)
82
+ link.value = mail
83
+ link.href = sprintf("mailto:%s", mail)
84
+ link
85
+ end
86
+ end
87
+ def email(model)
88
+ EmailValue.new(model, @session, self)
89
+ end
90
+ def last_login(model)
91
+ DateTimeView.new(:last_login, model, @session, self)
92
+ end
93
+ def active(model)
94
+ model.value(:active)
95
+ end
96
+ =end
97
+ def last_login(model)
98
+ @session.user.last_login(model.email)
99
+ end
100
+ def valid(model)
101
+ @lookandfeel.lookup(@session.user.entity_valid?(model.email).to_s)
102
+ end
103
+ private
104
+ def sort_link(header_key, matrix, component)
105
+ link = HtmlGrid::Link.new(header_key, @model, @session, self)
106
+ args = {
107
+ :sortvalue => component.to_s,
108
+ }
109
+ link.attributes['href'] = @lookandfeel._event_url(:customers, args)
110
+ link
111
+ end
112
+ end
113
+ class CustomersComposite < HtmlGrid::DivComposite
114
+ COMPONENTS = {
115
+ [0,0] => Filter,
116
+ [0,1] => :pager,
117
+ [0,2] => :customers,
118
+ }
119
+ CSS_ID_MAP = ['filter', 'pager']
120
+ def customers(model)
121
+ CustomersList.new(model.customers, @session, self)
122
+ end
123
+ def pager(model)
124
+ pager = []
125
+ if(model.index > 0)
126
+ pager.push(_pager_link(:previous, model.index - model.step))
127
+ end
128
+ pager.push(@lookandfeel.lookup(:pager_index, model.first, model.last))
129
+ if(model.last < model.total)
130
+ pager.push(_pager_link(:next, model.index + model.step))
131
+ end
132
+ pager.push(@lookandfeel.lookup(:pager_total, model.total))
133
+ end
134
+ def _pager_link(key, index)
135
+ link = HtmlGrid::Link.new(key, @model, @session, self)
136
+ link.href = @lookandfeel._event_url(:customers, :index => index)
137
+ link
138
+ end
139
+ end
140
+ class Customers < Template
141
+ CONTENT = CustomersComposite
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Favorites -- bbmb.ch -- 28.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/html/view/current_order'
5
+ require 'htmlgrid/formlist'
6
+
7
+ module BBMB
8
+ module Html
9
+ module View
10
+ class ClearFavorites < ClearOrder
11
+ EVENT = :clear_favorites
12
+ end
13
+ class SearchFavorites < Search
14
+ EVENT = :search_favorites
15
+ end
16
+ class FavoritesPositions < Positions
17
+ include Backorder
18
+ include PositionMethods
19
+ CSS_ID = 'favorites'
20
+ if BBMB.config.enable_price_levels
21
+ COMPONENTS = {
22
+ [0,0] => :delete_position,
23
+ [1,0] => :quantity,
24
+ [2,0] => :description,
25
+ [3,0] => :backorder,
26
+ [4,0] => :price_base,
27
+ [5,0] => :price_levels,
28
+ [6,0] => :price2,
29
+ [7,0] => :price3,
30
+ [5,1] => :price4,
31
+ [6,1] => :price5,
32
+ [7,1] => :price6,
33
+ [8,0] => :total,
34
+ }
35
+ CSS_MAP = {
36
+ [0,0] => 'delete',
37
+ [1,0] => 'tiny right',
38
+ [2,0] => 'description',
39
+ [4,0,4,2] => 'right',
40
+ [8,0] => 'total',
41
+ }
42
+ CSS_HEAD_MAP = {
43
+ [1,0] => 'right',
44
+ [4,0] => 'right',
45
+ [5,0] => 'right',
46
+ [8,0] => 'right',
47
+ }
48
+ else
49
+ COMPONENTS = {
50
+ [0,0] => :delete_position,
51
+ [1,0] => :quantity,
52
+ [2,0] => :description,
53
+ [3,0] => :backorder,
54
+ [4,0] => :price_base,
55
+ [5,0] => :total,
56
+ }
57
+ CSS_MAP = {
58
+ [0,0] => 'delete',
59
+ [1,0] => 'tiny right',
60
+ [2,0] => 'description',
61
+ [4,0] => 'right',
62
+ [5,0] => 'total',
63
+ }
64
+ CSS_HEAD_MAP = {
65
+ [1,0] => 'right',
66
+ [4,0] => 'right',
67
+ [5,0] => 'right',
68
+ }
69
+ end
70
+ SORT_DEFAULT = :description
71
+ def delete_position(model)
72
+ super(model, :favorite_product)
73
+ end
74
+ def description(model)
75
+ position_modifier(model, :description, :search_favorites)
76
+ end
77
+ def quantity(model)
78
+ name = "quantity[#{model.article_number}]"
79
+ input = HtmlGrid::InputText.new(name, model, @session, self)
80
+ input.value = model.quantity
81
+ input.css_class = 'tiny'
82
+ script = "if(this.value == '0') this.value = '';"
83
+ input.set_attribute('onFocus', script)
84
+ script = "if(this.value == '') this.value = '0';"
85
+ input.set_attribute('onBlur', script)
86
+ input
87
+ end
88
+ end
89
+ class FavoritesForm < HtmlGrid::DivForm
90
+ include UnavailableMethods
91
+ COMPONENTS = {
92
+ [0,0] => FavoritesPositions,
93
+ [0,1] => :unavailables,
94
+ }
95
+ EVENT = :increment_order
96
+ FORM_NAME = 'favorites'
97
+ def init
98
+ unless(@model.empty?)
99
+ components.update( [1,1] => :submit, [2,1] => :nullify, [3,1] => :reset )
100
+ end
101
+ super
102
+ end
103
+ def nullify(model)
104
+ button = HtmlGrid::Button.new(:nullify, model, @session, self)
105
+ button.set_attribute('onClick', "zeroise(this.form);")
106
+ button
107
+ end
108
+ def reset(model)
109
+ input = HtmlGrid::Button.new(:default_values, model, @session, self)
110
+ input.set_attribute('type', 'reset')
111
+ input
112
+ end
113
+ end
114
+ class FavoritesComposite < OrderComposite
115
+ COMPONENTS = {
116
+ [0,0] => SearchFavorites,
117
+ [1,0] => :barcode_reader,
118
+ [2,0] => :position_count,
119
+ [3,0] => :favorite_transfer,
120
+ [4,0] => :clear_favorites,
121
+ [0,1] => FavoritesForm,
122
+ }
123
+ CSS_ID_MAP = [ 'toolbar' ]
124
+ def barcode_reader(model)
125
+ if(@session.client_activex? && !@lookandfeel.disabled?(:barcode_reader))
126
+ BarcodeReader.new(model, @session, self)
127
+ end
128
+ end
129
+ def clear_favorites(model)
130
+ unless(model.empty?)
131
+ ClearFavorites.new(model, @session, self)
132
+ end
133
+ end
134
+ def favorite_transfer(model)
135
+ unless(@lookandfeel.disabled?(:transfer_dat))
136
+ TransferDat.new(:favorite_transfer, model, @session, self)
137
+ end
138
+ end
139
+ def position_count(model)
140
+ span = HtmlGrid::Span.new(model, @session, self)
141
+ span.value = @lookandfeel.lookup(:favorite_positions, model.size)
142
+ span.css_class = 'guide'
143
+ span
144
+ end
145
+ end
146
+ class Favorites < CurrentOrder
147
+ include HtmlGrid::DojoToolkit::DojoTemplate
148
+ include ActiveX
149
+ CONTENT = FavoritesComposite
150
+ DOJO_DEBUG = BBMB.config.debug
151
+ DOJO_PREFIX = {
152
+ 'ywesee' => '../javascript',
153
+ }
154
+ JAVASCRIPTS = [
155
+ "bcreader",
156
+ "order",
157
+ ]
158
+
159
+ end
160
+ end
161
+ end
162
+ end