lucasalary 0.1.24 → 0.1.27
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 +12 -0
- data/exe/luca-salary +32 -4
- data/lib/luca_salary/accumulator.rb +26 -0
- data/lib/luca_salary/base.rb +3 -1
- data/lib/luca_salary/payment.rb +30 -15
- data/lib/luca_salary/state.rb +53 -0
- data/lib/luca_salary/total.rb +21 -0
- data/lib/luca_salary/version.rb +1 -1
- data/lib/luca_salary.rb +3 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21cf8c51a5487b6c97376fe3ce9093dca20a7dc00943101f023ddf883bb20bf3
|
4
|
+
data.tar.gz: 427756bed92e1878f48763decf1924a475e3f70163f0a68fd48efd767c224a8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12943976db746cb20edb83d007efdd94a4ed69f11f05dd5fc3970e778955c199a1c713223e16106df5e58deea659e91630525144d40215f9aa731750147bd4c5
|
7
|
+
data.tar.gz: de251e1584866528cecde0dc2c76fd5da91c344622cb63f3d281fb9516a75958d2d5d1ab2ee7770c97452572c6847c1064cc5febc0be7f81f7dc55691fac72b8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## LucaSalary 0.1.27
|
2
|
+
|
3
|
+
* Implement LucaSalary::Total for Year totaling.
|
4
|
+
|
5
|
+
## LucaSalary 0.1.26
|
6
|
+
|
7
|
+
* Add `luca-salary payments report`: monthly statement by code.
|
8
|
+
|
9
|
+
## LucaSalary 0.1.25
|
10
|
+
|
11
|
+
* Add `luca-salary payments total --adjust`: applying yearly tax refund.
|
12
|
+
|
1
13
|
## LucaSalary 0.1.24
|
2
14
|
|
3
15
|
* Fix: remove null record from `luca-salary export` JSON
|
data/exe/luca-salary
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
require 'json'
|
4
5
|
require 'optparse'
|
5
6
|
require 'luca_salary'
|
6
7
|
require 'luca_salary/monthly'
|
@@ -40,8 +41,27 @@ module LucaCmd
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
|
-
def self.
|
44
|
-
|
44
|
+
def self.report(args = nil, params = nil)
|
45
|
+
render(LucaSalary::State.range(*args).report(), params)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.total(args = nil, params = nil)
|
49
|
+
if params['mode'] == 'adjust'
|
50
|
+
LucaSalary::Payment.year_adjust(args[0].to_i, args[1].to_i)
|
51
|
+
else
|
52
|
+
LucaSalary::Payment.year_total(args.first.to_i)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.render(dat, params)
|
57
|
+
case params[:output]
|
58
|
+
when 'json'
|
59
|
+
puts JSON.dump(dat)
|
60
|
+
when 'nu'
|
61
|
+
LucaSupport::View.nushell(YAML.dump(dat))
|
62
|
+
else
|
63
|
+
puts YAML.dump(dat)
|
64
|
+
end
|
45
65
|
end
|
46
66
|
end
|
47
67
|
end
|
@@ -84,11 +104,19 @@ when /payments?/
|
|
84
104
|
args = opt.parse(ARGV)
|
85
105
|
LucaCmd::Payment.list(args, params)
|
86
106
|
end
|
107
|
+
when 'report'
|
108
|
+
OptionParser.new do |opt|
|
109
|
+
opt.banner = 'Usage: luca-salary payments report [--nu] year month [year month]'
|
110
|
+
opt.on('--nu', 'show table in nushell') { |_v| params[:output] = 'nu' }
|
111
|
+
args = opt.parse(ARGV)
|
112
|
+
LucaCmd::Payment.report(args, params)
|
113
|
+
end
|
87
114
|
when 'total'
|
88
115
|
OptionParser.new do |opt|
|
89
|
-
opt.banner = 'Usage: luca-salary payments total year'
|
116
|
+
opt.banner = 'Usage: luca-salary payments total [--adjust] year [month]'
|
117
|
+
opt.on('--adjust', 'Apply year total adjustment to payslip of year/month') { |_v| params['mode'] = 'adjust' }
|
90
118
|
args = opt.parse(ARGV)
|
91
|
-
LucaCmd::Payment.total(args)
|
119
|
+
LucaCmd::Payment.total(args, params)
|
92
120
|
end
|
93
121
|
else
|
94
122
|
puts 'Proper subcommand needed.'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module LucaSalary
|
4
|
+
module Accumulator
|
5
|
+
def self.included(klass) #:nodoc:
|
6
|
+
klass.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def accumulate(records)
|
11
|
+
count = 0
|
12
|
+
result = records.each_with_object({}) do |record, result|
|
13
|
+
count += 1
|
14
|
+
record
|
15
|
+
.select { |k, _v| /^[1-4][0-9A-Fa-f]{,3}$/.match(k) }
|
16
|
+
.each do |k, v|
|
17
|
+
next if v.nil?
|
18
|
+
|
19
|
+
result[k] = result[k] ? result[k] + v : v
|
20
|
+
end
|
21
|
+
end
|
22
|
+
[result, count]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/luca_salary/base.rb
CHANGED
@@ -45,7 +45,9 @@ module LucaSalary
|
|
45
45
|
|
46
46
|
def self.sum_code(obj, code, exclude = nil)
|
47
47
|
target = obj.select { |k, _v| /^#{code}[0-9A-Fa-f]{,3}$/.match(k) }
|
48
|
-
target = target
|
48
|
+
target = target
|
49
|
+
.reject { |_k, v| v.nil? }
|
50
|
+
.reject { |k, _v| exclude&.include?(k) }
|
49
51
|
target.values.inject(:+) || 0
|
50
52
|
end
|
51
53
|
|
data/lib/luca_salary/payment.rb
CHANGED
@@ -9,6 +9,8 @@ require 'luca_record'
|
|
9
9
|
|
10
10
|
module LucaSalary
|
11
11
|
class Payment < LucaRecord::Base
|
12
|
+
include Accumulator
|
13
|
+
|
12
14
|
@dirname = 'payments'
|
13
15
|
|
14
16
|
def initialize(date = nil)
|
@@ -47,21 +49,9 @@ module LucaSalary
|
|
47
49
|
def self.year_total(year)
|
48
50
|
Profile.all do |profile|
|
49
51
|
id = profile.dig('id')
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
search(year, month, nil, id).each do |origin|
|
54
|
-
# TODO: to be updated null check
|
55
|
-
if origin == {}
|
56
|
-
month
|
57
|
-
else
|
58
|
-
origin.select { |k, _v| /^[1-4][0-9A-Fa-f]{,3}$/.match(k) }.each do |k, v|
|
59
|
-
payment[k] = payment[k] ? payment[k] + v : v
|
60
|
-
end
|
61
|
-
nil
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
52
|
+
slips = term(year, 1, year, 12, id)
|
53
|
+
payment, _count = accumulate(slips)
|
54
|
+
payment['profile_id'] = id
|
65
55
|
date = Date.new(year, 12, 31)
|
66
56
|
payment = local_convert(payment, date)
|
67
57
|
create(payment, date: date, codes: [id], basedir: 'payments/total')
|
@@ -78,6 +68,31 @@ module LucaSalary
|
|
78
68
|
return payment
|
79
69
|
end
|
80
70
|
|
71
|
+
# Apply adjustment for yearly refund.
|
72
|
+
# Search Year Total records 6 months before specified payslip month.
|
73
|
+
#
|
74
|
+
def self.year_adjust(year, month)
|
75
|
+
target_month = Date.new(year, month, 1)
|
76
|
+
total_st = target_month.prev_month(6)
|
77
|
+
search(year, month).each do |slip, path|
|
78
|
+
term(total_st.year, total_st.month, year, month, slip['profile_id'], "#{@dirname}/total/") do |total|
|
79
|
+
slip['3A1'] = total['3A1']
|
80
|
+
slip['4A1'] = total['4A1']
|
81
|
+
end
|
82
|
+
# Recalculate sum
|
83
|
+
['3', '4'].each do |key|
|
84
|
+
slip[key] = 0
|
85
|
+
slip[key] = LucaSalary::Base.sum_code(slip, key)
|
86
|
+
slip['5'] = slip['1'] - slip['2'] - slip['3'] + slip['4']
|
87
|
+
end
|
88
|
+
update_record(
|
89
|
+
@dirname,
|
90
|
+
path,
|
91
|
+
YAML.dump(LucaSupport::Code.readable(slip.sort.to_h))
|
92
|
+
)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
81
96
|
# Export json for LucaBook.
|
82
97
|
# Accrual_date can be change with `payment_term` on config.yml. Default value is 0.
|
83
98
|
# `payment_term: 1` means payment on the next month of calculation target.
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'luca_support'
|
4
|
+
require 'luca_record'
|
5
|
+
|
6
|
+
module LucaSalary
|
7
|
+
class State < LucaRecord::Base
|
8
|
+
include Accumulator
|
9
|
+
|
10
|
+
@dirname = 'payments'
|
11
|
+
|
12
|
+
def initialize(data, count = nil, start_d: nil, end_d: nil)
|
13
|
+
@monthly = data
|
14
|
+
@count = count
|
15
|
+
@start_date = start_d
|
16
|
+
@end_date = end_d
|
17
|
+
@dict = LucaRecord::Dict.load_tsv_dict(Pathname(LucaSupport::PJDIR) / 'dict' / 'code.tsv')
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.range(from_year, from_month, to_year = from_year, to_month = from_month)
|
21
|
+
date = Date.new(from_year.to_i, from_month.to_i, -1)
|
22
|
+
last_date = Date.new(to_year.to_i, to_month.to_i, -1)
|
23
|
+
raise 'invalid term specified' if date > last_date
|
24
|
+
|
25
|
+
counts = []
|
26
|
+
reports = [].tap do |r|
|
27
|
+
while date <= last_date do
|
28
|
+
slips = term(date.year, date.month, date.year, date.month)
|
29
|
+
record, count = accumulate(slips)
|
30
|
+
r << record.tap { |c| c['_d'] = date.to_s }
|
31
|
+
counts << count
|
32
|
+
date = Date.new(date.next_month.year, date.next_month.month, -1)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
new(reports, counts,
|
36
|
+
start_d: Date.new(from_year.to_i, from_month.to_i, 1),
|
37
|
+
end_d: Date.new(to_year.to_i, to_month.to_i, -1)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def report()
|
42
|
+
total, _count = LucaSalary::State.accumulate(@monthly)
|
43
|
+
total['_d'] = 'total'
|
44
|
+
[@monthly, total].flatten.map do |m|
|
45
|
+
{}.tap do |r|
|
46
|
+
m.sort.to_h.each do |k, v|
|
47
|
+
r["#{@dict.dig(k, :label) || k}"] = readable(v)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'luca_support'
|
4
|
+
require 'luca_record'
|
5
|
+
|
6
|
+
module LucaSalary
|
7
|
+
class Total < LucaRecord::Base
|
8
|
+
@dirname = 'payments/total'
|
9
|
+
|
10
|
+
attr_reader :slips
|
11
|
+
|
12
|
+
def initialize(year)
|
13
|
+
@date = Date.new(year.to_i, 12, -1)
|
14
|
+
@slips = Total.term(year, 1, year, 12).map do |slip, _path|
|
15
|
+
slip['profile'] = parse_current(Profile.find_secure(slip['profile_id']))
|
16
|
+
slip
|
17
|
+
end
|
18
|
+
@dict = LucaRecord::Dict.load_tsv_dict(Pathname(LucaSupport::PJDIR) / 'dict' / 'code.tsv')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/luca_salary/version.rb
CHANGED
data/lib/luca_salary.rb
CHANGED
@@ -4,7 +4,10 @@ require 'luca_record'
|
|
4
4
|
require 'luca_salary/version'
|
5
5
|
|
6
6
|
module LucaSalary
|
7
|
+
autoload :Accumulator, 'luca_salary/accumulator'
|
7
8
|
autoload :Base, 'luca_salary/base'
|
8
9
|
autoload :Payment, 'luca_salary/payment'
|
9
10
|
autoload :Profile, 'luca_salary/profile'
|
11
|
+
autoload :State, 'luca_salary/state'
|
12
|
+
autoload :Total, 'luca_salary/total'
|
10
13
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lucasalary
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chuma Takahiro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lucarecord
|
@@ -81,10 +81,13 @@ files:
|
|
81
81
|
- README.md
|
82
82
|
- exe/luca-salary
|
83
83
|
- lib/luca_salary.rb
|
84
|
+
- lib/luca_salary/accumulator.rb
|
84
85
|
- lib/luca_salary/base.rb
|
85
86
|
- lib/luca_salary/monthly.rb
|
86
87
|
- lib/luca_salary/payment.rb
|
87
88
|
- lib/luca_salary/profile.rb
|
89
|
+
- lib/luca_salary/state.rb
|
90
|
+
- lib/luca_salary/total.rb
|
88
91
|
- lib/luca_salary/version.rb
|
89
92
|
homepage: https://github.com/chumaltd/luca/tree/master/lucasalary
|
90
93
|
licenses:
|
@@ -108,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
111
|
- !ruby/object:Gem::Version
|
109
112
|
version: '0'
|
110
113
|
requirements: []
|
111
|
-
rubygems_version: 3.
|
114
|
+
rubygems_version: 3.4.1
|
112
115
|
signing_key:
|
113
116
|
specification_version: 4
|
114
117
|
summary: Salary calculation framework
|