Skip to content

Commit

Permalink
CAPT-2040 normalize names for payroll csv export
Browse files Browse the repository at this point in the history
  • Loading branch information
kenfodder committed Dec 10, 2024
1 parent da5cc90 commit f7d1bbf
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
39 changes: 39 additions & 0 deletions app/models/payroll/name_normalizer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module Payroll
class NameNormalizer
def self.normalize(name)
new(name).normalize
end

def initialize(name)
@name = name
end

def normalize
return nil if @name.nil?

@name
.then { |n| remove_typical_disallowed_chars(n) }
.then { |n| transliterate(n) }
.then { |n| final_cleanup(n) }
end

private

# Things we allow from `NameFormatValidator` and typically found in names
# but Payroll provider doesn't accept
# Also handles curly apostrophe commonly found
def remove_typical_disallowed_chars(name)
name.gsub(/[,.;\-'‘’\s]/, "")
end

# Attempt to replace things like `è` with `e`
def transliterate(name)
I18n.transliterate(name)
end

# Just remove anything missed that aren't allowed by Payroll
def final_cleanup(name)
name.gsub(/[^A-Za-z]/, "")
end
end
end
12 changes: 12 additions & 0 deletions app/models/payroll/payment_csv_row.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ def to_a

private

def first_name
NameNormalizer.normalize(model.first_name)
end

def middle_name
NameNormalizer.normalize(model.middle_name)
end

def surname
NameNormalizer.normalize(model.surname)
end

def title
TITLE
end
Expand Down
57 changes: 57 additions & 0 deletions spec/models/payroll/name_normalizer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require "rails_helper"

RSpec.describe Payroll::NameNormalizer do
describe ".normalize" do
subject { described_class.normalize(name) }

context "nil" do
let(:name) { nil }
it { is_expected.to be_nil }
end

context "empty string" do
let(:name) { "" }
it { is_expected.to eq "" }
end

context "blank string" do
let(:name) { " " }
it { is_expected.to eq "" }
end

context "name with nothing to change" do
let(:name) { "John" }
it { is_expected.to eq "John" }
end

context "name curly quotes" do
let(:name) { "O’Something" }
it { is_expected.to eq "OSomething" }
end

context "name accents and spaces" do
let(:name) { "Óscar Hernández" }
it { is_expected.to eq "OscarHernandez" }
end

context "name with multiple spaces" do
let(:name) { "Chan Chiu Bruce" }
it { is_expected.to eq "ChanChiuBruce" }
end

context "name with emojis spaces" do
let(:name) { "Thumbs 👍 Up " }
it { is_expected.to eq "ThumbsUp" }
end

context "name with semi-colon" do
let(:name) { "Samuel;" }
it { is_expected.to eq "Samuel" }
end

context "name that has it all" do
let(:name) { "Jámes', Ryan, O’Hughes 👍" }
it { is_expected.to eq "JamesRyanOHughes" }
end
end
end

0 comments on commit f7d1bbf

Please sign in to comment.