lucadeal 0.2.18 → 0.2.24

Sign up to get free protection for your applications and to get access to all the features.
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)