|
| 1 | +# frozen_string_literal: true |
| 2 | + |
| 3 | +# Onetime script to flag users from IRS CP 2100A notice for TIN re-verification |
| 4 | +# Usage: |
| 5 | +# tins = %w[111111111 222222222] |
| 6 | +# Onetime::FlagCp2100aTinReverification.perform(tins:, dry_run: true) # Preview only |
| 7 | +# Onetime::FlagCp2100aTinReverification.perform(tins:, dry_run: false) # Actually flag users |
| 8 | +class Onetime::FlagCp2100aTinReverification |
| 9 | + def self.perform(tins:, dry_run: true) |
| 10 | + if dry_run |
| 11 | + puts "DRY RUN MODE - No changes will be made" |
| 12 | + puts "" |
| 13 | + else |
| 14 | + puts "LIVE MODE - Users will be flagged for TIN re-verification" |
| 15 | + puts "" |
| 16 | + end |
| 17 | + |
| 18 | + puts "Processing #{tins.count} TINs from IRS CP 2100A notice..." |
| 19 | + puts "================================================================================" |
| 20 | + |
| 21 | + found_users = [] |
| 22 | + not_found_tins = [] |
| 23 | + |
| 24 | + all_compliance_infos = UserComplianceInfo.alive.where.not(tax_id: nil).includes(:user) |
| 25 | + |
| 26 | + tins.each do |tin| |
| 27 | + compliance_info = all_compliance_infos.find { |ci| ci.tax_id == tin } |
| 28 | + |
| 29 | + if compliance_info.nil? |
| 30 | + not_found_tins << tin |
| 31 | + next |
| 32 | + end |
| 33 | + |
| 34 | + user = compliance_info.user |
| 35 | + found_users << { |
| 36 | + user:, |
| 37 | + compliance_info:, |
| 38 | + tin:, |
| 39 | + } |
| 40 | + end |
| 41 | + |
| 42 | + puts "\n=== FOUND USERS (#{found_users.count}) ===" |
| 43 | + puts "================================================================================" |
| 44 | + |
| 45 | + if found_users.any? |
| 46 | + found_users.each_with_index do |data, index| |
| 47 | + user = data[:user] |
| 48 | + tin = data[:tin] |
| 49 | + |
| 50 | + puts "\n#{index + 1}. User ID: #{user.id}" |
| 51 | + puts " Email: #{user.email}" |
| 52 | + puts " Name: #{user.name}" |
| 53 | + puts " Legal Name: #{user.legal_name}" |
| 54 | + puts " TIN: ***#{tin[-4..]}" |
| 55 | + puts " Current Status: #{data[:compliance_info].requires_tin_reverification ? 'Already flagged' : 'Not flagged'}" |
| 56 | + |
| 57 | + if dry_run |
| 58 | + puts " [DRY RUN] Would flag this user for TIN re-verification and send email" |
| 59 | + else |
| 60 | + begin |
| 61 | + data[:compliance_info].update!( |
| 62 | + requires_tin_reverification: true, |
| 63 | + tax_id_status: nil |
| 64 | + ) |
| 65 | + UserMailer.tin_reverification_required(user.id).deliver_later |
| 66 | + puts " ✓ Flagged for TIN re-verification and email sent" |
| 67 | + rescue => e |
| 68 | + puts " ✗ Error: #{e.message}" |
| 69 | + end |
| 70 | + end |
| 71 | + end |
| 72 | + else |
| 73 | + puts "No users found with the provided TINs" |
| 74 | + end |
| 75 | + |
| 76 | + if not_found_tins.any? |
| 77 | + puts "\n=== NOT FOUND TINS (#{not_found_tins.count}) ===" |
| 78 | + puts "================================================================================" |
| 79 | + not_found_tins.each do |tin| |
| 80 | + puts " #{tin}" |
| 81 | + end |
| 82 | + end |
| 83 | + |
| 84 | + puts "\n================================================================================" |
| 85 | + puts "SUMMARY:" |
| 86 | + puts "================================================================================" |
| 87 | + puts " Total TINs processed: #{tins.count}" |
| 88 | + puts " Users found: #{found_users.count}" |
| 89 | + puts " TINs not found: #{not_found_tins.count}" |
| 90 | + |
| 91 | + if dry_run |
| 92 | + puts "\n✓ Dry run complete! No changes were made." |
| 93 | + puts " To actually flag users and send emails, run with dry_run: false" |
| 94 | + else |
| 95 | + puts "\n✓ Flagging complete!" |
| 96 | + puts " Users have been flagged for TIN re-verification and emails have been sent." |
| 97 | + end |
| 98 | + end |
| 99 | +end |
0 commit comments