bbmb 2.0.0 → 2.0.1
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.
- 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)
|