X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FMisc.pm;h=dca906cdead14387acf24981faf1e8a9c55b1074;hb=0b94e40c533288be69a4fe60da36a385d31eff7f;hp=e254b51fc0c03cd76f9eedc8db03379eecc93ebe;hpb=aa8d3305bddaca26d9222ebfa48af191d28f8230;p=freeside.git diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm index e254b51fc..dca906cde 100644 --- a/FS/FS/Misc.pm +++ b/FS/FS/Misc.pm @@ -7,15 +7,17 @@ use Carp; use Data::Dumper; use IPC::Run qw( run timeout ); # for _pslatex use IPC::Run3; # for do_print... should just use IPC::Run i guess +use File::Temp; #do NOT depend on any FS:: modules here, causes weird (sometimes unreproducable #until on client machine) dependancy loops. put them in FS::Misc::Something #instead @ISA = qw( Exporter ); @EXPORT_OK = qw( generate_email send_email send_fax - states_hash counties state_label + states_hash counties cities state_label card_types generate_ps generate_pdf do_print + csv_from_fixed ); $DEBUG = 0; @@ -554,6 +556,7 @@ Returns a list of counties for this state and country. sub counties { my( $state, $country ) = @_; + map { $_ } #return num_counties($state, $country) unless wantarray; sort map { s/[\n\r]//g; $_; } map { $_->county } qsearch({ @@ -565,6 +568,28 @@ sub counties { }); } +=item cities COUNTY STATE COUNTRY + +Returns a list of cities for this county, state and country. + +=cut + +sub cities { + my( $county, $state, $country ) = @_; + + map { $_ } #return num_cities($county, $state, $country) unless wantarray; + sort map { s/[\n\r]//g; $_; } + map { $_->city } + qsearch({ + 'select' => 'DISTINCT city', + 'table' => 'cust_main_county', + 'hashref' => { 'county' => $county, + 'state' => $state, + 'country' => $country, + }, + }); +} + =item state_label STATE COUNTRY_OR_LOCALE_SUBCOUNRY_OBJECT =cut @@ -774,6 +799,65 @@ sub do_print { } +=item csv_from_fixed, FILEREF COUNTREF, [ LENGTH_LISTREF, [ CALLBACKS_LISTREF ] ] + +Converts the filehandle referenced by FILEREF from fixed length record +lines to a CSV file according to the lengths specified in LENGTH_LISTREF. +The CALLBACKS_LISTREF refers to a correpsonding list of coderefs. Each +should return the value to be substituted in place of its single argument. + +Returns false on success or an error if one occurs. + +=cut + +sub csv_from_fixed { + my( $fhref, $countref, $lengths, $callbacks) = @_; + + eval { require Text::CSV_XS; }; + return $@ if $@; + + my $ofh = $$fhref; + my $unpacker = new Text::CSV_XS; + my $total = 0; + my $template = join('', map {$total += $_; "A$_"} @$lengths) if $lengths; + + my $dir = "%%%FREESIDE_CACHE%%%/cache.$FS::UID::datasrc"; + my $fh = new File::Temp( TEMPLATE => "FILE.csv.XXXXXXXX", + DIR => $dir, + UNLINK => 0, + ) or return "can't open temp file: $!\n" + if $template; + + while ( defined(my $line=<$ofh>) ) { + $$countref++; + if ( $template ) { + my $column = 0; + + chomp $line; + return "unexpected input at line $$countref: $line". + " -- expected $total but received ". length($line) + unless length($line) == $total; + + $unpacker->combine( map { my $i = $column++; + defined( $callbacks->[$i] ) + ? &{ $callbacks->[$i] }( $_ ) + : $_ + } unpack( $template, $line ) + ) + or return "invalid data for CSV: ". $unpacker->error_input; + + print $fh $unpacker->string(), "\n" + or return "can't write temp file: $!\n"; + } + } + + if ( $template ) { close $$fhref; $$fhref = $fh } + + seek $$fhref, 0, 0; + ''; +} + + =back =head1 BUGS