#!/usr/bin/perl
##############################################################################
# Fido pos terminal interaction                        Version 1.01         #
# Copyright 2012 JJP. 1stmuse, Etranet                                      #
##############################################################################
# Version 0.90 produces only log file, some invalid events are not recorded
# Version 0.91 produces daily log file and monthly billing, with one day delay    
# Version 0.94 produces daily log file and monthly billing, with no delay     
# Version 0.98 produces daily log file and monthly billing, with no delay    
# Version 1.01 a. produces daily log file, ALL events are recorded
# Version 1.01 b. produces correct billing file, with immediate response                                                               #
##############################################################################

BEGIN {
    my $b__dir = (-d '/home/loyaltyh/perl'?'/home/loyaltyh/perl':( getpwuid($>) )[7].'/perl');
    unshift @INC,$b__dir.'5/lib/perl5',$b__dir.'5/lib/perl5/x86_64-linux-thread-multi',map { $b__dir . $_ } @INC;
}


$EXCLUSIVE_LOCK = 2;
$UNLOCK         = 8;
$amount_limit   = 100.00;
%card_hash =();

use CGI qw (:standard);
use CGI::Carp qw(fatalsToBrowser);
use lib qw(.);
use CGI qw(nph);

use Encode;
use utf8;


$database_cards    = "$ENV{'DOCUMENT_ROOT'}/fido/fido_clients.txt";	

 $date_time = &get_date;
 $when_added =$date_time;
 $date_time =~ s/at/~/g;
 ($date_,$day_time) = split (/\~/,$date_time);
 $date_ =~ s/[\s]//g;
 $date_ =~ s/[\/]/~/g;
 ($dd,$mm,$yy) = split (/\~/,$date_);

 $timeStamp =$date_time;
 $timeStamp =~ s/[\s]//g; # trim whitespaces

# Format $dd,$mm numbers with up to 2 leading zeroes
$dd = sprintf("%02d", $dd);
$mm = sprintf("%02d", $mm);

 $log_file   = "$ENV{'DOCUMENT_ROOT'}/fido/fido_log" . $yy . "_". $mm . "_". $dd . ".txt";

# Print HTTP header for PLAIN TEXT
print "Content-type: text/plain; charset=iso-8859-2\r\n\r\n";

# Capture data arriving from the POS-terminal
 $pos_query_string = &capture_client_data;

 $correct_flag =1; # regular log event
# Return Response String and acknowlage reception
 $server_response_string = &server_response($pos_query_string);
 
 $correct_flag =1;
 if ($server_response_string =~ /error/i) {$correct_flag =0;};
 #print "correct_flag  $correct_flag $server_response_string \r\n\r\n";

 chomp $server_response_string;
 chomp $pos_query_string;
 &store_log_record($pos_query_string,$server_response_string,$correct_flag);

 if ($correct_flag) { # only correct events are recorded in the billing file
     &store_billing_record($pos_query_string);    # to be commented/neutralised, if we do not want subsecond billing response
 };

exit;









sub capture_client_data {

   # FIDO  uses the POST method to capture POS-terminal client data  
   # Get the input
   my $client_data="";

   read(STDIN, $client_data, $ENV{'CONTENT_LENGTH'});

   return $client_data;
}































########### Capture stat #############
sub capture_stat{
   my $stranica = $_[0];
   if ($stranica !~ /stat\=\&/) {
     $start = qq~stat=~;
     $stop  = qq~&~;
     $stranica  =~ s/$start(.+?)$stop//;  
     my $stat = $1;
     $stat =~ s/\s//g;
     return $stat;
   }
   else {
     return -1;
   }
}



########### Capture cardid #############
sub capture_cardid{
   my $stranica = $_[0];
   if ($stranica !~ /cardid\=\&/) {
     $start = qq~cardid=~;
     $stop  = qq~&~;
     $stranica  =~ s/$start(.+?)$stop//;  
     my $cardid = $1;
     $cardid =~ s/\s//g;
     if ($cardid eq "") {$cardid =0};
     return $cardid;

   }
   else {
     return 0;
   }
}






########### Capture terminalid #############
sub capture_terminalid{

   my $query = $_[0];
   chomp $query;
   $query .= "&";
   if ($query !~ /posterminalid\=\&/) {
     my $start = qq~posterminalid=~; 
     my $stop  = qq~&~;
     $query  =~ s/$start(.+?)$stop//;  
     my $terminalid = $1;
     $terminalid =~ s/\s//g;
     return $terminalid;
   }
   else {
     return "0";
   }
}






sub iso_encode{

  my $ime = $_[0];
  $slovo_sh  =encode("iso-8859-1", chr(185)); # š
  $slovo_zh  =encode("iso-8859-1", chr(190)); # ž
  $slovo_cch =encode("iso-8859-1", chr(232)); # č
  $slovo_ch  =encode("iso-8859-1", chr(230)); # ć 
  $slovo_dj  =encode("iso-8859-1", chr(240)); # đ 

  $slovo_Sh  =encode("iso-8859-1", chr(169)); # Š
  $slovo_Zh  =encode("iso-8859-1", chr(174)); # Ž
  $slovo_Cch =encode("iso-8859-1", chr(200)); # Č
  $slovo_Ch  =encode("iso-8859-1", chr(198)); # Ć 
  $slovo_Dj  =encode("iso-8859-1", chr(208)); # Đ 


  $ime =~ s/\&\#269\;/$slovo_cch/g; #č B9
  $ime =~ s/\&\#263\;/$slovo_ch/g; #ć E5
  $ime =~ s/\&\#382\;/$slovo_zh/g; #ž B8
  $ime =~ s/\/$slovo_zh/g; #ž B8 
  $ime =~ s/\&\scaron\;/$slovo_sh/g; #š A8
  $ime =~ s/\/$slovo_sh/g; #š A8
  $ime =~ s/\&\#273\;/$slovo_dj/g; #đ F0

  $ime =~ s/\&\#268\;/$slovo_Cch/g; #Č
  $ime =~ s/\&\#262\;/$slovo_Ch/g;  #Ć C5
  $ime =~ s/\/$slovo_Zh/g; #Ž B4
  $ime =~ s/\&\#381\;/$slovo_Zh/g; #Ž B4
  $ime =~ s/\&\Scaron\;/$slovo_Sh/g; #Š A6 
  $ime =~ s/\/$slovo_Sh/g; #Š A6 
  $ime =~ s/\&\#272\;/$slovo_Dj/g; #Đ D0

  return "$ime" 
}















########### Search Cards Database #############
sub search_cards{
  my $search_for   = $_[0];
  my $target_record ="";
  my @results =();
  my $cardId;

  $search_for =~ s/\s//g;
  $search_for =~ s/\D//g;

  
  open (DB, "$database_cards") or die "Error opening database. $database_cards $!\n";
    while(<DB>){

        ($key,$dbuser,$when_added,$CARD_Broj_kartice,
         $CARD_OIB,$CARD_Ime,$CARD_Prezime,$CARD_Datum_rodjenja,
         $CARD_Exp_date,$CARD_Bodovi,$CARD_Brand,$CARD_email,$CARD_popup) = split(/\|/, $_);

          $cardId = +$CARD_Broj_kartice;
          $cardId =~ s/\s//g;

          if ($cardId > 0) { 
             if ($cardId == $search_for) { push @results, $_};
          };

          if ($key > 0) { 
              $card_hash{$key} = $_;
          } 
                
    } # End of while.
  close (DB);



my $count = @results;
if ($count < 1){ 
    $target_record =""; 
    $err_message="Error=100 Neregistrirana kartica $search_for"; 
}

if($count > 1){ 
    $target_record =""; 
    $err_message="Error=101 Too many results found for CardId $search_for"; 
}

if($count == 1){ 
    $target_record = @results[0];
    $err_message="";
};

return "$err_message|$target_record";

} # End of search_cards subroutine.









########### Search Transaction LOG #############
sub daily_saldo_summation{
  my $terminalid = $_[0];
  chomp $terminalid;
  my @results =();

  open (LOG, "$log_file") or die "Error opening log file $log_file $!\n";
    while(<LOG>){
      chomp $_;
     ($key,$LOGuser,$when_added, $FIDO_IP, $FIDO_Port, $FIDO_Referral, $FIDO_Client_name, $FIDO_Client_query,
      $FIDO_Server_response, $FIDO_Time_stamp, $FIDO_Correct ) = split(/\|/, $_); 
     if ($FIDO_Correct eq "1" ) {

         $FIDO_Client_query =canoninize($FIDO_Client_query) ;       # canoninize to lowercase ASCII
         $tid = &capture_terminalid($FIDO_Client_query);

         if ($terminalid eq $tid) { 
            push @results, $_
         };
     }
    } # End of while.
  close (LOG);

$count = @results;
# print  "$terminalid eq $tid";

if($count < 1){ 
  return "Error=170 Nema podataka za terminal $terminalid";
}



$daily_revenue=0;
$daily_expenditure=0;
foreach $record (@results){
    chomp $record;
     ($key,$LOGuser,$when_added, $FIDO_IP, $FIDO_Port, $FIDO_Referral, $FIDO_Client_name, $FIDO_Client_query,
      $FIDO_Server_response, $FIDO_Time_stamp, $FIDO_Correct )  = split(/\|/, $record);       
 
     $amount=0;
     $FIDO_Client_query =canoninize($FIDO_Client_query) ;       # canoninize to lowercase ASCII

     $amount = &capture_amount($FIDO_Client_query);
     $amount = sprintf("%.2f", $amount);
     if ($amount > 0) {$daily_revenue +=$amount}
     else {$daily_expenditure +=$amount;}

}; # End of foreach record loop.


$daily_revenue      = sprintf("%.2f", $daily_revenue);
$daily_expenditure  = sprintf("%.2f", $daily_expenditure);
return "revenue\=$daily_revenue\&expenditure\=$daily_expenditure\r\n"; 

} # End of log_results subroutine.














sub copy {
# copy("/folder1/abc.dat", "/folder2/abc.dat") or die("cannot copy\b");
my($from, $to) = @_;
  if(open(IN, $from))  {  
    if(open(OUT, ">$to")) {
  	 binmode(OUT);  
     	 while(read IN, $buf, 4096) {   
           print OUT $buf;
        }
        close IN;
        close OUT;
        return 1;
     }
     close IN;  
   }
}






sub append {
# copy("/folder1/abc.dat", "/folder2/abc.dat") or die("cannot append\b");
my($from, $to) = @_;
  if(open(IN, $from))
  {  if(open(OUT, ">>$to")) {
  	   binmode(OUT);  
     	 while(read IN, $buf, 4096)
        {   print OUT $buf;
        }
        close IN;
        close OUT;
        return 1;
     }
     close IN;
  }
    

  return 0;
}







sub append_billing {

 my $old_log = $_[0];
 my @log_line =();
 print "appending $old_log\n";

 $date_time = &get_date;
 $date_time =~ s/at/~/g;
 ($date,$day_time) = split (/\~/,$date_time);
 $date_ =~ s/[\s]//g;
 $date_ =~ s/[\/]/~/g;
 ($dd,$mm,$yy) = split (/\~/,$date_);

# Format $dd,$mm numbers with up to 2 leading zeroes
$dd = sprintf("%02d", $dd);
$mm = sprintf("%02d", $mm);

   open (LOG, "$old_log") or die "Error opening log file $old_log $!\n";
   @log_line = <LOG>;
   close (LOG);

   $billing   = "$ENV{'DOCUMENT_ROOT'}/fido_billing/billing" . $yy . "_". $mm .  ".txt";

   unless (-e $billing){ open (BILLING, ">$billing") or die "Error creating database.  $!\n"; }
   else { open (BILLING, ">>$billing") or die "Error opening database.  $!\n"; }
   flock BILLING, $EXCLUSIVE;
   seek BILLING, 0, 2;
   foreach $log_record (@log_line){
   ($key,$LOGuser,$when_added, $FIDO_IP, $FIDO_Port, $FIDO_Referral, $FIDO_Client_name, $FIDO_Client_input, $FIDO_Server_response,$unix_time) = split(/\|/, $log_record);       
          

     $client_string =canoninize($FIDO_Client_query) ;       # canoninize to lowercase ASCII

   $residum  = $key % 43200;
   $FIDO_Day = ($key - $residum) / 43200;
   $FIDO_TimeStamp  = $when_added;
   chomp $client_string;
   $FIDO_TerminalId = &capture_terminalid($client_string);
   # print "$client_string ......... $FIDO_TerminalId\n";

   $FIDO_CardId = &capture_cardid($client_string);
   $FIDO_Amount = &capture_amount($client_string);
   

   if ($FIDO_Amount =~ /^(\-)?\d+([\.\,]\d+)?$/) {
      $record = "$key\|$LOGuser\|$when_added\|$FIDO_Day\|$FIDO_TimeStamp\|$FIDO_TerminalId\|$FIDO_CardId\|$FIDO_Amount";
      print BILLING "$record\n";
   }

   } # End of while.

  flock BILLING, $UNLOCK;
  close (BILLING);
    

  return 0;
}








########### Move old log file #############
sub move_old_log_file{
# identify the name of the log file
# backup copy of the old log file
# delete the log file
# append billing data
  my $path        = "$ENV{'DOCUMENT_ROOT'}/fido";
  my $backup_path = "$ENV{'DOCUMENT_ROOT'}/fido_backup";
  my $billing_path= "$ENV{'DOCUMENT_ROOT'}/fido_billing";
  my $file;
  my @filenames =();
  my @regular_file_name=();

  opendir(DIRHANDLE,$path );
  @filenames = readdir(DIRHANDLE);
  closedir(DIRHANDLE);
  
  $x=-1;
  foreach $file (@filenames) {
   if ($file =~ /fido_log/gi) {
     $x++;
     chomp $file;
     push @regular_file_name,$file;
     #print "\nlog_file_name x: $file\n";     
   }
  }

 my @file_names =sort(@regular_file_name);
 my $n_files =@file_names;
 #print "n_files .. $n_files \n";
 if ($n_files >1) {
  my $file_name =@file_names[0];
  my $old_log_file ="$path/$file_name";
  my $backup_file_name="$backup_path/$file_name";
  print "\n\r previous day log_file_name : $old_log_file\n";
  #print "\n\r backup_file_name: $backup_file_name\n";
  if ($file_name ne "") {
    # &append_billing($old_log_file); # used for day by day appending of the billing data
    &copy($old_log_file, $backup_file_name) or die("cannot copy $old_log_file\b");
#   delete the log file
    unlink($old_log_file) or warn "Could not unlink $log_file_name: $!";
  } 
  else {
    print "\n\r inexistent old_log_file: $old_log_file\n";
  }
 }
}

########### end of Move old log file #############













########### Capture amount #############
sub capture_amount{
   my $stranica = $_[0];
   if ($stranica =~ /amount\=\&/) {
     return "0";
   }
   else {
     $stranica =~ s/amount\=(.+?)\&//;  
     my $bodovi = $1;
     $bodovi =~ s/\s//g;
     $bodovi =~ s/\+//g;
     $bodovi =~ s/\,/\./g;
     $bodovi =~ s/\%2C/./ig;
     return $bodovi;
   }
}








########### canoninize to lowercase ASCII #############
sub canoninize{
   my $txt = $_[0];
   $txt .= "&";
   $txt =~ tr/A-Z/a-z/ ;       # canoninize to lowercase ASCII
   $txt =~ s/\s//g; # strip all whitespaces

   return $txt;
}























############### backup_fido ################
sub backup_fido{
# Author : John Jan Popovic
# Date : July, 2012
# Purpose: This procedure performs DBase adonis Backup


my $database =  "$ENV{'DOCUMENT_ROOT'}/fido/fido_clients.txt";	

# Create %adonis_hash
 %DBADONIS_hash = ();
 @DB_line = ();
 $homedir = $root_ ;
  open (DB, "$database") || die "Error opening database. $! $database \n";
 @DB_line = <DB>;
 close (DB);

foreach $adonis_record (@DB_line){
   chomp $adonis_record;
   @altro =();
  ($key,$dbuser,$when_added,@altro) = split(/\|/, $adonis_record);
  $DBADONIS_hash{$key} = $adonis_record;
} ;
# end of creating of %adonis_hash

 $date_time = &get_date;
 $date_time =~ s/at/~/g;
 ($date_,$day_time) = split (/\~/,$date_time);
 $date_ =~ s/[\s]//g;
 $date_ =~ s/[\/]/~/g;
 ($dd,$mm,$yy) = split (/\~/,$date_);

# Format $dd,$mm numbers with up to 2 leading zeroes
$dd = sprintf("%02d", $dd);
$mm = sprintf("%02d", $mm);

 $backupdb = $root_ . "/fido_backup/backup_clients" . $yy. "_". $mm ."_$dd" . ".txt";

  # save ADONIS records
  my @ADONIS_line = ();
  @ADONIS_line = values (%DBADONIS_hash);

 flock DATABASE, $EXCLUSIVE;
 open (DATABASE, ">$database") or die "Error opening file: $!\n";

  foreach $adonis_line (@ADONIS_line){ 
    chomp $adonis_line;
    print DATABASE "$adonis_line\n";
  }

  # backup ADONIS records
 flock DATABASE, $EXCLUSIVE;
 open (DATABASE, ">$backupdb") or die "Error opening file: $!\n";

  foreach $adonis_line (@ADONIS_line){ 
    chomp $adonis_line;
    print DATABASE "$adonis_line\n";
  }

  close (DATABASE);
  flock DATABASE, $UNLOCK;
  # end of saving ADONIS backup records

  # save ADONIS records
  @ADONIS_line = ();
  @ADONIS_line = values (%DBADONIS_hash);

 flock DATABASE, $EXCLUSIVE;
 open (DATABASE, ">$database") or die "Error opening file: $!\n";

  foreach $adonis_line (@ADONIS_line){ 
    chomp $adonis_line;
    print DATABASE "$adonis_line\n";
  }

  close (DATABASE);
  flock DATABASE, $UNLOCK;
  # end of saving ADONIS db records



} # End of Backup_adonis subroutine.



























sub store_log_record{

   my $client_query = $_[0];
   my $server_response = $_[1];
   my $correct_record  = $_[2];

   chomp $server_response;

   my $key   = time();
   my $when_added= &get_date;
   $client_query =~ s/\%2C/./ig;
   chomp $client_query;
   chomp $server_response;

   my $record=$key;
   $record  .= "\|fido";
   $record  .= "\|$when_added\|$ENV{'REMOTE_ADDR'}\|$ENV{'REMOTE_PORT'}\|$ENV{'HTTP_REFERER'}\|$ENV{'HTTP_USER_AGENT'}";
   $record  .= "\|$client_query\|$server_response\|$when_added\|$correct_record\|";

   unless (-e $log_file){ # first Log record in a day
       print "first Log record in a day \r\n";
       open (LOG, ">$log_file") or die "Error=creating fido log file $log_file  $!\r\n"; 
       flock LOG, $EXCLUSIVE_LOCK;
       print LOG "$record\n";
       flock LOG, $UNLOCK;  
       close (LOG);
      &move_old_log_file;
      #&backup_fido;
   }
   else { # all other Log records in a day are just appended
       open (LOG, ">>$log_file") or die "Error=opening fido log $log_file  $!\r\n"; 
       flock LOG, $EXCLUSIVE_LOCK;
       seek  LOG, 0, 2;
       print LOG "$record\n";
       flock LOG, $UNLOCK;  
       close (LOG);
   }


}











################ Get Date ##################

sub get_date  {
  local ($sec,$min,$hour,$mday,$mm,$year,$wday,$yday,$isdst,$date);   
  local (@days, @months);
  my $date;
  @days = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
  @months = ('January','February','March','April','May','June','July','August','September','October','November','December');
  ($sec,$min,$hour,$mday,$mm,$year,$wday,$yday,$isdst) = localtime(time);
  if ($hour < 10)    {    $hour = "0$hour";    }
  if ($min < 10)     {    $min = "0$min";    }
  if ($sec < 10)    { $sec = "0$sec";    }

  $month =@months[$mon];
  $mm++;
  $year += 1900;
# Format $dd,$mm numbers with up to 2 leading zeroes
  my $mday_ = sprintf("%02d", $mday);
  my $mm_   = sprintf("%02d", $mm);
  $date = "$mday_/$mm_/$year at $hour\:$min\:$sec";
  return $date;
  }















sub store_billing_record {

 my $client_string = $_[0];
 my @log_line =();
 my $Billing_user ="fido";

 chomp $client_string;

 #print "$client_string\n";

 $date_time = &get_date;
 $date_time =~ s/at/~/g;
 ($date,$day_time) = split (/\~/,$date_time);
 $date_ =~ s/[\s]//g;
 $date_ =~ s/[\/]/~/g;
 ($dd,$mm,$yy) = split (/\~/,$date_);

# Format $dd,$mm numbers with up to 2 leading zeroes
$dd = sprintf("%02d", $dd);
$mm = sprintf("%02d", $mm);

   my $key   = time();

   $billing   = "$ENV{'DOCUMENT_ROOT'}/fido_billing/billing" . $yy . "_". $mm .  ".txt";

   unless (-e $billing){ open (BILLING, ">$billing") or die "Error creating database.  $!\n"; }
   else { open (BILLING, ">>$billing") or die "Error opening database.  $!\n"; }
   flock BILLING, $EXCLUSIVE;
   seek BILLING, 0, 2;
         

   $client_string =canoninize($client_string) ;       # canoninize to lowercase ASCII


   $residum  = $key % 43200;
   $FIDO_Day = ($key - $residum) / 43200;


   $FIDO_TerminalId = &capture_terminalid($client_string);
   $FIDO_CardId = &capture_cardid($client_string);
   $FIDO_Amount = &capture_amount($client_string);
   
   

   if ($FIDO_Amount =~ /^(\-)?\d+([\.\,]\d+)?$/) { # store the billing record only if AMOUNT has the correct currency_format
      $record = "$key\|$Billing_user\|$date_time\|$FIDO_Day\|$date_time\|$FIDO_TerminalId\|$FIDO_CardId\|$FIDO_Amount";
      print BILLING "$record\n";
   }



  flock BILLING, $UNLOCK;
  close (BILLING);
    

  return 0;
}














########### Search Terminals Database #############
sub search_terminals{
  my $search_for   = $_[0];
  my $target_record ="";
  my @results =();

  $search_for =~ s/\s//g;
  $search_for =~ s/\D//g;

  $database_shops    = "$ENV{'DOCUMENT_ROOT'}/fido/fido_shops.txt";	

  open (DB, "$database_shops") or die "Error opening database. $database_shops $!\n";
    while(<DB>){

           ($key,$owner,$time_stamp,
            $TERMINAL_terminalId,$TERMINAL_terminalPwd,$TERMINAL_salesPoint,$TERMINAL_address,
            $TERMINAL_telephone,$TERMINAL_email,$TERMINAL_GIS_coordinates,$TERMINAL_referral_person,
            $TERMINAL_contractNumber,$TERMINAL_activityStatus) = split(/\|/, $_);


          $terminalId = $TERMINAL_terminalId;
          $terminalId =~ s/\s//g;

          if ($terminalId ne "") { 
             if ($terminalId eq $search_for) { 
               push @results, $_;
               $activity = $TERMINAL_activityStatus;
               chomp $activity;
             };
          };

                
    } # End of while.
  close (DB);



my $err_message=""; 


my $count = @results;
if ($count < 1){ 
    $err_message="error=140 Pos terminal nije registriran tid: $search_for"; 
}


if($count > 1){ 
    $err_message="error=141 Too many results found for tid $search_for"; 
}

if($count == 1){ 
    $target_record = @results[0];
    $err_message="";
    if ($activity == 0){ 
        $err_message="error=120 Pos terminal nije u aktivnom stanju tid: $search_for"; 
    }
};



 return "$err_message";
# print "$err_message";

} 
# End of Search Terminals Database subroutine.





















sub process_card{
    my $result_record =$_[0];
    my $bodovi =$_[1];
    my $response_string;


          if ($result_record !~ /error/i) {

           ########  update bodovi
           my @CARD_line = ();
            

           ($card_db_error,$key,$owner,$time_stamp,
            $CARD_Broj_kartice,$CARD_OIB,$CARD_Ime,$CARD_Prezime,
            $CARD_Datum_rodjenja,$CARD_Exp_date,$CARD_Bodovi,$CARD_Brand,$CARD_Email,$CARD_popup) = split (/\|/,$result_record);


            if ($bodovi =~ /^(\-)?\d+([\.\,]\d+)?$/) {
              $amount_format_error ="";
              if ($bodovi > $amount_limit ) {

                $amount_format_error =iso_encode("prekora\&\#269\;en iznos ");
                $response_string = "error=109 $amount_format_error invalid amount input $bodovi \r\n";
               # $store_flag = 0;
              } 
              else {

                my $bodovi_status =$CARD_Bodovi;
                # summ_points
                $CARD_Bodovi += $bodovi;
                $CARD_Bodovi  = sprintf("%.2f", $CARD_Bodovi);

                if ($CARD_Bodovi > 0 ) {
                  $record ="$key|$owner|$time_stamp|$CARD_Broj_kartice|$CARD_OIB|$CARD_Ime|$CARD_Prezime|$CARD_Datum_rodjenja|$CARD_Exp_date|$CARD_Bodovi|$CARD_Brand|$CARD_Email|";
                  $card_hash{$key} = $record;

                   # save DB records
                   @CARD_line = values (%card_hash);
                   flock DATABASE, $EXCLUSIVE;
                   open (DATABASE, ">$database_cards") or die "Error opening database: $database_cards $!\n";
                   foreach $adonis_line (@CARD_line){ 
                     chomp $adonis_line;
                     print DATABASE "$adonis_line\n";
                   }
                   flock DATABASE, $UNLOCK;             

                    $message =$CARD_popup;
                    if ($message eq "") {
                     $message ="OK";
                    }


                    $CARD_Ime       = &iso_encode($CARD_Ime);
                    $CARD_Prezime   = &iso_encode($CARD_Prezime);
                    $message_encoded= &iso_encode($message);

                    $server_record  ="message=$message_encoded\&firstName=$CARD_Ime\&lastName=$CARD_Prezime\&timeStamp=$timeStamp\&";                    $server_record .="cardBalance=$CARD_Bodovi";
                    $response_string = $server_record;
                 }
                 else {
                    $response_string = "error=103 nedovoljno bodova $bodovi_status \r\n";
                 #  $store_flag = 0; # insufficient amount card-transactions are not recorded
                 }


              }
             } 
             else {
               $response_string = "error=106 syntax error illegal input $bodovi \r\n";
              # $store_flag = 1; #card transactions is recorded
             }
             ######## end of update bodovi
          } 
          else {
             $response_string ="error=100 neregistrirana kartica";
           # $response_string = $result_record;
           # $store_flag = 0; #non-registred-card transactions are not recorded
          };

        print "$response_string\r\n";
        return $response_string;
}




















########### Response string #############

sub server_response {
 
my $client_string   =$_[0];
my $response_string ="";
#my $store_flag = 1; #yes
# $response_string .=CheckTerminalId($TerminalId);

# capture string from the posTerminalId
#amount=5,00&cardID=123456&posTerminalId=123456
chomp $client_string;
   $client_string =canoninize($client_string) ;       # canoninize to lowercase ASCII


#  capture $cardid
   my $cardid =&capture_cardid($client_string);
 
#  capture $terminalid
   my $terminalid =&capture_terminalid($client_string);

#  capture $bodovi
   my $bodovi =&capture_amount($client_string);

#  capture $stat
   my $stat = &capture_stat($client_string);

      if ($stat == 1 ) { # points_query
         $bodovi =0;
      }
  
      if ($bodovi eq "" ) {
         $bodovi =0;
      }  


#  capture $terminalid
   my $terminalid =&capture_terminalid($client_string);
   my $shop_record= &search_terminals($terminalid);

   if ($shop_record =~ /error/i) {
       print "$shop_record\r\n";
       $response_string =$shop_record;
       #error= Pos terminal is not active  |120|Pos terminal nije u aktivnom stanju
       #error= Pos terminal not registered |140| Pos terminal nije registriran 
   } 
   else { # process_card only if terminal Tid is registered and active

      if ($stat == 2 ) { 
          # daily balance
          $response_string = &daily_saldo_summation($terminalid);
          print "$response_string \r\n"; #OK
      }
      else {
          my $card_record = &search_cards($cardid);
          chop $card_record; # remove teminal | character
          if ($card_record =~ /error/i) {
             $response_string=$card_record;
             print "$response_string\r\n";
             return $response_string;
          }
          else {
             $response_string= &process_card($card_record,$bodovi);
          };

      } # end of else status=2
   
   };

   $return_string ="$response_string";
   return $return_string;
}

########### end of server_response #############

