@@ -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
610678end
0 commit comments