lucadeal 0.2.16 → 0.2.18
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 +9 -0
- data/README.md +40 -1
- data/exe/luca-deal +157 -80
- data/lib/luca_deal/invoice.rb +22 -0
- data/lib/luca_deal/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8159099446dcdae1b4c928d4eac5861cd35fe13f8d37155cdf28dafb30fc21e
|
4
|
+
data.tar.gz: 3c086a2ea6c4c9ec6bc9014fa9500ab9fde0a07c1778a5817fbb64e7409b5670
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a26cec96f1a0805044470f8710b36b60aacf344bad53527c2a9fd4ff64557a06836e4eefec21f083e0b51bc48a9854dbe2fdd6fed4d4754aba9fe51fa5890ce
|
7
|
+
data.tar.gz: 8a611e016833673fb1e7fcab747a24d4bfdb4152a60086791a1377d8576feb181255c8b2a0dfeca2f6807a4d11d4d2f579be6353ca62a7996a5f960d8b4f1311
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## LucaDeal 0.2.18
|
2
|
+
|
3
|
+
* Breaking change: restructure CLI in sub-sub command format.
|
4
|
+
* Add 'x-customer', 'x-editor' on export to LucaBook
|
5
|
+
|
6
|
+
## LucaDeal 0.2.17
|
7
|
+
|
8
|
+
* `luca-deal export` export JSON for LucaBook
|
9
|
+
|
1
10
|
## LucaDeal 0.2.14
|
2
11
|
|
3
12
|
* Introduce Product for selling items template.
|
data/README.md
CHANGED
@@ -22,7 +22,46 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
## Usage
|
24
24
|
|
25
|
-
|
25
|
+
You can create project skelton with `new` sub command.
|
26
|
+
|
27
|
+
```
|
28
|
+
$ luca-deal new Dir
|
29
|
+
```
|
30
|
+
|
31
|
+
Example assumes setup with bundler shim. `bundle exec` prefix may be needed in most cases.
|
32
|
+
|
33
|
+
|
34
|
+
### Manage Contract
|
35
|
+
|
36
|
+
Customer object can be created by `customer create` subcommand with name.
|
37
|
+
|
38
|
+
```
|
39
|
+
$ luca-deal customer create CustomerName
|
40
|
+
Successfully generated Customer 5976652cc2d9c0ebf4a8646f7a28aa8d6bd2d606
|
41
|
+
Edit customer detail.
|
42
|
+
```
|
43
|
+
|
44
|
+
Customer is filed under `data/customers` as YAML. Detail need to be editted.
|
45
|
+
Then, Contract object is created by `contract create` sub command with customer id.
|
46
|
+
|
47
|
+
```
|
48
|
+
$ luca-deal contract create 5976652cc2d9c0ebf4a8646f7a28aa8d6bd2d606
|
49
|
+
uccessfully generated Contract 814c6fc9fffe5566fe8e7ef683b439b355d612dc
|
50
|
+
Conditions are tentative. Edit contract detail.
|
51
|
+
```
|
52
|
+
|
53
|
+
Contract is filed under `data/contracts` as YAML. Detail need to be editted.
|
54
|
+
|
55
|
+
|
56
|
+
### Issue invoice
|
57
|
+
|
58
|
+
Monthly invoices are generated with `invoice create --monthly` sub command. Target month is optional. Without month, this month including today is the target.
|
59
|
+
|
60
|
+
```
|
61
|
+
$ luca-deal invoice create --monthly [yyyy m]
|
62
|
+
```
|
63
|
+
|
64
|
+
Invoice conditions are defined by contracts.
|
26
65
|
|
27
66
|
|
28
67
|
## Data Structure
|
data/exe/luca-deal
CHANGED
@@ -5,57 +5,102 @@ require 'date'
|
|
5
5
|
require 'optparse'
|
6
6
|
require 'luca_deal'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
8
|
+
module LucaCmd
|
9
|
+
class Customer
|
10
|
+
def self.create(args = nil, params = {})
|
11
|
+
if args
|
12
|
+
id = LucaDeal::Customer.create(name: args[0])
|
13
|
+
puts "Successfully generated Customer #{id}" if id
|
14
|
+
puts 'Edit customer detail.' if id
|
15
|
+
else
|
16
|
+
puts 'requires customer\'s name. exit'
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.delete(args = nil, params = {})
|
22
|
+
if args
|
23
|
+
id = LucaDeal::Customer.delete(args[0])
|
24
|
+
else
|
25
|
+
puts 'requires customer\'s id. exit'
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.list(args = nil, params = {})
|
31
|
+
LucaDeal::Customer.new.list_name
|
20
32
|
end
|
21
|
-
else
|
22
|
-
puts 'invalid option. --help for usage'
|
23
|
-
exit 1
|
24
33
|
end
|
25
|
-
end
|
26
34
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
class Contract
|
36
|
+
def self.create(args = nil, params = {})
|
37
|
+
if args
|
38
|
+
id = LucaDeal::Contract.new.generate!(args[0], params['category'])
|
39
|
+
puts "Successfully generated Contract #{id}" if id
|
40
|
+
puts 'Conditions are tentative. Edit contract detail.' if id
|
41
|
+
else
|
42
|
+
puts 'requires customer\'s id. exit'
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.delete(args = nil, params = {})
|
48
|
+
if args
|
49
|
+
id = LucaDeal::Contract.delete(args[0])
|
50
|
+
else
|
51
|
+
puts 'requires contract id. exit'
|
52
|
+
exit 1
|
53
|
+
end
|
37
54
|
end
|
38
|
-
else
|
39
55
|
end
|
40
|
-
end
|
41
56
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
57
|
+
class Invoice
|
58
|
+
def self.create(args = nil, params = {})
|
59
|
+
date = "#{args[0]}-#{args[1]}-#{args[2] || '1'}" if !args.empty?
|
60
|
+
case params['mode']
|
61
|
+
when 'monthly'
|
62
|
+
LucaDeal::Invoice.new(date).monthly_invoice
|
63
|
+
else
|
64
|
+
puts 'not implemented mode'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.delete(args = nil, params = {})
|
69
|
+
if args
|
70
|
+
id = LucaDeal::Invoice.delete(args[0])
|
71
|
+
else
|
72
|
+
puts 'requires contract id. exit'
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.export(args = nil, _params = nil)
|
78
|
+
if args
|
79
|
+
args << 28 if args.length == 2 # specify safe last day
|
80
|
+
LucaDeal::Invoice.new(args.join('-')).export_json
|
81
|
+
else
|
82
|
+
LucaDeal::Invoice.new.export_json
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.list(args = nil, params = {})
|
87
|
+
date = "#{args[0]}-#{args[1]}-#{args[2] || '1'}" if !args.empty?
|
88
|
+
if args.empty?
|
89
|
+
date = "#{Date.today.year}-#{Date.today.month}-1"
|
90
|
+
count = 3
|
91
|
+
end
|
92
|
+
LucaDeal::Invoice.new(date).stats(count || 1)
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.mail(args = nil, params = {})
|
96
|
+
date = "#{args[0]}-#{args[1]}-#{args[2] || '1'}" if !args.empty?
|
97
|
+
case params['mode']
|
98
|
+
when 'preview'
|
99
|
+
LucaDeal::Invoice.new(date).preview_mail
|
100
|
+
else
|
101
|
+
LucaDeal::Invoice.new(date).deliver_mail
|
102
|
+
end
|
103
|
+
end
|
59
104
|
end
|
60
105
|
end
|
61
106
|
|
@@ -65,44 +110,75 @@ end
|
|
65
110
|
|
66
111
|
LucaRecord::Base.valid_project?
|
67
112
|
cmd = ARGV.shift
|
113
|
+
params = {}
|
68
114
|
|
69
115
|
case cmd
|
70
|
-
when
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
params
|
116
|
+
when /customers?/
|
117
|
+
subcmd = ARGV.shift
|
118
|
+
case subcmd
|
119
|
+
when 'list'
|
120
|
+
OptionParser.new do |opt|
|
121
|
+
opt.banner = 'Usage: luca-deal customers list [options]'
|
122
|
+
args = opt.parse(ARGV)
|
123
|
+
LucaCmd::Customer.list(args, params)
|
78
124
|
end
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
OptionParser.new do |opt|
|
85
|
-
opt.banner = 'Usage: luca-deal contract [options]'
|
86
|
-
opt.on('--create CustomerId', 'register new contract') do |v|
|
87
|
-
params['mode'] = 'create'
|
88
|
-
params['customer_id'] = v
|
125
|
+
when 'create'
|
126
|
+
OptionParser.new do |opt|
|
127
|
+
opt.banner = 'Usage: luca-deal customers create CustomerName'
|
128
|
+
args = opt.parse(ARGV)
|
129
|
+
LucaCmd::Customer.create(args, params)
|
89
130
|
end
|
90
|
-
|
91
|
-
|
131
|
+
when 'delete'
|
132
|
+
LucaCmd::Customer.delete(ARGV)
|
133
|
+
else
|
134
|
+
puts 'Usage: luca-deal customers sub-commands'
|
135
|
+
end
|
136
|
+
when /contracts?/
|
137
|
+
subcmd = ARGV.shift
|
138
|
+
case subcmd
|
139
|
+
when 'create'
|
140
|
+
OptionParser.new do |opt|
|
141
|
+
opt.banner = 'Usage: luca-deal contracts create [options] CustomerId'
|
142
|
+
opt.on('--salesfee', 'create contract as sales fee definition') do |_v|
|
143
|
+
params['category'] = 'sales_fee'
|
144
|
+
end
|
145
|
+
args = opt.parse(ARGV)
|
146
|
+
LucaCmd::Contract.create(args, params)
|
92
147
|
end
|
93
|
-
|
94
|
-
|
148
|
+
when 'delete'
|
149
|
+
LucaCmd::Contract.delete(ARGV)
|
150
|
+
else
|
151
|
+
puts 'Usage: luca-deal contracts Subcommand'
|
95
152
|
end
|
96
|
-
when '
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
153
|
+
when 'export'
|
154
|
+
LucaCmd::Invoice.export(ARGV)
|
155
|
+
when /invoices?/, 'i'
|
156
|
+
subcmd = ARGV.shift
|
157
|
+
case subcmd
|
158
|
+
when 'create'
|
159
|
+
OptionParser.new do |opt|
|
160
|
+
opt.banner = 'Usage: luca-deal invoices create [options] year month [date]'
|
161
|
+
opt.on('--monthly', 'generate monthly data') { |v| params['mode'] = 'monthly' }
|
162
|
+
args = opt.parse(ARGV)
|
163
|
+
LucaCmd::Invoice.create(args, params)
|
164
|
+
end
|
165
|
+
when 'delete'
|
166
|
+
LucaCmd::Invoice.delete(ARGV)
|
167
|
+
when 'list'
|
168
|
+
OptionParser.new do |opt|
|
169
|
+
opt.banner = 'Usage: luca-deal invoices list [options] year month [date]'
|
170
|
+
args = opt.parse(ARGV)
|
171
|
+
LucaCmd::Invoice.list(args, params)
|
172
|
+
end
|
173
|
+
when 'mail'
|
174
|
+
OptionParser.new do |opt|
|
175
|
+
opt.banner = 'Usage: luca-deal invoices mail [options] year month [date]'
|
176
|
+
opt.on('--preview', 'send to preview user') { |v| params['mode'] = 'preview' }
|
177
|
+
args = opt.parse(ARGV)
|
178
|
+
LucaCmd::Invoice.mail(args, params)
|
179
|
+
end
|
180
|
+
else
|
181
|
+
puts 'Usage: luca-deal invoices SubCommand'
|
106
182
|
end
|
107
183
|
when 'new'
|
108
184
|
params = {}
|
@@ -112,7 +188,8 @@ when 'new'
|
|
112
188
|
end
|
113
189
|
else
|
114
190
|
puts 'Usage: luca-deal sub-command [--help|options]'
|
115
|
-
puts '
|
116
|
-
puts '
|
117
|
-
puts '
|
191
|
+
puts ' customers'
|
192
|
+
puts ' contracts'
|
193
|
+
puts ' invoices'
|
194
|
+
puts ' export'
|
118
195
|
end
|
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'
|
@@ -101,6 +102,27 @@ module LucaDeal
|
|
101
102
|
end
|
102
103
|
end
|
103
104
|
|
105
|
+
def export_json
|
106
|
+
[].tap do |res|
|
107
|
+
self.class.asof(@date.year, @date.month) do |dat|
|
108
|
+
item = {}
|
109
|
+
item['date'] = dat['issue_date']
|
110
|
+
item['debit'] = []
|
111
|
+
item['credit'] = []
|
112
|
+
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']) }
|
117
|
+
end
|
118
|
+
item['x-customer'] = dat['customer']['name'] if dat.dig('customer', 'name')
|
119
|
+
item['x-editor'] = 'LucaDeal'
|
120
|
+
res << item
|
121
|
+
end
|
122
|
+
puts JSON.dump(res)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
104
126
|
def monthly_invoice
|
105
127
|
LucaDeal::Contract.new(@date.to_s).active do |contract|
|
106
128
|
next if contract.dig('terms', 'billing_cycle') != 'monthly'
|
data/lib/luca_deal/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lucadeal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chuma Takahiro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lucarecord
|