#!/usr/bin/perl

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

use Opals::Context;
use Opals::Template qw(
    tmpl_preference
);
use Opals::User qw(
    user_getInformationById
);
use Opals::Tb_Transactions qw(
    trans_recordFine
    trans_getFineDetail
    trans_getBalance
    trans_getUnpaidFineList

);
use Opals::Tb_Fines qw(
    fine_getUserByOdl_id
);
use Opals::Date qw(
    date_getDeadLineDate
    date_text
    date_now
);

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

my $cgi      = CGI->new;
my $todayStr   = date_now();
my ($errCode, $ck, $user) = Opals::User::user_currentUser($dbh, $cgi);
my $loginuid   = $user->{'uid'};
my $input = {};
my $transList =();
my $paidTransList=();
my @trans;
my ($uid,$payMethod,$tender,$changeAmount,$received,$paymentId);
my $paymentInfo;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
   my ($responsibleInfo, $g) = user_getInformationById($dbh, $loginuid); 
   my $responsibleName = $responsibleInfo->{'firstname'} . " " . $responsibleInfo->{'lastname'};
   $input = decode_json($cgi->param('POSTDATA'));
   $uid = $input->{'uid'};
   $payMethod = $input->{'payMethod'};
   my $payInfo = $input->{'payInfo'};
   $tender  = $payInfo->{'tender'};
   $received = $payInfo->{'received'};
   $changeAmount = $payInfo->{'change'} ;

   my $balance = trans_getBalance($dbh,$uid );
   $paymentInfo = {
        uid       => $uid,
        payMethod => $payMethod,
        received  => $tender-$changeAmount,
        accountBalance=> $balance,
        tender    => $tender,
        changeAmnt=> $changeAmount,
        ondate    => $todayStr
   };
   if ($tender > 0 ) {
        $paymentId = _trans_paymentReceipt($dbh,$paymentInfo ); 
   }
   my $tid=0;
   $transList = $input->{'transList'};
   foreach my $t(@$transList){
       if ($t->{'selected'}) {
           $t->{'pid'} = $paymentId || 0;
            $tid = _trans_doPayment ($dbh,$uid,$responsibleName,$t);
            push (@$paidTransList,$t)
       }
   }
   my $balance = trans_getBalance($dbh,$uid );
}
my $patronInfo;
if ($uid && $uid>0){
    my ($userInfo, $guardian) = user_getInformationById($dbh, $uid);
    my $balance = trans_getBalance($dbh,$uid,0);
    if (defined $userInfo){
        $patronInfo={};
        foreach my $f (qw(uid userbarcode sid username firstname lastname nickname phone homeroom teacher grade program studies notes status expired categorycode email)){
            $patronInfo->{$f}=$userInfo->{$f};
        }
        $patronInfo->{'balance'} = $balance>0?$balance:0;
    }
    @trans = trans_getUnpaidFineList($dbh,$uid,'asc');
}
print "Content-type: text/plain\n\n";
print   to_json({ 
    uid         => $uid,
    patron      => $patronInfo,
    transList   => \@trans,
    paidTransList=>$paidTransList,
    pid         => $paymentId
});

my $sql_transaction =" 
insert into tb_transactions
set     ptid        = ?,
        uid         = ?,
        amount      = ?,
        balance     = ?,
        description = ?,
        date        =now(),
        code        =?
";
sub _trans_doPayment {
    my ($dbh,$uid,$responsible,$payInfo) = @_; 
    #my $sth_update_odl         =$dbh->prepare("update opl_odl set settleDate=now() where odl_id= ?");
    #my $sth_update_trans_settleDate= $dbh->prepare("update opl_transactions set settleDate=now() where settleDate is null && tid =? ");
    #my $sth_update_trans       =$dbh->prepare("update tb_transactions set  balance=(balance -amount) + ?, amount=? where tid=?");
    #my $sth_update_transDetail =$dbh->prepare("update tb_transactiondetail set forgivenAmount=  ? , amount =? , taxes=?,responsible=? where odl_id=? && tid=?");
    my $balance =trans_getBalance($dbh,$uid);
    my $description = 'payment by ' . $responsible;
    my $transCode =4; #payment
    if ($payInfo->{'transCode'} eq "waive"){
        $transCode = 5; #waive
    }
    if ($payInfo->{'transCode'} eq "refund"){
        $transCode = 8; #refund
    }
    my $sql = "insert into tb_transactions set     
        ptid        = ?,
        uid         = ?,
        pid         = ?,
        amount      = ?,
        balance     = ?,
        description = ?,
        date        =now(),
        code        =?
";
    my $sth_insert_trans = $dbh->prepare($sql);
    my $newBalance = $balance + $payInfo->{'amount'};
    if ($payInfo->{'transCode'} == 8){
        $newBalance = $balance + $payInfo->{'amount'};
        $sth_insert_trans->execute($payInfo->{'ptid'},$uid,$payInfo->{'pid'},$payInfo->{'amount'},$newBalance,$description,$transCode);
    }else{
        $sth_insert_trans->execute($payInfo->{'tid'},$uid,$payInfo->{'pid'},$payInfo->{'amount'},$newBalance,$description,$transCode);
    }
    my $tid =  $dbh->{'mysql_insertid'};
    return $tid;
}

sub _trans_paymentReceipt {
    my($dbh,$param)=@_;
    my @fields = ("uid=?");
    my @data = ();
    my $uid     =  $param->{'uid'};
    my $pid=0;
    if ($uid && $uid>0){
        @data = ($uid);
        if (defined $param->{'received'}){
            push @fields,'received=?';
            push @data,$param->{'received'};
        }
        if (defined $param->{'accountBalance'}){
            push @fields,'accountBalance=?';
            push @data,$param->{'accountBalance'};
        }
        if (defined $param->{'payMethod'}){
            push @fields,'payMethod=?';
            push @data,$param->{'payMethod'};
        }
        if (defined $param->{'tender'}){
            push @fields,'tender=?';
            push @data,$param->{'tender'};
        }
        if (defined $param->{'changeAmnt'}){
            push @fields,'changeAmnt=?';
            push @data,$param->{'changeAmnt'};
        }
        if (defined $param->{'ondate'}){
            push @fields,'ondate=?';
            push @data,$param->{'ondate'};
        }
        my $sql = "insert into tb_paymentReceipt set " . join (",", @fields);
        my $sth=$dbh->prepare($sql);
        $sth->execute(@data);
        ($pid)=$dbh->{'mysql_insertid'};
    }
    return $pid;
}



sub realignBalance{
    my($dbh,$uid,$tid)=@_;
    my $balance=0;
    my $sth_balance =$dbh->prepare("select balance from tb_transactions  where tid=?");
    my $sth_tidAmt =$dbh->prepare("select tid,code,amount from tb_transactions  where uid=? && tid > ? order by tid");
    my $sth =$dbh->prepare("update tb_transactions  set balance= ?  where tid= ?");
    $sth_balance->execute($tid);
    if(($balance) =$sth_balance->fetchrow_array){
        $sth_tidAmt->execute($uid,$tid);
        while(my ($tid,$code,$amt)=$sth_tidAmt->fetchrow_array){
            #debit for charge case 
            #1: overdue,2: lost,3: damaged,8: refund
            if($code ==1 ||$code ==2 || $code ==3 || $code ==8  ){
                $balance +=$amt;
            }
            #credit for case 
            # 4: payment, 5:forgive, 6:credit for lost refund
            else{
                $balance -=$amt;
            }
            $sth->execute($balance,$tid);
        }
    }
}

