lucadeal 0.2.16 → 0.2.23
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 +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +61 -1
- data/exe/luca-deal +387 -80
- data/lib/luca_deal/contract.rb +11 -1
- data/lib/luca_deal/customer.rb +17 -4
- data/lib/luca_deal/fee.rb +100 -34
- data/lib/luca_deal/invoice.rb +117 -46
- data/lib/luca_deal/templates/fee-report-mail.txt.erb +6 -0
- data/lib/luca_deal/templates/fee-report.html.erb +54 -0
- data/lib/luca_deal/templates/invoice-mail.txt.erb +6 -0
- data/lib/luca_deal/templates/invoice.html.erb +52 -0
- data/lib/luca_deal/templates/monthly-payment-list.html.erb +40 -0
- data/lib/luca_deal/version.rb +1 -1
- metadata +8 -3
data/lib/luca_deal/contract.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/luca_deal/customer.rb
CHANGED
@@ -12,14 +12,27 @@ module LucaDeal
|
|
12
12
|
@dirname = 'customers'
|
13
13
|
@required = ['name']
|
14
14
|
|
15
|
-
def initialize
|
15
|
+
def initialize
|
16
16
|
@date = Date.today
|
17
|
-
@pjdir = pjdir || Dir.pwd
|
18
17
|
end
|
19
18
|
|
20
19
|
def list_name
|
21
|
-
|
22
|
-
|
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,99 @@ 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
|
-
|
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
28
|
|
29
|
-
|
29
|
+
fee = { 'contract_id' => contract['id'], 'items' => [] }
|
30
|
+
fee['customer'] = get_customer(contract['customer_id'])
|
31
|
+
fee['issue_date'] = @date
|
32
|
+
Invoice.asof(@date.year, @date.month) do |invoice|
|
30
33
|
next if invoice.dig('sales_fee', 'id') != contract['id']
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
|
35
|
+
invoice['items'].each do |item|
|
36
|
+
rate = item['type'] == 'initial' ? @rate['initial'] : @rate['default']
|
37
|
+
fee['items'] << {
|
38
|
+
'invoice_id' => invoice['id'],
|
39
|
+
'customer_name' => invoice.dig('customer', 'name'),
|
40
|
+
'name' => item['name'],
|
41
|
+
'price' => item['price'],
|
42
|
+
'qty' => item['qty'],
|
43
|
+
'fee' => item['price'] * item['qty'] * rate
|
44
|
+
}
|
39
45
|
end
|
40
|
-
fee['
|
41
|
-
fee['customer'].delete('to')
|
42
|
-
fee['sales_fee'].merge! subtotal(fee['items'])
|
43
|
-
gen_fee!(fee)
|
46
|
+
fee['sales_fee'] = subtotal(fee['items'])
|
44
47
|
end
|
48
|
+
self.class.create(fee, date: @date, codes: Array(contract['id']))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def deliver_mail(attachment_type = nil, mode: nil)
|
53
|
+
attachment_type = CONFIG.dig('fee', 'attachment') || :html
|
54
|
+
fees = self.class.asof(@date.year, @date.month)
|
55
|
+
raise "No report for #{@date.year}/#{@date.month}" if fees.count.zero?
|
56
|
+
|
57
|
+
fees.each do |dat, path|
|
58
|
+
next if has_status?(dat, 'mail_delivered')
|
59
|
+
|
60
|
+
mail = compose_mail(dat, mode: mode, attachment: attachment_type.to_sym)
|
61
|
+
LucaSupport::Mail.new(mail, PJDIR).deliver
|
62
|
+
self.class.add_status!(path, 'mail_delivered')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def preview_mail(attachment_type = nil)
|
67
|
+
deliver_mail(attachment_type, mode: :preview)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Render HTML to console
|
71
|
+
#
|
72
|
+
def preview_stdout
|
73
|
+
self.class.asof(@date.year, @date.month) do |dat, _|
|
74
|
+
@company = set_company
|
75
|
+
fee_vars(dat)
|
76
|
+
puts render_report
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def compose_mail(dat, mode: nil, attachment: :html)
|
81
|
+
@company = set_company
|
82
|
+
fee_vars(dat)
|
83
|
+
|
84
|
+
mail = Mail.new
|
85
|
+
mail.to = dat.dig('customer', 'to') if mode.nil?
|
86
|
+
mail.subject = CONFIG.dig('invoice', 'mail_subject') || 'Your Report is available'
|
87
|
+
if mode == :preview
|
88
|
+
mail.cc = CONFIG.dig('mail', 'preview') || CONFIG.dig('mail', 'from')
|
89
|
+
mail.subject = '[preview] ' + mail.subject
|
90
|
+
end
|
91
|
+
mail.text_part = Mail::Part.new(body: render_erb(search_template('fee-report-mail.txt.erb')), charset: 'UTF-8')
|
92
|
+
mail.attachments[attachment_name(dat, attachment)] = render_report(attachment)
|
93
|
+
mail
|
94
|
+
end
|
95
|
+
|
96
|
+
def render_report(file_type = :html)
|
97
|
+
case file_type
|
98
|
+
when :html
|
99
|
+
render_erb(search_template('fee-report.html.erb'))
|
100
|
+
when :pdf
|
101
|
+
erb2pdf(search_template('fee-report.html.erb'))
|
102
|
+
else
|
103
|
+
raise 'This filetype is not supported.'
|
45
104
|
end
|
46
105
|
end
|
47
106
|
|
48
107
|
def get_customer(id)
|
49
108
|
{}.tap do |res|
|
50
|
-
|
109
|
+
Customer.find(id) do |dat|
|
51
110
|
customer = parse_current(dat)
|
52
111
|
res['id'] = customer['id']
|
53
112
|
res['name'] = customer.dig('name')
|
@@ -58,13 +117,19 @@ module LucaDeal
|
|
58
117
|
end
|
59
118
|
end
|
60
119
|
|
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
120
|
private
|
67
121
|
|
122
|
+
# set variables for ERB template
|
123
|
+
#
|
124
|
+
def fee_vars(fee_dat)
|
125
|
+
@customer = fee_dat['customer']
|
126
|
+
@items = readable(fee_dat['items'])
|
127
|
+
@sales_fee = readable(fee_dat['sales_fee'])
|
128
|
+
@issue_date = fee_dat['issue_date']
|
129
|
+
@due_date = fee_dat['due_date']
|
130
|
+
@amount = readable(fee_dat['sales_fee'].inject(0) { |sum, (_k, v)| sum + v })
|
131
|
+
end
|
132
|
+
|
68
133
|
def lib_path
|
69
134
|
__dir__
|
70
135
|
end
|
@@ -73,25 +138,20 @@ module LucaDeal
|
|
73
138
|
#
|
74
139
|
def set_company
|
75
140
|
{}.tap do |h|
|
76
|
-
h['name'] =
|
77
|
-
h['address'] =
|
78
|
-
h['address2'] =
|
141
|
+
h['name'] = CONFIG.dig('company', 'name')
|
142
|
+
h['address'] = CONFIG.dig('company', 'address')
|
143
|
+
h['address2'] = CONFIG.dig('company', 'address2')
|
79
144
|
end
|
80
145
|
end
|
81
146
|
|
82
147
|
# calc fee & tax amount by tax category
|
83
148
|
#
|
84
149
|
def subtotal(items)
|
85
|
-
{}.tap do |subtotal|
|
150
|
+
{ 'fee' => 0, 'tax' => 0 }.tap do |subtotal|
|
86
151
|
items.each do |i|
|
87
|
-
|
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
|
152
|
+
subtotal['fee'] += i['fee']
|
94
153
|
end
|
154
|
+
subtotal['tax'] = (subtotal['fee'] * load_tax_rate('default')).to_i
|
95
155
|
end
|
96
156
|
end
|
97
157
|
|
@@ -100,12 +160,18 @@ module LucaDeal
|
|
100
160
|
Date.new(base.year, base.month, -1)
|
101
161
|
end
|
102
162
|
|
163
|
+
# TODO: support due_date variation
|
164
|
+
def due_date(date)
|
165
|
+
next_month = date.next_month
|
166
|
+
Date.new(next_month.year, next_month.month, -1)
|
167
|
+
end
|
168
|
+
|
103
169
|
# load Tax Rate from config.
|
104
170
|
#
|
105
171
|
def load_tax_rate(name)
|
106
|
-
return 0 if
|
172
|
+
return 0 if CONFIG.dig('tax_rate', name).nil?
|
107
173
|
|
108
|
-
BigDecimal(take_current(
|
174
|
+
BigDecimal(take_current(CONFIG['tax_rate'], name).to_s)
|
109
175
|
end
|
110
176
|
|
111
177
|
def duplicated_contract?(id)
|
data/lib/luca_deal/invoice.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'luca_deal/version'
|
2
2
|
|
3
3
|
require 'mail'
|
4
|
+
require 'json'
|
4
5
|
require 'yaml'
|
5
6
|
require 'pathname'
|
6
7
|
require 'bigdecimal'
|
@@ -16,26 +17,33 @@ module LucaDeal
|
|
16
17
|
|
17
18
|
def initialize(date = nil)
|
18
19
|
@date = issue_date(date)
|
19
|
-
@pjdir = Pathname(LucaSupport::Config::Pjdir)
|
20
|
-
@config = load_config(@pjdir / 'config.yml')
|
21
20
|
end
|
22
21
|
|
23
|
-
def deliver_mail
|
24
|
-
attachment_type =
|
25
|
-
self.class.asof(@date.year, @date.month)
|
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|
|
26
28
|
next if has_status?(dat, 'mail_delivered')
|
27
29
|
|
28
|
-
mail = compose_mail(dat, attachment: attachment_type.to_sym)
|
29
|
-
LucaSupport::Mail.new(mail,
|
30
|
+
mail = compose_mail(dat, mode: mode, attachment: attachment_type.to_sym)
|
31
|
+
LucaSupport::Mail.new(mail, PJDIR).deliver
|
30
32
|
self.class.add_status!(path, 'mail_delivered')
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
36
|
def preview_mail(attachment_type = nil)
|
35
|
-
attachment_type
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
39
47
|
end
|
40
48
|
end
|
41
49
|
|
@@ -45,20 +53,27 @@ module LucaDeal
|
|
45
53
|
|
46
54
|
mail = Mail.new
|
47
55
|
mail.to = dat.dig('customer', 'to') if mode.nil?
|
48
|
-
mail.subject =
|
56
|
+
mail.subject = CONFIG.dig('invoice', 'mail_subject') || 'Your Invoice is available'
|
49
57
|
if mode == :preview
|
50
|
-
mail.cc =
|
58
|
+
mail.cc = CONFIG.dig('mail', 'preview') || CONFIG.dig('mail', 'from')
|
51
59
|
mail.subject = '[preview] ' + mail.subject
|
52
60
|
end
|
53
61
|
mail.text_part = Mail::Part.new(body: render_erb(search_template('invoice-mail.txt.erb')), charset: 'UTF-8')
|
54
|
-
|
55
|
-
mail.attachments[attachment_name(dat, attachment)] = render_erb(search_template('invoice.html.erb'))
|
56
|
-
elsif attachment == :pdf
|
57
|
-
mail.attachments[attachment_name(dat, attachment)] = erb2pdf(search_template('invoice.html.erb'))
|
58
|
-
end
|
62
|
+
mail.attachments[attachment_name(dat, attachment)] = render_invoice(attachment)
|
59
63
|
mail
|
60
64
|
end
|
61
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
|
+
|
62
77
|
# Output seriarized invoice data to stdout.
|
63
78
|
# Returns previous N months on multiple count
|
64
79
|
#
|
@@ -87,28 +102,83 @@ module LucaDeal
|
|
87
102
|
'customer' => invoice.dig('customer', 'name'),
|
88
103
|
'subtotal' => amount,
|
89
104
|
'tax' => tax,
|
90
|
-
'due' => invoice.dig('due_date')
|
105
|
+
'due' => invoice.dig('due_date'),
|
106
|
+
'mail' => invoice.dig('status')&.select { |a| a.keys.include?('mail_delivered') }&.first
|
91
107
|
}
|
92
108
|
end
|
93
109
|
stat['issue_date'] = scan_date.to_s
|
94
110
|
stat['count'] = stat['records'].count
|
95
111
|
stat['total'] = stat['records'].inject(0) { |sum, rec| sum + rec.dig('subtotal') }
|
96
112
|
stat['tax'] = stat['records'].inject(0) { |sum, rec| sum + rec.dig('tax') }
|
97
|
-
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(2).each.with_index(1) do |stat, i|
|
124
|
+
@issue_date = stat['issue_date'] if i == 1
|
125
|
+
stat['records'].each do |record|
|
126
|
+
res[record['customer']] ||= {}
|
127
|
+
res[record['customer']]['customer_name'] ||= record['customer']
|
128
|
+
res[record['customer']]["amount#{i}"] ||= record['subtotal']
|
129
|
+
res[record['customer']]["tax#{i}"] ||= record['tax']
|
130
|
+
end
|
131
|
+
end
|
132
|
+
@invoices = res.values
|
133
|
+
end
|
134
|
+
|
135
|
+
mail = Mail.new
|
136
|
+
mail.to = CONFIG.dig('mail', 'preview') || CONFIG.dig('mail', 'from')
|
137
|
+
mail.subject = 'Check monthly payment list'
|
138
|
+
mail.html_part = Mail::Part.new(body: render_erb(search_template('monthly-payment-list.html.erb')), content_type: 'text/html; charset=UTF-8')
|
139
|
+
LucaSupport::Mail.new(mail, PJDIR).deliver
|
140
|
+
end
|
141
|
+
|
142
|
+
def export_json
|
143
|
+
[].tap do |res|
|
144
|
+
self.class.asof(@date.year, @date.month) do |dat|
|
145
|
+
item = {}
|
146
|
+
item['date'] = dat['issue_date']
|
147
|
+
item['debit'] = []
|
148
|
+
item['credit'] = []
|
149
|
+
dat['subtotal'].map do |sub|
|
150
|
+
item['debit'] << { 'label' => '売掛金', 'amount' => readable(sub['items']) }
|
151
|
+
item['debit'] << { 'label' => '売掛金', 'amount' => readable(sub['tax']) }
|
152
|
+
item['credit'] << { 'label' => '売上高', 'amount' => readable(sub['items']) }
|
153
|
+
item['credit'] << { 'label' => '売上高', 'amount' => readable(sub['tax']) }
|
98
154
|
end
|
155
|
+
item['x-customer'] = dat['customer']['name'] if dat.dig('customer', 'name')
|
156
|
+
item['x-editor'] = 'LucaDeal'
|
157
|
+
res << item
|
99
158
|
end
|
100
|
-
puts
|
159
|
+
puts JSON.dump(res)
|
101
160
|
end
|
102
161
|
end
|
103
162
|
|
163
|
+
def single_invoice(contract_id)
|
164
|
+
contract = Contract.find(contract_id)
|
165
|
+
raise "Invoice already exists for #{contract_id}. exit" if duplicated_contract? contract['id']
|
166
|
+
|
167
|
+
gen_invoice!(invoice_object(contract))
|
168
|
+
end
|
169
|
+
|
104
170
|
def monthly_invoice
|
105
|
-
|
171
|
+
Contract.new(@date.to_s).active do |contract|
|
106
172
|
next if contract.dig('terms', 'billing_cycle') != 'monthly'
|
107
173
|
# TODO: provide another I/F for force re-issue if needed
|
108
174
|
next if duplicated_contract? contract['id']
|
109
175
|
|
110
|
-
|
111
|
-
|
176
|
+
gen_invoice!(invoice_object(contract))
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def invoice_object(contract)
|
181
|
+
{}.tap do |invoice|
|
112
182
|
invoice['contract_id'] = contract['id']
|
113
183
|
invoice['customer'] = get_customer(contract.dig('customer_id'))
|
114
184
|
invoice['due_date'] = due_date(@date)
|
@@ -121,25 +191,13 @@ module LucaDeal
|
|
121
191
|
item.dig('type') == 'initial' && subsequent_month?(contract.dig('terms', 'effective'))
|
122
192
|
end
|
123
193
|
invoice['subtotal'] = subtotal(invoice['items'])
|
124
|
-
|
125
|
-
gen_invoice!(invoice)
|
194
|
+
.map { |k, v| v.tap { |dat| dat['rate'] = k } }
|
126
195
|
end
|
127
196
|
end
|
128
197
|
|
129
|
-
# set variables for ERB template
|
130
|
-
#
|
131
|
-
def invoice_vars(invoice_dat)
|
132
|
-
@customer = invoice_dat['customer']
|
133
|
-
@items = invoice_dat['items']
|
134
|
-
@subtotal = invoice_dat['subtotal']
|
135
|
-
@issue_date = invoice_dat['issue_date']
|
136
|
-
@due_date = invoice_dat['due_date']
|
137
|
-
@amount = @subtotal.inject(0) { |sum, i| sum + i['items'] + i['tax'] }
|
138
|
-
end
|
139
|
-
|
140
198
|
def get_customer(id)
|
141
199
|
{}.tap do |res|
|
142
|
-
|
200
|
+
Customer.find(id) do |dat|
|
143
201
|
customer = parse_current(dat)
|
144
202
|
res['id'] = customer['id']
|
145
203
|
res['name'] = customer.dig('name')
|
@@ -155,7 +213,7 @@ module LucaDeal
|
|
155
213
|
|
156
214
|
[].tap do |res|
|
157
215
|
products.each do |product|
|
158
|
-
|
216
|
+
Product.find(product['id'])['items'].each do |item|
|
159
217
|
item['product_id'] = product['id']
|
160
218
|
item['qty'] ||= 1
|
161
219
|
res << item
|
@@ -176,11 +234,23 @@ module LucaDeal
|
|
176
234
|
|
177
235
|
# TODO: support due_date variation
|
178
236
|
def due_date(date)
|
179
|
-
|
237
|
+
next_month = date.next_month
|
238
|
+
Date.new(next_month.year, next_month.month, -1)
|
180
239
|
end
|
181
240
|
|
182
241
|
private
|
183
242
|
|
243
|
+
# set variables for ERB template
|
244
|
+
#
|
245
|
+
def invoice_vars(invoice_dat)
|
246
|
+
@customer = invoice_dat['customer']
|
247
|
+
@items = readable(invoice_dat['items'])
|
248
|
+
@subtotal = readable(invoice_dat['subtotal'])
|
249
|
+
@issue_date = invoice_dat['issue_date']
|
250
|
+
@due_date = invoice_dat['due_date']
|
251
|
+
@amount = readable(invoice_dat['subtotal'].inject(0) { |sum, i| sum + i['items'] + i['tax'] })
|
252
|
+
end
|
253
|
+
|
184
254
|
def lib_path
|
185
255
|
__dir__
|
186
256
|
end
|
@@ -189,9 +259,9 @@ module LucaDeal
|
|
189
259
|
#
|
190
260
|
def set_company
|
191
261
|
{}.tap do |h|
|
192
|
-
h['name'] =
|
193
|
-
h['address'] =
|
194
|
-
h['address2'] =
|
262
|
+
h['name'] = CONFIG.dig('company', 'name')
|
263
|
+
h['address'] = CONFIG.dig('company', 'address')
|
264
|
+
h['address2'] = CONFIG.dig('company', 'address2')
|
195
265
|
end
|
196
266
|
end
|
197
267
|
|
@@ -214,13 +284,14 @@ module LucaDeal
|
|
214
284
|
# load Tax Rate from config.
|
215
285
|
#
|
216
286
|
def load_tax_rate(name)
|
217
|
-
return 0 if
|
287
|
+
return 0 if CONFIG.dig('tax_rate', name).nil?
|
218
288
|
|
219
|
-
BigDecimal(take_current(
|
289
|
+
BigDecimal(take_current(CONFIG['tax_rate'], name).to_s)
|
220
290
|
end
|
221
291
|
|
222
292
|
def attachment_name(dat, type)
|
223
|
-
|
293
|
+
id = %r{/}.match(dat['id']) ? dat['id'].gsub('/', '') : dat['id'][0, 7]
|
294
|
+
"invoice-#{id}.#{type}"
|
224
295
|
end
|
225
296
|
|
226
297
|
def duplicated_contract?(id)
|