lucadeal 0.2.18 → 0.2.24

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.
data/lib/luca_deal.rb CHANGED
@@ -8,6 +8,7 @@ module LucaDeal
8
8
  autoload :Contract, 'luca_deal/contract'
9
9
  autoload :Fee, 'luca_deal/fee'
10
10
  autoload :Invoice, 'luca_deal/invoice'
11
+ autoload :NoInvoice, 'luca_deal/no_invoice'
11
12
  autoload :Product, 'luca_deal/product'
12
13
  autoload :Setup, 'luca_deal/setup'
13
14
  end
@@ -43,8 +43,18 @@ module LucaDeal
43
43
  end
44
44
  end
45
45
 
46
+ def describe(id)
47
+ contract = parse_current(self.class.find(id))
48
+ if contract['products']
49
+ contract['products'] = contract['products'].map do |product|
50
+ Product.find(product['id'])
51
+ end
52
+ end
53
+ readable(contract)
54
+ end
55
+
46
56
  def generate!(customer_id, mode = 'subscription')
47
- LucaDeal::Customer.find(customer_id) do |customer|
57
+ Customer.find(customer_id) do |customer|
48
58
  current_customer = parse_current(customer)
49
59
  if mode == 'sales_fee'
50
60
  obj = salesfee_template
@@ -12,14 +12,27 @@ module LucaDeal
12
12
  @dirname = 'customers'
13
13
  @required = ['name']
14
14
 
15
- def initialize(pjdir = nil)
15
+ def initialize
16
16
  @date = Date.today
17
- @pjdir = pjdir || Dir.pwd
18
17
  end
19
18
 
20
19
  def list_name
21
- list = self.class.all.map { |dat| parse_current(dat) }
22
- YAML.dump(list).tap { |l| puts l }
20
+ self.class.all.map { |dat| parse_current(dat).sort.to_h }
21
+ end
22
+
23
+ def describe(id)
24
+ customer = parse_current(self.class.find(id))
25
+ contracts = Contract.all.select { |contract| contract['customer_id'] == customer['id'] }
26
+ if !contracts.empty?
27
+ customer['contracts'] = contracts.map do |c|
28
+ {
29
+ 'id' => c['id'],
30
+ 'effective' => c['terms']['effective'],
31
+ 'defunct' => c['terms']['defunct']
32
+ }
33
+ end
34
+ end
35
+ readable(customer)
23
36
  end
24
37
 
25
38
  def self.create(obj)
data/lib/luca_deal/fee.rb CHANGED
@@ -14,40 +14,145 @@ module LucaDeal
14
14
 
15
15
  def initialize(date = nil)
16
16
  @date = issue_date(date)
17
- @config = load_config('config.yml')
18
17
  end
19
18
 
20
19
  # calculate fee, based on invoices
21
20
  #
22
21
  def monthly_fee
23
- LucaDeal::Contract.asof(@date.year, @date.month, @date.day) do |contract|
22
+ Contract.asof(@date.year, @date.month, @date.day) do |contract|
24
23
  next if contract.dig('terms', 'category') != 'sales_fee'
24
+ next if duplicated_contract? contract['id']
25
25
 
26
26
  @rate = { 'default' => BigDecimal(contract.dig('rate', 'default')) }
27
27
  @rate['initial'] = contract.dig('rate', 'initial') ? BigDecimal(contract.dig('rate', 'initial')) : @rate['default']
28
+ limit = contract.dig('terms', 'limit')
28
29
 
29
- LucaDeal::Invoice.asof(@date.year, @date.month) do |invoice|
30
+ fee = { 'contract_id' => contract['id'], 'items' => [] }
31
+ fee['customer'] = get_customer(contract['customer_id'])
32
+ fee['issue_date'] = @date
33
+ Invoice.asof(@date.year, @date.month) do |invoice|
30
34
  next if invoice.dig('sales_fee', 'id') != contract['id']
31
- next if duplicated_contract? invoice['contract_id']
35
+ next if exceed_limit?(invoice, limit)
32
36
 
33
- fee = invoice.dup
34
- fee['invoice'] = {}.tap do |f_invoice|
35
- %w[id contract_id issue_date due_date].each do |i|
36
- f_invoice[i] = invoice[i]
37
- fee.delete i
37
+ invoice['items'].each do |item|
38
+ rate = item['type'] == 'initial' ? @rate['initial'] : @rate['default']
39
+ fee['items'] << fee_record(invoice, item, rate)
40
+ end
41
+ fee['sales_fee'] = subtotal(fee['items'])
42
+ end
43
+ NoInvoice.asof(@date.year, @date.month) do |no_invoice|
44
+ next if no_invoice.dig('sales_fee', 'id') != contract['id']
45
+ next if exceed_limit?(invoice, limit)
46
+
47
+ no_invoice['items'].each do |item|
48
+ rate = item['type'] == 'initial' ? @rate['initial'] : @rate['default']
49
+ fee['items'] << fee_record(no_invoice, item, rate)
50
+ end
51
+ fee['sales_fee'] = subtotal(fee['items'])
52
+ end
53
+ self.class.create(fee, date: @date, codes: Array(contract['id']))
54
+ end
55
+ end
56
+
57
+ def deliver_mail(attachment_type = nil, mode: nil)
58
+ attachment_type = CONFIG.dig('fee', 'attachment') || :html
59
+ fees = self.class.asof(@date.year, @date.month)
60
+ raise "No report for #{@date.year}/#{@date.month}" if fees.count.zero?
61
+
62
+ fees.each do |dat, path|
63
+ next if has_status?(dat, 'mail_delivered')
64
+
65
+ mail = compose_mail(dat, mode: mode, attachment: attachment_type.to_sym)
66
+ LucaSupport::Mail.new(mail, PJDIR).deliver
67
+ self.class.add_status!(path, 'mail_delivered')
68
+ end
69
+ end
70
+
71
+ def preview_mail(attachment_type = nil)
72
+ deliver_mail(attachment_type, mode: :preview)
73
+ end
74
+
75
+ # Render HTML to console
76
+ #
77
+ def preview_stdout
78
+ self.class.asof(@date.year, @date.month) do |dat, _|
79
+ @company = set_company
80
+ fee_vars(dat)
81
+ puts render_report
82
+ end
83
+ end
84
+
85
+ def compose_mail(dat, mode: nil, attachment: :html)
86
+ @company = set_company
87
+ fee_vars(dat)
88
+
89
+ mail = Mail.new
90
+ mail.to = dat.dig('customer', 'to') if mode.nil?
91
+ mail.subject = CONFIG.dig('invoice', 'mail_subject') || 'Your Report is available'
92
+ if mode == :preview
93
+ mail.cc = CONFIG.dig('mail', 'preview') || CONFIG.dig('mail', 'from')
94
+ mail.subject = '[preview] ' + mail.subject
95
+ end
96
+ mail.text_part = Mail::Part.new(body: render_erb(search_template('fee-report-mail.txt.erb')), charset: 'UTF-8')
97
+ mail.attachments[attachment_name(dat, attachment)] = render_report(attachment)
98
+ mail
99
+ end
100
+
101
+ # Output seriarized fee data to stdout.
102
+ # Returns previous N months on multiple count
103
+ #
104
+ # === Example YAML output
105
+ # ---
106
+ # - records:
107
+ # - customer: Example Co.
108
+ # subtotal: 100000
109
+ # tax: 10000
110
+ # due: 2020-10-31
111
+ # issue_date: '2020-09-30'
112
+ # count: 1
113
+ # total: 100000
114
+ # tax: 10000
115
+ #
116
+ def stats(count = 1)
117
+ [].tap do |collection|
118
+ scan_date = @date.next_month
119
+ count.times do
120
+ scan_date = scan_date.prev_month
121
+ {}.tap do |stat|
122
+ stat['records'] = self.class.asof(scan_date.year, scan_date.month).map do |fee|
123
+ {
124
+ 'customer' => fee.dig('customer', 'name'),
125
+ 'client' => fee['items'].map{ |item| item.dig('customer_name') }.join(' / '),
126
+ 'subtotal' => fee.dig('sales_fee', 'fee'),
127
+ 'tax' => fee.dig('sales_fee', 'tax'),
128
+ 'due' => fee.dig('due_date'),
129
+ 'mail' => fee.dig('status')&.select { |a| a.keys.include?('mail_delivered') }&.first
130
+ }
38
131
  end
132
+ stat['issue_date'] = scan_date.to_s
133
+ stat['count'] = stat['records'].count
134
+ stat['total'] = stat['records'].inject(0) { |sum, rec| sum + rec.dig('subtotal') }
135
+ stat['tax'] = stat['records'].inject(0) { |sum, rec| sum + rec.dig('tax') }
136
+ collection << readable(stat)
39
137
  end
40
- fee['id'] = issue_random_id
41
- fee['customer'].delete('to')
42
- fee['sales_fee'].merge! subtotal(fee['items'])
43
- gen_fee!(fee)
44
138
  end
45
139
  end
46
140
  end
47
141
 
142
+ def render_report(file_type = :html)
143
+ case file_type
144
+ when :html
145
+ render_erb(search_template('fee-report.html.erb'))
146
+ when :pdf
147
+ erb2pdf(search_template('fee-report.html.erb'))
148
+ else
149
+ raise 'This filetype is not supported.'
150
+ end
151
+ end
152
+
48
153
  def get_customer(id)
49
154
  {}.tap do |res|
50
- LucaDeal::Customer.find(id) do |dat|
155
+ Customer.find(id) do |dat|
51
156
  customer = parse_current(dat)
52
157
  res['id'] = customer['id']
53
158
  res['name'] = customer.dig('name')
@@ -58,13 +163,19 @@ module LucaDeal
58
163
  end
59
164
  end
60
165
 
61
- def gen_fee!(fee)
62
- id = fee.dig('invoice', 'contract_id')
63
- self.class.create(fee, date: @date, codes: Array(id))
64
- end
65
-
66
166
  private
67
167
 
168
+ # set variables for ERB template
169
+ #
170
+ def fee_vars(fee_dat)
171
+ @customer = fee_dat['customer']
172
+ @items = readable(fee_dat['items'])
173
+ @sales_fee = readable(fee_dat['sales_fee'])
174
+ @issue_date = fee_dat['issue_date']
175
+ @due_date = fee_dat['due_date']
176
+ @amount = readable(fee_dat['sales_fee'].inject(0) { |sum, (_k, v)| sum + v })
177
+ end
178
+
68
179
  def lib_path
69
180
  __dir__
70
181
  end
@@ -73,25 +184,20 @@ module LucaDeal
73
184
  #
74
185
  def set_company
75
186
  {}.tap do |h|
76
- h['name'] = @config.dig('company', 'name')
77
- h['address'] = @config.dig('company', 'address')
78
- h['address2'] = @config.dig('company', 'address2')
187
+ h['name'] = CONFIG.dig('company', 'name')
188
+ h['address'] = CONFIG.dig('company', 'address')
189
+ h['address2'] = CONFIG.dig('company', 'address2')
79
190
  end
80
191
  end
81
192
 
82
193
  # calc fee & tax amount by tax category
83
194
  #
84
195
  def subtotal(items)
85
- {}.tap do |subtotal|
196
+ { 'fee' => 0, 'tax' => 0 }.tap do |subtotal|
86
197
  items.each do |i|
87
- rate = i.dig('type') || 'default'
88
- subtotal[rate] = { 'fee' => 0, 'tax' => 0 } if subtotal.dig(rate).nil?
89
- subtotal[rate]['fee'] += i['qty'] * i['price'] * @rate[rate]
90
- end
91
- subtotal.each do |rate, amount|
92
- amount['tax'] = (amount['fee'] * load_tax_rate(rate)).to_i
93
- amount['fee'] = amount['fee'].to_i
198
+ subtotal['fee'] += i['fee']
94
199
  end
200
+ subtotal['tax'] = (subtotal['fee'] * load_tax_rate('default')).to_i
95
201
  end
96
202
  end
97
203
 
@@ -100,19 +206,46 @@ module LucaDeal
100
206
  Date.new(base.year, base.month, -1)
101
207
  end
102
208
 
209
+ # TODO: support due_date variation
210
+ def due_date(date)
211
+ next_month = date.next_month
212
+ Date.new(next_month.year, next_month.month, -1)
213
+ end
214
+
103
215
  # load Tax Rate from config.
104
216
  #
105
217
  def load_tax_rate(name)
106
- return 0 if @config.dig('tax_rate', name).nil?
218
+ return 0 if CONFIG.dig('tax_rate', name).nil?
107
219
 
108
- BigDecimal(take_current(@config['tax_rate'], name).to_s)
220
+ BigDecimal(take_current(CONFIG['tax_rate'], name).to_s)
109
221
  end
110
222
 
223
+ # Fees are unique contract_id in each month
224
+ # If update needed, remove the target fee file.
225
+ #
111
226
  def duplicated_contract?(id)
112
227
  self.class.asof(@date.year, @date.month, @date.day) do |_f, path|
113
228
  return true if path.include?(id)
114
229
  end
115
230
  false
116
231
  end
232
+
233
+ def fee_record(invoice, item, rate)
234
+ {
235
+ 'invoice_id' => invoice['id'],
236
+ 'customer_name' => invoice.dig('customer', 'name'),
237
+ 'name' => item['name'],
238
+ 'price' => item['price'],
239
+ 'qty' => item['qty'],
240
+ 'fee' => item['price'] * item['qty'] * rate
241
+ }
242
+ end
243
+
244
+ def exceed_limit?(invoice, limit)
245
+ return false if limit.nil?
246
+
247
+ contract_start = Contract.find(invoice['contract_id']).dig('terms', 'effective')
248
+ contract_start.next_month(limit).prev_day < @date
249
+ end
117
250
  end
118
251
  end
@@ -17,26 +17,33 @@ module LucaDeal
17
17
 
18
18
  def initialize(date = nil)
19
19
  @date = issue_date(date)
20
- @pjdir = Pathname(LucaSupport::Config::Pjdir)
21
- @config = load_config(@pjdir / 'config.yml')
22
20
  end
23
21
 
24
- def deliver_mail
25
- attachment_type = @config.dig('invoice', 'attachment') || :html
26
- self.class.asof(@date.year, @date.month) do |dat, path|
22
+ def deliver_mail(attachment_type = nil, mode: nil)
23
+ attachment_type = CONFIG.dig('invoice', 'attachment') || :html
24
+ invoices = self.class.asof(@date.year, @date.month)
25
+ raise "No invoice for #{@date.year}/#{@date.month}" if invoices.count.zero?
26
+
27
+ invoices.each do |dat, path|
27
28
  next if has_status?(dat, 'mail_delivered')
28
29
 
29
- mail = compose_mail(dat, attachment: attachment_type.to_sym)
30
- LucaSupport::Mail.new(mail, @pjdir).deliver
30
+ mail = compose_mail(dat, mode: mode, attachment: attachment_type.to_sym)
31
+ LucaSupport::Mail.new(mail, PJDIR).deliver
31
32
  self.class.add_status!(path, 'mail_delivered')
32
33
  end
33
34
  end
34
35
 
35
36
  def preview_mail(attachment_type = nil)
36
- attachment_type ||= @config.dig('invoice', 'attachment') || :html
37
- self.class.asof(@date.year, @date.month) do |dat, _path|
38
- mail = compose_mail(dat, mode: :preview, attachment: attachment_type.to_sym)
39
- LucaSupport::Mail.new(mail, @pjdir).deliver
37
+ deliver_mail(attachment_type, mode: :preview)
38
+ end
39
+
40
+ # Render HTML to console
41
+ #
42
+ def preview_stdout
43
+ self.class.asof(@date.year, @date.month) do |dat, _|
44
+ @company = set_company
45
+ invoice_vars(dat)
46
+ puts render_invoice
40
47
  end
41
48
  end
42
49
 
@@ -46,20 +53,27 @@ module LucaDeal
46
53
 
47
54
  mail = Mail.new
48
55
  mail.to = dat.dig('customer', 'to') if mode.nil?
49
- mail.subject = @config.dig('invoice', 'mail_subject') || 'Your Invoice is available'
56
+ mail.subject = CONFIG.dig('invoice', 'mail_subject') || 'Your Invoice is available'
50
57
  if mode == :preview
51
- mail.cc = @config.dig('mail', 'preview') || @config.dig('mail', 'from')
58
+ mail.cc = CONFIG.dig('mail', 'preview') || CONFIG.dig('mail', 'from')
52
59
  mail.subject = '[preview] ' + mail.subject
53
60
  end
54
61
  mail.text_part = Mail::Part.new(body: render_erb(search_template('invoice-mail.txt.erb')), charset: 'UTF-8')
55
- if attachment == :html
56
- mail.attachments[attachment_name(dat, attachment)] = render_erb(search_template('invoice.html.erb'))
57
- elsif attachment == :pdf
58
- mail.attachments[attachment_name(dat, attachment)] = erb2pdf(search_template('invoice.html.erb'))
59
- end
62
+ mail.attachments[attachment_name(dat, attachment)] = render_invoice(attachment)
60
63
  mail
61
64
  end
62
65
 
66
+ def render_invoice(file_type = :html)
67
+ case file_type
68
+ when :html
69
+ render_erb(search_template('invoice.html.erb'))
70
+ when :pdf
71
+ erb2pdf(search_template('invoice.html.erb'))
72
+ else
73
+ raise 'This filetype is not supported.'
74
+ end
75
+ end
76
+
63
77
  # Output seriarized invoice data to stdout.
64
78
  # Returns previous N months on multiple count
65
79
  #
@@ -88,18 +102,47 @@ module LucaDeal
88
102
  'customer' => invoice.dig('customer', 'name'),
89
103
  'subtotal' => amount,
90
104
  'tax' => tax,
91
- 'due' => invoice.dig('due_date')
105
+ 'due' => invoice.dig('due_date'),
106
+ 'mail' => invoice.dig('status')&.select { |a| a.keys.include?('mail_delivered') }&.first
92
107
  }
93
108
  end
94
109
  stat['issue_date'] = scan_date.to_s
95
110
  stat['count'] = stat['records'].count
96
111
  stat['total'] = stat['records'].inject(0) { |sum, rec| sum + rec.dig('subtotal') }
97
112
  stat['tax'] = stat['records'].inject(0) { |sum, rec| sum + rec.dig('tax') }
98
- collection << stat
113
+ collection << readable(stat)
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ # send payment list to preview address or from address.
120
+ #
121
+ def stats_email
122
+ {}.tap do |res|
123
+ stats(3).each.with_index(1) do |stat, i|
124
+ stat['records'].each do |record|
125
+ res[record['customer']] ||= {}
126
+ res[record['customer']]['customer_name'] ||= record['customer']
127
+ res[record['customer']]["amount#{i}"] ||= record['subtotal']
128
+ res[record['customer']]["tax#{i}"] ||= record['tax']
129
+ end
130
+ if i == 1
131
+ @issue_date = stat['issue_date']
132
+ @total_amount = stat['total']
133
+ @total_tax = stat['tax']
134
+ @total_count = stat['count']
99
135
  end
100
136
  end
101
- puts YAML.dump(LucaSupport::Code.readable(collection))
137
+ @invoices = res.values
102
138
  end
139
+ @company = CONFIG.dig('company', 'name')
140
+
141
+ mail = Mail.new
142
+ mail.to = CONFIG.dig('mail', 'preview') || CONFIG.dig('mail', 'from')
143
+ mail.subject = 'Check monthly payment list'
144
+ mail.html_part = Mail::Part.new(body: render_erb(search_template('monthly-payment-list.html.erb')), content_type: 'text/html; charset=UTF-8')
145
+ LucaSupport::Mail.new(mail, PJDIR).deliver
103
146
  end
104
147
 
105
148
  def export_json
@@ -110,10 +153,10 @@ module LucaDeal
110
153
  item['debit'] = []
111
154
  item['credit'] = []
112
155
  dat['subtotal'].map do |sub|
113
- item['debit'] << { 'label' => '売掛金', 'value' => LucaSupport::Code.readable(sub['items']) }
114
- item['debit'] << { 'label' => '売掛金', 'value' => LucaSupport::Code.readable(sub['tax']) }
115
- item['credit'] << { 'label' => '売上高', 'value' => LucaSupport::Code.readable(sub['items']) }
116
- item['credit'] << { 'label' => '売上高', 'value' => LucaSupport::Code.readable(sub['tax']) }
156
+ item['debit'] << { 'label' => '売掛金', 'amount' => readable(sub['items']) }
157
+ item['debit'] << { 'label' => '売掛金', 'amount' => readable(sub['tax']) }
158
+ item['credit'] << { 'label' => '売上高', 'amount' => readable(sub['items']) }
159
+ item['credit'] << { 'label' => '売上高', 'amount' => readable(sub['tax']) }
117
160
  end
118
161
  item['x-customer'] = dat['customer']['name'] if dat.dig('customer', 'name')
119
162
  item['x-editor'] = 'LucaDeal'
@@ -123,14 +166,25 @@ module LucaDeal
123
166
  end
124
167
  end
125
168
 
126
- def monthly_invoice
127
- LucaDeal::Contract.new(@date.to_s).active do |contract|
128
- next if contract.dig('terms', 'billing_cycle') != 'monthly'
169
+ def single_invoice(contract_id)
170
+ contract = Contract.find(contract_id)
171
+ raise "Invoice already exists for #{contract_id}. exit" if duplicated_contract? contract['id']
172
+
173
+ gen_invoice!(invoice_object(contract))
174
+ end
175
+
176
+ def monthly_invoice(target = 'monthly')
177
+ Contract.new(@date.to_s).active do |contract|
178
+ next if contract.dig('terms', 'billing_cycle') != target
129
179
  # TODO: provide another I/F for force re-issue if needed
130
180
  next if duplicated_contract? contract['id']
131
181
 
132
- invoice = {}
133
- invoice['id'] = issue_random_id
182
+ gen_invoice!(invoice_object(contract))
183
+ end
184
+ end
185
+
186
+ def invoice_object(contract)
187
+ {}.tap do |invoice|
134
188
  invoice['contract_id'] = contract['id']
135
189
  invoice['customer'] = get_customer(contract.dig('customer_id'))
136
190
  invoice['due_date'] = due_date(@date)
@@ -143,25 +197,13 @@ module LucaDeal
143
197
  item.dig('type') == 'initial' && subsequent_month?(contract.dig('terms', 'effective'))
144
198
  end
145
199
  invoice['subtotal'] = subtotal(invoice['items'])
146
- .map { |k, v| v.tap { |dat| dat['rate'] = k } }
147
- gen_invoice!(invoice)
200
+ .map { |k, v| v.tap { |dat| dat['rate'] = k } }
148
201
  end
149
202
  end
150
203
 
151
- # set variables for ERB template
152
- #
153
- def invoice_vars(invoice_dat)
154
- @customer = invoice_dat['customer']
155
- @items = invoice_dat['items']
156
- @subtotal = invoice_dat['subtotal']
157
- @issue_date = invoice_dat['issue_date']
158
- @due_date = invoice_dat['due_date']
159
- @amount = @subtotal.inject(0) { |sum, i| sum + i['items'] + i['tax'] }
160
- end
161
-
162
204
  def get_customer(id)
163
205
  {}.tap do |res|
164
- LucaDeal::Customer.find(id) do |dat|
206
+ Customer.find(id) do |dat|
165
207
  customer = parse_current(dat)
166
208
  res['id'] = customer['id']
167
209
  res['name'] = customer.dig('name')
@@ -177,7 +219,7 @@ module LucaDeal
177
219
 
178
220
  [].tap do |res|
179
221
  products.each do |product|
180
- LucaDeal::Product.find(product['id'])['items'].each do |item|
222
+ Product.find(product['id'])['items'].each do |item|
181
223
  item['product_id'] = product['id']
182
224
  item['qty'] ||= 1
183
225
  res << item
@@ -198,11 +240,23 @@ module LucaDeal
198
240
 
199
241
  # TODO: support due_date variation
200
242
  def due_date(date)
201
- Date.new(date.year, date.month + 1, -1)
243
+ next_month = date.next_month
244
+ Date.new(next_month.year, next_month.month, -1)
202
245
  end
203
246
 
204
247
  private
205
248
 
249
+ # set variables for ERB template
250
+ #
251
+ def invoice_vars(invoice_dat)
252
+ @customer = invoice_dat['customer']
253
+ @items = readable(invoice_dat['items'])
254
+ @subtotal = readable(invoice_dat['subtotal'])
255
+ @issue_date = invoice_dat['issue_date']
256
+ @due_date = invoice_dat['due_date']
257
+ @amount = readable(invoice_dat['subtotal'].inject(0) { |sum, i| sum + i['items'] + i['tax'] })
258
+ end
259
+
206
260
  def lib_path
207
261
  __dir__
208
262
  end
@@ -211,9 +265,9 @@ module LucaDeal
211
265
  #
212
266
  def set_company
213
267
  {}.tap do |h|
214
- h['name'] = @config.dig('company', 'name')
215
- h['address'] = @config.dig('company', 'address')
216
- h['address2'] = @config.dig('company', 'address2')
268
+ h['name'] = CONFIG.dig('company', 'name')
269
+ h['address'] = CONFIG.dig('company', 'address')
270
+ h['address2'] = CONFIG.dig('company', 'address2')
217
271
  end
218
272
  end
219
273
 
@@ -236,13 +290,14 @@ module LucaDeal
236
290
  # load Tax Rate from config.
237
291
  #
238
292
  def load_tax_rate(name)
239
- return 0 if @config.dig('tax_rate', name).nil?
293
+ return 0 if CONFIG.dig('tax_rate', name).nil?
240
294
 
241
- BigDecimal(take_current(@config['tax_rate'], name).to_s)
295
+ BigDecimal(take_current(CONFIG['tax_rate'], name).to_s)
242
296
  end
243
297
 
244
298
  def attachment_name(dat, type)
245
- "invoice-#{dat.dig('id')[0, 7]}.#{type}"
299
+ id = %r{/}.match(dat['id']) ? dat['id'].gsub('/', '') : dat['id'][0, 7]
300
+ "invoice-#{id}.#{type}"
246
301
  end
247
302
 
248
303
  def duplicated_contract?(id)