#!/usr/bin/perl

#use utf8;
use strict;
use CGI;

use Opals::Context;use POSIX;

use Opals::Constant;

use Date::Calc qw(Day_of_Week Week_Number Day_of_Year);

use Opals::User qw(
    user_getInformationById
    user_list
    user_balance
    user_paid
    user_paymenthistory
);

use Opals::Circulation qw(
    circ_userListLoan
    circ_infoRecord
    circ_GetReserveList
    circ_cancelReserve
);

use Opals::Search qw(
    srch_searchRecord
);

use Opals::Date qw(
    date_parse
    date_today
    date_text
);

use Opals::Template qw(
    tmpl_read
    tmpl_write
    tmpl_preference
);


my $dbh = Opals::Context->dbh();
END { $dbh->disconnect(); }

my $cgi = CGI->new;
my $input = $cgi->Vars();

my ($permission, $cookie, $template) = tmpl_read(
        {
            dbh             => $dbh,
            cgi             => $cgi,
            tmplFile        => 'report/userreport.tmpl',
            reqPermission   => 'rpt_user',
        }
);

my $syspref = tmpl_preference($dbh);

#if ($permission && $permission->{'user_delete'}) 
#{
#    my $input = $cgi->Vars();
#    if ($input->{'op'} eq 'delete') 
#    {
#        if (user_delete($dbh, $input)) 
#        {
#            $template->param(success => 1);
#        }
#        else 
#        {
#            $template->param(error => 1);
#        }
#    }
#    $template->param(userDel => 1);
#}
    my @cookieList = (@$cookie);
    my $FromCookie = 0;
    my $errUser = 0;

    my $uInput = $cgi->param('uInput');
    my $uid;
    
    if ($uInput) 
    {
        $errUser = 1;
        my @uList = user_list($dbh, $uInput);
        if ($#uList == 0) # get only one user having this name
        {
            $uid = $uList[0]->{'uid'};
            push @cookieList, $cgi->cookie(
                    -name       => 'borrower',
                    -value      => $uid,
            );
            $errUser = 0;
        }
        elsif ($#uList < 0) # no user has this name/barcode
        {
            $template->param(
                userNotMatch  => 1,
                uInput => $uInput,
            );
        }
        else # list of users 
        {
            $template->param(uList => \@uList);
            $template->param(InvalidUser => 1);
        }
    }
    else 
    {
        # get user from selected item in list or from cookie
        if ( $input->{'InputFromList'} )
        {
            $uid = $input->{'InputFromList'};
            push @cookieList, $cgi->cookie(
                    -name       => 'borrower',
                    -value      => $uid,
            );
        }
        else
        {
            if ( $input->{'hiddenid'} ) { $uid = $input->{'hiddenid'}; }
            else
            {
                $uid = $cgi->cookie('borrower');
                $FromCookie = 1;
            }
        }
    }
    
    if ( $uid && !$errUser )
    {
        my $userID = GetUserInfo($dbh, $uid, $template);
        
        # if any input from user cause an invalid uid, it is an error
        if ( !$userID )
        {
            if ( !$FromCookie ) { $template->param(InvalidUser => 1); }
            $errUser = 1;
        }
    }

    my ($payCode, $MoneyBack);
    if ( $uid && !$errUser )
    {
        if ( $input->{'amount'} )
        {
            ($payCode, $MoneyBack) = user_paid($dbh, $uid, $input->{'amount'});
            $template->param(
                msg_withdraw => ($payCode == PAID_WITHDRAW) ? 1 : 0,
                msg_overpay  => ($payCode == PAID_OVERPAY) ? 1 : 0,
                msg_dtbsfail => ($payCode == PAID_DTBSFAIL) ? 1 : 0,
                msg_paysuccess => ($payCode == PAID_SUCCESS) ? 1 : 0,
                );
            if ( $payCode == PAID_OVERPAY ) 
            { 
                $MoneyBack = floor($MoneyBack*100)/100;
                $template->param(MoneyBack => $MoneyBack); 
            }
        }

        if ( $input->{'totalid'} )
        {
            for (my $i=0; $i < $input->{'totalid'}; $i++ )
            {
                if ( $input->{'idrsrv' . $i} )
                {
                    circ_cancelReserve($dbh, $input->{'idrsrv' . $i});
                }
            }
        }

        my $times = 5;
        if ( $input->{'paymenttimes'} ne '' )
        { 
            $times = scalar($input->{'paymenttimes'}); 
        }

        GetUserReport($dbh, $uid, $times, $template, $syspref);
    }
    else
    {
        $template->param(errUser => 1);
    }
     
    $template->param(hiddenid => $uid);
    $template->param(checkid => 1);
    tmpl_write($dbh, $cgi, \@cookieList, $template);

#---------------------------------------------------------------
sub GetUserReport
{
    my ($dbh, $idNumber, $times, $template, $syspref) = @_;
        
    GetItemsLoaned($dbh, $idNumber, $template);
    GetLostItems($dbh, $idNumber, $template);
    GetDamagedItems($dbh, $idNumber, $template);
    
    my ($bZebraServerDown, $reserveList, $NumOfReserve) = circ_GetReserveList($dbh, $idNumber);
    $template->param(zebraServerDown => $bZebraServerDown);
    $template->param(ReserveList => \@$reserveList);
    $template->param(NumOfReserves => $NumOfReserve);
    my $order = 0;
    foreach my $reserve (@$reserveList) 
    {
        $reserve->{'order'} = $order++;
    }
        
    GetPaymentHistory($dbh, $idNumber, $times, $template);
   
    my $balance = user_balance($dbh, $idNumber);
    my $showFine = ($syspref->{'charge_overdue'} == 0 && $balance == 0) ? 0:1;
    $template->param(showfine => $showFine);
    
    $balance = floor($balance*100 + 0.5)/100;
     
    $template->param(Balance => $balance);
    $template->param(paymenttimes => $times);
}

#---------------------------------------------------------------
sub GetUserInfo
{
    my ($dbh, $uid, $template) = @_;

    my ($userInfo, $guardian) = user_getInformationById($dbh, $uid);

    if ( !$userInfo->{'uid'} ) { return; }
    
    $template->param( firstname => $userInfo->{'firstname'} );
    $template->param( lastname => $userInfo->{'lastname'} );
    $template->param( grade => $userInfo->{'grade'} );
    $template->param( email => $userInfo->{'email'} );
    $template->param( username => $userInfo->{'username'} );

    $template->param(guardian => $guardian);
    $template->param(NumOfGuardians => scalar(@$guardian));
    
    return $userInfo->{'uid'};
}

#---------------------------------------------------------------
sub GetItemsLoaned
{
    my ($dbh, $idNumber, $template) = @_;
            
    # Get books in loan from user
    my $loanList = circ_userListLoan($dbh, $idNumber);
    my $bZebraServerDown = 0;
    my $overdueAmount = 0;

    my $lastloanDate = '';
    foreach my $loan (@$loanList) 
    {
        if ( $lastloanDate lt $loan->{'dateLoan'} ) { $lastloanDate = $loan->{'dateLoan'}; }

        $loan->{'dateLoan'} = date_text($loan->{'dateLoan'}, 0);
        $loan->{'dateDue'}  = date_text($loan->{'dateDue'}, 0);

        if ( $loan->{'overdue'} )
        {
            $loan->{'fine'} = $loan->{'deltaDueDay'}*$loan->{'finerate'};
            $overdueAmount += $loan->{'fine'};
        }

#        my $pqf = "\@attr 1=5000 $loan->{'barcode'}";
#        my ($resultSize, $result) = srch_searchRecord($dbh, 0, 'b', $pqf, 1, 1);
#        if ($result) 
#        {
#            my ($numTotal, $numLoan, $numReserve, $numHold, $items)
#                = circ_infoRecord($dbh, $result->[0]->{'rid'}, $result->[0]->{'item'});
#
#            $loan->{'rid'}     = $result->[0]->{'rid'};
#            $loan->{'title'}   = $result->[0]->{'title'};
#            $loan->{'author'}  = $result->[0]->{'author'};
#            $loan->{'pubName'} = $result->[0]->{'pubName'};
#            $loan->{'pubDate'} = $result->[0]->{'pubDate'};
#            $loan->{'dewey'}   = $items->[0]->{'callnumber'};
#        }
#        else 
#        {
#            $bZebraServerDown = 1;            
#        }
    }
    
    # Sort result and set into template   
    @$loanList = sort { $a->{'title'} cmp $b->{'title'} } @$loanList;

    # Get total loans so far
    my $query = $dbh->prepare("select count(*) as total from opl_loan where uid=$idNumber");
    $query->execute();
    my $rec = $query->fetchrow_hashref();
    $query->finish;
    $template->param(TotalLoans => $rec->{'total'});

    if ( $lastloanDate eq '' )
        { $template->param(LastLoanDate => "none" ); }
    else
        { $template->param(LastLoanDate => date_text($lastloanDate, 0) ); }

    $template->param(zebraServerDown => $bZebraServerDown);
    $template->param(LoanList => \@$loanList);
    $template->param(NumOfLoans => 0 + @$loanList);
    $template->param(OverdueFine => $overdueAmount);
}

#----------------------------------------------------------
sub GetLostItems
{
    my ($dbh, $idNumber, $template) = @_;
    my $bZebraServerDown = 0;
    my @lostList = ();
    my $lostAmount = 0;
#    my $query = $dbh->prepare("select opl_loan.barcode, dateloan, amount, final, ondate from opl_loan as l, opl_lost as b where uid=? && l.idloan=b.idloan");
    
    my $query = $dbh->prepare("select opl_loan.barcode, dateloan, dateReturn, amount, final, 
                ondate, callNumber, title, author, available 
            from opl_loan, opl_lost, opl_item, opl_marcRecord
            where opl_loan.idloan=opl_lost.idloan && opl_loan.barcode=opl_item.barcode 
                && opl_item.rid=opl_marcRecord.rid && opl_loan.uid=?");
    
    $query->execute($idNumber);
    
    my $qrFound = $dbh->prepare("select ondate from opl_found where barcode=? && ondate>=? order by ondate asc limit 0, 1");
    
    while ( my $rec = $query->fetchrow_hashref )
    {
        $rec->{'dateloan'} = date_text($rec->{'dateloan'}, 0);
        $rec->{'ondate'}   = date_text($rec->{'ondate'}, 0);

        $qrFound->execute($rec->{'barcode'}, $rec->{'dateReturn'});
        my ($dateFound) = $qrFound->fetchrow_array;
        $qrFound->finish;
        if ( $dateFound ) { $rec->{'dateFound'} = date_text($dateFound, 0); }

#        my $pqf = "\@attr 1=5000 $rec->{'barcode'}";
#        my ($resultSize, $result) = srch_searchRecord($dbh, 0, 'b', $pqf, 1, 1);
#        if ($result) 
#        {
#            my ($numTotal, $numLoan, $numReserve, $numHold, $items)
#                = circ_infoRecord($dbh, $result->[0]->{'rid'}, $result->[0]->{'item'});
#
#            $rec->{'rid'}     = $result->[0]->{'rid'};
#            $rec->{'title'}   = $result->[0]->{'title'};
#            $rec->{'author'}  = $result->[0]->{'author'};
#            $rec->{'pubName'} = $result->[0]->{'pubName'};
#            $rec->{'pubDate'} = $result->[0]->{'pubDate'};
#            $rec->{'dewey'}   = $items->[0]->{'callnumber'};
#        }
#        else 
#        {
#            $bZebraServerDown = 1;            
#        }

        if ( !$rec->{'final'} )
        {
            $rec->{'amount'} = "--";
        }
        else
        {
            $lostAmount += $rec->{'amount'};
        }        
        if($rec ->{'barcode'} =~m/^\_\_\_(.*)\_[\d]+$/){
            $rec ->{'barcode'}=$1;
        }
 
        push @lostList, $rec;
    }
    $query->finish;

    $template->param(LostList => \@lostList);
    $template->param(NumOfLost => scalar(@lostList) );
    $template->param(LostAmount => $lostAmount);
}

#----------------------------------------------------------
sub GetDamagedItems
{
    my ($dbh, $idNumber, $template) = @_;     
    my $bZebraServerDown = 0;
    my $query = $dbh->prepare("select l.barcode, l.dateloan, d.amount, d.final, d.ondate 
                                from opl_loan as l, opl_damage as d 
                                where uid=? && l.idloan=d.idloan");
    $query->execute($idNumber);

    my $damageAmount = 0;
    my @damageList = ();
    while ( my $rec = $query->fetchrow_hashref )
    {
        if ( $rec->{'ondate'} )
        {
            $rec->{'ondate'} = date_text($rec->{'ondate'}, 0);
        }

        my $pqf = "\@attr 1=5000 $rec->{'barcode'}";
        my ($resultSize, $result) = srch_searchRecord($dbh, 0, 'b', $pqf, $ENV{'Z_INDEX_BASE'}, 1);
        if ($result) 
        {
            my ($numTotal, $numLoan, $numReserve, $numHold, $items)
                = circ_infoRecord($dbh, $result->[0]->{'rid'}, $result->[0]->{'itemList'});

            $rec->{'rid'}     = $result->[0]->{'rid'};
            $rec->{'title'}   = $result->[0]->{'title'};
            $rec->{'author'}  = $result->[0]->{'author'};
            $rec->{'pubName'} = $result->[0]->{'pubName'};
            $rec->{'pubDate'} = $result->[0]->{'pubDate'};
            $rec->{'dewey'}   = $items->[0]->{'callnumber'};
        }
        else 
        {
            $bZebraServerDown = 1;            
        }

        if ( !$rec->{'final'} )
        {
            $rec->{'amount'} = "--";
        }
        else
        {
            $damageAmount += $rec->{'amount'};
        }
        push @damageList, $rec;
    }
    $query->finish;

    $template->param(DamageList => \@damageList);
    $template->param(NumOfDamage => scalar(@damageList) );
    $template->param(DamageAmount => $damageAmount);
}

#----------------------------------------------------------
sub GetReserve
{
    my ($dbh, $idNumber, $template) = @_;
    
    my $reserveList = circ_userListReserve($dbh, $idNumber);
    my $bZebraServerDown = 0;

    foreach my $rec (@$reserveList) 
    {
        $rec->{'dateReserve'} = date_text($rec->{'dateReserve'}, 0);
        $rec->{'dateExpiry'}  = date_text($rec->{'dateExpiry'}, 0);

#        my $pqf = "\@attr 1=12 $rec->{'rid'}";
#        my ($resultSize, $result) = srch_searchRecord($dbh, 0, 'b', $pqf, 1, 1);
#        if ($result) 
#        {
#            my ($numTotal, $numLoan, $numReserve, $numHold, $items)
#                = circ_infoRecord($dbh, $result->[0]->{'rid'}, $result->[0]->{'item'});
#
#            $rec->{'rid'}     = $result->[0]->{'rid'};
#            $rec->{'title'}   = $result->[0]->{'title'};
#            $rec->{'author'}  = $result->[0]->{'author'};
#            $rec->{'pubName'} = $result->[0]->{'pubName'};
#            $rec->{'pubDate'} = $result->[0]->{'pubDate'};
#            $rec->{'dewey'}   = $items->[0]->{'callnumber'};
#        }
#        else 
#        {
#            $bZebraServerDown = 1;            
#        }
    }
    
    # Sort result and set into template   
    @$reserveList = sort { $a->{'title'} cmp $b->{'title'} } @$reserveList;

    $template->param(zebraServerDown => $bZebraServerDown);
    $template->param(ReserveList => \@$reserveList);
    $template->param(NumOfReserves => scalar(@$reserveList) );
}

#----------------------------------------------------------
sub GetPaymentHistory
{
    my ($dbh, $idNumber, $times, $template) = @_;

    my $PaymentList = user_paymenthistory($dbh, $idNumber, $times);
    foreach my $rec (@$PaymentList)
    {
        $rec->{'ondate'} = date_text($rec->{'ondate'}, 0);
    }
    
    $template->param(PaymentList => \@$PaymentList);
    
}

__END_OF_FILE:

