#!/usr/bin/perl
##############################################################################
# fido2 pos terminal interaction                        Version 2.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     #
# Version 1.05 character encoding utf8  to iso-8859-2                        #
# Version 2.01 terminals are separated from shops, i.e. one shop can have several terminals      
##############################################################################

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   = 10000000.00;
%card_hash =();

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

use Encode;


$database_cards    = "$ENV{'DOCUMENT_ROOT'}/fido2/fido2_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'}/fido2/fido2_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 #1
 };

exit;









sub capture_client_data {

   # fido2  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/\ć/$slovo_ch/g;   #ć E5
  $ime =~ s/\č/$slovo_cch/g;  #č B9
  $ime =~ s/\đ/$slovo_dj/g;   #đ F0
  $ime =~ s/\š/$slovo_sh/g;   #š A8
  $ime =~ s/\ž/$slovo_zh/g;   #ž B8

  $ime =~ s/\Č/$slovo_Cch/g; #Č
  $ime =~ s/\Ć/$slovo_Ch/g;  #Ć C5
  $ime =~ s/\Đ/$slovo_Dj/g;  #Đ D0
  $ime =~ s/\Š/$slovo_Sh/g;  #Š A6 
  $ime =~ s/\Ž/$slovo_Zh/g;  #Ž B4



  $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 check_card{
  my $search_for   = $_[0];


  my $target_record ="";
  my @results =();
  my $cardId;
  my $err_message;

  $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,
         $CARD_Popup_autodelete,$CARD_Referral,$CARD_Type,$CARD_Password
         ) = split(/\|/, $_);

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

          if ($cardId > 0) { 
             if ($cardId eq $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];

        ($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,
         $CARD_Popup_autodelete,$CARD_Referral,$CARD_Limit,$CARD_Type,$CARD_Password
         ) = split(/\|/, $target_record);

# uvesti ograničenja za kartice Collection_only da ne dopuštaju trošenje
# uvesti ograničenja za kartice Redemption_only da ne dopuštaju skupljanje
     if ($CARD_Type eq "Collection_only") {
         $collection ="yes";
         $redemption ="no";
     }

     if ($CARD_Type eq "Redemption_only") {
         $collection ="no";
         $redemption ="yes";
     }

     if ($CARD_Type eq "Collection_and_Redemption") {
         $collection ="yes";
         $redemption ="yes";
     }

     if ($CARD_Type eq "") {
         $collection ="yes";
         $redemption ="yes";
     }

     $date_time = &get_date;
     $date_time =~ s/at/~/g;
    ($date,$day_time) = split (/\~/,$date_time);

    my $jd_today    =julian_day($date);
    my $jd_Exp_date =julian_day($CARD_Exp_date);
    my $delta = $jd_today - $jd_Exp_date;
     
#    print "testing .. today: $date, $jd_today, Exp_date: $CARD_Exp_date, $jd_Exp_date delta: $delta/n";

    if ($jd_today <= $jd_Exp_date) {
        $err_message="";
    }
    else {
        $err_message="Error=500 Valjanost kartice $search_for je istekla prije $delta dana"; 
    }
};

return "$err_message|$target_record";

} # End of check_card subroutine.









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

  open (LOG, "$log_file") or die "Error opening log\n"; # file $log_file $!\n";
    while(<LOG>){
      chomp $_;
     ($key,$LOGuser,$when_added, $fido2_IP, $fido2_Port, $fido2_Referral, $fido2_Client_name, $fido2_Client_query,
      $fido2_Server_response, $fido2_Time_stamp, $fido2_Correct ) = split(/\|/, $_); 
     if ($fido2_Correct eq "1" ) {

         $fido2_Client_query =canoninize($fido2_Client_query) ;       # canoninize to lowercase ASCII
         $tid = &capture_terminalid($fido2_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, $fido2_IP, $fido2_Port, $fido2_Referral, $fido2_Client_name, $fido2_Client_query,
      $fido2_Server_response, $fido2_Time_stamp, $fido2_Correct )  = split(/\|/, $record);       
 
     $amount=0;
     $fido2_Client_query =canoninize($fido2_Client_query) ;       # canoninize to lowercase ASCII

     $amount = &capture_amount($fido2_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);
$report_string      = "revenue\=$daily_revenue\&expenditure\=$daily_expenditure";
$report_string      =~ s/\./\,/g;
return $report_string; 

} # 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\r\n"; # file $old_log $!\n";
   @log_line = <LOG>;
   close (LOG);

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

   unless (-e $billing){ open (BILLING, ">$billing") or die "Error creating database $billing.  $!\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, $fido2_IP, $fido2_Port, $fido2_Referral, $fido2_Client_name, $fido2_Client_input, $fido2_Server_response,$unix_time) = split(/\|/, $log_record);       
          

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

   $residum  = $key % 43200;
   $fido2_Day = ($key - $residum) / 43200;
   $fido2_TimeStamp  = $when_added;
   chomp $client_string;
   $fido2_TerminalId = &capture_terminalid($client_string);


   $fido2_CardId = &capture_cardid($client_string);
   $fido2_Amount = &capture_amount($client_string);
   $fido2_Reference = &capture_reference($fido2_Client_query);   
#   print "Reference 1 ......... $fido2_Reference\n";

   if ($fido2_Amount =~ /^(\-)?\d+([\.\,]\d+)?$/) {
      $record = "$key\|$LOGuser\|$when_added\|$fido2_Day\|$fido2_TimeStamp\|$fido2_TerminalId\|$fido2_CardId\|$fido2_Amount\|$fido2_Reference";
      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'}/fido2";
  my $backup_path = "$ENV{'DOCUMENT_ROOT'}/fido2_backup";
  my $billing_path= "$ENV{'DOCUMENT_ROOT'}/fido2_billing";
  my $file;
  my @filenames =();
  my @regular_file_name=();

  opendir(DIRHANDLE,$path );
  @filenames = readdir(DIRHANDLE);
  closedir(DIRHANDLE);
  
  $x=-1;
  foreach $file (@filenames) {
   if ($file =~ /fido2_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 {
    $x ="\n\r inexistent old_log_file: $old_log_file\n";
   # 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_fido2 ################
sub backup_fido2{
# Author : John Jan Popovic
# Date : July, 2012
# Purpose: This procedure performs DBase adonis Backup


my $database =  "$ENV{'DOCUMENT_ROOT'}/fido2/fido2_clients.txt";	

# Create %adonis_hash
 %DBADONIS_hash = ();
 @DB_line = ();
 $homedir = $root_ ;
  open (DB, "$database") || die "Error opening 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_ . "/fido2_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 database \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 backupdb $!\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  .= "\|fido2";
   $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 log\r\n"; # file $log_file  $!\r\n"; 
       flock LOG, $EXCLUSIVE_LOCK;
       print LOG "$record\n";
       flock LOG, $UNLOCK;  
       close (LOG);
      &move_old_log_file;
      #&backup_fido2;
   }
   else { # all other Log records in a day are just appended
       open (LOG, ">>$log_file") or die "Error=opening log\r\n"; # $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 ="fido2";

 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'}/fido2_billing/billing" . $yy . "_". $mm .  ".txt";

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

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


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


   $fido2_TerminalId = &capture_terminalid($client_string_minusculo);
   $fido2_CardId = &capture_cardid($client_string_minusculo);
   $fido2_Amount = &capture_amount($client_string_minusculo);
   $fido2_Reference = &capture_reference($client_string);     
#   print "Reference 2 ......... $fido2_Reference\n";   

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



  flock BILLING, $UNLOCK;
  close (BILLING);
    

  return 0;
}




























########### 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_original =$client_string;
   $client_string =canoninize($client_string) ;       # canoninize to lowercase ASCII


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

#  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 $reference
   my $reference =&capture_reference($client_string_original);

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


#  capture $terminalid
   my $terminalid =&capture_terminalid($client_string);
   my $terminal_record= &search_terminals($terminalid); # new 0: and fetch_shop_record

   if ($terminal_record =~ /error/i) {
       print "$terminal_record\r\n";
       $response_string =$terminal_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"; #OK
      }
      else {
          my $card_record = &check_card($cardid);
          chop $card_record; # remove teminal | character
          if ($card_record =~ /error/i) {
             ($err_string,@resto) =split(/\|/,$card_record);
             print "$err_string\r\n";
             return $err_string;
          }
          else { # $stat == 0,1,3  // i.e all regular card operations
           # if ($stat == 3 ) { 
               # $response_string= &storno($cardid, $terminalid);
            # else { 
               $response_string= &process_card($card_record,$bodovi, $stat, $reference);
               $response_string .= $shop_annex; # new 3
            # }
          };

      } # end of else status=2
   
   };

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

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











########### Julian day #############
sub julian_day{
# The Julian day (jd) is computed from Gregorian date, month and year (d, m, y) as follows: http://en.wikipedia.org/wiki/Julian_day
# this code will stop working after 2100 , if you use format $dd/$mm/$yy
# but it will work correctly even after 2100 , if you use format $dd/$mm/$yyyy

use integer;
 my $datum = $_[0];
 my $jd;

 $datum =~ s/[\.\-]/\//g; # normalise: substitute dot and dash into slash
 ($dd,$mm,$yy) = split (/\//, $datum);

  if ($yy < 100) {$yy += 2000};
  $a1 =14 - $mm;
  $a = $a1/12.0;
  $y = $yy + 4800 - $a;
  $m = $mm +  12*$a - 3;  
  $j1 = 153*$m + 2;  
  $jd = $dd + $j1/5 + 365*$y + $y/4 - $y/100 + $y/400 - 32045;
  
  return $jd;

} # End of Julian day.




























########### Set Schema  #############




























sub set_popup_message{
# returned PopUp message depends on number of points
# 100=Osvojili ste kapu!; 200=Osvojili ste kiobran!; 500=Ostvarujete popust 10% na slijede&#263;oj kupovini!
# 100=Osvojili ste kapu!
# 200=Osvojili ste kiobran!
# 500=Ostvarujete popust 10% na slijedećoj kupovini!

my $points = $_[0];
my $schema_ = $_[1];
my @case =();
my $message;
my $bodovi;
my $prix;


@case =split(/\;/,$schema_);
$n =@case;

foreach $bod_prix (@case){
  ($bod, $prix)=split(/\=/,$bod_prix);
  if ($points >= $bod) {$message =$prix};
};

#if ($points >= 100) {$message ="Osvojili ste kapu!"};
#if ($points >= 200) {$message ="Osvojili ste kiobran!"};
#if ($points >= 500) {$message ="Ostvarujete popust 10% na slijede&#263;oj kupovini!"};

return $message;
}























sub set_brand_message{
# returned Brand message depends on number of points


my $points = $_[0];
my $schema_ = $_[1];
my @case =();
my $message;
my $bodovi;
my $prix;


@case =split(/\;/,$schema_);
$n =@case;

$message ="";

foreach $bod_prix (@case){
  ($bod, $prix)=split(/\=/,$bod_prix);
  if ($points >= $bod) {$message =$prix};
};

#if ($points >= 100) {$message ="Silver"};
#if ($points >= 200) {$message ="Vip"};
#if ($points >= 500) {$message ="Platinum"};

return $message;
}







sub set_point_upgrade{
# additional bonus POINTS depend on number of points and reward roules: $schema_


my $points  = $_[0];
my $schema_ = $_[1];
my @case =();
my $add_points;
my $bodovi;
my $bod_bonus;


$schema_ =~ s/\s//g;

@case =split(/\;/,$schema_);
my $n =@case;

$add_points ="";

foreach $bod_bonus (@case){
  ($bod, $bonus)=split(/\=/,$bod_bonus);
  if ($points >= $bod) {$add_points =$bonus};
};

#if ($points >= 500)  {$add_points =50};
#if ($points >= 1000) {$message =150};


return $add_points;
}













sub additional_condition{
# returned update_flag depends on additional_condition schema


my $datum_rodjenja = $_[0];
my $brand      = $_[1];
my $schema_    = $_[2];

print DEBUG "datum_rodjenja: $datum_rodjenja brand: $brand schema_: $schema_\n";

my @case =();
my $update_flag;
my $datum_rodjenja_dd, $datum_rodjenja_mm, $datum_rodjenja_yy;
my $variable_dd, $variable_mm, $variable_yy;

     ($datum_rodjenja_dd, $datum_rodjenja_mm, $datum_rodjenja_yy) =split(/\//,$datum_rodjenja);
print DEBUG "datum_rodjenja_dd: $datum_rodjenja_dd, datum_rodjenja_mm: $datum_rodjenja_mm, datum_rodjenja_yy: $datum_rodjenja_yy\n";

$update_flag ="no";

$schema_ =~ s/\s//g;
@case[0] =$schema_;
@case =split(/\;/,$schema_);


foreach $rule (@case){
  ($condition_type, $variable) = split(/\=/,$rule);

   $condition_type =~ tr/A-Z/a-z/ ;       # canoninize to lowercase ASCII
   $condition_type =~ s/\s//g; # strip all whitespaces

  if ($condition_type eq "card_brand") {
     if ($variable =~ /$brand/i) {$update_flag ="yes"};
  };

  if ($condition_type eq "card_datum_rodjenja") {
     ($variable_dd, $variable_mm, $variable_yy) =split(/\//,$variable);
     if (($variable_mm == $datum_rodjenja_mm) && ($variable_dd == $datum_rodjenja_dd)){
        $update_flag ="yes";
     };
  };
print DEBUG "condition_type: $condition_type, variable:  $variable, update_flag: $update_flag\n";

};


# if the additional_condition is empty, then $update_flag ="yes";

if ($schema_ eq "") {
  $update_flag ="yes";
}

print DEBUG " update_flag: $update_flag\n\n\n";

return $update_flag;
}




















sub apply_default_schema_on_card{

my $card_record =$_[0];
my $default_scheme ="";
my $updated_record;
my $brand;
my $Scheme_Cases_PopUp,$Scheme_Cases_Point_upgrade,$Scheme_Cases_Brand,$Scheme_Point_Reset,$scheme_additional_rule;

   $debugging   = "$ENV{'DOCUMENT_ROOT'}/fido2/debug.txt";
   open (DEBUG, ">$debugging") || die "Error opening $debugging.  $!\n";
   print DEBUG "Test run\n";


          $default_scheme = &search_schemas(); 
          chomp $default_scheme;

          ($k,$a,$d,$Scheme_Owner,$Scheme_Title,$Scheme_Periodicity,$Scheme_ExpDate,
           $Scheme_Cases_PopUp,$Scheme_Cases_Point_upgrade,$Scheme_Cases_Brand,
           $Scheme_Point_Reset,$scheme_additional_rule) =split(/\|/,$default_scheme);

   print DEBUG "$default_scheme\n";
   print DEBUG "$Scheme_Cases_PopUp\n";

        ($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, $CARD_Popup_autodelete, $CARD_Referral , 
         $CARD_Limit, $CARD_Type ,$CARD_Password) = split(/\|/, $card_record);

   print DEBUG "$card_record\n";

         $brand = $CARD_Brand;



          $dbuser ="admin";

          if ($key > 0)  {
            $updated_record  ="$key|$dbuser|$when_added|$CARD_Broj_kartice|$CARD_OIB|$CARD_Ime|$CARD_Prezime|$CARD_Datum_rodjenja|";
            $updated_record .="$CARD_Exp_date|$CARD_Bodovi|$CARD_Brand|$CARD_Email|$CARD_popup|$CARD_Popup_autodelete|$CARD_Referral|";
            $updated_record .="$CARD_Limit|$CARD_Type|$CARD_Password|";
            $updated_record  =~ s/\n//g;
            $db_hash{$key}  = $updated_record;
          };


print DEBUG "card: $CARD_Ime,$CARD_Prezime,$CARD_Datum_rodjenja CARD_Bodovi: $CARD_Bodovi CARD_Brand: $brand \n";

# gleda se sakupljeni broj bodova na kartici i onda se još dodaju dodatni nagradni bodovi, prema pravilima definiranim u $Scheme_Cases_Point_upgrade
          if ($Scheme_Cases_Point_upgrade =~ /\=/) {
            $bonus_Bodovi = set_point_upgrade($CARD_Bodovi, $Scheme_Cases_Point_upgrade);
            $CARD_Bodovi += $bonus_Bodovi;
          };

# gleda se sakupljeni broj bodova na kartici i onda se updatira record, odnosno setira se odgovarajuća PopUp poruka
          $CARD_popup_previous =$CARD_popup;
          if ($Scheme_Cases_PopUp =~ /\=/) {
            $CARD_popup  = set_popup_message($CARD_Bodovi, $Scheme_Cases_PopUp);
            if ($CARD_popup eq "") {$CARD_popup =$CARD_popup_previous }
          };

          # pop_up with dynamic ballance calculus
          $calculus =$CARD_popup;
          $calculus =~ s/(\$\([^)]*\))/calculus/;
          $dynamic_ballance =$1;
          $dynamic_ballance =~ s/[$()]//g;
          $dynamic_ballance =~ s/\D//g;
          $dynamic_calculus = $dynamic_ballance - $CARD_Bodovi;
          $dynamic_calculus = sprintf("%.2f", $dynamic_calculus);
          $dynamic_calculus =~ s/\./\,/g;

          $calculus =~ s/calculus/$dynamic_calculus/;
          $CARD_popup =$calculus;

          print DEBUG "calculus:$calculus .. dynamic_ballance:$dynamic_ballance\n";
          print DEBUG "dynamic calculus:$dynamic_calculus\n";
          # end of pop_up with dynamic ballance calculus

          print DEBUG "CARD_popup:$CARD_popup .. CARD_Bodovi: $CARD_Bodovi ... Scheme_Cases_PopUp: $Scheme_Cases_PopUp\n";

# gleda se sakupljeni broj bodova na kartici i onda se updatira record, odnosno setira se odgovarajuća BRAND poruka
          $CARD_Brand_previous =$CARD_Brand;
          if ($Scheme_Cases_Brand =~ /\=/) {          
            $CARD_Brand = set_brand_message($CARD_Bodovi, $Scheme_Cases_Brand);
            if ($CARD_Brand eq "") {$CARD_Brand =$CARD_Brand_previous }
            if  ($Scheme_Point_Reset =~ /yes/i) {
               $CARD_Bodovi=0; # reset bodovi only if the brand was changed/upgraded and if $Scheme_Point_Reset ="yes"
            };
          }
         
          
          
          $update_flag ="yes";
          if ($Scheme_additional_rule =~ /\=/) {  
              $update_flag = additional_condition($CARD_Datum_rodjenja,$brand,$Scheme_additional_rule);
          }


          if (($key >0) && ($update_flag =~ /yes/i)) {
            $updated_record  ="$key|$dbuser|$when_added|$CARD_Broj_kartice|$CARD_OIB|$CARD_Ime|$CARD_Prezime|$CARD_Datum_rodjenja|";
            $updated_record .="$CARD_Exp_date|$CARD_Bodovi|$CARD_Brand|$CARD_Email|$CARD_popup|$CARD_Popup_autodelete|$CARD_Referral|";
            $updated_record .="$CARD_Limit|$CARD_Type|$CARD_Password|";
            $updated_record  =~ s/\n//g;
            
          };
                

   print DEBUG "$updated_record\n";

close (DEBUG);

return $updated_record;


} # End of apply_schema_on_cards subroutine.
















########### Search Schemas Database #############
sub search_schemas{
  my $search_for   = "default";
  my $target_record ="";
  my @results =();
  my $err_message=""; 

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


  $database_schemas   = "$ENV{'DOCUMENT_ROOT'}/fido2/fido2_schemas.txt";	

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

           $Scheme_Title ="";

           ($key,$owner,$time_stamp,$Scheme_Owner,$Scheme_Title,$Scheme_Periodicity,$Scheme_ExpDate,
           $Scheme_Cases_PopUp,$Scheme_Cases_Point_upgrade,$Scheme_Cases_Brand,
           $Scheme_Point_Reset,$Scheme_additional_rule) = split(/\|/, $_);

            if ($Scheme_Title =~ /$search_for/i) { 
               push @results, $_;
            };
        
    } # End of while.
  close (SCHEME);




my $count = @results;
if ($count < 1){ 
    $err_message="error=340 Schema ne postoji: $search_for"; 
}


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



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

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

} 
# End of Search Schema Database subroutine.







































sub process_card{
    my $result_record =$_[0];
    my $bodovi = $_[1];
    my $status = $_[2];
    my $reference = $_[3];

    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,
            $CARD_Popup_autodelete,$CARD_Referral,$CARD_Limit, $CARD_Type,$CARD_Password
           ) = split (/\|/,$result_record);


# set Card_type flags (Collection_only, Redemption_only,Collection_and_Redemption)

            $CARD_Type =~ s/\s//g;

            if ($CARD_Type =~ /Collection_only/i) {
                $collection_flag ="yes";
                $redemption_flag ="no";
            };

            if ($CARD_Type =~ /Redemption_only/i) {
                $collection_flag ="no";
                $redemption_flag ="yes";
            };

            if ($CARD_Type =~ /Collection_and_Redemption/i) {
                $collection_flag ="yes";
                $redemption_flag ="yes";
            };

            if ($CARD_Type =~ /Discount_only/i) {
                $collection_flag ="no";
                $redemption_flag ="no";
            };

            if ($CARD_Type eq "") {
                $collection_flag ="yes";
                $redemption_flag ="yes";
            };

# end of Card_type flags setting

             if (($CARD_Type =~ /Collection_only/i) && ($bodovi <0) ) {
                    $response_string  ="error=card is $CARD_Type";
                    print "$response_string\r\n";
                    return $response_string;
             };


             if (($CARD_Type =~ /Redemption_only/i) && ($bodovi >0) ) {
                     $response_string  ="error=card is $CARD_Type";
                     print "$response_string\r\n";
                     return $response_string;
             };


             if (($CARD_Type =~ /Discount_only/i ) && ($status == 0) ) {
                     $response_string  ="error=card is $CARD_Type";
                     print "$response_string\r\n";
                     return $response_string;
             };


            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
                # print "$CARD_Type collection_flag: $collection_flag, redemption_flag: $redemption_flag\r\n";
                if ($collection_flag eq "yes") {
                    if ($bodovi >0)  { $CARD_Bodovi += $bodovi;}
                }

                if (($redemption_flag eq "yes") && ($bodovi <0) ) {
                    $CARD_Bodovi += $bodovi;
                }


                $CARD_Bodovi  = sprintf("%.2f", $CARD_Bodovi);

                if ($CARD_Bodovi >= 0 ) {


                  $updated_popup =$CARD_Popup;
                  if ($CARD_Popup_autodelete =~ /yes/i) {$updated_popup=""};

                  $record  ="$key|$owner|$time_stamp|$CARD_Broj_kartice|$CARD_OIB|$CARD_Ime|$CARD_Prezime|";
                  $record .="$CARD_Datum_rodjenja|$CARD_Exp_date|$CARD_Bodovi|$CARD_Brand|$CARD_Email|";
                  $record .="$updated_popup|$CARD_Popup_autodelete|$CARD_Referral|$CARD_Limit|$CARD_Type|$CARD_Password";


                  $new_record  =apply_default_schema_on_card($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_Popup,
            $CARD_Popup_autodelete,$CARD_Referral,$CARD_Limit, $CARD_Type,$CARD_Password
           ) = split (/\|/,$new_record);


                  $card_hash{$key} = $new_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);
                    $message_encoded=~ s/\#/\r/g;
                    $reference      = &iso_encode($reference);

                    $CARD_Bodovi_comma =$CARD_Bodovi;
                    $CARD_Bodovi_comma =~ s/\./\,/g;

                    $server_record  ="message=$message_encoded\&firstName=$CARD_Ime\&lastName=$CARD_Prezime\&timeStamp=$timeStamp\&";
                    $server_record .="cardBalance=$CARD_Bodovi_comma\&";
                    if ($reference  ne "") {$server_record .="reference=$reference"};
                    $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;
}











########### Capture reference #############
sub capture_reference{
   my $stranica = $_[0];
   $stranica .= qq~&~;
   if ($stranica !~ /reference\=\&/) {
     $start = qq~reference=~;
     $stop  = qq~&~;
     $stranica  =~ s/$start(.+?)$stop//;  
     my $reference = $1;
     return $reference;

   }
   else {
     return 0;
   }
}
































sub storno{
    my $cardid =$_[0];
    my $tid =$_[1];

    my $response_string;


          # $storno_bodovi =&storno_last_transaction_amount($cardid, $tid);


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










sub storno_last_transaction_amount{
    my $card_id =$_[0];
    my $tid =$_[1];






    $last_amount =





# ####### store_ storno _record 

 my $Billing_user ="fido2";


 $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'}/fido2_billing/billing" . $yy . "_". $mm .  ".txt";

   open (BILLING, ">>$billing") or die "Error opening database.  $!\n"; 
   flock BILLING, $EXCLUSIVE;
   seek BILLING, 0, 2;
         

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


   $fido2_TerminalId = $tid;
   $fido2_CardId = $card_id;
   $fido2_Amount = -$last_amount;
   $fido2_Reference = "storno";      
   

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



  flock BILLING, $UNLOCK;
  close (BILLING);
# ####### end of store_ storno _record 




}






























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

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

  $database_shops    = "$ENV{'DOCUMENT_ROOT'}/fido2/fido2_terminals.txt";	

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

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


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

          if ($terminalId ne "") { 
             if ($terminalId eq $search_for) { 
               chomp $TERMINAL_activityStatus;
               push @results, $_;
               $salesPoint= $TERMINAL_shopId; # new 1
               # print "salesPoint= $TERMINAL_shopId \n";
               if ($TERMINAL_activityStatus =~ /^active/i) { $activity = 1};
               if ($TERMINAL_activityStatus == 1 ) { $activity = 1};
             };
          };


                
    } # End of while.
  close (DB);




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


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

if($count == 1){ 
    $target_record = @results[0];
    $shop_record   = fetch_shop_record($salesPoint); # new 2

    $err_message="";
    if ($activity == 0){ 
        $err_message="error=120 Pos terminal tid: $search_for nije u aktivnom stanju!"; 
    }
};



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

} 
# End of Search Terminals Database subroutine.
















########### Search shop_record #############
sub fetch_shop_record{
  my $search_for   = $_[0];
  my $target_record ="";
  my @results =();
  my $err_message=""; 


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

  $shop_annex =""; 
  $database_shops    = "$ENV{'DOCUMENT_ROOT'}/fido2/fido2_shops.txt";	

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

         ($key,$owner,$time_stamp,
$SHOP_Id,
$SHOP_Pwd,
$SHOP_salesPoint,
$SHOP_address,
$SHOP_telephone,
$SHOP_email,
$SHOP_GIS_coordinates,
$SHOP_referral_person,
$SHOP_contractNumber,
$SHOP_activityStatus) = split(/\|/, $_);


          $SHOP_Id =~ s/\s//g;

          if ($SHOP_Id ne "") { 
              if ($SHOP_Id == $search_for) {

                if ($SHOP_salesPoint  ne "") {
                   $SHOP_salesPoint   = &iso_encode($SHOP_salesPoint);
                   $shop_annex .="SHOP_salesPoint=$SHOP_salesPoint&"; 
                };
                if ($SHOP_address ne "") {
                   $SHOP_address   = &iso_encode($SHOP_address);
                   $shop_annex    .="SHOP_address=$SHOP_address&"; 
                };
                print "$shop_annex";
                push @results, $_;
              };
          };
                
    } # End of while.
  close (DB);






my $count = @results;
if ($count < 1){ 
    $err_message="error=540 Shop nije registriran: $search_for"; 
}


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

if($count == 1){ 


 
    $target_record = @results[0];
     return "$target_record";

};



 return "$err_message";


} 
# End of fetch_shop_record subroutine.






