#!/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
);

use Opals::Transactions qw(
    trans_getTransactionDetail
    trans_doPayment
    trans_recordFine
    trans_getBalance
);

use Opals::Circulation qw(
    circ_userListReserve
    circ_GetLostNumber
    circ_GetDamagedNumber
);


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   => 'report',
        }
);
use Time::localtime;

my $syspref = tmpl_preference($dbh);
#ha
my $dateDue;
my @idloanArr;
my $tm = localtime;
my $todayStr = sprintf("%04d-%02d-%02d", $tm->year+1900, ($tm->mon)+1, $tm->mday);
my $dFirst = Opals::Context->preference('dateFirst');
my $dLast  = Opals::Context->preference('dateLast');
#ha

#if ($permission && $permission->{'user_delete'}) 
    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);
        
        # 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);
}

#---------------------------------------------------------------
#2008-28-02#2008-28-02

sub getUserInfo{
    my ($dbh,$uid)=@_;
    my ($userInfo, $guardian) = user_getInformationById($dbh, $uid);
    my $balance = trans_getBalance($dbh, $userInfo->{'uid'});
    $balance = floor($balance*100 + 0.50)/100; 
    $balance = sprintf("%.2f",$balance);

    GetLoanItems($dbh, $template, $userInfo->{'uid'});
    GetReservedItems($dbh, $template, $userInfo->{'uid'});
    
    GetLostDamagedItems($dbh, $userInfo->{'uid'});
    #GetLostItems($dbh, $userInfo->{'uid'}, $template);
    #GetDamagedItems($dbh, $userInfo->{'uid'}, $template);
    $template->param(
        user_uid            => $userInfo->{'uid'},
        user_barcode        => $userInfo->{'userbarcode'},
        user_username       => $userInfo->{'username'},
        user_firstname      => $userInfo->{'firstname'},
        user_lastname       => $userInfo->{'lastname'},
        homeroom            => $userInfo->{'homeroom'},
        teacher             => $userInfo->{'teacher'},
        notes               => $userInfo->{'notes'},

        balance     => $balance,
        lost        => (circ_GetLostNumber($dbh, $userInfo->{'uid'})),
        damaged     => (circ_GetDamagedNumber($dbh, $userInfo->{'uid'})),
    );
    $template->param(hiddenid => $userInfo->{'uid'});

    my $showFine = ($syspref->{'fine'} == 1 && $balance == 0) ? 0:1;
    $template->param(showfine => $showFine);
}

#----------------------------------------------------------
#2008-28-02
sub GetLoanItems
{
    my ($dbh, $template, $uid) = @_;
    
    # List items loaned by this borrower
    my ($loanList, $reserveList);
    $loanList = circ_userListLoan($dbh, $uid);
    my $count = 0;
    my $odCount = 0;
    foreach my $loan (@$loanList) 
    {
        if ( $loan->{'overdue'} ) { $odCount++; }
        $loan->{'dateLoan'} = date_text($loan->{'dateLoan'}, 0);
        $loan->{'dateDue'}  = date_text($loan->{'dateDue'}, 0);
        $loan->{'number'} = $count++;
        if($loan->{'barcode'} =~m/^\_\_\_(.*)/){
            $loan->{'org_barcode'} =$1;
        }
        else{
            $loan->{'org_barcode'} =$loan->{'barcode'};
        }
    }
    $template->param(loanList => \@$loanList);
    $template->param(LoanCount => scalar(@$loanList));
    $template->param(NumOfOverdue => $odCount);
}
#----------------------------------------------------------
#2008-28-02
sub GetReservedItems
{
    my ($dbh, $template, $uid) = @_;
    
    my $reserveList = circ_userListReserve($dbh, $uid);
    my $order = 0;
    foreach my $reserve (@$reserveList) 
    {
        $reserve->{'order'} = $order++;
        $reserve->{'dateReserve'} = date_text($reserve->{'dateReserve'}, 0);
        if($reserve->{'numCopyReserve'}==0){
            $reserve->{'dateExpiry'}  ='';
        }
        else{
                $reserve->{'dateExpiry'}  = date_text($reserve->{'dateExpiry'}, 0);
        }
    }
    $template->param(NumOfReserves => scalar(@$reserveList));
    #$template->param(hasReserves => scalar(@$reserveList));;
    $template->param(reserveList => \@$reserveList);
}
#----------------------------------------------------------
#2008-28-02
sub GetLostDamagedItems
{
    my ($dbh, $uid) = @_;
    my $dir ='desc';
    my @transTbl = trans_getTransactionDetail($dbh,$uid,$dir,'all');
      $template->param(
            transList  =>\@transTbl,
            numTrans   =>scalar(@transTbl),
            dateToday  => date_text($todayStr)
        );

    my $balance = trans_getBalance($dbh,$uid);
        $template->param(
           balance => $balance,
        );
    
  }
#---------------------------------------------------------------
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:

