invoice_sections_with_taxes per-agent, RT#79636
[freeside.git] / eg / TEMPLATE_cust_main.import
1 #!/usr/bin/perl -w
2 #
3 # Template for importing legacy customer data
4
5 use strict;
6 use Date::Parse;
7 use FS::UID qw(adminsuidsetup datasrc);
8 use FS::Record qw(fields qsearch qsearchs);
9 use FS::cust_main;
10 use FS::cust_pkg;
11 use FS::cust_svc;
12 use FS::svc_acct;
13 use FS::pkg_svc;
14
15 my $user = shift or die &usage;
16 adminsuidsetup $user;
17
18 # use these for the imported cust_main records (unless you have these in legacy
19 # data)
20 my($agentnum)=4;
21 my($refnum)=5;
22
23 # map from legacy billing data to pkgpart, maps imported field
24 # LegacyBillingData to pkgpart.  your names and pkgparts will be different
25 my(%pkgpart)=(
26   'Employee'          => 10,
27   'Business'          => 11,
28   'Individual'        => 12,
29   'Basic PPP'         => 13,
30   'Slave'             => 14,
31   'Co-Located Server' => 15,
32   'Virtual Web'       => 16,
33   'Perk Mail'         => 17,
34   'Credit Hold'       => 18,
35 );
36
37 my($file)="legacy_file";
38
39 open(CLIENT,$file) 
40   or die "Can't open $file: $!"; 
41
42 # put a tab-separated header atop the file, or define @fields
43 #   (use these names or change them below)
44 #
45 # for cust_main
46 #   custnum - unique
47 #   last - (name)
48 #   first - (name)
49 #   company
50 #   address1
51 #   address2
52 #   city
53 #   state
54 #   zip
55 #   country
56 #   daytime - (phone)
57 #   night - (phone)
58 #   fax
59 #   payby - CARD, BILL or COMP
60 #   payinfo - Credit card #, P.O. # or COMP authorization
61 #   paydate - Expiration
62 #   tax - 'Y' for tax exempt
63 # for cust_pkg
64 #   LegacyBillingData - maps via %pkgpart above to a pkgpart
65 # for svc_acct
66 #   username
67
68 my($header);
69 $header=<CLIENT>;
70 chop $header;
71 my(@fields)=map { /^\s*(.*[^\s]+)\s*$/; $1 } split(/\t/,$header);
72 #print join("\n",@fields);
73
74 my($error);
75 my($link,$line)=(0,0);
76 while (<CLIENT>) {
77   chop; 
78   next if /^[\s\t]*$/; #skip any blank lines
79
80   #define %svc hash for this record
81   my(@record)=split(/\t/);
82   my(%svc);
83   foreach (@fields) {
84     $svc{$_}=shift @record;   
85   }
86
87   # might need to massage some data like this
88   $svc{'payby'} =~ s/^Credit Card$/CARD/io;
89   $svc{'payby'} =~ s/^Check$/BILL/io;
90   $svc{'payby'} =~ s/^Cash$/BILL/io;
91   $svc{'payby'} =~ s/^$/BILL/o;
92   $svc{'First'} =~ s/&/and/go; 
93   $svc{'Zip'} =~ s/\s+$//go;
94
95   my($cust_main) = new FS::cust_main ( {
96     'custnum'  => $svc{'custnum'},
97     'agentnum' => $agentnum,
98     'last'     => $svc{'last'},
99     'first'    => $svc{'first'},
100     'company'  => $svc{'company'},
101     'address1' => $svc{'address1'},
102     'address2' => $svc{'address2'},
103     'city'     => $svc{'city'},
104     'state'    => $svc{'state'},
105     'zip'      => $svc{'zip'},
106     'country'  => $svc{'country'},
107     'daytime'  => $svc{'daytime'},
108     'night'    => $svc{'night'},
109     'fax'      => $svc{'fax'},
110     'payby'    => $svc{'payby'},
111     'payinfo'  => $svc{'payinfo'},
112     'paydate'  => $svc{'paydate'},
113     'payname'  => $svc{'payname'},
114     'tax'      => $svc{'tax'},
115     'refnum'   => $refnum,
116   } );
117
118   $error=$cust_main->insert;
119
120   if ( $error ) {
121     warn $cust_main->_dump;
122     warn map "$_: ". $svc{$_}. "|\n", keys %svc;
123     die $error;
124   }
125
126   my($cust_pkg)=new FS::cust_pkg ( {
127     'custnum' => $svc{'custnum'},
128     'pkgpart' => $pkgpart{$svc{'LegacyBillingData'}},
129     'setup'   => '', 
130     'bill'    => '',
131     'susp'    => '',
132     'expire'  => '',
133     'cancel'  => '',
134   } );
135
136   $error=$cust_pkg->insert;
137   if ( $error ) {
138     warn $svc{'LegacyBillingData'};
139     die $error;
140   }
141
142   unless ( $svc{'username'} ) {
143     warn "Empty login";
144   } else {
145     #find svc_acct record (imported with bin/svc_acct.import) for this username
146     my($svc_acct)=qsearchs('svc_acct',{'username'=>$svc{'username'}});
147     unless ( $svc_acct ) {
148       warn "username ", $svc{'username'}, " not found\n";
149     } else {
150       #link to the cust_pkg record we created above
151
152       #find cust_svc record for this svc_acct record
153       my($o_cust_svc)=qsearchs('cust_svc',{
154         'svcnum' => $svc_acct->svcnum,
155         'pkgnum' => '',
156       } );
157       unless ( $o_cust_svc ) {
158         warn "No unlinked cust_svc for svcnum ", $svc_acct->svcnum;
159       } else {
160
161         #make sure this svcpart is in pkgpart
162         my($pkg_svc)=qsearchs('pkg_svc',{
163           'pkgpart'  => $pkgpart{$svc{'LegacyBillingData'}},
164           'svcpart'  => $o_cust_svc->svcpart,
165           'quantity' => 1,
166         });
167         unless ( $pkg_svc ) {
168           warn "login ", $svc{'username'}, ": No svcpart ", $o_cust_svc->svcpart,
169                " for pkgpart ", $pkgpart{$svc{'Acct. Type'}}, "\n" ;
170         } else {
171
172           #create new cust_svc record linked to cust_pkg record 
173           my($n_cust_svc) = new FS::cust_svc ({
174             'svcnum'  => $o_cust_svc->svcnum,
175             'pkgnum'  => $cust_pkg->pkgnum,
176             'svcpart' => $pkg_svc->svcpart,
177           });
178           my($error) = $n_cust_svc->replace($o_cust_svc);
179           die $error if $error;
180           $link++;
181         }
182       }
183     }
184   }
185
186   $line++;
187
188 }
189
190 warn "\n$link of $line lines linked\n";
191
192 # ---
193
194 sub usage {
195   die "Usage:\n\n  cust_main.import user\n";
196 }