#!/usr/bin/perl use strict; use Getopt::Std; use Data::Faker; use Business::CreditCard; use FS::UID qw(adminsuidsetup); use FS::Record qw(qsearch); use FS::cust_main; use FS::cust_pkg; use FS::svc_acct; use FS::svc_phone; use FS::svc_domain; use FS::svc_broadband; use FS::state; use Data::Dumper; use strict; my $refnum = 1; #my @pkgs = ( 4, 5, 6 ); use vars qw( $opt_p $opt_a $opt_k ); getopts('p:a:k:'); my $agentnum = $opt_a || 1; my @pkgs = split(/,\s*/, $opt_k); @pkgs or die &usage; my $user = shift or die &usage; my $num = shift or die &usage; adminsuidsetup($user); my $onum = $num; my $start = time; our $faker = Data::Faker->new; our @states = map { $_->get('state') } qsearch('state', { country => 'US' }); sub location { # yeah, produces cities/states/zip codes that don't match up; # a future version of this might check for that my $tries = 5; my $error; while ($tries--) { # Data::Faker sometimes returns stupid results that don't pass our data # checks. keep trying until it gets it right. my $location = FS::cust_location->new({ 'address1' => $faker->street_address, 'address2' => (rand() < 0.2 ? ($faker->secondary_unit_designator . ' ' . $faker->secondary_unit_number) : '' ), 'city' => $faker->city, 'state' => $states[ int(rand($#states)) ], 'zip' => $faker->us_zip_code, 'country' => 'US', 'custnum' => 1, # just so we can check it }); $error = $location->check; if (!$error) { $location->custnum(''); return $location; } } die "couldn't create a valid location: $error\n"; } for ( my $num = 0; $num < $onum; $num++ ) { print "$num\n"; my $cust_main = new FS::cust_main { 'agentnum' => $agentnum, 'refnum' => $refnum, 'first' => $faker->first_name, 'last' => $faker->last_name, 'company' => ( $num % 2 ? $faker->company : '' ), #half with companies.. 'daytime' => $faker->phone_number, 'night' => $faker->phone_number, 'payby' => '', 'payip' => $faker->ip_address, }; $cust_main->set('bill_location', location()); if ( $num % 10 == 0 ) { $cust_main->set('ship_location', location()); } else { $cust_main->set('ship_location', $cust_main->get('bill_location')); } if ( $num % 3 > 0 ) { $cust_main->payby('CARD'); my $cardnum = '4123'. sprintf('%011u', int(rand(100000000000)) ); $cust_main->payinfo( $cardnum. generate_last_digit($cardnum) ); $cust_main->paydate( '2020-05-01' ); } else { $cust_main->payby('CHEK'); my $payinfo = sprintf('%7u@%09u', int(rand(10000000)), int(rand(1000000000)) ); $cust_main->payinfo($payinfo); $cust_main->payname( 'Bank of Testing' ); } my $error = $cust_main->insert; die Dumper($cust_main)."\ninserting cust_main:\n$error\n" if $error; # scatter start dates within the first 6 months my $now = time; my $period = 60*60*24*180; my $start = $now + int(rand($period)); # give each customer half of the specified set of packages for (my $i = 0; $i <= scalar(@pkgs)/2; $i++) { my $pkgpart = $pkgs[ ($num + $i) % scalar(@pkgs) ], my @svcs; my $cust_pkg = new FS::cust_pkg { 'pkgpart' => $pkgpart, 'start_date' => $start, }; foreach my $pkg_svc (qsearch('pkg_svc', { pkgpart => $pkgpart, quantity => {op => '>', value => 0}, })) { my $part_svc = $pkg_svc->part_svc; my $svc; if ( $part_svc->svcdb eq 'svc_acct' ) { $svc = new FS::svc_acct { 'username' => $faker->username, }; $svc->set_password; while ( FS::svc_acct->count('username = ?', $svc->username) ) { my $username = $svc->username; $username++; $svc->username($username); } } elsif ( $part_svc->svcdb eq 'svc_broadband' ) { $svc = new FS::svc_broadband { 'ip_addr' => sprintf('10.%u.%u.%u', int(rand(255)), int(rand(255)), int(rand(255)) ), 'mac_addr' => sprintf('00:00:%02x:%02x:%02x:%02x', int(rand(255)), int(rand(255)), int(rand(255)), int(rand(255)) ), }; } elsif ( $part_svc->svcdb eq 'svc_phone' ) { my $phonenum = $faker->phone_number; $phonenum =~ s/\D//g; $svc = new FS::svc_phone { 'phonenum' => $phonenum, 'pin' => sprintf('%05u', int(rand(100000))), }; } elsif ( $part_svc->svcdb eq 'svc_domain' ) { my $domain; do { $domain = $faker->domain_word . '.com'; } until FS::svc_domain->count('domain = ?', $domain) == 0; $svc = new FS::svc_domain { domain => $domain }; } else { # unsupported svc_x; do nothing next; } $svc->set('svcpart', $part_svc->svcpart); push @svcs, $svc; } # foreach $pkg_svc $error = $cust_main->order_pkg( cust_pkg => $cust_pkg, svcs => \@svcs, ); die Dumper($cust_pkg) . "\ninserting cust_pkg:\n$error\n" if $error; } # package } # customer my $end = time; my $sec = $end-$start; $sec=1 if $sec==0; my $persec = $onum / $sec; print "$onum customers inserted in $sec seconds ($persec customers/sec)\n"; #--- sub usage { die "Usage:\n\n customer-faker [ -a agentnum ] [ -k pkgpart,pkgpart,pkgpart... ] user num_fakes\n"; }