time_crunch 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.md +21 -0
- data/README.md +26 -0
- data/lib/time_crunch.rb +12 -0
- data/lib/time_crunch/conversion.rb +23 -0
- data/lib/time_crunch/time_card.rb +20 -0
- data/lib/time_crunch/time_entry.rb +46 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 43a865302f70babe1bf27a25235a5723f247bede
|
4
|
+
data.tar.gz: d7b159b74d7e24127686dd8f3b8fc5e3ca0be42d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f803bba2fb55269e6f7ce83ca6af866929d9360ce69c2bfcfe22d27df1e5b1f729493480b61d5a3d5fe95ec6bcffd43f5fea47fc8ef54363946c0bbc0d73e173
|
7
|
+
data.tar.gz: 7079ee7d5bed30103425dc1345cea46fc1c6323b0d6c3c3b7d63dbd265ab1989b036ad5672f7e2515a4c87900315100637fcf1e6af4f695dec2f4f0183815360
|
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2017 Stephen Kiningham
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# time_crunch
|
2
|
+
|
3
|
+
Convert a TPD file from a digital timeclock into an Excel workbook. A few caveats:
|
4
|
+
* The TPD format is, as far as I know, not a standard format.
|
5
|
+
* The TPD format is already CSV. This gem cleans up the CSV and adds it as a worksheet to the workbook. It also adds a summary worksheet with each employee's total time.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add it to your Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'time_crunch'
|
13
|
+
```
|
14
|
+
|
15
|
+
## TPD Format
|
16
|
+
|
17
|
+
The accepted format looks like this:
|
18
|
+
|
19
|
+
```
|
20
|
+
3,0001,2017-12-16,08:00
|
21
|
+
3,0002,2017-12-16,08:01
|
22
|
+
2,0002,2017-12-16,12:03
|
23
|
+
2,0001,2017-12-16,12:05
|
24
|
+
```
|
25
|
+
|
26
|
+
In this format, `3` means `In` and `2` means `Out`. The second column references the employee. A mapping between ID and name is accepted by this gem to output names in the worksheets. The third column is the date, and the fourth column is the 24-hour time (physical clock's timezone). Ideally each `In` should pair with an `Out`, but since this is not always the case, each day with an odd number of entries has the oddity discarded for purposes of the summary calculation. In the future, the worksheets may be updated to include formulas so that the manual addition of time entries on one worksheet would update the summary worksheet.
|
data/lib/time_crunch.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module TimeCrunch
|
2
|
+
require 'time_crunch/conversion'
|
3
|
+
require 'time_crunch/time_entry'
|
4
|
+
require 'time_crunch/time_card'
|
5
|
+
require 'time'
|
6
|
+
require 'csv'
|
7
|
+
require 'rubyXL'
|
8
|
+
|
9
|
+
def self.process(input_file_path, output_file_path, employee_map: {})
|
10
|
+
TimeCrunch::Conversion.new(input_file_path, employee_map: employee_map).write_xlsx(output_file_path)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TimeCrunch
|
2
|
+
class Conversion
|
3
|
+
def initialize(file_path, employee_map: {})
|
4
|
+
@time_entries = CSV.read(file_path).collect { |row| TimeEntry.new(row, employee_map) }.sort
|
5
|
+
end
|
6
|
+
|
7
|
+
def write_xlsx(file_path)
|
8
|
+
workbook = RubyXL::Workbook.new
|
9
|
+
summary_sheet = workbook['Sheet1']
|
10
|
+
summary_sheet.sheet_name = 'Summary'
|
11
|
+
# TODO: Add data to summary
|
12
|
+
|
13
|
+
entries_sheet = workbook.add_worksheet('Time Entries')
|
14
|
+
@time_entries.each_with_index do |time_entry, i|
|
15
|
+
3.times do |j|
|
16
|
+
entries_sheet.add_cell(i, j, time_entry.value_by_index(j))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
workbook.write(file_path)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module TimeCrunch
|
2
|
+
class TimeCard
|
3
|
+
attr_accessor :time_entries
|
4
|
+
attr_reader :employee
|
5
|
+
|
6
|
+
def initialize(time_entries)
|
7
|
+
raise 'All time entries must belong to same employee' unless time_entries.uniq(&:employee).one?
|
8
|
+
@employee = time_entries.first.employee
|
9
|
+
@time_entries = time_entries.sort
|
10
|
+
end
|
11
|
+
|
12
|
+
def valid?
|
13
|
+
# TODO
|
14
|
+
end
|
15
|
+
|
16
|
+
def total
|
17
|
+
# TODO
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module TimeCrunch
|
2
|
+
class TimeEntry
|
3
|
+
include Enumerable
|
4
|
+
attr_reader :employee, :timestamp
|
5
|
+
|
6
|
+
def initialize(csv_row, employee_map)
|
7
|
+
raise 'Row does not have four columns' unless csv_row.size == 4
|
8
|
+
|
9
|
+
@clock_in = csv_row[0] == '3'
|
10
|
+
@employee = employee_map.key?(csv_row[1]) ? employee_map[csv_row[1]] : csv_row[1]
|
11
|
+
@timestamp = Time.parse("#{csv_row[2]} #{csv_row[3]}")
|
12
|
+
end
|
13
|
+
|
14
|
+
def clock_in?
|
15
|
+
@clock_in
|
16
|
+
end
|
17
|
+
|
18
|
+
def clock_out?
|
19
|
+
!clock_in?
|
20
|
+
end
|
21
|
+
|
22
|
+
def direction
|
23
|
+
clock_in? ? 'IN' : 'OUT'
|
24
|
+
end
|
25
|
+
|
26
|
+
def value_by_index(ind)
|
27
|
+
raise IndexError if ind > 2 || ind < 0
|
28
|
+
case ind
|
29
|
+
when 0
|
30
|
+
direction
|
31
|
+
when 1
|
32
|
+
employee
|
33
|
+
when 2
|
34
|
+
timestamp.strftime('%Y-%m-%d %H:%M:%S')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def <=>(other)
|
39
|
+
timestamp <=> other.timestamp
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
"<direction: #{direction}, employee: #{employee}, timestamp: #{timestamp.strftime('%Y-%m-%d %H:%M:%S')}>"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: time_crunch
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stephen Kiningham
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-12-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rubyXL
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description:
|
28
|
+
email: time_crunch@kiningham.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- LICENSE.md
|
34
|
+
- README.md
|
35
|
+
- lib/time_crunch.rb
|
36
|
+
- lib/time_crunch/conversion.rb
|
37
|
+
- lib/time_crunch/time_card.rb
|
38
|
+
- lib/time_crunch/time_entry.rb
|
39
|
+
homepage: https://github.com/skiningham/time_crunch
|
40
|
+
licenses:
|
41
|
+
- MIT
|
42
|
+
metadata: {}
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options: []
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 2.0.0
|
52
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
requirements: []
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 2.4.5.1
|
60
|
+
signing_key:
|
61
|
+
specification_version: 4
|
62
|
+
summary: Convert TPD timeclock data to XLSX
|
63
|
+
test_files: []
|