working_times 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5a2fb5e4c26ca5d6f922fc3f1bd01a0557ff60331f34b5e58163de1a13a8284
4
- data.tar.gz: 1c870e507ac414e53d4a45d873b012226986b9d39c6bd505b31dd0b8ffc9d4b6
3
+ metadata.gz: 9ccab617c04629dffdd39a32e931a3e00c8e8ae4639c1627a72a1b54b4042b02
4
+ data.tar.gz: 2745ebe905da60de2db8d7bb9f70da78de4b96fd0df4901ac2fd4dfeb5f6fe44
5
5
  SHA512:
6
- metadata.gz: d693128ec3ef10af8c1fcf9dbb139c51d33878bfd3888aa737e3c938ed4a48287b1fe23104ac8ca0bc2b1841c6dd7a980696c5aef62f5b61b0e5829b3451cb56
7
- data.tar.gz: 7a0296790a7170b47daacf803734942b1cc2af0b6ab8bfe3df6dc676ec34c7842818d4c5ab4c975b453c8eaa2175afd218432ce1bd270f08805007db44e1addd
6
+ metadata.gz: 8c047ff14e1b8c6d20dab82c21ce329dd44731ca97c0f21d80549744a12a42cd19543f1b94f231e3817083643b27048bb0851826c720dd76517211ec27d3c118
7
+ data.tar.gz: d01a5f63e2c43f16979615c6f7787eda71ea4390fdb8478566c1a026e28d0f0a63036f154997cc67d93b605d206bc73e3270f019f9d846cb1793fbc428c56f38
@@ -13,6 +13,7 @@ module WorkingTimes
13
13
  end
14
14
 
15
15
  FileUtils.mkdir_p(File.join(workon, 'terms'))
16
+ FileUtils.mkdir_p(File.join(workon, 'invoices'))
16
17
  initialize_wtconf(workon, term, company)
17
18
  end
18
19
 
@@ -57,6 +58,21 @@ module WorkingTimes
57
58
  Record.new(timestamp: DateTime.now, duration: duration).rest
58
59
  end
59
60
 
61
+ option :build, type: :boolean, aliases: ['-b']
62
+ desc 'invoice', 'Create invoice for current term by TeX template. It will build pdf if option is set'
63
+ def invoice
64
+ Invoice.new.tap do |invoice|
65
+ invoice.generate
66
+ invoice.build if options[:build]
67
+ end
68
+ puts "Invoice created to #{path_invoice_current_term}."
69
+ end
70
+
71
+ desc 'version', 'Show version of working_times'
72
+ def version
73
+ puts 'version: ' + VERSION
74
+ end
75
+
60
76
  private
61
77
 
62
78
  def initialize_wtconf(workon, term, company)
@@ -65,7 +81,12 @@ module WorkingTimes
65
81
  File.write(File.join(data_dir, 'wtconf.json'), <<~WTCONF)
66
82
  {
67
83
  "term": "#{term}",
68
- "company": "#{company}"
84
+ "invoice": {
85
+ "company": "#{company}",
86
+ "template": "",
87
+ "salaryPerHour": 0,
88
+ "taxRate": 0.0
89
+ }
69
90
  }
70
91
  WTCONF
71
92
  end
@@ -32,6 +32,22 @@ module WorkingTimes
32
32
  wtconf['company']
33
33
  end
34
34
 
35
+ def invoice_dir
36
+ File.join(data_dir, 'invoices')
37
+ end
38
+
39
+ def invoice_info
40
+ wtconf['invoice']
41
+ end
42
+
43
+ def dir_invoice_current_term
44
+ File.join(invoice_dir, current_term)
45
+ end
46
+
47
+ def path_invoice_current_term
48
+ File.join(dir_invoice_current_term, "#{current_term}.tex")
49
+ end
50
+
35
51
  def wtconf
36
52
  JSON.parse(File.read(path_wtconf))
37
53
  end
@@ -1,5 +1,5 @@
1
1
  module WorkingTimes
2
- VERSION = '0.6.0'.freeze
2
+ VERSION = '0.7.0'.freeze
3
3
 
4
4
  START_MSG = [
5
5
  'Have a nice work!',
@@ -0,0 +1,133 @@
1
+ module WorkingTimes
2
+ # Class about creating invoice
3
+ # This class is designed to build data_dir/invoices/current_term/invoice.tex
4
+ # from data_dir/invoices/template.tex
5
+ class Invoice
6
+ include Config
7
+ attr_reader :path_template, :salary_per_hour, :tax_rate, :company
8
+
9
+ WDAYS = %w[日 月 火 水 木 金 土].freeze
10
+ Date::DATE_FORMATS[:jp_date] = '%m月%d日'
11
+ Time::DATE_FORMATS[:only_hm] = '%H:%M'
12
+
13
+ # path_template : String
14
+ # salary_per_hour : Integer
15
+ # tax_rate : Float
16
+ # company : String
17
+ def initialize
18
+ h_invoice_info = invoice_info
19
+
20
+ @path_template = h_invoice_info['template']
21
+ @salary_per_hour = h_invoice_info['salaryPerHour']
22
+ @tax_rate = h_invoice_info['taxRate']
23
+ @company = h_invoice_info['company']
24
+ end
25
+
26
+ def generate
27
+ create_dir_invoice_current_term
28
+ makeup_worktable
29
+ generate_invoice_from_template
30
+ end
31
+
32
+ def build
33
+ puts 'Currently, it is not available to build pdf with latexmk.'
34
+ puts 'Wait for new version!'
35
+ end
36
+
37
+ private
38
+
39
+ def create_dir_invoice_current_term
40
+ FileUtils.mkdir_p(dir_invoice_current_term)
41
+ end
42
+
43
+ def makeup_worktable
44
+ @worktable = [
45
+ '\hline',
46
+ '日付 & 曜日 & 内容 & 出勤 & 退勤 & 休憩 & 労働時間 \\\\ \hline\hline'
47
+ ]
48
+ @allworktime_on_sec = 0.0
49
+ working_times = CSV.open(path_current_term, headers: true)
50
+ row = working_times.first
51
+ date_itr = beginning_of_month(row['started_at'])
52
+ date_itr.upto(date_itr.end_of_month) do |date|
53
+ if row.nil?
54
+ @worktable << format_worktable_row(date)
55
+ elsif same_day?(row['started_at'], date.rfc3339)
56
+ worktime = calculate_worktime(row['started_at'], row['finished_at'], row['rest_sec'])
57
+ @allworktime_on_sec += worktime
58
+ @worktable <<
59
+ format_worktable_row(date, row['comment'], row['started_at'], row['finished_at'], row['rest_sec'], worktime)
60
+ row = working_times.readline
61
+ else
62
+ @worktable << format_worktable_row(date)
63
+ end
64
+ end
65
+ end
66
+
67
+ def generate_invoice_from_template
68
+ template = File.readlines(path_template)
69
+ File.open(path_invoice_current_term, 'w') do |f|
70
+ template.each do |t|
71
+ t.gsub!(/##COMPANY##/, company)
72
+ t.gsub!(/##WORKTIME##/, parse_second_to_hh_str(@allworktime_on_sec))
73
+ t.gsub!(/##ACTUALWORKTIME##/, parse_second_to_hm_str(@allworktime_on_sec))
74
+ t.gsub!(/##SALARYPERHOUR##/, salary_per_hour.to_s)
75
+ t.gsub!(/##SALARY##/, salary.to_s)
76
+ t.gsub!(/##TAXRATE##/, "#{(tax_rate * 100).to_i}\\%")
77
+ t.gsub!(/##TAX##/, tax.to_s)
78
+ t.gsub!(/##SALARYWITHTAX##/, (salary + tax).to_s)
79
+ # on gsub, '\' means 'replace sub string'.
80
+ # so we should use block if work as expected
81
+ t.gsub!(/##WORKTABLE##/) { @worktable.join("\n") }
82
+
83
+ f.write(t)
84
+ end
85
+ end
86
+ end
87
+
88
+ def beginning_of_month(rfc3339)
89
+ Date.parse(rfc3339).beginning_of_month
90
+ end
91
+
92
+ def same_day?(one_rfc3339, another_rfc3339)
93
+ Date.parse(one_rfc3339) == Date.parse(another_rfc3339)
94
+ end
95
+
96
+ def calculate_worktime(st_rfc3339, fi_rfc3339, rest_sec)
97
+ Time.parse(fi_rfc3339) - Time.parse(st_rfc3339) - rest_sec.to_i
98
+ end
99
+
100
+ # date : Date
101
+ # comment : String
102
+ # started_at, finished_at : String (RFC3339)
103
+ # rest, worktime : Integer
104
+ def format_worktable_row(date, comment = nil, started_at = nil, finished_at = nil, rest = nil, worktime = nil)
105
+ "#{date.to_s(:jp_date)} & " \
106
+ "#{WDAYS[date.wday]} & " \
107
+ "#{comment || '-'} & " \
108
+ "#{started_at.nil? ? '-' : Time.parse(started_at).to_s(:only_hm)} & " \
109
+ "#{finished_at.nil? ? '-' : Time.parse(finished_at).to_s(:only_hm)} & " \
110
+ "#{rest.nil? ? '-' : parse_second_to_hm_str(rest.to_i)} & " \
111
+ "#{worktime.nil? ? '-' : parse_second_to_hm_str(worktime)} \\\\ \\hline"
112
+ end
113
+
114
+ def parse_second_to_hm_str(second)
115
+ h = (second / 3600).to_i
116
+ m = second - (3600 * h)
117
+ "#{h.to_i}:#{m.to_i.to_s.rjust(2, '0')}"
118
+ end
119
+
120
+ def parse_second_to_hh_str(second)
121
+ (second / 3600).to_i.to_s
122
+ end
123
+
124
+ # calculate with 'hour' only
125
+ def salary
126
+ @salary ||= @allworktime_on_sec.to_i / 3600 * salary_per_hour
127
+ end
128
+
129
+ def tax
130
+ @tax ||= (salary * tax_rate).to_i
131
+ end
132
+ end
133
+ end
data/lib/working_times.rb CHANGED
@@ -2,4 +2,5 @@ require 'working_times/constants'
2
2
  require 'working_times/config'
3
3
  require 'working_times/state'
4
4
  require 'working_times/record'
5
+ require 'working_times/invoice'
5
6
  require 'working_times/cli'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: working_times
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aoshi Fujioka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-25 00:00:00.000000000 Z
11
+ date: 2020-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -135,6 +135,7 @@ files:
135
135
  - lib/working_times/cli.rb
136
136
  - lib/working_times/config.rb
137
137
  - lib/working_times/constants.rb
138
+ - lib/working_times/invoice.rb
138
139
  - lib/working_times/record.rb
139
140
  - lib/working_times/state.rb
140
141
  homepage: https://github.com/arsley/working_times