Return.pl
#!/usr/bin/perl ####### ## Collins, Chris type ## Oct 2014 ######## ## insert daily orders on emergency use strict ; use warnings ; push( @INC, "/jet/prod/include" ) ; use Getopt::Long ; use Data::Dumper ; use POSIX qw( strftime ) ; use File::Basename ; use File::Path qw(make_path remove_tree) ; use Log::Log4perl ; use DBI ; use Time::Local ; use Date::Calc qw(Delta_Days) ; use Sys::Hostname ; use SendMail 2.04 ; use File::Spec::Functions ; use Array::Utils qw(:all) ; my $Help ; my $Date ; my $Log ; my $noEmail ; my $job ; my $BATCH_PREFIX ; my $ref = {} ; my $verbose = 1 ; my $simulateError = 0 ; my $testDB = 0 ; my $hostname = hostname ; $Data::Dumper::Sortkeys = 1 ; $|++ ; my $script = &scriptName ( $ref ) ; &getOptions ( $ref ) ; if ( $testDB ) { $ref->{ TESTDB } = 1 ; } if ( $Help ) { &Help ( @_ ) ; } &getLocalEnv ( $ref ) ; &getDate ( $ref ) ; &getEnv ( "/jet/prod/TJX/env.ini" ) ; my $log = &log4p () ; $log->info ( "On $ref->{config}->{ENV}" ) ; $log->info ( "Using Database $ref->{CARD}->{SID}" ) ; $ref->{ JOB } = $job ; $log->info ( "Using Job : $ref->{JOB} " ) ; #&getOrders($ref); #&getPrisdOrders ( $ref ) ; #foreach my $order (@{$ref->{ORDER}}){ &getSerial ( $ref ) ; # print Dumper $ref->{TRA}; # print Dumper $ref->{SER}; #} &getTracking ( $ref ) ; &output ( $ref ) ; #&sendMail($ref); $log->info ( "The End" ) ; exit( 0 ) ; ############################ #functions ############################ sub output { my $ref = shift( @_ ) ; my $function = ( caller( 0 ) )[ 3 ] ; $log->debug ( "$function" ) ; my $date = &getDateTime ( $ref ) ; my $outputFile = $ref->{ config }->{ RETURNFILE } . "/" . $ref->{ JOB } . "_Return-" . $date . ".csv" ; open( FH, "> $outputFile" ) ; my $sep = ','; my $quote = '\''; print FH "STORE" . $sep . $quote . "ITEM" . $quote . $sep . $quote . "BUNDLE" . $quote . $sep . $quote . "BEG_CARD" . $quote . $sep . $quote . "END_CARD" . $quote . $sep . $quote . "TRACKING" . $quote . $sep . $quote . "ORDER" . $quote . $sep . $quote . "QTY" . $quote . "\n" ; $log->debug ( "STORE|ITEM|BUNDLE|BEG_CARD|END_CARD|TRACKING" ) ; foreach my $ORDER ( keys %{ $ref->{ SER } } ) { $log->debug ( "ORDER : $ORDER" ) ; foreach my $ITEM ( keys %{ $ref->{ SER }->{ $ORDER } } ) { $log->debug ( "ITEM : $ITEM" ) ; foreach my $BUNDLE ( keys %{ $ref->{ SER }->{ $ORDER }->{ $ITEM } } ) { $log->debug ( "BUNDLE : $BUNDLE" ) ; my $STORE = $ref->{ SER }->{ $ORDER }->{ $ITEM }->{ $BUNDLE }->{ STORE } ; my $BEG_CARD = $ref->{ SER }->{ $ORDER }->{ $ITEM }->{ $BUNDLE }->{ BEG_CARD } ; my $END_CARD = $ref->{ SER }->{ $ORDER }->{ $ITEM }->{ $BUNDLE }->{ END_CARD } ; my $TRACKING = $ref->{ SER }->{ $ORDER }->{ $ITEM }->{ $BUNDLE }->{ TRACKING } ; my $QTY = $ref->{ SER }->{ $ORDER }->{ $ITEM }->{ $BUNDLE }->{ QTY } ; print FH $STORE . $sep . $quote . $ITEM . $quote . $sep . $quote . $BUNDLE . $quote . $sep . $quote . $BEG_CARD . $quote . $sep . $quote . $END_CARD . $quote . $sep . $quote . $TRACKING . $quote . $sep . $quote . $ORDER . $quote . $sep . $quote . $QTY . $quote . "\n" ; $log->debug ( "$STORE|$ITEM|$BUNDLE|$BEG_CARD|$END_CARD|$TRACKING" ) ; } } } close FH ; } sub getOrders { my $ref = shift( @_ ) ; my $function = ( caller( 0 ) )[ 3 ] ; $log->info ( "$function" ) ; my $dbh = &connectToDB () ; my $sql = qq{ select distinct order_number from fulfill.orders where client_code = 36 and po = ? } ; $log->debug ( " SQL" ) ; $log->debug ( " \t$sql" ) ; my $query = $dbh->prepare ( $sql ) ; $log->debug ( "Variables are $ref->{JOB}" ) ; $query->execute ( $ref->{ JOB } ) ; while ( my $hash = $query->fetchrow_hashref ) { unless ( defined $hash->{ ORDER_NUMBER } ) { $hash->{ ORDER_NUMBER } = '' ; } my $ORDER = &trim ( $hash->{ ORDER_NUMBER } ) ; push( @{ $ref->{ ORDER } }, $ORDER ) ; $log->debug ( "ORDER : $ORDER" ) ; } } sub getSerial { my $ref = shift( @_ ) ; my $function = ( caller( 0 ) )[ 3 ] ; $log->info ( "$function" ) ; my $dbh = &connectToDB () ; my $sql = qq{ SELECT B.IN_ORDER ORDER_N, substr(O.SHIPTO_COMPANY,1,1)|| regexp_replace(SHIPTO_COMPANY, '[^[:digit:]]') STORE, '17312001' || substr(B.ITEM_TYPE,2,4)ITEM, min(I.PIN) BEG_CARD, max(I.PIN) END_CARD, trim(B.BUNDLE_NUMBER) BUNDLE FROM FULFILL.BUNDLE B, FULFILL.ITEM I, FULFILL.ORDERS O Where SUBSTR(B.ITEM_TYPE,2,4) = SUBSTR(I.ITEM_TYPE,2,4) AND B.CLIENT_CODE = I.CLIENT_CODE AND B.BUNDLE_NUMBER = I.IN_BUNDLE AND B.IN_ORDER = O.ORDER_NUMBER AND B.IN_ORDER in ( select distinct order_number from fulfill.orders where client_code = 36 and po = ? ) group by O.SHIPTO_COMPANY, B.item_type, i.in_bundle, B.BUNDLE_NUMBER, B.IN_ORDER order by B.item_type } ; $log->debug ( " SQL" ) ; $log->debug ( " \t$sql" ) ; my $query = $dbh->prepare ( $sql ) ; #$query->execute($order); $query->execute ( $ref->{ JOB } ) ; #$query->execute ( ) ; while ( my $hash = $query->fetchrow_hashref ) { unless ( defined $hash->{ ORDER_N } ) { $hash->{ ORDER_N } = '' ; } unless ( defined $hash->{ STORE } ) { $hash->{ STORE } = '' ; } unless ( defined $hash->{ ITEM } ) { $hash->{ ITEM } = '' ; } unless ( defined $hash->{ BEG_CARD } ) { $hash->{ BEG_CARD } = '' ; } unless ( defined $hash->{ END_CARD } ) { $hash->{ END_CARD } = '' ; } unless ( defined $hash->{ BUNDLE } ) { $hash->{ BUNDLE } = '' ; } my $ORDER = &trim ( $hash->{ ORDER_N } ) ; my $STORE = &trim ( $hash->{ STORE } ) ; my $ITEM = &trim ( $hash->{ ITEM } ) ; my $BEG_CARD = &trim ( $hash->{ BEG_CARD } ) ; my $END_CARD = &trim ( $hash->{ END_CARD } ) ; my $BUNDLE = &trim ( $hash->{ BUNDLE } ) ; my $UNIQUE = $ITEM . "-" . $BUNDLE ; # 'ITEMBUNDLE-ITEM-BEG_CARD-or-END_CARD'; $ref->{ SER }->{ $ORDER }->{ $ITEM }->{ $BUNDLE }->{ BEG_CARD } = $BEG_CARD ; $ref->{ SER }->{ $ORDER }->{ $ITEM }->{ $BUNDLE }->{ END_CARD } = $END_CARD ; $ref->{ SER }->{ $ORDER }->{ $ITEM }->{ $BUNDLE }->{ STORE } = $STORE ; } return ; } sub getPrisdOrders { my $ref = shift( @_ ) ; my $order = shift( @_ ) ; my $function = ( caller( 0 ) )[ 3 ] ; $log->info ( "$function" ) ; my $dbh = &connectToPrismDB () ; my $sql = qq[ SELECT SH_ORDER ORDER_NUMBER FROM PWIN171.SH Where SH_CUST = '17312' AND SH_CUST_REF = ? AND SH_STATUS = '2' ] ; $log->debug ( " SQL" ) ; $log->debug ( " \t$sql" ) ; my $query = $dbh->prepare ( $sql ) ; $log->debug ( "Getting orders for job : $ref->{JOB}" ) ; $query->execute ( $ref->{ JOB } ) ; while ( my $hash = $query->fetchrow_hashref ) { unless ( defined $hash->{ ORDER_NUMBER } ) { $hash->{ ORDER_NUMBER } = '' ; } my $ORDER = &trim ( $hash->{ ORDER_NUMBER } ) ; push( @{ $ref->{ ORDER } }, $ORDER ) ; $log->debug ( "ORDER : $ORDER" ) ; } return ; } sub getTracking { my $ref = shift( @_ ) ; my $function = ( caller( 0 ) )[ 3 ] ; $log->info ( "$function" ) ; my $dbh = &connectToPrismDB () ; my $sql = qq[ select trim(SD_QTY_ORDER) QTY, trim(ST_PICK) PIC, trim( sd_order) O, trim(st_del_code) STORE, regexp_replace(sd_stock, '-') ITEM, ST_COURIER_REF TRACKING from sd, st where st_order = sd_order and trim(st_pick) = trim(SD_LAST_PICK_NUM) and trim(sd_cust) = '17312' and trim(sd_stock) is not null and trim(sd_order) in ( SELECT trim(SH_ORDER) ORDER_NUMBER FROM PWIN171.SH Where SH_CUST = '17312' AND SH_STATUS = '2' AND SH_CUST_REF = ? ) order by sd_order,st_del_code ] ; $log->debug ( " SQL" ) ; $log->debug ( " \t$sql" ) ; my $query = $dbh->prepare ( $sql ) ; $log->debug ( "Finding Tracking numbers for : $ref->{JOB}" ) ; $query->execute ( $ref->{ JOB } ) ; # $query->execute ( ) ; while ( my $hash = $query->fetchrow_hashref ) { unless ( defined $hash->{ O } ) { $hash->{ O } = '' ; } unless ( defined $hash->{ QTY } ) { $hash->{ QTY } = '' ; } unless ( defined $hash->{ STORE } ) { $hash->{ STORE } = '' ; } unless ( defined $hash->{ ITEM } ) { $hash->{ ITEM } = '' ; } unless ( defined $hash->{ TRACKING } ) { $hash->{ TRACKING } = '' ; } my $order = &trim ( $hash->{ O } ) ; my $QTY = &trim ( $hash->{ QTY } ) ; my $PIC = &trim ( $hash->{ PIC } ) ; my $STORE = &trim ( $hash->{ STORE } ) ; my $ITEM = &trim ( $hash->{ ITEM } ) ; my $TRACKING = &trim ( $hash->{ TRACKING } ) ; my $UNIQUE = $ITEM ; my $count = $QTY ; # interate over the bundles foreach my $bundle ( keys %{ $ref->{ SER }->{ $order }->{ $ITEM } } ) { if ( defined $ref->{ SER }->{ $order }->{ $ITEM }->{ $bundle }->{ TRACKING } ) { $log->debug ( "Tracker defined for order : $order Bundle : $bundle " ) ; next ; } $log->debug ( "Adding Tracking for order : $order Bundle : $bundle" ) ; $log->debug ( " \t$QTY : $PIC : $STORE : $ITEM : $TRACKING " ) ; $ref->{ SER }->{ $order }->{ $ITEM }->{ $bundle }->{ TRACKING } = $hash->{ TRACKING } ; $ref->{ SER }->{ $order }->{ $ITEM }->{ $bundle }->{ STORE } = $hash->{ STORE } ; $ref->{ SER }->{ $order }->{ $ITEM }->{ $bundle }->{ PIC } = $hash->{ PIC } ; $ref->{ SER }->{ $order }->{ $ITEM }->{ $bundle }->{ QTY } = $hash->{ QTY } ; $ref->{ TRA }->{ $order }->{ $ITEM }->{ $QTY }->{ PIC } = $hash->{ PIC } ; $ref->{ TRA }->{ $order }->{ $ITEM }->{ $QTY }->{ TRACKING } = $hash->{ TRACKING } ; } } return ; } sub sendMail() { my $ref = shift( @_ ) ; my $function = ( caller( 0 ) )[ 3 ] ; $log->debug ( "$function" ) ; $log->debug ( "Sending Email" ) ; my $ENV = $ref->{ config }->{ ENV } ; my $msg .= $ref->{ CARD }->{ SID } ; $msg .= "\n" ; $msg .= "$ref->{config}->{Log} \n" ; $msg .= "\n" ; my $emailSUBJ = "$ENV -- Chipotle DAILY Orders for $ref->{config}->{Date} ($0 on $hostname)" ; $emailSUBJ = "$ENV -- $ref->{config}->{Date} ($0 on $hostname)" ; my $emailSENDER = 'jetitmanager@jetlitho.com' ; # use the sender's address here my @emailRECIPIENTS ; if ( $ref->{ config }->{ simulateError } == 1 || $ref->{ TESTDB } ) { @emailRECIPIENTS = qw(christopherc@jetlitho.com) ; } else { @emailRECIPIENTS = split( /,/, $ref->{ config }->{ emailRECIPIENTS } ) ; } my $sm = new SendMail ( "jet-mail" ) ; $sm->From ( $emailSENDER ) ; $sm->To ( @emailRECIPIENTS ) ; $sm->Subject ( $emailSUBJ ) ; $sm->setMailBody ( $msg ) ; $log->debug ( "--[ From: $emailSENDER" ) ; $log->debug ( "--[ To: (" . join( ' ', @emailRECIPIENTS ) . ")" ) ; $log->debug ( "--[ Subject: $emailSUBJ" ) ; $log->debug ( "--[ Body: $msg" ) ; my $rv = $sm->sendMail () ; if ( $rv != 0 ) { $log->debug ( "\n\n\tAttempt to send mail failed \n $!\n" ) ; } else { $log->debug ( "\n\n\tAttempt to send mail successful\n" ) ; } return ; } sub log4p { my $function = ( caller( 0 ) )[ 3 ] ; print "$function \n" ; # Date used for the logs my $date = &getDateTime(); unless ( $Log ) { $Log = $script . "-" . $date . ".log" ; } $ref->{ config }->{ logDir } = "/jet/prod/log/$date/TJX" ; $ref->{ config }->{ Log } = $ref->{ config }->{ logDir } . "/" . $Log ; $ref->{ config }->{ Debug } = $ref->{ config }->{ logDir } . "/" . "Debug.out" ; $ref->{ config }->{ simulateError } = $simulateError ; # make the path make_path ( $ref->{ config }->{ logDir } ) ; my $log_conf = qq( log4perl.rootLogger = DEBUG, LOG, SCREEN log4perl.appender.LOG = Log::Log4perl::Appender::File log4perl.appender.LOG.filename = $ref->{config}->{Log} log4perl.appender.LOG.mode = append log4perl.appender.LOG.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.LOG.layout.ConversionPattern = %d %p %m %n log4perl.appender.DEBUG = Log::Log4perl::Appender::File log4perl.appender.DEBUG.filename = $ref->{config}->{Debug} log4perl.appender.DEBUG.mode = append log4perl.appender.DEBUG.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.DEBUG.layout.ConversionPattern = %d %p %m %n log4perl.appender.SCREEN = Log::Log4perl::Appender::Screen log4perl.appender.SCREEN.stderr = 0 log4perl.appender.SCREEN.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.SCREEN.layout.ConversionPattern = %d %p %m %n ) ; Log::Log4perl::init ( \$log_conf ) ; my $log = Log::Log4perl->get_logger () ; return $log ; } sub connectToPrismDB { my $dbh = DBI->connect ( "dbi:Oracle:host=$ref->{PRISM}->{SVER};sid=$ref->{PRISM}->{SID};port=$ref->{PRISM}->{PRT}", "$ref->{PRISM}->{USER}", "$ref->{PRISM}->{PASS}", { Warn => 1, ChopBlanks => 1, AutoCommit => 1, RaiseError => 1, PrintError => 1 } ) or die "Can't connect to Oracle database: $DBI::errstr\n" ; # 0 - Trace disabled. # 1 - Trace top-level DBI method calls returning with results or errors. # 2 - As above, adding tracing of top-level method entry with parameters. # 3 - As above, adding some high-level information from the driver # 4 - As above, adding more detailed information from the driver. # 5 to 15 - As above but with more and more internal information. my $trace = DBI->trace ( 0, "$0.dbitrace.out" ) ; return $dbh ; } sub connectToDB { my $dbh = DBI->connect ( "dbi:Oracle:host=$ref->{CARD}->{SVER};sid=$ref->{CARD}->{SID};port=1521", "$ref->{CARD}->{USER}", "$ref->{CARD}->{PASS}", { AutoCommit => 1, RaiseError => 1, PrintError => 1 } ) or die "Can't connect to Oracle database: $DBI::errstr\n" ; return $dbh ; } sub checkDay { my $ref = shift( @_ ) ; my $function = ( caller( 0 ) )[ 3 ] ; $log->info ( "$function" ) ; my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) ; my @nummonths = qw(01 02 03 04 05 06 07 08 09 10 11 12) ; my @weekDays = qw(SUN MON TUE WED THU FRI SAT) ; my ( $second, $minute, $hours, $dayOfMonth, $months, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings ) = localtime() ; my $theTime = "$weekDays[$dayOfWeek]" ; return $theTime ; } sub Help { my $function = ( caller( 0 ) )[ 3 ] ; $log->info ( "$function" ) ; print "--[ @_ \n" ; print <<"EOF"; \t--[ $0 \n \t--[ \t Simulate Error \t--[ -simulateError 1 \n \t--[ -s 1 \n \t--[ \t sends email \n \t--[ -testDB 1 \n \t--[ \t use the test DB \n EOF exit( 1 ) ; } sub getEnv { my $file = shift( @_ ) ; my $function = ( caller( 0 ) )[ 3 ] ; print "$function \n" ; unless ( -f $file ) { print "Could not find $file.\n" ; exit( 1 ) ; } open( FILE, "< $file" ) ; while ( <FILE> ) { chomp ; next if /^\s*\#/ ; next unless /=/ ; my ( $key, $variable ) = split( /=/, $_, 2 ) ; $variable =~ s/\s+//g ; $key =~ s/\s+//g ; $ref->{ config }->{ $key } = $variable ; } close FILE ; if ( $ref->{ TESTDB } ) { $ref->{ CARD }->{ SID } = $ref->{ config }->{ CARDTESTSID } ; $ref->{ CARD }->{ SVER } = $ref->{ config }->{ CARDTESTSVER } ; $ref->{ CARD }->{ USER } = $ref->{ config }->{ CARDTESTUSER } ; $ref->{ CARD }->{ PASS } = $ref->{ config }->{ CARDTESTPASS } ; $ref->{ CARD }->{ PRT } = $ref->{ config }->{ CARDTESTPRT } ; $ref->{ PRISM }->{ SID } = $ref->{ config }->{ PRISMTESTSID } ; $ref->{ PRISM }->{ SVER } = $ref->{ config }->{ PRISMTESTSVER } ; $ref->{ PRISM }->{ USER } = $ref->{ config }->{ PRISMTESTUSER } ; $ref->{ PRISM }->{ PASS } = $ref->{ config }->{ PRISMTESTPASS } ; $ref->{ PRISM }->{ PRT } = $ref->{ config }->{ PRISMTESTPRT } ; } else { $ref->{ CARD }->{ SID } = $ref->{ config }->{ CARDSID } ; $ref->{ CARD }->{ SVER } = $ref->{ config }->{ CARDSVER } ; $ref->{ CARD }->{ USER } = $ref->{ config }->{ CARDUSER } ; $ref->{ CARD }->{ PASS } = $ref->{ config }->{ CARDPASS } ; $ref->{ CARD }->{ PRT } = $ref->{ config }->{ CARDPRT } ; $ref->{ PRISM }->{ SID } = $ref->{ config }->{ PRISMSID } ; $ref->{ PRISM }->{ SVER } = $ref->{ config }->{ PRISMSVER } ; $ref->{ PRISM }->{ USER } = $ref->{ config }->{ PRISMUSER } ; $ref->{ PRISM }->{ PASS } = $ref->{ config }->{ PRISMPASS } ; $ref->{ PRISM }->{ PRT } = $ref->{ config }->{ PRISMPRT } ; } } sub getDate { my $ref = shift( @_ ) ; my $me = ( caller( 0 ) )[ 3 ] ; print( "$me \n" ) ; unless ( $Date ) { $Date = strftime ( '%Y%m%d', localtime ) ; $ref->{ config }->{ Date } = $Date ; } } sub getDateTime { my $ref = shift( @_ ) ; my $me = ( caller( 0 ) )[ 3 ] ; print( "$me \n" ) ; my $Date = strftime ( '%Y%m%d%H%M%S', localtime ) ; return $Date; } sub changeDir { my $dir = shift( @_ ) ; my $me = ( caller( 0 ) )[ 3 ] ; $log->info ( "$me " ) ; chdir( $dir ) ; $log->info ( "Change dir to $dir" ) ; } sub getOptions { my $ref = shift( @_ ) ; my $me = ( caller( 0 ) )[ 3 ] ; print( "$me \n" ) ; GetOptions ( "Help" => \$Help, "h" => \$Help, "Job=s" => \$job, "job=s" => \$job, "j=s" => \$job, "b=s" => \$BATCH_PREFIX, "t" => \$testDB, "testDB" => \$testDB, "n" => \$noEmail, ) # flag or warn( "Error in command line arguments &Help\n" ) ; } sub scriptName { my $ref = shift( @_ ) ; my $me = ( caller( 0 ) )[ 3 ] ; print( "$me \n" ) ; my $script = basename ( $0 ) ; $script =~ s/\.pl// ; return $script ; } sub getLocalEnv { my $ref = shift( @_ ) ; my $me = ( caller( 0 ) )[ 3 ] ; print( "$me \n" ) ; my $env = $ENV{ ENV } ; chomp( $env ) ; my $ENV = uc( $env ) ; $ref->{ config }->{ ENV } = $ENV ; } sub trim { my $s = shift ; $s =~ s/^\s+|\s+$//g ; return $s; }