#!/usr/bin/perl

#use utf8;
use strict;
use CGI;

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

use Opals::Tb_Record qw(
    
    tb_createNextBiggerBc
    tb_barcode_getMaxValue

);


use Opals::Constant;

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        => 'txtbk/ajax/record/barcodeMnt.tmpl',
        reqPermission   => 'tb_record_edit',
    }
);

my $syspref = tmpl_preference($dbh);
my $sessionid = $cgi->cookie('sessionID');
my $opt = $input->{'opt'};


if ($permission && $permission->{'tb_record_edit'}) {
    
    if (defined $opt && $opt eq 'getSetPending'){
        my $startBc = $input->{'bc_start'};
        my $rId = $input->{'rId'};
        my $rangeId = $input->{'rangeId'};
        my ($pending,$pendingFor) =(-1,'');
        my $nBarcode = 0;
        my $bcList = [];

        if (defined $rId && $rId >0){
            $pending=$rId;
            $pendingFor='edit';
        }
        elsif(defined $input->{'iid'} && $input->{'iid'} >0 ){
            $pending=$input->{'iid'};
            $pendingFor ='import';
        }
        if (defined $input->{'nCopy'} && $input->{'nCopy'} > 0){
            $nBarcode=$input->{'nCopy'};
        }
        if ($nBarcode>0){
            $bcList =  bcm_getSetPending($dbh,$startBc,$rangeId,$nBarcode,$pending,$pendingFor,$sessionid);

        }
        $template->param(
            getSetPending   => 1,
            bcList          => $bcList
        );
    }
    else{
        my $vendorList = bcm_getVendorList($dbh);
        $template->param(vendorList => $vendorList);
        my $maxBarcode  = tb_barcode_getMaxValue($dbh);
        my $nextBc =  tb_createNextBiggerBc($dbh,$maxBarcode);
        $template->param( nextBc => $nextBc );
        $template->param( getList=> 1);
    }
}
tmpl_write($dbh, $cgi, $cookie, $template);


#-------------------------------------------------------------------------------------------

#---Will put (them0 in Module Tb_BarcodeMgnt.pm


sub bcm_getVendorList {

    my ($dbh) = @_;
    
    my $sql = <<_STH_;
select      v.vid vid,vendor, r.rid as rid,bcLen,preFix,rangeFr,rangeTo , 
            min(s.barcode) as firstAvail, count(barcode) availTotal,
            s.pending,s.pendingFor  
from        tb_bcmVendor v inner join tb_bcmRange r on v.vid=r.vid 
            inner join tb_bcmBc s on s.rid = r.rid  
where       s.status = 'available' && 
            (pending is NULL || pending = '' || pending = -1) && 
            (pendingFor is NULL || pendingFor ='') 
group by vid,r.rid  having availTotal>0 
order by    vid,rid
_STH_
    
    my $sth = $dbh->prepare($sql);
    $sth->execute();
    my  @list =();
    my $preVid=-1;
    my $i=-1;
    while (my $rec = $sth->fetchrow_hashref) {
        my ($rangeFr,$rangeTo)=('','');
        my $preFix= $rec->{'preFix'};
        my $padLen=$rec->{'bcLen'}- length($preFix);
        $rangeFr =sprintf("%s%0*d",$preFix,$padLen,$rec->{'rangeFr'});
        $rangeTo =sprintf("%s%0*d",$preFix,$padLen,$rec->{'rangeTo'});

        my $vGrp={  rid       =>$rec->{'rid'},
                    rangeFr   =>$rangeFr,
                    rangeTo   =>$rangeTo,
                    availTotal=>$rec->{'availTotal'},
                    firstAvail=>$rec->{'firstAvail'}
                   };
        if($preVid != $rec->{'vid'}){
            push @list,{ vid=> $rec->{'vid'}, vendor  => $rec->{'vendor'}};
            $i++;
            $preVid = $rec->{'vid'};
        }
        push @{@list[$i]->{'vendorGrp'}},$vGrp;
    }
    $sth->finish;
    return \@list;

}

sub bcm_getSetPending{
    my ($dbh,$startBc,$rangeId,$n,$pending,$pendingFor,$sessionid) = @_;
    if($rangeId>0){
        getSetPending_vendor($dbh,$startBc,$rangeId,$n,$pending,$pendingFor,$sessionid);
    }
    else{
        getSetPending_manual($dbh,$startBc,$rangeId,$n,$pending,$pendingFor,$sessionid);
    }
}

sub getSetPending_vendor {
     my ($dbh,$startBc,$rangeId,$n,$pending,$pendingFor,$sessionid) = @_;
    my  @bcList =();
    return \@bcList if(!defined $n || $n<=0);

    my $sql = <<_STH_;
select      barcode  
from        tb_bcmBc s left outer join tb_items i using(barcode)
where       s.rid = $rangeId && 
            s.status = 'available' && 
            s.pending = -1 && 
            s.barcode >='$startBc' &&
            i.barcode is null
order by    s.barcode 
limit      $n 
_STH_
    my $sth = $dbh->prepare($sql);
    $sth->execute();
    while (my $barcode = $sth->fetchrow_array) {
        push @bcList , {barcode=>$barcode};
    }
    $sth->finish;
#set pending
    if($#bcList >=0 ){
        my $firstBc=@bcList[0]->{'barcode'};
        my $lastBc=@bcList[$#bcList]->{'barcode'};
        $sth =$dbh->prepare("update tb_bcmBc set pending=?,pendingFor=?,sessionid =? where rid=? && barcode >=? && barcode <=?");
        $sth->execute($pending,$pendingFor,$sessionid,$rangeId,$firstBc,$lastBc);
    }
    return \@bcList;
}
sub getSetPending_manual{
    my ($dbh,$startBc,$rid,$n,$pending,$pendingFor,$sessionid) = @_;
    my  @bcList =();
    return \@bcList if(!defined $n || $n<=0);
    my $prefix="";
    my $bc=0;
    my $bcLen=0;
    my $sth = $dbh->prepare("replace into  tb_bcmBc set  rid  =0,status='available', pending=? , pendingFor=? , sessionid=? ,barcode = ?");

    if($startBc =~ m/([\D]*)([\d]*$)/){
        $prefix=$1;
        $bc=int($2);
        $bcLen=length($2);
    }
    my $strFmt="%s%0$bcLen" ."d";
    my $count=0;
    while($count <$n){
        my $t=$n - $count;
        my $bcFirst=sprintf($strFmt,$prefix,$bc);
        my $nextBc=$bcFirst;
        my $bcLast=sprintf($strFmt,$prefix,($bc+$t));
        my $bcUsed=_getBcUsedInRange($dbh,$bcFirst,$bcLast);
        for(my $i=0; $i<$t;$i++){
            $nextBc=sprintf($strFmt,$prefix,$bc);
            if(!defined $bcUsed->{$nextBc}){
                push @bcList, {barcode=>$nextBc};
                $sth->execute($pending,$pendingFor,$sessionid,$nextBc);
                $count++;
            }
            $bc++;
        }
    }
   
    return \@bcList;
}
sub _getBcUsedInRange{
    my($dbh,$bc_first,$bc_last)=@_;
    my $bcList={};
    my $sth=$dbh->prepare("select barcode from tb_items where barcode between ? AND ?");
    $sth->execute($bc_first,$bc_last);
    while(my ($bc)=$sth->fetchrow_array){
        $bcList->{$bc}=1;
    }
    return $bcList;
       
}
sub bcm_updateStatusBcTbl{
    my ($dbh,$barcodes,$status,$rid,$pending,$pendingFor,$sessionid) = @_;
    
    my $sql = <<_STH_;
update  tb_bcmBc 
set     status = ? , sessionid = ?,
        pending= ?, pendingFor = ? 
where   barcode = ? && rid= ?
_STH_
    my $sth = $dbh->prepare($sql);
    my @arrBarcodes = split /,/,$barcodes;
    for(my $i=0; $i <scalar(@arrBarcodes); $i++){
        $sth->execute($status,$sessionid,$pending,$pendingFor,@arrBarcodes[$i],$rid);
    }
    $sth->finish;

}

