#!/usr/bin/perl

#use utf8;
use strict;
use CGI;
use Digest::SHA qw(
    sha1_base64
    sha1_hex
);

use Time::localtime;
use Opals::Context;
use Opals::Template qw(
    tmpl_read
    tmpl_write
    tmpl_preference
);

use POSIX qw(
    floor
);
use Opals::User qw(
    user_getInformationById
);
use Opals::Tb_Circulation qw(

    circ_getItemStatus
    circ_getItemInfo
    circ_setAvailable
    circ_record_ODL
    circ_processReturn
    circ_updateItemStatus

);
#circ_placeHold
#circ_fillReserve



use Opals::Date qw(
    date_getDeadLineDate
    date_deltaWorkDay   
    date_parse

);
use Opals::Tb_Transactions qw(
    trans_doReverseLost
    
);

use Opals::Constant;

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

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


my ($status,$errorCode,$errorMsg)    ;
my ($permission, $cookie, $template) = tmpl_read(
    {
        dbh             => $dbh,
        cgi             => $cgi,
        tmplFile        => '/txtbk/ajax/circ/return.tmpl',
        reqPermission   => 'tb_circ_return',
    }
);

my $loginuid = $template->param('curUserId');
my $tm = localtime;
my $todayStr = sprintf("%04d-%02d-%02d", $tm->year+1900, ($tm->mon)+1, $tm->mday);
my @retRSArr=();

if ($permission && $permission->{'tb_circ_return'}) {
    my $barcodeType = $syspref->{'barcodeType'}; 
    my @arrReturn = split /,/,$input->{'bcList'};
    my @arrDelBc = split /,/,$input->{'delBcList'};
   
     
    foreach my $barcode( @arrReturn){
        $barcode    =~ s/^\s+|\s+$//g;
        if($barcode && $barcode ne ''){
            my ($overdue_odl_id,$daysOverdue,$damaged_odl_id)=(0,0,0);
            my ($retRS,$return) =processReturn($dbh,$barcode);
            if($input->{'condition'} =~ m/^damaged$/i){
                circ_updateItemStatus($dbh,$barcode,ITEM_DAMAGED,$retRS->{'uid'});
                #circ_updateItemStatus($dbh,$barcode,ITEM_DAMAGED);
                if($retRS->{'idloan'}){
                    my $idloan = $retRS->{'idloan'};
                    $damaged_odl_id = circ_record_ODL($dbh,$idloan,'damaged',0);
                }
            }
            my $retStatusCode = 'retStatusCode_' .$retRS->{'retStatusCode'}; 
            $retRS->{'lid'}=$return->{'lid'};
            $retRS->{'retStatusCode'}   =$retStatusCode;
            $retRS->{'barcode'}         =$barcode;
            $retRS->{'overdue_odl_id'}  =$return->{'odl_id'};
            $retRS->{'daysOverdue'}     =$return->{'overdue'};
            $retRS->{'damaged_odl_id'}  =$damaged_odl_id;
            
            push @retRSArr,$retRS;
        }

    }
    $template->param(returnList => \@retRSArr);
  
}
tmpl_write($dbh, $cgi, $cookie, $template);
#########################################################################
sub isInDelList{
    my($bc,$delBcList)=@_;
    for(my $i=0; $i<scalar(@$delBcList); $i++){
        if($bc eq @$delBcList[$i]){
            return 1;
        }
    }
    return 0;
}

#########################################################################

sub processReturn {
    my ($dbh, $barcode) = @_;
    my $itemCircStatus  = circ_getItemStatus($dbh, $barcode);
    my $return ; 
    my $itemInfo        = circ_getItemInfo($dbh, $barcode, undef);
    my $retval = {
        rid          => $itemInfo->{'rid'},
        title        => $itemInfo->{'title'},
        author       => $itemInfo->{'author'},
        pubName      => $itemInfo->{'pubName'},
        pubDate      => $itemInfo->{'pubDate'},
        price        => $itemInfo->{'price'},
        itemType     => $itemInfo->{'typeId'},
        callNumber   => $itemInfo->{'classNumber'},
        barcode      => $barcode
    };
    my $overdue =0;
    if ($itemCircStatus->{'status'} == IT_STAT_ONLOAN 
        || $itemCircStatus->{'status'} == IT_STAT_HAVE_RSVR
        || $itemCircStatus->{'status'} == IT_STAT_HOLD_EXPIRE) {

        if($itemCircStatus->{'status'} == IT_STAT_ONLOAN 
        || $itemCircStatus->{'status'} == IT_STAT_HAVE_RSVR){
            $retval->{'idloan'}=$itemCircStatus->{'l_idLoan'};
            $return  =doReturn($dbh,$itemCircStatus->{'l_uid'}, $barcode,$todayStr);
             $overdue      = $return->{'overdue'} >0?1:0;
             $retval->{'uid'} = $itemCircStatus->{'l_uid'};
        }
        my $reserveList  = $itemCircStatus->{'reserveList'};
        # Check if item is on reserved
        if (!$reserveList || scalar(@$reserveList) == 0) {
            $retval->{'retStatusCode'} = "1$overdue";
        }
        else {
            if($itemCircStatus->{'status'} == IT_STAT_HOLD_EXPIRE){
                 $retval->{'retStatusCode'} = "22";
            }
            else{
               $retval->{'retStatusCode'} = "2$overdue";
            }
            my ($idReserve, $uidReserve, $reserveExpiry, $dateExpiry);
            $idReserve      = $reserveList->[0]->{'idReserve'};
            $uidReserve     = $reserveList->[0]->{'uid'};
            $reserveExpiry  = $reserveList->[0]->{'dateExpiry'};

            $itemInfo   = circ_getItemInfo($dbh, $barcode, $uidReserve);
            $dateExpiry =date_getDeadLineDate($itemInfo->{'holdPeriod'}, $todayStr);
            if ($dateExpiry > $reserveExpiry) {
                $dateExpiry = $reserveExpiry;
            }
            circ_fillReserve($dbh,$uidReserve ,$itemCircStatus->{'rid'});#Ha
            circ_placeHold($dbh, $idReserve, $todayStr, $dateExpiry);

            my ($reserveUser, $guardian) = 
                user_getInformationById($dbh, $uidReserve);
            $retval->{'reserveUserUid'}   =  $uidReserve;
            $retval->{'reserveUserFirstname'}   = $reserveUser->{'firstname'};
            $retval->{'reserveUserLastname'}    = $reserveUser->{'lastname'};
        }
    }
    elsif ($itemCircStatus->{'status'} == IT_STAT_LOST) {
        $retval->{'retStatusCode'} = '30';
        circ_setAvailable($dbh,$barcode,IT_STAT_LOST);
        trans_doReverseLost($dbh,$barcode,$loginuid);
        my $loanUId=  circ_getLastLoanUId($dbh,$barcode);
        if ($loanUId){
            my ($lostUser, $guardian) = 
                user_getInformationById($dbh, $loanUId);
            $retval->{'lostUserId'}   =  $loanUId;
            $retval->{'lostFirstname'} =  $lostUser->{'firstname'};
            $retval->{'lostLastname'} =  $lostUser->{'lastname'};
        }
    }
    elsif ($itemCircStatus->{'status'} == IT_STAT_NOEXIST) {
        $retval->{'retStatusCode'} = '40';
    }
    elsif ($itemCircStatus->{'status'} == IT_STAT_ONHOLD) {
        $retval->{'retStatusCode'} ='50';

        my $holdList = $itemCircStatus->{'holdList'};
        $retval->{'holdUserUid'}       = $holdList->[0]->{'uid'};
        $retval->{'holdUserFirstname'} = $holdList->[0]->{'firstname'};
        $retval->{'holdUserLastname'}  = $holdList->[0]->{'lastname'};
    }
    elsif($itemCircStatus->{'status'} == IT_STAT_MISSING) {
        $retval->{'retStatusCode'} ='70';
        if($input->{'Condition'} eq "Damaged"){
            circ_updateItemStatus($dbh,$barcode,ITEM_DAMAGED);
            #???????????? opl_odl  
        }
        else{
            circ_setAvailable($dbh,$barcode,IT_STAT_MISSING);
        }
    }
    elsif($itemCircStatus->{'status'} == IT_STAT_HOLD_EXPIRE){

    }

    else {
        $retval->{'retStatusCode'} ='60';
    }
    return ($retval,$return);
}
#-------------------------------------------------------------------------------
sub doReturn{
    my ($dbh,$uid,$barcode,$dateReturn)=@_;
    
    my $sth = $dbh->prepare("select id, dateDue from tb_loan where uid=? && barcode=? && dateReturn is null");
    $sth->execute($uid,$barcode);
    my $rec = $sth->fetchrow_hashref;
    my $idloan   = $rec->{'id'};
    my $dateDue    = date_parse($rec->{'dateDue'});
    my $dateRet = date_parse($dateReturn);
    my $NumOfOverdue = date_deltaWorkDay($dateDue, $dateRet);
    $NumOfOverdue=0 if ($NumOfOverdue<=0);
    my $odl_id =0;

    # Even overduefine = 0, it is still recorded to keep track how many times
    # user make overdue
    if ($NumOfOverdue>0)
    {
        $odl_id = circ_record_ODL($dbh,$idloan ,'overdue',$NumOfOverdue);
    }

   my $return={lid=>$idloan,overdue=>$NumOfOverdue,odl_id=>$odl_id};
   circ_processReturn($dbh,$uid,$barcode,$dateReturn);
   return $return;
   
}
sub circ_getLastLoanUId {
    my ($dbh,$barcode) = @_;
    my $sth = $dbh->prepare("select uid from tb_loan where barcode=? order by dateReturn desc limit 1");
    $sth->execute($barcode);
    my $rec =$sth->fetchrow_hashref; 
    my $uid = 0;
    if($rec){
        $uid = $rec->{'uid'}; 
    }
    $sth->finish;
    return $uid;
}
