#!/usr/bin/perl

#use utf8;
use strict;
use CGI;
use JSON;

use Opals::Context;

use Opals::User qw(
    user_getInformationById
    user_isUserBc
    user_getUserCircInfo
);
use Opals::Constant;

use Opals::Template qw(
    tmpl_preference
);

use Opals::Equipment qw(
    eq_item_findByBarcode
);
use Opals::Eq_Circulation qw(
    
    circ_getItemInfo
    circ_getItemStatus
    
    circ_getUserCircStatus
    circ_getUserListLoan
    circ_getUserListReserve
    circ_getUserLoanHistory

    circ_processLoan
    circ_processReturn
    circ_processRenew

    circ_fillHold
    circ_placeHold
    circ_cancelHold
    circ_cancelHold_all
    circ_isOnHold

    circ_fillReserve
    circ_placeReserve
    circ_cancelReserve
    circ_resetReserve

    circ_declareLost
    circ_setAvailable
    circ_record_ODL

);
use Opals::Date qw(

    date_time_text
    date_now
    date_parse
    date_getDeadLineDate
    date_deltaWorkDay
    date_getDeadLineDateTime
);

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

my $syspref    = tmpl_preference($dbh);
my $validateBc       = $syspref->{'validateBarcode'};
my $barcodeType      = $syspref->{'barcodeType'};

my $todayStr   = date_now();
my $input = {};
my $uid = "";
my $returnMsg = [];
my $op = $input->{'op'} || "";

if ($ENV{'REQUEST_METHOD'} eq "POST") {
   $input = decode_json($cgi->param('POSTDATA'));
   $uid = $input->{'uid'};
   $op = $input->{'op'} || "";
   if ($op eq 'lost'){
       foreach my $bc(@{$input->{'bcList'}}){
            push @$returnMsg , declareLost($dbh,$uid,$bc);
       }
   }
   else {
       foreach my $bc(@{$input->{'bcList'}}){
           push @$returnMsg , processReturn($dbh, $uid, $bc);
       }
   }
} #if ($ENV{'REQUEST_METHOD'} eq "POST")

print "Content-type: text/plain\n\n";
print   to_json({ 
    uid           => $uid,
    returnMsgList => $returnMsg,
});


sub doReturn{
    my ($dbh, $uid,$barcode,$dateReturn)= @_;
    my $sth = $dbh->prepare("select id as idLoan, dateDue from eq_loan where uid=? && barcode =? && dateReturn is null");
    $sth->execute($uid,$barcode);
    my $rec = $sth->fetchrow_hashref;
    my ($idLoan,$dateDue) = ($rec->{'idLoan'}, date_parse($rec->{'dateDue'}));
    my $dateRet = date_parse($dateReturn);
    my $odCount = date_deltaWorkDay($dateDue,$dateRet) ? date_deltaWorkDay($dateDue,$dateRet) : 0 ;
    my $odl_id = 0;
    if ($odCount > 0) {
        $odl_id = circ_record_ODL($dbh,$idLoan,'overdue',$odCount);
    }
    $sth->finish;
    return circ_processReturn($dbh, {uid=>$uid, barcode=>$barcode , dateReturn=>$dateReturn});
}

sub processReturn{
    my ($dbh, $uid, $barcode) = @_;
    my $retVal;
    my $itemInfo = circ_getItemInfo($dbh, $barcode);
    $retVal->{'itemInfo'} = $itemInfo;
    $retVal->{'itemInfo'}->{'barcode'} = $barcode;
    my $itemCircStatus  = circ_getItemStatus($dbh, {barcode=>$barcode});
    my $overdue=0;
    if ($itemCircStatus->{'status'} == IT_STAT_ONLOAN || $itemCircStatus->{'status'} == IT_STAT_HAVE_RSVR){
        my $return= doReturn($dbh, $uid, $barcode, $todayStr);
        $overdue = $itemCircStatus->{'l_duedate'}>$todayStr?1:0;
        my $reserveList = $itemCircStatus->{'reserveList'};
        $retVal->{'uid'} = $itemCircStatus->{'l_uid'};
        $retVal->{'retStatusCode'} = "retStatusCode_" . $return . $overdue;
        #check if current item is on reserve
        if ($reserveList && scalar(@$reserveList) > 0){
            my $idReserve   = @$reserveList[0]->{'idReserve'};
            my $uidReserve  = @$reserveList[0]->{'uid'};
            my ($reserveUser, $guardien) = user_getInformationById($dbh, $uidReserve);
            $itemInfo   = circ_getItemInfo($dbh, $barcode, $uidReserve);
            my $reserveExpiry  = @$reserveList[0]->{'dateExpiry'};
            my $dateExpiry      = getDeadLineDate($itemInfo->{'holdPeriod'}, $todayStr);
            if ($dateExpiry > $reserveExpiry){
                $dateExpiry = $reserveExpiry;
            }
            circ_fillReserve($dbh, $uidReserve, $itemCircStatus->{'rid'});
            my $placeOnHold = circ_placeHold($dbh, $idReserve, $todayStr, $dateExpiry);
        }
    }
    return $retVal;
}

sub declareLost{
    my ($dbh, $uid, $barcode) = @_;
    my $retVal;
    my $itemCircStatus  = circ_getItemStatus($dbh, {barcode=>$barcode});
    my $itemInfo        = circ_getItemInfo($dbh, $barcode, $uid);
    $retVal->{'itemInfo'} = $itemInfo;
    $retVal->{'itemInfo'}->{'barcode'} = $barcode;
    if ($itemCircStatus->{'l_uid'} == $uid){
        circ_declareLost($dbh, $uid ,$barcode);
        $retVal->{'retStatusCode'} = "retStatusCode_30"; 
    }
    if ($itemCircStatus->{'l_idLoan'}){
        my $lost_odl_id = circ_record_ODL($dbh,$itemCircStatus->{'l_idLoan'},'lost', 0 );
    }
    return $retVal;
}

