Skip to content

Commit 205bc52

Browse files
ankitkhadriaStefanni Brasil
and
Stefanni Brasil
authored
Added Faker::Company.indian_gst_number fixed #2823 (#2825)
* Added Faker::Company.indian_gst_number fixed #2823 * refactor: using positional generator and added state code validation * fix: state code validation condition * Update styling of if condition to check state code validation Co-authored-by: Stefanni Brasil <[email protected]> --------- Co-authored-by: Stefanni Brasil <[email protected]>
1 parent e8870fc commit 205bc52

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

doc/default/company.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,8 @@ Faker::Company.russian_tax_number #=> "0965855857"
8484
Faker::Company.russian_tax_number(region: '77') #=> "7717152803"
8585
Faker::Company.russian_tax_number(type: :individual) #=> "488935903348"
8686
Faker::Company.russian_tax_number(region: '77', type: :individual) #=> "779124694601"
87+
88+
# Get a random formatted Indian tax number (GST)
89+
Faker::Company.indian_gst_number #=> "15VQPNZ2126J2ZU"
90+
Faker::Company.indian_gst_number(state_code: "22") #=> "22ZVWEY6632K0ZN"
8791
```

lib/faker/default/company.rb

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,61 @@ def sic_code
464464
fetch('company.sic_code')
465465
end
466466

467+
##
468+
# Get a random Indian Goods and Services Tax (GST) number.
469+
# For more on Indian tax number here:
470+
# https://simple.wikipedia.org/wiki/GSTIN
471+
# @params state code [String] Any state code.
472+
#
473+
# @return [String]
474+
# @example
475+
# Faker::Company.indian_gst_number #=> "15VQPNZ2126J2ZU"
476+
# Faker::Company.indian_gst_number(state_code: "22") #=> "22ZVWEY6632K0ZN"
477+
#
478+
# @faker.version 3.2.1
479+
def indian_gst_number(state_code: nil)
480+
# Check if state code is valid
481+
state_code_ranges = [('02'..'38'), ['98']]
482+
if state_code && !(state_code_ranges[0].include?(state_code) || state_code == '98')
483+
raise ArgumentError, 'state code must be in a range of 02 to 38 or 98'
484+
end
485+
486+
PositionalGenerator.new(:string) do |gen|
487+
# Generate a state code if not given
488+
if state_code
489+
gen.lit(state_code, name: :state_code_param)
490+
else
491+
gen.letter(name: :state_code_param, length: 1, ranges: state_code_ranges)
492+
end
493+
494+
# Construct taxpayer number
495+
gen.group(name: :taxpayer_number) do |g_|
496+
g_.letter(length: 3, ranges: ['A'..'Z'])
497+
g_.letter(length: 1, ranges: [%w[A B C F G H L J P T K]].to_a)
498+
g_.letter(length: 1, ranges: ['A'..'Z'])
499+
g_.int(length: 4, ranges: [0..9999])
500+
g_.letter(length: 1, ranges: ['A'..'Z'])
501+
end
502+
503+
gen.int(name: :registration_number, length: 1, ranges: [0..9])
504+
505+
gen.letter(name: :z_char, length: 1, ranges: [['Z']])
506+
507+
gen.computed(deps: %i[state_code_param taxpayer_number registration_number]) do |state_code_param, taxpayer_number, registration_number|
508+
gst_base = "#{state_code_param}#{taxpayer_number}#{registration_number}"
509+
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.chars
510+
values = gst_base.chars
511+
sum = values.map.with_index do |char, index|
512+
product = chars.index(char) * (index.odd? ? 2 : 1)
513+
(product / chars.length).floor + (product % chars.length)
514+
end.reduce(:+)
515+
516+
checksum = (chars.length - (sum % chars.length)) % chars.length
517+
chars[checksum]
518+
end
519+
end.generate
520+
end
521+
467522
private
468523

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

606661
result.to_s[0].to_i + result.to_s[1].to_i
607662
end
663+
664+
def calculate_gst_checksum(state_code, taxpayer_number, registration_number)
665+
gst_base = "#{state_code}#{taxpayer_number}#{registration_number}"
666+
chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.chars
667+
values = gst_base.upcase.chars
668+
sum = values.map.with_index do |char, index|
669+
product = chars.index(char) * (index.odd? ? 2 : 1)
670+
(product / chars.length).floor + (product % chars.length)
671+
end.reduce(:+)
672+
673+
checksum = (chars.length - (sum % chars.length)) % chars.length
674+
chars[checksum]
675+
end
608676
end
609677
end
610678
end

test/faker/default/test_faker_company.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,23 @@ def test_spanish_b_algorithm
250250
assert_equal(3, @tester.send(:spanish_b_algorithm, 6))
251251
end
252252

253+
def text_indian_gst_number
254+
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)
255+
end
256+
257+
def test_state_code_in_indian_gst_number
258+
assert_raise ArgumentError do
259+
@tester.indian_gst_number(state_code: '01')
260+
end
261+
assert_raise ArgumentError do
262+
@tester.indian_gst_number(state_code: '100')
263+
end
264+
end
265+
266+
def test_indian_gst_number_with_state_code
267+
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'))
268+
end
269+
253270
private
254271

255272
def czech_o_n_checksum(org_no)

0 commit comments

Comments
 (0)