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,16 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::State::ShowPass -- bbmb.ch -- 18.10.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/html/state/global'
5
+ require 'bbmb/html/view/show_pass'
6
+
7
+ module BBMB
8
+ module Html
9
+ module State
10
+ class ShowPass < Global
11
+ VIEW = View::ShowPass
12
+ VOLATILE = true
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::State::Viral::Admin -- bbmb.ch -- 18.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/html/state/customer'
5
+ require 'bbmb/html/state/customers'
6
+ require 'bbmb/html/state/orders'
7
+ require 'bbmb/html/state/history'
8
+ require 'sbsm/viralstate'
9
+
10
+ module BBMB
11
+ module Html
12
+ module State
13
+ module Viral
14
+ module Admin
15
+ include SBSM::ViralState
16
+ EVENT_MAP = {
17
+ :customers => State::Customers,
18
+ :customer => State::Customer,
19
+ :history => State::History,
20
+ :orders => State::Orders,
21
+ }
22
+ def _customer(customer_id = @session.user_input(:customer_id))
23
+ Model::Customer.find_by_customer_id(customer_id)
24
+ end
25
+ def home
26
+ trigger(@session.user.home || :customers)
27
+ end
28
+ def order
29
+ if(order_id = @session.user_input(:order_id))
30
+ customer_id, commit_id = order_id.split('-', 2)
31
+ State::Order.new(@session, _customer(customer_id).order(commit_id))
32
+ end
33
+ end
34
+ def zone_navigation
35
+ [:customers]
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::State::Viral::Customer -- bbmb.ch -- 20.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/html/state/current_order'
5
+ require 'bbmb/html/state/favorites'
6
+ require 'bbmb/html/state/favorites_result'
7
+ require 'bbmb/html/state/order'
8
+ require 'bbmb/html/state/orders'
9
+ require 'bbmb/html/state/result'
10
+ require 'sbsm/viralstate'
11
+
12
+ module BBMB
13
+ module Html
14
+ module State
15
+ module Viral
16
+ module Customer
17
+ include SBSM::ViralState
18
+ EVENT_MAP = {
19
+ :current_order => State::CurrentOrder,
20
+ :favorites => State::Favorites,
21
+ :orders => State::Orders,
22
+ :search => State::Result,
23
+ :search_favorites => State::FavoritesResult,
24
+ }
25
+ def _customer
26
+ @customer ||= Model::Customer.find_by_email(@session.user.name)
27
+ end
28
+ def _increment_order(order)
29
+ quantities = user_input(:quantity)
30
+ if(error?)
31
+ false
32
+ else
33
+ quantities.each { |article_number, quantity|
34
+ if(prod = Model::Product.find_by_article_number(article_number))
35
+ order.increment(quantity.to_i, prod)
36
+ end
37
+ }
38
+ BBMB.persistence.save(order, _customer)
39
+ true
40
+ end
41
+ end
42
+ def _transfer(order)
43
+ if(io = user_input(:file_chooser))
44
+ BBMB::Util::TransferDat.parse(io) { |info|
45
+ if(product = Model::Product.find_by_pcode(info.pcode) \
46
+ || Model::Product.find_by_ean13(info.ean13))
47
+ order.increment(info.quantity, product)
48
+ else
49
+ order.unavailable.push(info)
50
+ end
51
+ }
52
+ end
53
+ self
54
+ end
55
+ def _update_order(order)
56
+ quantities = user_input(:quantity)
57
+ if(error?)
58
+ false
59
+ else
60
+ quantities.each { |article_number, quantity|
61
+ order.add(quantity.to_i,
62
+ Model::Product.find_by_article_number(article_number))
63
+ }
64
+ BBMB.persistence.save(order, _customer)
65
+ true
66
+ end
67
+ end
68
+ def clear_favorites
69
+ _customer.favorites.clear
70
+ self
71
+ end
72
+ def clear_order
73
+ _customer.current_order.clear
74
+ self
75
+ end
76
+ def delete_unavailable
77
+ if(@model.respond_to?(:unavailable) && (ids = user_input(:quantity)))
78
+ ids.each { |id, qty|
79
+ @model.unavailable.delete_at(id.to_i)
80
+ }
81
+ BBMB.persistence.save(@model)
82
+ end
83
+ self
84
+ end
85
+ def favorite_product
86
+ if(_update_order(_customer.favorites))
87
+ trigger(:favorites)
88
+ end
89
+ end
90
+ def favorite_transfer
91
+ _transfer(_customer.favorites)
92
+ end
93
+ def home
94
+ trigger(@session.user.home || :current_order)
95
+ end
96
+ def increment_order
97
+ if(_increment_order(_customer.current_order))
98
+ trigger(:current_order)
99
+ end
100
+ end
101
+ def order
102
+ if(order_id = @session.user_input(:order_id))
103
+ customer_id, commit_id = order_id.split('-', 2)
104
+ State::Order.new(@session, _customer.order(commit_id))
105
+ end
106
+ end
107
+ def order_product
108
+ if(_update_order(_customer.current_order))
109
+ trigger(:current_order)
110
+ end
111
+ end
112
+ def order_transfer
113
+ _transfer(_customer.current_order)
114
+ end
115
+ def scan
116
+ success = false
117
+ if(port = user_input(:comport))
118
+ @session.set_cookie_input(:comport, port)
119
+ end
120
+ if(@model.is_a?(Model::Order))
121
+ user_input(:EAN_13).each { |key, quantity|
122
+ success = true
123
+ if(product = Model::Product.find_by_ean13(key))
124
+ @model.increment(quantity.to_i, product)
125
+ else
126
+ info = Model::Order::Info.new
127
+ info.ean13 = key
128
+ info.quantity = quantity
129
+ @model.unavailable.push(info)
130
+ end
131
+ }
132
+ BBMB.persistence.save(@model)
133
+ end
134
+ State::Json.new(@session, {:success => success})
135
+ end
136
+ def zone_navigation
137
+ [ :current_order, :orders, :favorites ]
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::Util::KnownUser -- bbmb.ch -- 18.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/user'
5
+
6
+ module BBMB
7
+ module Html
8
+ module Util
9
+ class KnownUser < SBSM::User
10
+ ### Admin users need permissions for:
11
+ # login BBMB.config.auth_domain + ".Admin"
12
+ # edit yus.entities
13
+ # set_password
14
+ # grant login
15
+ #
16
+ ### Customers need permissions for:
17
+ # login BBMB.config.auth_domain + ".Customer"
18
+ attr_reader :auth_session
19
+ PREFERENCE_KEYS = [ :home, :pagestep ]
20
+ PREFERENCE_KEYS.each { |key|
21
+ define_method(key) {
22
+ remote_call(:get_preference, key)
23
+ }
24
+ }
25
+ def initialize(session)
26
+ @auth_session = session
27
+ end
28
+ def allowed?(action, key=nil)
29
+ allowed = remote_call(:allowed?, action, key)
30
+ BBMB.logger.debug('User') {
31
+ sprintf('%s: allowed?(%s, %s) -> %s', name, action, key, allowed)
32
+ }
33
+ allowed
34
+ end
35
+ def entity_valid?(email)
36
+ !!(allowed?('edit', 'yus.entities') \
37
+ && (entity = remote_call(:find_entity, email)) && entity.valid?)
38
+ end
39
+ def navigation
40
+ [ :logout ]
41
+ end
42
+ def remote_call(method, *args, &block)
43
+ @auth_session.send(method, *args, &block)
44
+ rescue RangeError, DRb::DRbError => e
45
+ BBMB.logger.error('auth') { e }
46
+ end
47
+ alias :method_missing :remote_call
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::Util::Multilingual -- bbmb -- 09.08.2007 -- hwyss@ywesee.com
3
+
4
+ module BBMB
5
+ module Html
6
+ module Util
7
+ module Multilingual
8
+ def _(value)
9
+ if(value.is_a?(BBMB::Util::Multilingual))
10
+ value.send(@session.language) || value.default
11
+ else
12
+ value
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::Util::Session -- bbmb.ch -- 15.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/config'
5
+ require 'bbmb/html/util/known_user'
6
+ require 'bbmb/html/state/login'
7
+ require 'sbsm/session'
8
+ require 'sbsm/redirector'
9
+
10
+ module BBMB
11
+ module Html
12
+ module Util
13
+ class Session < SBSM::Session
14
+ include SBSM::Redirector
15
+ DEFAULT_LANGUAGE = 'de'
16
+ DEFAULT_STATE = State::Login
17
+ EXPIRES = BBMB.config.session_timeout
18
+ PERSISTENT_COOKIE_NAME = "bbmb-barcodereader"
19
+ def login
20
+ @user = @app.login(user_input(:email), user_input(:pass))
21
+ @user.session = self if(@user.respond_to?(:session=))
22
+ @user
23
+ end
24
+ def logout
25
+ @app.logout(@user.auth_session) if(@user.respond_to?(:auth_session))
26
+ super
27
+ end
28
+ def lookandfeel
29
+ if(@lookandfeel.nil? \
30
+ || (@lookandfeel.language != persistent_user_input(:language)))
31
+ require 'bbmb/html/util/lookandfeel'
32
+ @lookandfeel = Lookandfeel.new(self) # dtsttcpw
33
+ end
34
+ @lookandfeel
35
+ end
36
+ def process(request)
37
+ begin
38
+ if(@user.is_a?(KnownUser) && @user.auth_session.expired?)
39
+ logout
40
+ end
41
+ rescue DRb::DRbError, RangeError, NoMethodError
42
+ logout
43
+ end
44
+ super
45
+ end
46
+ def validate(key, value)
47
+ @validator.validate(key, value)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::Util::Validator -- bbmb.ch -- 15.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'sbsm/validator'
5
+
6
+ module BBMB
7
+ module Html
8
+ module Util
9
+ class Validator < SBSM::Validator
10
+ BOOLEAN = [ :accept_terms, :order_confirmation ]
11
+ ENUMS = {
12
+ :canton => [
13
+ nil, "AG", "AI", "AR", "BE", "BL", "BS", "FR", "GE", "GL", "GR", "JU",
14
+ "LU", "NE", "NW", "OW", "SG", "SH", "SO", "SZ", "TG", "TI", "UR", "VD",
15
+ "VS", "ZG", "ZH" ],
16
+ :title => [nil, 'title_f', 'title_m']
17
+ }
18
+ EVENTS = [ :ajax, :change_pass, :clear_favorites, :clear_order, :commit,
19
+ :current_order, :customer, :customers, :delete_unavailable, :favorites,
20
+ :favorite_product, :favorite_transfer, :generate_pass, :history, :home,
21
+ :increment_order, :login, :logout, :order, :orders, :order_product,
22
+ :order_transfer, :request_access, :save, :scan, :show_pass, :search,
23
+ :search_favorites, :sort ]
24
+ FILES = [ :file_chooser ]
25
+ NUMERIC = [ :comport, :customer_id, :EAN_13, :index, :plz, :priority,
26
+ :quantity ]
27
+ STRINGS = [ :address1, :address2, :address3, :city, :comment,
28
+ :drtitle, :fax, :filter, :firstname, :lastname, :order_id,
29
+ :organisation, :phone_business, :phone_mobile, :phone_private,
30
+ :query, :reference, :sortvalue ]
31
+ def ean13(value)
32
+ return nil if(value.empty?)
33
+ match = /\d{13}/.match(value.to_s)
34
+ unless match
35
+ raise SBSM::InvalidDataError.new(:e_invalid_ean13, :ean13, value)
36
+ end
37
+ values = match[0].split("")
38
+ check = values.pop
39
+ sum = 0
40
+ values.each_with_index { |val, index|
41
+ modulus = ((index%2)*2)+1
42
+ sum += (modulus*val.to_i)
43
+ }
44
+ unless (check.to_i == (10-(sum%10))%10)
45
+ raise SBSM::InvalidDataError.new(:e_invalid_ean13, :ean13, value)
46
+ end
47
+ match[0]
48
+ end
49
+ def perform_validation(key, value)
50
+ super(key, u(value))
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::Backorder -- bbmb.ch -- 06.10.2006 -- hwyss@ywesee.com
3
+
4
+ module BBMB
5
+ module Html
6
+ module View
7
+ module Backorder
8
+ def backorder(model)
9
+ value = if(date = model.backorder_date)
10
+ date.strftime(@lookandfeel.lookup(:backorder_date))
11
+ elsif(model.backorder)
12
+ @lookandfeel.lookup(:backorder)
13
+ end
14
+ if(value)
15
+ div = HtmlGrid::Div.new(model, @session, self)
16
+ div.css_class = 'limited'
17
+ div.value = value
18
+ div
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # Html::View::ChangePassword -- virbac.bbmb.ch -- 28.06.2007 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/html/view/template'
5
+ require 'htmlgrid/errormessage'
6
+ require 'htmlgrid/form'
7
+
8
+ module BBMB
9
+ module Html
10
+ module View
11
+ class ChangePasswordForm < HtmlGrid::Form
12
+ include HtmlGrid::ErrorMessage
13
+ COMPONENTS = {
14
+ [0,0] => :email,
15
+ [0,1] => :pass,
16
+ [0,2] => :confirm_pass,
17
+ [1,3] => :submit,
18
+ }
19
+ EVENT = :save
20
+ LABELS = true
21
+ SYMBOL_MAP = {
22
+ :pass => HtmlGrid::Pass,
23
+ :confirm_pass => HtmlGrid::Pass,
24
+ }
25
+ def init
26
+ super
27
+ error_message
28
+ end
29
+ end
30
+ class ChangePasswordComposite < HtmlGrid::DivComposite
31
+ COMPONENTS = {
32
+ [0,0] => "change_pass",
33
+ [0,1] => ChangePasswordForm,
34
+ }
35
+ CSS_ID_MAP = ['title']
36
+ end
37
+ class ChangePassword < Template
38
+ CONTENT = ChangePasswordComposite
39
+ end
40
+ end
41
+ end
42
+ end