bbmb 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.travis.yml +26 -0
- data/Gemfile +11 -0
- data/Guide.txt +129 -0
- data/History.txt +9 -0
- data/Manifest.txt +2 -0
- data/Rakefile +16 -23
- data/bbmb.gemspec +45 -0
- data/bbmb.jpeg +0 -0
- data/bin/bbmbd +0 -1
- data/bin/migrate_to_utf_8 +244 -0
- data/lib/bbmb.rb +1 -1
- data/lib/bbmb/html/state/global.rb +0 -1
- data/lib/bbmb/html/view/json.rb +1 -1
- data/lib/bbmb/model/order.rb +5 -5
- data/lib/bbmb/persistence/odba.rb +2 -1
- data/lib/bbmb/persistence/odba/model/order.rb +0 -0
- data/lib/bbmb/util/invoicer.rb +6 -8
- data/lib/bbmb/util/mail.rb +2 -0
- data/lib/bbmb/util/smtp_tls.rb +70 -0
- data/lib/bbmb/util/transfer_dat.rb +3 -3
- data/lib/bbmb/version.rb +6 -0
- data/readme.md +30 -0
- data/test/model/test_customer.rb +5 -9
- data/test/model/test_order.rb +24 -34
- data/test/model/test_product.rb +5 -4
- data/test/model/test_promotion.rb +3 -2
- data/test/suite.rb +31 -6
- data/test/test_bbmb.rb +2 -2
- data/test/util/test_invoicer.rb +9 -5
- data/test/util/test_mail.rb +8 -5
- data/test/util/test_money.rb +6 -5
- data/test/util/test_password_generator.rb +3 -3
- data/test/util/test_polling_manager.rb +7 -7
- data/test/util/test_server.rb +13 -18
- data/test/util/test_target_dir.rb +4 -4
- data/test/util/test_transfer_dat.rb +13 -12
- metadata +353 -72
- data/README.txt +0 -25
data/lib/bbmb.rb
CHANGED
data/lib/bbmb/html/view/json.rb
CHANGED
data/lib/bbmb/model/order.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# Model::Order -- bbmb.ch -- 22.09.2006 -- hwyss@ywesee.com
|
3
3
|
|
4
|
-
require 'encoding/character/utf-8'
|
5
4
|
require 'bbmb/config'
|
6
5
|
require 'bbmb/util/numbers'
|
7
6
|
require 'csv'
|
@@ -214,9 +213,10 @@ class Order
|
|
214
213
|
end
|
215
214
|
def to_csv
|
216
215
|
result = ''
|
217
|
-
|
218
|
-
|
219
|
-
|
216
|
+
BBMB.config.target_format_fs ||= ','
|
217
|
+
BBMB.config.target_format_rs ||= "\n"
|
218
|
+
CSV.generate(result, { :col_sep => BBMB.config.target_format_fs,
|
219
|
+
:row_sep => BBMB.config.target_format_rs}) { |writer|
|
220
220
|
@positions.each { |position|
|
221
221
|
writer << [
|
222
222
|
@customer.customer_id,
|
@@ -248,7 +248,7 @@ class Order
|
|
248
248
|
end
|
249
249
|
private
|
250
250
|
def _formatted_comment(replacement=';')
|
251
|
-
|
251
|
+
@comment.to_s.gsub(/[\r\n]+/, replacement)[0,60] if @comment
|
252
252
|
end
|
253
253
|
end
|
254
254
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# Persistence::ODBA -- bbmb.ch -- 13.06.2013 -- yasaka@ywesee.com
|
2
3
|
# Persistence::ODBA -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
|
3
4
|
|
4
5
|
require 'bbmb/config'
|
@@ -35,7 +36,7 @@ module BBMB
|
|
35
36
|
end
|
36
37
|
end
|
37
38
|
end
|
38
|
-
ODBA.storage.dbi = ODBA::ConnectionPool.new("DBI:
|
39
|
+
ODBA.storage.dbi = ODBA::ConnectionPool.new("DBI:Pg:#{@config.db_name}",
|
39
40
|
@config.db_user, @config.db_auth)
|
40
41
|
ODBA.cache.setup
|
41
42
|
ODBA.cache.prefetch
|
File without changes
|
data/lib/bbmb/util/invoicer.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# Util::Invoicer -- bbmb.ch -- 03.10.2006 -- hwyss@ywesee.com
|
3
3
|
|
4
|
-
require 'iconv'
|
5
4
|
require 'ydim/config'
|
6
5
|
require 'ydim/client'
|
7
6
|
require 'openssl'
|
@@ -9,7 +8,6 @@ require 'openssl'
|
|
9
8
|
module BBMB
|
10
9
|
module Util
|
11
10
|
module Invoicer
|
12
|
-
@iconv = Iconv.new('ISO-8859-1//TRANSLIT//IGNORE', 'UTF-8')
|
13
11
|
class << self
|
14
12
|
def run(range, date=Date.today)
|
15
13
|
orders = orders(range)
|
@@ -43,27 +41,27 @@ Outstanding: %10.2f
|
|
43
41
|
baseamount = Util::Money.new(BBMB.config.invoice_monthly_baseamount)
|
44
42
|
ydim_connect { |client|
|
45
43
|
ydim_inv = client.create_invoice(BBMB.config.ydim_id)
|
46
|
-
ydim_inv.description = sprintf(
|
44
|
+
ydim_inv.description = sprintf(BBMB.config.invoice_format,
|
47
45
|
time_range.first.strftime("%d.%m.%Y"),
|
48
46
|
(time_range.last - 1).strftime("%d.%m.%Y"))
|
49
47
|
ydim_inv.date = date
|
50
48
|
ydim_inv.currency = currency
|
51
49
|
ydim_inv.payment_period = 30
|
52
50
|
items = []
|
53
|
-
item_format =
|
51
|
+
item_format = BBMB.config.invoice_item_format
|
54
52
|
item_args = [orders.size]
|
55
53
|
time = Time.local(date.year, date.month, date.day)
|
56
54
|
if baseamount > 0
|
57
|
-
item_format =
|
55
|
+
item_format = BBMB.config.invoice_item_overrun_format
|
58
56
|
basepart = [baseline, owed].min
|
59
57
|
text = sprintf(BBMB.config.invoice_item_baseline_format,
|
60
58
|
basepart, owed, *item_args)
|
61
59
|
item_data = {
|
62
60
|
:price => baseamount.to_f,
|
63
61
|
:quantity => 1,
|
64
|
-
:text =>
|
62
|
+
:text => number_format(text),
|
65
63
|
:time => time,
|
66
|
-
:unit =>
|
64
|
+
:unit => BBMB.config.invoice_item_baseamount_unit,
|
67
65
|
}
|
68
66
|
item_args.unshift owed
|
69
67
|
items.push item_data
|
@@ -74,7 +72,7 @@ Outstanding: %10.2f
|
|
74
72
|
item_data = {
|
75
73
|
:price => owed.to_f * BBMB.config.invoice_percentage / 100,
|
76
74
|
:quantity => 1,
|
77
|
-
:text =>
|
75
|
+
:text => number_format(text),
|
78
76
|
:time => Time.local(date.year, date.month, date.day),
|
79
77
|
:unit => "%0.1f%" % BBMB.config.invoice_percentage,
|
80
78
|
}
|
data/lib/bbmb/util/mail.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# Util::Mail -- bbmb.ch -- 19.11.2012 -- yasaka@ywesee.com
|
2
3
|
# Util::Mail -- bbmb.ch -- 27.09.2006 -- hwyss@ywesee.com
|
3
4
|
|
4
5
|
require 'bbmb/config'
|
5
6
|
require 'net/smtp'
|
6
7
|
require 'rmail'
|
7
8
|
require 'pp'
|
9
|
+
require 'bbmb/util/smtp_tls'
|
8
10
|
|
9
11
|
module BBMB
|
10
12
|
module Util
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "openssl"
|
2
|
+
require "net/smtp"
|
3
|
+
|
4
|
+
Net::SMTP.class_eval do
|
5
|
+
private
|
6
|
+
def do_start(helodomain, user, secret, authtype)
|
7
|
+
raise IOError, 'SMTP session already started' if @started
|
8
|
+
|
9
|
+
if RUBY_VERSION == '1.8.6'
|
10
|
+
check_auth_args user, secret, authtype if user or secret
|
11
|
+
else # > 1.8.7
|
12
|
+
check_auth_args user, secret if user or secret
|
13
|
+
end
|
14
|
+
|
15
|
+
sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
|
16
|
+
@socket = Net::InternetMessageIO.new(sock)
|
17
|
+
@socket.read_timeout = 60 #@read_timeout
|
18
|
+
@socket.debug_output = STDERR #@debug_output
|
19
|
+
|
20
|
+
check_response(critical { recv_response() })
|
21
|
+
do_helo(helodomain)
|
22
|
+
|
23
|
+
raise 'openssl library not installed' unless defined?(OpenSSL)
|
24
|
+
starttls
|
25
|
+
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
26
|
+
ssl.sync_close = true
|
27
|
+
ssl.connect
|
28
|
+
@socket = Net::InternetMessageIO.new(ssl)
|
29
|
+
@socket.read_timeout = 60 #@read_timeout
|
30
|
+
@socket.debug_output = STDERR #@debug_output
|
31
|
+
do_helo(helodomain)
|
32
|
+
|
33
|
+
authenticate user, secret, authtype if user
|
34
|
+
@started = true
|
35
|
+
ensure
|
36
|
+
unless @started
|
37
|
+
# authentication failed, cancel connection.
|
38
|
+
@socket.close if not @started and @socket and not @socket.closed?
|
39
|
+
@socket = nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def do_helo(helodomain)
|
44
|
+
begin
|
45
|
+
if @esmtp
|
46
|
+
ehlo helodomain
|
47
|
+
else
|
48
|
+
helo helodomain
|
49
|
+
end
|
50
|
+
rescue Net::ProtocolError
|
51
|
+
if @esmtp
|
52
|
+
@esmtp = false
|
53
|
+
@error_occured = false
|
54
|
+
retry
|
55
|
+
end
|
56
|
+
raise
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def starttls
|
61
|
+
getok('STARTTLS')
|
62
|
+
end
|
63
|
+
|
64
|
+
def quit
|
65
|
+
begin
|
66
|
+
getok('QUIT')
|
67
|
+
rescue EOFError
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -18,9 +18,9 @@ module TransferDat
|
|
18
18
|
def TransferDat.parse_line(line)
|
19
19
|
begin
|
20
20
|
result = Model::Order::Info.new
|
21
|
-
result.pcode =
|
22
|
-
result.description =
|
23
|
-
result.ean13 =
|
21
|
+
result.pcode = line[13,7].to_i.to_s
|
22
|
+
result.description = line[20,50].strip
|
23
|
+
result.ean13 = line[74,13]
|
24
24
|
result.quantity = line[70,4].to_i
|
25
25
|
result
|
26
26
|
rescue Exception => e
|
data/lib/bbmb/version.rb
ADDED
data/readme.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# bbmb
|
2
|
+
|
3
|
+
* https://github.com/zdavatz/bbmb
|
4
|
+
|
5
|
+
You can find a graphical overview here
|
6
|
+
|
7
|
+
* https://github.com/zdavatz/bbmb/bbmb.jpeg
|
8
|
+
|
9
|
+
## DESCRIPTION:
|
10
|
+
|
11
|
+
Browserbasierte Medikamenten Bestellung (bbmb).
|
12
|
+
|
13
|
+
## FEATURES/PROBLEMS:
|
14
|
+
|
15
|
+
* Switch to use the Google SMTP.
|
16
|
+
|
17
|
+
## INSTALL:
|
18
|
+
|
19
|
+
* sudo gem install bbmb
|
20
|
+
* For configuration see Guide.txt
|
21
|
+
|
22
|
+
## DEVELOPERS:
|
23
|
+
|
24
|
+
* Masaomi Hatakeyama
|
25
|
+
* Zeno Davatz
|
26
|
+
* Hannes Wyss (up to Version 2.0)
|
27
|
+
|
28
|
+
## LICENSE:
|
29
|
+
|
30
|
+
* GPLv2
|
data/test/model/test_customer.rb
CHANGED
@@ -4,16 +4,16 @@
|
|
4
4
|
$: << File.expand_path('..', File.dirname(__FILE__))
|
5
5
|
$: << File.expand_path('../../lib', File.dirname(__FILE__))
|
6
6
|
|
7
|
-
require
|
7
|
+
require "minitest/autorun"
|
8
|
+
require 'flexmock/test_unit'
|
8
9
|
require 'bbmb'
|
9
10
|
require 'bbmb/model/customer'
|
10
11
|
require 'bbmb/model/order'
|
11
12
|
require 'stub/persistence'
|
12
|
-
require 'flexmock'
|
13
13
|
|
14
14
|
module BBMB
|
15
15
|
module Model
|
16
|
-
class TestCustomer < Test
|
16
|
+
class TestCustomer < Minitest::Test
|
17
17
|
include FlexMock::TestCase
|
18
18
|
def setup
|
19
19
|
Customer.clear_instances
|
@@ -39,9 +39,7 @@ class TestCustomer < Test::Unit::TestCase
|
|
39
39
|
end
|
40
40
|
def test_email_writer__both_nil
|
41
41
|
BBMB.server = flexmock('server')
|
42
|
-
|
43
|
-
@customer.email = nil
|
44
|
-
}
|
42
|
+
@customer.email = nil
|
45
43
|
assert_equal(nil, @customer.email)
|
46
44
|
end
|
47
45
|
def test_protect
|
@@ -65,9 +63,7 @@ class TestCustomer < Test::Unit::TestCase
|
|
65
63
|
order = flexmock(Model::Order.new(@customer))
|
66
64
|
time = Time.now
|
67
65
|
order.should_receive(:commit!).with(1, time).times(1)
|
68
|
-
|
69
|
-
@customer.inject_order(order, time)
|
70
|
-
}
|
66
|
+
@customer.inject_order(order, time)
|
71
67
|
assert_equal({1 => order}, @customer.archive)
|
72
68
|
end
|
73
69
|
end
|
data/test/model/test_order.rb
CHANGED
@@ -3,19 +3,27 @@
|
|
3
3
|
|
4
4
|
$: << File.expand_path('../../lib', File.dirname(__FILE__))
|
5
5
|
|
6
|
+
require "minitest/autorun"
|
7
|
+
require 'flexmock/test_unit'
|
6
8
|
require 'bbmb/model/order'
|
7
9
|
require 'date'
|
8
|
-
require 'flexmock'
|
9
|
-
require 'test/unit'
|
10
10
|
|
11
11
|
module BBMB
|
12
12
|
module Model
|
13
|
-
class TestOrder <
|
13
|
+
class TestOrder < Minitest::Test
|
14
14
|
include FlexMock::TestCase
|
15
15
|
def setup
|
16
16
|
@customer = flexmock("customer")
|
17
17
|
@customer.should_receive(:quota)
|
18
18
|
@order = Order.new(@customer)
|
19
|
+
@position = flexmock('position')
|
20
|
+
@position.should_receive(:pcode).and_return(nil).by_default
|
21
|
+
@position.should_receive(:price).and_return(nil).by_default
|
22
|
+
@position.should_receive(:ean13).and_return("EAN13").by_default
|
23
|
+
@position.should_receive(:article_number).and_return("ArticleNumber").by_default
|
24
|
+
@position.should_receive(:quantity).and_return(17).by_default
|
25
|
+
@position.should_receive(:freebies).and_return(nil).by_default
|
26
|
+
BBMB.config.i2_100 = 'YWESEE'
|
19
27
|
end
|
20
28
|
def test_add
|
21
29
|
assert_equal(true, @order.empty?)
|
@@ -128,12 +136,8 @@ class TestOrder < Test::Unit::TestCase
|
|
128
136
|
def test_to_i2
|
129
137
|
@customer.should_receive(:customer_id).and_return(7)
|
130
138
|
@customer.should_receive(:organisation).and_return('Organisation')
|
131
|
-
position
|
132
|
-
|
133
|
-
position.should_receive(:article_number).and_return("ArticleNumber")
|
134
|
-
position.should_receive(:quantity).and_return(17)
|
135
|
-
position.should_ignore_missing
|
136
|
-
@order.positions.push(position)
|
139
|
+
@position.should_ignore_missing
|
140
|
+
@order.positions.push(@position)
|
137
141
|
@order.reference = "Reference"
|
138
142
|
@order.comment = "Comment"
|
139
143
|
@order.commit!('8', Time.local(2006,9,27,9,50,12))
|
@@ -170,12 +174,8 @@ class TestOrder < Test::Unit::TestCase
|
|
170
174
|
def test_to_i2__no_comment
|
171
175
|
@customer.should_receive(:customer_id).and_return(7)
|
172
176
|
@customer.should_receive(:organisation).and_return('Organisation')
|
173
|
-
position
|
174
|
-
|
175
|
-
position.should_receive(:article_number).and_return("ArticleNumber")
|
176
|
-
position.should_receive(:quantity).and_return(17)
|
177
|
-
position.should_ignore_missing
|
178
|
-
@order.positions.push(position)
|
177
|
+
@position.should_ignore_missing
|
178
|
+
@order.positions.push(@position)
|
179
179
|
@order.reference = "Reference"
|
180
180
|
@order.commit!('8', Time.local(2006,9,27,9,50,12))
|
181
181
|
@order.priority = 41
|
@@ -210,12 +210,8 @@ class TestOrder < Test::Unit::TestCase
|
|
210
210
|
def test_to_i2__configurable_origin
|
211
211
|
@customer.should_receive(:customer_id).and_return(7)
|
212
212
|
@customer.should_receive(:organisation).and_return('Organisation')
|
213
|
-
position
|
214
|
-
|
215
|
-
position.should_receive(:article_number).and_return("ArticleNumber")
|
216
|
-
position.should_receive(:quantity).and_return(17)
|
217
|
-
position.should_ignore_missing
|
218
|
-
@order.positions.push(position)
|
213
|
+
@position.should_ignore_missing
|
214
|
+
@order.positions.push(@position)
|
219
215
|
@order.reference = "Reference"
|
220
216
|
@order.comment = "Comment"
|
221
217
|
@order.commit!('8', Time.local(2006,9,27,9,50,12))
|
@@ -322,6 +318,8 @@ class TestOrder < Test::Unit::TestCase
|
|
322
318
|
@customer.should_receive(:ean13).and_return(1234567890123)
|
323
319
|
@customer.should_receive(:organisation).and_return('Organisation')
|
324
320
|
position = flexmock('position')
|
321
|
+
position.should_receive(:pcode).and_return(nil)
|
322
|
+
position.should_receive(:price).and_return(nil)
|
325
323
|
position.should_receive(:ean13).and_return("EAN13")
|
326
324
|
position.should_receive(:article_number).and_return("ArticleNumber")
|
327
325
|
position.should_receive(:quantity).and_return(17)
|
@@ -341,12 +339,8 @@ class TestOrder < Test::Unit::TestCase
|
|
341
339
|
@customer.should_receive(:customer_id).and_return(7)
|
342
340
|
@customer.should_receive(:ean13).and_return(1234567890123)
|
343
341
|
@customer.should_receive(:organisation).and_return('Organisation')
|
344
|
-
position
|
345
|
-
|
346
|
-
position.should_receive(:article_number).and_return("ArticleNumber")
|
347
|
-
position.should_receive(:quantity).and_return(17)
|
348
|
-
position.should_ignore_missing
|
349
|
-
@order.positions.push(position, position)
|
342
|
+
@position.should_ignore_missing
|
343
|
+
@order.positions.push(@position, @position)
|
350
344
|
@order.reference = "Reference"
|
351
345
|
@order.commit!('8', Time.local(2006,9,27,9,50,12))
|
352
346
|
@order.priority = 41
|
@@ -360,12 +354,8 @@ class TestOrder < Test::Unit::TestCase
|
|
360
354
|
@customer.should_receive(:customer_id).and_return(7)
|
361
355
|
@customer.should_receive(:ean13).and_return(1234567890123)
|
362
356
|
@customer.should_receive(:organisation).and_return('Organisation')
|
363
|
-
position
|
364
|
-
|
365
|
-
position.should_receive(:article_number).and_return("ArticleNumber")
|
366
|
-
position.should_receive(:quantity).and_return(17)
|
367
|
-
position.should_ignore_missing
|
368
|
-
@order.positions.push(position)
|
357
|
+
@position.should_ignore_missing
|
358
|
+
@order.positions.push(@position)
|
369
359
|
@order.reference = "Reference"
|
370
360
|
@order.comment = "Comment"
|
371
361
|
@order.commit!('8', Time.local(2006,9,27,9,50,12))
|
@@ -405,7 +395,7 @@ class TestOrder < Test::Unit::TestCase
|
|
405
395
|
assert_equal(expected, @order.to_target_format)
|
406
396
|
end
|
407
397
|
end
|
408
|
-
class TestOrderPosition < Test
|
398
|
+
class TestOrderPosition < Minitest::Test
|
409
399
|
include FlexMock::TestCase
|
410
400
|
def setup
|
411
401
|
@product = flexmock('product')
|
data/test/model/test_product.rb
CHANGED
@@ -3,13 +3,14 @@
|
|
3
3
|
|
4
4
|
$: << File.expand_path('../../lib', File.dirname(__FILE__))
|
5
5
|
|
6
|
-
require
|
6
|
+
require "minitest/autorun"
|
7
|
+
require 'flexmock/test_unit'
|
7
8
|
require 'bbmb/model/product'
|
8
9
|
require 'bbmb/model/promotion'
|
9
10
|
|
10
11
|
module BBMB
|
11
12
|
module Model
|
12
|
-
class TestProduct < Test
|
13
|
+
class TestProduct < Minitest::Test
|
13
14
|
def setup
|
14
15
|
@product = Product.new("article_number")
|
15
16
|
end
|
@@ -50,11 +51,11 @@ class TestProduct < Test::Unit::TestCase
|
|
50
51
|
assert_equal(false, @product.backorder)
|
51
52
|
end
|
52
53
|
def test_equals
|
53
|
-
|
54
|
+
refute_equal(@product, 'article_number')
|
54
55
|
other = Product.new("article_number")
|
55
56
|
assert_equal(@product, other)
|
56
57
|
other = Product.new("foobar")
|
57
|
-
|
58
|
+
refute_equal(@product, other)
|
58
59
|
end
|
59
60
|
def test_price
|
60
61
|
assert_equal(nil, @product.price)
|