6 use Business::CreditCard;
7 use FS::UID qw(adminsuidsetup);
8 use FS::Record qw(qsearch);
14 use FS::svc_broadband;
21 #my @pkgs = ( 4, 5, 6 );
23 use vars qw( $opt_p $opt_a $opt_k );
26 my $agentnum = $opt_a || 1;
28 my @pkgs = split(/,\s*/, $opt_k);
31 my $user = shift or die &usage;
32 my $num = shift or die &usage;
33 adminsuidsetup($user);
38 our $faker = Data::Faker->new;
39 our @states = map { $_->get('state') } qsearch('state', { country => 'US' });
42 # yeah, produces cities/states/zip codes that don't match up;
43 # a future version of this might check for that
47 # Data::Faker sometimes returns stupid results that don't pass our data
48 # checks. keep trying until it gets it right.
49 my $location = FS::cust_location->new({
50 'address1' => $faker->street_address,
51 'address2' => (rand() < 0.2 ?
52 ($faker->secondary_unit_designator . ' ' . $faker->secondary_unit_number)
55 'city' => $faker->city,
56 'state' => $states[ int(rand($#states)) ],
57 'zip' => $faker->us_zip_code,
59 'custnum' => 1, # just so we can check it
61 $error = $location->check;
63 $location->custnum('');
67 die "couldn't create a valid location: $error\n";
70 for ( my $num = 0; $num < $onum; $num++ ) {
73 my $cust_main = new FS::cust_main {
74 'agentnum' => $agentnum,
76 'first' => $faker->first_name,
77 'last' => $faker->last_name,
78 'company' => ( $num % 2 ? $faker->company : '' ), #half with companies..
79 'daytime' => $faker->phone_number,
80 'night' => $faker->phone_number,
82 'payip' => $faker->ip_address,
84 $cust_main->set('bill_location', location());
85 if ( $num % 10 == 0 ) {
86 $cust_main->set('ship_location', location());
88 $cust_main->set('ship_location', $cust_main->get('bill_location'));
92 $cust_main->payby('CARD');
93 my $cardnum = '4123'. sprintf('%011u', int(rand(100000000000)) );
94 $cust_main->payinfo( $cardnum. generate_last_digit($cardnum) );
95 $cust_main->paydate( '2020-05-01' );
97 $cust_main->payby('CHEK');
98 my $payinfo = sprintf('%7u@%09u', int(rand(10000000)), int(rand(1000000000)) );
99 $cust_main->payinfo($payinfo);
100 $cust_main->payname( 'Bank of Testing' );
103 my $error = $cust_main->insert;
104 die Dumper($cust_main)."\ninserting cust_main:\n$error\n" if $error;
106 # scatter start dates within the first 6 months
108 my $period = 60*60*24*180;
109 my $start = $now + int(rand($period));
111 # give each customer half of the specified set of packages
112 for (my $i = 0; $i <= scalar(@pkgs)/2; $i++) {
114 my $pkgpart = $pkgs[ ($num + $i) % scalar(@pkgs) ],
116 my $cust_pkg = new FS::cust_pkg {
117 'pkgpart' => $pkgpart,
118 'start_date' => $start,
120 foreach my $pkg_svc (qsearch('pkg_svc', { pkgpart => $pkgpart,
121 quantity => {op => '>', value => 0},
124 my $part_svc = $pkg_svc->part_svc;
126 if ( $part_svc->svcdb eq 'svc_acct' ) {
127 $svc = new FS::svc_acct {
128 'username' => $faker->username,
132 while ( FS::svc_acct->count('username = ?', $svc->username) ) {
133 my $username = $svc->username;
135 $svc->username($username);
137 } elsif ( $part_svc->svcdb eq 'svc_broadband' ) {
138 $svc = new FS::svc_broadband {
139 'ip_addr' => sprintf('10.%u.%u.%u',
144 'mac_addr' => sprintf('00:00:%02x:%02x:%02x:%02x',
151 } elsif ( $part_svc->svcdb eq 'svc_phone' ) {
152 my $phonenum = $faker->phone_number;
153 $phonenum =~ s/\D//g;
154 $svc = new FS::svc_phone {
155 'phonenum' => $phonenum,
156 'pin' => sprintf('%05u', int(rand(100000))),
158 } elsif ( $part_svc->svcdb eq 'svc_domain' ) {
161 $domain = $faker->domain_word . '.com';
162 } until FS::svc_domain->count('domain = ?', $domain) == 0;
163 $svc = new FS::svc_domain {
167 # unsupported svc_x; do nothing
170 $svc->set('svcpart', $part_svc->svcpart);
174 $error = $cust_main->order_pkg(
175 cust_pkg => $cust_pkg,
178 die Dumper($cust_pkg) . "\ninserting cust_pkg:\n$error\n" if $error;
185 my $sec = $end-$start;
187 my $persec = $onum / $sec;
188 print "$onum customers inserted in $sec seconds ($persec customers/sec)\n";
193 die "Usage:\n\n customer-faker [ -a agentnum ] [ -k pkgpart,pkgpart,pkgpart... ] user num_fakes\n";