bbmb 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,140 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::Mail -- bbmb.ch -- 27.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/config'
5
+ require 'net/smtp'
6
+ require 'rmail'
7
+ require 'pp'
8
+
9
+ module BBMB
10
+ module Util
11
+ module Mail
12
+ def Mail.notify_confirmation_error(order)
13
+ config = BBMB.config
14
+ if to = config.confirm_error_to
15
+ header, message = setup
16
+ customer = order.customer
17
+ from = header.from = config.confirm_error_from
18
+ header.to = to
19
+ cc = header.cc = config.confirm_error_cc
20
+ header.subject = config.confirm_error_subject % customer.customer_id
21
+ message.body = config.confirm_error_body % customer.customer_id
22
+ Mail.sendmail message, from, to, cc
23
+ end
24
+ end
25
+ def Mail.notify_debug(subject, body)
26
+ header, message = setup
27
+ config = BBMB.config
28
+ from = header.from = config.mail_order_from
29
+ to = header.to = config.error_recipients
30
+ header.subject = sprintf "%s: %s", BBMB.config.name, subject
31
+ message.body = body
32
+ Mail.sendmail(message, from, to)
33
+ end
34
+ def Mail.notify_error(error)
35
+ header, message = setup
36
+ config = BBMB.config
37
+ from = header.from = config.mail_order_from
38
+ to = header.to = config.error_recipients
39
+ header.subject = sprintf "%s: %s", BBMB.config.name, error.message
40
+ message.body = [ error.class, error.message,
41
+ error.backtrace.pretty_inspect ].join("\n")
42
+ Mail.sendmail(message, from, to)
43
+ end
44
+ def Mail.notify_inject_error(order, opts={})
45
+ config = BBMB.config
46
+ if to = config.inject_error_to
47
+ customer = order.customer
48
+ header, message = setup
49
+ from = header.from = config.inject_error_from
50
+ header.to = to
51
+ cc = header.cc = config.inject_error_cc
52
+ header.subject = config.inject_error_subject % [
53
+ order.order_id,
54
+ opts[:customer_name] || customer.customer_id,
55
+ ]
56
+ message.body = config.inject_error_body % [
57
+ opts[:customer_name] || customer.customer_id,
58
+ order.commit_time.strftime('%d.%m.%Y %H:%M:%S'),
59
+ customer.customer_id,
60
+ ]
61
+ Mail.sendmail message, from, to, cc
62
+ end
63
+ end
64
+ def Mail.sendmail(message, from, to, cc=[])
65
+ config = BBMB.config
66
+ Net::SMTP.start(config.smtp_server, config.smtp_port, config.smtp_helo,
67
+ config.smtp_user, config.smtp_pass,
68
+ config.smtp_authtype) { |smtp|
69
+ smtp.sendmail(message.to_s, from, [to, cc].flatten.compact)
70
+ }
71
+ end
72
+ def Mail.send_confirmation(order)
73
+ config = BBMB.config
74
+ ## there are two switches that determine whether a confirmation is sent out:
75
+ # application-wide: mail_confirm_reply_to must be configured
76
+ reply_to = config.mail_confirm_reply_to or return nil
77
+ # per-customer: order_confirmation must be checked
78
+ order.customer.order_confirmation or return nil
79
+ to = order.customer.email or return notify_confirmation_error(order)
80
+ body = config.mail_confirm_body or return nil
81
+ date = order.commit_time.strftime("%d.%m.%Y")
82
+ parts = []
83
+ config.mail_confirm_lines.collect do |line|
84
+ content = order.collect do |pos|
85
+ sprintf line, pos.quantity, pos.description, pos.price_qty, pos.total
86
+ end
87
+ parts.push date, content.join("\n"), order.total
88
+ if vtotal = order.total_incl_vat
89
+ parts.push vtotal
90
+ end
91
+ end
92
+
93
+ header, message = setup
94
+ from = header.from = config.mail_confirm_from
95
+ header.to = to
96
+ header.subject = config.mail_confirm_subject % order.order_id
97
+ header.add('Message-ID', sprintf('<%s@%s>', order.order_id,
98
+ from.tr('@', '.')))
99
+ header.add('Reply-To', reply_to)
100
+ message.body = sprintf body, *parts
101
+
102
+ Mail.sendmail(message, from, to, config.mail_confirm_cc)
103
+ end
104
+ def Mail.send_order(order)
105
+ header, message = setup
106
+ config = BBMB.config
107
+ from = header.from = config.mail_order_from
108
+ to = header.to = config.mail_order_to
109
+ cc = header.cc = config.mail_order_cc
110
+ header.subject = config.mail_order_subject % order.order_id
111
+ header.add('Message-ID', sprintf('<%s@%s>', order.order_id,
112
+ from.tr('@', '.')))
113
+ message.body = order.to_target_format
114
+
115
+ Mail.sendmail(message, from, to, cc)
116
+ end
117
+ def Mail.send_request(email, organisation, body)
118
+ header, message = setup
119
+ config = BBMB.config
120
+ from = header.from = config.mail_request_from
121
+ to = header.to = config.mail_request_to
122
+ cc = header.cc = config.mail_request_cc
123
+ header.subject = config.mail_request_subject % organisation
124
+ header.add('Reply-To', email)
125
+ message.body = body
126
+ Mail.sendmail(message, from, to, cc)
127
+ end
128
+ def Mail.setup
129
+ message = RMail::Message.new
130
+ header = message.header
131
+ header.add('Date', Time.now.rfc822)
132
+ header.add('Mime-Version', '1.0')
133
+ header.add('User-Agent', BBMB.config.name)
134
+ header.add('Content-Type', 'text/plain', nil, 'charset' => 'utf-8')
135
+ header.add('Content-Disposition', 'inline')
136
+ [header, message]
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::Multilingual -- de.oddb.org -- 04.09.2006 -- hwyss@ywesee.com
3
+
4
+ module BBMB
5
+ module Util
6
+ class Multilingual
7
+ include Comparable
8
+ attr_reader :canonical
9
+ attr_reader :synonyms
10
+ def initialize(canonical={})
11
+ @canonical = canonical
12
+ @synonyms = []
13
+ end
14
+ def all
15
+ @canonical.values.concat(@synonyms)
16
+ end
17
+ def default
18
+ @canonical.values.sort.first
19
+ end
20
+ def empty?
21
+ @canonical.empty?
22
+ end
23
+ def method_missing(meth, *args, &block)
24
+ case meth.to_s
25
+ when /^[a-z]{2}$/
26
+ @canonical[meth]
27
+ when /^([a-z]{2})=$/
28
+ key = $~[1].to_sym
29
+ if(value = args.first)
30
+ @canonical.store(key, value)
31
+ else
32
+ @canonical.delete(key)
33
+ end
34
+ else
35
+ super(meth, *args, &block)
36
+ end
37
+ end
38
+ def to_s
39
+ default.to_s
40
+ end
41
+ def ==(other)
42
+ case other
43
+ when String
44
+ @canonical.values.any? { |val| val == other } \
45
+ || @synonyms.any? { |val| val == other }
46
+ when Multilingual
47
+ @canonical == other.canonical && @synonyms == other.synonyms
48
+ else
49
+ false
50
+ end
51
+ end
52
+ def <=>(other)
53
+ all.sort <=> other.all.sort
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::Money -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
3
+
4
+ module BBMB
5
+ module Util
6
+ module Numbers
7
+ def Numbers.append_features(mod)
8
+ super
9
+ mod.module_eval {
10
+ class << self
11
+ def money_accessor(*keys)
12
+ keys.each { |key|
13
+ attr_reader key
14
+ define_method("#{key}=") { |value|
15
+ money = Util::Money.new(value) if(value.to_f > 0)
16
+ instance_variable_set("@#{key}", money)
17
+ }
18
+ }
19
+ end
20
+ def int_accessor(*keys)
21
+ keys.each { |key|
22
+ attr_reader key
23
+ define_method("#{key}=") { |value|
24
+ int = value.to_i if(value)
25
+ instance_variable_set("@#{key}", int)
26
+ }
27
+ }
28
+ end
29
+ end
30
+ }
31
+ end
32
+ end
33
+ class Money
34
+ attr_reader :credits
35
+ include Comparable
36
+ def initialize(amount)
37
+ @credits = (amount.to_f * 100).round
38
+ end
39
+ def to_f
40
+ @credits.to_f / 100
41
+ end
42
+ def to_s
43
+ sprintf("%1.2f", to_f)
44
+ end
45
+ def +(other)
46
+ Money.new(to_f + other.to_f)
47
+ end
48
+ def -(other)
49
+ Money.new(to_f - other.to_f)
50
+ end
51
+ def *(other)
52
+ Money.new(to_f * other.to_f)
53
+ end
54
+ def /(other)
55
+ Money.new(to_f / other.to_f)
56
+ end
57
+ def <=>(other)
58
+ case other
59
+ when Money
60
+ @credits <=> other.credits
61
+ else
62
+ to_f <=> other.to_f
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # PasswordGenerator -- bbmb -- 11.10.2002 -- hwyss@ywesee.com
3
+
4
+ module BBMB
5
+ module Util
6
+ class PasswordGenerator
7
+ SEQUENCE = [ :char, :char, :sym, :num ]
8
+ SIZE = {
9
+ :char => 2,
10
+ :num => 4,
11
+ :sym => 1,
12
+ }
13
+ POOL = {
14
+ :char => ("A".."Z").to_a + ("a".."z").to_a,
15
+ :num => ("0".."9").to_a,
16
+ :sym => %w{! @ * ?},
17
+ }
18
+ class << self
19
+ def generate(user)
20
+ pool = POOL.dup
21
+ char = [user.organisation, user.firstname, user.lastname].join
22
+ if(char.length >= 12)
23
+ pool[:char] = char.scan(/\w/)
24
+ end
25
+ pass = ""
26
+ random_sequence.each { |type|
27
+ SIZE[type].times {
28
+ pass << pool[type].at(rand(pool[type].size))
29
+ }
30
+ }
31
+ pass
32
+ end
33
+ def random_sequence
34
+ sequence = SEQUENCE.dup
35
+ random = []
36
+ while(sequence.length > 0)
37
+ random.push(sequence.delete_at(rand(sequence.size)))
38
+ end
39
+ random
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::PollingManager -- bbmb.ch -- 14.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb'
5
+ require 'bbmb/util/mail'
6
+ require 'fileutils'
7
+ require 'net/ftp'
8
+ require 'net/pop'
9
+ require 'tmpdir'
10
+ require 'uri'
11
+ require 'yaml'
12
+
13
+ module BBMB
14
+ module Util
15
+ class FileMission
16
+ attr_accessor :backup_dir, :delete, :directory, :glob_pattern
17
+ def file_paths
18
+ path = File.expand_path(@glob_pattern || '*', @directory)
19
+ Dir.glob(path).collect { |entry|
20
+ File.expand_path(entry, @directory)
21
+ }.compact
22
+ end
23
+ def poll(&block)
24
+ @directory = File.expand_path(@directory, BBMB.config.bbmb_dir)
25
+ file_paths.each { |path|
26
+ poll_path(path, &block)
27
+ }
28
+ end
29
+ def poll_path(path, &block)
30
+ File.open(path) { |io|
31
+ block.call(File.basename(path), io)
32
+ }
33
+ rescue StandardError => err
34
+ BBMB::Util::Mail.notify_error(err)
35
+ ensure
36
+ if(@backup_dir)
37
+ dir = File.expand_path(@backup_dir, BBMB.config.bbmb_dir)
38
+ FileUtils.mkdir_p(dir)
39
+ FileUtils.cp(path, dir)
40
+ end
41
+ if(@delete)
42
+ FileUtils.rm(path)
43
+ end
44
+ end
45
+ end
46
+ class PopMission
47
+ attr_accessor :host, :port, :user, :pass, :delete
48
+ @@ptrn = /name=(?:(?:(?<quote>['"])(?:=\?.+?\?[QB]\?)?(?<file>.*?)(\?=)?(?<!\\)\k<quote>)|(?:(?<file>.+?)(?:;|$)))/i
49
+ def poll(&block)
50
+ Net::POP3.start(@host, @port || 110, @user, @pass) { |pop|
51
+ pop.each_mail { |mail|
52
+ poll_mail(mail, &block)
53
+ }
54
+ }
55
+ end
56
+ def poll_mail(mail, &block)
57
+ source = mail.pop
58
+ ## work around a bug in RMail::Parser that cannot deal with
59
+ ## RFC-2822-compliant CRLF..
60
+ source.gsub!(/\r\n/, "\n")
61
+ poll_message(RMail::Parser.read(source), &block)
62
+ mail.delete if(@delete)
63
+ rescue StandardError => err
64
+ BBMB::Util::Mail.notify_error(err)
65
+ end
66
+ def poll_message(message, &block)
67
+ if(message.multipart?)
68
+ message.each_part { |part|
69
+ poll_message(part, &block)
70
+ }
71
+ elsif(match = @@ptrn.match(message.header["Content-Type"]))
72
+ block.call(match["file"], message.decode)
73
+ end
74
+ end
75
+ end
76
+ class FtpMission
77
+ attr_accessor :backup_dir, :delete, :pattern, :directory
78
+ def initialize(*args)
79
+ super
80
+ @regexp = Regexp.new('.*')
81
+ end
82
+ def poll(&block)
83
+ @backup_dir ||= Dir.tmpdir
84
+ FileUtils.mkdir_p(@backup_dir)
85
+ @regexp = Regexp.new(@pattern || '.*')
86
+ uri = URI.parse(@directory)
87
+ locals = []
88
+ Net::FTP.open(uri.host) do |ftp|
89
+ ftp.login uri.user, uri.password
90
+ ftp.chdir uri.path
91
+ ftp.nlst.each do |file|
92
+ if(local = poll_remote ftp, file)
93
+ locals.push local
94
+ end
95
+ end
96
+ end
97
+ locals.each do |path|
98
+ poll_file path, &block
99
+ end
100
+ end
101
+ def poll_file(path, &block)
102
+ File.open(path) { |io|
103
+ block.call(File.basename(path), io)
104
+ }
105
+ rescue StandardError => err
106
+ BBMB::Util::Mail.notify_error(err)
107
+ end
108
+ def poll_remote(ftp, file)
109
+ if(@regexp.match file)
110
+ local = File.join(@backup_dir, file)
111
+ ftp.get file, local
112
+ ftp.delete file if @delete
113
+ local
114
+ end
115
+ end
116
+ def regexp
117
+ end
118
+ end
119
+ class PollingManager
120
+ def load_sources(&block)
121
+ file = File.open(BBMB.config.polling_file)
122
+ YAML.load_documents(file) { |mission|
123
+ block.call(mission)
124
+ }
125
+ ensure
126
+ file.close if(file)
127
+ end
128
+ def poll_sources(&block)
129
+ load_sources { |source|
130
+ source.poll(&block)
131
+ }
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,159 @@
1
+ #!/usr/bin/env ruby
2
+ # Util::Server -- de.bbmb.org -- 01.09.2006 -- hwyss@ywesee.com
3
+
4
+ require 'bbmb/config'
5
+ require 'bbmb/html/util/known_user'
6
+ require 'bbmb/html/util/session'
7
+ require 'bbmb/html/util/validator'
8
+ require 'bbmb/util/invoicer'
9
+ require 'bbmb/util/mail'
10
+ require 'bbmb/util/updater'
11
+ require 'date'
12
+ require 'sbsm/drbserver'
13
+
14
+ module BBMB
15
+ module Util
16
+ class Server < SBSM::DRbServer
17
+ ENABLE_ADMIN = true
18
+ SESSION = Html::Util::Session
19
+ VALIDATOR = Html::Util::Validator
20
+ attr_reader :updater
21
+ def inject_order(customer_id, products, infos, opts={})
22
+ customer = Model::Customer.find_by_customer_id(customer_id) \
23
+ || Model::Customer.find_by_ean13(customer_id)
24
+ needed_create = false
25
+ unless customer
26
+ if idtype = opts[:create_missing_customer] && !customer_id.empty?
27
+ customer = Model::Customer.new(customer_id)
28
+ if idtype.to_s == 'ean13'
29
+ customer.ean13 = customer_id
30
+ end
31
+ BBMB.persistence.save(customer)
32
+ needed_create = true
33
+ else
34
+ raise "Unknown Customer #{customer_id}"
35
+ end
36
+ end
37
+ order = Model::Order.new(customer)
38
+ products.each { |info|
39
+ if(product = Model::Product.find_by_pcode(info[:pcode]) \
40
+ || Model::Product.find_by_ean13(info[:ean13]) \
41
+ || Model::Product.find_by_article_number(info[:article_number]))
42
+ order.add(info[:quantity], product)
43
+ [:article_number, :backorder].each do |key|
44
+ info.store key, product.send(key)
45
+ end
46
+ info.store :description, product.description.de
47
+ info[:deliverable] = info[:quantity]
48
+ else
49
+ info[:deliverable] = 0
50
+ end
51
+ }
52
+ infos.each { |key, value|
53
+ order.send("#{key}=", value)
54
+ }
55
+ customer.inject_order(order)
56
+ if opts[:deliver]
57
+ async do
58
+ send_order order, customer
59
+ end
60
+ end
61
+ if needed_create
62
+ BBMB::Util::Mail.notify_inject_error(order, opts)
63
+ end
64
+ { :order_id => order.order_id, :products => products }
65
+ end
66
+ def invoice(range)
67
+ Invoicer.run(range)
68
+ rescue Exception => e
69
+ Mail.notify_error(e)
70
+ end
71
+ def login(email, pass)
72
+ session = BBMB.auth.login(email, pass, BBMB.config.auth_domain)
73
+ Html::Util::KnownUser.new(session)
74
+ end
75
+ def logout(session)
76
+ BBMB.auth.logout(session)
77
+ rescue DRb::DRbError, RangeError, NameError
78
+ end
79
+ def rename_user(old, new)
80
+ return if(old == new)
81
+ BBMB.auth.autosession(BBMB.config.auth_domain) { |session|
82
+ if(old.nil?)
83
+ session.create_entity(new)
84
+ else
85
+ session.rename(old, new)
86
+ end
87
+ }
88
+ end
89
+ def run_invoicer
90
+ @invoicer ||= Thread.new {
91
+ Thread.current.abort_on_exception = true
92
+ loop {
93
+ today = Date.today
94
+ day = today >> 1
95
+ start = Time.local(today.year, today.month)
96
+ now = Time.now
97
+ at = Time.local(day.year, day.month)
98
+ secs = at - now
99
+ BBMB.logger.debug("invoicer") {
100
+ "sleeping %.2f seconds" % secs
101
+ }
102
+ sleep(secs)
103
+ invoice(start...at)
104
+ }
105
+ }
106
+ end
107
+ def run_updater
108
+ @updater ||= Thread.new {
109
+ loop {
110
+ day = Date.today
111
+ now = Time.now
112
+ if(now.hour >= BBMB.config.update_hour)
113
+ day += 1
114
+ end
115
+ at = Time.local(day.year, day.month, day.day,
116
+ BBMB.config.update_hour)
117
+ secs = at - now
118
+ BBMB.logger.debug("updater") {
119
+ "sleeping %.2f seconds" % secs
120
+ }
121
+ sleep(secs)
122
+ update
123
+ }
124
+ }
125
+ end
126
+ def send_order order, customer
127
+ begin
128
+ Timeout.timeout(300) {
129
+ BBMB::Util::TargetDir.send_order(order)
130
+ }
131
+ rescue StandardError => err
132
+ err.message << " (Email: #{customer.email} - Customer-Id: #{customer.customer_id})"
133
+ BBMB::Util::Mail.notify_error(err)
134
+ end
135
+ begin
136
+ Timeout.timeout(300) {
137
+ BBMB::Util::Mail.send_order(order)
138
+ }
139
+ rescue StandardError => err
140
+ err.message << " (Email: #{customer.email} - Customer-Id: #{customer.customer_id})"
141
+ BBMB::Util::Mail.notify_error(err)
142
+ end
143
+ begin
144
+ Timeout.timeout(300) {
145
+ BBMB::Util::Mail.send_confirmation(order)
146
+ }
147
+ rescue StandardError => err
148
+ err.message << " (Email: #{customer.email} - Customer-Id: #{customer.customer_id})"
149
+ BBMB::Util::Mail.notify_error(err)
150
+ end
151
+ end
152
+ def update
153
+ Updater.run
154
+ rescue Exception => e
155
+ Mail.notify_error(e)
156
+ end
157
+ end
158
+ end
159
+ end