Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Faker::Company.indian_gst_number fixed #2823 #2825

Merged
merged 8 commits into from Nov 2, 2023
4 changes: 4 additions & 0 deletions doc/default/company.md
Expand Up @@ -84,4 +84,8 @@ Faker::Company.russian_tax_number #=> "0965855857"
Faker::Company.russian_tax_number(region: '77') #=> "7717152803"
Faker::Company.russian_tax_number(type: :individual) #=> "488935903348"
Faker::Company.russian_tax_number(region: '77', type: :individual) #=> "779124694601"

# Get a random formatted Indian tax number (GST)
Faker::Company.indian_gst_number #=> "15VQPNZ2126J2ZU"
Faker::Company.indian_gst_number(state_code: "22") #=> "22ZVWEY6632K0ZN"
```
68 changes: 68 additions & 0 deletions lib/faker/default/company.rb
Expand Up @@ -464,6 +464,61 @@ def sic_code
fetch('company.sic_code')
end

##
# Get a random Indian Goods and Services Tax (GST) number.
# For more on Indian tax number here:
# https://simple.wikipedia.org/wiki/GSTIN
# @params state code [String] Any state code.
#
# @return [String]
# @example
# Faker::Company.indian_gst_number #=> "15VQPNZ2126J2ZU"
# Faker::Company.indian_gst_number(state_code: "22") #=> "22ZVWEY6632K0ZN"
#
# @faker.version 3.2.1
def indian_gst_number(state_code: nil)
ankitkhadria marked this conversation as resolved.
Show resolved Hide resolved
# Check if state code is valid
state_code_ranges = [('02'..'38'), ['98']]
if state_code && !(state_code_ranges[0].include?(state_code) || state_code == '98')
raise ArgumentError, 'state code must be in a range of 02 to 38 or 98'
end

PositionalGenerator.new(:string) do |gen|
# Generate a state code if not given
if state_code
gen.lit(state_code, name: :state_code_param)
else
gen.letter(name: :state_code_param, length: 1, ranges: state_code_ranges)
end

# Construct taxpayer number
gen.group(name: :taxpayer_number) do |g_|
g_.letter(length: 3, ranges: ['A'..'Z'])
g_.letter(length: 1, ranges: [%w[A B C F G H L J P T K]].to_a)
g_.letter(length: 1, ranges: ['A'..'Z'])
g_.int(length: 4, ranges: [0..9999])
g_.letter(length: 1, ranges: ['A'..'Z'])
end

gen.int(name: :registration_number, length: 1, ranges: [0..9])

gen.letter(name: :z_char, length: 1, ranges: [['Z']])

gen.computed(deps: %i[state_code_param taxpayer_number registration_number]) do |state_code_param, taxpayer_number, registration_number|
gst_base = "#{state_code_param}#{taxpayer_number}#{registration_number}"
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.chars
values = gst_base.chars
sum = values.map.with_index do |char, index|
product = chars.index(char) * (index.odd? ? 2 : 1)
(product / chars.length).floor + (product % chars.length)
end.reduce(:+)

checksum = (chars.length - (sum % chars.length)) % chars.length
chars[checksum]
end
end.generate
end

private

# Mod11 functionality from https://github.com/badmanski/mod11/blob/master/lib/mod11.rb
Expand Down Expand Up @@ -605,6 +660,19 @@ def spanish_b_algorithm(value)

result.to_s[0].to_i + result.to_s[1].to_i
end

def calculate_gst_checksum(state_code, taxpayer_number, registration_number)
gst_base = "#{state_code}#{taxpayer_number}#{registration_number}"
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.chars
values = gst_base.upcase.chars
sum = values.map.with_index do |char, index|
product = chars.index(char) * (index.odd? ? 2 : 1)
(product / chars.length).floor + (product % chars.length)
end.reduce(:+)

checksum = (chars.length - (sum % chars.length)) % chars.length
chars[checksum]
end
end
end
end
17 changes: 17 additions & 0 deletions test/faker/default/test_faker_company.rb
Expand Up @@ -250,6 +250,23 @@ def test_spanish_b_algorithm
assert_equal(3, @tester.send(:spanish_b_algorithm, 6))
end

def text_indian_gst_number
assert_match(/^([0-2][0-9]|[3][0-7])[A-Z]{3}[ABCFGHLJPTK][A-Z]\d{4}[A-Z][A-Z0-9][Z][A-Z0-9]$/i, @tester.indian_gst_number)
end

def test_state_code_in_indian_gst_number
assert_raise ArgumentError do
@tester.indian_gst_number(state_code: '01')
end
assert_raise ArgumentError do
@tester.indian_gst_number(state_code: '100')
end
end

def test_indian_gst_number_with_state_code
ankitkhadria marked this conversation as resolved.
Show resolved Hide resolved
assert_match(/^(22)[A-Z]{3}[ABCFGHLJPTK][A-Z]\d{4}[A-Z][A-Z0-9][Z][A-Z0-9]$/i, @tester.indian_gst_number(state_code: '22'))
end

private

def czech_o_n_checksum(org_no)
Expand Down