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,99 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::Product -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/model/subject'
5
+ require 'bbmb/util/numbers'
6
+ require 'date'
7
+
8
+ module BBMB
9
+ module Model
10
+ class ProductInfo < Subject
11
+ include Util::Numbers
12
+ attr_reader :article_number, :backorder
13
+ attr_accessor :backorder_date, :commit_date, :ean13, :expiry_date,
14
+ :partner_index, :pcode, :promotion, :sale, :status
15
+ multilingual :description, :catalogue1, :catalogue2, :catalogue3
16
+ int_accessor :l1_qty, :l2_qty, :l3_qty, :l4_qty, :l5_qty, :l6_qty
17
+ money_accessor :price, :l1_price, :l2_price, :l3_price, :l4_price,
18
+ :l5_price, :l6_price, :vat
19
+ def initialize(article_number)
20
+ @article_number = article_number
21
+ @backorder = false
22
+ end
23
+ def current_promo
24
+ [@sale, @promotion].find { |promo| promo }
25
+ end
26
+ def freebies(level)
27
+ (promo = current_promo) && promo.freebies(level)
28
+ end
29
+ def price(qty=nil)
30
+ qty ||= 1
31
+ res = @price
32
+ (1..6).each { |num|
33
+ if(res.nil? || ((tmp = instance_variable_get("@l#{num}_qty")) \
34
+ && qty >= tmp))
35
+ res = instance_variable_get("@l#{num}_price") || res
36
+ end
37
+ }
38
+ if((pr = current_promo) && (((price = pr.price_qty(qty)) && price > res) \
39
+ || ((price = pr.l1_price) && price > res)))
40
+ res = price
41
+ end
42
+ res
43
+ end
44
+ def price_base
45
+ price(1)
46
+ end
47
+ def price_effective(qty=nil)
48
+ price = price_qty(qty)
49
+ if((promo = current_promo) && (discount = promo.discount(qty)))
50
+ price *= (100.0 - discount) / 100.0
51
+ end
52
+ price || Util::Money.new(0)
53
+ end
54
+ def price_qty(qty=nil)
55
+ ((promo = current_promo) && promo.price_qty(qty)) \
56
+ || price(qty)
57
+ end
58
+ def qty_level(level=nil)
59
+ if((promo = current_promo) && promo.has_price_qty?)
60
+ promo.qty_level(level)
61
+ else
62
+ instance_variable_get("@l#{level}_qty")
63
+ end
64
+ end
65
+ def to_info
66
+ self
67
+ end
68
+ def ==(other)
69
+ other.is_a?(ProductInfo) && @article_number == other.article_number
70
+ end
71
+ end
72
+ class Product < ProductInfo
73
+ def backorder=(value)
74
+ case value
75
+ when true, 1, /^(ja?|y(es)?|1)$/i
76
+ @backorder = true
77
+ else
78
+ @backorder = false
79
+ end
80
+ end
81
+ def current_promo
82
+ [@sale, @promotion].find { |promo| promo && promo.current? }
83
+ end
84
+ def to_info
85
+ info = ProductInfo.new(@article_number)
86
+ [ :backorder_date, :catalogue1, :catalogue2, :catalogue3,
87
+ :description, :ean13, :expiry_date, :partner_index, :pcode,
88
+ :status, :l1_qty, :l2_qty, :l3_qty, :l4_qty, :l5_qty, :l6_qty, :vat,
89
+ :price, :l1_price, :l2_price, :l3_price, :l4_price, :l5_price, :l6_price
90
+ ].each { |key|
91
+ info.send("#{key}=", self.send(key))
92
+ }
93
+ info.promotion = @promotion.dup if(@promotion && @promotion.current?)
94
+ info.sale = @sale.dup if(@sale && @sale.current?)
95
+ info
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::Promotion -- bbmb -- 10.04.2007 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/model/subject'
5
+ require 'bbmb/util/numbers'
6
+ require 'date'
7
+
8
+ module BBMB
9
+ module Model
10
+ class Promotion < Subject
11
+ include Util::Numbers
12
+ attr_accessor :end_date, :start_date
13
+ int_accessor :l1_qty, :l2_qty, :l3_qty, :l4_qty,
14
+ :l1_free, :l2_free, :l3_free, :l4_free,
15
+ :l1_discount, :l2_discount, :l3_discount, :l4_discount
16
+ money_accessor :l1_price, :l2_price, :l3_price, :l4_price
17
+ multilingual :lines
18
+ def current?
19
+ today = Date.today
20
+ !!(@start_date || @end_date) \
21
+ && (@start_date.nil? || today >= @start_date) \
22
+ && (@end_date.nil? || today <= @end_date)
23
+ end
24
+ def discount(qty)
25
+ data_qty(qty, "discount")
26
+ end
27
+ def freebies(qty)
28
+ data_qty(qty, "free")
29
+ end
30
+ def has_price_qty?
31
+ !@l1_price.nil?
32
+ end
33
+ def price_qty(qty)
34
+ data_qty(qty, "price")
35
+ end
36
+ def qty_level(level)
37
+ instance_variable_get("@l#{level}_qty")
38
+ end
39
+ private
40
+ def data_qty(qty, key)
41
+ return if qty.nil?
42
+ res = nil
43
+ (1..4).each { |num|
44
+ if((tmp = qty_level(num)) && qty >= tmp)
45
+ res = instance_variable_get("@l#{num}_#{key}") || res
46
+ end
47
+ }
48
+ res
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::Deal -- bbmb -- 11.04.2007 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/util/numbers'
5
+
6
+ module BBMB
7
+ module Model
8
+ class Quota
9
+ class << self
10
+ def delegate(*keys)
11
+ keys.each { |key|
12
+ define_method(key) { @product.send(key) }
13
+ }
14
+ end
15
+ end
16
+ include Util::Numbers
17
+ attr_reader :product
18
+ attr_accessor :start_date, :end_date
19
+ int_accessor :target, :actual, :difference
20
+ money_accessor :price
21
+ delegate :article_number, :description
22
+ def initialize(product)
23
+ @product = product
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ # Model -- bbmb -- 08.08.2007 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/util/multilingual'
5
+
6
+ module BBMB
7
+ module Model
8
+ class Subject
9
+ class << self
10
+ def multilingual(*keys)
11
+ @multilinguals ||= []
12
+ keys.each { |key|
13
+ @multilinguals.push key
14
+ name = "@#{key}"
15
+ define_method(key) {
16
+ instance_variable_get(name) or begin
17
+ instance_variable_set(name, Util::Multilingual.new)
18
+ end
19
+ }
20
+ define_method(:to_s) {
21
+ self.send(key).to_s
22
+ }
23
+ ml = @multilinguals
24
+ define_method(:multilinguals) { ml }
25
+ protected
26
+ attr_writer key
27
+ }
28
+ end
29
+ end
30
+ def migrate_to_subject
31
+ changed = false
32
+ multilinguals.each { |key|
33
+ name = "@#{key}"
34
+ if((var = instance_variable_get(name)) \
35
+ && !var.is_a?(Util::Multilingual))
36
+ changed = true
37
+ ml = Util::Multilingual.new
38
+ ml.de = var
39
+ instance_variable_set(name, ml)
40
+ end
41
+ }
42
+ changed
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # Persistence::None -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/persistence/odba/product'
5
+ require 'bbmb/persistence/odba/customer'
6
+
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # Persistence::ODBA -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/config'
5
+ require 'odba'
6
+ require 'odba/connection_pool'
7
+ require 'odba/drbwrapper'
8
+ require 'bbmb/persistence/odba/model/customer'
9
+ require 'bbmb/persistence/odba/model/order'
10
+ require 'bbmb/persistence/odba/model/product'
11
+ require 'bbmb/persistence/odba/model/quota'
12
+
13
+ module BBMB
14
+ module Persistence
15
+ module ODBA
16
+ def ODBA.all(klass, &block)
17
+ klass.odba_extent(&block)
18
+ end
19
+ def ODBA.save(*objs)
20
+ objs.each { |obj| obj.odba_store }
21
+ end
22
+ def ODBA.delete(*objs)
23
+ objs.each { |obj| obj.odba_delete }
24
+ end
25
+ def ODBA.migrate_to_subject
26
+ all(Model::Product) { |product|
27
+ product.migrate_to_subject && product.odba_store
28
+ }
29
+ all(Model::Order) { |order|
30
+ order.each { |position|
31
+ position.migrate_to_subject && position.odba_store
32
+ }
33
+ }
34
+ ::ODBA.cache.create_deferred_indices(true)
35
+ end
36
+ end
37
+ end
38
+ ODBA.storage.dbi = ODBA::ConnectionPool.new("DBI:pg:#{@config.db_name}",
39
+ @config.db_user, @config.db_auth)
40
+ ODBA.cache.setup
41
+ ODBA.cache.prefetch
42
+ end
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::Customer -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/model/customer'
5
+
6
+ module BBMB
7
+ module Model
8
+ class Customer
9
+ include ODBA::Persistable
10
+ ODBA_PREFETCH = true
11
+ ODBA_SERIALIZABLE = ['@protected']
12
+ odba_index :customer_id
13
+ odba_index :ean13
14
+ odba_index :email
15
+ alias :__old_current_order__ :current_order
16
+ def current_order
17
+ if(@current_order.nil?)
18
+ __old_current_order__
19
+ odba_store
20
+ end
21
+ @current_order
22
+ end
23
+ alias :__old_commit_order__ :commit_order!
24
+ def commit_order!(*args)
25
+ order = __old_commit_order__(*args)
26
+ @archive.odba_store
27
+ odba_store
28
+ order
29
+ end
30
+ alias :__old_inject_order__ :inject_order
31
+ def inject_order(*args)
32
+ order = __old_inject_order__(*args)
33
+ @archive.odba_store
34
+ odba_store
35
+ order
36
+ end
37
+ alias :__old_favorites__ :favorites
38
+ def favorites
39
+ if(@favorites.nil?)
40
+ __old_favorites__
41
+ odba_store
42
+ end
43
+ @favorites
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::Order -- bbmb.ch -- 25.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/model/order'
5
+
6
+ module BBMB
7
+ module Model
8
+ class Order
9
+ class Position
10
+ include ODBA::Persistable
11
+ alias :__old_commit__ :commit!
12
+ def commit!(*args)
13
+ res = __old_commit__(*args)
14
+ odba_store
15
+ res
16
+ end
17
+ end
18
+ include ODBA::Persistable
19
+ ODBA_SERIALIZABLE = ['@unavailable']
20
+ alias :__old_add__ :add
21
+ def add(quantity, product)
22
+ if(pos = __old_add__(quantity, product))
23
+ if(quantity.zero?)
24
+ pos.odba_delete
25
+ else
26
+ pos.odba_store
27
+ end
28
+ @positions.odba_store
29
+ pos
30
+ end
31
+ end
32
+ alias :__old_clear__ :clear
33
+ def clear
34
+ @positions.each { |pos|
35
+ pos.odba_delete
36
+ }
37
+ res = __old_clear__
38
+ @positions.odba_store
39
+ odba_store
40
+ res
41
+ end
42
+ alias :__old_commit__ :commit!
43
+ def commit!(*args)
44
+ res = __old_commit__(*args)
45
+ odba_store
46
+ res
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::Product -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/model/product'
5
+
6
+ module BBMB
7
+ module Model
8
+ class ProductInfo
9
+ def migrate_to_subject
10
+ changed = super
11
+ @promotion && @promotion.migrate_to_subject && (changed = true)
12
+ @sale && @sale.migrate_to_subject && (changed = true)
13
+ changed
14
+ end
15
+ end
16
+ class Product
17
+ include ODBA::Persistable
18
+ odba_index :article_number
19
+ odba_index :ean13
20
+ odba_index :description, 'description.all'
21
+ odba_index :pcode
22
+ odba_index :catalogue1, 'catalogue1.all'
23
+ odba_index :catalogue2, 'catalogue2.all'
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # Model::Quota -- bbmb -- 11.04.2007 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/model/quota'
5
+
6
+ module BBMB
7
+ module Model
8
+ class Quota
9
+ include ODBA::Persistable
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::Invoicer -- bbmb.ch -- 03.10.2006 -- hwyss@ywesee.com
3
+
4
+ require 'iconv'
5
+ require 'ydim/config'
6
+ require 'ydim/client'
7
+ require 'openssl'
8
+
9
+ module BBMB
10
+ module Util
11
+ module Invoicer
12
+ @iconv = Iconv.new('ISO-8859-1//TRANSLIT//IGNORE', 'UTF-8')
13
+ class << self
14
+ def run(range, date=Date.today)
15
+ orders = orders(range)
16
+ turnover = deduction = Util::Money.new(0)
17
+ baseline = Util::Money.new(BBMB.config.invoice_baseline)
18
+ total = orders.inject(turnover) { |memo, order| order.total + memo }
19
+ if(total == 0 || baseline > 0)
20
+ all_orders = orders(fiscal_year(range))
21
+ turnover = all_orders.inject(turnover) { |memo, order|
22
+ order.total + memo }
23
+ deduction = [deduction, baseline - turnover].max
24
+ end
25
+ owed = total - deduction
26
+ if(owed > 0)
27
+ invoice = create_invoice(range, owed, orders, date)
28
+ send_invoice(invoice.unique_id)
29
+ else
30
+ body = sprintf(<<-EOS, baseline, turnover + total, total, deduction - total)
31
+ Baseline: %10.2f
32
+ Turnover: %10.2f
33
+ Current Month: %10.2f
34
+ -------------------------
35
+ Outstanding: %10.2f
36
+ EOS
37
+ Util::Mail.notify_debug("No invoice necessary", body)
38
+ end
39
+ end
40
+ def create_invoice(time_range, owed, orders, date, currency='CHF')
41
+ time = Time.now
42
+ baseline = Util::Money.new(BBMB.config.invoice_monthly_baseline)
43
+ baseamount = Util::Money.new(BBMB.config.invoice_monthly_baseamount)
44
+ ydim_connect { |client|
45
+ ydim_inv = client.create_invoice(BBMB.config.ydim_id)
46
+ ydim_inv.description = sprintf(@iconv.iconv(BBMB.config.invoice_format),
47
+ time_range.first.strftime("%d.%m.%Y"),
48
+ (time_range.last - 1).strftime("%d.%m.%Y"))
49
+ ydim_inv.date = date
50
+ ydim_inv.currency = currency
51
+ ydim_inv.payment_period = 30
52
+ items = []
53
+ item_format = @iconv.iconv(BBMB.config.invoice_item_format)
54
+ item_args = [orders.size]
55
+ time = Time.local(date.year, date.month, date.day)
56
+ if baseamount > 0
57
+ item_format = @iconv.iconv(BBMB.config.invoice_item_overrun_format)
58
+ basepart = [baseline, owed].min
59
+ text = sprintf(BBMB.config.invoice_item_baseline_format,
60
+ basepart, owed, *item_args)
61
+ item_data = {
62
+ :price => baseamount.to_f,
63
+ :quantity => 1,
64
+ :text => @iconv.iconv(number_format(text)),
65
+ :time => time,
66
+ :unit => @iconv.iconv(BBMB.config.invoice_item_baseamount_unit),
67
+ }
68
+ item_args.unshift owed
69
+ items.push item_data
70
+ end
71
+ if owed > baseline
72
+ owed -= baseline
73
+ text = sprintf(item_format, owed, *item_args)
74
+ item_data = {
75
+ :price => owed.to_f * BBMB.config.invoice_percentage / 100,
76
+ :quantity => 1,
77
+ :text => @iconv.iconv(number_format(text)),
78
+ :time => Time.local(date.year, date.month, date.day),
79
+ :unit => "%0.1f%" % BBMB.config.invoice_percentage,
80
+ }
81
+ items.push item_data
82
+ end
83
+ client.add_items(ydim_inv.unique_id, items)
84
+ ydim_inv
85
+ }
86
+ end
87
+ def fiscal_year(range)
88
+ day, month, = BBMB.config.invoice_newyear.split('.', 3)
89
+ time = range.first
90
+ year = time.year
91
+ first = Time.local(year, month, day)
92
+ if(first > time)
93
+ first = Time.local(year - 1, month, day)
94
+ end
95
+ first...time
96
+ end
97
+ def number_format(string)
98
+ string.reverse.gsub(/\d{3}(?=\d)(?!\d*\.)/) do |match|
99
+ match << "'"
100
+ end.reverse
101
+ end
102
+ def orders(range)
103
+ BBMB.persistence.all(Model::Order).select { |order|
104
+ order.commit_time && range.include?(order.commit_time)
105
+ }
106
+ end
107
+ def send_invoice(invoice_id)
108
+ ydim_connect { |client| client.send_invoice(invoice_id) }
109
+ end
110
+ def ydim_connect(&block)
111
+ config = YDIM::Client::CONFIG
112
+ if(path = BBMB.config.ydim_config)
113
+ config.load(path)
114
+ end
115
+ server = DRbObject.new(nil, config.server_url)
116
+ client = YDIM::Client.new(config)
117
+ key = OpenSSL::PKey::DSA.new(File.read(config.private_key))
118
+ client.login(server, key)
119
+ block.call(client)
120
+ ensure
121
+ client.logout if(client)
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end