uob-payroll 1.0.5 → 1.1.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
- SHA1:
3
- metadata.gz: ffc20a1da3bc5aebc95f34d5751534f32886c086
4
- data.tar.gz: 6ff939c710c741b2700d934f17b45dce2b4cdc19
2
+ SHA256:
3
+ metadata.gz: 5dffc887932bef572a29ee714a2df50ec348256822bf8d8b00ff87690b9f44db
4
+ data.tar.gz: 720c558fbdd4414c4bcb341e3bb2b7f813ee80ded4e601e98a41f726e6ba1449
5
5
  SHA512:
6
- metadata.gz: c5b8e0106265cc6a2b1ef65b52d2e653962808eb93577b0231405383bb719d70f60fffcd24688557b976849042f19857b942a3b729ac8fa5013f77bcabaa2ffe
7
- data.tar.gz: 7304289625f6026dbc825163d15f368c3671ad9ac45657ecec7f4f594c03f1a88739bae5cf1aead15dbb231bd4653498d8703e78ddffe028508857b053e80524
6
+ metadata.gz: '09068c411cb2e052d0ac2c6e92d2c2d20f0b13fa1630d0802618dd9040466f17cacfe13063ce2cfa2409e7ab62d7496f7e6dc0afab78a8a127d78cddaa55d7c9'
7
+ data.tar.gz: 864c2477f16f0a45c9fa423a2344575cadef9b8a27d6f6061c7fd05bed96b18994264e8945ce8e3f6f4deca8c4739ed7334386a2875dcf43ab15027674907602
@@ -0,0 +1,63 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: build
9
+
10
+ on: [push, pull_request]
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-20.04
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ ruby:
19
+ - 2.7
20
+ - 2.6
21
+ - 2.5
22
+ - 2.4
23
+ - 2.3
24
+ - 2.2
25
+ gemfile:
26
+ - Gemfile-5-0
27
+ - Gemfile-5-1
28
+ - Gemfile-5-2
29
+ - Gemfile-6-0
30
+ - Gemfile-6-1
31
+ exclude:
32
+ - gemfile: Gemfile-6-0
33
+ ruby: 2.4
34
+ - gemfile: Gemfile-6-1
35
+ ruby: 2.4
36
+ - gemfile: Gemfile-6-0
37
+ ruby: 2.3
38
+ - gemfile: Gemfile-6-1
39
+ ruby: 2.3
40
+ - gemfile: Gemfile-6-0
41
+ ruby: 2.2
42
+ - gemfile: Gemfile-6-1
43
+ ruby: 2.2
44
+ - gemfile: Gemfile-5-0
45
+ ruby: 2.7
46
+ - gemfile: Gemfile-5-1
47
+ ruby: 2.7
48
+ - gemfile: Gemfile-5-0
49
+ ruby: 3.0
50
+ - gemfile: Gemfile-5-1
51
+ ruby: 3.0
52
+ - gemfile: Gemfile-5-2
53
+ ruby: 3.0
54
+
55
+ env:
56
+ BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}
57
+ steps:
58
+ - uses: actions/checkout@v2
59
+ - uses: ruby/setup-ruby@v1
60
+ with:
61
+ ruby-version: ${{ matrix.ruby }}
62
+ bundler-cache: true
63
+ - run: bundle exec rspec
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'rails', '~> 5.0.7'
6
+ gem 'sqlite3', '< 1.4'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'rails', '~> 5.1.4'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'rails', '~> 5.2.6'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'rails', '~> 6.0.4'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec path: '..'
4
+
5
+ gem 'rails', '~> 6.1.4'
@@ -0,0 +1,51 @@
1
+ module TxtData
2
+ # A helpful module for formatting fields for fixed length txt data files.
3
+ module FormatHelpers
4
+ # Right justified, "0" padded, 2 decimal places, with no separator.
5
+ # @param [Fixnum] value
6
+ # @param [Fixnum] length
7
+ def money_format(value, length:, just: :right, pad: '0')
8
+ txt = ("%.2f" % value.round(2)).to_s.sub(".", "").truncate(length, omission: "")
9
+ justify(txt, length, just, pad)
10
+ end
11
+
12
+ # Right justified, "0" padded, no decimal places, with no separator.
13
+ # @param [Fixnum] value
14
+ # @param [Fixnum] length
15
+ # @param [Symbol] just
16
+ # @param [String] pad
17
+ def number_format(value, length:, just: :right, pad: '0')
18
+ txt = value.to_i.to_s.truncate(length, omission: "")
19
+ justify(txt, length, just, pad)
20
+ end
21
+
22
+ # Left justified, " " padded, text.
23
+ # @param [String] value
24
+ # @param [Fixnum] length
25
+ # @param [Symbol] just
26
+ # @param [String] pad
27
+ def text_format(value, length:, just: :left, sanitize:, pad: ' ')
28
+ txt = sanitize ? filter_illegal_characters(value.to_s).truncate(length, omission: "") : value
29
+ justify(txt, length, just, pad)
30
+ end
31
+
32
+ # Filters invalid characters specified in CPF eSubmission spec file.
33
+ # @param [String] value
34
+ def filter_illegal_characters(value)
35
+ value.tr("-_+$<>:;?!=[]`^|\\'\"`~", "")
36
+ end
37
+
38
+ private
39
+
40
+ def justify(txt, length, just, pad)
41
+ case just
42
+ when :left
43
+ txt.ljust(length, pad)
44
+ when :right
45
+ txt.rjust(length, pad)
46
+ else
47
+ raise ArgumentError, "Justification #{just} is not supported."
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ require 'txt_data/format_helpers'
2
+
3
+ module TxtData::TxtDataRowDSL
4
+ Field = Struct.new(:symbol, :range, :just, :pad, :value, :format, :sanitize) do
5
+ include TxtData::FormatHelpers
6
+
7
+ def to_s(record)
8
+ data = get_data(record)
9
+ validate_length!(data)
10
+ format_data data
11
+ end
12
+
13
+ private
14
+
15
+ def format_data(data)
16
+ case format
17
+ when :text
18
+ format_text(data, sanitize: sanitize)
19
+ when :number
20
+ number_format(data, length: range.size, just: just, pad: pad)
21
+ when :money
22
+ money_format(data, length: range.size, just: just, pad: pad)
23
+ else
24
+ raise ArgumentError, "Unsupported format #{format}"
25
+ end
26
+ end
27
+
28
+ def validate_length!(data)
29
+ #Do not use .blank? we need to match ' ' for pad.
30
+ if (pad.nil? || pad.empty?) && data.length != range.size
31
+ raise ArgumentError, "Data #{data} is not the correct length for field #{symbol}"
32
+ end
33
+ end
34
+
35
+ def get_data(record)
36
+ value || record.public_send(symbol)
37
+ end
38
+
39
+ def format_text(data, sanitize:)
40
+ text_format(data.to_s, length: range.size, just: just, pad: pad, sanitize: sanitize)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,79 @@
1
+ module TxtData
2
+ # DSL for defining a class which gives you back a row of a txt data file.
3
+ # @example
4
+ # class MyTxtRow
5
+ # include TxtData::TxtDataRowDSL
6
+ # text :date, 1..6
7
+ # spaces 7..51
8
+ # number :my_number, 52..55
9
+ # text :my_text, 56..58
10
+ # text :my_fixed_text, 58..71, value: '1234'
11
+ #
12
+ # def date
13
+ # '151201'
14
+ # end
15
+ #
16
+ # def my_number
17
+ # 12
18
+ # end
19
+ #
20
+ # def my_text
21
+ # "barf"
22
+ # end
23
+ # end
24
+ # Use #text to define some text, it is by default left padded with spaces
25
+ # Use #number fo define a number, it is by default left padded with zeroes
26
+ # Use #spaces to add spaces in that field.
27
+ module TxtDataRowDSL
28
+ extend ActiveSupport::Concern
29
+ extend ActiveSupport::Autoload
30
+ autoload :Field
31
+
32
+ class_methods do
33
+ def fields
34
+ @fields ||= []
35
+ end
36
+
37
+ # Add a text field, right justified with space padding by default.
38
+ # @param [Symbol] symbol
39
+ # @param [Range] range
40
+ # @param [:right|:left] just
41
+ # @param [String] pad
42
+ # @param [String] value
43
+ def text(symbol, range, just: :right, pad: ' ', value: nil, sanitize: true)
44
+ data(symbol, range, just: just, pad: pad, format: :text, value: value, sanitize: sanitize)
45
+ end
46
+
47
+ def money(symbol, range, just: :right, pad: '0', value: nil)
48
+ data(symbol, range, just: just, pad: pad, format: :money, value: value)
49
+ end
50
+
51
+ # Add a number field, right justified with zero padding by default.
52
+ # @param [Symbol] symbol
53
+ # @param [Range] range
54
+ # @param [:right|:left] just
55
+ # @param [String] pad
56
+ # @param [String] value
57
+ def number(symbol, range, just: :right, pad: '0', value: nil)
58
+ data(symbol, range, just: just, pad: pad, format: :number, value: value)
59
+ end
60
+
61
+ # @param [Range] range
62
+ def spaces(range)
63
+ data(:spaces, range, just: :left, pad: ' ', format: :text, value: ' ' * range.size)
64
+ end
65
+
66
+ private
67
+
68
+ def data(symbol, range, just: :none, pad:, value: nil, format: :text, sanitize: true)
69
+ fields << Field.new(symbol, range, just, pad, value, format, sanitize)
70
+ end
71
+ end
72
+
73
+ def to_s
74
+ self.class.fields.map { |field|
75
+ field.to_s(self)
76
+ }.join("")
77
+ end
78
+ end
79
+ end
@@ -28,7 +28,7 @@ module UOB
28
28
  def sum_header
29
29
  calculate_string(header.originating_bic_code) +
30
30
  calculate_padded_string(string: header.originating_account_number, size: 34) +
31
- calculate_padded_string(string: header.originating_account_name, size: 140)
31
+ calculate_padded_string(string: sanitize(header.originating_account_name), size: 140)
32
32
  end
33
33
 
34
34
  def sum_rows
@@ -41,7 +41,7 @@ module UOB
41
41
 
42
42
  sum += calculate_string(row.receiving_bic_code) +
43
43
  hash_code * calculate_padded_string(string: row.receiving_account_number, size: 34) +
44
- hash_code * calculate_padded_string(string: row.receiving_account_name, size: 140) +
44
+ hash_code * calculate_padded_string(string: sanitize(row.receiving_account_name), size: 140) +
45
45
  calculate_payment_type(hash_code) +
46
46
  calculate_string('SGD') +
47
47
  calculate_padded_string(string: row.formatted_amount, size: 18, pad: '0', just: :right) +
@@ -53,6 +53,11 @@ module UOB
53
53
 
54
54
  private
55
55
 
56
+ # Remove "-" from names.
57
+ def sanitize(string)
58
+ string.gsub(/-|'/,'')
59
+ end
60
+
56
61
  # Payment Type is always 'R', so Payment Code = 22
57
62
  def calculate_payment_type(index)
58
63
  22 * (index)
@@ -1,12 +1,12 @@
1
1
  require 'active_model'
2
- require 'ph_utility'
3
2
  require_relative '../hash_calculator'
3
+ require 'txt_data/txt_data_row_dsl'
4
4
 
5
5
  module UOB
6
6
  module Payroll
7
7
  class TXTFile::Footer
8
8
  include ActiveModel::Model
9
- include PhUtility::TxtData::TxtDataRowDSL
9
+ include TxtData::TxtDataRowDSL
10
10
 
11
11
  number :record_type, 1..1, value: 9
12
12
  text :formatted_total_amount, 2..19, just: :right, pad: '0'
@@ -1,11 +1,11 @@
1
1
  require 'active_model'
2
- require 'ph_utility'
2
+ require 'txt_data/txt_data_row_dsl'
3
3
 
4
4
  module UOB
5
5
  module Payroll
6
6
  class TXTFile::Header
7
7
  include ActiveModel::Model
8
- include PhUtility::TxtData::TxtDataRowDSL
8
+ include TxtData::TxtDataRowDSL
9
9
 
10
10
  number :record_type, 1..1, value: 1
11
11
  text :filename, 2..11
@@ -1,11 +1,11 @@
1
1
  require 'active_model'
2
- require 'ph_utility'
2
+ require 'txt_data/txt_data_row_dsl'
3
3
 
4
4
  module UOB
5
5
  module Payroll
6
6
  class TXTFile::Row
7
7
  include ActiveModel::Model
8
- include PhUtility::TxtData::TxtDataRowDSL
8
+ include TxtData::TxtDataRowDSL
9
9
 
10
10
  number :record_type, 1..1, value: 2
11
11
  text :receiving_bic_code, 2..12, just: :left
@@ -30,13 +30,13 @@ module UOB
30
30
  @bic_code = bic_code
31
31
  @account_number = account_number
32
32
  @account_name = account_name
33
- @amount = amount
33
+ @amount = amount.is_a?(String) ? BigDecimal(amount) : amount
34
34
 
35
35
  raise Errors::Invalid, errors.full_messages.to_sentence unless valid?
36
36
  end
37
37
 
38
38
  def formatted_amount
39
- (format '%014.2f', amount).gsub('.','')
39
+ (format '%014.2f', amount.round(2)).gsub('.','')
40
40
  end
41
41
 
42
42
  def receiving_bic_code
@@ -20,7 +20,7 @@ module UOB
20
20
  value_date: payable_date
21
21
  )
22
22
  @rows = transactions.map { |transaction| Row.new transaction }
23
- @footer = Footer.new total_amount: rows.sum(&:amount), header: header, rows: rows
23
+ @footer = Footer.new total_amount: total_amount(rows), header: header, rows: rows
24
24
  end
25
25
 
26
26
  def content
@@ -33,6 +33,14 @@ module UOB
33
33
 
34
34
  private
35
35
 
36
+ # We need to round each amount first before summing them up so that it matches
37
+ # the amounts in the details
38
+ def total_amount(rows)
39
+ rows.each.map { |row|
40
+ row.amount.round(2)
41
+ }.reduce(0, :+)
42
+ end
43
+
36
44
  attr_accessor :header, :rows, :footer
37
45
  end
38
46
  end
@@ -1,5 +1,5 @@
1
1
  module Uob
2
2
  module Payroll
3
- VERSION = "1.0.5"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
data/uob-payroll.gemspec CHANGED
@@ -19,14 +19,17 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.11"
23
- spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "bundler", "> 1.16", "< 3"
23
+ spec.add_development_dependency "rake"
24
24
  spec.add_development_dependency "rspec", "~> 3.0"
25
25
  spec.add_development_dependency 'pry'
26
- spec.add_development_dependency 'github_changelog_generator'
26
+ if RUBY_VERSION < "2.3"
27
+ spec.add_development_dependency 'github_changelog_generator', '< 1.15'
28
+ else
29
+ spec.add_development_dependency 'github_changelog_generator'
30
+ end
27
31
 
28
32
  spec.add_dependency 'activesupport'
29
33
  spec.add_dependency 'activemodel'
30
34
  spec.add_dependency 'ph_model'
31
- spec.add_dependency 'ph_utility'
32
35
  end
metadata CHANGED
@@ -1,43 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uob-payroll
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vincent Paca
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-26 00:00:00.000000000 Z
11
+ date: 2021-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '1.11'
22
+ version: '3'
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">"
25
28
  - !ruby/object:Gem::Version
26
- version: '1.11'
29
+ version: '1.16'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rake
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - "~>"
37
+ - - ">="
32
38
  - !ruby/object:Gem::Version
33
- version: '10.0'
39
+ version: '0'
34
40
  type: :development
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
- - - "~>"
44
+ - - ">="
39
45
  - !ruby/object:Gem::Version
40
- version: '10.0'
46
+ version: '0'
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: rspec
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +128,6 @@ dependencies:
122
128
  - - ">="
123
129
  - !ruby/object:Gem::Version
124
130
  version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: ph_utility
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :runtime
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
131
  description: A UOB Payroll File Generator
140
132
  email:
141
133
  - vpaca@payrollhero.com
@@ -143,6 +135,7 @@ executables: []
143
135
  extensions: []
144
136
  extra_rdoc_files: []
145
137
  files:
138
+ - ".github/workflows/build.yml"
146
139
  - ".gitignore"
147
140
  - ".rspec"
148
141
  - ".travis.yml"
@@ -155,6 +148,14 @@ files:
155
148
  - Rakefile
156
149
  - bin/console
157
150
  - bin/setup
151
+ - gemfiles/Gemfile-5-0
152
+ - gemfiles/Gemfile-5-1
153
+ - gemfiles/Gemfile-5-2
154
+ - gemfiles/Gemfile-6-0
155
+ - gemfiles/Gemfile-6-1
156
+ - lib/txt_data/format_helpers.rb
157
+ - lib/txt_data/txt_data_row_dsl.rb
158
+ - lib/txt_data/txt_data_row_dsl/field.rb
158
159
  - lib/uob/payroll.rb
159
160
  - lib/uob/payroll/errors.rb
160
161
  - lib/uob/payroll/hash_calculator.rb
@@ -184,8 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
185
  - !ruby/object:Gem::Version
185
186
  version: '0'
186
187
  requirements: []
187
- rubyforge_project:
188
- rubygems_version: 2.5.1
188
+ rubygems_version: 3.0.9
189
189
  signing_key:
190
190
  specification_version: 4
191
191
  summary: A UOB Payroll File Generator