@@ -464,6 +464,61 @@ def sic_code
464
464
fetch ( 'company.sic_code' )
465
465
end
466
466
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
+
467
522
private
468
523
469
524
# Mod11 functionality from https://github.com/badmanski/mod11/blob/master/lib/mod11.rb
@@ -605,6 +660,19 @@ def spanish_b_algorithm(value)
605
660
606
661
result . to_s [ 0 ] . to_i + result . to_s [ 1 ] . to_i
607
662
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
608
676
end
609
677
end
610
678
end
0 commit comments