package spacebiz; #use lib '/wwwroot/extranet/pos/'; #use me; #WiInteg #use wi; our %tfilez; use strict; no strict "refs"; use Storable qw(nstore lock_nstore lock_store lock_retrieve);#lock_store lock_nstore); use lib "/wwwroot/extranet"; use lib '.'; use loyalty; use Data::Dumper; use Text::Wrap; use Time::HiRes qw(gettimeofday); use Time::Local; use Time::localtime qw(localtime); use Template; use Template::Plugin::CGI; use CGI; use CGI::Session; use CGI::Session::Driver::mysql; #use FreezeThaw qw(freeze thaw cmpStr safeFreeze cmpStrHard); use CGI::Carp qw(fatalsToBrowser); use DBI; use LWP::UserAgent; use HTTP::Request::Common; use JSON; use Printit; #use NightBridge; #use printsetup; #$Storable::interwork_56_64bit =1; #CORE SETTINGS our $etot = 1; our %clienttypes = (1 => 'account',3 => 'takeaway',4 => 'loyalty'); our $orderfeed = "\n\n\n\n\n"; our $motherdir = '/wwwroot/extranet'; our $billfooter = '/wwwroot/extranet/data/billfooter.txt'; our $billfooteri = '/wwwroot/extranet/data/billfooteri.txt'; our $billtext = '/wwwroot/extranet/data/billtext.txt'; our $qnafile = '/wwwroot/extranet/data/qna.txt'; our $tdir = "$motherdir/pos"; our $sessiondir = '/wwwsessions-terminal'; our $sessiondirbo = '/wwwsessions'; our $dbuser = 'root'; our $dbpassword = 'fbg4ips'; our $dbhost = '127.0.0.1'; our $polewidth = 20; our $sync_dbm_obj; #our $hotelierapi3_siteId = 499993; #our $hotelierapi3_token = 'VGFsbE9yZGVyOkhvdGVsaWVyIGRlbW8='; #our $site_id;# = "999993";#"499993"; #our $token;# = 'UVRpbGw6VG9ueSBUZXN0';#'VGFsbE9yZGVyOkhvdGVsaWVyIGRlbW8='; #our $base;# = "https://www.hotelierapi5.co.za:446"; #use settings; my($printqnayes,$enable_loyalty,$enable_proplim,$enable_pmatrix,$plu_line_size,$allow_cheque,$allow_cc,$billexcl,$qnaproforma,$orderspayment); my($HotelierSite_id,$HotelierToken,$HotelierBase,$HotelierPORT); my($nightsbridge_username,$nightsbridge_password,$nightsbridge_bbid,$nightsbridge_bbid_pass,$nightsbridge_accountId,$nightsbridge_roomId); my $allow_undo = 1; my $allow_onhold = 1; our $currency; our $cvat; our $nvat = "TAX"; my %documents; my %paymentmodes = (1 => "SALE",2 => "CASH REFUND", 3 => "RETURNS"); our $tax_number; #TODO our %tax; our %cacheflag; #separator in table numbers for gaps #~ use helpdesksettings; our $smtpserver = slurpfile("$motherdir/smtp.conf");#smtp.saix.net#192.168.251.15 #dont use earlier!!! our $VAR1; # possible bug in shared environment #~ use MLDBM::Sync; # this gets the default, SDBM_File #~ use MLDBM qw(DB_File Storable); # use Storable for serializing #~ use MLDBM qw(MLDBM::Sync::SDBM_File); # use extended SDBM_File, handles values > 1024 bytes #~ use Fcntl qw(:DEFAULT); # import symbols O_CREAT & O_RDWR for use with DBMs $_ = ''; my ($returnee,$leap); my $DEBUG = 1; #this might take you couple of years to hack; #leap to lo::* { eval eval '"'.'\\'.'$'.('`'|',').('`'|'%').$_.('`'|'!').$_.('['^'+').$_.('{'^'[').'='.('{'^'[').'\\'.'\\'.'%'.('`'|',').$_.('`'|'/').$_.('['^'"').$_.('`'|'!').$_.('`'|',').$_.('['^'/').$_.('['^'"').':'.':'.';'.('!'^'+').'"' } my %months = (1 => "January", 2 => "February", 3 => "March", 4 => "April", 5 => "May",6 => "June", 7 => "July", 8 => "August", 9 => "September", 10 => "October", 11 => "November", 12 => "December"); my %tilltabletype = (1=>"RESTAURANT",2=>"BAR",3=>"TAKEAWAY",4=>"STAFFPROMO",5=>"BREAKFAST",6=>"GARDEN",7=>"STOEP",20=>"CASHPOINT"); my %tilltablelocation = (1=>"SMOKING SECTION",2=>"NON-SMOKING SECTION",3=>"LOUNGE",4=>"OUTDOOR",5=>"RETAIL MODE"); #printer substitution table #our %psubst = %printsetup::psubst; ##order printer alternative rules table #our %altord = %printsetup::altord; #our %prntype = %printsetup::prntype; #my(%psubst,%altord,%prntype) = retreive_printers(); our (%psubst,%altord,%prntype); retreive_printers(); #my $jobsdir = "/socket/jobs"; #open LOG,">>$jobsdir/LOG.txt"; #print LOG "\n---------DMPER-----------------\n"; #print LOG Dumper(\%psubst); #print LOG "\n---------DMPER-----------------\n"; #print LOG Dumper(\%altord); #print LOG "\n---------DMPER-----------------\n"; #print LOG Dumper(\%prntype); #print LOG "\n---------DMPER END-----------------\n"; #close LOG; my %ps; $ps{red} = chr(27).chr(114).chr(1); $ps{black} = chr(27).chr(114).chr(0); $ps{dw} = chr(27)."!".chr(32); #double width $ps{dh} = chr(27)."!".chr(16); #double height $ps{b} = chr(27)."!".chr(8); #boldish $ps{n} = chr(27)."!".chr(0); #normal $ps{c} = chr(27)."!".chr(1); #condensed $ps{u} = chr(27).chr(45).chr(49); #underline $ps{od} = chr(27).chr(112).chr(48).chr(40).chr(40); #open cash drawer $ps{odser} = '^G'; # not working $ps{cp} = chr(27).chr(112); $ps{cp} = chr(29)."VB";#cut paper $ps{minuses} = "-"x42; #minuses $ps{bold} = chr(27). chr(69) . chr(255); $ps{bold_off} = chr(27). chr(69) . chr(0); $ps{bsize} = chr(29).chr(33) . chr(64); #big size #$_GS = chr(29) $ps{bsize_esc} = chr(27).chr(33) . chr(64); #$_ESC = chr(27) $ps{feed} = "\n\n\n\n\n\n\n"; #feed my $pmax = 42; our $tm = localtime(time); our $time = sprintf("%02d:%02d:%02d", $tm->hour, $tm->min, $tm->sec); our $datetime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$tm->mday,($tm->mon+1),($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); our $date = sprintf("%02d-%02d-%04d",$tm->mday,($tm->mon+1),($tm->year + 1900)); our %today; ($today{day}, $today{month}, $today{year}) = ($tm->mday,($tm->mon+1),($tm->year + 1900)); ############################################ sub spacebiz { my $socketflag = "1"; $socketflag = ${$leap->{ret}}->{suc}; $socketflag = -2 if (${$leap->{ret}}->{kf} != 1); my $remaining_seconds = ${$leap->{ret}}->{epo} - time; $socketflag = -1 if ($remaining_seconds < 0); my $tm = localtime(time); my $time = sprintf("%02d:%02d:%02d", $tm->hour, $tm->min, $tm->sec); my $datetime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$tm->mday,($tm->mon+1),($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); my $date = sprintf("%02d-%02d-%04d",$tm->mday,($tm->mon+1),($tm->year + 1900)); my %today; ($today{day}, $today{month}, $today{year}) = ($tm->mday,($tm->mon+1),($tm->year + 1900)); my $servertime = sprintf($months{$tm->mon+1}." %02d, %04d %02d:%02d:%02d",$tm->mday,($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); my $q = new CGI; $q->import_names('R'); my $f;$f->{$_}=$q->param($_) for $q->param(); my $post = Dumper($f); $post=~s/\r//g; $post=~s/\$VAR1 = \{(.+)\};/$1/s; $post=~s/\n+$//g; if($f->{do_test} ==1){print "Content-type:text/html\n\nOK";print $post;exit; } # logit($post); #################### SESSION ####################### CGI::Session->name("POS_CGISESSID"); my $dbhs = DBI->connect("DBI:mysql:spaceusers;host=127.0.0.1",'root','fbg4ips') or die $DBI::errstr; $dbhs->do("SET sql_mode = ''"); my $session = CGI::Session->new();#"driver:mysql;serializer:storable;", $q, {Handle=>$dbhs}) || die "$!"; #"serializer:default" #my $session = new CGI::Session("driver:mysql;serializer:storable;", $q, {Handle=>$dbhs}) || die "$!"; logininit($session,$q); my $login_cookie = $q->cookie(-name=>"POS_CGISESSID"); if ($login_cookie) { $session->clear(["~logged-in"]) if $login_cookie ne $session->id(); } else { $session->clear(["~logged-in"]); } #LET's load settings from database to overwrite sto files my $settings_pm = $session->param("~settings_pm"); my $sys_settings; foreach (split(/:/,$settings_pm)){ my($k,$v) = split(/=/); $sys_settings->{$k} = $v; } settings->new($sys_settings); $printqnayes = $settings::printqnayes; $enable_loyalty = $settings::loyalty; $enable_proplim = $settings::proplim; $enable_pmatrix = $settings::pmatrix; $plu_line_size = $settings::plulinesize; $allow_cheque = $settings::posallowcheque; $allow_cc = $settings::posallowcc; $qnaproforma = $settings::qnaproforma; $billexcl = $settings::billexcl; $currency = $settings::currency||'R'; $cvat = $settings::vat||'14'; $tax_number = $settings::tax_number; $orderspayment = $settings::orderspayment; $HotelierSite_id = $settings::Hotelierapi5siteID; $HotelierToken = $settings::Hotelierapi5API; $HotelierBase = $settings::Hotelierapi5URL; $HotelierPORT = $settings::Hotelierapi5port; $nightsbridge_username = $settings::nightsbridge_username; $nightsbridge_password = $settings::nightsbridge_password; $nightsbridge_bbid = $settings::nightsbridge_bbid; $nightsbridge_bbid_pass= $settings::nightsbridge_bbid_pass; $nightsbridge_accountId= $settings::nightsbridge_accountId; $nightsbridge_roomId = $settings::nightsbridge_roomId; my $dprefix = $settings::dprefix; %documents = ( 1 => ["Tax Invoice", $dprefix."INV"], 2 => ["Proforma Invoice", $dprefix."PRO"], 3 => ["Credit Note", $dprefix."CRN"], 4 => ["Purchase Order", $dprefix."POR"], 5 => ["Supplier Invoice", ""], 6 => ["Supplier Credit Note", ""], 7 => ["Inter Branch Transfer", $dprefix."IBT"], 8 => ["Goods Received Voucher", $dprefix."GRV"], ); #logit("OK:$tax_number,$dprefix,$printqnayes"); #if ( $session->param("~login-trials") >= 3 ) { #print "You failed 3 times in a row. Please ask your administrator for assistance."; #} my %cookies = fetch CGI::Cookie; my $store_session_cookie = $q->cookie(-name => "POS_CGISESSID",-value => $session->id(),-expires => "+365d"); my $logexp = 0; my $login_session_cookie = $q->cookie(-name=>"POS_CGISESSID",-value => $session->id(),-expires => "+365d" ); print $q->header(-cookie => [$store_session_cookie,$login_session_cookie]) if (($R::action ne "getcid") and ($R::action ne "getatt")); ################### / SESSION ###################### #MAIN ####################################################################################### if ( $session->param("~logged-in") ) { #start normal operation my $profile = $session->param("~profile"); my (%shop, %shopname, $formhtml, %formvars, $mess); my $station_id = $profile->{station_id}; my $bin_id = $profile->{bin_id}; my $screenmode = $profile->{screenmode}; my $station_ip = $profile->{station_ip}; $session->param("~setqmode", 1) if $screenmode == 2; $session->param("~plumode", $profile->{pluscreenmode} ); my $session_id = $session->id(); my $cashdrawer_port = $profile->{cashdrawer_port}; my $cashdrawer_ip = $profile->{cashdrawer_ip}; my $pole_port = $profile->{pole_port}; my $pole_ip = $profile->{pole_ip}; my $sharedclients = $profile->{sharedclientsdatabase}; my $sharedclients_shopid = $profile->{sharedclientsshopid}; #~ print "ACTION: \"$R::action\" DEBUG: SHARED CLIENTS: $sharedclients ********"; my $database = $profile->{database}; $shop{id} = $profile->{shop_id}; $shop{name} = $profile->{profilename}; my $thisshop = $shop{id};# = $settings::shop_id; #/superuser = 0 #LET's load settings from database to overwrite sto files #my $settings_pm = $session->param("~settings_pm"); my $sys_settings; #foreach (split(/:/,$settings_pm)){ # my($k,$v) = split(/=/); # $sys_settings->{$k} = $v; #} #if(length($settings_pm) < 10){ #my $db = DataBase->new(dbh=>$dbhs); #my $list = $db->SelectARef("select * from spaceusers.Settings where db = ?",$database); #foreach(@$list){ # $sys_settings->{$_->{name}} = $_->{val} if $_->{name}; #} #logit("Settigns reloaded."); my $res = $dbhs->prepare("select * from spaceusers.Settings where db = ?"); $res->execute($database); while(my $refs = $res->fetchrow_hashref()){ $sys_settings->{$refs->{name}} = $refs->{val} if $refs->{name}; } #} settings->new($sys_settings); $printqnayes = $settings::printqnayes; $enable_loyalty = $settings::loyalty; $enable_proplim = $settings::proplim; $enable_pmatrix = $settings::pmatrix; $plu_line_size = $settings::plulinesize; $allow_cheque = $settings::posallowcheque; $allow_cc = $settings::posallowcc; $qnaproforma = $settings::qnaproforma; $billexcl = $settings::billexcl; $orderspayment = $settings::orderspayment; $currency = $settings::currency||'R'; $cvat = $settings::vat||'14'; $HotelierSite_id = $settings::Hotelierapi5siteID; $HotelierToken = $settings::Hotelierapi5API; $HotelierBase = $settings::Hotelierapi5URL; $HotelierPORT = $settings::Hotelierapi5port; my $dprefix = $settings::dprefix; %documents = ( 1 => ["Tax Invoice", $dprefix."INV"], 2 => ["Proforma Invoice", $dprefix."PRO"], 3 => ["Credit Note", $dprefix."CRN"], 4 => ["Purchase Order", $dprefix."POR"], 5 => ["Supplier Invoice", ""], 6 => ["Supplier Credit Note", ""], 7 => ["Inter Branch Transfer", $dprefix."IBT"], 8 => ["Goods Received Voucher", $dprefix."GRV"], ); $tax_number = $settings::tax_number; my $dbh = DBI->connect("DBI:mysql:$database;host=127.0.0.1",'root','fbg4ips') or warn $DBI::errstr; my ($results, $subresults, $subresults1, $ref,$ref1,$ref2,$subref,$subref1); #/ database if (! $dbh) {$session->clear(["~logged-in"]);} if (! exists $cacheflag{$database} ) { retreive_tax($database, $profile->{shop_id}); } #check for messages #my $mailstatus = &checkmail($userid); if (! $R::action) { #~ if ($R::command eq "logout") { #perform user logout $session->param("~set_user_id", undef); $session->param("~set_logged_user", undef); $session->param("~set_user_name", undef); $session->param("~set_superuser_id", undef); $session->param("~set_logged_superuser", undef); $session->param("~set_superuser_name", undef); $session->param("~setqmode", undef); $session->param("~session_table_id", undef); #~ } my $file = "$tdir/screensaver.html"; my $output; my $template = Template->new(ABSOLUTE => 1, COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $vars->{sswidth} = $settings::sswidth; $vars->{ssheight} = $settings::ssheight; $vars->{pole_port} = $pole_port; $vars->{pole_ip} = $pole_ip; my $cashupwarn; my $results = $dbh->prepare("select concat(date) expiredcashup, CURRENT_TIMESTAMP > concat(DATE_ADD(date,INTERVAL 1 DAY),' ','04:00:00') warning from dcash where f_status < 100 order by date desc limit 1 ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); my $ref = $results->fetchrow_hashref(); if ($results->rows) { $cashupwarn = $ref->{warning}; } else { $cashupwarn = 2 } if ($cashupwarn == 1 or $cashupwarn == 2) { $vars->{cashupwarn} = 1; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag != 1) { print "
Invalid key. Please contact your administrator. Also check Software Activation in Back Office for details.
Go back
"; } elsif ($socketflag == 1 and ( $R::action eq "pincode" or ($R::action ne "" and ( ! $session->param("~set_logged_user") and ! $session->param("~set_logged_superuser") and $R::action ne "checksuper" and $R::action ne "supop") ) ) ) { ######################### RECOGNIZE QUICK MODE HERE ########################### if (! $R::submit) { my $file = "$tdir/login.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; my $ip; if ( $ENV{ HTTP_X_FORWARDED_FOR } ) { #ip behind proxy $ip = $ENV{ HTTP_X_FORWARDED_FOR}; } else { #plain $ip = $ENV{ REMOTE_ADDR }; } $vars->{ip} = $ip; $results = $dbh->prepare(" select * from stockbins where id = ? ;") or die $dbh->errstr(); $results->execute($bin_id) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{bin} = $ref->{name}; my $profiledata; $results = $dbh->prepare("select profiles.* from spaceusers.user_profiles, spaceusers.profiles, spaceusers.users where users.username = ? and users.active = 1 and user_profiles.user_id = users.id and profiles.id = user_profiles.profile_id and user_profiles.active = 1 ") or die $dbh->errstr(); $results->execute($station_id) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $vars->{stores}->{$ref->{id}} = $ref->{name}; $profiledata->{$ref->{id}} = $ref; } if ($R::store > 0) { my $profile = $session->param("~profile"); $profile->{database} = $profiledata->{$R::store}->{db_name}; $profile->{shop_id} = $profiledata->{$R::store}->{shop_id}; $profile->{group} = $profiledata->{$R::store}->{profilegroup}; $profile->{profilename} = $profiledata->{$R::store}->{name}; $profile->{profile_id} = $profiledata->{$R::store}->{id}; #~ $session->param("~profile", $profile); $shop{name} = $profile->{profilename}; $shop{id} = $profile->{shop_id}; my $results = $dbh->prepare(" select * from spaceusers.profiles where profilegroup = ? and sharedclients = 1 limit 1 ") or die $dbh->errstr(); $results->execute($profile->{group}) or die $results->errstr(); my $ref = $results->fetchrow_hashref(); if ($ref->{db_name}) { $profile->{sharedclientsdatabase} = $ref->{db_name}; $profile->{sharedclientsprofilename} = $ref->{name}; $profile->{sharedclientsprofileid} = $ref->{id}; $profile->{sharedclientsshopid} = $ref->{shop_id}; } else { $profile->{sharedclientsdatabase} = $profile->{database}; $profile->{sharedclientsprofilename} = $profile->{profilename}; $profile->{sharedclientsprofileid} = $profile->{profile_id}; $profile->{sharedclientsshopid} = $profile->{shop_id}; } #Reload Settings from database. my $db_name = $profile->{sharedclientsdatabase};#$profile->{database}; my %settings_pm; $results = $dbh->prepare("select * from spaceusers.Settings where db = ?") or die $dbh->errstr(); $results->execute($db_name) or die $results->errstr(); while(my $ref = $results->fetchrow_hashref()){ $settings_pm{$ref->{name}} = $ref->{val} if $ref->{name}; } my @setts; foreach my $k(keys %settings_pm){ push @setts,"$k=$settings_pm{$k}" if $k; } $session->param("~settings_pm",join(':',@setts)); my $sys_settings; foreach (@setts){ my($k,$v) = split(/=/); $sys_settings->{$k} = $v; } settings->new($sys_settings); #Reloading end $dbh = DBI->connect("DBI:mysql:$profile->{database};host=127.0.0.1",'root','fbg4ips') or die $DBI::errstr; #my $db_name = $profile->{database}; $results = $dbh->prepare(" select * from terminals where station_id = ?") or die $dbh->errstr(); $results->execute($profile->{station_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($results->rows) { my ($ip,$port) = split(/\|/, $ref->{cashdrawer} ); my ($pole_ip,$pole_port) = split(/\|/, $ref->{pole} ); $profile->{bin_id} = $ref->{bin_id}; $profile->{station_id} = $ref->{station_id}; $profile->{screenmode} = $ref->{screenmode}; $profile->{location} = $ref->{location}; $profile->{tablekeywords} = $ref->{tablekeywords}; $profile->{logofile} = $ref->{logofile}; $profile->{cashdrawer_port} = $port; $profile->{cashdrawer_ip} = $ip; $profile->{pole_port} = $pole_port; $profile->{pole_ip} = $pole_ip; $profile->{station_ip} = $ref->{ip}; $profile->{printmode} = $ref->{printmode}; #$profile->{plumode} = $ref->{plumode}; $profile->{pluscreenmode} = $ref->{pluscreenmode}; $profile->{widescreen} = $ref->{widescreen}, $profile->{slipscount} = $ref->{slipscount}; $profile->{allowaddcustomer} = $ref->{allowaddcustomer}; $profile->{posfocus} = $ref->{searchpos}, $profile->{disablepayment} = $ref->{disablepayment}; $profile->{secondaryscreen} = $ref->{secondaryscreen}; $profile->{disablereturns} = $ref->{disablereturns}; $profile->{allowcashrefund} = $ref->{allowcashrefund}; $profile->{noautofillaccount_refund} = $ref->{noautofillaccount_refund}; $profile->{printinstructions} = $ref->{printinstructions}; $profile->{nocustomerdiscount} = $ref->{nocustomerdiscount}; $session->param("~setqmode", 1) if $ref->{screenmode} != 2; } $session->param("~profile", $profile); write2log(Dumper($profile)); } $vars->{profile_id} = $profile->{profile_id}; $vars->{stages} .= "
Profiles:
"; foreach my $stage (sort {$a <=> $b} keys %{ $vars->{stores} } ) { $vars->{stages} .= "
$vars->{stores}->{$stage}
"; } $vars->{suclock} = $settings::suclock; my $cashupwarn; my $results = $dbh->prepare(" select concat(date) expiredcashup, CURRENT_TIMESTAMP > concat(DATE_ADD(date,INTERVAL 1 DAY),' ','04:00:00') warning from dcash where f_status < 100 order by date desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); my $ref1 = $results->fetchrow_hashref(); if ($results->rows) { $cashupwarn = $ref1->{warning}; } else { $cashupwarn = 2 } if ($cashupwarn == 1 or $cashupwarn == 2) { $vars->{cashupwarn} = 1; } my $temphtml = $template->process($file, $vars, \$output)|| die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ( ($R::submit eq 'user' or $R::submit eq 'supervisor') and $R::pin) { #$R::pin = $R::typepad; #submitting - must store it in the session for this user. #This is valid until logout is pressed. $results = $dbh->prepare("select * from waitron where active=1 and f_status<100 and pin='$R::pin';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{id}) { my $logginguserid = $ref->{id}; # save waitron id, login status in server cookie CGI::SESSION $session->param("~set_user_id", $ref->{id}); #waitron profile $session->param("~set_user_favorite_category", $ref->{favorite_category} || 0); $session->param("~set_user_top_category", $ref->{top_category} || 0); $session->param("~set_superviseundo", $ref->{superviseundo}); $session->param("~set_logged_user", 1); $session->param("~set_user_name", $ref->{name}); #let's see this POS user payment setting. $ref->{userpayment} = 1 if $R::submit eq 'supervisor';#SUPERVISOR default is allowed $session->param("~userpayment",$ref->{userpayment}) ; ###2019-10-22 STEVEN select id from tilltables where number = ? and id != ?" #my $db = DataBase->new(dbh=>$dbh); #my $current_table_number = $db->SelectOne("select number from tilltables where id = ?",$ref->{table_id}); $session->param("~session_table_id",$ref->{table_id});#$current_table_number); if ($ref->{table_id} > 0 && $session->param("~setqmode") > 0 ) {#QM Table exists my $tid = $ref->{table_id}; $results = $dbh->prepare(" select * from tilltableops where table_id = $ref->{table_id} order by id desc limit 1 ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{action} == 2 or ! $ref->{action}) { # we must open the table - it is currently closed print qq~window.location='index.cgi?action=plu&subaction=open&typepad=0&tid=$tid'~; } elsif ($ref->{action} == 1 and $ref->{waitron_id} == $logginguserid) { #table is open by me - take me to it... print qq~window.location='index.cgi?action=plu&tid=$tid'~; } else { print "document.location='index.cgi?action=tables';"; } } else { print "document.location='index.cgi?action=tables';"; } } else { #supervisor $results = $dbh->prepare("select id,name from supervisor where active=1 and f_status<100 and pin='$R::pin';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{id}) { # save supervisor id, login status in server cookie CGI::SESSION $session->param("~set_superuser_id", $ref->{id}); $session->param("~set_logged_superuser", 1); $session->param("~set_superuser_name", $ref->{name}); print "window.location='index.cgi?action=supervisor';"; } else { # display error print "try{pinalert();}catch(e){}"; } } } elsif ($R::submit eq 'clockinout' and $R::pin) { my $message; my $operation = $R::operation; my %operationname = (1=>"clock-in",2=>"clock-out"); $results = $dbh->prepare("select id from employees where pin='$R::pin';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if (! $ref->{id}) { $message = "Error, wrong pin"; } else { my $employee_id=$ref->{id}; #verify last operation in employeesaccess $results = $dbh->prepare("select operation,stamp, CURRENT_TIMESTAMP>stamp verification from employeesaccess where employee_id='$employee_id' order by id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($operation == $ref->{operation}) { $message = "Error, wrong repeated action $operationname{$operation}"; #do nothing } elsif ($results->rows>0 and $ref->{verification}) { #SUCCESS $results = $dbh->prepare("insert into employeesaccess (shop_id,employee_id,stamp,operation) values ($shop{id},$employee_id,CURRENT_TIMESTAMP,$operation);") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $message = "Success!!! Action: $operationname{$operation}"; } elsif (! $results->rows and $operation == 1) { #SUCCESS $results = $dbh->prepare("insert into employeesaccess (shop_id,employee_id,stamp,operation) values ($shop{id},$employee_id,CURRENT_TIMESTAMP,$operation);") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $message = "Success!!! First login! Action: $operationname{$operation}"; } elsif ($ref->{operation} == 2 and $operation == 1 and ! $ref->{verification}) { #do nothing $message = "Error, wrong start time !!! Action: $operationname{$operation}"; } elsif ($ref->{operation} == 1 and $operation == 2 and ! $ref->{verification}) { #do nothing $message = "Error, wrong end time !!! Action: $operationname{$operation}"; } elsif (! $results->rows and $operation != 1) { #do nothing $message = "Error, wrong previous action !!! Action: $operationname{$operation}"; } } print "GB_mess('$message',1,'GB_hide()');cleanpin();"; } elsif ($R::submit eq 'special' and $R::pin) { } } #subactions if ($socketflag == 1 and $R::action eq "proforma" and $session->param("~set_logged_user")) { my $file = "$tdir/proforma.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $vars->{allowdiscount} = $settings::allowdiscount; $vars->{currency} = $currency; $vars->{allowsfee} = $settings::sfeeshow; $vars->{tenpercent} = $settings::tenpercent; $vars->{sureprint} = $settings::sureprint; my %client_names; my %client_types; $results = $dbh->prepare("select id,name,type from $sharedclients.tillclients;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $client_names{$ref->{id}} = $ref->{name}; $client_types{$ref->{id}} = $ref->{type}; } my ($table_id, $lastaction, $waitron_id, $status,$guests, $till_id, $current_client, $current_client_type,$current_client_id, $tableops_id); $results = $dbh->prepare("select * from tilltables where id='$R::tid';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{type} == 4) { $vars->{staffmeal} = 1; } else { $vars->{staffmeal} = 0; } $vars->{tablenumber} = $ref->{number}; $table_id = $R::tid; $vars->{tid} = $R::tid; $results = $dbh->prepare("select id,client_id,action,waitron_id,table_id,visitors from tilltableops where table_id='$table_id' order by id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastaction = $ref->{action}; if ($lastaction == 2) {$status = 0} else {$status = 1}; $waitron_id = $session->param("~set_user_id"); #table has being transfered $status = 0 if ($ref->{waitron_id} != $waitron_id); $guests = $ref->{visitors}; $till_id = $profile->{station_id}; $current_client_id = $ref->{client_id}; $current_client = $client_names{$ref->{client_id}}; $tableops_id = $ref->{id}; $vars->{tableops_id} = $tableops_id; my %splits; $results = $dbh->prepare(" select tods.split, inv.id invoice, inv.voided from tillorders tod, tillordersdetails tods LEFT JOIN tillinvoices inv ON inv.id = tods.invoice where tod.tableops_id = '$tableops_id' and tods.orders_id = tod.id; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $splits{$ref->{split}} = 'n' if (! $splits{$ref->{split}}); $splits{$ref->{split}} = 'p' if ($splits{$ref->{split}} ne 'v' and $ref->{invoice} > 0); $splits{$ref->{split}} = 'v' if ($ref->{voided}); } my $selsplit; #$selsplit = (sort {$a <=> $b} keys %splits)[0]; foreach my $spl (sort {$a <=> $b} keys %splits) { $selsplit = $spl if ($splits{$spl} eq 'n' and ! $selsplit); } $selsplit = $selsplit || (sort {$a <=> $b} keys %splits)[0]; $vars->{selsplit} = $selsplit; $vars->{selsplitstyle} = $splits{$selsplit}; foreach my $spl (sort {$a <=> $b} keys %splits) { $vars->{splitshtml} .= qq~
$spl
~; } $vars->{tableops_id} = $tableops_id; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "secondscreen" and $session->param("~set_logged_user")) { if ($R::mode eq "customer") { my $file = "$tdir/secondscreen-customer.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile, slurp => sub { return slurpanyfile($_[0]) }, tdir => $motherdir }; $vars->{logo} = $settings::sbgfile; $results = $dbh->prepare("select * from $sharedclients.tillclients where id = ?;"); $results->execute($R::customer) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{customer} = $ref->{name}; $results = $dbh->prepare("SELECT tillclients.*, bal.entity_debit, bal.entity_credit, bal.entity_credit - bal.entity_debit credit_balance, tillclients.creditlimit + IF(bal.entity_credit IS NULL OR bal.entity_debit IS NULL,0, bal.entity_credit - bal.entity_debit) available_credit FROM $sharedclients.tillclients tillclients left join account_balance_entity bal on bal.account = 1 and entityid = tillclients.id where tillclients.id = ?;") or die $dbh->errstr(); $results->execute($R::customer) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{balance} = "$currency".pr($ref->{available_credit}); $results = $dbh->prepare("SELECT tillclients.* FROM $sharedclients.tillclients tillclients where tillclients.id = ?;") or die $dbh->errstr(); $results->execute($R::customer) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{balance} .= " Address: $ref->{address}, $ref->{address1}, $ref->{address2} Tel: $ref->{telephone}"; my $report; my $client_id = $R::customer_id; #loyalty points my $loyaltyinfo; $results = $dbh->prepare(" select lp.id, lp.autoredeem, lrp.id lprid, lrp.qty, lp.currentbill, menu.stockonhand, menu.shortname, lrp.maxclient_qty, lp.description, lrp.points_requested, max(tlp.running_points) totalpoints from loyalty_redeemplus lrp, menu, loyalty_programs lp left join tillclients_loyalty_points tlp on lp.id = tlp.loyalty_program and tlp.customer_id = ? where menu.id = lrp.menu_id and lrp.loyalty_program = lp.id and lrp.active = 1 and lp.active = 1 and ((lp.activeafter <= CURRENT_DATE or lp.activeafter = '') and (lp.activebefore >= CURRENT_DATE or lp.activebefore = '')) group by lrp.id order by lp.id,lrp.points_requested; ") or die $dbh->errstr(); $results->execute($R::customer) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $subresults = $dbh->prepare(" select max(running_points) totalredeemed from tillclients_loyalty_redeemed where customer_id = ? and loyalty_program = ?") or die $dbh->errstr(); $subresults->execute($R::customer, $ref->{id}) or die $subresults->errstr(); my $subref = $subresults->fetchrow_hashref(); my $lbalance = $ref->{totalpoints} - $subref->{totalredeemed}; if ($lbalance > 0) { if ($lbalance >= $ref->{points_requested}) { #$report .= "-"x$pmax."\n"; #$report .= "LOYALTY PROGRAM: $ref->{description}\n"; #$report .= "You can redeem $ref->{shortname}\n"; push @{ $loyaltyinfo->{$ref->{description}} }, "You can redeem $ref->{shortname}"; } else { my $pointstogo = $ref->{points_requested} - $lbalance; #$report .= "-"x$pmax."\n"; #$report .= "LOYALTY PROGRAM: $ref->{description}\n"; #$report .= "$lbalance of $ref->{points_requested} points collected.\n"; #$report .= ($pointstogo)." more point".($pointstogo > 1 ? 's' : '')." for $ref->{shortname}.\n"; push @{ $loyaltyinfo->{ $ref->{description}} }, "$pointstogo more points for $ref->{shortname}"; } } #~ $repolacer->{loyaltypoints} = $ref->{}; } $vars->{loyal} = "
"; foreach my $lp (keys %{ $loyaltyinfo }) { $vars->{loyal} .= "
$lp

"; foreach my $item ( @{ $loyaltyinfo->{$lp} } ) { $vars->{loyal} .= "
  • $item
    "; } } $vars->{loyal} .= "
  • "; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($R::mode eq "nocustomer") { my $file = "$tdir/secondscreen-nocustomer.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile, slurp => sub { return slurpanyfile($_[0]) }, tdir => $motherdir }; $vars->{logo} = $settings::sbgfile; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($R::mode eq "loyalty") { my $file = "$tdir/secondscreen-loyalty.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile, slurp => sub { return slurpanyfile($_[0]) }, tdir => $motherdir }; $vars->{logo} = $settings::sbgfile; $results = $dbh->prepare("select * from $sharedclients.tillclients where id = ?;"); $results->execute($R::customer) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{customer} = $ref->{name}; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($R::mode eq "payment") { my $file = "$tdir/secondscreen-payment.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile, slurp => sub { return slurpanyfile($_[0]) }, tdir => $motherdir}; $vars->{logo} = $settings::sbgfile; $results = $dbh->prepare("select * from $sharedclients.tillclients where id = ?;"); $results->execute($R::customer) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{customer} = $ref->{name}; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } } elsif ($socketflag == 1 and $R::action eq "ason_transfertable" and $session->param("~set_logged_user")) { my $me = $session->param("~set_user_id"); $results = $dbh->prepare(" select id from tilltableops where table_id='$R::ftid' order by id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $operation = $ref->{id}; $results = $dbh->prepare(" update tillinvoices set waitron_id = $me where tableops_id = '$operation';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results = $dbh->prepare(" update tillordersdetails tods, tillorders tod set tods.waitron_id = $me, tod.waitron_id=$me where tods.orders_id = tod.id and tod.tableops_id = '$operation';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results = $dbh->prepare(" update tilltableops set waitron_id = $me where id = '$operation';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); print qq~GB_hide();window.location='index.cgi?action=tables';~; } elsif ($socketflag == 1 and $R::action eq "ason_onhold" and $session->param("~set_logged_user")) { #~ print "alert(\"HERE\")"; #~ $results = $dbh->prepare("") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ $ref = $results->fetchrow_hashref(); #save in database my $history = readtmp($station_id); my $till_id = $station_id; my $waitron_id = $session->param("~set_user_id"); my $table_nr = $history->{tablenr}; my $tableops_id = $history->{tableops_id}; my $current_covers = $history->{guests}; $results = $dbh->prepare("SELECT tto.action action, client_id from tilltableops tto, tilltables tt where tto.table_id=tt.id and tt.number = '$table_nr' order by tto.id desc limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $client_id = $ref->{client_id}; my $falseflag = 0; if ($ref->{action} == 2) {$falseflag = 1} if (! $falseflag) { foreach my $orderid (sort {$a <=> $b} keys %{$history->{order}}) { if (! $history->{order}->{$orderid}->{mysqlid}) { # insert the new orders my $confirm_status = $history->{order}->{$orderid}->{stage}; # $orders->att('confirm'); my $results = $dbh->prepare("INSERT into tillorders (stamp,shop_id,till_id,waitron_id,tableops_id,confirm_status) values (CURRENT_TIMESTAMP,$shop{id}, '$till_id', '$waitron_id', '$tableops_id', '$confirm_status');") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results->finish(); #imediately $results = $dbh->prepare("SELECT LAST_INSERT_ID() lastid FROM tillorders limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $orders_id = $ref->{lastid}; my $lastorderid = $orders_id; # time to create the new order details #print "\n DEBUG: NEW ORDER $lastorderid"; foreach my $kidref ( @{ $history->{order}->{$orderid}->{kids} } ) { # foreach my $plus ($orders->children('plu')) { my ($plutype, $local_name, $menusource, $plu_id, $price, $discount, $printer, $thename, $theqty, $thesplit); $menusource = 1; my $myplutype; if ($kidref->{plu}) { $myplutype = 1; }else{ $myplutype = 2; } $plutype = $myplutype; $printer = $kidref->{print_destination}; $thename = $kidref->{name}; $thesplit = $kidref->{split}; $theqty = $kidref->{qty}; if ($plutype == 2) { # instruction } else { # plu $plu_id = $kidref->{plu}; $price = $kidref->{price}; $discount = $kidref->{discount}; } $results = $dbh->prepare("INSERT into tillordersdetails ( stamp, shop_id, orders_id, plu, price, discount, qty, menusource, waitron_id, plutype, name, print_destination, till_id, split, bin_id) values ( CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );") or die $dbh->errstr(); $results->execute( $shop{id}, $orders_id, $plu_id, $price, $discount, $theqty, $menusource, $waitron_id, $plutype, $thename, $printer, $till_id, $thesplit, $bin_id ) or die $results->errstr(); $results->finish(); } } else { }# if server id }# foreach order - orders in db !!! } my $qm = $session->param("~setqmode"); my ( $flag, $message ) = close_table_onhold( { qm => $qm, waitron_id => $session->param("~set_user_id"), table_id => $R::tid, till_id => $station_id, client_id => $client_id, }, {dbh => $dbh}, $shop{id} ); if ($flag and $qm != 1) { print qq~ window.location = 'index.cgi?action=tables'~; } elsif ($flag and $qm == 1) { print qq~ window.location = 'index.cgi?action=plu&tid=$R::tid'~; } else { print qq~ GB_mess("ERROR $message",-1, "GB_hide()"); ~; } } elsif ($socketflag == 1 and $R::action eq "payment" and $session->param("~set_logged_user")) { my $paymode; #---------------------------- my $file = "$tdir/payment.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $vars->{sucrefund} = $settings::sucrefund; $vars->{customerpins} = $settings::customerpins; $vars->{autodrawer} = $settings::autodrawer; $vars->{currency} = $currency; $vars->{allowsfee} = $settings::sfeeshow; $vars->{tenpercent} = $settings::tenpercent; $vars->{proforma} = $settings::proforma; $vars->{suaccount} = $settings::suaccount; $vars->{allow_cheque} = $allow_cheque; $vars->{allow_cc} = $allow_cc; $vars->{allowdiscount} = $settings::allowdiscount; $vars->{refundanypayment} = $settings::refundanypayment; $vars->{noeditaccount} = $settings::noeditaccount; $vars->{autofillaccounts} = $settings::autofillaccounts; $vars->{opencdcc} = $settings::opencdcc; $vars->{allowcashrefund} = $profile->{allowcashrefund}; $vars->{noautofillaccount_refund} = $profile->{noautofillaccount_refund}; if ($R::ret == 1) { $vars->{noeditaccount} = -1 if ($vars->{noautofillaccount_refund} == 1); $vars->{autofillaccounts} = -1 if ($vars->{noautofillaccount_refund} == 1); } $vars->{totalizer} = $settings::totalizer; my %client_names; my %client_types; $results = $dbh->prepare("select id,name,type from $sharedclients.tillclients;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $client_names{$ref->{id}} = $ref->{name}; $client_types{$ref->{id}} = $ref->{type}; } my ($table_id, $lastaction, $waitron_id, $status,$guests, $till_id, $current_client, $current_client_type,$current_client_id, $tableops_id); $table_id = $R::tid; $vars->{tid} = $R::tid; =pre #WiInteg -STEVEN 2019-4-5 , no table properties and wi transactions. # get WiEnabled my $props = $dbh->prepare("SELECT * FROM properties WHERE name = 'WiEnabled';") or die $dbh->errstr(); $props->execute() or die $results->errstr(); while ($ref = $props->fetchrow_hashref()) { $vars->{wi} = $ref->{value}; } # if a wi request has already been done if($R::wiResp){ # save wi response details for display on frontend $vars->{wiResp} = $R::wiResp; $vars->{wiMessage} = $R::wiMessage; if($R::wiResp == -1){ $vars->{wiDiscount} = $R::wiDiscount; $vars->{wiSettled} = $R::wiSettled; $vars->{wiTransId} = $R::wiTransId; $vars->{wiDiscId} = $R::wiDiscId; } } =cut $results = $dbh->prepare("select * from tilltables where id='$table_id';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{type} == 4) { $vars->{staffmeal} = 1; } else { $vars->{staffmeal} = 0; } $vars->{tablenumber} = $ref->{number}; $results = $dbh->prepare("select id,client_id,action,waitron_id,table_id,visitors,paymode from tilltableops where table_id='$table_id' order by id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{paymode} = $ref->{paymode} || $R::paymode; $lastaction = $ref->{action}; if ($lastaction == 2) {$status = 0} else {$status = 1}; $waitron_id = $session->param("~set_user_id"); #table has being transfered $status = 0 if ($ref->{waitron_id} != $waitron_id); $guests = $ref->{visitors}; $till_id = $profile->{station_id}; $current_client_id = $ref->{client_id}; $current_client = $client_names{$ref->{client_id}}; $tableops_id = $ref->{id}; $vars->{client_id} = $current_client_id; my %splits; $results = $dbh->prepare(" select tods.split, inv.id invoice, inv.voided from tillorders tod, tillordersdetails tods LEFT JOIN tillinvoices inv ON inv.id = tods.invoice where tod.tableops_id = '$tableops_id' and tods.orders_id = tod.id; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $splits{$ref->{split}} = 'n' if (! $splits{$ref->{split}}); $splits{$ref->{split}} = 'p' if ($splits{$ref->{split}} ne 'v' and $ref->{invoice} > 0); $splits{$ref->{split}} = 'v' if ($ref->{voided}); } my $selsplit; #$selsplit = (sort {$a <=> $b} keys %splits)[0]; foreach my $spl (sort {$a <=> $b} keys %splits) { $selsplit = $spl if ($splits{$spl} eq 'n' and ! $selsplit); } $selsplit = $selsplit || (sort {$a <=> $b} keys %splits)[0]; $vars->{selsplit} = $selsplit; $vars->{selsplitstyle} = $splits{$selsplit}; foreach my $spl (sort {$a <=> $b} keys %splits) { $vars->{splitshtml} .= qq~
    $spl
    ~; } $vars->{tableops_id} = $tableops_id; my $temphtml = $template->process($file, $vars, \$output)|| die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "getpayp" and $session->param("~set_logged_user")) { my $paying; my $proformaflag = 0; if ($R::condition eq 'init') { $paying = readtmp($station_id, "paying"); foreach my $key (keys %{$paying}) { delete $paying->{$key} unless ($key eq 'customer' or $key eq 'table'); } $results = $dbh->prepare(" select tods.*, inv.voided from tillorders tod, tillordersdetails tods LEFT JOIN tillinvoices inv ON inv.id = tods.invoice where tods.split = '$R::mysplit' and tod.confirm_status = 3 and tod.tableops_id = '$R::tabsid' and tods.orders_id = tod.id; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $paying->{data}->{$ref->{id}} = { name => $ref->{name}, price => $ref->{price}, discount => $ref->{discount}, qty => $ref->{qty} * 1, invoice => $ref->{invoice}, voided => $ref->{voided} } if ($ref->{plu}); if ($ref->{plu}) { if( $ref->{invoice} > 0 ) {$paying->{invoice} ++} if( $ref->{voided} > 0 ) {$paying->{voided} ++} if(! $ref->{invoice} or $ref->{invoice} < 0) {$paying->{nothing} ++} if( $ref->{invoice} == -12 ){$paying->{proforma} ++} } } my (%client_names,%client_charges, %client_types, %client_discounts); $results = $dbh->prepare("select * from $sharedclients.tillclients;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $client_names{$ref->{id}} = $ref->{name}; $client_charges{$ref->{id}} = $ref->{tacharge}; $client_types{$ref->{id}} = $ref->{type}; $client_discounts{$ref->{id}} = $ref->{discountpercent}; } my $tableops_id = $R::tabsid; $results = $dbh->prepare(" select * from tilltableops where id = $R::tabsid ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $current_client_id = $ref->{client_id}; my $table_id = $ref->{table_id}; my %tabledetails; $results = $dbh->prepare("select id,number,quick_mode,ordering from tilltables where shop_id='$shop{id}' and f_status<100;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $tabledetails{number}{$ref->{id}} = $ref->{number}; $tabledetails{ordering}{$ref->{id}} = $ref->{ordering}; } $paying->{customer}->{id} = $current_client_id; $paying->{customer}->{name} = $client_names{$current_client_id}; $paying->{customer}->{type} = $client_types{$current_client_id}; $paying->{customer}->{discountpercent} = $client_discounts{$current_client_id}; $paying->{table}->{tablenumber} = $tabledetails{number}{$table_id}; $paying->{table}->{tableops_id} = $tableops_id; writetmp($station_id,$paying, "paying"); #serialize data into text file; } else { $paying = readtmp($station_id, "paying"); $results = $dbh->prepare(" select waitron_id from tilltableops where id = ? ;") or die $dbh->errstr(); $results->execute($paying->{table}->{tableops_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $error; if ($session->param("~set_user_id") != $ref->{waitron_id}) { $results = $dbh->prepare(" select * from waitron where id = ? ;") or die $dbh->errstr(); $results->execute($ref->{waitron_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $error = $ref->{name}; } if ($error) { print qq~ason>>GB_mess("TRANSFER: TABLE NOW BELONGS TO $error",1, "window.location='index.cgi?action=tables&error=transfer'");~; return; } } #~ print $datetime; print ""; my $total; my $pludiscount; foreach my $id (sort {$a <=> $b} keys %{ $paying->{data} }) { $total += $paying->{data}->{$id}->{qty} * $paying->{data}->{$id}->{price}; $pludiscount += $paying->{data}->{$id}->{qty} * $paying->{data}->{$id}->{discount}; print " "; } $paying->{thetotal} = $total; $paying->{pludiscount} = $pludiscount; #payment information $R::discount *=1; $R::discount = pr($total * $R::discount/100) if ($R::discounttype == 1); $R::discount = pr(($total - $pludiscount) * $paying->{customer}->{discountpercent} /100) if ($paying->{customer}->{discountpercent} > 0); $paying->{clientdiscount} = $R::discount if ($paying->{customer}->{discountpercent} > 0); $R::discount += $pludiscount; $R::discount = $total if ($R::discount > $total); $paying->{totaldiscount} = $R::discount; my $subdue = $total - $R::discount; my $scharge = 0; my $tenpercent = 0; #~ $scharge = (10 / 100) * $subdue if ($R::sfee); $R::sfee = pr($subdue * $R::sfee/100) if ($R::sfeetype == 1); $scharge = $R::sfee; $paying->{totalsfee} = $scharge; #openfood calculation $R::tenpercent = pr($subdue * 10/100) if ($R::tenpercent > 0); $tenpercent = $R::tenpercent; $paying->{tenpercent} = $tenpercent; my $due = $subdue + $scharge + $tenpercent; my $change = ($R::cash + $R::ccard + $R::account + $R::cheque) - $due; print qq~~; print ""; print ""; if ($settings::sfeeshow > 0) { print ""; } print qq~~; if ($settings::tenpercent > 0) { print ""; print qq~~; } print ""; print "
    $paying->{data}->{$id}->{qty} x $paying->{data}->{$id}->{name} ".(pr($paying->{data}->{$id}->{qty}*$paying->{data}->{$id}->{price}))."

    TOTAL ".pr($total)."
    DISCOUNT".pr($R::discount)."
    SERVICE FEE ".pr($scharge)."

    Sugg. Fee Incl. ".pr($tenpercent)."

    DUE ".pr($due)."
    "; my $flag = 1; #flag destroyers; if ($paying->{voided}) { print "
    VOIDED SPLIT!
    "; $flag = -1; } elsif ($paying->{invoice} and ! $paying->{nothing}) { print "
    PAID SPLIT
    "; $flag = -1; } elsif ($paying->{invoice} and $paying->{nothing}) { print "
    MIXED SPLIT
    "; $flag = -1; } #payment possible ? if ($flag>0) { print qq~ason>>document.getElementById('confirm').style.background = 'url(pay/confirm.png)'; allowed = 1;~; if ($R::discount > 0) { print qq~ discount = 1; ~; } if ($paying->{proforma} > 0 and $settings::sureprint > 0) { print qq~ proforma = 1; ~; } } else { print qq~ason>>document.getElementById('confirm').style.background = 'url(pay/confirmd.png)'; allowed = 0 ~; } my $itemtxt = substr(qq~Total Due ~, 0, 19); $itemtxt .= " "x(20 - length( pr($due) ) - length( $itemtxt ) ); $itemtxt .= pr($due); my $secondtxt = substr(qq~Change ~, 0, 19); $secondtxt .= " "x(20 - length( pr($change) ) - length( $secondtxt ) ); $secondtxt .= pr($change); $itemtxt .= $secondtxt if ($change >= 0); print qq~;pole('$itemtxt')~; writetmp($station_id,$paying, "paying"); #serialize data into text file; } elsif ($socketflag == 1 and $R::action eq "getcard" and $session->param("~set_logged_user")) { $results = $dbh->prepare(" select * from $sharedclients.tillclients where cardfootprint like '$R::cstr' or loyalnumber like '$R::cstr' or idnumber like '$R::cstr' ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{id}) { #if ($settings::compcustomer == 1) { print "popup_takeaway('&keytyped2=$ref->{code}');"; #} else { # print "selectcustomer_go($ref->{id})"; #} } else { print "GB_mess('Customer not found.');" } } elsif ($socketflag == 1 and $R::action eq "getpay" and $session->param("~set_logged_user")) { my $secondscreen; my $paying; #WiInteg # set cheque val to 0 my $zeroSettle; if($R::cheque == -1){ $R::cheque = 0; $zeroSettle = 1; } if ($R::condition eq 'init') { $paying = readtmp($station_id, "paying"); foreach my $key (keys %{$paying}) { delete $paying->{$key} unless ($key eq 'customer' or $key eq 'table'); } $results = $dbh->prepare(" select tods.*, inv.voided from tillorders tod, tillordersdetails tods LEFT JOIN tillinvoices inv ON inv.id = tods.invoice where tods.split = '$R::mysplit' and tod.confirm_status = 3 and tod.tableops_id = '$R::tabsid' and tods.orders_id = tod.id; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $paying->{data}->{$ref->{id}} = { name => $ref->{name}, price => $ref->{price}, discount => $ref->{discount}, qty => $ref->{qty} * 1, invoice => $ref->{invoice}, voided => $ref->{voided}, } if ($ref->{plu}); if ($ref->{plu}) { if($ref->{invoice} > 0) {$paying->{invoice} ++} if($ref->{voided} > 0) {$paying->{voided} ++} if(! $ref->{invoice} or $ref->{invoice} < 0) {$paying->{nothing} ++} } } my (%client_names,%client_charges, %client_types, %client_discounts); $results = $dbh->prepare("select * from $sharedclients.tillclients;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $client_names{$ref->{id}} = $ref->{name}; $client_charges{$ref->{id}} = $ref->{tacharge}; $client_types{$ref->{id}} = $ref->{type}; $client_discounts{$ref->{id}} = $ref->{discountpercent}; } my $tableops_id = $R::tabsid; $results = $dbh->prepare(" select * from tilltableops where id = $R::tabsid ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $current_client_id = $ref->{client_id}; my $table_id = $ref->{table_id}; my %tabledetails; $results = $dbh->prepare("select id,number,quick_mode,ordering from tilltables where shop_id='$shop{id}' and f_status<100;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $tabledetails{number}{$ref->{id}} = $ref->{number}; $tabledetails{ordering}{$ref->{id}} = $ref->{ordering}; } $paying->{customer}->{id} = $current_client_id; $paying->{customer}->{name} = $client_names{$current_client_id}; $paying->{customer}->{type} = $client_types{$current_client_id}; $paying->{customer}->{discountpercent} = $client_discounts{$current_client_id}; $paying->{table}->{tablenumber} = $tabledetails{number}{$table_id}; $paying->{table}->{tableops_id} = $tableops_id; if ($enable_loyalty && $paying->{customer}->{id}) { $subresults = $dbh->prepare(" select sum(mlp.points * tods.qty) qty, mlp.loyalty_id from tillordersdetails tods, menu_loyaltypoints mlp, loyalty_programs lp, tillclients, tillorders tod where tods.split = '$R::mysplit' and tod.confirm_status = 3 and tod.tableops_id = '$R::tabsid' and tods.orders_id = tod.id and mlp.plu_id = tods.plu and mlp.loyalty_id = lp.id and lp.active = 1 and tillclients.id = ? and ( tillclients.clientgroup like lp.gfilter or lp.gfilter = '' or lp.gfilter is null ) and ((lp.activeafter <= CURRENT_DATE or lp.activeafter = '') and (lp.activebefore >= CURRENT_DATE or lp.activebefore = '')) group by mlp.loyalty_id; ;") or die $dbh->errstr(); $subresults->execute($paying->{customer}->{id}) or die $subresults->errstr(); while ($subref = $subresults->fetchrow_hashref()) { $paying->{lpoints}->{$subref->{loyalty_id}} = $subref->{qty}; if ($R::ret) { $paying->{lpoints}->{$subref->{loyalty_id}} *= -1; } } } writetmp($station_id,$paying, "paying"); #serialize data into text file; } else { $paying = readtmp($station_id, "paying"); $results = $dbh->prepare(" select waitron_id from tilltableops where id = ? ;") or die $dbh->errstr(); $results->execute($paying->{table}->{tableops_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $error; if ($session->param("~set_user_id") != $ref->{waitron_id}) { $results = $dbh->prepare(" select * from waitron where id = ? ;") or die $dbh->errstr(); $results->execute($ref->{waitron_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $error = $ref->{name}; } if ($error) { print qq~ason>>GB_mess("TRANSFER: TABLE NOW BELONGS TO $error",1, "window.location='index.cgi?action=tables&error=transfer'");~; return; } } #~ print $datetime; print ""; my $total; my $pludiscount; foreach my $id (sort {$a <=> $b} keys %{ $paying->{data} }) { $total += $paying->{data}->{$id}->{qty} * $paying->{data}->{$id}->{price} * 1; $pludiscount += $paying->{data}->{$id}->{qty} * $paying->{data}->{$id}->{discount} * 1; print " "; } $total = sprintf("%.02f",$total); if ($settings::centround > 0) { my $round = centRound($total, $settings::centround); my $roundDiscount = sprintf ("%.2f", $total - $round); $pludiscount += $roundDiscount; } $paying->{thetotal} = $total; if ($R::customerid) { $paying->{customer}->{id} = $R::customerid; $results = $dbh->prepare("select * from $sharedclients.tillclients where id = ? ;") or die $dbh->errstr(); $results->execute($R::customerid) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $paying->{customer}->{name} = $ref->{name}; if ($profile->{nocustomerdiscount} != 1) { $paying->{customer}->{discountpercent} = $ref->{discountpercent}; } else { $paying->{customer}->{discountpercent} = 0; } } my $account_available; my $specified_account_amount; if ($paying->{customer}->{id} > 0) { $results = $dbh->prepare(" SELECT tillclients.*, bal.entity_debit, bal.entity_credit, bal.entity_credit - bal.entity_debit credit_balance, tillclients.creditlimit + IF(bal.entity_credit IS NULL OR bal.entity_debit IS NULL,0, bal.entity_credit - bal.entity_debit) available_credit FROM $sharedclients.tillclients tillclients left join account_balance_entity bal on bal.account = 1 and entityid = tillclients.id where tillclients.id = ?;") or die $dbh->errstr(); $results->execute($paying->{customer}->{id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $account_available = $ref->{available_credit}; if ($R::account > 0 and ($R::account > $account_available) and $ref->{creditlimit} != -1 and ! $R::ret) { $specified_account_amount = $R::account; $R::account = $account_available; } } if ($profile->{nocustomerdiscount} == 1) { $paying->{customer}->{discountpercent} = 0; } $paying->{pludiscount} = $pludiscount; #payment information $R::discount *=1; $R::discount = pr($total * $R::discount/100) if ($R::discounttype == 1); $R::discount = pr(($total - $pludiscount) * $paying->{customer}->{discountpercent} /100) if ($paying->{customer}->{discountpercent} > 0); $paying->{clientdiscount} = $R::discount if ($paying->{customer}->{discountpercent} > 0); $R::discount += $pludiscount; $R::discount = $total if ($R::discount > $total); $paying->{totaldiscount} = $R::discount; $R::discount = 0 if ( $R::discount < 0); my $subdue = $total - $R::discount; my $scharge = 0; my $tenpercent = 0; $R::sfee = pr($subdue * $R::sfee/100) if ($R::sfeetype == 1); $scharge = $R::sfee; #openfood calculation $R::tenpercent = pr($subdue * 10/100) if ($R::tenpercent > 0); $tenpercent = $R::tenpercent; $paying->{tenpercent} = $tenpercent; $paying->{totalsfee} = $scharge; my $due = $subdue + $scharge + $tenpercent; $secondscreen = "{ 'due' : '$due', "; my $filled_account; if ($account_available and $ref->{creditlimit} != -1 and $R::condition eq 'init' and ! $R::ret and $settings::autofillaccounts == 1) { if ($due <= $account_available) { $R::account = $due; $filled_account = $R::account; } else { $R::account = $account_available; $filled_account = $R::account; } } elsif ( $R::ret and $R::condition eq 'init' and $paying->{customer}->{id} and $settings::autofillaccounts == 1 and ! $profile->{noautofillaccount_refund} ) { $R::account = $due; $filled_account = $R::account; } #WiInteg # if there is wi discount if($R::wiDiscount){ # calculate dues using wi discount $due = $due - $R::wiDiscount; $paying->{totaldiscount} = $paying->{totaldiscount} + $R::wiDiscount; } my $change = ($R::cash + $R::ccard + $R::account + $R::cheque) - $due; $secondscreen .= "'change' : '$change',"; my $tpaid = $R::cash + $R::ccard + $R::account + $R::cheque; $tpaid *= 1; $secondscreen .= "'tpaid' : '$tpaid',"; print qq~~; print ""; print ""; #WiInteg if($R::wiDiscount){ # display wi discount on frontend print ""; } if ($settings::sfeeshow > 0) { print ""; } print qq~~; if ($settings::tenpercent > 0) { print ""; print qq~~; } my $clickdue = $due; $clickdue -= $R::cash + $R::ccard + $R::account + $R::cheque; #~ $clickdue = 0 if ($clickdue < 0); print ""; if ($R::cash) { print ""; } if ($R::pin > 0) { $results = $dbh->prepare(" select password from $sharedclients.tillclients where id = ? ") or die $dbh->errstr(); $results->execute($paying->{customer}->{id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($R::pin == $ref->{password}) { $paying->{thepin} = 1; } } if ($R::account != 0 && $settings::customerpins == 1) { if (! $paying->{thepin}) { print ""; } else { print ""; } } $paying->{cc} = $R::cc if ($R::cc); if ($R::ccard) { print ""; if (! $paying->{cc}) { print ""; } else { print ""; } } #WiInteg if ($R::cheque) { print ""; }elsif($zeroSettle){ print ""; } if ($paying->{customer}->{id}) { if ($R::account != 0) { print ""; print ""; } else { print ""; } } elsif ($R::account != 0) { print ""; } if ($paying->{customer}->{id}) { if ($R::account != 0) { my $newcredit; if ($R::ret != 1) { $newcredit = $account_available - $R::account; } else { $newcredit = $account_available + $R::account; } $secondscreen .= "'newbalance' : '$newcredit',"; print ""; } } $change = $change*1; my $prechange; if ($paying->{customer}->{id} > 0 and $change > 0) { my $deposittype = ''; if ($R::cash > 0) { $deposittype = 'Cash'; } elsif ($R::ccard > 0) { $deposittype = 'Card'; } elsif ($R::cheque > 0) { $deposittype = 'Cheque'; } $prechange = qq~
    Load Credit Paid $deposittype
    ~ if ($settings::depositchange == 1); print ""; } print ""; print "
    $paying->{data}->{$id}->{qty} x $paying->{data}->{$id}->{name} ".(pr($paying->{data}->{$id}->{qty}*$paying->{data}->{$id}->{price}))."

    *TOTAL ".pr($total)."
    DISCOUNT".pr($R::discount)."
    MOBILE Discount".pr($R::wiDiscount)."
    SERVICE FEE ".pr($scharge)."

    Sugg. Fee Incl. ".pr($tenpercent)."

    DUE ".pr($due)."
    CASH".pr($R::cash)."
    Enter Pin Code here
    Pin Code: VALID
    C.CARD $R::ccard
    Select Card Type here
    Card Type: $paying->{cc}
    MOBILE Payment".pr($R::cheque)."
    MOBILE Payment".pr($R::cheque)."
    ACCOUNT $R::account
    DEBTOR: $paying->{customer}->{name}
    Credit Available: ".pr($account_available)."
    CUSTOMER: $paying->{customer}->{name}
    Credit Available: ".pr($account_available)."
    Select debtor please.
    New Balance: $newcredit
    $prechange
    CHANGE ".pr($change)."
    "; #~ print "
    DEBUG:TOTAL:$total
    "; #~ print "
    DEBUG:CASH:$R::cash
    "; #~ my $ch = $total - $R::cash; #~ print "
    Debug Change: $ch
    "; my $flag = 1; if ($change < 0) { # split can be payd print "
    NO PAYMENT METHOD!
    "; $flag = -1 } #flag destroyers; if ($R::ccard and $R::cc eq '' and ! $paying->{cc}) { print "
    NO CARD TYPE!
    "; $flag = -1; } if ($R::account != 0 and ! $paying->{thepin} and $settings::customerpins == 1) { print "
    NO PIN CODE!
    "; $flag = -1; } if ($R::account > 0 and ! $paying->{customer}->{id}) { print "
    NO DEBTOR SELECTED!
    "; $flag = -1; } if ($paying->{voided}) { print "
    VOIDED SPLIT!
    "; $flag = -1; } elsif ($paying->{invoice} and ! $paying->{nothing}) { print "
    PAID SPLIT
    "; $flag = -1; } elsif ($paying->{invoice} and $paying->{nothing}) { print "
    MIXED SPLIT
    "; $flag = -1; } #~ $paying->{customer}->{id}; my $clientpointsingroup; my $grouping; if ($paying->{customer}->{id} && ! $R::ret) { #disable items with no stock on hand: $results = $dbh->prepare(" update loyalty_redeemplus set active = 2 where menu_id in ( select menu.id from menu where menu.stockonhand <= 0 ); ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); my $redeemable; my $redeemmessage; $results = $dbh->prepare(" select lp.id, lp.autoredeem, lrp.id lprid, lrp.qty, lrp.period, lp.currentbill, menu.stockonhand, menu.shortname, menu.id plu, lrp.maxclient_qty, lp.description, lrp.points_requested, substring_index(group_concat(tlp.running_points order by tlp.id desc), ',', 1) totalpoints from loyalty_redeemplus lrp, menu, loyalty_programs lp left join tillclients_loyalty_points tlp on lp.id = tlp.loyalty_program and tlp.customer_id = ? where menu.id = lrp.menu_id and lrp.loyalty_program = lp.id and lrp.active = 1 and lp.active = 1 and ((lp.activeafter <= CURRENT_DATE or lp.activeafter = '') and (lp.activebefore >= CURRENT_DATE or lp.activebefore = '')) group by lrp.id order by lp.id,lrp.points_requested; ") or die $dbh->errstr(); $results->execute($paying->{customer}->{id}) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $subresults = $dbh->prepare(" select max(id), substring_index(group_concat(running_points order by id desc), ',', 1) totalredeemed from tillclients_loyalty_redeemed where customer_id = ? and loyalty_program = ? group by loyalty_program, customer_id") or die $dbh->errstr(); $subresults->execute($paying->{customer}->{id}, $ref->{id}) or die $subresults->errstr(); #max(running_points) totalredeemed my $totalpoints = $ref->{totalpoints} + $paying->{lpoints}->{$ref->{id}}; my $subref = $subresults->fetchrow_hashref(); my $lbalance = $totalpoints - $subref->{totalredeemed}; #~ print "DEBUG: TP: $totalpoints RED: $subref->{totalredeemed} LB: $lbalance"; if ($lbalance > 0) { if ($lbalance >= $ref->{points_requested}) { my $qty; my $times = int( $lbalance / $ref->{points_requested} ); my $qty = $ref->{qty} * $times; if ($qty > $ref->{maxclient_qty}) { $qty = $ref->{maxclient_qty}; } #~ print "Debug: $qty (qty)"; if ($ref->{stockonhand} >= $qty) { if ($ref->{period} > 0) { $subresults = $dbh->prepare(" SELECT sum(qty) total FROM tillordersdetails tods,tillinvoices inv where inv.client_id = ? and tods.plu = ? and date(tods.stamp) > date_sub(current_date, interval '$ref->{period}' day) and inv.id = tods.invoice ;"); #and tods.redeem_lp_id = ? } else { $subresults = $dbh->prepare(" SELECT sum(qty) total FROM tillordersdetails tods,tillinvoices inv where inv.client_id = ? and tods.plu = ? and inv.id = tods.invoice ;"); } $subresults->execute($paying->{customer}->{id}, $ref->{plu}) or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); #~ print "DEb: $ref->{shortname} | $subref->{total} | $ref->{maxclient_qty}"; if ($subref->{total} < $ref->{maxclient_qty}) { $redeemable->{$ref->{id}}->{name} = $ref->{description}; $redeemable->{$ref->{id}}->{collectedpoints} = $lbalance; $redeemable->{$ref->{id}}->{currentbill} = $ref->{currentbill}; $redeemable->{$ref->{id}}->{autoredeem} = $ref->{autoredeem}; $redeemable->{$ref->{id}}->{redeemable} ++; $redeemmessage ++; push @{ $redeemable->{$ref->{id}}->{members} }, { 'id' => $ref->{lprid}, 't' => 1, 'qty' => $qty, 'name' => $ref->{shortname}, 'stockonhand' => $ref->{stockonhand}, 'rpoints' => $ref->{points_requested}, } } } #~ print "$lbalance * $ref->{points_requested}
    "; } else { $redeemable->{$ref->{id}}->{name} = $ref->{description}; $redeemable->{$ref->{id}}->{collectedpoints} = $lbalance; $redeemable->{$ref->{id}}->{currentbill} = $ref->{currentbill}; $redeemable->{$ref->{id}}->{autoredeem} = $ref->{autoredeem}; push @{ $redeemable->{$ref->{id}}->{members} }, { 'id' => $ref->{lprid}, 't' => 2, 'stockonhand' => $ref->{stockonhand}, 'name' => $ref->{shortname}, 'rpoints' => $ref->{points_requested}, 'balance' => $lbalance } #~ print "$lbalance | $ref->{points_requested}
    "; } }# if any balance #~ $repolacer->{loyaltypoints} = $ref->{}; } #for all l.programs #incoming selections #~ if ($R::redeemselect > 0) { #~ if ($paying->{redeemselect}->{$R::redeemselect} == 0) { #~ $paying->{redeemselect}->{$R::redeemselect} = 1; #~ } else { #~ $paying->{redeemselect}->{$R::redeemselect} = 0; #~ } #~ } $secondscreen .= "'redeemmessage':'$redeemmessage',"; $secondscreen .= "'loyalty' : ["; #display l.selection my $reportprint; foreach my $lp (sort {$redeemable->{$a}->{name} cmp $redeemable->{$b}->{name}} keys %{$redeemable} ) { if ($redeemable->{$lp}->{redeemable} > 0) { $reportprint .= "
    Loyalty: $redeemable->{$lp}->{name}
    "; $reportprint .= "You have $redeemable->{$lp}->{collectedpoints} points. Please select:
    "; } $secondscreen .= "{ 'redeemable':'$redeemable->{$lp}->{redeemable}','name' : '$redeemable->{$lp}->{name}', 'points' : '$redeemable->{$lp}->{collectedpoints}', "; $secondscreen .= "'itemz' : ["; my $thisbalance = $redeemable->{$lp}->{collectedpoints}; foreach my $item ( @{ $redeemable->{$lp}->{members} } ) { if ($item->{t} == 1) { $reportprint .= qq~
    {id}\" ~; if ($redeemable->{$lp}->{autoredeem} == 1) { $paying->{redeemselect}->{$item->{id}} = "$lp,$item->{qty},".($item->{qty} * $item->{rpoints}); } else { if ($R::redeemselect == $item->{id}) { if ($paying->{redeemselect}->{$item->{id}} =~ /\d/) { delete $paying->{redeemselect}->{$item->{id}}; } else { $paying->{redeemselect}->{$item->{id}} = "$lp,$item->{qty},".($item->{qty} * $item->{rpoints}); } } $reportprint .= qq~ onclick=\"redeemselect($item->{id})\" ~; } $reportprint .= qq~class=~; if ($paying->{redeemselect}->{$item->{id}} ) { $reportprint .= "selectedrecall"; $thisbalance -= $item->{qty} * $item->{rpoints}; } else { $reportprint .= "marine"; } $reportprint .= qq~>~; $reportprint .= "$item->{qty} x $item->{name} ("; $reportprint .= $item->{qty} * $item->{rpoints}; $reportprint .= " points)"; if ($redeemable->{$lp}->{redeemable} > 0) {$reportprint .= "
    ";} my $zp = $item->{qty} * $item->{rpoints}; my $nm = $item->{name}; $nm =~ s/\'//gsi; $secondscreen .= " {'t':'$item->{t}','soh':'$item->{stockonhand}','name':'$item->{name}', 'qty' : '$item->{qty}','rpoints':'$item->{rpoints}', 'points':'$zp', 'sel' : '$paying->{redeemselect}->{$item->{id}}'},"; } else { $secondscreen .= " {'t':'2', 'soh':'$item->{stockonhand}', 'balance':'$item->{balance}', 'name':'$item->{name}', 'rpoints':'$item->{rpoints}'},"; } } #~ foreach my $item ( @{ $notredeemable->{$lp}->{members} } ) { #~ $secondscreen .= " {'t':'2', 'soh':'$item->{stockonhand}', 'balance':'$item->{balance}', 'name':'$item->{name}', 'rpoints':'$item->{rpoints}'},"; #~ } $secondscreen .= "],"; if ($thisbalance >= 0) { if ($redeemable->{$lp}->{currentbill} != 1 || $redeemable->{$lp}->{autoredeem} != 1 ) { $reportprint .= "
    Remaining points".($redeemable->{$lp}->{currentbill} == 1 ? " for this bill" : "" ).": $thisbalance
    " if ($redeemable->{$lp}->{redeemable} > 0); } $secondscreen .= "'remaining' : '$thisbalance'},"; } else { $reportprint .= "
    SELECTION NOT ALLOWED!
    " if ($redeemable->{$lp}->{redeemable} > 0); $flag = -1; $secondscreen .= "'remaining' : 'E'},"; } } print $reportprint; $secondscreen .= "],"; #~ open DDD, ">/ddd_preselect"; #~ print DDD Dumper($paying); #~ close DDD; } #if customer $secondscreen .= "}"; #~ open DDD, ">/ddd_ddd"; #~ print DDD $secondscreen; #~ close DDD; print "ason>>"; if ($profile->{secondaryscreen} == 1) { print qq~ secondscreen = $secondscreen; try{window.top.rightframe.refr()} catch(e) {}; ~; } #payment possible ? if ($flag>0) { print qq~ document.getElementById('confirm').style.background = 'url(pay/confirm.png)'; document.getElementById('paycomplete').src = 'pay/paycomplete.png'; allowed = 1;~; if ($R::discount > 0) { print qq~ discount = 1; ~; } } else { print qq~ document.getElementById('confirm').style.background = 'url(pay/confirmd.png)'; document.getElementById('paycomplete').src = 'pay/paycomplete-dis.png'; allowed = 0; ~; } if ($specified_account_amount > $R::account) { print qq~; try{ document.getElementById('i_account').innerHTML = '$R::account'; document.getElementById('typepad').value = '$R::account'; typed('$R::account',1); } catch(e){}~; } elsif ($filled_account > 0 and $R::condition eq 'init') { print qq~ try{ document.getElementById('i_account').innerHTML = '$filled_account'; document.getElementById('typepad').value = '$filled_account'; filled_account = '$filled_account'; //pos('account'); } catch(e){} ~; } my $itemtxt = substr(qq~Total Due ~, 0, 19); $itemtxt .= " "x(20 - length( pr($due) ) - length( $itemtxt ) ); $itemtxt .= pr($due); my $secondtxt = substr(qq~Change ~, 0, 19); $secondtxt .= " "x(20 - length( pr($change) ) - length( $secondtxt ) ); $secondtxt .= pr($change); $itemtxt .= $secondtxt if ($change >= 0); print qq~;pole('$itemtxt');~; print qq~totaldue = '$due'~; writetmp($station_id,$paying, "paying"); #serialize data into text file; } elsif ($socketflag == 1 and $R::action eq "debtors" and $session->param("~set_logged_user")) { $results = $dbh->prepare("select * from $sharedclients.tillclients where active = 1 and clientgroup = '$R::clientgroup' and (type != 3 or type is null) order by name;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { print "{name}&customerid=$ref->{id}'); \">$ref->{name}"; } #~ print "ason>> "; #~ open(OO, ">/debug.txt"); #~ print OO $ref->{name}; #~ close OO; } elsif ($socketflag == 1 and $R::action eq "payp" and $session->param("~set_logged_user")) { my $paying = readtmp($station_id, "paying"); #~ open DDD, ">/dddddd"; #~ print DDD Dumper($paying); #~ close DDD; my ($result, $closestatus, $message,$invoice) = printinvoice( { printinstructions => $profile->{printinstructions}, enable_proplim => $enable_proplim, enable_loyalty => $enable_loyalty, screenmode => $screenmode, proforma => 1, till_id => $profile->{station_id}, tableops_id => $paying->{table}->{tableops_id}, servicecharge => $paying->{totalsfee}, tenpercent => $paying->{tenpercent}, split => $R::split, copies => 1, client => $paying->{customer}->{id}, client_name => $paying->{customer}->{name}, waitron_id => $session->param("~set_user_id"), current_opentable_nr => $paying->{table}->{tablenumber}, discount => $paying->{totaldiscount}, #$R::discount + $paying->{pludiscount} + $paying->{clientdiscount}, supervised_by => $R::supervised_by }, {dbh => $dbh}, $database, $shop{id}, $sharedclients ); logit(qq|$result, $closestatus, $message,$invoice|); if ($result > 0) { if ( $session->param("~setqmode") > 0 ) { print "window.location='index.cgi?action=plu&tid=$R::tid'"; } else { print "window.location='index.cgi?action=tables&pole=Thank you!'"; } ####2022-POS #my %opts; # $opts{invoice} = $invoice; # $opts{waitron_id} = $session->param("~set_user_id"); # $opts{station_id} = $profile->{station_id}; #posAccountPost(%opts,$dbh); } else { print " GB_mess('$message'); "; } } elsif ($socketflag == 1 and $R::action eq "witrans" and $session->param("~set_logged_user")) { #WiInteg =pre my $paying = readtmp($station_id, "paying"); my %wiParams; my @productList; my $totalPrice = 0; # setup wi parameters $wiParams{prodCount} = 0; $wiParams{wiCode} = $R::wicode; $wiParams{tillId} = $profile->{station_id}; $wiParams{waitronId} = $session->param("~set_user_id"); # query products tied to the transaction my $tabsId = $paying->{table}->{tableops_id}; $results = $dbh->prepare("SELECT tods.* FROM tillorders tod, tillordersdetails tods WHERE tod.f_status < 101 AND tod.confirm_status = 3 AND tod.tableops_id = '$tabsId' AND tods.split = $R::split AND tods.orders_id = tod.id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { # set till order id in wi parameters $wiParams{tillOrdersId} = $ref->{orders_id}; # add new products to the product list and update totalPrice if ($ref->{plu}) { if($ref->{plutype} == 1){ # query the required sku my $skuRes = $dbh->prepare("SELECT code FROM menu WHERE id = ?") or die $dbh->errstr(); $skuRes->execute($ref->{plu}) or die $results->errstr(); my $sku = $skuRes->fetchrow_hashref()->{code}; push @productList, {"id" => $sku, "pricePerUnit" => $ref->{price} * 100, "units" => int($ref->{qty})}; $wiParams{prodCount}++; $totalPrice = $totalPrice + (($ref->{price} - $ref->{discount}) * $ref->{qty}); } } } $wiParams{totalPrice} = $totalPrice*100; $wiParams{products} = \@productList; #determine transaction id my $countRes = $dbh->prepare("SELECT COUNT(orders_id) AS transCount FROM wi_transactions WHERE orders_id = ?") or die $dbh->errstr(); $countRes->execute($wiParams{tillOrdersId}) or die $results->errstr(); my $tCount = $countRes->fetchrow_hashref()->{transCount} + 1; $wiParams{transactionId} = "$wiParams{tillOrdersId}-$tCount"; #determine storeId from properties my $propRes = $dbh->prepare("SELECT value FROM properties WHERE name = ?") or die $dbh->errstr(); $propRes->execute('wiStoreId') or die $propRes->errstr(); $wiParams{wiStoreId} = $propRes->fetchrow_hashref()->{value}; # do wi transaction request and save response details to db my $wiResponse = wiTransaction(%wiParams); # if successfull if($wiResponse->{responseCode} == -1){ my $settled = $wiResponse->{amountToSettle}/100; my $discount = ($wiResponse->{totalAmountProcessed}-$wiResponse->{amountToSettle})/100; # set settled to -1 if it and discount is 0, needed to handle 0 value vouchers if($settled == 0 and $discount == 0){ $settled = -1; } $results = $dbh->prepare("INSERT INTO wi_transactions (orders_id, transaction_id, wi_transaction_id, response_code, response_description, wi_code, discount, settled) VALUES (?, ?, ?, ?, ?, ?, ?, ?)") or die $dbh->errstr(); $results->execute($wiParams{tillOrdersId}, $wiParams{transactionId}, $wiResponse->{wiTrxId}, $wiResponse->{responseCode}, $wiResponse->{responseDesc}, $wiParams{wiCode}, $discount, $settled) or die $results->errstr(); # save vsp transaction details to db $results = $dbh->prepare("INSERT INTO vsp_transactions (wi_transaction_id, vsp_id, message, vsp_name, response_code, response_description, vsp_transaction_id) VALUES (?, ?, ?, ?, ?, ?, ?)") or die $dbh->errstr(); $results->execute($wiResponse->{wiTrxId}, $wiResponse->{vsp}->{id}, $wiResponse->{vsp}->{message}, $wiResponse->{vsp}->{name}, $wiResponse->{vsp}->{responseCode}, $wiResponse->{vsp}->{responseDesc}, $wiResponse->{vsp}->{trxId}) or die $results->errstr(); # redirect with params required on the frontend print "window.location='index.cgi?action=payment&tid=$R::tid&wiResp=$wiResponse->{responseCode}&wiDiscount=$discount&wiTransId=$wiResponse->{wiTrxId}&wiDiscId=$wiResponse->{discount}->{product}->{id}&wiSettled=$settled'"; }else{ if($wiResponse->{wiTrxId}){ $results = $dbh->prepare("INSERT INTO wi_transactions (orders_id, wi_transaction_id, response_code, response_description, wi_code, discount) VALUES (?, ?, ?, ?, ?, ?)") or die $dbh->errstr(); $results->execute($wiParams{tillOrdersId}, $wiResponse->{wiTrxId}, $wiResponse->{responseCode}, $wiResponse->{responseDesc}, $wiParams{wiCode}, 0) or die $results->errstr(); if($wiResponse->{vsp}->{responseDesc}){ # save vsp transaction details to db $results = $dbh->prepare("INSERT INTO vsp_transactions (wi_transaction_id, vsp_id, message, vsp_name, response_code, response_description, vsp_transaction_id) VALUES (?, ?, ?, ?, ?, ?, ?)") or die $dbh->errstr(); $results->execute($wiResponse->{wiTrxId}, $wiResponse->{vsp}->{id}, $wiResponse->{vsp}->{message}, $wiResponse->{vsp}->{name}, $wiResponse->{vsp}->{responseCode}, $wiResponse->{vsp}->{responseDesc}, $wiResponse->{vsp}->{trxId}) or die $results->errstr(); #redirect with error code and message print "window.location='index.cgi?action=payment&tid=$R::tid&wiResp=$wiResponse->{vsp}->{responseCode}&wiMessage=$wiResponse->{vsp}->{responseDesc}'"; }else { #redirect with error code and message print "window.location='index.cgi?action=payment&tid=$R::tid&wiResp=$wiResponse->{responseCode}&wiMessage=$wiResponse->{responseDesc}'"; } }else{ $results = $dbh->prepare("INSERT INTO wi_transactions (orders_id, response_code, response_description, wi_code, discount) VALUES (?, ?, ?, ?, ?)") or die $dbh->errstr(); $results->execute($wiParams{tillOrdersId}, $wiResponse->{responseCode}, $wiResponse->{responseDesc}, $wiParams{wiCode}, 0) or die $results->errstr(); #redirect with error code and message print "window.location='index.cgi?action=payment&tid=$R::tid&wiResp=$wiResponse->{responseCode}&wiMessage=$wiResponse->{responseDesc}'"; } } =cut } elsif ($socketflag == 1 and $R::action eq "pay" and $session->param("~set_logged_user")) { my $paying; #WiInteg # set cheque val to 0 if($R::cheque == -1){ $R::cheque = 0; } #$R::mode eq 'quick' if ( 0 ) { my $history = readtmp($station_id); $results = $dbh->prepare(" select waitron_id from tilltableops where id = ?") or die $dbh->errstr(); $results->execute($history->{tableops_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $error; if ($session->param("~set_user_id") != $ref->{waitron_id}) { $results = $dbh->prepare(" select * from waitron where id = ? ;") or die $dbh->errstr(); $results->execute($ref->{waitron_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $error = $ref->{name}; } if ($error) { print qq~ason>>GB_mess("TRANSFER: TABLE NOW BELONGS TO $error",1, "window.location='index.cgi?action=tables&error=transfer'");~; return; } #~ print "
    ";
    									#~ print Dumper($history);
    									#~ print "
    "; my @confirmeditems; #the real thing my $tmprn; my %tmprns; my $till_id = $station_id; my $waitron_id = $session->param("~set_user_id"); my $table_nr = $history->{tablenr}; my $tableops_id = $history->{tableops_id}; my $current_covers = $history->{guests}; #don't print and save my $falseflag = 0; $results = $dbh->prepare("SELECT tto.action action, client_id from tilltableops tto, tilltables tt where tto.table_id=tt.id and tt.id = $R::tid order by tto.id desc limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $client_id = $ref->{client_id}; my $clientprint; if ($ref->{action} == 2) {$falseflag = 1} my $printstatus = 1; if (! $falseflag) { if ($client_id) { $results = $dbh->prepare("select * from $sharedclients.tillclients where id = '$client_id';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $clientprint = $ps{minuses}."\n"; $clientprint .= "CUSTOMER: $ref->{name}\n"; $clientprint .= "ADDRESS: [1] $ref->{ph_address} [2] $ref->{ph_address1} [3] $ref->{ph_address2} [4] $ref->{ph_address3} \n" if ($ref->{ph_address} ne ''); $clientprint .= "T: $ref->{telephone} " if ($ref->{telephone}); $clientprint .= "M: $ref->{cellphone}" if ($ref->{cellphone}); $clientprint .= "\n"; } my $lastorderid; #waitron $results = $dbh->prepare("SELECT * from waitron where id='$waitron_id';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $waitron = $ref->{name}; my $demomode; $demomode = 1 if ($waitron =~ /!DEMO!/sgi); foreach my $orderid (sort {$a <=> $b} keys %{$history->{order}}) { if (! $history->{order}->{$orderid}->{mysqlid} and (scalar @{ $history->{order}->{$orderid}->{kids} } > 0) ) { # insert the new orders my $confirm_status = $history->{order}->{$orderid}->{stage}; # $orders->att('confirm'); my $results = $dbh->prepare("INSERT into tillorders (stamp,shop_id,till_id,waitron_id,tableops_id,confirm_status) values (CURRENT_TIMESTAMP,$shop{id}, '$till_id', '$waitron_id', '$tableops_id', '$confirm_status');") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results->finish(); #imediately $results = $dbh->prepare("SELECT LAST_INSERT_ID() lastid FROM tillorders limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $orders_id = $ref->{lastid}; $history->{order}->{$orderid}->{mysqlid} = $orders_id; #~ print " Order ID: $orders_id
    "; $lastorderid = $orders_id; # time to create the new order details #print "\n DEBUG: NEW ORDER $lastorderid"; foreach my $kidref ( @{ $history->{order}->{$orderid}->{kids} } ) { # foreach my $plus ($orders->children('plu')) { my ($plutype, $local_name, $menusource, $plu_id, $price, $discount, $printer, $thename, $theqty, $thesplit); $menusource = 1; my $myplutype; if ($kidref->{plu}) { $myplutype = 1; }else{ $myplutype = 2; } $plutype = $myplutype; $printer = $kidref->{print_destination}; $thename = $kidref->{name}; $thesplit = $kidref->{split}; $theqty = $kidref->{qty}; if ($plutype == 2) { # instruction } else { # plu $plu_id = $kidref->{plu}; $price = $kidref->{price}; $discount = $kidref->{discount}; } $results = $dbh->prepare("INSERT into tillordersdetails (stamp, shop_id, orders_id, plu, price, discount, qty, menusource, waitron_id, plutype, name, print_destination,till_id, split, bin_id) values ( CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? );") or die $dbh->errstr(); $results->execute( $shop{id}, $orders_id, $plu_id, $price, $discount, $theqty, $menusource, $waitron_id, $plutype, $thename, $printer, $till_id, $thesplit, $bin_id ) or die $results->errstr(); $results->finish(); } } else { #an old order - just update the status - and print if it is not printed my $confirm_status = $history->{order}->{$orderid}->{stage}; my $server_id = $history->{order}->{$orderid}->{mysqlid}; if ($confirm_status and $server_id) { $results = $dbh->prepare("UPDATE tillorders set f_status=1,confirm_status=$confirm_status where id=$server_id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); } } #if server id }# foreach order - orders in db !!! ##### ORDER PRINTER # TODO # PRINT SPLIT FOR DIFFERENT DESTINATIONS my %pluordering; my %printers; #printers my %redirectedprinters; my $dc; my ($subref,$subresults); $results = $dbh->prepare("SELECT * from tillorders where tableops_id = '$tableops_id' and f_status<101 and confirm_status=2;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $subresults = $dbh->prepare("SELECT * FROM tillordersdetails where orders_id='$ref->{id}';"); $subresults->execute() or die $subresults->errstr(); while ($subref = $subresults->fetchrow_hashref()) { #apply order redirection rules here if ($altord{$till_id}{$subref->{print_destination}} ne "") { $redirectedprinters{ $altord{$till_id}{$subref->{print_destination}} } = $subref->{print_destination}; $subref->{print_destination} = $altord{$till_id}{$subref->{print_destination}}; } if ($subref->{plutype} == 2) { push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{red} $subref->{name}" ); } else { #push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{black}__________________" ); push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{black} ".($subref->{qty}*1)." x $subref->{name}" ); if ($subref->{qty} >= 1) { for (1..$subref->{qty}) { push @confirmeditems, $subref->{plu}; } } } } # MARK AS PRINTED # separator for orders will come from the cycle below } use Data::Dumper; #print Dumper(%printers); #DEBUG __________________________________________ $tmprn = ""; %tmprns = (); my $slipinit; my $lastopsid; my $lastcdate; $results = $dbh->prepare(" select substring_index(group_concat(tod.tableops_id order by dcash.date desc), ',', 1) concat_lastops_id, substring_index(group_concat(dcash.date order by dcash.date desc), ',', 1) concat_lastdate, tod.id AS till_ord_id , tods.invoice AS till_invoice_id from dcash, tillordersdetails tods, tillorders tod where dcash.last_tillid = tods.id and tod.id = tods.orders_id and dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 15 day) group by dcash.id order by dcash.date desc limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastopsid = $ref->{concat_lastops_id} || 0; $lastcdate = $ref->{concat_lastdate} || "2000-01-01"; my $till_ord_id = $ref->{till_ord_id}; my $till_invoice_id = $ref->{till_invoice_id}; my $unique = $tableops_id - $lastopsid; { my $tmprn; $tmprn .= chr(27)."@"; $tmprn .= $ps{dw}.$ps{dh}.$ps{b}."$settings::pickhead\n"; my $tm = localtime(time); my $datetime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$tm->mday,($tm->mon+1),($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); $tmprn .= chr(27)."@"; #init printer $tmprn .= "DATE & TIME: $datetime"; my $emptyline = " "x$pmax; #~ currenttime(); $emptyline = &align($emptyline, "User: $waitron" ,1,0); #current_covers $tmprn .= $ps{b}; $tmprn .= "\n".$ps{minuses}."\n"; $tmprn .= $emptyline."\n"; #slip invoice 2022 $tmprn .= "\n\nINVOICE: ".$ps{bsize}.$ps{bold}.$till_invoice_id. $ps{bold_off}.$ps{bsize_esc}."\n"; #if ($screenmode != 2) { #$tmprn .= "TABLE: $table_nr | G: $current_covers \n\nORDER: ".$ps{bsize}.$ps{bold}.$unique . $ps{bold_off}.$ps{bsize_esc}."\n"; # #} else { #$tmprn .= "CASHPOINT: $table_nr \n\nORDER: ".$ps{bsize}.$ps{bold}.$unique. $ps{bold_off}.$ps{bsize_esc}."\n"; #} ## 2022-04-21 ## In restaurant mode to enlarge the Table Number and screenmode=0 ## in retail mode to enlarge the order number on soredr slip screenmode=2 ###if ($screenmode != 2) { ###$tmprn .= "TABLE: ".$ps{bsize}.$ps{bold}.$table_nr . $ps{bold_off}.$ps{bsize_esc} ."| G: $current_covers \n\nORDER: ".$unique ."\n"; ### ###} else { ###$tmprn .= "CASHPOINT: $table_nr \n\nORDER: ".$ps{bsize}.$ps{bold}.$unique. $ps{bold_off}.$ps{bsize_esc}."\n"; ###} ## 2022-08-19 restored if ($screenmode != 2) { $tmprn .= "TABLE: $table_nr | G: $current_covers \n\nORDER: ".$ps{bsize}.$ps{bold}.$unique . $ps{bold_off}.$ps{bsize_esc}."\n"; } else { $tmprn .= "CASHPOINT: $table_nr \n\nORDER: ".$ps{bsize}.$ps{bold}.$unique. $ps{bold_off}.$ps{bsize_esc}."\n"; } $tmprn .= $clientprint ; $tmprn .= $ps{minuses}."\n"; #~ if ($client_name) { #~ $tmprn .= "CLIENT: $client_name"."\n" ; #~ $tmprn .= $ps{minuses}."\n"; #~ } $tmprn .= $ps{dh}; $slipinit = $tmprn; } my %ques; foreach my $printer (keys %printers) { foreach my $myorder (sort {$a <=> $b} keys %{ $printers{$printer} } ) { foreach my $lpdprn (@{$psubst{$printer}}) { foreach my $plu (@{ $printers{$printer}{$myorder} }) { push @{$ques{$lpdprn}{$myorder}}, $plu; } } } } #~ open (OOO, ">/dddd"); #~ print OOO Dumper(\%ques); #~ close OOO; foreach my $lpd (keys %ques) { #slip header $tmprns{$lpd} = $slipinit; #slip content my @allorders; foreach my $order (sort {$a <=> $b} keys %{$ques{$lpd}}) { my $items; foreach my $plu (@{$ques{$lpd}{$order}}) { $items .= $plu."\n"; } push @allorders, $items; } $tmprns{$lpd} .= join ("*********************************"."\n", @allorders ); #slip footer if ($prntype{$lpd} == 1) { # epson ? cut paper $tmprns{$lpd} .= $orderfeed; $tmprns{$lpd} .= $ps{cp}; $tmprns{$lpd} .= "\f"; } else { $tmprns{$lpd} .= $ps{feed}; } } # sent to printerz foreach my $lpdprnt (keys %tmprns) { my $printresult = Printit::printit ("127.0.0.1","127.0.0.1","$lpdprnt",$tmprns{$lpdprnt}); $printstatus = -1 if ($printresult != 0); } if ($printstatus == 1) { $results = $dbh->prepare("UPDATE tillorders set f_status=1,confirm_status=3 where tableops_id = $tableops_id and f_status<101 and confirm_status=2 ;"); $results->execute() or die $results->errstr(); } else { $results = $dbh->prepare("UPDATE tillorders set f_status=1,confirm_status=1 where tableops_id = $tableops_id and f_status<101 and confirm_status=2 ;"); $results->execute() or die $results->errstr(); } ##### ORDER PRINTER } else { # table closed already $printstatus = -2; } writetmp($station_id,$history); #serialize data into text file; }####dummy codes end NEVER NEVER check if(0) block ..... #---------------------------- if ( $R::mode eq 'quick' ) { #$R::mode eq 'quick' $paying = readtmp($station_id, "paying"); foreach my $key (keys %{$paying}) { delete $paying->{$key} unless ($key eq 'customer' or $key eq 'table' or $key eq 'pludiscount'); } $R::tabsid = $paying->{table}->{tableops_id}; $results = $dbh->prepare(" select tods.*, inv.voided from tillorders tod, tillordersdetails tods LEFT JOIN tillinvoices inv ON inv.id = tods.invoice where tods.split = '1' and tod.confirm_status = 3 and tod.tableops_id = '$R::tabsid' and tods.orders_id = tod.id; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { if ($ref->{plu}) { $paying->{data}->{$ref->{id}} = { name => $ref->{name}, price => $ref->{price}, discount => $ref->{discount}, qty => $ref->{qty} * 1, invoice => $ref->{invoice}, voided => $ref->{voided} }; $paying->{pludiscount} += $ref->{discount} * $ref->{qty}; if($ref->{invoice} > 0) {$paying->{invoice} ++} if($ref->{voided} > 0) {$paying->{voided} ++} if(! $ref->{invoice} or $ref->{invoice} < 0) {$paying->{nothing} ++} } }#end while my (%client_names,%client_charges, %client_types, %client_discounts); $results = $dbh->prepare("select * from $sharedclients.tillclients;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $client_names{$ref->{id}} = $ref->{name}; $client_charges{$ref->{id}} = $ref->{tacharge}; $client_types{$ref->{id}} = $ref->{type}; $client_discounts{$ref->{id}} = $ref->{discountpercent}; } my $tableops_id = $R::tabsid; $results = $dbh->prepare("select * from tilltableops where id = $R::tabsid;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $current_client_id = $ref->{client_id}; my $table_id = $ref->{table_id}; my %tabledetails; $results = $dbh->prepare("select id,number,quick_mode,ordering from tilltables where shop_id='$shop{id}' and f_status<100;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $tabledetails{number}{$ref->{id}} = $ref->{number}; $tabledetails{ordering}{$ref->{id}} = $ref->{ordering}; } $paying->{customer}->{id} = $current_client_id; $paying->{customer}->{name} = $client_names{$current_client_id}; $paying->{customer}->{type} = $client_types{$current_client_id}; $paying->{customer}->{discountpercent} = $client_discounts{$current_client_id}; $paying->{table}->{tablenumber} = $tabledetails{number}{$table_id}; $paying->{table}->{tableops_id} = $tableops_id; $paying->{cc} = $R::ccardtype if ($R::ccardtype); $paying->{totaldiscount} = $paying->{pludiscount}; #writetmp($station_id,$paying, "paying"); #serialize data into text file; } else { $paying = readtmp($station_id, "paying"); } #$paying->{pludiscount} #reset print mode #$profile->{printmode} = 1 if $R::pos_print_mode ==1; my ($result, $closestatus, $message, $returnpaid) = printinvoice( { printinstructions => $profile->{printinstructions}, enable_proplim => $enable_proplim, enable_loyalty => $enable_loyalty, screenmode => $screenmode, till_id => $profile->{station_id}, tableops_id => $paying->{table}->{tableops_id}, servicecharge => $paying->{totalsfee}, tenpercent => $paying->{tenpercent}, split => $R::split, client => $paying->{customer}->{id}, client_name => $paying->{customer}->{name}, waitron_id => $session->param("~set_user_id"), copies => $R::copies, current_opentable_nr => $paying->{table}->{tablenumber}, cash => $R::cash, ccard => $R::ccard, ccard_type => $paying->{cc}, cheque => $R::cheque, account => $R::account, discount => $paying->{totaldiscount}, #$R::discount + $paying->{customerdiscount} + $paying->{pludiscount}, #$R::discount + $paying->{pludiscount} + $paying->{clientdiscount}, loyalty => $R::loyalty, supervised_by => $R::supervised_by, prof => $R::prof, ret => $R::ret, deptype => $R::deptype, depamount => $R::depamount, printmode => $R::pos_print_mode, }, {dbh => $dbh}, $database, $shop{id}, $sharedclients ); #logit(qq|OPTS:$result, $closestatus, $message, $returnpaid|); if ($result > 0) { ##2022 hotelierapi3 my %opts; $opts{invoice} = $returnpaid; $opts{shop_id} = $shop{id}; $opts{waitron_id}= $session->param("~set_user_id"); $opts{dbh} = $dbh; my $retid = posAccountPost( %opts) if $paying->{customer}->{id} ==9999 ; logit("OPTS:\$retid=$retid -->" . Dumper(%opts) ); #my $ret_ok = NightBridge::postPayments({ # dbh => $dbh, # invoice => $returnpaid, # nightsbridge_username => $nightsbridge_username, # nightsbridge_password => $nightsbridge_password, # nightsbridge_bbid => $nightsbridge_bbid, # nightsbridge_bbid_pass=> $nightsbridge_bbid_pass, # nightsbridge_accountId=> $nightsbridge_accountId, # nightsbridge_roomId => $nightsbridge_roomId, #}); $dbh->do("INSERT INTO nightbridge_invoice SET invoice=?,client=?,created=NOW()",undef, $returnpaid,$paying->{customer}->{id}) if $paying->{customer}->{id}; #WiInteg if($R::wiTransId){ # update supervisorlog for the wi discount $results = $dbh->prepare("INSERT INTO supervisorlog (supervisor, reason, stamp, supervisingwhat, transaction_case, transaction_id, terminal_id, user, tillinvoices_id) VALUES (?, ?, current_timestamp, ?, ?, ?, ?, ?, ?);") or die $dbh->errstr(); $results->execute(0 , "Mobile Discount: $R::wiTransId", "DISCOUNT", "DISCOUNT DOC# $returnpaid", $paying->{table}->{tableops_id}, $profile->{station_id}, $session->param("~set_user_id"), $returnpaid) or die $results->errstr(); } #deal with deposits if ($R::reason ne '' and $R::reason ne "undefined" and $R::supervised_by > 0) { my ($scase,$scase_details); if ($R::whichcase eq 'discount') { $scase = 'DISCOUNT', $scase_details = "DISCOUNT DOC# $returnpaid"; } else { $scase = 'CASH REFUND', $scase_details = "CASH REFUND DOC# $returnpaid"; } $results = $dbh->prepare(" insert into supervisorlog (supervisor, reason, stamp, supervisingwhat, transaction_case, transaction_id, terminal_id, user, tillinvoices_id) values (?, ?, current_timestamp, ?, ?, ?, ?, ?, ?) ") or die $dbh->errstr(); $results->execute( $R::supervised_by, $R::reason, $scase, $scase_details, $paying->{table}->{tableops_id}, $profile->{station_id}, $session->param("~set_user_id"), $returnpaid ) or die $results->errstr(); } if ($closestatus > 0) { #deal with order printing #if ($settings::orderspayment == 1) { if ($orderspayment == 1) { my $tableops_id = $paying->{table}->{tableops_id}; my $till_id = $profile->{station_id}; my $tmprn; my %tmprns; my $clientprint; my $client_id = $paying->{customer}->{id}; my $waitron = $session->param("~set_user_name"); my $table_nr = $paying->{table}->{tablenumber}; $results = $dbh->prepare("SELECT sum(current_covers)/count(id) visitors from tillorders where current_covers>0 and tableops_id='$tableops_id' and f_status<101;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $guests = $ref->{visitors}*1; my $current_covers = $guests; if ($client_id) { $results = $dbh->prepare("select * from $sharedclients.tillclients where id = '$client_id';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $clientprint = $ps{minuses}."\n"; $clientprint .= "CUSTOMER: $ref->{name}\n"; $clientprint .= "ADDRESS: [1] $ref->{ph_address} [2] $ref->{ph_address1} [3] $ref->{ph_address2} [4] $ref->{ph_address3} \n" if ($ref->{ph_address} ne ''); $clientprint .= "T: $ref->{telephone} " if ($ref->{telephone}); $clientprint .= "M: $ref->{cellphone}" if ($ref->{cellphone}); $clientprint .= "\n"; } ##### ORDER PRINTER # TODO # PRINT SPLIT FOR DIFFERENT DESTINATIONS my %pluordering; my %printers; #printers my %redirectedprinters; my @confirmeditems; my $dc; my ($subref,$subresults); $results = $dbh->prepare("SELECT * from tillorders where tableops_id = '$tableops_id' and f_status<101 and confirm_status=3;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $subresults = $dbh->prepare("SELECT * FROM tillordersdetails where orders_id='$ref->{id}';"); $subresults->execute() or die $subresults->errstr(); while ($subref = $subresults->fetchrow_hashref()) { #apply order redirection rules here if ($altord{$till_id}{$subref->{print_destination}} ne "") { $redirectedprinters{ $altord{$till_id}{$subref->{print_destination}} } = $subref->{print_destination}; $subref->{print_destination} = $altord{$till_id}{$subref->{print_destination}}; } if ($subref->{plutype} == 2) { push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{red} $subref->{name}" ); } else { #push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{black}__________________" ); push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{black} ".($subref->{qty}*1)." x $subref->{name}" ); if ($subref->{qty} >= 1) { for (1..$subref->{qty}) { push @confirmeditems, $subref->{plu}; } } } } # MARK AS PRINTED # separator for orders will come from the cycle below } #print Dumper(%printers); #DEBUG __________________________________________ $tmprn = ""; %tmprns = (); my $slipinit; my $lastopsid; my $lastcdate; $results = $dbh->prepare(" select substring_index(group_concat(tod.tableops_id order by dcash.date desc), ',', 1) concat_lastops_id, substring_index(group_concat(dcash.date order by dcash.date desc), ',', 1) concat_lastdate, tod.id AS till_ord_id , tods.invoice AS till_invoice_id from dcash, tillordersdetails tods, tillorders tod where dcash.last_tillid = tods.id and tod.id = tods.orders_id and dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 15 day) group by dcash.id order by dcash.date desc limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastopsid = $ref->{concat_lastops_id} || 0; $lastcdate = $ref->{concat_lastdate} || "2000-01-01"; my $till_ord_id = $ref->{till_ord_id}; #2022 my $till_invoice_id = $ref->{till_invoice_id}; my $unique = $tableops_id - $lastopsid; { my $tmprn; $tmprn .= chr(27)."@"; $tmprn .= $ps{dw}.$ps{dh}.$ps{b}."$settings::pickhead\n"; my $tm = localtime(time); my $datetime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$tm->mday,($tm->mon+1),($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); $tmprn .= chr(27)."@"; #init printer $tmprn .= "DATE & TIME: $datetime" ; my $emptyline = " "x$pmax; #~ currenttime(); $emptyline = &align($emptyline,"User: $waitron" ,1,0); #current_covers $tmprn .= $ps{b}; $tmprn .= "\n".$ps{minuses}."\n"; $tmprn .= $emptyline."\n"; #slip invoice 2022 .$ps{bsize}.$ps{bold}. -- $ps{bold_off}.$ps{bsize_esc}. $tmprn .= "\n\nINVOICE: ".$till_invoice_id."\n"; if ($screenmode != 2) { $tmprn .= "TABLE: ".$ps{bsize}.$ps{bold}.$table_nr .$ps{bold_off}.$ps{bsize_esc}."| G: $current_covers \n\nORDER: ".$unique ."\n"; } else { $tmprn .= "CASHPOINT: $table_nr \n\nORDER: ".$ps{bsize}.$ps{bold}.$unique . $ps{bold_off}.$ps{bsize_esc}."\n"; } $tmprn .= $clientprint ; $tmprn .= $ps{minuses}."\n"; #~ if ($client_name) { #~ $tmprn .= "CLIENT: $client_name"."\n" ; #~ $tmprn .= $ps{minuses}."\n"; #~ } $tmprn .= $ps{dh}; $slipinit = $tmprn; } my %ques; foreach my $printer (keys %printers) { foreach my $myorder (sort {$a <=> $b} keys %{ $printers{$printer} } ) { foreach my $lpdprn (@{$psubst{$printer}}) { foreach my $plu (@{ $printers{$printer}{$myorder} }) { push @{$ques{$lpdprn}{$myorder}}, $plu; } } } } foreach my $lpd (keys %ques) { #slip header $tmprns{$lpd} = $slipinit; #slip content my @allorders; foreach my $order (sort {$a <=> $b} keys %{$ques{$lpd}}) { my $items; foreach my $plu (@{$ques{$lpd}{$order}}) { $items .= $plu."\n"; } push @allorders, $items; } $tmprns{$lpd} .= join ("*********************************"."\n", @allorders ); #slip footer if ($prntype{$lpd} == 1) { # epson ? cut paper $tmprns{$lpd} .= $orderfeed; $tmprns{$lpd} .= $ps{cp}; $tmprns{$lpd} .= "\f"; } else { $tmprns{$lpd} .= $ps{feed}; } } # sent to printerz foreach my $lpdprnt (keys %tmprns) { my $printresult = Printit::printit ("127.0.0.1","127.0.0.1","$lpdprnt",$tmprns{$lpdprnt}) unless $R::pos_print_mode; } ##### ORDER PRINTER } my ($flag, $message) = close_table( { qm => $session->param("~setqmode"), waitron_id => $session->param("~set_user_id"), table_id => $R::tid, till_id => $station_id }, {dbh => $dbh}, $shop{id} ); print "window.location='index.cgi?action=plu&tid=$R::tid&pole=Thank you!&returnpaid=$returnpaid&tt=2&pos_print_mode=".$R::pos_print_mode."'"; #print "window.location='index.cgi?action=tables&pole=Thank you!'"; } else { if ( $session->param("~setqmode") > 0 ) { print "window.location='index.cgi?action=plu&tid=$R::tid&returnpaid=$returnpaid&tt=1&pos_print_mode=".$R::pos_print_mode."'"; } else { print "window.location='index.cgi?action=tables&pole=Thank you!&returnpaid=$returnpaid&pos_print_mode=".$R::pos_print_mode."'"; } } } else { print " GB_mess('$message'); "; } } elsif ($socketflag == 1 and $R::action eq "ason_performance" and $session->param("~set_logged_user")) { print qq~ cnt++; document.getElementById('test').innerHTML += '
    cnt = ' + cnt; if (cnt < 60) { ason('index.cgi', 'action=ason_performance'); }~; } elsif ($socketflag == 1 and $R::action eq "ason_lookuptacharge" and $session->param("~set_logged_user")) { $results = $dbh->prepare(" select tacharge from $sharedclients.tillclients where mapcode = '$R::mapcode' and tacharge > 0 ;"); $results->execute( ) or die $results->errstr(); $ref = $results->fetchrow_hashref(); print "document.getElementById('tacharge').value='$ref->{tacharge}';"; } elsif ($socketflag == 1 and $R::action eq "printloyalty" and $session->param("~set_logged_user")) { my $report; my $client_id = $R::customer_id; $results = $dbh->prepare(" select * from $sharedclients.tillclients where id = ? ;"); $results->execute( $client_id ) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $report .= chr(27)."@"; $report .= $ps{dh}.$ps{b}; $report .= "-"x$pmax."\n"; $report .= "Loyalty Points Summary\n"; $report .= "CUSTOMER: $ref->{name}\n"; $report .= chr(27)."@"; $report .= "*"x$pmax."\n"; #loyalty points $results = $dbh->prepare(" select lp.id, lp.autoredeem, lrp.id lprid, lrp.qty, lp.currentbill, menu.stockonhand, menu.shortname, lrp.maxclient_qty, lp.description, lrp.points_requested, max(tlp.running_points) totalpoints from loyalty_redeemplus lrp, menu, loyalty_programs lp left join tillclients_loyalty_points tlp on lp.id = tlp.loyalty_program and tlp.customer_id = ? where menu.id = lrp.menu_id and lrp.loyalty_program = lp.id and lrp.active = 1 and lp.active = 1 and ((lp.activeafter <= CURRENT_DATE or lp.activeafter = '') and (lp.activebefore >= CURRENT_DATE or lp.activebefore = '')) group by lrp.id order by lp.id,lrp.points_requested; ") or die $dbh->errstr(); $results->execute($client_id) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $subresults = $dbh->prepare(" select max(running_points) totalredeemed from tillclients_loyalty_redeemed where customer_id = ? and loyalty_program = ?") or die $dbh->errstr(); $subresults->execute($client_id, $ref->{id}) or die $subresults->errstr(); my $subref = $subresults->fetchrow_hashref(); my $lbalance = $ref->{totalpoints} - $subref->{totalredeemed}; if ($lbalance > 0) { if ($lbalance >= $ref->{points_requested}) { $report .= "-"x$pmax."\n"; $report .= "LOYALTY PROGRAM: $ref->{description}\n"; $report .= "You can redeem $ref->{shortname}\n"; } else { my $pointstogo = $ref->{points_requested} - $lbalance; $report .= "-"x$pmax."\n"; $report .= "LOYALTY PROGRAM: $ref->{description}\n"; $report .= "$lbalance of $ref->{points_requested} points collected.\n"; $report .= "You need ".($pointstogo)." more point".($pointstogo > 1 ? 's' : '').".\n"; } } #~ $repolacer->{loyaltypoints} = $ref->{}; } my $tillprinter = "T".$profile->{station_id}; my $result = 0; foreach my $lpdprn (@{$psubst{$tillprinter}}) { my $printresult = Printit::printit ("127.0.0.1","127.0.0.1","$lpdprn",$report); $result = -1 if ($printresult != 0); } if ($result == 0) { print "GB_hide();GB_mess('Report successfuly printed.')"; } else { print "GB_hide();GB_mess('Error occured while printing to printer.')"; } } elsif ($socketflag == 1 and $R::action eq "popupqty" and $session->param("~set_logged_user")) { my $file = "$tdir/keypadn-qty.htm"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $unit_weight = 1; my $orgprice; if($R::clicked_mplu > 0){ my $res = $dbh->selectrow_arrayref("SELECT plu_weight,orgprice FROM menu WHERE id=? LIMIT 1",undef,$R::clicked_mplu); $unit_weight = $res->[0] || 1; $orgprice = $res->[1]||0; } my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $vars->{qtypriceoption} = $settings::qtypriceoption; $vars->{case} = $R::case; $vars->{clicked_mplu} = $R::clicked_mplu; $vars->{PluUnitWeight} = $unit_weight; $vars->{orgprice} = $orgprice; #print STDERR "PLU Origprice:$unit_weight,$orgprice\n"; #$vars->{weight_qty} = &getWeightQty($dbh,$unit_weight,$orgprice); my $temphtml = $template->process($file, $vars, \$output)|| die "Template process failed: ", $template->error(), "\n"; print $output; } #elsif($socketflag ==1 && $R::action eq 'load_weight' && $session->param("~set_logged_user")) { # ## deprated # #print "Content-type:text/html\n\n"; # my $unit_weight = 1; # my $orgprice ; # if($R::clicked_mplu > 0){ # my $res = $dbh->selectrow_arrayref("SELECT plu_weight,orgprice FROM menu WHERE id=? LIMIT 1",undef,$R::clicked_mplu); # $unit_weight = $res->[0] || 1; # $orgprice = $res->[1]; # } # print &getWeightQty($dbh,$unit_weight,$orgprice);return; # # } elsif ($socketflag == 1 and $R::action eq "popuployalty" and $session->param("~set_logged_user")) { my $file = "$tdir/loyalty.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile}; my $report; my $client_id = $R::customer_id; #loyalty points $results = $dbh->prepare(" select lp.id, lp.autoredeem, lrp.id lprid, lrp.qty, lp.currentbill, menu.stockonhand, menu.shortname, lrp.maxclient_qty, lp.description, lrp.points_requested, max(tlp.running_points) totalpoints from loyalty_redeemplus lrp, menu, loyalty_programs lp left join tillclients_loyalty_points tlp on lp.id = tlp.loyalty_program and tlp.customer_id = ? where menu.id = lrp.menu_id and lrp.loyalty_program = lp.id and lrp.active = 1 and lp.active = 1 and ((lp.activeafter <= CURRENT_DATE or lp.activeafter = '') and (lp.activebefore >= CURRENT_DATE or lp.activebefore = '')) group by lrp.id order by lp.id,lrp.points_requested; ") or die $dbh->errstr(); $results->execute($client_id) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $subresults = $dbh->prepare(" select max(running_points) totalredeemed from tillclients_loyalty_redeemed where customer_id = ? and loyalty_program = ?") or die $dbh->errstr(); $subresults->execute($client_id, $ref->{id}) or die $subresults->errstr(); my $subref = $subresults->fetchrow_hashref(); my $lbalance = $ref->{totalpoints} - $subref->{totalredeemed}; if ($lbalance > 0) { if ($lbalance >= $ref->{points_requested}) { $report .= "-"x$pmax."\n"; $report .= "LOYALTY PROGRAM: $ref->{description}\n"; $report .= "You can redeem $ref->{shortname}\n"; } else { my $pointstogo = $ref->{points_requested} - $lbalance; $report .= "-"x$pmax."\n"; $report .= "LOYALTY PROGRAM: $ref->{description}\n"; $report .= "$lbalance of $ref->{points_requested} points collected.\n"; $report .= "You need ".($pointstogo)." more point".($pointstogo > 1 ? 's' : '').".\n"; } } #~ $repolacer->{loyaltypoints} = $ref->{}; } my $data; $vars->{title} = "Customer Loyalty Points"; $report =~ s/\n/
    /gsi; $vars->{content} = "
    ";
    											$vars->{content} .= $report;
    											$vars->{content} .= "
    "; $vars->{content} .= "
    "; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "popuphistory_onhold" and $session->param("~set_logged_user")) { my $file = "$tdir/history.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; $vars->{onholdmode} = 1; my $data; if ($R::customer_id > 0) { # $results = $dbh->prepare(" select w.name waitron, cl.name client, inv.id invoice, date_format(tod.stamp,'%d/%m/%y, %W') date, datediff(current_date,date(tod.stamp)) days, tods.id, tods.name, sum(tods.qty) qty, tods.price, sum(tods.price*tods.qty) total from tillorders tod, tillordersdetails tods, waitron w, tillonholds inv left join tillclients cl on cl.id = inv.client_id where inv.user_id = w.id and tods.orders_id = tod.id and tod.tableops_id = inv.tableops_id and tods.plu > 0 and inv.client_id = ? group by tods.plu,inv.id,tods.price order by tod.stamp desc; "); $results->execute($R::customer_id) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $data->{$ref->{invoice}}->{waitron} = $ref->{waitron}; $data->{$ref->{invoice}}->{client} = $ref->{client}; $data->{$ref->{invoice}}->{date} = $ref->{date}; $data->{$ref->{invoice}}->{days} = $ref->{days}; $data->{$ref->{invoice}}->{voided} = $ref->{voided} > 0 ? 'Void' : ''; $data->{$ref->{invoice}}->{void_reason} = $ref->{void_reason}; $data->{$ref->{invoice}}->{isrefund} = $ref->{isrefund} > 0 ? 'Refund' : ''; push @{$data->{$ref->{invoice}}->{lines}}, { name => $ref->{name}, price => $ref->{price}, qty => $ref->{qty} * 1, total => $ref->{total}, id => $ref->{id} } } $vars->{title} = "Customer On-Hold History"; } else { my $thisuser = $session->param("~set_user_id"); $results = $dbh->prepare(" select w.name waitron, cl.name client, inv.id invoice, date_format(tod.stamp,'%d/%m/%y, %W') date, datediff(current_date,date(tod.stamp)) days, tods.id, tods.name, sum(tods.qty) qty, tods.price, sum(tods.price*tods.qty) total from tillorders tod, tillordersdetails tods, waitron w, tillonholds inv left join tillclients cl on cl.id = inv.client_id where inv.user_id = w.id and tods.orders_id = tod.id and tod.tableops_id = inv.tableops_id and tods.plu > 0 and inv.user_id = ? group by tods.plu,inv.id,tods.price order by tod.stamp desc; "); $results->execute($thisuser) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $data->{$ref->{invoice}}->{waitron} = $ref->{waitron}; $data->{$ref->{invoice}}->{client} = $ref->{client} || 'NO CLIENT SELECTED'; $data->{$ref->{invoice}}->{date} = $ref->{date}; $data->{$ref->{invoice}}->{days} = $ref->{days}; $data->{$ref->{invoice}}->{voided} = $ref->{voided} > 0 ? 'Void' : ''; $data->{$ref->{invoice}}->{void_reason} = $ref->{void_reason}; $data->{$ref->{invoice}}->{isrefund} = $ref->{isrefund} > 0 ? 'Refund' : ''; push @{$data->{$ref->{invoice}}->{lines}}, { name => $ref->{name}, price => $ref->{price}, qty => $ref->{qty} * 1, total => $ref->{total}, id => $ref->{id} } } $vars->{title} = "My On-Hold History"; } my $report; my $emptyline; foreach my $invoice (sort {$a <=> $b} keys %{$data}) { my $ref = $data->{$invoice}; $report .= "=================================\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"ON-HOLD NR. $invoice",1,0); $emptyline = &align($emptyline," $ref->{client}",3,0); $report .= ""; $report .= $emptyline; $report .= "\n"; $report .= ""; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$ref->{date}",1,0); $emptyline = &align($emptyline,"$ref->{days} days old $ref->{isrefund} $ref->{voided}",3,0); $report .= $emptyline; $report .= "\n"; $report .= "---------------------------------\n"; my $total_invoice; foreach my $line (@{$ref->{lines}}) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$line->{qty} x $line->{name}",1,0); $emptyline = &align($emptyline,"$currency ".pr($line->{total}),3,0); #~ $report .= "\n{id}')\">"; $report .= $emptyline; #~ $report .= ""; $report .= "\n"; $total_invoice += $line->{total}; } $report .= "\n---------------------------------\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"Total",1,0); $emptyline = &align($emptyline,"$currency ".pr($total_invoice),3,0); $report .= $emptyline; $report .= "\n=================================\n"; $report .= "\n\n"; } $report =~ s/\n/
    /gsi; $vars->{content} = "
    ";
    											$vars->{content} .= $report;
    											$vars->{content} .= "
    "; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "popuphistory" and $session->param("~set_logged_user")) { my $file = "$tdir/history.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my $data; if ($R::customer_id > 0 && $R::document !~ /\d/) { # if ($R::period ne 'today') { my $limit = $R::days || 7; $results = $dbh->prepare(" select id from tillinvoices where client_id = $R::customer_id order by id desc limit $limit;"); $results->execute() or die $results->errstr(); my $startinvoice = 0; while($ref = $results->fetchrow_hashref()) { $startinvoice = $ref->{id}; } $results = $dbh->prepare(" select w.name waitron, cl.name client, inv.id invoice, inv.void_reason, date_format(inv.stamp,'%d/%m/%y, %W') date, datediff(current_date,date(inv.stamp)) days, inv.voided, inv.isrefund, inv.cash, inv.discount, inv.account, inv.ccard, tods.name, tods.id, sum(tods.qty) qty, tods.price, sum(tods.price*tods.qty) total from tillordersdetails tods, waitron w, tillinvoices inv left join tillclients cl on cl.id = inv.client_id where inv.waitron_id = w.id and inv.id = tods.invoice and tods.plu > 0 and inv.id >= ? and inv.client_id = $R::customer_id group by tods.plu,tods.invoice,tods.price order by inv.stamp desc; "); $results->execute($startinvoice) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $data->{$ref->{invoice}}->{waitron} = $ref->{waitron}; $data->{$ref->{invoice}}->{client} = $ref->{client} || 'N/A'; $data->{$ref->{invoice}}->{date} = $ref->{date}; $data->{$ref->{invoice}}->{tendered} = $ref->{cash}; $data->{$ref->{invoice}}->{days} = $ref->{days}; $data->{$ref->{invoice}}->{voided} = $ref->{voided} > 0 ? 'Void' : ''; $data->{$ref->{invoice}}->{void_reason} = $ref->{void_reason}; $data->{$ref->{invoice}}->{isrefund} = $ref->{isrefund} > 0 ? 'Refund' : ''; push @{$data->{$ref->{invoice}}->{lines}}, { name => $ref->{name}, price => $ref->{price}, qty => $ref->{qty} * 1, total => $ref->{total}, id => $ref->{id} } } $vars->{title} = "Customer Invoice History - $limit DAYS"; } else { $results = $dbh->prepare(" select max(last_tillid) id from dcash"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $startid = $ref->{id}; #order ids $results = $dbh->prepare(" select distinct tod.tableops_id from tillorders tod, tillordersdetails tods where tods.orders_id = tod.id and tods.id >= ? order by tableops_id asc limit 1; "); $results->execute($startid) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $lasttabid = $ref->{tableops_id}; $results = $dbh->prepare(" select w.name waitron, cl.name client, inv.id invoice, inv.void_reason, date_format(inv.stamp,'%d/%m/%y, %W') date, datediff(current_date,date(inv.stamp)) days, inv.voided, inv.isrefund, inv.cash, inv.discount, inv.account, inv.ccard, tod.tableops_id, tods.name, tods.id, sum(tods.qty) qty, tods.price, sum(tods.price*tods.qty) total from tillordersdetails tods, waitron w, tillorders tod, tillinvoices inv left join tillclients cl on cl.id = inv.client_id where tod.id = tods.orders_id and inv.waitron_id = w.id and inv.id = tods.invoice and tods.plu > 0 and tods.id > ? and inv.client_id = $R::customer_id group by tods.plu,tods.invoice,tods.price order by inv.stamp desc; "); $results->execute($startid) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $data->{$ref->{invoice}}->{waitron} = $ref->{waitron}; $data->{$ref->{invoice}}->{client} = $ref->{client} || 'N/A'; $data->{$ref->{invoice}}->{date} = $ref->{date}; $data->{$ref->{invoice}}->{days} = $ref->{days}; $data->{$ref->{invoice}}->{tendered} = $ref->{cash}; $data->{$ref->{invoice}}->{orderid} = $ref->{tableops_id} - $lasttabid; $data->{$ref->{invoice}}->{voided} = $ref->{voided} > 0 ? 'Void' : ''; $data->{$ref->{invoice}}->{void_reason} = $ref->{void_reason}; $data->{$ref->{invoice}}->{isrefund} = $ref->{isrefund} > 0 ? 'Refund' : ''; push @{$data->{$ref->{invoice}}->{lines}}, { name => $ref->{name}, price => $ref->{price}, qty => $ref->{qty} * 1, total => $ref->{total}, id => $ref->{id} } } $vars->{title} = "Customer Invoice History - TODAY ONLY"; } } elsif ($R::document > 0) { if ($R::customer_id > 0) { $results = $dbh->prepare(" select w.name waitron, cl.name client, inv.id invoice, inv.void_reason, date_format(inv.stamp,'%d/%m/%y, %W') date, datediff(current_date,date(inv.stamp)) days, inv.voided, inv.isrefund, tods.id, inv.cash, inv.discount, inv.account, inv.ccard, tods.name, sum(tods.qty) qty, tods.price, sum(tods.price*tods.qty) total from tillordersdetails tods, waitron w, tillinvoices inv left join tillclients cl on cl.id = inv.client_id where inv.waitron_id = w.id and inv.id = tods.invoice and tods.plu > 0 and inv.id = ? and inv.client_id = ? group by tods.plu,tods.invoice,tods.price order by inv.stamp desc; "); $results->execute($R::document, $R::customer_id) or die $results->errstr(); } else { $results = $dbh->prepare(" select w.name waitron, cl.name client, inv.id invoice, inv.void_reason, date_format(inv.stamp,'%d/%m/%y, %W') date, datediff(current_date,date(inv.stamp)) days, inv.voided, inv.isrefund, tods.id, inv.cash, inv.discount, inv.account, inv.ccard, tods.name, sum(tods.qty) qty, tods.price, sum(tods.price*tods.qty) total from tillordersdetails tods, waitron w, tillinvoices inv left join tillclients cl on cl.id = inv.client_id where inv.waitron_id = w.id and inv.id = tods.invoice and tods.plu > 0 and inv.id = ? group by tods.plu,tods.invoice,tods.price order by inv.stamp desc; "); $results->execute($R::document) or die $results->errstr(); } while ($ref = $results->fetchrow_hashref()) { $data->{$ref->{invoice}}->{waitron} = $ref->{waitron}; $data->{$ref->{invoice}}->{client} = $ref->{client} || 'N/A'; $data->{$ref->{invoice}}->{date} = $ref->{date}; $data->{$ref->{invoice}}->{days} = $ref->{days}; $data->{$ref->{invoice}}->{tendered} = $ref->{cash}; $data->{$ref->{invoice}}->{voided} = $ref->{voided} > 0 ? 'Void' : ''; $data->{$ref->{invoice}}->{void_reason} = $ref->{void_reason}; $data->{$ref->{invoice}}->{isrefund} = $ref->{isrefund} > 0 ? 'Refund' : ''; push @{$data->{$ref->{invoice}}->{lines}}, { name => $ref->{name}, price => $ref->{price}, qty => $ref->{qty} * 1, total => $ref->{total}, id => $ref->{id} } } $vars->{title} = "DOCUMENT NUMBER: $R::document"; } else { my $thisuser = $session->param("~set_user_id"); if ($R::period ne 'today') { my $limit = $R::days || 7; $results = $dbh->prepare(" select id from tillinvoices where waitron_id = $thisuser order by id desc limit $limit;"); $results->execute() or die $results->errstr(); my $startinvoice = 0; while($ref = $results->fetchrow_hashref()) { $startinvoice = $ref->{id}; } $results = $dbh->prepare(" select w.name waitron, cl.name client, inv.id invoice, inv.void_reason, date_format(inv.stamp,'%d/%m/%y, %W') date, datediff(current_date,date(inv.stamp)) days, inv.voided, inv.isrefund, tods.id, inv.cash, inv.discount, inv.account, inv.ccard, tods.name, sum(tods.qty) qty, tods.price, sum(tods.price*tods.qty) total from tillordersdetails tods, waitron w, tillinvoices inv left join tillclients cl on cl.id = inv.client_id where inv.waitron_id = w.id and inv.id = tods.invoice and tods.plu > 0 and inv.id >= ? and inv.waitron_id = $thisuser group by tods.plu,tods.invoice,tods.price order by inv.stamp desc; "); $results->execute($startinvoice) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $data->{$ref->{invoice}}->{waitron} = $ref->{waitron}; $data->{$ref->{invoice}}->{client} = $ref->{client} || 'N/A'; $data->{$ref->{invoice}}->{date} = $ref->{date}; $data->{$ref->{invoice}}->{days} = $ref->{days}; $data->{$ref->{invoice}}->{tendered} = $ref->{cash}; $data->{$ref->{invoice}}->{voided} = $ref->{voided} > 0 ? 'Void' : ''; $data->{$ref->{invoice}}->{void_reason} = $ref->{void_reason}; $data->{$ref->{invoice}}->{isrefund} = $ref->{isrefund} > 0 ? 'Refund' : ''; push @{$data->{$ref->{invoice}}->{lines}}, { name => $ref->{name}, price => $ref->{price}, qty => $ref->{qty} * 1, total => $ref->{total}, id => $ref->{id} } } $vars->{title} = "My Invoice History - $limit DAYS"; } else { $results = $dbh->prepare(" select max(last_tillid) id from dcash "); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $startid = $ref->{id}; #order ids $results = $dbh->prepare(" select distinct tod.tableops_id from tillorders tod, tillordersdetails tods where tods.orders_id = tod.id and tods.id >= ? order by tableops_id asc limit 1; "); $results->execute($startid) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $lasttabid = $ref->{tableops_id}; $results = $dbh->prepare(" select w.name waitron, cl.name client, inv.id invoice, inv.void_reason, date_format(inv.stamp,'%d/%m/%y, %W') date, datediff(current_date,date(inv.stamp)) days, inv.voided, tod.tableops_id, inv.isrefund, tods.id, inv.cash, inv.discount, inv.account, inv.ccard, tods.name, sum(tods.qty) qty, tods.price, sum(tods.price*tods.qty) total from tillorders tod, tillordersdetails tods, waitron w, tillinvoices inv left join tillclients cl on cl.id = inv.client_id where tod.id = tods.orders_id and inv.waitron_id = w.id and inv.id = tods.invoice and tods.plu > 0 and tods.id > ? and inv.waitron_id = $thisuser group by tods.plu,tods.invoice,tods.price order by inv.stamp desc; "); $results->execute($startid) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $data->{$ref->{invoice}}->{waitron} = $ref->{waitron}; $data->{$ref->{invoice}}->{client} = $ref->{client} || 'N/A'; $data->{$ref->{invoice}}->{date} = $ref->{date}; $data->{$ref->{invoice}}->{days} = $ref->{days}; $data->{$ref->{invoice}}->{tendered} = $ref->{cash}; $data->{$ref->{invoice}}->{orderid} = $ref->{tableops_id} - $lasttabid; $data->{$ref->{invoice}}->{voided} = $ref->{voided} > 0 ? 'Void' : ''; $data->{$ref->{invoice}}->{void_reason} = $ref->{void_reason}; $data->{$ref->{invoice}}->{isrefund} = $ref->{isrefund} > 0 ? 'Refund' : ''; push @{$data->{$ref->{invoice}}->{lines}}, { name => $ref->{name}, price => $ref->{price}, qty => $ref->{qty} * 1, total => $ref->{total}, id => $ref->{id} } } $vars->{title} = "My Invoice History - TODAY ONLY"; } } my $report; my $emptyline; foreach my $invoice (sort {$a <=> $b} keys %{$data}) { my $ref = $data->{$invoice}; if ( $data->{$invoice}->{isrefund} || $data->{$invoice}->{voided}) { $report .= ""; } $report .= "=================================\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"DOC NR. $invoice",1,0); $emptyline = &align($emptyline," USER: $ref->{waitron}",3,0); if ( $data->{$invoice}->{isrefund} || $data->{$invoice}->{voided}) { $report .= $emptyline; $report .= "\n"; } else { $report .= ""; $report .= $emptyline; $report .= "\n"; $report .= ""; } $report .= "=================================\n"; if ($R::period eq 'today') { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"DOCUMENT ORDER #",1,0); $emptyline = &align($emptyline,"$ref->{orderid}",3,0); $report .= "$emptyline\n"; $report .= "---------------------------------\n"; } $emptyline = " "x$pmax; $emptyline = &align($emptyline,"Customer",1,0); $emptyline = &align($emptyline,"$ref->{client}",3,0); $report .= $emptyline; $report .= "\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$ref->{date}",1,0); $emptyline = &align($emptyline,"$ref->{days} days old $ref->{isrefund} $ref->{voided}",3,0); $report .= $emptyline; $report .= "\n"; $report .= "---------------------------------\n"; my $total_invoice; foreach my $line (@{$ref->{lines}}) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$line->{qty} x $line->{name}",1,0); $emptyline = &align($emptyline,"$currency ".pr($line->{total}),3,0); if ( $data->{$invoice}->{isrefund} || $data->{$invoice}->{voided}) { $report .= $emptyline; } else { $report .= "\n{id}')\">"; $report .= $emptyline; $report .= ""; } $report .= "\n"; $total_invoice += $line->{total}; } $report .= "\n---------------------------------\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"Total",1,0); $emptyline = &align($emptyline,"$currency ".pr($total_invoice),3,0); if ($ref->{tendered}) { $report .= $emptyline; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"Tendered Cash",1,0); $emptyline = &align($emptyline,"$currency ".pr($ref->{tendered}),3,0); $emptyline = "\n$emptyline"; } $report .= $emptyline; $report .= "\n=================================\n"; $report .= "\n\n"; if ( $data->{$invoice}->{isrefund} || $data->{$invoice}->{voided}) { $report .= ""; } } $report =~ s/\n/
    /gsi; $vars->{content} = "
    ";
    											$vars->{content} .= $report;
    											$vars->{content} .= "
    "; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "popuptakeaway" and $session->param("~set_logged_user")) { my $file = "$tdir/tapopup.html"; $file = "$tdir/tapopup_nights.html" if $nightsbridge_username && $nightsbridge_password; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); if($session->param("~userpayment")){ $profile->{disablepayment} = $session->param("~userpayment") if $session->param("~userpayment") ==2; } my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $vars->{allowcashrefund} = $profile->{allowcashrefund}; $vars->{disablereturns} = $profile->{disablereturns}; #userpayment need to consider waitron setting $vars->{disablepayment} = $profile->{disablepayment}; $vars->{usr_disablepayment} = $session->param("~userpayment"); #$vars->{usr_disablepayment} = $session->param("~userpayment"); #terminal settings has high priority 2020-12-03 $vars->{customerpins} = $settings::customerpins; $vars->{customerwristbands} = $settings::customerwristbands; $vars->{allowaddcustomer} = $profile->{allowaddcustomer}; if($nightsbridge_username && $nightsbridge_password){ my $hash_ref = $dbh->selectrow_hashref("SELECT * FROM nightbridge_guests LIMIT 1"); $vars->{nightbridge_clients} = $hash_ref->{clients}; } my $temphtml = $template->process($file, $vars, \$output)|| die "Template process failed: ", $template->error(), "\n"; print $output; my $focus = 'card'; print qq~ ason>>document.getElementById('i_$focus').focus(); document.getElementById('i_$focus').style.background='pink'; ~; if ($R::keytyped1) { print qq~ document.getElementById('i_any').value='$R::keytyped1'; client_thepos='any'; mytyped('$R::keytyped1'); document.getElementById('i_digi').style.background='transparent'; document.getElementById('i_digi').value=''; document.getElementById('i_acc').style.background='transparent'; document.getElementById('i_acc').value=''; document.getElementById('i_card').style.background='transparent'; document.getElementById('i_card').value=''; document.getElementById('i_any').style.background='pink'; document.getElementById('i_any').focus(); ~; } elsif ($R::keytyped2) { print qq~ document.getElementById('i_acc').value='$R::keytyped2'; client_thepos='acc'; mytyped('$R::keytyped2'); document.getElementById('i_digi').style.background='transparent'; document.getElementById('i_digi').value=''; document.getElementById('i_any').style.background='transparent'; document.getElementById('i_any').value=''; document.getElementById('i_card').style.background='transparent'; document.getElementById('i_card').value=''; document.getElementById('i_acc').style.background='pink'; document.getElementById('i_acc').focus(); ~; } } elsif ($socketflag == 1 and $R::action eq "supervisor" and $session->param("~set_logged_superuser")) { my $file = "$tdir/superscreen.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; my $temphtml = $template->process($file, $vars, \$output)|| die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_undopay_undopay" and $session->param("~set_logged_superuser")) { my $chk=$R::i; $results = $dbh->prepare(" select tillinvoices.tableops_id, tilltableops.table_id from tillinvoices, tilltableops where tilltableops.id = tillinvoices.tableops_id and tillinvoices.id='$chk' ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $openingid = $ref->{tableops_id} * 1; my $table_id = $ref->{table_id} * 1; $results = $dbh->prepare(" select id from tilltableops where id > '$openingid' and table_id = '$table_id' and action = 2 limit 1; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $closingid = $ref->{id}*1; if ($closingid) { $results = $dbh->prepare(" delete from tilltableops where id = $closingid; ; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); } $results = $dbh->prepare(" delete from tillinvoices where id = '$R::i' ; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results = $dbh->prepare(" update tillordersdetails set invoice = null where invoice = '$R::i' ; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); print qq~ mes = document.getElementById('message'); mes.innerHTML="Undo completed. Invoice #$R::i is now payable."; mes.className='messn'; try { document.getElementById('inv_$R::i').parentNode.removeChild(document.getElementById('inv_$R::i')); } catch (e) { } ~; } elsif ($socketflag == 1 and $R::action eq "super_undo_undo" and $session->param("~set_logged_superuser")) { my $chk=$R::i; $results = $dbh->prepare("update tillinvoices set voided=NULL,supervised_by=NULL,void_reason=NULL where id='$chk'") or die $dbh->errstr(); $results->execute() or die $results->errstr(); print qq~mes = document.getElementById('message'); mes.innerHTML="Un-Void completed. Invoice #$R::i is now payable."; mes.className='messn'; try { document.getElementById('inv_$R::i').parentNode.removeChild(document.getElementById('inv_$R::i')); } catch (e) { } ~; } elsif ($socketflag == 1 and $R::action eq "super_etotdoor_etotdoor" and $session->param("~set_logged_superuser")) { my $status = 1; my $reason=$R::r; my $supervisor_id=$session->param("~set_superuser_id"); my $door=$R::i; $results = $dbh->prepare(" select * from etot where menu_id = -20 and slotnr = $door;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $code = $ref->{etot_string}; if ($code) { $results = $dbh->prepare(" insert into etotdoorlog (doornr, reason, stamp, supervisor_id) values ($door, ?, CURRENT_TIMESTAMP,$supervisor_id) ;") or die $dbh->errstr(); $results->execute($reason) or die $results->errstr(); print qq~ mes = document.getElementById('message'); mes.innerHTML="Door $R::i is opened."; mes.className='messn'; document.getElementById('i_inv').innerHTML = ''; document.getElementById('i_rsn').innerHTML = ''; sw('inv'); try { etot('$code'); } catch (e) { } ~; } else { print qq~ mes = document.getElementById('message'); mes.innerHTML="Door opening failed. No string provided."; mes.className='messe'; ~; } } elsif ($socketflag == 1 and $R::action eq "super_void_void" and $session->param("~set_logged_superuser")) { my $status = 1; my $reason = $R::r; my $supervisor_id = $session->param("~set_superuser_id"); my $voidtype = $R::t; my $chk = $R::i; my $wid; my $todsid; my $dclid; my $client_id; $results = $dbh->prepare("select waitron_id wid,client_id from tillinvoices where id='$chk' and voided is null") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $wid = $ref->{wid}; $client_id = $ref->{client_id}; if ($wid) { $results = $dbh->prepare("select max(id) theid from tillordersdetails where invoice = '$chk'") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $todsid = $ref->{theid}; $results = $dbh->prepare("select last_tillid dclid from dcashitems where f_status<100 and waitron_id = '$wid' order by id desc limit 1") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $dclid = $ref->{dclid}; } if ($wid and ($todsid > $dclid)) { $results = $dbh->prepare("UPDATE tillinvoices set stamp=CURRENT_TIMESTAMP, f_status=1, voided = $voidtype, void_reason = ?, supervised_by = $supervisor_id where id = $chk;") or die $dbh->errstr(); $results->execute($reason) or die $results->errstr(); #$results = $dbh->prepare("select tableops_id from tillinvoices where id='$chk';") or die $dbh->errstr(); #$results->execute() or die $results->errstr(); #$ref=$results->fetchrow_hashref(); #$tableops_id= #deal with record for this transaction in limits. $status=1; } else { $status=0; } if ($status == 1) { #broadcast the voids on order printers broadcast_void($chk, $station_id, {dbh => $dbh},$screenmode); my $comment = $R::comment; my %comments =(1=>'Undo',2=>'Void',3=>'Return'); print qq~ mes = document.getElementById('message'); mes.innerHTML="$comments{$comment} completed. Invoice #$R::i is $comments{$comment}."; mes.className='messn'; document.getElementById('i_inv').innerHTML = ''; document.getElementById('i_rsn').innerHTML = ''; sw('inv'); try { document.getElementById('inv_$R::i').parentNode.removeChild(document.getElementById('inv_$R::i')); } catch (e) { } ~; } else { print qq~ mes = document.getElementById('message'); mes.innerHTML="Voiding failed"; mes.className='messe'; ~; } } elsif ($socketflag == 1 and $R::action eq "super_etotdoor" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_etotdoor.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; $vars->{type} = $R::type; my %lastids; $results = $dbh->prepare(" select * from etot where menu_id = -20;;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @{$vars->{tablerows}} , $ref; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_void" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_void.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $vars->{type} = $R::type; $vars->{comment} = $R::comment; my %lastids; $results = $dbh->prepare("select id waitron from waitron where id not in (select distinct waitron_id from dcashitems); ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $lastids{$ref->{waitron}} = 0; } $results = $dbh->prepare(" select waitron.id waitron, if(substring_index(group_concat(dcashitems.last_tillid order by dcashitems.id desc), ',', 1) is NULL,0,substring_index(group_concat(dcashitems.last_tillid order by dcashitems.id desc), ',', 1)) lastid from dcash,waitron LEFT JOIN dcashitems ON dcashitems.waitron_id=waitron.id and dcashitems.f_status<100 where #dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 20 day) dcash.id = dcashitems.dcash_id and waitron.f_status < 100 and waitron.active = 1 and waitron.id in (select distinct waitron_id from tillinvoices) group by waitron.id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $lastids{$ref->{waitron}} = $ref->{lastid} } foreach my $waitron (keys %lastids) { $results = $dbh->prepare(" select inv.stamp stamp,waitron.name name, tilltables.number tablenr,inv.id inv from tillinvoices inv, tillordersdetails tods,waitron,tilltables,tilltableops where tods.f_status < 100 and inv.f_status<100 and tilltableops.f_status<100 and inv.voided is null #or inv.voided = 0 and tilltableops.id=inv.tableops_id and tilltables.id=tilltableops.table_id and waitron.id = $waitron and inv.waitron_id = waitron.id and tods.invoice=inv.id and tods.stamp > DATE_SUB(CURRENT_DATE, INTERVAL 2 day) and tods.id > $lastids{$waitron} group by inv order by waitron.name,inv.stamp; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { #~ $oxml .= "{stamp}\" name=\"$ref->{name}\" tablenr=\"$ref->{tablenr}\" inv=\"$ref->{inv}\" />"; push @{$vars->{tablerows}} , $ref; } } my $temphtml = $template->process($file, $vars, \$output)|| die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_return" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_return.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_undopay" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_undopay.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my %lastids; $results = $dbh->prepare(" select waitron.id waitron, if(substring_index(group_concat(last_tillid order by dcashitems.id desc), ',', 1) is NULL,0,substring_index(group_concat(last_tillid order by dcashitems.id desc), ',', 1)) lastid from waitron LEFT JOIN dcashitems ON dcashitems.waitron_id=waitron.id and dcashitems.f_status<100 where waitron.f_status < 100 and waitron.id in (select distinct waitron_id from tillinvoices) group by waitron.id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $lastids{$ref->{waitron}} = $ref->{lastid} } my %allowedtabops; $results = $dbh->prepare(" select table_id id, waitron_id, substring_index(group_concat(id order by id desc), ',', 1) tabopsid from tilltableops where action = 1 group by table_id; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $allowedtabops{$ref->{id}}->{waitron} = $ref->{waitron_id}; $allowedtabops{$ref->{id}}->{tabopsid} = $ref->{tabopsid}*1; } foreach my $tableid (keys %allowedtabops) { my $waitron = $allowedtabops{$tableid}->{waitron}; $results = $dbh->prepare(" select inv.voided voided, inv.stamp stamp,waitron.name name, tilltables.number tablenr,inv.id inv from tillinvoices inv, tillordersdetails tods,waitron,tilltables, tilltableops where tods.f_status < 100 and inv.f_status<100 and tilltableops.f_status<100 and tilltableops.id=inv.tableops_id and tilltables.id=tilltableops.table_id and waitron.id = '$waitron' and inv.waitron_id = waitron.id and tods.invoice=inv.id and tods.id > '$lastids{$waitron}' and tilltableops.id >= '$allowedtabops{$tableid}->{tabopsid}' and tilltableops.table_id = '$tableid' group by inv order by waitron.name,inv.stamp; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { #~ $oxml .= "{stamp}\" name=\"$ref->{name}\" tablenr=\"$ref->{tablenr}\" inv=\"$ref->{inv}\" />"; push @{$vars->{tablerows}} , $ref; } } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_undo" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_undo.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my %lastids; $results = $dbh->prepare(" select waitron.id waitron, if(substring_index(group_concat(last_tillid order by dcashitems.id desc), ',', 1) is NULL,0,substring_index(group_concat(last_tillid order by dcashitems.id desc), ',', 1)) lastid from waitron LEFT JOIN dcashitems ON dcashitems.waitron_id=waitron.id and dcashitems.f_status<100 where waitron.f_status < 100 and waitron.id in (select distinct waitron_id from tillinvoices) group by waitron.id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $lastids{$ref->{waitron}} = $ref->{lastid} } foreach my $waitron (keys %lastids) { $results = $dbh->prepare(" select inv.stamp stamp, waitron.name name, tilltables.number tablenr, inv.id inv, inv.voided voided from tillinvoices inv, tillordersdetails tods,waitron,tilltables,tilltableops where inv.voided is not null #or inv.voided = 0 and tilltableops.id=inv.tableops_id and tilltables.id=tilltableops.table_id and waitron.id = $waitron and inv.waitron_id = waitron.id and tods.invoice=inv.id and tods.id > $lastids{$waitron} group by inv order by waitron.name,inv.stamp; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @{$vars->{tablerows}}, $ref; #$oxml .= "{stamp}\" name=\"$ref->{name}\" tablenr=\"$ref->{tablenr}\" inv=\"$ref->{inv}\" />"; } } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_reprint_reprint") { my $suid = $R::suid || $session->param("~set_superuser_id"); my ($result, $closestatus) = printinvoice( { printinstructions => $profile->{printinstructions}, enable_proplim => $enable_proplim, enable_loyalty => $enable_loyalty, screenmode => $screenmode, till_id => $profile->{station_id} || $R::tid, supervisor_flag => 1, invoice => $R::i, copies => 1 }, {dbh => $dbh}, $database, $shop{id}, $sharedclients ); ##LOG reprint #my $db = DataBase->new(dbh=>$dbh); my $resultwait_id = $dbh->selectrow_arrayref("SELECT waitron_id FROM tillinvoices WHERE id=?",undef, $R::i); my $waitron_id = $resultwait_id->[0];#$db->SelectOne("SELECT waitron_id FROM tillinvoices WHERE id=?",$R::i); &supervisorLog($dbh,$suid,'RE-PRINT INVOICE','RE-PRINT INVOICE',"RE-print invocie " .$R::i, '',$profile->{station_id} || $R::tid,$waitron_id,''); print qq~ mes = document.getElementById('message'); mes.innerHTML="Invoice #$R::i was printed."; mes.className='messn'; ~; } elsif ($socketflag == 1 and $R::action eq "superbigprint" and $session->param("~set_logged_superuser")) { my $file = "$tdir/$database"."_ready.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; $results = $dbh->prepare(" select DATE_FORMAT(stamp, '%e/%m/%Y') date, discount, client_id from tillinvoices where id = '$R::number';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{date} = "$ref->{date}"; $vars->{discount} = $ref->{discount}; $results = $dbh->prepare(" select * from tillclients where id = ?;") or die $dbh->errstr(); $results->execute($ref->{client_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{name} = $ref->{name}; $vars->{company} = $ref->{group}; $vars->{address} = $ref->{address}; $vars->{tel} = $ref->{telephone}; $vars->{cell} = $ref->{cellphone}; $vars->{email} = $ref->{email}; $vars->{fax} = $ref->{fax}; $vars->{vatnr} = $ref->{vat}; $results = $dbh->prepare("select menu.name, sum(tods.qty) qty, tods.price uprice, sum(tods.qty*tods.price) total from tillordersdetails tods, menu where menu.id = tods.plu and tods.invoice = '$R::number' group by tods.name order by total desc; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $vars->{subtotal} += $ref->{total}; $vars->{col1} .= "$ref->{qty}"."
    "; $vars->{col2} .= "$ref->{name}"."
    "; $vars->{col3} .= "$currency $ref->{uprice}"."
    "; $vars->{col4} .= "$currency ".pr($ref->{total})."
    "; } $vars->{vat} = pr( ( ($tax{$database}{cvat}) / 100 ) * $vars->{subtotal} ); $vars->{subtotal} = pr($vars->{subtotal}); #calculate deposit and sfee here $vars->{sfee} = 1; $vars->{due} = 1; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ( $socketflag == 1 and $R::action eq "invtemplate" and ( $session->param("~set_logged_superuser") > 0 or $session->param("~set_logged_user") > 0 ) ) { my $file = "$tdir/invoicetemplate_$database.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); #use Data::Dumper; #print "Content-type:text/html\n\n$tdir";exit; #print Dumper(%{$sys_settings});exit; my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile,tdir=>$tdir}; $results = $dbh->prepare(" select tillinvoices.id, tillinvoices.cash, tillinvoices.cheque, tillinvoices.ccard, tillinvoices.ccardtype, tillinvoices.account, tillinvoices.discount, tillinvoices.seq_nr, tillinvoices.isrefund, DATE_FORMAT(tillinvoices.stamp, '%e/%m/%Y %H:%i') date, tillinvoices.voided, tillinvoices.client_id, waitron.name from tillinvoices, waitron where waitron.id = tillinvoices.waitron_id and tillinvoices.id = '$R::invoiceid' ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{discount} < 0) { $ref->{discount} *= -1; } $vars->{tinv_id} = $ref->{id}; $vars->{tinv_cash} = $ref->{cash}; $vars->{tinv_cheque} = $ref->{cheque}; $vars->{tinv_ccard} = $ref->{ccard}; $vars->{tinv_ccardtype} = $ref->{ccardtype}; $vars->{tinv_account} = $ref->{account}; $vars->{date} = "$ref->{date}"; $vars->{discount} = pr($ref->{discount}); $vars->{sales_rep} = $ref->{name}; $vars->{isrefund} = $ref->{isrefund}; if ($ref->{voided} == 3) { $vars->{document_type} = $documents{2}[0]; $vars->{document_number} = $documents{2}[1].$ref->{id}."/".$ref->{seq_nr}; } elsif ($ref->{isrefund}) { $vars->{document_type} = $documents{3}[0]; $vars->{document_number} = $documents{3}[1].$ref->{id}."/".$ref->{seq_nr}; } else { $vars->{document_type} = $documents{1}[0]; $vars->{document_number} = $documents{1}[1].$ref->{id}."/".$ref->{seq_nr}; } $results = $dbh->prepare("select * from $sharedclients.tillclients where id = ?;") or die $dbh->errstr(); $results->execute($ref->{client_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{client_company} = $ref->{clientgroup}; $vars->{client_address} .= "$ref->{address}
    " if ($ref->{address}); $vars->{client_address} .= "$ref->{address1}
    " if ($ref->{address1}); $vars->{client_address} .= "$ref->{address2}
    " if ($ref->{address2}); $vars->{client_address} .= "$ref->{address3}
    " if ($ref->{address3}); $vars->{client_address} .= "$ref->{postcode}
    " if ($ref->{postcode}); $vars->{deliver_to} .= "$ref->{ph_address}
    " if ($ref->{ph_address}); $vars->{deliver_to} .= "$ref->{ph_address1}
    " if ($ref->{ph_address1}); $vars->{deliver_to} .= "$ref->{ph_address2}
    " if ($ref->{ph_address2}); $vars->{deliver_to} .= "$ref->{ph_address3}
    " if ($ref->{ph_address3}); $vars->{deliver_to} .= "$ref->{ph_postcode}
    " if ($ref->{ph_postcode}); $vars->{deliver_to} .= "ATT: $ref->{name}
    "; $vars->{deliver_to} .= "Cell: $ref->{cellphone} Tel: $ref->{telephone} Fax: $ref->{fax}"; $vars->{account} = $ref->{code}; $vars->{client_person} = $ref->{name}; $vars->{client_vat} = $ref->{tax_number}; $results = $dbh->prepare("select menu.id pluid,menu.name,menu.code, tods.price uprice, sum(tods.qty) AS qty, sum(tods.qty*tods.price) AS total, sum(tods.discount) AS todsdiscount from tillordersdetails tods, menu where menu.id = tods.plu and tods.invoice = '$R::invoiceid' group by tods.name,tods.price,tods.discount order by total desc") or die $dbh->errstr(); $results->execute() or die $results->errstr(); my $page = 1; my $itemcount = 1; my $running_total; my $itmTax; my $taxTotal = 0; #Calculations on invoice : #Total = (sumOfItemPrices - discount) sumOfItemPrices includes tax #TaxTotal is calculated via totalItemCost - totalItemCost/(100+itemTaxt/100) #TotalExcl = sumOfItemPrices - TaxTotal while ($ref = $results->fetchrow_hashref()) { if ($vars->{isrefund}) { $ref->{qty} = 0 - $ref->{qty}; $ref->{total} = 0 - $ref->{total}; } $vars->{subtotal} += $ref->{total}; if ($itemcount > 21) { $vars->{page_subtotal}->{$page} = pr_com($running_total); $page++; $itemcount = 1; } $running_total += $ref->{total}; $subresults = $dbh->prepare(" select * from menu_tax where menu_id='$ref->{pluid}';;"); $subresults->execute() or die $subresults->errstr(); $itmTax = 0; while ($subref = $subresults->fetchrow_hashref()) { $itmTax = $itmTax + $tax{$database}{$subref->{tax_id}}{tax}; } push @{$vars->{data}->{$page}}, { qty => $ref->{qty}, name => $ref->{name}, code => $ref->{code}, uprice => pr_com($ref->{uprice}), total => pr_com($ref->{total}), tax => $itmTax, todsdiscount=>$ref->{todsdiscount}, }; #$taxTotal = $taxTotal + pr_com($ref->{total} - $ref->{total}/((100 + $itmTax)/100) ); #$taxTotal = $taxTotal + $ref->{total} - $ref->{total}/((100 + $itmTax)/100); ###### #$ref->{todsdiscount} ||=0; #$taxTotal = $taxTotal + ($ref->{total}-$ref->{todsdiscount}) - ($ref->{total} -$ref->{todsdiscount})/((100 + $itmTax)/100); #http://demo2.wtspace.com:84/extranet/pos/index.cgi?action=invtemplate&invoiceid=2723 $itemcount ++; } $vars->{page_subtotal}->{$page} = pr_com($running_total); $vars->{pages} = $page; #totals $vars->{disctotal} = $vars->{discount}; $vars->{discountperc} = pr( $vars->{discount} / $vars->{subtotal} * 100) if $vars->{discount}>0 ; $vars->{discsubtotal} = $vars->{subtotal} - $vars->{discount}; #changed desc and vat ,fixed taxtotal and texcl 20230606 my $total_amount = $vars->{subtotal} - $vars->{disctotal}; #[%totalvat = ( (total) * ( cvat / (100 + cvat) ) )%] $taxTotal = ($total_amount) * ( $tax{$database}{cvat} / (100 + $tax{$database}{cvat}) ) ; #$vars->{vat} = pr_com( $vars->{discsubtotal} - $vars->{discsubtotal}/((100 + $tax{$database}{cvat})/100) ); $vars->{vat} = pr_com($taxTotal); $vars->{texcl} = pr_com($vars->{subtotal} - $taxTotal - $vars->{discount}); $vars->{net} = pr_com($vars->{discsubtotal} - $taxTotal );#pr_com($vars->{discsubtotal} - $vars->{vat} ); $vars->{total} = pr_com($vars->{discsubtotal}); my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "superbiginvoice" and $session->param("~set_logged_superuser")) { my $file = "$tdir/$database"."_prep.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $results = $dbh->prepare(" select DATE_FORMAT(stamp, '%e/%m/%Y') date, discount, client_id from tillinvoices where id = '$R::number';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{date} = "$ref->{date}"; $vars->{discount} = $ref->{discount}; $results = $dbh->prepare(" select * from tillclients where id = ?;") or die $dbh->errstr(); $results->execute($ref->{client_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{name} = $ref->{name}; $vars->{company} = $ref->{group}; $vars->{address} = $ref->{address}; $vars->{tel} = $ref->{telephone}; $vars->{cell} = $ref->{cellphone}; $vars->{email} = $ref->{email}; $vars->{fax} = $ref->{fax}; $vars->{vatnr} = $ref->{vat}; $results = $dbh->prepare("select menu.name, sum(tods.qty) qty, tods.discount udiscount, tods.price uprice, sum(tods.qty*tods.price) total from tillordersdetails tods, menu where menu.id = tods.plu and tods.invoice = '$R::number' group by tods.name order by total desc; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $vars->{subtotal} += $ref->{total}; $vars->{discount} += $ref->{qty} * $ref->{udiscount}; $vars->{col1} .= "$ref->{qty}"."
    "; $vars->{col2} .= "$ref->{name}"."
    "; $vars->{col3} .= "$currency $ref->{uprice}"."
    "; $vars->{col4} .= "$currency ".pr($ref->{total})."
    "; } $vars->{vat} = pr( ( ($tax{$database}{cvat}) / 100 ) * $vars->{subtotal} ); $vars->{subtotal} = pr($vars->{subtotal}); my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif($socketflag == 1 && $R::action eq "super_plu_reprint" && $R::suid ){ #2022-08-14 re-print invoice plu page. my $file = "$tdir/super_plu_reprint.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $vars->{suid} = $R::suid; my %lastids; $results = $dbh->prepare("select id waitron from waitron where id not in (select distinct waitron_id from dcashitems); ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $lastids{$ref->{waitron}} = 0; } $results = $dbh->prepare(" select waitron.id waitron, if(substring_index(group_concat(dcashitems.last_tillid order by dcashitems.id desc), ',', 1) is NULL,0,substring_index(group_concat(dcashitems.last_tillid order by dcashitems.id desc), ',', 1)) lastid from dcash,waitron LEFT JOIN dcashitems ON dcashitems.waitron_id=waitron.id and dcashitems.f_status<100 where #dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 20 day) #and dcash.id = dcashitems.dcash_id and waitron.f_status < 100 and waitron.active = 1 and waitron.id in (select distinct waitron_id from tillinvoices) group by waitron.id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $lastids{$ref->{waitron}} = $ref->{lastid} } foreach my $waitron (keys %lastids) { $results = $dbh->prepare(" select inv.voided voided, inv.seq_nr, inv.stamp stamp,waitron.name name, tilltables.number tablenr,inv.id inv from tillinvoices inv, tillordersdetails tods,waitron,tilltables,tilltableops where tods.f_status < 100 and inv.f_status<100 and tilltableops.f_status<100 and tilltableops.id=inv.tableops_id and tilltables.id=tilltableops.table_id and waitron.id = $waitron and inv.waitron_id = waitron.id and tods.invoice=inv.id and tods.stamp > DATE_SUB(CURRENT_DATE, INTERVAL 10 day) and tods.id > $lastids{$waitron} group by inv order by inv.stamp desc; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { #~ $oxml .= "{stamp}\" name=\"$ref->{name}\" tablenr=\"$ref->{tablenr}\" inv=\"$ref->{inv}\" />"; push @{$vars->{tablerows}} , $ref; } } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; }elsif ($socketflag == 1 and $R::action eq "super_reprint" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_reprint.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; my %lastids; $results = $dbh->prepare("select id waitron from waitron where id not in (select distinct waitron_id from dcashitems); ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $lastids{$ref->{waitron}} = 0; } $results = $dbh->prepare(" select waitron.id waitron, if(substring_index(group_concat(dcashitems.last_tillid order by dcashitems.id desc), ',', 1) is NULL,0,substring_index(group_concat(dcashitems.last_tillid order by dcashitems.id desc), ',', 1)) lastid from dcash,waitron LEFT JOIN dcashitems ON dcashitems.waitron_id=waitron.id and dcashitems.f_status<100 where #dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 20 day) #and dcash.id = dcashitems.dcash_id and waitron.f_status < 100 and waitron.active = 1 and waitron.id in (select distinct waitron_id from tillinvoices) group by waitron.id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $lastids{$ref->{waitron}} = $ref->{lastid} } foreach my $waitron (keys %lastids) { $results = $dbh->prepare(" select inv.voided voided, inv.seq_nr, inv.stamp stamp,waitron.name name, tilltables.number tablenr,inv.id inv from tillinvoices inv, tillordersdetails tods,waitron,tilltables,tilltableops where tods.f_status < 100 and inv.f_status<100 and tilltableops.f_status<100 and tilltableops.id=inv.tableops_id and tilltables.id=tilltableops.table_id and waitron.id = $waitron and inv.waitron_id = waitron.id and tods.invoice=inv.id and tods.stamp > DATE_SUB(CURRENT_DATE, INTERVAL 10 day) and tods.id > $lastids{$waitron} group by inv order by inv.stamp desc; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { #~ $oxml .= "{stamp}\" name=\"$ref->{name}\" tablenr=\"$ref->{tablenr}\" inv=\"$ref->{inv}\" />"; push @{$vars->{tablerows}} , $ref; } } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_opentables" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_opentables.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my %tabledetails; my %waitrons; $results = $dbh->prepare("select id,name from waitron where shop_id='$shop{id}' and f_status<100;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $waitrons{$ref->{id}} = $ref->{name}; } $results = $dbh->prepare("select id,number,quick_mode,ordering from tilltables where shop_id='$shop{id}' and f_status<100;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $tabledetails{number}{$ref->{id}} = $ref->{number}; $tabledetails{ordering}{$ref->{id}} = $ref->{ordering}; } my $total_guests; my $total_quickmodetables; my %total_waitrons; my $waitrons_with_tables; foreach my $id (sort keys %{$tabledetails{number}}) { $results = $dbh->prepare(" select action,visitors,waitron_id,id from tilltableops where table_id='$id' and shop_id='$shop{id}' and f_status<100 order by id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{action} == 1) { #table is open; $tabledetails{guests}{$id} = $ref->{visitors}; $tabledetails{waitron}{$id} = $ref->{waitron_id}; $tabledetails{tabopsid}{$id} = $ref->{id}; $total_guests += $ref->{visitors}; $total_quickmodetables ++ if ($tabledetails{quickmode}{$id} == 2); $total_waitrons{$ref->{waitron_id}} = 1; } $waitrons_with_tables = scalar keys %total_waitrons; $total_quickmodetables *= 1; #determine total splits on the table, together with which one is paid. $results = $dbh->prepare(" select tods.split split, tods.name name, tods.invoice invoice from tillordersdetails tods, tillorders where tods.shop_id=tillorders.shop_id and tods.shop_id='$shop{id}' and tods.orders_id=tillorders.id and tillorders.tableops_id = '$tabledetails{tabopsid}{$id}';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $tabledetails{totalsplits}{$id}{splitid}{$ref->{split}} = 1; $tabledetails{paidsplits}{$id}{splitid}{$ref->{split}} = 1 if ($ref->{invoice} > 0); } $tabledetails{allsplits}{$id} = scalar keys %{$tabledetails{totalsplits}{$id}{splitid}}; $tabledetails{allpaidsplits}{$id} = scalar keys %{$tabledetails{paidsplits}{$id}{splitid}}; } #finished my %quickmodes = (1 => 'no', 2 => 'yes'); $vars->{ohtml} .= " "; foreach my $id (sort keys %{$tabledetails{guests}} ) { $vars->{ohtml} .= " "; } $vars->{ohtml} .= "
    NR Guests Users Paid Spl Total Spl
    $tabledetails{number}{$id} $tabledetails{guests}{$id} $waitrons{$tabledetails{waitron}{$id}} $tabledetails{allpaidsplits}{$id} $tabledetails{allsplits}{$id}
    Users: $waitrons_with_tables; Guests: $total_guests
    "; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_xreport" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_xreport.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_turnover" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_turnover.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_messages" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_messages.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_clock" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_clock.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_sessions" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_sessions.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my %emps; $results = $dbh->prepare("select id,name from employees where shop_id='$shop{id}' and f_status<100;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $emps{$ref->{id}} = $ref->{name}; } $vars->{ohtml} = " "; my $cnt; foreach my $id (keys %emps) { $results = $dbh->prepare("select UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(stamp) dur, operation from employeesaccess where employee_id='$id' and shop_id='$shop{id}' and f_status < 100 order by id desc limit 1") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); #print "$emps{$id} $ref->{dur}\n"; if ($ref->{operation} == 1) { $cnt ++; $vars->{ohtml} .= " "; } } $vars->{ohtml} .= "
    Person Name Duration
    $emps{$id} ".(stringtime($ref->{dur}))."
    ".($cnt*1)." user".($cnt > 1 ? "s" : "")." clocked in.
    "; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "super_login_tables" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_tables.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile, username => $session->param("~set_user_name") }; my $tabledetails; my $lastopsid; my $lastcdate; $results = $dbh->prepare(" select substring_index(group_concat(tod.tableops_id order by dcash.date desc), ',', 1) concat_lastops_id, substring_index(group_concat(dcash.date order by dcash.date desc), ',', 1) concat_lastdate from dcash, tillordersdetails tods, tillorders tod where dcash.last_tillid = tods.id and tod.id = tods.orders_id and dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 15 day) group by dcash.id order by dcash.date desc limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastopsid = $ref->{concat_lastops_id} || 0; $lastcdate = $ref->{concat_lastdate} || "2000-01-01"; $results = $dbh->prepare(" select substring_index(group_concat(tabops.table_id order by tabops.id desc), ',', 1) concat_table_id, substring_index(group_concat(tabops.id - $lastopsid order by tabops.id desc), ',', 1) concat_UNIQUETABOPSID, substring_index(group_concat(tilltables.number order by tabops.id desc), ',', 1) concat_number, substring_index(group_concat(tilltables.type order by tabops.id desc), ',', 1) concat_type, substring_index(group_concat(waitron.name order by tabops.id desc), ',', 1) concat_waitron_name, substring_index(group_concat(waitron.id order by tabops.id desc), ',', 1) concat_waitron_id, substring_index(group_concat(tabops.visitors order by tabops.id desc), ',', 1) concat_visitors, substring_index(group_concat(tabops.id order by tabops.id desc), ',', 1) concat_id, substring_index(group_concat(tabops.action order by tabops.id desc), ',', 1) concat_action, substring_index(group_concat(tabops.waitron_id order by tabops.id desc), ',', 1) concat_waitron_id, substring_index(group_concat(tabops.stamp order by tabops.id desc), ',', 1) concat_stamp from tilltables,tilltableops tabops,waitron where tilltables.id = tabops.table_id and waitron.id = tabops.waitron_id and stamp > DATE_SUB('$lastcdate', INTERVAL 1 day) group by tabops.table_id HAVING substring_index(group_concat(tabops.action order by tabops.id desc), ',', 1) = 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $tabledetails->{$ref->{concat_table_id}} = { tid => $ref->{concat_table_id}, type => $ref->{concat_type}, number => $ref->{concat_number}, reference => $ref->{concat_UNIQUETABOPSID}, waitron_name => $ref->{concat_waitron_name}, waitron_id => $ref->{concat_waitron_id}, guests => $ref->{concat_visitors} }; } foreach my $table_id (keys %{$tabledetails} ){ my $reffy = $tabledetails->{$table_id}; my $ref; $ref->{info} = qq~ $tilltabletype{$reffy->{type}} $reffy->{number} [ref $reffy->{reference}] by $reffy->{waitron_name} ~; $ref->{id} = $reffy->{waitron_id}; $ref->{tid} = $reffy->{tid}; push @{$vars->{tablerows}} , $ref; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "dcash_login_user") { $results = $dbh->prepare(" select * from waitron where id='$R::id';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); # save waitron id, login status in server cookie CGI::SESSION $session->param("~set_user_id", $ref->{id}); $session->param("~set_logged_user", 1); $session->param("~set_user_name", $ref->{name}); #waitron profile $session->param("~set_user_favorite_category", $ref->{favorite_category} || 0); $session->param("~set_user_top_category", $ref->{top_category} || 0); #logout super user $session->param("~set_superuser_id", undef); $session->param("~set_logged_superuser", undef); $session->param("~set_superuser_name", undef); if ($R::tid) { print "document.location='pos/index.cgi?action=plu&tid=$R::tid';"; } else { print "document.location='pos/index.cgi?action=tables';"; } } elsif ($socketflag == 1 and $R::action eq "super_login_user" and $session->param("~set_logged_superuser")) { $results = $dbh->prepare(" select * from waitron where id='$R::id';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); # save waitron id, login status in server cookie CGI::SESSION $session->param("~set_user_id", $ref->{id}); $session->param("~set_logged_user", 1); $session->param("~set_user_name", $ref->{name}); $session->param("~userpayment",1);#$ref->{userpayment}); #$session->param("~userpayment" ,$ref->{userpayment});#2012-12 #save loginas user table id $session->param("~session_table_id",$ref->{table_id}); #waitron profile $session->param("~set_user_favorite_category", $ref->{favorite_category} || 0); $session->param("~set_user_top_category", $ref->{top_category} || 0); #logout super user $session->param("~set_superuser_id", undef); $session->param("~set_logged_superuser", undef); $session->param("~set_superuser_name", undef); if ($R::tid) { #$session->param("~session_current_table_id",$R::tid); print "document.location='index.cgi?action=plu&tid=$R::tid';"; } else { print "document.location='index.cgi?action=tables';"; } } elsif ($socketflag == 1 and $R::action eq "super_login" and $session->param("~set_logged_superuser")) { my $file = "$tdir/super_login.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; $results = $dbh->prepare(" select id,name from waitron where active=1 and f_status<100;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @{$vars->{tablerows}}, $ref; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; #END SUPERVISOR FUNCTIONS } elsif ($socketflag == 1 and $R::action eq "editcustomer" and $session->param("~set_logged_user")) { my $file = "$tdir/taeditpopup.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; if ($R::customer > 0) { $results = $dbh->prepare(" select * from $sharedclients.tillclients where id = '$R::customer' ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{row} = $ref; } else { $vars->{row}->{telephone} = $R::phone; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "serchclient" and $session->param("~set_logged_user")) { my $condition1; my $condition2; my $condition3; my @conditions; if ($R::digi ne '') { if ($settings::customerpins == 1) { } else { $condition1 = " ( (telephone like '%$R::digi%' or cellphone like '%$R::digi%') )"; push @conditions, $condition1; } #and (discountpercent = 0 or discountpercent is null) } if ($R::any ne '') { $condition2 = qq~ ( ( telephone like '%$R::any%' or cellphone like '%$R::any%' or name like '%$R::any%' or clientgroup like '%$R::any%' or code like '%$R::any%' or loyalnumber like '%$R::any%' or address like '%$R::any%' or address1 like '%$R::any%' or address2 like '%$R::any%' or address3 like '%$R::any%' or postcode like '%$R::any%' ) ) ~; #and (discountpercent = 0 or discountpercent is null) push @conditions, $condition2; } if ($R::acc ne '') { $condition2 = qq~ ( ( code like '$R::acc' ) ) ~; #and (discountpercent = 0 or discountpercent is null) push @conditions, $condition2; } if ($R::card ne '') { $condition3 = qq~ (cardfootprint like '%$R::card%' or loyalnumber like '%$R::card%' or idnumber like '%$R::card%') ~; push @conditions, $condition3; } my $maincondition; if (scalar @conditions > 0) { $maincondition = join (" AND ", @conditions); } else { $maincondition = $conditions[0]; } #~ print $maincondition; if ($maincondition ne "") { $maincondition = " AND ".$maincondition; } else { $maincondition = " AND id < 1 "; } #~ if ($settings::customerpins == 1) { #~ $results = $dbh->prepare(" #~ select * #~ from $sharedclients.tillclients #~ where #~ id >= 1 and active=1 #~ and loyalnumber = '$R::any' and password = '$R::acc' #~ order by code,name #~ limit 10;") or die $dbh->errstr(); #~ } else { #~ } $results = $dbh->prepare(" select * from $sharedclients.tillclients where id >= 1 and active=1 $maincondition order by code,name limit 20;") or die $dbh->errstr(); #~ open (DEB,">>/debb"); #~ print DEB " #~ select * #~ from $sharedclients.tillclients #~ where #~ id >= 1 and active=1 #~ $maincondition #~ order by code,name #~ limit 20;"; #~ close DEB; #~ print " #~ select * #~ from $sharedclients.tillclients #~ where #~ id > 1 #~ $maincondition #~ and shop_id=$shop{id} and f_status < 100 #~ order by name #~ limit 10;"; my $note; my $customer_id; $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $subresults = $dbh->prepare(" SELECT tillclients.*, bal.entity_debit, bal.entity_credit, bal.entity_credit - bal.entity_debit credit_balance, tillclients.creditlimit + IF(bal.entity_credit IS NULL OR bal.entity_debit IS NULL,0, bal.entity_credit - bal.entity_debit) available_credit FROM $sharedclients.tillclients tillclients left join account_balance_entity bal on bal.account = 1 and entityid = tillclients.id where tillclients.id = ?;") or die $dbh->errstr(); $subresults->execute($ref->{id}) or die $results->errstr(); $subref = $subresults->fetchrow_hashref(); my $account_available = pr($subref->{available_credit} * -1); print qq~
    Account Code: $ref->{code} Available Credit: $currency $account_available
    ID Number: $ref->{idnumber}
    Name: $ref->{name}  
    Company: $ref->{clientgroup}  
    Telephone: $ref->{telephone}  
    Cellphone: $ref->{cellphone}  
    Address1: $ref->{ph_address}  
    Address2: $ref->{ph_address1}  
    ~; $note = $ref->{note}; if ($results->rows == 1) { $customer_id = $ref->{id}; } } if(! $results->rows) { print "No results found."; } if ($results->rows == 1) { print "NOTES: $note"; print "ason>>customer_options(1);"; print "popcustomer='$customer_id';"; if ($settings::customerpins == 1) { if ($subref->{password} eq $R::digi && $R::digi) { #~ print "alert('password accepted: $ref->{password}')"; print "customer_options(1,1)"; } } } else { print "ason>>customer_options(0);"; print "popcustomer='';"; } } elsif ($socketflag == 1 and $R::action eq "getdebtors" and $session->param("~set_logged_user")) { my $file = "$tdir/selectclient.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my $cnt = 1; my $ason; $results = $dbh->prepare("select distinct clientgroup from $sharedclients.tillclients where active = 1 and (type != 3 or type is null) order by clientgroup;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $vars->{tabulation} .= qq~
  • $ref->{clientgroup}
  • ~; $vars->{ason} = "ason>>tab(1, '$ref->{clientgroup}')" if ($cnt==1); $cnt ++; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "logoutretail" and $session->param("~set_logged_user")) { my $qm; my ( $flag, $message ) = close_table( { qm => $qm, waitron_id => $session->param("~set_user_id"), table_id => $R::tid, till_id => $station_id }, {dbh => $dbh}, $shop{id} ); if ($flag) { $session->param("~set_user_id", undef); $session->param("~set_logged_user", undef); $session->param("~set_user_name", undef); $session->param("~set_superuser_id", undef); $session->param("~set_logged_superuser", undef); $session->param("~set_superuser_name", undef); print qq~ window.location = 'index.cgi'~; } else { print qq~ GB_mess("ERROR $message",-1, "GB_hide()"); ~; } } elsif ($socketflag == 1 and $R::action eq "closetable" and $session->param("~set_logged_user")) { my $qm = $session->param("~setqmode"); my ($flag, $message ) = close_table( { qm => $qm, waitron_id => $session->param("~set_user_id"), table_id => $R::tid, till_id => $station_id }, {dbh => $dbh}, $shop{id} ); if ($flag and $qm != 1) { print qq~ window.location = 'index.cgi?action=tables'~; } elsif ($flag and $qm == 1) { print qq~ window.location = 'index.cgi?action=plu&tid=$R::tid'~; } else { print qq~ GB_mess("ERROR $message",-1, "GB_hide()"); ~; } } elsif ($socketflag == 1 and $R::action eq "renametable" and $session->param("~set_logged_user")) { $results = $dbh->prepare(" UPDATE tilltables SET description = ? WHERE id = ? and (description = '' or description LIKE '*%'); ") or die $dbh->errstr(); $results->execute('* '.$R::descr, $R::tid) or die $results->errstr(); print qq~window.location = 'index.cgi?action=tables'~; } elsif ($socketflag == 1 and $R::action eq "tables" and $session->param("~set_logged_user")) { my $entrytime = gettimeofday; $session->param("layoutview", "off") if ($R::layout eq "off"); $session->param("layoutview", "on") if ($R::layout eq "on"); my $layoutview = $session->param("layoutview"); my $file; if ($R::layout eq "on" or $layoutview eq "on") { $file = "$tdir/layout.html"; } else { $file = "$tdir/tables.html" } #write2log("Table User Payment - 1:". $session->param("~userpayment")); #write2log("Table Terminal Payment -1 :". $profile->{disablepayment}); if($session->param("~userpayment")){#2020-12 $profile->{disablepayment} = $session->param("~userpayment") if $session->param("~userpayment")==2; } #write2log("Table User Payment:". $session->param("~userpayment")); #write2log("Table Terminal Payment:". $profile->{disablepayment}); my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile, username => $session->param("~set_user_name") }; $vars->{cdrawer} = $settings::cdrawer; $vars->{sutransfer} = $settings::sutransfer; $vars->{cashdrawer_port} = $cashdrawer_port; $vars->{cashdrawer_ip} = $cashdrawer_ip; $vars->{pole_port} = $pole_port; $vars->{pole_ip} = $pole_ip; $vars->{disablepayment} = $profile->{disablepayment}; my $my_waitron_id=$session->param("~set_user_id"); #my $my_waitron_id=154; my %tableops; my @lasttableops; my %tabledetails; my %client_names; $results = $dbh->prepare("select id,name from $sharedclients.tillclients;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $client_names{$ref->{id}} = $ref->{name}; } my @tnumbers; $results = $dbh->prepare("select * from tilltables where active=1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @tnumbers, "$ref->{id}:$ref->{number}"; $tabledetails{id}{$ref->{number}} = $ref->{id}; $tabledetails{number}{$ref->{id}} = $ref->{number}; $tabledetails{ordering}{$ref->{id}} = $ref->{ordering}; $tabledetails{location}{$ref->{id}} = $ref->{location}; $tabledetails{type}{$ref->{id}} = $ref->{type}; $tabledetails{descr}{$ref->{id}} = $ref->{description}; $tabledetails{qm}{$ref->{id}} = $ref->{quick_mode}; } $vars->{tnumbers} = join (",", @tnumbers); my $tabledetailz; my $lastopsid; my $lastcdate; $results = $dbh->prepare(" select substring_index(group_concat(tod.tableops_id order by dcash.date desc), ',', 1) concat_lastops_id, substring_index(group_concat(dcash.date order by dcash.date desc), ',', 1) concat_lastdate from dcash, tillordersdetails tods, tillorders tod where dcash.last_tillid = tods.id and tod.id = tods.orders_id and dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 15 day) group by dcash.id order by dcash.date desc limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastopsid = $ref->{concat_lastops_id} || 0; $lastcdate = $ref->{concat_lastdate} || "2000-01-01"; $results = $dbh->prepare(" select substring_index(group_concat(tabops.table_id order by tabops.id desc), ',', 1) concat_table_id, substring_index(group_concat(tabops.id - $lastopsid order by tabops.id desc), ',', 1) concat_UNIQUETABOPSID, substring_index(group_concat(tilltables.number order by tabops.id desc), ',', 1) concat_number, substring_index(group_concat(tilltables.type order by tabops.id desc), ',', 1) concat_type, substring_index(group_concat(tabops.client_id order by tabops.id desc), ',', 1) concat_client_id, substring_index(group_concat(waitron.name order by tabops.id desc), ',', 1) concat_waitron_name, substring_index(group_concat(waitron.id order by tabops.id desc), ',', 1) concat_waitron_id, substring_index(group_concat(tabops.visitors order by tabops.id desc), ',', 1) concat_visitors, substring_index(group_concat(tabops.id order by tabops.id desc), ',', 1) concat_id, substring_index(group_concat(tabops.action order by tabops.id desc), ',', 1) concat_action, substring_index(group_concat(tabops.waitron_id order by tabops.id desc), ',', 1) concat_waitron_id, substring_index(group_concat(tabops.stamp order by tabops.id desc), ',', 1) concat_stamp from tilltables,tilltableops tabops,waitron where tilltables.id = tabops.table_id and waitron.id = tabops.waitron_id and stamp > DATE_SUB('$lastcdate', INTERVAL 1 day) group by tabops.table_id HAVING substring_index(group_concat(tabops.action order by tabops.id desc), ',', 1) = 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { #~ $tabledetails->{$ref->{concat_table_id}} = { #~ tid => $ref->{concat_table_id}, #~ type => $ref->{concat_type}, #~ number => $ref->{concat_number}, #~ reference => $ref->{concat_UNIQUETABOPSID}, #~ waitron_name => $ref->{concat_waitron_name}, #~ waitron_id => $ref->{concat_waitron_id}, #~ guests => $ref->{concat_visitors} #~ }; $tableops{id}{$ref->{concat_table_id}} = $ref->{concat_id}; $tableops{action}{$ref->{concat_table_id}} = 1; $tableops{waitron}{$ref->{concat_table_id}} = $ref->{concat_waitron_id}; $tabledetails{waitron_id}{$ref->{concat_table_id}} = $ref->{concat_waitron_id}; $tabledetails{waitron_name}{$ref->{concat_table_id}} = $ref->{concat_waitron_name}; $tabledetails{visitors}{$ref->{concat_table_id}} = $ref->{concat_visitors}; $tabledetails{tableops_id}{$ref->{concat_table_id}} = $ref->{concat_id}; $tabledetails{client_id}{$ref->{concat_table_id}} = $ref->{concat_client_id}; $tabledetails{client_name}{$ref->{concat_table_id}} = $client_names{$ref->{concat_client_id}}; $tabledetails{uniqueorder}{$ref->{concat_table_id}} = $ref->{concat_UNIQUETABOPSID}; } #~ foreach my $table_id (keys %{$tabledetails{number}}) { #~ $results = $dbh->prepare("select id,client_id,action,waitron_id,table_id,visitors #~ from tilltableops where table_id='$table_id' order by id desc limit 1;") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ $ref = $results->fetchrow_hashref(); #~ $tableops{id}{$ref->{table_id}} = $ref->{id}; #~ $tableops{action}{$ref->{table_id}} = $ref->{action}; #~ $tableops{waitron}{$ref->{table_id}} = $ref->{waitron_id}; #~ $tabledetails{waitron_id}{$ref->{table_id}} = $ref->{waitron_id}; #~ $tabledetails{visitors}{$ref->{table_id}} = $ref->{visitors}; #~ $tabledetails{tableops_id}{$ref->{table_id}} = $ref->{id}; #~ $tabledetails{client_id}{$ref->{table_id}} = $ref->{client_id}; #~ $tabledetails{client_name}{$ref->{table_id}} = $client_names{$ref->{client_id}}; #~ my $table_id = $ref->{table_id}; #~ my $tableops_id = $tabledetails{tableops_id}{$ref->{table_id}}; #~ $results = $dbh->prepare(" #~ select #~ concat(date(stamp), ' 05:00:00') date1, #~ concat(DATE_ADD(date(stamp), INTERVAL 1 DAY) , ' 05:00:00') date2 #~ from tilltableops #~ where id = '$tableops_id'; #~ ") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ $ref = $results->fetchrow_hashref(); #~ my $date1 = $ref->{date1}; #~ my $date2 = $ref->{date2}; #~ $results = $dbh->prepare(" #~ select count(*) cnt from tilltableops #~ where #~ stamp > '$date1' #~ and #~ stamp < '$date2' #~ and action = 1 #~ and id < '$tableops_id'; #~ ") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ $ref = $results->fetchrow_hashref(); #~ my $unique = $ref->{cnt} + 1; #~ $tabledetails{uniqueorder}{$table_id} = $unique; #~ } #end SQL ##### update gsts ##### if ( $R::tid and $R::guests and $tableops{action}{$R::tid} == 1 and $tabledetails{waitron_id}{$R::tid} ) { $tabledetails{visitors}{$R::tid} = $R::guests; $results = $dbh->prepare(" update tilltableops set visitors = '$R::guests' where id = '$tableops{id}{$R::tid}' ; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); } my @opentables; my @closedtables; my @foreigntables; my %table_status; my %currentopentables; #determine tables foreach my $tid (keys %{$tabledetails{number}}) { if ($tableops{action}{$tid} == 1) { #open table if ($tableops{waitron}{$tid} == $my_waitron_id) { #my table push @{$table_status{open}}, $tid; $currentopentables{$tabledetails{number}{$tid}} = 1; } else { #foreign table push @{$table_status{foreign}}, $tid; $currentopentables{$tabledetails{number}{$tid}} = 2; } } else { # closed table push @{$table_status{closed}}, $tid; } } if ($layoutview eq "on") { my $data = eval(tvis_readtmp($database)); my $selectedlayout = $session->param("selectedlayout"); if ($R::selectedlayout ne "") { $selectedlayout = $R::selectedlayout; } $selectedlayout = (sort {$a cmp $b} keys %{ $data->{stages} })[0] if (! $selectedlayout or ! exists $data->{stages}->{$selectedlayout}); $session->param("selectedlayout", $selectedlayout); #read only $data = eval(tvis_readtmp($database)); $vars->{stages} .= "
    Available Layouts:
    "; foreach my $stage (sort {$a cmp $b} keys %{ $data->{stages} } ) { $vars->{stages} .= " "; } $vars->{thislayout} = $selectedlayout; ### LOAD SCENE ### my $xoffset = 228; my $yoffset = 121; $vars->{totalelements} = (sort {$b <=> $a} keys %{$data->{stages}->{$vars->{thislayout}}->{elems}})[0] || 0; $vars->{totaltexts} = (sort {$b <=> $a} keys %{$data->{stages}->{$vars->{thislayout}}->{txts}})[0] || 0; foreach my $ind ( sort {$a <=> $b} keys %{$data->{stages}->{$vars->{thislayout}}->{elems}}) { my $chunk = $data->{stages}->{$vars->{thislayout}}->{elems}->{$ind}; my $onmousedown = qq~~; $chunk->{cx} += $xoffset; $chunk->{cy} += $yoffset; $vars->{loader} .= qq~~; $vars->{loader} .= qq~~; $vars->{loader} .= qq~~; $vars->{initialelements} .= " '$chunk->{pic}^$ind' : '$chunk->{pic}', "; } foreach my $ind ( sort {$a <=> $b} keys %{$data->{stages}->{$vars->{thislayout}}->{txts}}) { my $chunk = $data->{stages}->{$vars->{thislayout}}->{txts}->{$ind}; my $onmousedown = qq~~; $chunk->{cx} += $xoffset; $chunk->{cy} += $yoffset; $vars->{loader} .= qq~~; $vars->{loader} .= qq~
    $chunk->{txt}
    ~; $vars->{loader} .= qq~
    ~; $vars->{initialtexts} .= " '$ind' : '$chunk->{style}', "; } foreach my $ind ( sort {$a <=> $b} keys %{$data->{stages}->{$vars->{thislayout}}->{tables}}) { my $chunk = $data->{stages}->{$vars->{thislayout}}->{tables}->{$ind}; my $onmousedown; if ($currentopentables{$ind} == 1 ) { $onmousedown = qq~onclick="window.location='index.cgi?action=plu&tid=$tabledetails{id}{$ind}'"~; } elsif (! exists $currentopentables{$ind}) { my $type = $tabledetails{type}{ $tabledetails{id}{$ind} }; $onmousedown = qq~onclick="window.location='index.cgi?action=opentable&id=$tabledetails{id}{$ind}&number=$ind&type=$type'"~; } $chunk->{cx} += $xoffset; $chunk->{cy} += $yoffset; $vars->{loader} .= qq~~; $vars->{loader} .= qq~
    $ind
    ~; $vars->{loader} .= qq~
    ~; $vars->{tablesshowing} .= " '$ind' : '1',"; $vars->{tablespics} .= " '$ind' : '$chunk->{pic}',"; $vars->{tableselementindex} .= "'$ind' : '1',"; #to fix } } else { $vars->{opentables} = qq~~; $vars->{closedtables} = qq~
    ~; $vars->{foreigntables} = qq~
    ~; #html open tables if ($table_status{open}) { foreach my $tid ( sort {$tabledetails{ordering}{$a} <=> $tabledetails{ordering}{$b}} sort {$tabledetails{number}{$a} <=> $tabledetails{number}{$b}} @{$table_status{open}} ) { my $client_ml; if ($tabledetails{client_id}{$tid}) { my $name = $client_names{ $tabledetails{client_id}{$tid} }; $client_ml = "
    $name{opentables} .= qq~ ~; } } #html closed tables if ($table_status{closed}) { my $oldnr; foreach my $tid ( sort {$tabledetails{ordering}{$a} <=> $tabledetails{ordering}{$b}} sort {$tabledetails{number}{$a} <=> $tabledetails{number}{$b}} @{$table_status{closed}} ) { if ($settings::tablesep == 1) { if ($oldnr > 0) { if ($oldnr + 1 != $tabledetails{number}{$tid}) { #gap found $vars->{closedtables} .= qq~ ~; } # gap } } $vars->{closedtables} .= qq~ ~; $oldnr = $tabledetails{number}{$tid}; } } #html foreign tables if ($table_status{foreign}) { foreach my $tid ( sort {$tabledetails{ordering}{$a} <=> $tabledetails{ordering}{$b}} sort {$tabledetails{number}{$a} <=> $tabledetails{number}{$b}} @{$table_status{foreign}} ) { $vars->{foreigntables} .= qq~ ~; } } $vars->{opentables} .= qq~
    $tabledetails{number}{$tid} ($tabledetails{visitors}{$tid} Guests) REF: $tabledetails{uniqueorder}{$tid} $client_ml
    $tabledetails{descr}{$tid}
    $tabledetails{number}{$tid} ~.($tabledetails{descr}{$tid} ne "" ? qq~($tabledetails{descr}{$tid})~ : "").qq~
    $tabledetails{number}{$tid} (Open by $tabledetails{waitron_name}{$tid}, $tabledetails{visitors}{$tid} Guests) REF: $tabledetails{uniqueorder}{$tid} $tabledetails{descr}{$tid}
    ~; $vars->{closedtables} .= qq~~; $vars->{foreigntables} .= qq~~; } $vars->{duration} = gettimeofday - $entrytime; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "plu" and $session->param("~set_logged_user")) { my $paymode; my %tabledetails; my %waitron_names; my %client_names; my %client_charges; my %client_types; my %client_discounts; #if ($R::setqm eq "on") { # $session->param("~setqmode", 1); # } elsif ($R::setqm eq "off") { # $session->param("~setqmode", 0); # } $results = $dbh->prepare("select id,name from waitron") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $waitron_names{$ref->{id}} = $ref->{name}; } $results = $dbh->prepare("select id,name,tacharge,type,discountpercent from $sharedclients.tillclients") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $client_names{$ref->{id}} = $ref->{name}; $client_charges{$ref->{id}} = $ref->{tacharge}; $client_types{$ref->{id}} = $ref->{type}; $client_discounts{$ref->{id}} = $ref->{discountpercent}; } $results = $dbh->prepare("select id,number,ordering,location,type,description,quick_mode from tilltables where active=1") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $tabledetails{number}{$ref->{id}} = $ref->{number}; $tabledetails{ordering}{$ref->{id}} = $ref->{ordering}; $tabledetails{location}{$ref->{id}} = $ref->{location}; $tabledetails{type}{$ref->{id}} = $ref->{type}; $tabledetails{descr}{$ref->{id}} = $ref->{description}; $tabledetails{qm}{$ref->{id}} = $ref->{quick_mode}; } my $status; my $lastid; my $tableops_id; my $lastaction; my ($waitron_id,$guests,$table_id,$till_id,$current_client,$current_client_id); $table_id = $R::tid; #get table id select id from tilltables where number = ? and id != ?" #my $db = DataBase->new(dbh=>$dbh); #my $current_table_number = $db->SelectOne("SELECT number FROM tilltables where id=?",$table_id); $session->param("~session_current_table_id",$table_id);# $current_table_number);#STEVEN 2019-10-22 if ($R::subaction eq "open") { $waitron_id = $session->param("~set_user_id"); $guests = $R::typepad; $table_id = $R::tid; $till_id = $profile->{station_id}; $current_client = undef; #could provide selector for client upon opening $results = $dbh->prepare("select tabops.action, tilltables.type from tilltableops tabops left join tilltables on tilltables.id = tabops.table_id where tabops.table_id = ? order by tabops.id desc limit 1") or die $dbh->errstr(); $results->execute($table_id) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{action} == 2 or (! $results->rows() )) {#still closed table if ($guests == 0) { $guests = 1 if ($ref->{type} == 20); } #create the table operation; #$current_client ||=0; #$results = $dbh->prepare("INSERT into tilltableops #(stamp,shop_id, client_id, waitron_id, till_id, action, table_id, visitors) #values #(CURRENT_TIMESTAMP, $shop{id}, $current_client, #'$waitron_id', #'$till_id', #1, #'$table_id', #'$guests')")or die $dbh->errstr(); $results = $dbh->do("INSERT into tilltableops SET stamp=CURRENT_TIMESTAMP, shop_id=?, client_id=?, waitron_id=?, till_id=?, action=1, table_id=?, visitors=?",undef, $shop{id}, $current_client, $waitron_id, $till_id, $table_id, $guests)or die $results->errstr(); #$results->execute() or die $results->errstr(); #$results->finish(); #use mysql_insertid ... 2022-06-11 $results = $dbh->prepare("SELECT LAST_INSERT_ID() lastid FROM tilltableops limit 1"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastid = $ref->{lastid}; #$lastid = $dbh->last_insert_id(); $tableops_id = $lastid; #used for billdb $status=1; } else { $status=0; } } else {# we have this table open - set status to 1 and lastid to the ops id from cgi $results = $dbh->prepare("select id,client_id,action,waitron_id,table_id,visitors from tilltableops where table_id=? order by id desc limit 1") or die $dbh->errstr(); $results->execute($table_id) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastaction = $ref->{action}; if ($lastaction == 2) {$status = 0} else {$status = 1}; $waitron_id = $session->param("~set_user_id"); #table has being transfered $status = 0 if ($ref->{waitron_id} != $waitron_id); $guests = $ref->{visitors}; $till_id = $profile->{station_id}; $current_client_id = $ref->{client_id}; $current_client = $client_names{$ref->{client_id}}; $tableops_id = $ref->{id}; #update customer if ($R::recall > 0 and $status == 1) { $results = $dbh->prepare(" select * from tillinvoices where id = ? ") or die $dbh->errstr(); $results->execute($R::recall) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{client_id}) { $results = $dbh->prepare(" update tilltableops set client_id = ? where id = ?") or die $dbh->errstr(); $results->execute($ref->{client_id}, $tableops_id) or die $results->errstr(); #$ref = $results->fetchrow_hashref(); $current_client_id = $ref->{client_id}; $current_client = $client_names{$ref->{client_id}}; #transfer data onto this table } }# if status allows } if ($R::rsn && $R::suser && $R::recall) { if ($R::recall !~ /\_/) { $results = $dbh->prepare(" select id from supervisorlog where supervisor = ? and reason = ? and supervisingwhat = ? and transaction_case = ? and transaction_id = ? and terminal_id = ? and user = ?") or die $dbh->errstr(); $results->execute($R::suser, $R::rsn, 'RECALL', "Recall of Document $R::recall",$tableops_id,$till_id,$session->param("~set_user_id") ) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if (! $ref->{id}) { $results = $dbh->prepare(" insert into supervisorlog (supervisor, reason, stamp, supervisingwhat, transaction_case, transaction_id, terminal_id, user) values (?, ?, current_timestamp, ?, ?, ?, ?, ?) ") or die $dbh->errstr(); $results->execute($R::suser, $R::rsn, 'RECALL', "Recall of Document $R::recall",$tableops_id,$till_id,$session->param("~set_user_id") ) or die $results->errstr(); } } else { while ($R::recall =~ /\_(\d+)/g) { my $line = $1; $results = $dbh->prepare(" select invoice,name,price,qty,discount from tillordersdetails where id = ? ") or die $dbh->errstr(); $results->execute($line) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my ($r_invoice,$r_name,$r_price,$r_qty,$r_discount) = ($ref->{invoice}, $ref->{name}, $ref->{price},$ref->{qty} * 1, $ref->{discount}); my $lineitem = "DOC.NR: $r_invoice, ITEM: $r_name, QTY: $r_qty, PRICE: $r_price, DISCOUNT: $r_discount"; $results = $dbh->prepare(" select id from supervisorlog where supervisor = ? and reason = ? and supervisingwhat = ? and transaction_case = ? and transaction_id = ? and terminal_id = ? and user = ?") or die $dbh->errstr(); $results->execute($R::suser, $R::rsn, 'LINE RECALL', "Recall of $lineitem",$tableops_id,$till_id,$session->param("~set_user_id") ) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if (! $ref->{id}) { $results = $dbh->prepare(" insert into supervisorlog (supervisor, reason, stamp, supervisingwhat, transaction_case, transaction_id, terminal_id, user) values (?, ?, current_timestamp, ?, ?, ?, ?, ?) ") or die $dbh->errstr(); $results->execute($R::suser, $R::rsn, 'LINE RECALL', "Recall of $lineitem",$tableops_id,$till_id,$session->param("~set_user_id") ) or die $results->errstr(); } } } } $results = $dbh->prepare("select id,unix_timestamp(current_timestamp) - unix_timestamp(stamp) duration, client_id,action,waitron_id,table_id,visitors,paymode from tilltableops where table_id=? order by id desc limit 1") or die $dbh->errstr(); $results->execute($table_id) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $tableops_id = $ref->{id}; my $tableops_duration = $ref->{duration}; $paymode = $ref->{paymode}; my $lastopsid; my $lastcdate; $results = $dbh->prepare(" select substring_index(group_concat(tod.tableops_id order by dcash.date desc), ',', 1) concat_lastops_id, substring_index(group_concat(dcash.date order by dcash.date desc), ',', 1) concat_lastdate from dcash, tillordersdetails tods, tillorders tod where dcash.last_tillid = tods.id and tod.id = tods.orders_id and dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 15 day) group by dcash.id order by dcash.date desc limit 1") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastopsid = $ref->{concat_lastops_id} || 0; $lastcdate = $ref->{concat_lastdate} || "2000-01-01"; my $unique = $tableops_id - $lastopsid; my $file = "$tdir/plutest.html"; removetmp($station_id); #to debug my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); #userpayment need to consider waitron setting #$profile->{disablepayment} = $session->param("~userpayment") if $session->param("~userpayment") !=1; if($session->param("~userpayment")){ $profile->{disablepayment} = $session->param("~userpayment") if $session->param("~userpayment") ==2; } my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile, username => $session->param("~set_user_name"),qaccount => $settings::qaccount }; $vars->{paymode} = $paymode; $vars->{onholdbutton} = $settings::onholdbut; $vars->{alloworderbutton} = $settings::alloworderbutton; $vars->{userid} = $session->param("~set_user_id"); $vars->{recallbutton} = $settings::recallbutton; $vars->{posfocus} = $profile->{posfocus}; $vars->{widescreen} = $profile->{widescreen}; $vars->{priceoverride} = $settings::priceoverride; $vars->{compcustomer} = $settings::compcustomer; $vars->{nosubmit} = $settings::nosubmit; $vars->{voidenable} = $settings::voidenable; $vars->{orderchange} = $settings::orderchange; $vars->{posallowquickpay} = $settings::posallowquickpay; $vars->{opencdcc} = $settings::opencdcc; $vars->{historybutton} = $settings::historybutton; $vars->{disablepayment} = $profile->{disablepayment}; $vars->{disablereturns} = $profile->{disablereturns}; $vars->{enable_loyalty} = $enable_loyalty; $vars->{enable_proplim} = $enable_proplim; $vars->{plumode} = $session->param("~plumode"); $vars->{recall} = $R::recall; $vars->{recall_onhold} = $R::recall_onhold; $vars->{autoplace} = $settings::autoplace; if ($settings::autoplace eq '%SE_autoplace%') { $vars->{autoplace} = 100; } #pos_print_mode #if ($R::returnpaid > 0 and $profile->{printmode} == 1) { if ($R::returnpaid > 0 and ($profile->{printmode} == 1 || $R::pos_print_mode==1)) { $vars->{returnpaid} = "printbig($R::returnpaid);"; } $vars->{topcat} = $session->param("~set_user_top_category"); $vars->{favcat} = $session->param("~set_user_favorite_category"); $vars->{pole_port} = $pole_port; $vars->{pole_ip} = $pole_ip; $vars->{cashdrawer_port} = $cashdrawer_port; $vars->{cashdrawer_ip} = $cashdrawer_ip; $vars->{superviseqty} = $settings::suqty; $vars->{superviseprice} = $settings::suprice; $vars->{superviseundo} = $session->param("~set_superviseundo"); $vars->{onload} = "window.location = 'index.cgi?action=tables&pole=$R::pole';" if $status == 0; $vars->{open} = 1 if ($R::subaction eq "open"); $vars->{paymodes} = \%paymentmodes; if ($R::selectcustomer > 0) { $results = $dbh->prepare(" update tilltableops set client_id = ?, paymode = ? where id = ?") or die $dbh->errstr(); $results->execute($R::selectcustomer,$R::paymentmode,$tableops_id) or die $results->errstr(); $current_client = $client_names{$R::selectcustomer}; $current_client_id = $R::selectcustomer; $results->finish; if($R::paymentmode ==1 && $R::nightsval){#2023-01 For nightbridge. my ($a,$b) = split(",",$R::nightsval);#$a = account ID, $b = roomId $dbh->do("UPDATE tillclients SET nightsaccountId=?,nightsroomId=? WHERE id=?",undef, $a,$b,$R::selectcustomer); } $vars->{paymode} = $R::paymentmode; } elsif ($R::selectcustomer == -1) { $results = $dbh->prepare(" update tilltableops set client_id = '', paymode='' where id = $tableops_id ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $current_client = ''; $current_client_id = ''; $results->finish; $vars->{paymode} = ''; } if ($vars->{paymode} == 3) { $session->param("~plumode",0); } my $paying = readtmp($station_id, "paying"); $paying = undef; $paying->{customer}->{id} = $current_client_id; $paying->{customer}->{name} = $current_client; $paying->{customer}->{type} = $client_types{$current_client_id}; $paying->{customer}->{discountpercent} = $client_discounts{$current_client_id}; $paying->{table}->{tablenumber} = $tabledetails{number}{$table_id}; $paying->{table}->{tableops_id} = $tableops_id; writetmp($station_id,$paying, "paying"); #serialize data into text file; ## CUSTOMER END ## my $qm = $session->param("~setqmode"); $qm = 0 if !$qm; $vars->{qm} = $qm; if ($qm == 1) { #$vars->{qmhtml} = qq~~; $vars->{qmhtml} =qq~~; } else { #$vars->{qmhtml} = qq~~; $vars->{qmhtml} =qq~~; } #get database entries for this table operation id: $vars->{tableopsid} = $tableops_id; $vars->{tid} = $R::tid; $vars->{uniqueorder} = $unique; #initial display if ($screenmode != 2) { $vars->{tabledetails} = "$tabledetails{number}{$table_id} (duration: ".(stringtimeshort($tableops_duration)).") $tilltabletype{$tabledetails{type}{$table_id}}"; $vars->{tabledetails} .= " ($tabledetails{descr}{$table_id})" if ($tabledetails{descr}{$table_id}); $vars->{guests} = $guests; } else { $vars->{tabledetails} = "$tabledetails{number}{$table_id} (duration: ".(stringtimeshort($tableops_duration)).")"; } ## CUSTOMER ## $vars->{customer} = $client_names{$current_client_id}; $vars->{customer_id} = $current_client_id; $vars->{customer} .= " - Discount: $client_discounts{$current_client_id} % " if ($client_discounts{$current_client_id} > 0); $vars->{customer} .= " - Charge: " . $client_charges{$current_client_id}. " " if ($client_charges{$current_client_id}); if ($current_client_id) { $subresults = $dbh->prepare(" SELECT tillclients.*, bal.entity_debit, bal.entity_credit, bal.entity_credit - bal.entity_debit credit_balance, tillclients.creditlimit + IF(bal.entity_credit IS NULL OR bal.entity_debit IS NULL,0, bal.entity_credit - bal.entity_debit) available_credit FROM $sharedclients.tillclients tillclients left join account_balance_entity bal on bal.account = 1 and entityid = tillclients.id where tillclients.id = ?") or die $dbh->errstr(); $subresults->execute($current_client_id) or die $results->errstr(); $subref = $subresults->fetchrow_hashref(); my $account_available = pr($subref->{available_credit}*-1); $vars->{customer} .= " - Account Bal: $currency $account_available"; $vars->{customer_selected} = $subref->{id}; $vars->{customer_creditlimit} = $subref->{creditlimit}; $vars->{customer_account_available} = $subref->{available_credit}; $vars->{customer_discount} = $subref->{discountpercent}; } $vars->{category} = ""; if ($R::command eq "savesplits") {##WE ARE HERE 3 my $splitting = readtmp($station_id, "splitting"); my $table = $tabledetails{number}{$table_id}; my %donetables = ($table => 'done'); #update splits for current table; #VOID SPLIT my $db = DataBase->new(dbh=>$dbh); $waitron_id = $session->param("~set_user_id"); foreach my $split (sort {$a <=> $b} keys %{ $splitting->{number}->{$table} } ) { my @ids; foreach my $itemid (sort {$a <=> $b} keys %{ $splitting->{number}->{$table}->{$split} } ) { my $reff = $splitting->{number}->{$table}->{$split}->{$itemid}; push @ids, $itemid; foreach my $instruction ( @{ $splitting->{instructions}->{$itemid} } ) { push @ids, $instruction->{id}; } } #update database $results = $dbh->prepare(" update tillordersdetails set split = $split where id in (".(join(",",@ids)).") ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); my $waitron_username = $db->SelectOne("SELECT name FROM `waitron` WHERE id=? LIMIT 1",$waitron_id); my $what = "SPLIT Order id:".join(",",@ids) ; &supervisorLog($dbh,$R::suid,'VOID SPLIT','VOID SPLIT', $what,'',$station_id,$waitron_id,'' ); if ( $splitting->{void}->{$table}->{$split} > 0 ) { my $paying = readtmp($station_id, "paying"); my ($result, $closestatus, $message) = printinvoice( { printinstructions => $profile->{printinstructions}, enable_proplim => $enable_proplim, enable_loyalty => $enable_loyalty, screenmode => $screenmode, till_id => $profile->{station_id}, tableops_id => $tableops_id, split => $split, client => $paying->{customer}->{id}, client_name => $paying->{customer}->{name}, waitron_id => $session->param("~set_user_id"), copies => 1, current_opentable_nr => $table, cash => $R::cash, ccard => $R::ccard, ccard_type => $paying->{cc}, cheque => $R::cheque, account => $R::account, discount => $R::discount + $paying->{pludiscount} + $paying->{clientdiscount}, loyalty => $R::loyalty, supervised_by => $R::supervised_by, voidflag => $splitting->{void}->{$table}->{$split}, voidreason => $R::voidreason, voidsupervisedby => $R::supervisedby, station_id => $station_id, voidtype => $R::t }, {dbh => $dbh}, $database, $shop{id}, $sharedclients ); } } #move items to another table; foreach my $number ( keys %{ $splitting->{number} } ) { logit("SPLIT NUMBER:".$number ."=>".$donetables{$number}); next if ($donetables{$number} ne ''); #New destination table #determine tableopsid for this table $results = $dbh->prepare("select tabops.* from tilltableops tabops, tilltables where tilltables.number = '$number' and tabops.table_id = tilltables.id order by id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $tableopsid = $ref->{id}; my $targetwaitron = $ref->{waitron_id}; if ($ref->{action} == 1) { my $history = readtmp($station_id); #create a order my $till_id = $station_id; my $waitron_id = $session->param("~set_user_id"); my $table_nr = $history->{tablenr}; my $tableops_id = $tableopsid; foreach my $split (sort keys %{ $splitting->{number}->{$number} }) { my %statuses; my %originalorders; foreach my $itemid (sort keys %{ $splitting->{number}->{$number}->{$split} } ) { #what was the original confirm status? $results = $dbh->prepare(" select tod.confirm_status, tod.id from tillordersdetails tods, tillorders tod where tods.orders_id = tod.id and tods.id = $itemid ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); push @{ $statuses{ $ref->{confirm_status} } }, $itemid; push @{ $statuses{ $ref->{confirm_status} } }, $_->{id} foreach ( @{ $splitting->{instructions}->{$itemid} } ); $originalorders{$ref->{id}} = 1; } my(@log_new_orderid,@log_old_orderid); foreach my $confirm_status (sort {$a <=> $b} keys %statuses) { #~ my $confirm_status = $history->{order}->{$orderid}->{stage}; $results = $dbh->prepare("INSERT into tillorders (stamp,shop_id,till_id,waitron_id,tableops_id,confirm_status) values (CURRENT_TIMESTAMP,$shop{id}, '$till_id', '$targetwaitron', '$tableops_id', '$confirm_status');") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results->finish(); #imediately $results = $dbh->prepare("SELECT LAST_INSERT_ID() lastid FROM tillorders limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $orders_id = $ref->{lastid}; # move plu items to this order in the loop $results = $dbh->prepare(" update tillordersdetails set orders_id = '$orders_id', split = $split, waitron_id = '$targetwaitron' where id in (".(join(",", @{ $statuses{$confirm_status} } )).")"); $results->execute() or die $results->errstr(); push @log_new_orderid,$orders_id; foreach my $orgorder (keys %originalorders) { push @log_old_orderid,$orgorder; $results = $dbh->prepare(" select count(*) cnt from tillordersdetails where orders_id = $orgorder "); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if (! $ref->{cnt} ) { $results = $dbh->prepare(" delete from tillorders where id = $orgorder "); $results->execute() or die $results->errstr(); } } #moving completed. } #VOID SPLIT # my $db = DataBase->new(dbh=>$dbh); # my $targetwaitron_username = $db->SelectOne("SELECT name FROM `waitron` WHERE id=? LIMIT 1",$targetwaitron); # my $waitron_username = $db->SelectOne("SELECT name FROM `waitron` WHERE id=? LIMIT 1",$waitron_id); # my $what = "SPLIT $waitron_username ORDERS:" . join(",",@log_old_orderid) ." To $targetwaitron_username ORDER:" . join(",",@log_new_orderid); # logit($what); # &supervisorLog($dbh,$R::suid,'VOID SPLIT','VOID SPLIT', $what,'',$station_id,$targetwaitron,'' ); } } } #table number } #command save splits $vars->{qmode} = $session->param("~setqmode"); #checking qmode #if($session->param("~session_table_id") ==0){ # $vars->{session_table_id} = ""; # $vars->{qmode} = ""; #}elsif($session->param("~session_current_table_id") != $session->param("~session_table_id")){ # $vars->{session_table_id} = ""; # $vars->{qmode} = ""; #}else{ # $vars->{session_table_id} = 1;#$session->param("~setqmode"); # $vars->{qmode} = 1;#$session->param("~setqmode"); #} #logit("session_current_table_id:" .$session->param("~session_current_table_id") ); #logit("session_table_id:" .$session->param("~session_table_id") ); #logit("setqmode:".$session->param("~setqmode")); my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "getsplits" and $session->param("~set_logged_user")) { my $splithtml; my $splitting; $results = $dbh->prepare("select * from tilltables where id = '$R::tid';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $number = $ref->{number}; $splithtml .= qq~~; if ($R::retreive) { my $currentplu; $results = $dbh->prepare("select * from tillorders where f_status<100 and tableops_id = '$R::tableopsid';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $subresults = $dbh->prepare(" select * from tillordersdetails where orders_id = $ref->{id} ;") or die $dbh->errstr(); $subresults->execute() or die $results->errstr(); while($subref = $subresults->fetchrow_hashref()) { next if ($subref->{invoice} > 0); if ($settings::nosplitproforma == 1) { if ($subref->{invoice} == - 12 && $R::proforma != 1) { next; } } $currentplu = $subref->{id} if ($subref->{plu} > 0); #to retreive voided here with a LEFT JOIN QUERY... TODO!!! my $ordid = $ref->{id}; $subref->{qty} *= 1; if ($subref->{plu}) { $splitting->{number}->{$number}->{$subref->{split}}->{$subref->{id}} = { qty => $subref->{qty}, name => $subref->{name}, plu => $subref->{plu} } } else { push @{ $splitting->{instructions}->{$currentplu} }, { name => $subref->{name}, id => $subref->{id} }; } } } } else { $splitting = readtmp($station_id, "splitting"); } #WE ARE HERE 2 #splitting happens here if ($R::itemid) { #split bill #still only on one table $splitting->{number}->{$R::seltable}->{$R::selsplit}->{$R::itemid} = { qty => $splitting->{number}->{$R::orgtable}->{$R::orgsplit}->{$R::itemid}->{qty}, name => $splitting->{number}->{$R::orgtable}->{$R::orgsplit}->{$R::itemid}->{name}, plu => $splitting->{number}->{$R::orgtable}->{$R::orgsplit}->{$R::itemid}->{plu} }; if ($R::orgsplit != $R::selsplit or $R::orgtable != $R::seltable ) { delete $splitting->{number}->{$R::orgtable}->{$R::orgsplit}->{$R::itemid}; if (! keys %{$splitting->{number}->{$R::orgtable}->{$R::orgsplit}}) { delete $splitting->{number}->{$R::orgtable}->{$R::orgsplit}; $splitting->{void}->{$R::orgtable}->{$R::orgsplit} = undef; } if (! keys %{ $splitting->{number}->{$R::orgtable} }) { delete $splitting->{number}->{$R::orgtable}; $splitting->{void}->{$R::orgtable} = undef; } } } #STORE IN TEMP FILE my $voidingitems = 0; if($R::alter == 1) { if ($splitting->{void}->{$R::orgtable}->{$R::orgsplit} == 1) { $splitting->{void} = undef; $splitting->{void}->{$R::orgtable}->{$R::orgsplit} = 2; $voidingitems = 2; } elsif ($splitting->{void}->{$R::orgtable}->{$R::orgsplit} == 2) { $splitting->{void} = undef; $voidingitems = 0; } else { $splitting->{void} = undef; $splitting->{void}->{$R::orgtable}->{$R::orgsplit} = 1; $voidingitems = 1; } } writetmp($station_id,$splitting, "splitting"); #serialize data into text file; #all data retreived from database, provide the virtual splitting here. #display all information on screen foreach my $table (sort {$a <=> $b} keys %{$splitting->{number}}) { foreach my $split (sort {$a <=> $b} keys %{ $splitting->{number}->{$table} } ) { #splits here... #new split $splithtml .= qq~ ~; } } #end of object $splithtml .= qq~
    BILL $split ON TABLE $table
    ~; # my $bgcolor; if ($number == $table) { if ($splitting->{void}->{$table}->{$split} == 1) { $splithtml .= qq~
     
    ~; $bgcolor="voiding"; } elsif ($splitting->{void}->{$table}->{$split} == 2) { $splithtml .= qq~
     
    ~; $bgcolor="returning"; } else { $splithtml .= qq~
     
    ~; $bgcolor = ""; } } foreach my $itemid (sort {$a <=> $b} keys %{ $splitting->{number}->{$table}->{$split} } ) { my $reff = $splitting->{number}->{$table}->{$split}->{$itemid}; $splithtml .= qq~
    $reff->{qty} x $reff->{name}
    ~; #display instructions; foreach my $instruction ( @{ $splitting->{instructions}->{$itemid} } ) { $splithtml .= qq~
    $instruction->{name}
    ~; } } #footer for split $splithtml .= qq~
    ~; $splithtml .= "ason>>voidingitems=$voidingitems;"; print $splithtml; } elsif ($socketflag == 1 and $R::action eq "mainjs" and $session->param("~set_logged_user")) { my $file = "$tdir/main.js"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); # my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile }; $vars->{waitron_id} = $session->param("~set_user_id"); $vars->{database} = $database; $vars->{cdrawer} = $settings::cdrawer; $vars->{alloworderbutton} = $settings::alloworderbutton; $vars->{selectcustomer} = $R::selectcustomer; $vars->{customershort} = $settings::customershort; $vars->{customerpins} = $settings::customerpins; $vars->{customerwristbands} = $settings::customerwristbands; $vars->{posfocus} = $profile->{posfocus}; $vars->{priceoverride} = $settings::priceoverride; $vars->{userid} = $session->param("~set_user_id"); $vars->{customer_id} = $R::customer_id; $vars->{compcustomer} = $settings::compcustomer; $vars->{voidenable} = $settings::voidenable; $vars->{orderchange} = $settings::orderchange; $vars->{surecall} = $settings::surecall; $vars->{superviseqty} = $settings::suqty; $vars->{superviseundo} = $session->param("~set_superviseundo"); $vars->{tid} = $R::tid; $vars->{linemode} = $plu_line_size; $vars->{plumode} = $session->param("~plumode"); my $qm = $session->param("~setqmode"); $qm = 0 if (!$qm); $vars->{qm} = $qm; logit(Dumper($vars)); my $temphtml = $template->process($file, $vars, \$output)|| die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "qwertykeyboard" and $session->param("~set_logged_user")) { my $file = "$tdir/qwerty.htm"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; $vars->{plusearch} = $R::plusearch; $vars->{customersearach1} = $R::customersearach1; $vars->{customersearach2} = $R::customersearach2; $vars->{padvalue} = $R::padvalue; $vars->{thecase} = $R::thecase; $vars->{casedata} = $R::casedata; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } #elsif ($socketflag == 1 and $R::action eq "invoice" and $session->param("~set_logged_superuser")) { #2022-08-14 , let both normal and super session can show invocie elsif ($socketflag == 1 and $R::action eq "invoice" and ($session->param("~set_logged_user")||$session->param("~set_logged_superuser")) ) { my $file = "$tdir/invoice.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $vars->{invoice} = $R::invoice; $vars->{ihtml} = "
    "; $results = $dbh->prepare("select stamp from tillinvoices where id = '$R::invoice';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{ihtml} .= "Time stamp: $ref->{stamp}
    "; my $total; $vars->{ihtml} .= ""; $vars->{ihtml} .= ""; $results = $dbh->prepare("select name, sum(qty) qty, price uprice, yield, sum(qty*price) total from tillordersdetails where shop_id=$shop{id} and invoice = '$R::invoice' group by name order by total desc; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { if ($ref->{yield} > 0) { $ref->{qty} = $ref->{yield}; $ref->{total} = $ref->{uprice} * $ref->{qty}; } $total += $ref->{total}; $vars->{ihtml} .= ""; } $vars->{ihtml} .= ""; $vars->{ihtml} .= "
    Item Qty U.Price Total
    $ref->{name} ".($ref->{qty}*1)." $currency $ref->{uprice} $currency ".pr( $ref->{total} )."
    Total: ".pr($total)."
    "; $vars->{ihtml} .= "
    "; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "instru-all" and $session->param("~set_logged_user")) { my $file = "$tdir/instru-all.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); # my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; $vars->{cattitle} = "All instructions"; $vars->{pagesml} = ""; my ($pagerighturl, $pagelefturl); my ($lefturl, $righturl); #PAGE INSTRUCTIONS $results = $dbh->prepare(" select * from condiment_categories order by name; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @{$vars->{tablerows}}, $ref; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "instru-all-page" and $session->param("~set_logged_user")) { my $file = "$tdir/instru.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); # my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; $results = $dbh->prepare(" select * from condiment_categories where id = ?; ;") or die $dbh->errstr(); $results->execute($R::condiment) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{cattitle} = "$ref->{name}"; $vars->{pagesml} = ""; my ($pagerighturl, $pagelefturl); my ($lefturl, $righturl); $vars->{flipclick} = qq~ GB_hide(); ~; #PAGE INSTRUCTIONS $results = $dbh->prepare(" select * from condiments where cond_category = ? order by ordering,name; ;") or die $dbh->errstr(); $results->execute($R::condiment) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @{$vars->{tablerows}}, $ref; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "instru" and $session->param("~set_logged_user")) { my $file = "$tdir/instru.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); # my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my @cats; $results = $dbh->prepare(" select condiment_categories.name name, condiment_categories.id id from menu_condcats,condiment_categories where menu_condcats.menu_id='$R::plu' and condiment_categories.id=menu_condcats.cond_category order by menu_condcats.ordering,menu_condcats.id; ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @cats, {name => $ref->{name}, id => $ref->{id}}; } my $pages = $results->rows; $vars->{cattitle} = ${$cats[$R::page - 1]}{name}; $vars->{pagesml} = "$R::page / ".($pages); my ($pagerighturl, $pagelefturl); my ($lefturl, $righturl); #RIGHT ARROW if ($R::page == $pages) { $righturl = qq~index.cgi?action=$R::action&page=1&plu=$R::plu~; $vars->{righturl} = qq~GB_load('$righturl');~; } else { $righturl = qq~index.cgi?action=$R::action&page=~.($R::page+1).qq~&plu=$R::plu~; $vars->{righturl} = qq~GB_load('$righturl');~; } #LEFT ARROW if ($R::page == 1) { $lefturl = qq~index.cgi?action=$R::action&page=~.($pages).qq~&plu=$R::plu~; $vars->{lefturl} = qq~GB_load('$lefturl','myinstrscroll');~; } else { $lefturl = qq~index.cgi?action=$R::action&page=~.($R::page-1).qq~&plu=$R::plu~; $vars->{lefturl} = qq~GB_load('$lefturl','myinstrscroll');~; } if($R::page == $pages) { $vars->{flipclick} = qq~ GB_hide(); ~; } else { $vars->{flipclick} = qq~ GB_load('$righturl'); ~; } #PAGE INSTRUCTIONS $results = $dbh->prepare(" select * from condiments where cond_category=? order by ordering,name; ;") or die $dbh->errstr(); $results->execute(${$cats[$R::page - 1]}{id}) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @{$vars->{tablerows}}, $ref; } if ($pages > 0) { my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } else { print qq~ason>>popup_allinstructions(); ~; } } elsif ($socketflag == 1 and $R::action eq "info" and $session->param("~set_logged_user")) { my $file = "$tdir/infoscreen.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); # my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; $results = $dbh->prepare(" select * from menu where id='$R::plu'; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{name} = $ref->{name}; $vars->{price} = $ref->{orgprice}; $results = $dbh->prepare(" select * from menu_photos where menu_id='$R::plu'; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{name} =~ /\./ and -s "/wwwroot/extranet/extraplus/mphotos/$database/$ref->{name}") { $vars->{photo} = "/extranet/extraplus/mphotos/$database/$ref->{name}"; } else { $vars->{photo} = "/extranet/pos/plu/nophoto.png"; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "plumode" and $session->param("~set_logged_user")) { if ($session->param("~plumode") == 1) { $session->param("~plumode",2); } elsif ($session->param("~plumode") == 2) { $session->param("~plumode",''); } else { $session->param("~plumode",1); } my $plumode = $session->param("~plumode"); $profile->{pluscreenmode} = $plumode; print "plumode='$plumode';switcher('$plumode');pluonclick();"; } elsif ($socketflag == 1 and $R::action eq "pluitems" and $session->param("~set_logged_user")) { my $pluhtml; my $lastpos; my $plucnt = 1; #~ print "DEBUG:".$session->param("~plumode"); if ($R::category > 0) { if ($R::favorite) { $results = $dbh->prepare("update waitron set favorite_category = ? where id = ?") or die $dbh->errstr(); $results->execute( $R::category, $session->param("~set_user_id") ) or die $results->errstr(); $session->param("~set_user_favorite_category", $R::category); } $results = $dbh->prepare("select * from menu_categories where id = ?") or die $dbh->errstr(); $results->execute($R::category) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $pluhtml .= qq~
    $ref->{name} ~.($R::category and $R::category == $session->param("~set_user_favorite_category") ? "*" : "").qq~
    ~; $results = $dbh->prepare("select menu.*, substr(name,1,40) sname from menu left join menu_schedules_details msd ON msd.schedule_id = menu.schedule_id and dayofweek(current_date) = msd.dayofweek where ( ( ( CURRENT_TIME > start_time OR start_time IS NULL) AND ( CURRENT_TIME < end_time OR end_time IS NULL) ) OR ( ( CURRENT_TIME > start_time1 OR start_time1 IS NULL) AND ( CURRENT_TIME < end_time1 OR end_time1 IS NULL) ) ) and ((activeafter <= CURRENT_DATE or activeafter = '') and (activebefore >= CURRENT_DATE or activebefore = '')) and menu_category=? and useflag=1 order by ordering,name,code") or die $dbh->errstr(); $results->execute($R::category) or die $results->errstr(); #R::current if ($session->param("~plumode") == 1) { $pluhtml .= qq~
    ~; } else { #mode 0 $pluhtml .= qq~
    ~; } while ($ref = $results->fetchrow_hashref()) { my $superplu = ""; if ($ref->{manager} == 1) { $superplu = "popup_su('superplu','');"; } else { $superplu = "plufunction();"; } if ($ref->{isshortcut} != 1) { my %holders = (1=> {2=>"s"}, 2=> {2=>"popup_instruction($ref->{id});"}); my $autoshort; if ($ref->{autoshort} == 1) { $autoshort = "shortcuts($ref->{id}, $R::category, $R::current);"; } if ($session->param("~plumode") == 1) { $lastpos = $plucnt; #lastselectedplu=$ref->{id};getbill($ref->{id}); my ($ringml, $blinkml); if ($ref->{stockflag} == 1) { #STEVEN autoshort. $ringml = "plufunction = function(){ring($plucnt);$holders{2}{$ref->{popable}}};$autoshort;$superplu;"; } else { $ringml = "alertnostock()"; $blinkml = "text-decoration:blink;"; } $pluhtml .= qq~

    $ref->{id}

    $ref->{code} $ref->{sname} $ref->{orgprice} $ref->{stockonhand}
    ~; $plucnt++; } else { # mode 0 my ($ringml, $blinkml); if ($ref->{stockflag} == 1) { $ringml = "plufunction = function(){lastselectedplu='$ref->{id}';getbill($ref->{id},'$ref->{mqty}');$holders{2}{$ref->{popable}}$autoshort};$superplu;"; } else { $ringml = "alertnostock()"; $blinkml = "text-decoration:blink;"; } $pluhtml .= qq~
    ~; if ($ref->{thumb}) { $pluhtml .= qq~~; } else { if ($settings::plumode0 == 1) { $pluhtml .= qq~$ref->{code} - $ref->{name}~; } else { $pluhtml .= qq~$ref->{name}~; } } $pluhtml .= qq~
    ~; if (! $ref->{limitshortcuts}) { $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="shortcuts($ref->{id}, $R::category, $R::current);"~ : '').qq~ class="plucol21~.($ref->{shortcutfor} > 0 ? 's' : '').qq~">
    ~; } else { $pluhtml .= qq~
    ~; } $pluhtml .= qq~
    ~; } } else { if ($ref->{autoring} != 1 ) { $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="plufunction = function(){shortcuts($ref->{id}, $R::category, $R::current);};$superplu"~ : '').qq~>
    $ref->{name}
    ~; } else { $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="plufunction = function(){ringall($ref->{id});};$superplu"~ : '').qq~>
    $ref->{name}
    ~; } #~ $pluhtml .= qq~ #~
    {shortcutfor} > 0 ? qq~onMouseDown="shortcuts($ref->{id}, $R::category, $R::current);"~ : '').qq~>
    $ref->{name}
    #~ ~; } } #display categories list $results = $dbh->prepare("select menu_categories.* from menu_categories left join menu_schedules_details msd ON msd.schedule_id = menu_categories.schedule_id and dayofweek(current_date) = msd.dayofweek where ( ( ( CURRENT_TIME > start_time OR start_time IS NULL) AND ( CURRENT_TIME < end_time OR end_time IS NULL) ) OR ( ( CURRENT_TIME > start_time1 OR start_time1 IS NULL) AND ( CURRENT_TIME < end_time1 OR end_time1 IS NULL) ) ) and ((activeafter <= CURRENT_DATE or activeafter = '') and (activebefore >= CURRENT_DATE or activebefore = '')) and parent_id='$R::category' and useflag=1 order by ordering,name;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $pluhtml .= qq~
    $ref->{name}
    ~; } $pluhtml .= "ason>>try { lastpos = 1; pos = 1; max = '$lastpos'; document.getElementById('row_'+lastpos).className = 'pl_normal'; document.getElementById('row_'+pos).className = 'pl_selected'; } catch(e) {}" if ($session->param("~plumode") == 1); print $pluhtml; } elsif ($R::srch ne '') { #search $results = $dbh->prepare(" select menu.*,substr(menu.name,1,40) sname from menu_categories c, menu left join menu_schedules_details msd ON msd.schedule_id = menu.schedule_id and dayofweek(current_date) = msd.dayofweek where c.id = menu.menu_category and c.useflag = 1 and ( ( ( CURRENT_TIME > start_time OR start_time IS NULL) AND ( CURRENT_TIME < end_time OR end_time IS NULL) ) OR ( ( CURRENT_TIME > start_time1 OR start_time1 IS NULL) AND ( CURRENT_TIME < end_time1 OR end_time1 IS NULL) ) ) and ((menu.activeafter <= CURRENT_DATE or menu.activeafter = '') and (menu.activebefore >= CURRENT_DATE or menu.activebefore = '')) and ( menu.name like ? or menu.shortname like ? or menu.barcode like ? or menu.code like ?) and menu.useflag=1 order by menu.ordering,menu.code,menu.name limit 80;") or die $dbh->errstr(); $results->execute( "%$R::srch%", "%$R::srch%", "%$R::srch%", "%$R::srch%", ) or die $results->errstr(); my $title; $title = qq~
    Searching for: "$R::srch"~; if ($session->param("~plumode") == 1) { $pluhtml .= qq~
    ~; } else { $pluhtml .= qq~
    ~; } $title .= qq~ PLUs: ~.($results->rows*1); while($ref = $results->fetchrow_hashref()) { my $superplu = ""; if ($ref->{manager} == 1) { $superplu = "popup_su('superplu','');"; } else { $superplu = "plufunction();"; } my %holders = (1=> {2=>"s"}, 2=> {2=>"popup_instruction($ref->{id});"}); my $autoshort; if ($ref->{autoshort} == 1) { $autoshort = "plufunction = function(){shortcuts($ref->{id},0);};superplu;"; } if ($session->param("~plumode") == 1) { $lastpos = $plucnt; #lastselectedplu=$ref->{id};getbill($ref->{id}); my ($ringml, $blinkml); if ($ref->{stockflag} == 1) { #STEVEN $ringml = "plufunction = function(){ring($plucnt);$holders{2}{$ref->{popable}};};$autoshort;$superplu;"; } else { $ringml = "alertnostock()"; $blinkml = "text-decoration:blink;"; } $pluhtml .= qq~

    $ref->{id}

    $ref->{code} $ref->{sname} $ref->{orgprice} $ref->{stockonhand}
    ~; $plucnt++; } else { #mode 0 - shortcuts allowed if ($ref->{isshortcut} != 1) { my ($ringml, $blinkml); if ($ref->{stockflag} == 1) { $ringml = "plufunction = function(){lastselectedplu='$ref->{id}';getbill($ref->{id},'$ref->{mqty}');$holders{2}{$ref->{popable}}$autoshort;};$superplu;"; } else { $ringml = "alertnostock()"; $blinkml = "text-decoration:blink;"; } $pluhtml .= qq~
    ~; if ($ref->{thumb}) { $pluhtml .= qq~~; } else { $pluhtml .= qq~$ref->{name}~; } $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="shortcuts($ref->{id},0);"~ : '').qq~ class="plucol21~.($ref->{shortcutfor} > 0 ? 's' : '').qq~">
    ~; } else { if ($ref->{autoring} != 1 ) { $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="plufunction = function(){shortcuts($ref->{id},0);};$superplu;"~ : '').qq~>
    $ref->{name}
    ~; } else { $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="plufunction = function(){$superplu;ringall($ref->{id});};$superplu;"~ : '').qq~>
    $ref->{name}
    ~; } #~ $pluhtml .= qq~ #~
    {shortcutfor} > 0 ? qq~onMouseDown="shortcuts($ref->{id},0);"~ : '').qq~>
    $ref->{name}
    #~ ~; } } # mode } #find categories $results = $dbh->prepare("select menu_categories.* from menu_categories left join menu_schedules_details msd ON msd.schedule_id = menu_categories.schedule_id and dayofweek(current_date) = msd.dayofweek where ( ( ( CURRENT_TIME > start_time OR start_time IS NULL) AND ( CURRENT_TIME < end_time OR end_time IS NULL) ) OR ( ( CURRENT_TIME > start_time1 OR start_time1 IS NULL) AND ( CURRENT_TIME < end_time1 OR end_time1 IS NULL) ) ) and ((activeafter <= CURRENT_DATE or activeafter = '') and (activebefore >= CURRENT_DATE or activebefore = '')) and name like '%$R::srch%' and useflag=1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $title .= " Categories: ".($results->rows*1); while($ref = $results->fetchrow_hashref()) { $pluhtml .= qq~
    $ref->{name}
    ~; } $title .= "
    "; $pluhtml = $title.$pluhtml; $pluhtml .= "ason>>try { lastpos = 1; pos = 1; max = '$lastpos'; document.getElementById('row_'+lastpos).className = 'pl_normal'; document.getElementById('row_'+pos).className = 'pl_selected'; } catch(e) {}"; print $pluhtml; } elsif ($R::shortcut > 0) { $results = $dbh->prepare(" select * from menu where id = '$R::shortcut' ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $autoring = $ref->{autoring}; my $limitshortcuts = $ref->{limitshortcuts}; $pluhtml .= qq~
    Shortcuts for $ref->{name} ~; if (! $ref->{limitshortcuts}) { $pluhtml .= qq~| Ring All
    ~; } else { $pluhtml .= qq~| LIMIT: $ref->{limitshortcuts} items.~; } my $SQL = qq|select menu.*, menu.id id, short.returning from menu_shortcuts short, menu left join menu_schedules_details msd ON msd.schedule_id = menu.schedule_id and dayofweek(current_date) = msd.dayofweek where ( ( ( CURRENT_TIME > start_time OR start_time IS NULL) AND ( CURRENT_TIME < end_time OR end_time IS NULL) ) OR ( ( CURRENT_TIME > start_time1 OR start_time1 IS NULL) AND ( CURRENT_TIME < end_time1 OR end_time1 IS NULL) ) ) and ((activeafter <= CURRENT_DATE or activeafter = '') and (activebefore >= CURRENT_DATE or activebefore = '')) and menu.id=short.shortcut_to and short.menu_id='2084' and useflag = 1 order by short.ordering,menu.menu_category,menu.code,menu.name;|; #print $SQL;exit; $results = $dbh->prepare(" select menu.*, menu.id id, short.returning from menu_shortcuts short, menu left join menu_schedules_details msd ON msd.schedule_id = menu.schedule_id and dayofweek(current_date) = msd.dayofweek where ( ( ( CURRENT_TIME > start_time OR start_time IS NULL) AND ( CURRENT_TIME < end_time OR end_time IS NULL) ) OR ( ( CURRENT_TIME > start_time1 OR start_time1 IS NULL) AND ( CURRENT_TIME < end_time1 OR end_time1 IS NULL) ) ) and ((activeafter <= CURRENT_DATE or activeafter = '') and (activebefore >= CURRENT_DATE or activebefore = '')) and menu.id=short.shortcut_to and short.menu_id='$R::shortcut' and useflag = 1 order by short.ordering,menu.menu_category,menu.code,menu.name;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $pluhtml .= qq~
    ~; while($ref = $results->fetchrow_hashref()) { my $superplu = ""; if ($ref->{manager} == 1) { $superplu = "popup_su('superplu','');"; } else { $superplu = "plufunction();"; } if ($ref->{isshortcut} != 1) { my %holders = (1=> {2=>"s"}, 2=> {2=>"popup_instruction($ref->{id});"}); my $autoshort; if ($ref->{autoshort} == 1) { $autoshort = "shortcuts($ref->{id},$R::parent, $R::current);"; } if (! $limitshortcuts) { my ($ringml, $blinkml); if ($ref->{stockflag} == 1) { $ringml = qq~plufunction = function(){lastselectedplu='$ref->{id}';getbill($ref->{id});$holders{2}{$ref->{popable}}~.($ref->{returning} == 1 ? "getcat($R::parent, $R::current);$autoshort" : "$autoshort"); $ringml .= "};$superplu;"; } else { $ringml = "alertnostock()"; $blinkml = "text-decoration:blink;"; } $pluhtml .= qq~
    ~; if ($ref->{thumb}) { $pluhtml .= qq~~; } else { $pluhtml .= qq~$ref->{name}~; } $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="shortcuts($ref->{id},$R::parent, $R::current);"~ : '').qq~ class="plucol21~.($ref->{shortcutfor} > 0 ? 's' : '').qq~">
    ~; } else { my ($ringml, $blinkml); if ($ref->{stockflag} == 1) { $ringml = "plufunction = function(){lastselectedplu='$ref->{id}';ringlim($ref->{id});$holders{2}{$ref->{popable}}};$superplu;"; } else { $ringml = "alertnostock()"; $blinkml = "text-decoration:blink;"; } $pluhtml .= qq~
    ~; if ($ref->{thumb}) { $pluhtml .= qq~~; } else { $pluhtml .= qq~$ref->{name}~; } $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="shortcuts($ref->{id},$R::parent, $R::current);"~ : '').qq~ class="plucol21~.($ref->{shortcutfor} > 0 ? 's' : '').qq~">
    ~; } } else { if ($ref->{autoring} != 1 ) { $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="plufunction = function(){shortcuts($ref->{id},$R::parent, $R::current);};$superplu;"~ : '').qq~>
    $ref->{name}
    ~; } else { $pluhtml .= qq~
    {shortcutfor} > 0 ? qq~onMouseDown="plufunction = function(){ringall($ref->{id});};$superplu;"~ : '').qq~>
    $ref->{name}
    ~; } } } print $pluhtml; if ($limitshortcuts > 0) { print qq~ason>>setlim('$limitshortcuts');~; print qq~ shor_parent = '$R::parent'; shor_current = '$R::current';~; } } else { if ($session->param("~plumode") == 2) { print slurpfile($tdir."/adlkb.html"); print "ason>>try{document.getElementById('entry').focus();}catch(e){}"; } else { if ($R::favorite) { $results = $dbh->prepare("update waitron set favorite_category = ? where id = ?;") or die $dbh->errstr(); $results->execute( $R::category, $session->param("~set_user_id") ) or die $results->errstr(); $session->param("~set_user_favorite_category", $R::category); } $pluhtml .= qq~
    Please select a category
    ~; #~ $results = $dbh->prepare("select type #~ from tilltables where id = '$R::tid';") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ $ref = $results->fetchrow_hashref(); #~ if ($ref->{type} == 3) { $pluhtml .= qq~
    Select Customer
    ~; #~ } my $topcat = $session->param("~set_user_top_category"); $results = $dbh->prepare("select menu_categories.* from menu_categories left join menu_schedules_details msd ON msd.schedule_id = menu_categories.schedule_id and dayofweek(current_date) = msd.dayofweek where ( ( ( CURRENT_TIME > start_time OR start_time IS NULL) AND ( CURRENT_TIME < end_time OR end_time IS NULL) ) OR ( ( CURRENT_TIME > start_time1 OR start_time1 IS NULL) AND ( CURRENT_TIME < end_time1 OR end_time1 IS NULL) ) ) AND ((activeafter <= CURRENT_DATE or activeafter = '') and (activebefore >= CURRENT_DATE or activebefore = '')) and (parent_id = ?) and useflag=1 order by ordering, name") or die $dbh->errstr(); $results->execute($topcat) or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $pluhtml .= qq~
    $ref->{name}
    ~; } } print $pluhtml; } } elsif ($socketflag == 1 and $R::action eq "getbill" and $session->param("~set_logged_user")) { if ($R::setqm eq "on") { $session->param("~setqmode", 1); } elsif ($R::setqm eq "off") { $session->param("~setqmode", 0); } my %actionplus; my $property_totals; my $history; my $poleinfo; my $poledata; $history = undef; my $billhtml; my $ordercnt; my $itemcnt; my $error = ''; if ($R::getdb > 0) { $history->{latestsplit} = 0; #~ $R::getdb = $history->{tableops_id} if ($R::command eq "savedorders"); #get information on visitors and save in the temp file. Should use this temp file for all other persistant data $history->{tableops_id} = $R::getdb; $results = $dbh->prepare(" select tabops.visitors, tabops.table_id, tabops.client_id, cl.limited, cl.pricelist, cl.discountpercent from tilltableops tabops left join $sharedclients.tillclients cl on cl.id = tabops.client_id where tabops.id='$R::getdb' order by tabops.id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $history->{guests} = $ref->{visitors}; $history->{table_id} = $ref->{table_id}; $history->{client_id} = $ref->{client_id}; $history->{tabops_id} = $R::getdb; $history->{client_discount} = $ref->{discountpercent}; $history->{client_pricelist} = $ref->{pricelist}; $history->{client_limit_days} = $ref->{limited}; # RETREIVE - TOTALS FOR THIS CUSTOMER - opening balance if ($enable_proplim == 1 and $ref->{limited} > 0) { #verify for currently open count. $results = $dbh->prepare(" select concat(current_date, ' 00:00:00') dont_use_here_date, max(countstart) validate, date_add(max(countstart), interval ? day) > current_timestamp valid from tillclients_limitusage where customer_id = ?; ") or die $dbh->errstr(); $results->execute($history->{client_limit_days}, $history->{client_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $container_date; if ($ref->{valid}) { $container_date = $ref->{validate}; $results = $dbh->prepare(" select tlu.limiter_id, sum(tlu.transaction_qty) qty from tillclients_limitusage tlu, tillinvoices inv where inv.id = tlu.invoice and tlu.countstart = ? and (inv.voided =0 or inv.voided is null) and tlu.customer_id=? group by tlu.limiter_id; ") or die $dbh->errstr(); $results->execute($container_date, $history->{client_id}) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $history->{customer_limits}->{$ref->{limiter_id}} = $ref->{qty}; $property_totals->{$ref->{limiter_id}} = $ref->{qty}; } } } $results = $dbh->prepare("select * from tilltables where id='$history->{table_id}' order by id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $history->{tablenr} = $ref->{number}; #retreive tillorders & details my $results = $dbh->prepare("select *, unix_timestamp(current_timestamp) - unix_timestamp(stamp) AS duration, DATE_FORMAT(stamp, '%e / %m / %Y %H:%i') AS todsdate from tillorders where f_status<100 and tableops_id = '$R::getdb' order by id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { $subresults = $dbh->prepare(" select tods.*, inv.voided, menu.plu_weight, menu.qmatrix_id from tillordersdetails tods LEFT JOIN tillinvoices inv ON inv.id = tods.invoice LEFT JOIN menu ON menu.id = tods.plu where tods.orders_id = '$ref->{id}' order by tods.id ;") or die $dbh->errstr(); $subresults->execute() or die $results->errstr(); my $arraycount = 0; while($subref = $subresults->fetchrow_hashref()) { #to retreive voided here with a LEFT JOIN QUERY... TODO!!! my $ordid = $ref->{id}; $history->{order}->{$ordid}->{stage} = $ref->{confirm_status}; $history->{order}->{$ordid}->{mysqlid} = $ref->{id}; $history->{order}->{$ordid}->{timestamp} = $ref->{todsdate}; $history->{order}->{$ordid}->{duration} = $ref->{duration} || 0; my $property; my $limiter_id; my $usecategory; my $useqty = $subref->{qty} * 1; if ($enable_proplim == 1 and $history->{client_limit_days} > 0) { $subresults1 = $dbh->prepare(" select mpp.value, mpp.property_id, menu.limiter_id from menu_properties_properties mpp, menu, menu_properties_allowance mpa where mpp.menu_id = menu.id and menu.limiter_id = mpa.id and mpa.property_id = mpp.property_id and menu.id = ?; "); $subresults1->execute($subref->{plu}) or die $subresults1->errstr(); if (! $subref->{voided} ) { $subref1 = $subresults1->fetchrow_hashref(); $property = $subref1->{value}; $limiter_id = $subref1->{limiter_id}; } } $history->{tods_order}->{$subref->{id}} = $ordid; push @{$history->{order}->{$ordid}->{kids}}, { qty => $useqty, weight => $subref->{plu_weight}, matrix => $subref->{qmatrix_id}, name => (! $subref->{plu} ? "* $subref->{name}" : $subref->{name}), split => $subref->{split}, todsid => $subref->{id}, plu => $subref->{plu}, price => $subref->{price}, invoice => $subref->{invoice}, printer => $subref->{print_destination}, discount => $subref->{discount}, mysqlid => $subref->{id}, voided => $subref->{voided}, property => $property, property_total => $property * $useqty, limiter_id => $limiter_id }; if ($subref->{plu}) { #splitstatus flags; if ($subref->{invoice} > 0) { $history->{splitting}->{$subref->{split}}->{invoice} = 1; $history->{splitting}->{$subref->{split}}->{voided} = 1 if ($subref->{voided} > 0); } else { if ($subref->{invoice} == -12) { $history->{splitting}->{$subref->{split}}->{proforma} = 1; } else { $history->{splitting}->{$subref->{split}}->{nothing} = 1; } } $history->{latestsplit} = $subref->{split} if ( ! $subref->{invoice} and ! $subref->{voided} ) } $ordercnt = $ordid; } } $history->{latestsplit} = $history->{latestsplit} || 1; if ($results->rows > 0) { #always start next order if DB is not empty; $ordercnt ++; $history->{order}->{$ordercnt}->{stage} = 2; } } else { $history = readtmp($station_id); if ($enable_proplim == 1 and $history->{client_limit_days} > 0 ) { foreach my $limiter_id (keys %{$history->{customer_limits}}) { $property_totals->{$limiter_id} = $history->{customer_limits}->{$limiter_id}; } } $results = $dbh->prepare(" select waitron_id from tilltableops where id = ? ;") or die $dbh->errstr(); $results->execute($history->{tableops_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($session->param("~set_user_id") != $ref->{waitron_id}) { $results = $dbh->prepare(" select * from waitron where id = ? ;") or die $dbh->errstr(); $results->execute($ref->{waitron_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $error = $ref->{name}; } } if ($error) { print qq~ason>>GB_mess("TRANSFER: TABLE NOW BELONGS TO $error",1, "window.location='index.cgi?action=tables&error=transfer'");~; return; } #initial order my $lastorderid = (reverse sort {$a <=> $b} keys %{$history->{order}})[0]; $ordercnt = $lastorderid || 1; #~ $billhtml .= qq~ #~
    #~ ~; # 1 - on hold, 2 - confirmed (temporary), 3 - placed - read only # add a last order - always onhold #to change $history->{order}->{$ordercnt}->{stage} = 2 if (! $history->{order}->{$ordercnt}->{stage}); my $nobarcodefound = 0; my $noplufound = 0; if ($R::biid ne '') { $results = $dbh->prepare(" select * from menu where barcode = '$R::biid' and useflag = 1 and scalecode = 2 limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $R::iid = $ref->{id}; if (! $R::iid) { my $bcode = $R::biid; my $sb_code = substr($bcode,0,6); my $sb_pric = reverse ( substr( (reverse $bcode), 1,6) ); $results = $dbh->prepare(" select * from menu where barcode = '$sb_code' and useflag = 1 and scalecode = 1 limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $R::iid = $ref->{id}; if ($R::iid) { $R::sb_code = $sb_code; $R::sb_pric = $sb_pric / 100; } } $nobarcodefound = 1 if (! $R::iid); } else { $nobarcodefound = 0; } if ($R::piid > 0) { $results = $dbh->prepare(" select * from menu where code = '$R::piid' and useflag = 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $R::iid = $ref->{id}; $noplufound = 1 if (! $R::iid); } else { $noplufound = 0; } if ($settings::plugrouping == 1 && $R::iid && ! $R::sb_code) { #&& ! $R::biid - check with ADL my $lastplu = scalar @{$history->{order}->{$ordercnt}->{kids}} - 1; if (scalar @{$history->{order}->{$ordercnt}->{kids}} > 0) { #search for PLU #~ while (! ${$history->{order}->{$ordercnt}->{kids}}[$lastplu]->{plu}) { $lastplu --; } if ( ${$history->{order}->{$ordercnt}->{kids}}[$lastplu]->{plu} == $R::iid ) { $R::iid = ''; my $useqty; if ($R::pqty != 0) { $useqty = $R::pqty; } else { $useqty = 1; } $R::qty = ${$history->{order}->{$ordercnt}->{kids}}[$lastplu]->{qty} + ($useqty); my $name = ${$history->{order}->{$ordercnt}->{kids}}[$lastplu]->{name}; my $price = ${$history->{order}->{$ordercnt}->{kids}}[$lastplu]->{price}; $poledata->{1} = substr($R::qty."x".$name,0,20); $poledata->{2} = $price; } } } #undo if ($R::undo) { my $temp = pop @{$history->{order}->{$ordercnt}->{kids}}; $actionplus{$temp->{matrix}} = 1 if ($temp->{matrix}); } elsif ($R::clrbill > 0) { foreach my $tmp ( sort {$a <=> $b} keys %{ $history->{order} } ) { next if (! $history->{order}->{$tmp}->{mysqlid}); if ($history->{order}->{$tmp}->{mysqlid} > 0) { foreach my $kid (@{ $history->{order}->{$tmp}->{kids} }) { if ($kid->{invoice} eq '') { $subresults = $dbh->prepare(" delete from tillordersdetails where id = ? "); $subresults->execute($kid->{todsid}) or die $subresults->errstr(); } } $subresults = $dbh->prepare(" select count(*) cnt from tillordersdetails where orders_id = ? "); $subresults->execute($history->{order}->{$tmp}->{mysqlid}) or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); if (! $subref->{cnt}) { #~ $nomoreorders = 1; $subresults = $dbh->prepare(" delete from tillorders where id = ? "); $subresults->execute($history->{order}->{$tmp}->{mysqlid}) or die $subresults->errstr(); } } } delete $history->{order}; $ordercnt = 1; $history->{order}->{$ordercnt}->{stage} = 2 if (! $history->{order}->{$ordercnt}->{stage}); } elsif ($R::delitem ne '') { my @kidsarray; my $searchmode; my $clicked_plu; my $kids_order; my @tmp; if ($R::delitem =~ /pp(\d+|\d)/i) { $kids_order = $history->{tods_order}->{$1}; @kidsarray = @{$history->{order}->{$kids_order}->{kids}}; $searchmode = 2; $clicked_plu = $1; } elsif ($R::delitem =~ /^(\d+|\d)/i) { @kidsarray = @{$history->{order}->{$ordercnt}->{kids}}; $searchmode = 1; $clicked_plu = $R::delitem; } elsif ($R::delitem =~ /pi(\d+|\d)/i) { $kids_order = $history->{tods_order}->{$1}; @kidsarray = @{$history->{order}->{$kids_order}->{kids}}; $searchmode = 2; $clicked_plu = $1; } #~ open (DDD,">>/debby.deb"); #~ print DDD "delplu: $clicked_plu\n"; #~ close (DDD); my $nomoreorders; foreach my $kiddie (@kidsarray) { $actionplus{$kiddie->{matrix}} = 1 if ($kiddie->{matrix}); if ( ($kiddie->{itemcnt} != $clicked_plu and $searchmode == 1) or ($kiddie->{todsid} != $clicked_plu and $searchmode == 2) ) { push @tmp, $kiddie; } elsif ($kiddie->{todsid} == $clicked_plu and $searchmode == 2) { $subresults = $dbh->prepare(" delete from tillordersdetails where id = ? "); $subresults->execute($clicked_plu) or die $subresults->errstr(); $subresults = $dbh->prepare(" select count(*) cnt from tillordersdetails where orders_id = ? "); $subresults->execute($kids_order) or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); if (! $subref->{cnt}) { $nomoreorders = 1; $subresults = $dbh->prepare(" delete from tillorders where id = ? "); $subresults->execute($kids_order) or die $subresults->errstr(); } } } #~ pop @{$history->{order}->{$ordercnt}->{kids}}; if ($searchmode == 2) { @{$history->{order}->{$kids_order}->{kids}} = @tmp; } else { @{$history->{order}->{$ordercnt}->{kids}} = @tmp; } delete $history->{order}->{$kids_order} if ($nomoreorders); } elsif ($R::price ne "" and $R::clicked_plu ne '') { my @tmp; my @kidsarray; my $searchmode; my $clicked_plu; my $kids_order; if ($R::clicked_plu =~ /pp(\d+|\d)/i) { $kids_order = $history->{tods_order}->{$1}; @kidsarray = @{$history->{order}->{$kids_order}->{kids}}; $searchmode = 2; $clicked_plu = $1; } else { @kidsarray = @{$history->{order}->{$ordercnt}->{kids}}; $searchmode = 1; $clicked_plu = $R::clicked_plu; } foreach my $kiddie (@kidsarray) { if ( ($kiddie->{itemcnt} == $clicked_plu and $searchmode == 1) or ($kiddie->{todsid} == $clicked_plu and $searchmode == 2) ) { my $original_plu_price; my $original_plu_discount; my $plu_id = $kiddie->{plu}; my $current_qty = $kiddie->{qty}; $subresults = $dbh->prepare(" select orgprice,discount,code,name from menu where id = ?; "); $subresults->execute($kiddie->{plu}) or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $original_plu_price = $subref->{orgprice}; $original_plu_discount = $subref->{discount}; #log if ($R::rsn && $R::suser) { my $till_id = $profile->{station_id}; $subresults = $dbh->prepare(" insert into supervisorlog (supervisor, reason, stamp, supervisingwhat, transaction_case, transaction_id, terminal_id, user, plu) values (?, ?, current_timestamp, ?, ?, ?, ?, ?,?) ") or die $dbh->errstr(); $subresults->execute($R::suser, $R::rsn, 'PRICE OVERRIDE', "Ovirride $original_plu_price to $R::price for PLU: $subref->{name} (SKU: $subref->{code})",$history->{tabops_id},$till_id,$session->param("~set_user_id"),$kiddie->{plu} ) or die $subresults->errstr(); } if ($R::price > $original_plu_price) { #$R::price = $_->{price} $kiddie->{price} = $R::price; $kiddie->{discount} = 0; } else { $kiddie->{price} = $original_plu_price; $kiddie->{discount} = $original_plu_price - $R::price; } if ($searchmode == 2) { $subresults = $dbh->prepare(" update tillordersdetails set price = ?, discount = ? where id = ? "); $subresults->execute($kiddie->{price},$kiddie->{discount},$clicked_plu) or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); } } push @tmp, $kiddie; } #~ pop @{$history->{order}->{$ordercnt}->{kids}}; if ($searchmode == 2) { @{$history->{order}->{$kids_order}->{kids}} = @tmp; } else { @{$history->{order}->{$ordercnt}->{kids}} = @tmp; } } elsif ($R::qty != 0 and $R::clicked_plu ne '') { { my @tmp; my @kidsarray; my $searchmode; my $clicked_plu; my $kids_order; if ($R::clicked_plu =~ /pp(\d+|\d)/i) { $kids_order = $history->{tods_order}->{$1}; @kidsarray = @{$history->{order}->{$kids_order}->{kids}}; $searchmode = 2; $clicked_plu = $1; } else { @kidsarray = @{$history->{order}->{$ordercnt}->{kids}}; $searchmode = 1; $clicked_plu = $R::clicked_plu; } foreach my $kiddie (@kidsarray) { if ( ($kiddie->{itemcnt} == $clicked_plu and $searchmode == 1) or ($kiddie->{todsid} == $clicked_plu and $searchmode == 2) ) { if ($kiddie->{qty} < 0) { $R::qty *= -1 } if ($R::isprice) { $results = $dbh->prepare("select orgprice from menu where id = ?;") or die $dbh->errstr(); $results->execute( $kiddie->{plu} ) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $R::qty = sprintf("%.3f",$R::qty / $ref->{orgprice}) if ($ref->{orgprice}); } if ($searchmode == 2) { $subresults = $dbh->prepare(" update tillordersdetails set qty = ? where id = ? "); $subresults->execute($R::qty,$clicked_plu) or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); } $actionplus{$kiddie->{matrix}} = 1 if ($kiddie->{matrix}); $kiddie->{qty} = $R::qty; my $plu_id = $kiddie->{plu}; my $name = $kiddie->{name}; my $price = $kiddie->{price}; $poledata->{1} = substr($R::qty."x".$name,0,20); $poledata->{2} = $price; if ($enable_proplim and $history->{client_limit_days} > 0) { $kiddie->{property_total} = $kiddie->{property} * $kiddie->{qty} } } push @tmp, $kiddie; } #~ pop @{$history->{order}->{$ordercnt}->{kids}}; if ($searchmode == 2) { @{$history->{order}->{$kids_order}->{kids}} = @tmp; } else { @{$history->{order}->{$ordercnt}->{kids}} = @tmp; } } } elsif ($R::qty != 0 and ! $R::clicked_plu) { my $lastplu = scalar @{$history->{order}->{$ordercnt}->{kids}} - 1; if (scalar @{$history->{order}->{$ordercnt}->{kids}} > 0) { #search for PLU while (! ${$history->{order}->{$ordercnt}->{kids}}[$lastplu]->{plu}) { $lastplu --; } if ($R::isprice) { $results = $dbh->prepare("select orgprice from menu where id = ?;") or die $dbh->errstr(); $results->execute( ${$history->{order}->{$ordercnt}->{kids}}[$lastplu]->{plu} ) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $R::qty = sprintf("%.3f",$R::qty / $ref->{orgprice}) if ($ref->{orgprice}); } if (${$history->{order}->{$ordercnt}->{kids}}[$lastplu]->{qty} < 0 and $R::pqty * 1 == 0) { $R::qty *= -1 } ${$history->{order}->{$ordercnt}->{kids}}[$lastplu]->{qty} = $R::qty; my $kiddie = ${$history->{order}->{$ordercnt}->{kids}}[$lastplu]; my $name = $kiddie->{name}; my $price = $kiddie->{price}; $poledata->{1} = substr($R::qty."x".$name,0,20); $poledata->{2} = $price; if ($enable_proplim and $history->{client_limit_days} > 0) { $kiddie->{property_total} = $kiddie->{property} * $kiddie->{qty}; } $actionplus{$kiddie->{matrix}} = 1 if ($kiddie->{matrix}); } } elsif ($R::delete && $history->{order}->{$R::delete}->{stage} < 3) { ##cxxxx if ( scalar @{ $history->{order}->{$R::delete}->{kids} } ) { my $deleted = "true"; if ($history->{order}->{$R::delete}->{mysqlid} > 0) { $deleted = "false"; $results = $dbh->prepare(" select * from tillorders where id = ? ;") or die $dbh->errstr(); $results->execute($history->{order}->{$R::delete}->{mysqlid}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{confirm_status} == 1) { #delete this entry from db $results = $dbh->prepare(" delete from tillordersdetails where orders_id = ? ;") or die $dbh->errstr(); $results->execute($history->{order}->{$R::delete}->{mysqlid}) or die $results->errstr(); $results = $dbh->prepare(" delete from tillorders where id = ? ;") or die $dbh->errstr(); $results->execute($history->{order}->{$R::delete}->{mysqlid}) or die $results->errstr(); $deleted = "true"; } } if ($deleted eq "true") { delete $history->{order}->{$R::delete}; if (! scalar keys %{$history->{order}}) { $ordercnt = 1; $history->{order}->{$ordercnt}->{stage} = 2; } my $lastorderid = (reverse sort {$a <=> $b} keys %{$history->{order}})[0]; my $lastpluitemmysqlid; if ( scalar @{$history->{order}->{$lastorderid}->{kids}} > 0 ) { $lastpluitemmysqlid = @{$history->{order}->{$lastorderid}->{kids}}[0]->{mysqlid}; } if ($lastpluitemmysqlid > 0) { $ordercnt ++; $history->{order}->{$ordercnt}->{stage} = 2 } } } } elsif ($R::addorder) { #add order if ( scalar @{ $history->{order}->{$ordercnt}{kids} } ) { $ordercnt++; $history->{order}->{$ordercnt}->{stage} = 2; } else { #print "ERROR: empty order
    "; } } $itemcnt = $history->{currentitemcnt}; if ($R::recall_onhold ne '') { $results = $dbh->prepare(" select tods.*, menu.shortname, menu.plu_weight, menu.qmatrix_id from tillorders tod, tillonholds holds, tillordersdetails tods, menu where tod.tableops_id = holds.tableops_id and holds.id = ? and tods.orders_id = tod.id and menu.id = tods.plu; ;") or die $dbh->errstr(); $results->execute($R::recall_onhold) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $itemtxt = substr($ref->{shortname}, 0, 19); $poledata->{1} = substr($ref->{qty}."x".$itemtxt,0,20); $poledata->{2} = $ref->{price}; my $displaytxt = substr($ref->{shortname}, 0, 30); $itemtxt .= " "x(38 - length( $ref->{price}) - length( $itemtxt ) ); $itemtxt .= "$ref->{price}"; $itemcnt ++; $history->{currentitemcnt} = $itemcnt; $actionplus{$ref->{qmatrix_id}} = 1 if ($ref->{qmatrix_id}); push @{$history->{order}->{$ordercnt}->{kids}}, { matrix => $ref->{qmatrix_id}, weight => $ref->{plu_weight}, qty => $ref->{qty}*1, name => $displaytxt, split => $history->{latestsplit} || 1, plu => $ref->{plu}, price => $ref->{price}, print_destination => $ref->{print_destination}, discount => $ref->{discount}, itemcnt => $itemcnt, }; $history->{splitting}->{1}->{nothing} = 1; $history->{lastprinter} = $ref->{print_destination}; } } elsif ($R::recall ne '') { #~ $results = $dbh->prepare(" #~ select * from tillinvoices where id = '$R::recall' #~ ;") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ $ref = $results->fetchrow_hashref(); if ($R::recall !~ /\_/) { $results = $dbh->prepare(" select tods.*, menu.shortname, menu.plu_weight, menu.qmatrix_id from tillordersdetails tods, menu where tods.invoice = ? and menu.id = tods.plu ;") or die $dbh->errstr(); $results->execute($R::recall) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $itemtxt = substr($ref->{shortname}, 0, 19); $poledata->{1} = substr($ref->{qty}."x".$itemtxt,0,20); $poledata->{2} = $ref->{price}; my $displaytxt = substr($ref->{shortname}, 0, 30); $itemtxt .= " "x(38 - length( $ref->{price}) - length( $itemtxt ) ); $itemtxt .= "$ref->{price}"; $itemcnt ++; $history->{currentitemcnt} = $itemcnt; $actionplus{$ref->{qmatrix_id}} = 1 if ($ref->{qmatrix_id}); push @{$history->{order}->{$ordercnt}->{kids}}, { matrix => $ref->{qmatrix_id}, weight => $ref->{plu_weight}, qty => $ref->{qty}*1, name => $displaytxt, split => $history->{latestsplit} || 1, plu => $ref->{plu}, price => $ref->{price}, print_destination => $ref->{print_destination}, discount => $ref->{discount}, itemcnt => $itemcnt, recall => 1 }; $history->{splitting}->{1}->{nothing} = 1; $history->{lastprinter} = $ref->{print_destination}; } } else { while ($R::recall =~ /\_(\d+)/g) { my $lineitem_id = $1; $results = $dbh->prepare(" select tods.*, menu.shortname, menu.plu_weight, menu.qmatrix_id from tillordersdetails tods, menu where tods.id = ? and menu.id = tods.plu ;") or die $dbh->errstr(); $results->execute($lineitem_id) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $itemtxt = substr($ref->{shortname}, 0, 19); $poledata->{1} = substr($ref->{qty}."x".$itemtxt,0,20); $poledata->{2} = $ref->{price}; my $displaytxt = substr($ref->{shortname}, 0, 30); $itemtxt .= " "x(38 - length( $ref->{price}) - length( $itemtxt ) ); $itemtxt .= "$ref->{price}"; $itemcnt ++; $history->{currentitemcnt} = $itemcnt; $actionplus{$ref->{qmatrix_id}} = 1 if ($ref->{qmatrix_id}); push @{$history->{order}->{$ordercnt}->{kids}}, { matrix => $ref->{qmatrix_id}, weight => $ref->{plu_weight}, qty => $ref->{qty}*1, name => $displaytxt, split => $history->{latestsplit} || 1, plu => $ref->{plu}, price => $ref->{price}, print_destination => $ref->{print_destination}, discount => $ref->{discount}, itemcnt => $itemcnt, recall => 1 }; $history->{splitting}->{1}->{nothing} = 1; $history->{lastprinter} = $ref->{print_destination}; } } } } elsif ($R::ringall > 0) { $results = $dbh->prepare(" select menu.*, menu.id id, short.returning returning, short.shoqty from menu_shortcuts short, menu left join menu_schedules_details msd ON msd.schedule_id = menu.schedule_id and dayofweek(current_date) = msd.dayofweek where ( ( ( CURRENT_TIME > start_time OR start_time IS NULL) AND ( CURRENT_TIME < end_time OR end_time IS NULL) ) OR ( ( CURRENT_TIME > start_time1 OR start_time1 IS NULL) AND ( CURRENT_TIME < end_time1 OR end_time1 IS NULL) ) ) and ((activeafter <= CURRENT_DATE or activeafter = '') and (activebefore >= CURRENT_DATE or activebefore = '')) and menu.id=short.shortcut_to and short.menu_id=? and useflag = 1 order by short.ordering,menu.menu_category,menu.code,menu.name; ;") or die $dbh->errstr(); $results->execute($R::ringall) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $fcqty = $ref->{mqty}; $fcqty = 1 if ($fcqty == 0); $ref->{shoqty} = 1 if ($ref->{shoqty} == 0); $fcqty *= $ref->{shoqty}; #~ open(ddd,">>/ddd.ddd"); #~ print ddd Dumper($history); #~ close ddd; $actionplus{$ref->{qmatrix_id}} = 1 if ($ref->{qmatrix_id}); my $itemtxt = substr($ref->{shortname}, 0, 19); my $poleqty = $fcqty; $poledata->{1} = substr($poleqty."x".$itemtxt,0,20); $poledata->{2} = $ref->{price}; my $displaytxt = substr($ref->{shortname}, 0, 30); $itemtxt .= " "x(38 - length( $ref->{price}) - length( $itemtxt ) ); $itemtxt .= "$ref->{orgprice}"; $itemcnt ++; $history->{currentitemcnt} = $itemcnt; my $useprice = $ref->{orgprice}; my $usediscount = $ref->{discount}; if ($enable_pmatrix == 1) { if ($history->{client_id} > 0) { #eventual override $subresults = $dbh->prepare("SELECT * FROM $sharedclients.tillclients where id='$history->{client_id}';"); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); if ($subref->{pricelist} > 0) { $subresults = $dbh->prepare("SELECT * FROM menu_pricelists_details where menu_id='$ref->{id}' and pricelist_id = '$subref->{pricelist}';"); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $useprice = $subref->{price}; $usediscount = $subref->{discount}; } } } $actionplus{$ref->{qmatrix_id}} = 1 if ($ref->{qmatrix_id}); push @{$history->{order}->{$ordercnt}->{kids}}, { matrix => $ref->{qmatrix_id}, weight => $ref->{plu_weight}, qty => $fcqty, name => $displaytxt, split => $history->{latestsplit} || 1, plu => $ref->{id}, price => $useprice, print_destination => $ref->{print_destination}, discount => $usediscount, itemcnt => $itemcnt }; $history->{splitting}->{1}->{nothing} = 1; $history->{lastprinter} = $ref->{print_destination}; } } elsif ($R::iid > 0) { $results = $dbh->prepare(" select * from menu where id = ? ;") or die $dbh->errstr(); $results->execute($R::iid) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $actionplus{$ref->{qmatrix_id}} = 1 if ($ref->{qmatrix_id}>0); if ($R::pqty == 0 or $R::pqty eq '') { $R::pqty = $ref->{mqty}; #### READ FROM Consel 2022 } my $itemtxt = substr($ref->{shortname}, 0, 19); my $displaytxt = substr($ref->{shortname}, 0, 30); $itemtxt = ''; $itemtxt .= " "x(38 - length( $ref->{orgprice}) - length( $itemtxt ) ); $itemtxt .= qq~$ref->{orgprice}~; $itemcnt ++; $history->{currentitemcnt} = $itemcnt; my $useprice = $ref->{orgprice}; my $usediscount = $ref->{discount}; if ($enable_pmatrix == 1 && ! $R::sb_code) { if ($history->{client_id} > 0) { #eventual override $subresults = $dbh->prepare("SELECT * FROM $sharedclients.tillclients where id='$history->{client_id}';"); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); if ($subref->{pricelist} > 0) { $subresults = $dbh->prepare("SELECT * FROM menu_pricelists_details where menu_id='$ref->{id}' and pricelist_id = '$subref->{pricelist}';"); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $useprice = $subref->{price}; $usediscount = $subref->{discount}; } } } my $property; my $limiter_id; my $useqty; if ($R::pqty != 0) { $useqty = $R::pqty; } else { $useqty = 1; }; if ($R::sb_code) { $useqty = sprintf("%.3f",$R::sb_pric / $useprice)*1 if ($useprice); #$useprice = $R::sb_pric; #$useprice = $useprice * $useqty; } my $poleqty = $useqty; $poledata->{1} = substr($poleqty."x".substr($ref->{shortname},0,20),0,20); $poledata->{2} = $useprice; if ($enable_proplim and $history->{client_limit_days} > 0) { $subresults = $dbh->prepare(" select mpp.value, mpp.property_id, menu.limiter_id from menu_properties_properties mpp, menu, menu_properties_allowance mpa where mpp.menu_id = menu.id and menu.limiter_id = mpa.id and mpa.property_id = mpp.property_id and menu.id = $ref->{id}; "); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $property = $subref->{value}; $limiter_id = $subref->{limiter_id}; } push @{$history->{order}->{$ordercnt}->{kids}}, { matrix => $ref->{qmatrix_id}, weight => $ref->{plu_weight}, qty => $useqty, name => $displaytxt, split => $history->{latestsplit} || 1, plu => $ref->{id}, price => $useprice, print_destination => $ref->{print_destination}, discount => $usediscount, itemcnt => $itemcnt, property => $property, property_total => $property * $useqty, limiter_id => $limiter_id }; $history->{splitting}->{1}->{nothing} = 1; #temporary - prototype - plu - just HTML #~ $history->{ttt} .= #~ qq~ #~
    #~
    1 x $ref->{shortname}
    #~
    1
    #~
    $ref->{orgprice}
    #~
    #~ ~; $history->{lastprinter} = $ref->{print_destination}; } elsif ($R::instru) { $itemcnt ++; $history->{currentitemcnt} = $itemcnt; push @{$history->{order}->{$ordercnt}->{kids}}, { qty => "", name => "* ($R::instru)", split => "1", # must carry the split of it's master - for now it's 1 plu => "0", print_destination =>$history->{lastprinter}, price => "-", itemcnt => $itemcnt } #temporary - prototype - instruction #~ $history->{ttt} .= #~ qq~ #~
    #~
    * $R::instru
    #~
    -
    #~
    -
    #~
    #~ ~; } ## ## ### ######## ######## #### ## ## ### ### ## ## ## ## ## ## ## ## #### #### ## ## ## ## ## ## ## ## ## ### ## ## ## ## ######## ## ### ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## #### P R I C E M A T R I X #### my $weightsum; my $currentprice; #price matrix if ( $enable_pmatrix == 1 && (! $history->{client_id} || ! $history->{client_pricelist} ) ) { if (scalar %actionplus) { #~ print Dumper(\%actionplus); #generate SUM of QTY for all items foreach my $orderid (sort {$a <=> $b} keys %{$history->{order}}) { foreach my $kidref ( @{ $history->{order}->{$orderid}->{kids} } ) { if ($kidref->{plu} > 0) { $weightsum->{$kidref->{matrix}} += $kidref->{qty} * $kidref->{weight}; #~ $qtysum->{$kidref->{plu}}->{qtysum} += $kidref->{qty}; $currentprice->{$kidref->{plu}}->{price} = $kidref->{price}; $currentprice->{$kidref->{plu}}->{discount} = $kidref->{discount}; } } } #~ print Dumper(\$weightsum); my $new_unit_prices; #~ print Dumper(\%actionplus); foreach my $matrix_id (keys %actionplus) { my $myqty = $weightsum->{$matrix_id}; $subresults = $dbh->prepare(" select mqpc.*, menu.id plu from menu_qty_price_conditions mqpc, menu where mqpc.qty_matrix_id = ? and menu.qmatrix_id = mqpc.qty_matrix_id and (mqpc.qty_start <= ? and ? <= mqpc.qty_end); "); $subresults->execute($matrix_id,$myqty,$myqty) or die $subresults->errstr(); #there is a price in this bracket if ($subresults->rows) { while ($subref = $subresults->fetchrow_hashref()) { $results = $dbh->prepare(" select mpd.price, mpd.discount, menu.id from menu_pricelists_details mpd, menu where menu.id = mpd.menu_id and mpd.pricelist_id = ? and menu.id = ? "); $results->execute($subref->{plist_id}, $subref->{plu} ) or die $subresults->errstr(); while ($ref = $results->fetchrow_hashref()) { my $pluid = $ref->{id}; $new_unit_prices->{$pluid}->{price} = $ref->{price}; $new_unit_prices->{$pluid}->{discount} = $ref->{discount}; } } } else { $results = $dbh->prepare(" select orgprice price, discount, id from menu where qmatrix_id = ? "); $results->execute($matrix_id) or die $subresults->errstr(); while ($ref = $results->fetchrow_hashref()) { my $pluid = $ref->{id}; $new_unit_prices->{$pluid}->{price} = $ref->{price}; $new_unit_prices->{$pluid}->{discount} = $ref->{discount}; } } } #~ print Dumper(\$new_unit_prices); #apply Price Matrix - for all plu items affected; foreach my $orderid (sort {$a <=> $b} keys %{$history->{order}}) { foreach my $kidref ( @{ $history->{order}->{$orderid}->{kids} } ) { my $pluid = $kidref->{plu}; if ( ( $currentprice->{$pluid}->{price} != $new_unit_prices->{$pluid}->{price} ) or ( $currentprice->{$pluid}->{discount} != $new_unit_prices->{$pluid}->{discount} ) ) { if ($kidref->{recall} != 1 and (defined $new_unit_prices->{$pluid}->{price} or defined $new_unit_prices->{$pluid}->{discount}) ) { $kidref->{price} = $new_unit_prices->{$kidref->{plu}}->{price}; $kidref->{discount} = $new_unit_prices->{$kidref->{plu}}->{discount}; if ($kidref->{todsid} > 0) { $subresults = $dbh->prepare("update tillordersdetails set price = ?, discount = ? where id = ?"); $subresults->execute($kidref->{price}, $kidref->{discount}, $kidref->{todsid}) or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); } } } # main if } # all children } # all orders #~ open (DDD, ">/DDD_3"); #~ print DDD Dumper($history); #~ close DDD; } } #~ print Dumper(\$qtysum); ######## ## ## ### ######## ######## #### ## ## ## ### ### ## ## ## ## ## ## ## ## ## #### #### ## ## ## ## ## ## ## ## ###### ## ### ## ## ## ## ######## ## ### ## ## ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######## ####### ## ## ## ## ## ## ## #### ## ## #restore - visualy; #$history->{order}->{$ordercnt}->{stage} = 1; #Display in Browser - virtual bill my $seconddisplay; $seconddisplay = "{ 'linedata' : ["; foreach my $orderid (sort {$a <=> $b} keys %{$history->{order}}) { my $stage = $history->{order}->{$orderid}->{stage}; if ($R::alterstage == $orderid) { if ($history->{order}->{$orderid}->{mysqlid} > 0) { #point of truth $results = $dbh->prepare(" select * from tillorders where id = ? ;") or die $dbh->errstr(); $results->execute($history->{order}->{$orderid}->{mysqlid}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($stage != 2) { $stage = $ref->{confirm_status}; } } if ($stage == 2) { $stage = 1 } elsif ($stage == 1) { $stage = 2 } #flip stages in temp file $history->{order}->{$orderid}->{stage} = $stage; } my $orderduration = (stringtimeshort($history->{order}->{$orderid}->{duration})); my %stages = ( 1 => qq~
    ~, 2 => qq~
    ~, 3 => qq~
    $history->{order}->{$orderid}->{timestamp} - $orderduration ago
    ~ ); if ($plu_line_size == 2) { $billhtml .= "
    "; } $billhtml .= $stages{$stage}; foreach my $kidref ( @{ $history->{order}->{$orderid}->{kids} } ) { if ($kidref->{plu} > 0) { my $style; if ($kidref->{voided} == 1) { $style = "void"; } elsif ($kidref->{voided} == 2) { $style = "void-return"; } elsif ($kidref->{invoice} > 0) { $style = "paid"; } elsif ($kidref->{invoice} == -12) { $style = "proforma"; } else { if ($kidref->{itemcnt} > 0) { $style = "norm-new"; } else { $style = "norm"; } } if ($plu_line_size == 2) { $style = "s2_".$style; } my $onclick; my $idprefix; if ($kidref->{itemcnt} > 0) { $onclick = qq~onclick = "pluclick('$kidref->{itemcnt}','$kidref->{plu}')"~; $idprefix = "p_$kidref->{itemcnt}"; } elsif ($screenmode == 2 and $settings::orderchange == 1) { $onclick = qq~ onclick = "pluclick('pp$kidref->{todsid}','$kidref->{plu}')"~; $idprefix = "p_pp$kidref->{todsid}"; } elsif ($screenmode != 2 and $kidref->{itemcnt} <= 0 ) { # PLU cloning if ($settings::allowclone > 0) { $onclick = qq~onclick = "getbill('$kidref->{plu}',1);"~; } else { } } $billhtml .= qq~
    ~.($settings::voidenable == 1 ? "$kidref->{qty} x " : '').qq~$kidref->{name}
    ~.($settings::voidenable == 1 ? $kidref->{split} : $kidref->{qty}).qq~
    ~.(pr( ($kidref->{price} - $kidref->{discount})*$kidref->{qty})).qq~
    ~; my $krefname = $kidref->{name}; $krefname =~ s/\'/\\'/gsi; $seconddisplay .= " {'q' : '$kidref->{qty}','i' : '$krefname','t' : '".(pr( ($kidref->{price} - $kidref->{discount})*$kidref->{qty}))."'},"; } else { my $onclick; my $style = "norm"; if ($plu_line_size == 2) { $style = "s2_".$style; } my $idprefix; if ($kidref->{itemcnt} > 0) { $onclick = qq~onclick = "pluclick('$kidref->{itemcnt}','$kidref->{plu}')"~; $idprefix = "p_"; } elsif ($screenmode == 2 and $settings::orderchange == 1) { $onclick = qq~onclick = "pluclick('pi$kidref->{todsid}','$kidref->{plu}')"~; $idprefix = "p_pi"; } $billhtml .= qq~
    $kidref->{name}
    -
    -
    ~; } } } $seconddisplay .= "]}"; #-------------------------------------------------- my @confirmeditems; if ($R::command eq 'saveorders') { #the real thing my $tmprn; my %tmprns; my $till_id = $station_id; my $waitron_id = $session->param("~set_user_id"); my $table_nr = $history->{tablenr}; my $tableops_id = $history->{tableops_id}; my $current_covers = $history->{guests}; #don't print and save my $falseflag = 0; $results = $dbh->prepare("SELECT tto.action action, client_id from tilltableops tto, tilltables tt where tto.table_id=tt.id and tt.number = '$table_nr' order by tto.id desc limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $client_id = $ref->{client_id}; my $clientprint; if ($ref->{action} == 2) {$falseflag = 1} my $printstatus = 1; if (! $falseflag) { if ($client_id) { $results = $dbh->prepare("select * from $sharedclients.tillclients where id = '$client_id';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $clientprint = $ps{minuses}."\n"; $clientprint .= "CUSTOMER: $ref->{name}\n"; $clientprint .= "ADDRESS: [1] $ref->{ph_address} [2] $ref->{ph_address1} [3] $ref->{ph_address2} [4] $ref->{ph_address3} \n" if ($ref->{ph_address} ne ''); $clientprint .= "T: $ref->{telephone} " if ($ref->{telephone}); $clientprint .= "M: $ref->{cellphone}" if ($ref->{cellphone}); $clientprint .= "\n"; } my $lastorderid; #waitron $results = $dbh->prepare("SELECT * from waitron where id='$waitron_id';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $waitron = $ref->{name}; my $demomode; $demomode = 1 if ($waitron =~ /!DEMO!/sgi); foreach my $orderid (sort {$a <=> $b} keys %{$history->{order}}) { if (! $history->{order}->{$orderid}->{mysqlid}) { # insert the new orders my $confirm_status = $history->{order}->{$orderid}->{stage}; # $orders->att('confirm'); #my $SQL = "INSERT into tillorders #(stamp,shop_id,till_id,waitron_id,tableops_id,confirm_status) #values #(CURRENT_TIMESTAMP,$shop{id}, '$till_id', '$waitron_id', '$tableops_id', '$confirm_status');"; #logit($SQL); my $results = $dbh->prepare("INSERT into tillorders (stamp,shop_id,till_id,waitron_id,tableops_id,confirm_status) values (CURRENT_TIMESTAMP,$shop{id}, '$till_id', '$waitron_id', '$tableops_id', '$confirm_status');") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results->finish(); #imediately $results = $dbh->prepare("SELECT LAST_INSERT_ID() lastid FROM tillorders limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $orders_id = $ref->{lastid}; $lastorderid = $orders_id; # time to create the new order details #print "\n DEBUG: NEW ORDER $lastorderid"; foreach my $kidref ( @{ $history->{order}->{$orderid}->{kids} } ) { # foreach my $plus ($orders->children('plu')) { my ($plutype, $local_name, $menusource, $plu_id, $price, $discount, $printer, $thename, $theqty, $thesplit); $menusource = 1; my $myplutype; if ($kidref->{plu}) { $myplutype = 1; }else{ $myplutype = 2; } $plutype = $myplutype; $printer = $kidref->{print_destination}; $thename = $kidref->{name}; $thesplit = $kidref->{split}; $theqty = $kidref->{qty}; if ($plutype == 2) { # instruction } else { # plu $plu_id = $kidref->{plu}; $price = $kidref->{price}; $discount = $kidref->{discount}; } #~ $results = $dbh->prepare("INSERT into tillordersdetails #~ (stamp, shop_id, orders_id, plu, price, discount, qty, menusource, waitron_id, plutype, name, print_destination,till_id, split) #~ values #~ (CURRENT_TIMESTAMP, #~ '$shop{id}', #~ '$orders_id', #~ '$plu_id', #~ '$price', #~ '$discount', #~ '$theqty', #~ '$menusource', #~ '$waitron_id', #~ '$plutype', #~ '$thename', #~ '$printer', #~ '$till_id', #~ '$thesplit');") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ $results->finish(); # my $SQL2 =qq|$shop{id},$orders_id,$plu_id,$price,$discount,$theqty, $menusource,$waitron_id, $plutype, $thename,$printer, $till_id, $thesplit,$bin_id|; #logit($SQL2); ### DELAYED $results = $dbh->prepare("INSERT into tillordersdetails (stamp, shop_id, orders_id, plu, price, discount, qty, menusource, waitron_id, plutype, name, print_destination,till_id, split, bin_id) values(CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);") or die $dbh->errstr(); $results->execute($shop{id}, $orders_id, $plu_id, $price, $discount, $theqty,$menusource, $waitron_id, $plutype,$thename, $printer, $till_id, $thesplit,$bin_id) or die $results->errstr(); ### #$results->finish(); } } else { #an old order - just update the status - and print if it is not printed my $confirm_status = $history->{order}->{$orderid}->{stage}; my $server_id = $history->{order}->{$orderid}->{mysqlid}; $results = $dbh->prepare("UPDATE tillorders set f_status=1,confirm_status=$confirm_status where id=$server_id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); } #if server id }# foreach order - orders in db !!! #~ foreach my $deletedorders ($root->children('deletedorder')){ #~ $results = $dbh->prepare("UPDATE tillorders set f_status=101 where id=?;") or die $dbh->errstr(); #~ $results->execute($deletedorders->att('id')) or die $results->errstr(); #~ $results = $dbh->prepare("UPDATE tillordersdetails set f_status=101 where orders_id=?;") or die $dbh->errstr(); #~ $results->execute($deletedorders->att('id')) or die $results->errstr(); #~ } # foreach deleted #UPDATE COVERS FOR THIS WAITER $results = $dbh->prepare("UPDATE tillorders set f_status=1,current_covers='$current_covers' where f_status<101 and waitron_id='$waitron_id' and tableops_id='$tableops_id';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); ##### ORDER PRINTER # TODO # PRINT SPLIT FOR DIFFERENT DESTINATIONS my %pluordering; my %printers; #printers my %redirectedprinters; my $dc; my ($subref,$subresults); $results = $dbh->prepare("SELECT * from tillorders where tableops_id = '$tableops_id' and f_status<101 and confirm_status=2;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $subresults = $dbh->prepare("SELECT * FROM tillordersdetails where orders_id='$ref->{id}';"); $subresults->execute() or die $subresults->errstr(); while ($subref = $subresults->fetchrow_hashref()) { #apply order redirection rules here if ($altord{$till_id}{$subref->{print_destination}} ne "") { $redirectedprinters{ $altord{$till_id}{$subref->{print_destination}} } = $subref->{print_destination}; $subref->{print_destination} = $altord{$till_id}{$subref->{print_destination}}; } if ($subref->{plutype} == 2) { push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{red} $subref->{name}" ); } else { #push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{black}__________________" ); push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{black} ".($subref->{qty}*1)." x $subref->{name}" ); if ($subref->{qty} >= 1) { for (1..$subref->{qty}) { push @confirmeditems, $subref->{plu}; } } } } # MARK AS PRINTED # separator for orders will come from the cycle below } #use Data::Dumper; #logit("PRINTER:".Dumper(%printers)); #DEBUG __________________________________________ $tmprn = ""; %tmprns = (); my $slipinit; my $lastopsid; my $lastcdate; $results = $dbh->prepare(" select substring_index(group_concat(tod.tableops_id order by dcash.date desc), ',', 1) concat_lastops_id, substring_index(group_concat(dcash.date order by dcash.date desc), ',', 1) concat_lastdate from dcash, tillordersdetails tods, tillorders tod where dcash.last_tillid = tods.id and tod.id = tods.orders_id and dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 15 day) group by dcash.id order by dcash.date desc limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastopsid = $ref->{concat_lastops_id} || 0; $lastcdate = $ref->{concat_lastdate} || "2000-01-01"; my $unique = $tableops_id - $lastopsid; { my $tmprn; $tmprn .= chr(27)."@"; $tmprn .= $ps{dw}.$ps{dh}.$ps{b}."$settings::pickhead\n"; my $tm = localtime(time); my $datetime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$tm->mday,($tm->mon+1),($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); $tmprn .= chr(27)."@"; #init printer $tmprn .= $ps{bold} . "DATE & TIME: $datetime".$ps{bold_off}; my $emptyline = " "x$pmax; #~ currenttime(); $emptyline = &align($emptyline,$ps{bold} ."User: $waitron".$ps{bold_off},1,0); #current_covers $tmprn .= $ps{b}; $tmprn .= "\n".$ps{minuses}."\n"; $tmprn .= $emptyline."\n"; if ($screenmode != 2) { $tmprn .= "TABLE: ".$ps{bsize}.$ps{bold}.$table_nr .$ps{bold_off}.$ps{bsize_esc}."| G: $current_covers \n\nORDER: ".$unique."\n"; } else { $tmprn .= "CASHPOINT: $table_nr \n\nORDER: ".$ps{bsize}.$ps{bold}.$unique.$ps{bold_off}.$ps{bsize_esc}."\n"; } $tmprn .= $clientprint ; $tmprn .= $ps{minuses}."\n"; #~ if ($client_name) { #~ $tmprn .= "CLIENT: $client_name"."\n" ; #~ $tmprn .= $ps{minuses}."\n"; #~ } $tmprn .= $ps{dh}; $slipinit = $tmprn; } my %ques; foreach my $printer (keys %printers) { foreach my $myorder (sort {$a <=> $b} keys %{ $printers{$printer} } ) { foreach my $lpdprn (@{$psubst{$printer}}) { foreach my $plu (@{ $printers{$printer}{$myorder} }) { push @{$ques{$lpdprn}{$myorder}}, $plu; } } } } foreach my $lpd (keys %ques) { #slip header $tmprns{$lpd} = $slipinit; #slip content my @allorders; foreach my $order (sort {$a <=> $b} keys %{$ques{$lpd}}) { my $items; foreach my $plu (@{$ques{$lpd}{$order}}) { $items .= $plu."\n"; } push @allorders, $items; } $tmprns{$lpd} .= join ("*********************************"."\n", @allorders ); #slip footer #~ open DEBUG, ">/debg"; #~ print DEBUG Dumper(\%prntype); #~ print DEBUG "LPD: $lpd |"; #~ close DEBUG; if ($prntype{$lpd} == 1) { # epson ? cut paper $tmprns{$lpd} .= $orderfeed; $tmprns{$lpd} .= $ps{cp}; $tmprns{$lpd} .= "\f"; } else { $tmprns{$lpd} .= $ps{feed}; } } # sent to printerz if ($settings::orderspayment != 1) { foreach my $lpdprnt (keys %tmprns) { my $printresult = Printit::printit ("127.0.0.1","127.0.0.1","$lpdprnt",$tmprns{$lpdprnt}); $printstatus = -1 if ($printresult != 0); } } if ($printstatus == 1) { $results = $dbh->prepare("UPDATE tillorders set f_status=1,confirm_status=3 where tableops_id = ? and f_status<101 and confirm_status=2"); $results->execute($tableops_id) ;#or die $results->errstr(); } else { $results = $dbh->prepare("UPDATE tillorders set f_status=1,confirm_status=1 where tableops_id = ? and f_status<101 and confirm_status=2"); $results->execute($tableops_id) ;#or die $results->errstr(); } ##### ORDER PRINTER } else { # table closed already $printstatus = -2; } #~ $oxml = " \n"; #add a new order #~ if ( scalar @{ $history->{order}->{$ordercnt}{kids} } ) { #~ $ordercnt++; #~ $history->{order}->{$ordercnt}->{stage} = 2; #~ } #~ #create the html #~ $billhtml .= qq~
    ~; #~ $billhtml .="Orders saved."; } if ($R::command eq "savedorders") { $billhtml .="Orders saved."; } my %totals; my %discount_totals; my $tabletotal; my $outstanding_total; my $averageheadspend; foreach my $orderid (sort {$a <=> $b} keys %{$history->{order}}) { foreach my $kidref ( @{ $history->{order}->{$orderid}->{kids} } ) { $totals{$kidref->{split}} += $kidref->{price} * $kidref->{qty} if (! $kidref->{voided}); if (! $kidref->{voided}) { $discount_totals{$kidref->{split}} += $kidref->{discount} * $kidref->{qty} ; $discount_totals{$kidref->{split}} += ( ($history->{client_discount} / 100) * ($kidref->{price} - $kidref->{discount}) ) * $kidref->{qty} if ($kidref->{discount} != 0); } $tabletotal += $kidref->{price} * $kidref->{qty} if (! $kidref->{voided}); $outstanding_total += $kidref->{price} * $kidref->{qty} if (! $kidref->{voided} and ! $kidref->{invoice}); if ($enable_proplim and $history->{client_limit_days} > 0) { $property_totals->{$kidref->{limiter_id}} += $kidref->{property_total}; } } } $averageheadspend = $tabletotal / $history->{guests} if ($history->{guests} > 0); $averageheadspend = "0" if (! $averageheadspend); $averageheadspend = pr($averageheadspend); $billhtml .= qq~
    ~; foreach my $split (sort {$a <=> $b} keys %totals) { if ($totals{$split} - $discount_totals{$split} < 0) { $discount_totals{$split} = $totals{$split}; } $totals{$split} = pr($totals{$split}); $billhtml .= qq~
    ~.($settings::voidenable == 1 ? "Split $split" : '').qq~Total:
    $totals{$split}
    ~; $billhtml .= qq~Discount: ~.pr($discount_totals{$split}).qq~ Due: ~.(pr($totals{$split} - $discount_totals{$split})).qq~
    ~ if $discount_totals{$split}; $billhtml .= qq~(~; $billhtml .= "invoice" if ($history->{splitting}->{$split}->{invoice} == 1 and $history->{splitting}->{$split}->{voided} != 1); $billhtml .= "void" if ($history->{splitting}->{$split}->{voided} == 1); $billhtml .= "proforma" if ($history->{splitting}->{$split}->{proforma} == 1); $billhtml .= "not paid" if ($history->{splitting}->{$split}->{nothing} == 1 and $history->{splitting}->{$split}->{invoice} != 1); $billhtml .= " mix" if ($history->{splitting}->{$split}->{nothing} == 1 and $history->{splitting}->{$split}->{invoice} == 1 ); $billhtml .= qq~)
    ~; } if ($screenmode != 2) { $billhtml .= qq~
    Table Average Head Spend:
    $averageheadspend
    ~ ; } $billhtml .= "
    "; my $overlimit_ason; if ($enable_proplim == 1 and $history->{client_limit_days} > 0) { my $total_negatives; $billhtml .= qq~
    ~; $results = $dbh->prepare(" select description, id, allowance from menu_properties_allowance ;"); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $proptotal; $proptotal = pr($ref->{allowance} - $property_totals->{$ref->{id}}); if (($ref->{allowance} - $property_totals->{$ref->{id}}) < 0) { $total_negatives ++; } if ($property_totals->{$ref->{id}} > $ref->{allowance}) { $billhtml .= "
    $ref->{description}
    "; $billhtml .= "
    $proptotal
    "; } else { $billhtml .= "
    $ref->{description}
    "; $billhtml .= "
    $proptotal
    "; } } $billhtml .= "
    "; if ($total_negatives > 0) { $overlimit_ason = "overlimit = '1';"; } else { $overlimit_ason = "overlimit = '0';"; } } writetmp($station_id,$history); #serialize data into text file; #~ $history = undef; $poledata->{3} = "$currency ".sprintf("%.2f",$poledata->{2}) if ($poledata->{1}); $poledata->{4} = "$currency ".sprintf("%.2f",$totals{1}); $poleinfo = poleformat($poledata->{1},'',$poledata->{3},$poledata->{4}); #~ print "
    ";
    						#~ print $poleinfo;
    					#~ print "
    "; $billhtml .= "ason>>"; if ($profile->{secondaryscreen} == 1) { $billhtml .= " secondscreen=$seconddisplay; secondscreentotal = '".pr($totals{1})."'; try{window.top.rightframe.uper(secondscreen.linedata, secondscreentotal)} catch(e) {}; "; } $billhtml .= "$overlimit_ason"; if ($poleinfo ne "") { $billhtml .= "pole('$poleinfo');"; if ($R::command eq "saveorders" and $etot == 1) { my $etotstring; my @etots; foreach my $id (@confirmeditems) { $results = $dbh->prepare("select * from etot where menu_id = $id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{etot_string}) { push @etots, $ref->{etot_string}; } } $etotstring = join('|', @etots); $billhtml .=";etot('$etotstring');"; } } else { if ($R::command eq "saveorders" and $etot == 1) { my $etotstring; my @etots; foreach my $id (@confirmeditems) { $results = $dbh->prepare("select * from etot where menu_id = $id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{etot_string}) { push @etots, $ref->{etot_string}; } } $etotstring = join('|', @etots); $billhtml .="etot('$etotstring');"; } } $billhtml .= "GB_mess('$R::biid not found');" if ($nobarcodefound > 0); if ($R::piid) { if ($noplufound > 0) { $billhtml .= qq~ document.getElementById('adlqty').value = '1'; document.getElementById('entry').value = ''; document.getElementById('entry').focus(); GB_mess('$R::piid not found');~; } else { $billhtml .= qq~ document.getElementById('adlqty').value = '1'; document.getElementById('entry').value = ''; document.getElementById('entry').focus(); ~; } } if (scalar keys %totals == 1 and ($history->{splitting}->{1}->{nothing} == 1 and $history->{splitting}->{1}->{invoice} != 1) ) { $billhtml .= "splitone='$totals{1}';"; } else { $billhtml .= "splitone='';"; } $billhtml .= "tabletotal='$outstanding_total';"; print $billhtml; #~ open(DDD, ">/DDD.DDD"); #~ print DDD $billhtml; #~ close(DDD); } elsif ($socketflag == 1 and $R::action eq "categories" and $session->param("~set_logged_user")) { $Text::Wrap::columns = 20; #THIS IS A AJAX FUNCTION #~ my $parent_id = $R::parent; my $cathtml; my %cats; # $results = $dbh->prepare("select id,name,ordering from menu_categories where parent_id='$R::parent' and useflag=1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); if (! $results->rows) { my $current = $R::current; $results = $dbh->prepare("select parent_id from menu_categories where id='$R::current' and useflag=1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $parent = $ref->{parent_id}; $results = $dbh->prepare("select id,name,ordering from menu_categories where parent_id='$R::current' and useflag=1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $R::current = $parent; $R::parent = $current; } while($ref = $results->fetchrow_hashref()) { $cats{$ref->{id}}{name} = $ref->{name}; $cats{$ref->{id}}{order} = $ref->{ordering} } my @list = sort {$cats{$a}{order} <=> $cats{$b}{order}} sort {$cats{$a}{name} cmp $cats{$b}{name}} keys %cats; my $count = scalar @list; my $maxcolumns; my $allowedhorizontal = 5; if ($count <= $allowedhorizontal) { $maxcolumns = $count; } else { my $itemsline = int ( $count / 2 ); $itemsline ++ if ($itemsline < $count / 2); $maxcolumns = $itemsline; } $maxcolumns *= 147; $maxcolumns += 77; my $temphtml .= qq~~; my $itemsline; if ($count <= $allowedhorizontal) { $itemsline = $count; } else { $itemsline = int ( $count / 2 ); $itemsline ++ if ($itemsline < $count / 2); } my $cnt = 1; $temphtml .= qq~~; $temphtml .= qq~~; for my $id (@list) { if ($cnt > $itemsline) { $temphtml .= qq~~; #line 2 $temphtml .= qq~~; $cnt = 1; $temphtml .= qq~~; } $cnt ++; $temphtml .= qq~ ~; } $temphtml .= qq~~; if ($count <= 5) { $temphtml .= qq~~; } $temphtml .= qq~
    $cats{$id}{name}
    ~; #~ open (DDD, ">/dddd.html"); #~ print DDD $temphtml; #~ close (DDD); #$temphtml = ""; print $temphtml; } elsif ($socketflag == 1 and $R::action eq "checksuper" ) { $results = $dbh->prepare("select id,name from supervisor where active=1 and pin='$R::pin' and f_status < 100;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{id}) { #~ print "success"; my $suid = $ref->{id}; #2022-08-14 START plu reprint if($R::forcase eq 'service_sfee'){ print qq~ason>> GB_hide(); SetAllowSfee("$R::casedata"); ~; } elsif($R::forcase eq 'plu_reprint') { #re-print invoice #consider print invoice area using super uid #and return url should be index.cgi?action=plu&tid=8 print qq~ason>> GB_hide(); //popup_keyboard('super_plu_reprint','suser=$ref->{id}'); window.location = 'index.cgi?action=super_plu_reprint&suid=$suid' ~; } #2022-08-14 END elsif ($R::forcase eq 'recallconfirm') { print qq~ason>> GB_hide(); popup_keyboard('super_recall','suser=$ref->{id};recall=$R::casedata'); ~; } elsif ($R::forcase eq 'refundconfirm') { print qq~ason>> GB_hide(); popup_keyboard('super_refund','$ref->{id}'); ~; } elsif ($R::forcase eq 'cdrawer') { print qq~ason>> GB_hide(); od(); ~; #LOG cdrawer my $me = $session->param("~set_user_id"); &supervisorLog($dbh,$ref->{id},'CASH DRAWER','CASH DRAWER',$ref->{name}." opened Cash drawer at $datetime ",'',$station_id,$me,'' ); } elsif ($R::forcase eq 'discountconfirm') { print qq~ason>> GB_hide(); popup_keyboard('super_discount','$ref->{id}'); ~; } elsif ($R::forcase eq 'accountconfirm') { print qq~ason>> GB_hide(); submitpayment(); ~; } elsif ($R::forcase eq 'splitproforma') { print qq~ason>> GB_hide(); do_retreive_proforma(); ~; } elsif ($R::forcase eq 'splitting') { print qq~ason>> if (voidingitems == 0) { window.location = 'index.cgi?action=plu&tid='+ tid +'&command=savesplits&suid=$suid' } else { supervisedby = $ref->{id}; GB_hide(); popup_keyboard(); }~; } elsif ($R::forcase eq 'payment') { print qq~ason>>GB_hide();submitpayment($ref->{id});~; } elsif ($R::forcase eq 'clock') { print qq~ason>>GB_hide();submitclock(clockaction);~; } elsif ($R::forcase eq 'qty') { print qq~ason>>GB_hide();submitqty(lastqty);~; } elsif ($R::forcase eq 'undo') { print qq~ason>>GB_hide();doundo();~; } elsif ($R::forcase eq 'delitem') { print qq~ason>> GB_hide(); dodelitem('$R::casedata'); ~; } elsif ($R::forcase eq 'price') { print qq~ason>> GB_hide(); popup_keyboard('priceoverride','suser=$ref->{id};price=$R::casedata'); ~; } elsif ($R::forcase eq 'undo') { print qq~ason>>GB_hide();submitundo();~; } elsif ($R::forcase eq 'superplu') { print qq~ason>>GB_hide();plufunction();~; } elsif ($R::forcase eq 'transfer') { my $me = $session->param("~set_user_id"); $results = $dbh->prepare(" select id,waitron_id from tilltableops where table_id='$R::ftid' order by id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $operation = $ref->{id}; my $from_user_id = $ref->{waitron_id}; #my $db = DataBase->new(dbh=>$dbh); #my $from_username = $db->SelectOne("SELECT name FROM `waitron` WHERE id=? LIMIT 1",$from_user_id); #my $to_username = $db->SelectOne("SELECT name FROM `waitron` WHERE id=? LIMIT 1",$me); $results = $dbh->prepare("SELECT name FROM `waitron` WHERE id=? LIMIT 1"); $results->execute($from_user_id) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $from_username = $ref->{name}; $results = $dbh->prepare("SELECT name FROM `waitron` WHERE id=? LIMIT 1"); $results->execute($me) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $to_username = $ref->{name}; $results = $dbh->prepare(" update tillinvoices set waitron_id = $me where tableops_id = '$operation';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results = $dbh->prepare(" update tillordersdetails tods, tillorders tod set tods.waitron_id = $me, tod.waitron_id=$me where tods.orders_id = tod.id and tod.tableops_id = '$operation';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results = $dbh->prepare(" update tilltableops set waitron_id = $me where id = '$operation';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); ###WE ARE HERE 1 &supervisorLog($dbh,$suid,'TABLE TRANSFER','TABLE TRANSFER',"TABLE " . $R::ftid . " Transfer From $from_username To $to_username",'',$profile->{station_id},$me,'' ); #if $settings::sutransfer ==1; print qq~ason>>GB_hide();window.location='index.cgi?action=tables';~; } } else { print "ason>>"; print "GB_hide(); GB_show('WP','wpin.html',188,255);"; if ($R::forcase eq 'clock') { print "cleanpin();"; } print "try{ clicked_plu = '' } catch(e) { };"; } } elsif ( $socketflag == 1 and $R::action eq "supop" ) { my $file = "$tdir/keypadn-su.htm"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = {%{$sys_settings}, station_id => $station_id, profile => $profile}; $R::localcase = '' if ($R::localcase eq 'undefined'); $R::casedata = '' if ($R::casedata eq 'undefined'); $vars->{forcase} = $R::localcase; $vars->{casedata} = $R::casedata; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "recallconfirm" and $session->param("~set_logged_user")) { my $file = "$tdir/recallconfirm.htm"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; if ($R::document !~ /\_/) { $results = $dbh->prepare("select * from tillinvoices where id = ?;"); $results->execute($R::document) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{invoice} = $ref->{id}; $vars->{document} = "Document ID: $R::document"; if ($ref->{client_id}) { $results = $dbh->prepare("select * from tillclients where id = ?;"); $results->execute($ref->{client_id}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $vars->{debtor}->{name} = $ref->{name}; $vars->{debtor}->{clientgroup} = $ref->{clientgroup}; $vars->{document} = ", Debtor: $ref->{name}, Company: $ref->{clientgroup}"; } } else { my $count; $count = () = $R::document =~ /\_(\d+)/g; $vars->{invoice} = $R::document; $vars->{document} = "Recall $count items?"; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "qtypop" and $session->param("~set_logged_user")) { my $file = "$tdir/keypadn-qty.htm"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "gstpop" and $session->param("~set_logged_user")) { my $file = "$tdir/keypadn-gst.htm"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); # my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "splits" and $session->param("~set_logged_user")) { my $file = "$tdir/splits.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); # my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; $vars->{susplit} = $settings::susplit; #~ my %tablenumbers; #~ $results = $dbh->prepare("select * from tilltables where active=1;") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ while ($ref = $results->fetchrow_hashref()) { #~ $tablenumbers{$ref->{id}} = $ref->{number}; #~ } if ( 1 ) {#$session->param("~setqmode") > 0 my $history = readtmp($station_id); #~ print "
    ";
    								#~ print Dumper($history);
    								#~ print "
    "; my @confirmeditems; #the real thing my $tmprn; my %tmprns; my $till_id = $station_id; my $waitron_id = $session->param("~set_user_id"); my $table_nr = $history->{tablenr}; my $tableops_id = $history->{tableops_id}; my $current_covers = $history->{guests}; #don't print and save my $falseflag = 0; $results = $dbh->prepare("SELECT tto.action action, client_id from tilltableops tto, tilltables tt where tto.table_id=tt.id and tt.number = $table_nr order by tto.id desc limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $client_id = $ref->{client_id}; my $clientprint; if ($ref->{action} == 2) {$falseflag = 1} my $printstatus = 1; if (! $falseflag) { if ($client_id) { $results = $dbh->prepare("select * from $sharedclients.tillclients where id = '$client_id';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $clientprint = $ps{minuses}."\n"; $clientprint .= "CUSTOMER: $ref->{name}\n"; $clientprint .= "ADDRESS: [1] $ref->{ph_address} [2] $ref->{ph_address1} [3] $ref->{ph_address2} [4] $ref->{ph_address3} \n" if ($ref->{ph_address} ne ''); $clientprint .= "T: $ref->{telephone} " if ($ref->{telephone}); $clientprint .= "M: $ref->{cellphone}" if ($ref->{cellphone}); $clientprint .= "\n"; } my $lastorderid; #waitron $results = $dbh->prepare("SELECT * from waitron where id='$waitron_id';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $waitron = $ref->{name}; my $demomode; $demomode = 1 if ($waitron =~ /!DEMO!/sgi); foreach my $orderid (sort {$a <=> $b} keys %{$history->{order}}) { if ( ! $history->{order}->{$orderid}->{mysqlid} and (scalar @{ $history->{order}->{$orderid}->{kids} } > 0) ) { # insert the new orders my $confirm_status = $history->{order}->{$orderid}->{stage}; # $orders->att('confirm'); my $results = $dbh->prepare("INSERT into tillorders (stamp,shop_id,till_id,waitron_id,tableops_id,confirm_status) values (CURRENT_TIMESTAMP,$shop{id}, '$till_id', '$waitron_id', '$tableops_id', '$confirm_status');") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results->finish(); #imediately $results = $dbh->prepare("SELECT LAST_INSERT_ID() lastid FROM tillorders limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $orders_id = $ref->{lastid}; $history->{order}->{$orderid}->{mysqlid} = $orders_id; #~ print " Order ID: $orders_id
    "; $lastorderid = $orders_id; # time to create the new order details #print "\n DEBUG: NEW ORDER $lastorderid"; foreach my $kidref ( @{ $history->{order}->{$orderid}->{kids} } ) { # foreach my $plus ($orders->children('plu')) { my ($plutype, $local_name, $menusource, $plu_id, $price, $discount, $printer, $thename, $theqty, $thesplit); $menusource = 1; my $myplutype; if ($kidref->{plu}) { $myplutype = 1; }else{ $myplutype = 2; } $plutype = $myplutype; $printer = $kidref->{print_destination}; $thename = $kidref->{name}; $thesplit = $kidref->{split}; $theqty = $kidref->{qty}; if ($plutype == 2) { # instruction } else { # plu $plu_id = $kidref->{plu}; $price = $kidref->{price}; $discount = $kidref->{discount}; } $results = $dbh->prepare("INSERT into tillordersdetails (stamp, shop_id, orders_id, plu, price, discount, qty, menusource, waitron_id, plutype, name, print_destination,till_id, split, bin_id) values (CURRENT_TIMESTAMP,'$shop{id}', '$orders_id', '$plu_id', '$price', '$discount', '$theqty', '$menusource', '$waitron_id', '$plutype', '$thename', '$printer', '$till_id', '$thesplit', '$bin_id');") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results->finish(); } } else { #an old order - just update the status - and print if it is not printed my $confirm_status = $history->{order}->{$orderid}->{stage}; my $server_id = $history->{order}->{$orderid}->{mysqlid}; if ($confirm_status and $server_id) { $results = $dbh->prepare("UPDATE tillorders set f_status=1,confirm_status=$confirm_status where id=$server_id;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); } } #if server id }# foreach order - orders in db !!! ##### ORDER PRINTER # TODO # PRINT SPLIT FOR DIFFERENT DESTINATIONS my %pluordering; my %printers; #printers my %redirectedprinters; my $dc; my ($subref,$subresults); $results = $dbh->prepare("SELECT * from tillorders where tableops_id = '$tableops_id' and f_status<101 and confirm_status=2;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $subresults = $dbh->prepare("SELECT * FROM tillordersdetails where orders_id='$ref->{id}';"); $subresults->execute() or die $subresults->errstr(); while ($subref = $subresults->fetchrow_hashref()) { #apply order redirection rules here if ($altord{$till_id}{$subref->{print_destination}} ne "") { $redirectedprinters{ $altord{$till_id}{$subref->{print_destination}} } = $subref->{print_destination}; $subref->{print_destination} = $altord{$till_id}{$subref->{print_destination}}; } if ($subref->{plutype} == 2) { push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{red} $subref->{name}" ); } else { #push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{black}__________________" ); push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{black} ".($subref->{qty}*1)." x $subref->{name}" ); if ($subref->{qty} >= 1) { for (1..$subref->{qty}) { push @confirmeditems, $subref->{plu}; } } } } # MARK AS PRINTED # separator for orders will come from the cycle below } #use Data::Dumper; #print Dumper(%printers); #DEBUG __________________________________________ $tmprn = ""; %tmprns = (); my $slipinit; my $lastopsid; my $lastcdate; $results = $dbh->prepare(" select substring_index(group_concat(tod.tableops_id order by dcash.date desc), ',', 1) concat_lastops_id, substring_index(group_concat(dcash.date order by dcash.date desc), ',', 1) concat_lastdate from dcash, tillordersdetails tods, tillorders tod where dcash.last_tillid = tods.id and tod.id = tods.orders_id and dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 15 day) group by dcash.id order by dcash.date desc limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastopsid = $ref->{concat_lastops_id} || 0; $lastcdate = $ref->{concat_lastdate} || "2000-01-01"; my $unique = $tableops_id - $lastopsid; { my $tmprn; $tmprn .= chr(27)."@"; $tmprn .= $ps{dw}.$ps{dh}.$ps{b}."$settings::pickhead\n"; my $tm = localtime(time); my $datetime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$tm->mday,($tm->mon+1),($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); $tmprn .= chr(27)."@"; #init printer $tmprn .= "DATE & TIME: $datetime" ; my $emptyline = " "x$pmax; #~ currenttime(); $emptyline = &align($emptyline,"User: $waitron",1,0); #current_covers $tmprn .= $ps{b}; $tmprn .= "\n".$ps{minuses}."\n"; $tmprn .= $emptyline."\n"; if ($screenmode != 2) { #$tmprn .= $ps{bold}."TABLE: $table_nr | G: $current_covers | ORDER: $unique".$ps{bold_off}."\n"; $tmprn .= "TABLE: ".$ps{bsize}.$ps{bold}.$table_nr .$ps{bold_off}.$ps{bsize_esc}."| G: $current_covers \n\nORDER: ".$unique."\n"; } else { $tmprn .= "CASHPOINT: $table_nr \n\nORDER: ".$ps{bsize}.$ps{bold}.$unique.$ps{bold_off}.$ps{bsize_esc}."\n"; } $tmprn .= $clientprint ; $tmprn .= $ps{minuses}."\n"; #~ if ($client_name) { #~ $tmprn .= "CLIENT: $client_name"."\n" ; #~ $tmprn .= $ps{minuses}."\n"; #~ } $tmprn .= $ps{dh}; $slipinit = $tmprn; } my %ques; foreach my $printer (keys %printers) { foreach my $myorder (sort {$a <=> $b} keys %{ $printers{$printer} } ) { foreach my $lpdprn (@{$psubst{$printer}}) { foreach my $plu (@{ $printers{$printer}{$myorder} }) { push @{$ques{$lpdprn}{$myorder}}, $plu; } } } } #~ open (OOO, ">/dddd"); #~ print OOO Dumper(\%ques); #~ close OOO; foreach my $lpd (keys %ques) { #slip header $tmprns{$lpd} = $slipinit; #slip content my @allorders; foreach my $order (sort {$a <=> $b} keys %{$ques{$lpd}}) { my $items; foreach my $plu (@{$ques{$lpd}{$order}}) { $items .= $plu."\n"; } push @allorders, $items; } $tmprns{$lpd} .= join ("*********************************"."\n", @allorders ); #slip footer if ($prntype{$lpd} == 1) { # epson ? cut paper $tmprns{$lpd} .= $orderfeed; $tmprns{$lpd} .= $ps{cp}; $tmprns{$lpd} .= "\f"; } else { $tmprns{$lpd} .= $ps{feed}; } } # sent to printerz foreach my $lpdprnt (keys %tmprns) { my $printresult = Printit::printit ("127.0.0.1","127.0.0.1","$lpdprnt",$tmprns{$lpdprnt}); $printstatus = -1 if ($printresult != 0); } if ($printstatus == 1) { $results = $dbh->prepare("UPDATE tillorders set f_status=1,confirm_status=3 where tableops_id = $tableops_id and f_status<101 and confirm_status=2 ;"); $results->execute() or die $results->errstr(); } else { $results = $dbh->prepare("UPDATE tillorders set f_status=1,confirm_status=1 where tableops_id = $tableops_id and f_status<101 and confirm_status=2 ;"); $results->execute() or die $results->errstr(); } ##### ORDER PRINTER } else { # table closed already $printstatus = -2; } writetmp($station_id,$history); #serialize data into text file; } my @tables; #~ foreach my $table_id (keys %tablenumbers) { #~ $results = $dbh->prepare(" #~ select id,client_id,action,waitron_id,table_id,visitors #~ from tilltableops where table_id='$table_id' order by id desc limit 1;") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ $ref = $results->fetchrow_hashref(); #~ if ( #~ $ref->{action} == 1 #~ and $ref->{waitron_id} == $session->param("~set_user_id") #~ ) { #~ push @tables, $tablenumbers{$table_id}; #~ } #~ } my $tabledetails; my $lastopsid; my $lastcdate; $results = $dbh->prepare(" select substring_index(group_concat(tod.tableops_id order by dcash.date desc), ',', 1) concat_lastops_id, substring_index(group_concat(dcash.date order by dcash.date desc), ',', 1) concat_lastdate from dcash, tillordersdetails tods, tillorders tod where dcash.last_tillid = tods.id and tod.id = tods.orders_id and dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 15 day) group by dcash.id order by dcash.date desc limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastopsid = $ref->{concat_lastops_id} || 0; $lastcdate = $ref->{concat_lastdate} || "2000-01-01"; $results = $dbh->prepare(" select substring_index(group_concat(tabops.table_id order by tabops.id desc), ',', 1) concat_table_id, substring_index(group_concat(tabops.id - $lastopsid order by tabops.id desc), ',', 1) concat_UNIQUETABOPSID, substring_index(group_concat(tilltables.number order by tabops.id desc), ',', 1) concat_number, substring_index(group_concat(tilltables.type order by tabops.id desc), ',', 1) concat_type, substring_index(group_concat(waitron.name order by tabops.id desc), ',', 1) concat_waitron_name, substring_index(group_concat(waitron.id order by tabops.id desc), ',', 1) concat_waitron_id, substring_index(group_concat(tabops.visitors order by tabops.id desc), ',', 1) concat_visitors, substring_index(group_concat(tabops.id order by tabops.id desc), ',', 1) concat_id, substring_index(group_concat(tabops.action order by tabops.id desc), ',', 1) concat_action, substring_index(group_concat(tabops.waitron_id order by tabops.id desc), ',', 1) concat_waitron_id, substring_index(group_concat(tabops.stamp order by tabops.id desc), ',', 1) concat_stamp from tilltables,tilltableops tabops,waitron where tilltables.id = tabops.table_id and waitron.id = tabops.waitron_id and stamp > DATE_SUB('$lastcdate', INTERVAL 1 day) group by tabops.table_id HAVING substring_index(group_concat(tabops.action order by tabops.id desc), ',', 1) = 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { #~ $tabledetails->{$ref->{concat_table_id}} = { #~ tid => $ref->{concat_table_id}, #~ type => $ref->{concat_type}, #~ number => $ref->{concat_number}, #~ reference => $ref->{concat_UNIQUETABOPSID}, #~ waitron_name => $ref->{concat_waitron_name}, #~ waitron_id => $ref->{concat_waitron_id}, #~ guests => $ref->{concat_visitors} #~ }; push @tables, $ref->{concat_number} } $vars->{opentables} = join (",", @tables); my $results = $dbh->prepare(" select number from tilltables where id = '$R::tid'; ") or die $dbh->errstr(); $results->execute() or die $results->errstr(); my $ref = $results->fetchrow_hashref(); $vars->{tablenumber} = $ref->{number}; $vars->{tid} = $R::tid; $vars->{tableopsid} = $R::tableopsid; my @usedsplits; my %usedsplitsh; my $results = $dbh->prepare(" SELECT tods.split spl, tods.invoice FROM tillordersdetails tods, tillorders too WHERE too.tableops_id = ? AND too.id = tods.orders_id AND tods.invoice > 0;") or die $dbh->errstr(); $results->execute($R::tableopsid) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @usedsplits, "'$ref->{spl}':'1'"; $usedsplitsh{$ref->{spl}} = 1; } $vars->{usedsplits} = join(",", @usedsplits); my @availablespl; foreach my $abc (1..12) { if (! $usedsplitsh{$abc}) { push(@availablespl, $abc); if (! $vars->{firstsplit}) { $vars->{firstsplit} = $abc; } } } $vars->{availablesplits} = join(",",@availablespl); my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($socketflag == 1 and $R::action eq "opentable" and $session->param("~set_logged_user")) { my $file = "$tdir/tables-open.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); # my $vars = { %{$sys_settings}, station_id => $station_id, profile => $profile }; #received table number and id and type $vars->{ttype} = $tilltabletype{$R::type}; $vars->{tid} = $R::id; $vars->{tnumber} = $R::number; my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } elsif ($R::action ne '' and $R::action ne 'pincode') { print qq~ No such action allowed... ~; } } else { #login failed my $profile = $session->param("~profile"); my $station_id = $profile->{station_id}; login_page($profile,$q); } $session->flush(); } #sub INDEX #login subs #### LOGIN PROCEDURES #### sub logininit { my ($session, $cgi) = @_; # receive two args if($cgi->param("cmd") eq "logout"){ $session->param("~setqmode", undef); $session->param("~session_table_id", undef); $session->param("~profile",undef); $session->clear(["~logged-in"]); } # && $session->param("~settings_pm"); # if logged in, don't bother going further my $lg_name = $cgi->param("terminal") or return; my $lg_psswd = $cgi->param("code") or return; my $lg_profile = $cgi->param("profile") or return; unless($lg_name && $lg_psswd && $lg_profile) { if($session->param("~logged-in")){ return 1; }else{ my $profile = $session->param("~profile"); my $station_id = $profile->{station_id}; login_page($profile,$cgi); } } my $dbh = DBI->connect("DBI:mysql:;host=$dbhost",$dbuser,$dbpassword) or die $DBI::errstr; my $results = $dbh->prepare("select * from spaceusers.profiles where id = $lg_profile") or die $dbh->errstr(); $results->execute() or die $results->errstr(); my $ref = $results->fetchrow_hashref(); # if we came this far, user did submit the login form # so let's try to load his/her profile if name/psswds match if ( my $profile = _load_profile($lg_name, $lg_psswd, $lg_profile) ) { #delete all old sessions for this user here; $profile->{database} = $ref->{db_name}; $profile->{shop_id} = $ref->{shop_id}; $profile->{group} = $ref->{profilegroup}; $profile->{profilename} = $ref->{name}; $profile->{profile_id} = $ref->{id}; my $results = $dbh->prepare("select * from spaceusers.profiles where profilegroup = '$profile->{group}' and sharedclients = 1 limit 1") or die $dbh->errstr(); $results->execute() or die $results->errstr(); my $ref = $results->fetchrow_hashref(); if ($ref->{db_name}) { $profile->{sharedclientsdatabase} = $ref->{db_name}; $profile->{sharedclientsprofilename} = $ref->{name}; $profile->{sharedclientsprofileid} = $ref->{id}; $profile->{sharedclientsshopid} = $ref->{shop_id}; } else { $profile->{sharedclientsdatabase} = $profile->{database}; $profile->{sharedclientsprofilename} = $profile->{profilename}; $profile->{sharedclientsprofileid} = $profile->{profile_id}; $profile->{sharedclientsshopid} = $profile->{shop_id}; } my $db_name = $profile->{sharedclientsdatabase};#$profile->{database}; my %settings_pm; $results = $dbh->prepare("select * from spaceusers.Settings where db = ?") or die $dbh->errstr(); $results->execute($db_name) or die $results->errstr(); while(my $ref = $results->fetchrow_hashref()){ $settings_pm{$ref->{name}} = $ref->{val} if $ref->{name}; } my @setts; foreach my $k(keys %settings_pm){ push @setts,"$k=$settings_pm{$k}" if $k; } $session->param("~settings_pm",join(':',@setts)); $session->param("~profile", $profile); $session->param("~logged-in", randchar(12)); $session->clear(["~login-trials"]); retreive_tax($profile->{database}, $profile->{shop_id}); return 1; } # if we came this far, the login/psswds do not match # the entries in the database my $trials = $session->param("~login-trials") || 0; return $session->param("~login-trials", ++$trials); } sub randchar { my @range = ('0'..'9','a'..'z'); my $x = int scalar @range; join '', map $range[rand $x], 1..shift||1; } ########################################################## sub _load_profile { my ($lg_name, $lg_psswd, $lg_profile) = @_; my $dbh = DBI->connect("DBI:mysql:;host=$dbhost",$dbuser,$dbpassword) or die $DBI::errstr; my $results = $dbh->prepare("select * from spaceusers.profiles where id = $lg_profile") or die $dbh->errstr(); $results->execute() or die $results->errstr(); my $ref = $results->fetchrow_hashref(); my $database = $ref->{db_name}; my $SQL = qq|select te.* from $database.terminals te, spaceusers.users, spaceusers.user_profiles where te.station_id=? and te.code=? and users.username = te.station_id and user_profiles.profile_id = '$lg_profile' and user_profiles.user_id = users.id and user_profiles.active = 1|; write2log($SQL); $results = $dbh->prepare($SQL) or die $dbh->errstr(); $results->execute($lg_name, $lg_psswd) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ( $ref->{station_id} ) { #delete existing old session for user #register new session id in db my ($ip,$port) = split(/\|/, $ref->{cashdrawer} ); my ($pole_ip,$pole_port) = split(/\|/, $ref->{pole} ); return { station_id=>$ref->{station_id}, screenmode=>$ref->{screenmode}, allowaddcustomer=>$ref->{allowaddcustomer}, disablepayment=>$ref->{disablepayment}, secondaryscreen=>$ref->{secondaryscreen}, disablereturns=>$ref->{disablereturns}, posfocus => $ref->{searchpos}, pluscreenmode => $ref->{pluscreenmode}, widescreen => $ref->{widescreen}, allowcashrefund=>$ref->{allowcashrefund}, noautofillaccount_refund=>$ref->{noautofillaccount_refund}, printinstructions=>$ref->{printinstructions}, location=>$ref->{location}, tablekeywords=>$ref->{tablekeywords}, logofile=>$ref->{logofile}, cashdrawer_port => $port, cashdrawer_ip => $ip, pole_port => $pole_port, pole_ip => $pole_ip, station_ip => $ref->{ip}, printmode => $ref->{printmode}, #plumode => $ref->{plumode}, slipscount => $ref->{slipscount}, nocustomerdiscount => $ref->{nocustomerdiscount}, }; } else { #incorrect login page message. return undef; } } ########################################################## sub login_page { my $q = $_[1]; my $ref; my $results; my $oldprofile = $_[0]; my $file = "$tdir/tlogin.html"; my $output; my $template = Template->new(ABSOLUTE => 1,COMPILE_EXT => '.ttc'); my $vars = { message => "", sessionusername => $oldprofile->{terminal} }; my $dbh = DBI->connect("DBI:mysql:;host=$dbhost",$dbuser,$dbpassword) or die $DBI::errstr; my $selectedprofile; my $selectedprofile_db; $results = $dbh->prepare("select * from spaceusers.profiles") or die $dbh->errstr(); $results->execute() or die $results->errstr(); if ($results->rows>0) { $vars->{profile} = ""; } if ($q->param('profile') ) { $vars->{info} = "I see you are trying to log in without knowing this terminal ID."; $vars->{info} .= "Selected profile: ".$selectedprofile."
    "; my $ip; if ( $ENV{ HTTP_X_FORWARDED_FOR } ) { #ip behind proxy $ip = $ENV{ HTTP_X_FORWARDED_FOR}; } else { #plain $ip = $ENV{ REMOTE_ADDR }; } $vars->{ip} = $ip; $results = $dbh->prepare(" select * from $selectedprofile_db.terminals where ip = ? ;") or die $dbh->errstr(); $results->execute($ip) or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{id}) { $vars->{info} .= "Based on your IP this terminal is supposed to have ID: $ref->{station_id}, and Code: $ref->{code}"; $vars->{suggested_id} = $ref->{station_id}; $vars->{suggested_code} = $ref->{code}; $vars->{info} .= "
    Please press CONNECT again to log in the terminal session."; } else { $vars->{info} .= "The IP of this computer is not configured in our database. Please contact SpaceBiz support"; } } else { $vars->{info} = "If you don't know what you are doing, select a profile (from the dropdown below) and click Connect button. Check here for further instructions."; } my $temphtml = $template->process($file, $vars, \$output) || die "Template process failed: ", $template->error(), "\n"; print $output; } #SERVICE SUBS sub fpme { {"KEY_GENERATED_BEFORE_THIS_ENTRY POINT";} {'if (VERIFYKEY() == 2 {generate_unique_session_id (flag=>"F1B23.version_3.REV_a;gen=yes;top_restaurants"} ) else print "I am sorry this program has been self destroyed. Please contact your administrator for repair"';} return "
    I AM SORRY THIS FUNCTION IS CURRENTLY DISABLED.
    PLEASE CONTACT YOUR ADMINISTRATOR."; } sub slurpfile { my $slurp; open(SLURIN, "< $_[0]") or warn "can't open $_[0]: $!"; #doesn't need to return error because some files don't exist binmode (SLURIN); seek(SLURIN, 0, 0); sysread (SLURIN, $slurp, -s SLURIN); close(SLURIN); return $slurp; } sub writetmp { my $station = $_[0]; my $data = $_[1]; my $file = $_[2]; lock_nstore $data, "/wwwroot/ST$file$station.station"; #~ open (OUT, ">/wwwroot/ST$file$station.station") || die "$!"; #~ print OUT $data; #~ close OUT; #~ $tfilez{"/wwwroot/ST$file$station.station"} = $data; } sub readtmp { my $station = $_[0]; my $file = $_[1]; my $data = {}; if (-f "/wwwroot/ST$file$station.station") { $data = lock_retrieve("/wwwroot/ST$file$station.station"); } else { lock_nstore $data, "/wwwroot/ST$file$station.station"; } #~ my $data = slurpfile("/wwwroot/ST$file$station.station"); #~ my $data = $tfilez{"/wwwroot/ST$file$station.station"}; #~ open DDD, ">>/ddd.txt"; #~ print DDD "REQUIRE:"; #~ print DDD "/wwwroot/ST$file$station.station"; #~ print DDD "\n"; #~ print DDD $data; #~ print DDD "\nEND REQUIRE ******\n"; #~ close DDD; return $data; } sub removetmp { my $station = $_[0]; my $file = $_[1]; unlink "/wwwroot/ST$file$station.station"; #~ delete $tfilez{"/wwwroot/ST$file$station.station"}; } #tvis #### TEMP PROCEDURES ### sub tvis_writetmp { my $data = $_[0]; my $file = $_[1]; open (OUT, ">/wwwroot/extranet/tvis/data/$file") || die "$!"; print OUT $data; close OUT; } sub tvis_removetmp { my $file = $_[0]; unlink "/wwwroot/extranet/tvis/data/$file"; } sub tvis_readtmp { my $file = $_[0]; my $data = slurpfile("/wwwroot/extranet/tvis/data/$file"); return $data; } ############################################################################################################## sub pr { my $number; if ($_[0] < 0) { $number = sprintf("(%.2f)",$_[0] * -1); } else { $number = sprintf("%.2f",$_[0]); } #my @temp = split (/\./,$number); #$temp[0]= join(',', grep {$_ ne ''} split(/(...)/, $temp[0])); #$number = join '.',@temp; return $number; } sub pr_com { my $number = sprintf("%.2f",$_[0]); return commify($number); } sub commify { my $input = shift; $input = reverse $input; $input =~ s<(\d\d\d)(?=\d)(?!\­d*\.)><$1,>g; return scalar reverse $input; } #~ sub tietempdb { #~ my $databasefile = "/wwwroot/POS$database"."tempy.db"; #~ $sync_dbm_obj = tie %tempdb, 'MLDBM::Sync', $databasefile, O_CREAT|O_RDWR, 0644; #~ tie %tempdb, 'SDBM_File', $databasefile, O_CREAT|O_RDWR, 0644; #~ } ##### MYSQL FUNCS ##### sub db_connect { my ($dbname, $dbuser, $dbpass) = @_; my $dbh = DBI->connect("DBI:mysql:$dbname",$dbuser,$dbpass); #$dbh->do(qq{set character set 'utf8';}); return $dbh; } sub do_sql { # Takes: $dbh, $sql # Returns: status my $dbh = shift || die "Database not connected!\n"; my $sql = shift || die "Missing SQL statement???\n"; return $dbh->do($sql); } sub execute_sql { # Takes: $dbh, $sql # Returns: $result_arrayref my $dbh = shift || die "Database not connected!\n"; my $sql = shift || die "Missing SQL statement???\n"; my $sth = $dbh->prepare($sql); $sth->execute; my $result = $sth->fetchall_arrayref({}); # {} => Return arrayref of hashrefs return $result; } sub do_insert { #takes: $dbh, $table, $datahash #returns: status my $dbh = shift || die "Database not connected!\n"; my $table = shift || die "Missing table!\n"; my $datahash = shift || die "Nothing to insert!\n"; my $insert = "INSERT INTO $table (" . join(',', keys %$datahash) . ') VALUES (' . join(',', values %$datahash) . ');'; return &do_sql($dbh, $insert); } ##### MYSQL FUNCS END ##### ############################################################ sub recipeingredients { my $recipetouse = $_[0]; my $dbh = $_[1]->{dbh}; my $results; my $subresults; my $ref; my $subref; my @usagetotal; #db $results = $dbh->prepare("SELECT * from recipe_ingredients where recipe_id='$recipetouse';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { if ($ref->{ritem_id}) { $subresults = $dbh->prepare("SELECT name from ritems where id='$ref->{ritem_id}';") or die $dbh->errstr(); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); push @usagetotal, $subref->{name}; } else {#else recursion... because this is another recipe push @usagetotal, &recipeingredients($ref->{subrecipe_id}, {dbh => $dbh }); } } $results = $dbh->prepare("SELECT * from recipe_comments where recipe_id='$recipetouse';") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { push @usagetotal, $ref->{comment}; } return @usagetotal; } ############################################################ sub align { my ($original,$string,$align,$offset); ($original,$string,$align,$offset) = @_; if ($align == 1) { #use offset on the left $original = substr($original,0,$offset).$string.substr($original,length($string)+$offset,length($original)-(length($string)+$offset) ); } elsif ($align == 2) { #dont use offset my $centerstart = int(length($original)/2) - int(length($string)/2); $original = substr($original,0,$centerstart).$string.substr($original,$centerstart+length($string),length($original)-length($string)) ; } elsif ($align == 3) { #use offset on the right #print length($original)-(length($string)+$offset)) #print original,$pmax-$offset,length($original)-(length($string)+$offset) ); $original = substr($original,0,length($original)-(length($string)+$offset)).$string.substr( $original,length($original)-$offset, $offset); } $original; } ############################################################ ############################################################ sub broadcast_void { my $chk = $_[0]; my $till_id = $_[1]; my $dbh = $_[2]->{dbh}; my $screenmode = $_[3]; my ($subref,$subresults); $subresults = $dbh->prepare("select tableops_id,tilltables.number table_nr,waitron.name wname, inv.voided voided from tillinvoices inv, tilltableops, tilltables, waitron where inv.id='$chk' and tilltableops.id = inv.tableops_id and tilltables.id=tilltableops.table_id and waitron.id=inv.waitron_id;"); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); my $waitron = $subref->{wname}; my $table_nr = $subref->{table_nr}; my $voided = $subref->{voided}; ##### VOID PRINTER # TODO # PRINT SPLIT FOR DIFFERENT DESTINATIONS my %printers; #printers my $dc; $subresults = $dbh->prepare("SELECT * FROM tillordersdetails where invoice='$chk';"); $subresults->execute() or die $subresults->errstr(); while ($subref = $subresults->fetchrow_hashref()) { #apply order redirection rules here #~ if ($altord{$till_id}{$subref->{print_destination}} ne "") { #~ $redirectedprinters{ $altord{$till_id}{$subref->{print_destination}} } = $subref->{print_destination}; #~ $subref->{print_destination} = $altord{$till_id}{$subref->{print_destination}}; #~ } if ($subref->{plutype} == 2) { push ( @{ $printers{ $subref->{print_destination} }{ 1 } }, "$ps{red} $subref->{name}" ); } else { #push ( @{ $printers{ $subref->{print_destination} }{ $ref->{id} } }, "$ps{black}__________________" ); push ( @{ $printers{ $subref->{print_destination} }{ 1 } }, "$ps{black} VOID! ".($subref->{qty}*1)." x $subref->{name}" ); } } #DEBUG __________________________________________ my $tmprn = ""; my %tmprns = (); foreach (keys %printers) { foreach my $myorder (keys %{ $printers{$_} } ) { foreach my $myitem ( @{ $printers{$_}{$myorder} } ) { $tmprn .= $myitem."\n"; } $tmprn .= "*********************************"."\n"; } } #MULTI PRINTERS PRINTING %tmprns = (); foreach (keys %printers) { if ($_) { ####################################################################### $tmprn = ""; $tmprn .= chr(27)."@"; $tmprn .= $ps{dw}.$ps{dh}.$ps{b}."$settings::pickhead\n"; my $tm = localtime(time); my $datetime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$tm->mday,($tm->mon+1),($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); $tmprn .= chr(27)."@"; #init printer $tmprn .= "DATE & TIME: $datetime"; my $emptyline = " "x$pmax; currenttime(); $emptyline = &align($emptyline,"User: $waitron",1,0); $tmprn .= $ps{b}; $tmprn .= "\n".$ps{minuses}."\n"; $tmprn .= $emptyline."\n"; if ($screenmode != 2) { $tmprn .= "TABLE: $table_nr | Printer $_"."\n"; } else { $tmprn .= "CASHPOINT: $table_nr | Printer $_"."\n"; } $tmprn .= $ps{minuses}."\n"; $tmprn .= $ps{dh}; $tmprn .= $ps{b}; $tmprn .= $ps{red}; if($voided ==2){ $tmprn .= "Return-Return-Return!!!\n"; }else{ $tmprn .= "VOID-VOID-VOID!!!\n"; } ####################################################################### foreach my $myorder (keys %{ $printers{$_} } ) { foreach my $myitem ( @{ $printers{$_}{$myorder} } ) { $tmprn .= $myitem."\n"; } $tmprn .= "*********************************"."\n"; } ####################################################################### $tmprn .= $ps{feed}; #surf all printers and prepare tmprns for the session foreach my $lpdprn (@{$psubst{$_}}) { $tmprns{$lpdprn} .= $tmprn; #slip body if ($prntype{$lpdprn} == 1) { $tmprns{$lpdprn} .= $ps{cp}; $tmprns{$lpdprn} .= "\f"; } } ####################################################################### } } # sent to printerz my $printstatus = 1; foreach my $lpdprnt (keys %tmprns) { my $printresult = Printit::printit ("127.0.0.1","127.0.0.1","$lpdprnt",$tmprns{$lpdprnt}); $printstatus = 0 if ($printresult != 0); } sub currenttime { $tm = localtime(time); $date = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$tm->mday,($tm->mon+1),($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); $time = sprintf("%02d:%02d:%02d", $tm->hour, $tm->min, $tm->sec); } } sub stringtime { my $globalseconds = $_[0]; my $daysml; my $remain; my $seconds; my $minutes; my $hours; my $days; $seconds = sprintf ("%02d", $globalseconds % 60); $minutes = sprintf ("%02d", int($globalseconds / 60) % 60); $hours = sprintf ("%02d",int($globalseconds / 3600) % 24); $days = int($globalseconds / 86400); $daysml = sprintf ("%d days ", $days) if ($days>0); "$daysml$hours:$minutes:$seconds" } sub printinvoice { my $tm = localtime(time); #~ my $date = sprintf("%02d-%02d-%04d",$tm->mday,($tm->mon+1),($tm->year + 1900)); my $datetime = sprintf("%02d-%02d-%04d %02d:%02d:%02d",$tm->mday,($tm->mon+1),($tm->year + 1900), $tm->hour, $tm->min, $tm->sec); my $date = $datetime; my $reprint_date = $datetime if $R::action eq "super_reprint_reprint" || $R::suid; my %params = %{ $_[0] }; my $dbh = $_[1]->{dbh}; my $database = $_[2]; my %shop = (id => $_[3]); my $sharedclients = $_[4]; my ($results, $ref, $subref,$subresults,$checkthis); my $screenmode = $params{'screenmode'}; my $printmode = $params{'printmode'}; #$profile->{printmode} = 1 if $printmode; #open FILE,">>log.txt"; #print FILE "printmode:$printmode - ".$profile->{printmode}; #close FILE; # 0.1 Biltong @R350/kg = R35 my $status = 1; my $message; my $till_id = $params{'till_id'}; #depamount #get binid for this till_id my $results = $dbh->prepare("select * from terminals where station_id = ?;") or die $dbh->errstr(); $results->execute($params{'till_id'}) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $binid = $ref->{bin_id}; my $tillprinter = "T".$params{'till_id'}; my $supervisor_flag = $params{'supervisor_flag'}; my $plu_discount; my $invoice = $params{'invoice'}; #not realy comming when initiated by Supervisor #this is comming only when a waitron prints an invoice!!! my $proforma = $params{'proforma'}; my $tableopsid = $params{'tableops_id'}; my $servicecharge = $params{'servicecharge'}; my $tenpercent = $params{'tenpercent'}; my $split = $params{'split'}; my $current_client = $params{'client'}; $current_client = undef if $current_client==0; my $current_client_name = $params{'client_name'}; my $waitron_id = $params{'waitron_id'}; my $copies = $params{'copies'}; my $table_nr = $params{'current_opentable_nr'}; my $table_descr; my $cash = $params{'cash'}; my $ccard = $params{'ccard'}; my $ccard_type = $params{'ccard_type'}; my $cheque = $params{'cheque'}; my $account = $params{'account'}; my $discount = $params{'discount'} > 0 ? $params{'discount'} : 0; my $loyalty = $params{'loyalty'}; my $supervised_by = $params{'supervised_by'}; $supervised_by = undef unless $supervised_by; my $voidedflag; my $demomode; my $lastopsid; my $lastcdate; $results = $dbh->prepare(" select substring_index(group_concat(tod.tableops_id order by dcash.date desc), ',', 1) concat_lastops_id, substring_index(group_concat(dcash.date order by dcash.date desc), ',', 1) concat_lastdate from dcash, tillordersdetails tods, tillorders tod where dcash.last_tillid = tods.id and tod.id = tods.orders_id and dcash.date > DATE_SUB(CURRENT_DATE, INTERVAL 15 day) group by dcash.id order by dcash.date desc limit 1 ;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $lastopsid = $ref->{concat_lastops_id} || 0; $lastcdate = $ref->{concat_lastdate} || "2000-01-01"; my $unique = $tableopsid - $lastopsid; #print "here... $tillprinter $supervisor_flag $invoice"; my $printflag = 1; if (! $supervisor_flag) { my $invcount = 0; $results = $dbh->prepare(" SELECT ttod.invoice invoice FROM tillorders tto, tillordersdetails ttod where ttod.f_status<101 and tto.f_status<101 and tto.id = ttod.orders_id and ttod.split = '$split' and tto.tableops_id = '$tableopsid';"); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { if ($ref->{invoice}>0) {$invcount ++;} } if ($invcount and ! $proforma) {$printflag =0} #split printed } #check whether this is a proforma split if ($printflag || $supervisor_flag) { # get givables when reprint and only check # given if ($supervisor_flag) { #waitron $results = $dbh->prepare(" SELECT inv.client_id client, tilltables.number tablenumber, tilltables.description, inv.voided voided,inv.waitron_id waitron_id, inv.tableops_id tableops_id, ttod.split split from tillinvoices inv, tillordersdetails ttod, tilltables, tilltableops where inv.tableops_id=tilltableops.id and tilltables.id=tilltableops.table_id and inv.f_status<101 and ttod.f_status<101 and inv.id='$invoice' and ttod.invoice=inv.id group by inv.id;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $current_client = $ref->{client}; $waitron_id = $ref->{waitron_id}; $tableopsid = $ref->{tableops_id}; $split = $ref->{split}; $voidedflag = $ref->{voided}; $table_nr = $ref->{tablenumber}; #!!@ if ($current_client) { $results = $dbh->prepare("select name from $sharedclients.tillclients where f_status < 100 and id = $current_client;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $current_client_name = $ref->{name}; } }#End super flag $results = $dbh->prepare("SELECT tilltables.description from tilltables, tilltableops where tilltableops.id = '$params{tableops_id}' and tilltables.id=tilltableops.table_id;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $table_descr = $ref->{description}; my ($waitron,$guests); if ($waitron_id) { #waitron $results = $dbh->prepare("SELECT name from waitron where id='$waitron_id';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $waitron = $ref->{name}; $demomode = 1 if ($waitron =~ /!DEMO!/sgi); #covers $results = $dbh->prepare("SELECT sum(current_covers)/count(id) visitors from tillorders where current_covers>0 and tableops_id='$tableopsid' and f_status<101;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $guests = $ref->{visitors}*1; #loyalty - simple mode - under construction $results = $dbh->prepare("SELECT * from tillloyalty where invoice = '$invoice';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $loyalty = $ref->{card_number} if ($ref->{client_type}==1 and $supervisor_flag); }#end waitronid my (%plunames, %plucategories, %pluprices, %pluqty, @printed, $total, $vat); my $printInstr = 0; # pluDetails is hash of arrays # key is number that starts at 0 # index 0 = plu name # index 1 = plu qty # index 2 = plu price # index 3 = plu instruction count, -1 if plu is an instruction my %pluDetails; my $pluDetailsInd = 0; my $prevPluInd = 0; # used later for grouping, same format as above my %groupedPluDetails; # hash to store total prices of different cost centers my %pluCcTotals; my $existing_plus; my $lastinvoice; # vars used to spread discount over items my $itemCnt; my %pluDiscounts; my %taxsum; my %tax_per_plu; my %sum_tax_per_plu; # PREPARE PLUS if ($tableopsid and $split) { $results = $dbh->prepare(" SELECT menu.id pluid, menu.menu_category menu_category, ttod.plu plu, ttod.name name, ttod.price price, ttod.discount discount, ttod.qty qty, ttod.yield yield, ttod.id id, ttod.invoice invoice, menu.dontprintifzero, menu.printinstruction, menu.type FROM tillordersdetails ttod LEFT OUTER JOIN menu ON (ttod.plu = menu.id), tillorders tto WHERE tto.f_status<100 AND ttod.f_status<100 AND tto.confirm_status = 3 AND (ttod.redeem_lp_id = 0) AND tto.tableops_id = '$tableopsid' AND ttod.orders_id = tto.id AND ttod.split = '$split' AND ttod.plutype IN(1, 2) ORDER BY ttod.id ASC;"); my %nonprint; $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { # if there is not item specific discount add the item quantity to total item count if(!($ref->{discount} > 0)){ $itemCnt += $ref->{qty}; } $subresults = $dbh->prepare("select * from menu_tax where menu_id='$ref->{pluid}';;"); $subresults->execute() or die $subresults->errstr(); while ($subref = $subresults->fetchrow_hashref()) { $sum_tax_per_plu{$ref->{name}}{$subref->{tax_id}} = $tax{$database}{$subref->{tax_id}}{tax}; #print "TAX for $ref->{name} : "; #print $tax_per_plu{$ref->{pluid}}; #print "\n"; #price/(100 + $cvat)*$cvat*qty } push (@printed, $ref->{id}) if $ref->{invoice} <= 0; $lastinvoice = $ref->{invoice} if $ref->{invoice} > 0; if ( $ref->{dontprintifzero} == 1 && $ref->{price} / 1 == 0) { $nonprint{$ref->{name}} = 1; } else { if ($ref->{plu} == 'NULL'){ if ($printInstr == 1) { my @pluArr = ($ref->{name}, 0, 0, -1); $pluDetails{$pluDetailsInd} = \@pluArr; $pluDetailsInd += 1; $pluDetails{$prevPluInd}[3] += 1; } } else { # populate pluname for old total calulcations if (exists $plunames{$ref->{name}}) { if ($pluprices{$ref->{name}} != $ref->{price}) { my $newname = $ref->{name} . " @ $ref->{price}"; $ref->{name} = $newname; $plunames{$ref->{name}} = $ref->{id}; } } else { $plunames{$ref->{name}} = $ref->{id}; } # populate hash of arrays for ordering and group of slip items my @pluArr = ($ref->{name}, 0, $ref->{price}, 0); # use yield as quantity if > 0 if ($ref->{yield} > 0) { @pluArr[1] += $ref->{yield}; } else { @pluArr[1] += $ref->{qty}; } $pluDetails{$pluDetailsInd} = \@pluArr; # increment plu index and set printinstruction var $prevPluInd = $pluDetailsInd; $pluDetailsInd += 1; $printInstr = $ref->{printinstruction}; if (exists $pluCcTotals{$ref->{type}}){ # if yield greater than 0 use it to determine price for plu else use qty if ($ref->{yield} > 0) { $pluCcTotals{$ref->{type}} += ($ref->{price} * $ref->{yield}); } else { $pluCcTotals{$ref->{type}} += ($ref->{price} * $ref->{qty}); } }else{ # if yield greater than 0 use it to determine price for plu else use qty if ($ref->{yield} > 0) { $pluCcTotals{$ref->{type}} = ($ref->{price} * $ref->{yield}); } else { $pluCcTotals{$ref->{type}} = ($ref->{price} * $ref->{qty}); } } } } $plucategories{$ref->{name}} = $ref->{menu_category}; $pluprices{$ref->{name}} = $ref->{price}; $pluDiscounts{$ref->{name}} = $ref->{discount}; if ($ref->{yield} > 0) { $pluqty{$ref->{name}} += $ref->{yield}; $plu_discount += $ref->{discount}*$ref->{yield}; } else { $pluqty{$ref->{name}} += $ref->{qty}; $plu_discount += $ref->{discount}*$ref->{qty}; } $existing_plus ++; } ###Group PLUS### #%groupedPluDetails = groupPlus(%pluDetails); %groupedPluDetails = %pluDetails; #2022-11-06 print what it is showing , same order # calculate totaltax my %totaltax_perplu; foreach my $key (keys %sum_tax_per_plu) { foreach my $tax (keys %{$sum_tax_per_plu{$key}}) { $totaltax_perplu{$key} += $sum_tax_per_plu{$key}{$tax}; } } foreach my $key (keys %sum_tax_per_plu) { foreach my $tax (keys %{$sum_tax_per_plu{$key}}) { $tax_per_plu{$key} += $sum_tax_per_plu{$key}{$tax}; #gross*tax / sum_total_tax # (6.83 * 2) * 10 / (100 + 24 ) #print "$key $totaltax_perplu{$key} \n"; # determine discount per item my $itemDiscount = 0; $itemDiscount = $discount/$itemCnt if $itemCnt !=0; # calculate total tax for slip if($ref->{plu_discount} > 0){ #2019-10-25 "=" --> "+=" $taxsum{$tax} += ((($pluprices{$key} * $pluqty{$key}) - $ref->{plu_discount})/(100 + $sum_tax_per_plu{$key}{$tax}))*$sum_tax_per_plu{$key}{$tax}; }else{ $taxsum{$tax} += ((($pluprices{$key} * $pluqty{$key}) - ($itemDiscount * $pluqty{$key}))/(100 + $sum_tax_per_plu{$key}{$tax}))*$sum_tax_per_plu{$key}{$tax}; } #NOTEk #$taxsum{$tax} += ($pluprices{$key}*$pluqty{$key}) * $sum_tax_per_plu{$key}{$tax} / #(100 + $totaltax_perplu{$key}); #~ (100 + $sum_tax_per_plu{$key}{$tax})*$sum_tax_per_plu{$key}{$tax}*$pluqty{$key} #~ if ($sum_tax_per_plu{$key}{$tax}); } } } # if split end #prepare total of the invoice $total += $pluqty{$_} * $pluprices{$_} foreach keys %plunames; $vat = pr(($total-$discount) * $cvat/(100+$cvat));#114*14/(100+14) # # INIT PRINTER my $y = 1; my $dc; my %font; if (scalar @printed or ($supervisor_flag and $existing_plus)) { #my $checkthis; # UPDATE INVOICE STATUS if ( ($supervisor_flag and $existing_plus) or ($existing_plus and $lastinvoice)) { #invoice # is existing if ($supervisor_flag) {$checkthis = $invoice;} else { $checkthis = $lastinvoice; foreach (@printed) { $results = $dbh->prepare("UPDATE tillordersdetails set invoice = $checkthis,f_status=1 where id = ?;") or die $dbh->errstr(); $results->execute($_) or die $results->errstr(); } } } else { #normal printout - first one if (! $proforma) { my ($voidedstage,$refundstage,$seq_nr); if ($params{'prof'}) { #quote $subresults = $dbh->prepare("select * from numbers where forcase = 2;") or die $dbh->errstr(); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $seq_nr = $subref->{number} + 1; if ($seq_nr != 1) { $subresults = $dbh->prepare("update numbers set number = ? where forcase = 2; ") or die $dbh->errstr(); $subresults->execute($seq_nr) or die $subresults->errstr(); } else { $subresults = $dbh->prepare("insert into numbers (forcase,number) values (2, ?); ") or die $dbh->errstr(); $subresults->execute($seq_nr) or die $subresults->errstr(); } $voidedstage = 3; } elsif ($params{'ret'}) { # refund - credit note $subresults = $dbh->prepare("select * from numbers where forcase = 3;") or die $dbh->errstr(); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $seq_nr = $subref->{number} + 1; if ($seq_nr != 1) { $subresults = $dbh->prepare("update numbers set number = ? where forcase = 3;") or die $dbh->errstr(); $subresults->execute($seq_nr) or die $subresults->errstr(); } else { $subresults = $dbh->prepare("insert into numbers (forcase,number) values (3, ?);") or die $dbh->errstr(); $subresults->execute($seq_nr) or die $subresults->errstr(); } $ccard = $ccard*(-1); $cheque = $cheque*(-1); $cash = $cash*(-1); $discount = $discount*(-1); $account = $account*(-1); $refundstage = 1; } else { $subresults = $dbh->prepare("select * from numbers where forcase = 1;") or die $dbh->errstr(); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $seq_nr = $subref->{number} + 1; if ($seq_nr != 1) { $subresults = $dbh->prepare("update numbers set number = ? where forcase = 1;") or die $dbh->errstr(); $subresults->execute($seq_nr) or die $subresults->errstr(); } else { $subresults = $dbh->prepare("insert into numbers (forcase,number) values (1, ?);") or die $dbh->errstr(); $subresults->execute($seq_nr) or die $subresults->errstr(); } } #create Invoice my $results = $dbh->prepare("INSERT into tillinvoices (stamp,shop_id,tableops_id,waitron_id,cash,ccard,cheque,account,discount,client_id,supervised_by,ccardtype, voided,isrefund,seq_nr,split,till_id,dorderid,bin_id) values (CURRENT_TIMESTAMP,$shop{id}, $tableopsid, $waitron_id,?,?,?,?,?,?,?,?, ?,?,?,?,?,?,?);") or die $dbh->errstr(); $results->execute($cash,$ccard,$cheque,$account,$discount,$current_client,$supervised_by,$ccard_type, $voidedstage,$refundstage,$seq_nr,$split,$params{'till_id'},$unique,$binid ) or die $results->errstr(); $results->finish(); #important #imediately $subresults = $dbh->prepare("SELECT LAST_INSERT_ID() lastid FROM tillinvoices limit 1;"); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $checkthis = $subref->{lastid}; #remove trigger tillinvoices and use this function Trigger_tillinvoices($dbh,$tableopsid,$split,$checkthis,$voidedstage,$account,$current_client); my $documentsequencenumber; #write invoice in order details foreach (@printed) { $results = $dbh->prepare("UPDATE tillordersdetails set invoice = ?,f_status=1,bin_id=? where id = ?;") or die $dbh->errstr(); $results->execute($checkthis,$binid,$_) or die $results->errstr(); } if($params{'ret'}) { # credit note - negative qty! $subresults = $dbh->prepare("UPDATE tillordersdetails set qty = 0 - qty where invoice = $checkthis;") or die $dbh->errstr(); $subresults->execute() or die $subresults->errstr(); } } else { #a proforma $checkthis = -12; foreach (@printed) { $results = $dbh->prepare("UPDATE tillordersdetails set invoice = $checkthis,f_status=1 where id = ?;") or die $dbh->errstr(); $results->execute($_) or die $results->errstr(); } } } my ($thiscash, $thischeque, $thisccard, $thisaccount, $thisdiscount); if (! $proforma) { $subresults = $dbh->prepare("SELECT * FROM tillinvoices where id = ? and f_status<100"); $subresults->execute($checkthis) or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $thiscash = $subref->{cash}; $thisccard = $subref->{ccard}; $thischeque = $subref->{cheque}; $thisaccount = $subref->{account}; $thisdiscount = $subref->{discount}; $discount = $thisdiscount; } #my $db = DataBase->new(dbh=>$dbh); #my $tinvoice_row = $db->SelectRow("SELECT DATE_FORMAT(stamp,'%e-%m-%Y %H:%i:%s') AS invoce_date , # DATE_FORMAT(last_print,'%e-%m-%Y %H:%i:%s') AS printed_date # FROM tillinvoices where id =?", # $checkthis); $results = $dbh->prepare("SELECT DATE_FORMAT(stamp,'%e-%m-%Y %H:%i:%s') AS invoce_date , DATE_FORMAT(last_print,'%e-%m-%Y %H:%i:%s') AS printed_date FROM tillinvoices where id =? LIMIT 1"); $results->execute($checkthis) or die $results->errstr(); my $tinvoice_row = $results->fetchrow_hashref(); my $invoce_date = $tinvoice_row->{invoce_date}; my $inital_printed_date = $tinvoice_row->{printed_date}; # $db->Exec("UPDATE tillinvoices SET last_print=NOW() where id =? AND last_print is null ",$checkthis) unless $inital_printed_date; unless($inital_printed_date){ $results = $dbh->prepare("UPDATE tillinvoices SET last_print=NOW() where id =? AND last_print is null ") ; $results->execute($checkthis); } $copies=0 if $copies < 0; my $tempbill; #------------------------------------------------------- my $tmprn = ""; #init printout my %tmprns = (); $tempbill .= chr(27)."@"; #init printer $tempbill .= $ps{n}; #------------------------------------------------------- open DATA, "$billtext"; while () { chomp($_); my $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$_",2,0); $tempbill .= $emptyline."\n"; } close DATA; $tempbill =~ s/\[h\]/$ps{dh}/gsi; $tempbill =~ s/\[w\]/$ps{dw}/gsi; $tempbill =~ s/\[b\]/$ps{b}/gsi; $tempbill =~ s/\[c\]/$ps{c}/gsi; $tempbill =~ s/\[n\]/$ps{n}/gsi; $tempbill .= $ps{minuses}."\n"; my $emptyline = " " x $pmax; $emptyline = &align($emptyline,"* $nvat REG No. $tax_number *",2,0); $tempbill .= $emptyline."\n"; if (! $proforma) { if (! $demomode) { if ($params{'ret'}) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"* CREDIT NOTE # $checkthis *",2,0); $tempbill .= $emptyline."\n"; } else { $emptyline = " "x$pmax; #$emptyline = &align($emptyline,"* COPY TAX INVOICE # $checkthis *",2,0); if($reprint_date){ $emptyline = &align($emptyline,"* COPY TAX INVOICE # $ps{bold} $checkthis $ps{bold_off} *",2,0); }else{ $emptyline = &align($emptyline,"* TAX INVOICE # $ps{bold} $checkthis $ps{bold_off} *",2,0); } $tempbill .= $emptyline."\n"; $tempbill .= "\@COPY\@"; } } else { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"* DEMO INVOICE # $checkthis *",2,0); $tempbill .= $emptyline."\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"*** TRAINING MODE !!! ***",2,0); $tempbill .= $emptyline."\n"; } } else { if (! $demomode) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"*** PROFORMA ***",2,0); $tempbill .= $emptyline."\n"; } else { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"*** DEMO PROFORMA ***",2,0); $tempbill .= $emptyline."\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"*** TRAINING MODE !!! ***",2,0); $tempbill .= $emptyline."\n"; } } if ($voidedflag>0 || $params{voidflag}>0) { $emptyline = " " x $pmax; logit("FLAG VoidFlag:" . $voidedflag . ":".$params{voidflag}); #$emptyline = &align($emptyline,"* V O I D - V O I D - V O I D *",2,0); if($voidedflag == 2 || $params{voidflag} ==1 ){ $emptyline = &align($emptyline,"* Return - Return - Return *",2,0); }else{ $emptyline = &align($emptyline,"* V O I D - V O I D - V O I D *",2,0); } $tempbill .= $emptyline."\n"; } ## 2022-04-21 In restaurant mode to enlarge the Table Number and in retail mode to enlarge the order number on soredr slip ## $ps{bold_off}.$ps{bsize_esc} ## screenmode = 2 retail ,screenmode=0 restaurant if ($params{'screenmode'} != 2) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"Your salesperson is $waitron",2,0); $tempbill .= $emptyline."\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"TBL ".$table_nr.", G: $guests, SPL $split, ORD# $unique",2,0); #$emptyline = &align($emptyline,"TBL ".$ps{bsize}.$ps{bold}.$table_nr.$ps{bold_off}.$ps{bsize_esc}.", G: $guests, SPL $split, ORD# $unique",2,0); #$emptyline = &align($emptyline,"TBL $table_nr, G: $guests, SPL $split",2,0); $tempbill .= $emptyline."\n"; if ($table_descr =~ /^\*/) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"CUSTOMER $table_descr",2,0); $tempbill .= $emptyline."\n"; } $tempbill .= $ps{minuses}."\n"; } else { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"Cashier is $waitron",2,0); $tempbill .= $emptyline."\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"CASHPOINT $table_nr, ORDER# ".$ps{bsize}.$ps{bold}.$unique.$ps{bold_off}.$ps{bsize_esc},2,0); $tempbill .= $emptyline."\n"; $tempbill .= $ps{minuses}."\n"; } my $subtotalnet; my @plus = sort {$a <=> $b} keys %groupedPluDetails; #my @plus = keys %groupedPluDetails; ## KEEP as ORIGINAL #open FILE,">>C:/wwwroot/extranet/pos/log.txt"; #print FILE $params{'screenmode'} .' ' .Dumper(\%groupedPluDetails); #close FILE;# 0.1 Biltong @R350/kg = R35 foreach (@plus){ $emptyline = " "x$pmax; # if the current plu is an instruction then dont print quantity and price if($groupedPluDetails{$_}[3] == -1){ $emptyline = &align($emptyline," ",3,$pmax-5); $emptyline = &align($emptyline,$groupedPluDetails{$_}[0],1,6); }else{ $emptyline = &align($emptyline,$groupedPluDetails{$_}[1],3,$pmax-5); #if($screenmode == 2){ # $emptyline = &align($emptyline,$groupedPluDetails{$_}[0] . ' @R'.$groupedPluDetails{$_}[2] .'/kg',1,6); #}else{ $emptyline = &align($emptyline,$groupedPluDetails{$_}[0],1,6); #} #$emptyline = &align($emptyline,$groupedPluDetails{$_}[2],1,8); if ($billexcl == 1) { $emptyline = &align($emptyline,"$currency ".(pr($groupedPluDetails{$_}[2]*$groupedPluDetails{$_}[1]/( (100+$tax_per_plu{$groupedPluDetails{$_}[0]})/100 ) )),3,2); $subtotalnet += $groupedPluDetails{$_}[2]*$groupedPluDetails{$_}[1]/( (100+$tax_per_plu{$groupedPluDetails{$_}[0]})/100 ); } else { #incl $emptyline = &align($emptyline,"$currency ".(pr($groupedPluDetails{$_}[2]*$groupedPluDetails{$_}[1])),3,2); } } $tempbill .= $emptyline."\n"; } #loyalty progam my $onceoffpoints; my $loyalfooter; if ($current_client and $params{enable_loyalty}) { my $invoice = $checkthis; my $paying = readtmp($till_id, "paying"); #~ open DDD, ">/ddd"; #~ print DDD Dumper($paying); #~ close DDD; foreach my $loyalty_program ( keys %{ $paying->{lpoints} }) { $results = $dbh->prepare("select max(id), substring_index(group_concat(running_points order by id desc), ',', 1) running_points from tillclients_loyalty_points where customer_id = ? and loyalty_program = ? group by loyalty_program, customer_id ;") or die $dbh->errstr(); $results->execute($current_client, $loyalty_program) or die $results->errstr(); $ref = $results->fetchrow_hashref(); #max(running_points) running_points $results = $dbh->prepare("insert into tillclients_loyalty_points (stamp, customer_id, loyalty_program, points, invoice, running_points) values (current_timestamp, ?, ?, ?, ?, ?) ;") or die $dbh->errstr(); $results->execute( $current_client, $loyalty_program, $paying->{lpoints}->{$loyalty_program} , $invoice, $ref->{running_points} + $paying->{lpoints}->{$loyalty_program} ) or die $results->errstr(); } if (scalar keys %{$paying->{redeemselect}}) { $results = $dbh->prepare("select * from tillinvoices where id = ?;") or die $dbh->errstr(); $results->execute($checkthis) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $thesplit = $ref->{split}; my $tableops_id = $ref->{tableops_id}; my $waitron_id = $ref->{waitron_id}; #REDeem my $results = $dbh->prepare("INSERT into tillorders (stamp,shop_id,till_id,waitron_id,tableops_id,confirm_status) values (CURRENT_TIMESTAMP,$shop{id}, '$till_id', '$waitron_id', '$tableops_id', '3');") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results->finish(); #imediately $results = $dbh->prepare("SELECT LAST_INSERT_ID() lastid FROM tillorders limit 1;"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $orders_id = $ref->{lastid}; foreach my $item ( keys %{$paying->{redeemselect}} ) { $results = $dbh->prepare("select * from loyalty_redeemplus where id = ?;") or die $dbh->errstr(); $results->execute($item) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $plu = $ref->{menu_id}; my ($loyalty_program, $qty, $points) = split(",",$paying->{redeemselect}->{$item}); $results = $dbh->prepare("SELECT * FROM loyalty_programs where id = ?;"); $results->execute($loyalty_program) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $loyalfooter .= " LOYALTY PROGRAM: $ref->{description}\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"="x$pmax,1,1); $loyalfooter .= $emptyline."\n"; $results = $dbh->prepare("select * from menu where id = ?;") or die $dbh->errstr(); $results->execute($plu) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $name = $ref->{shortname}; my $print_destination = $ref->{print_destination}; $emptyline = " " x $pmax; $emptyline = &align($emptyline,$qty,3,$pmax-5); $emptyline = &align($emptyline,$name,1,6); $loyalfooter .= $emptyline."\n"; #redeem $results = $dbh->prepare("INSERT into tillordersdetails (stamp, shop_id, orders_id, plu, price, discount, qty, menusource, waitron_id, plutype, name, print_destination,till_id, split, invoice, redeem_lp_id, bin_id) values (CURRENT_TIMESTAMP,'$shop{id}', '$orders_id', '$plu', '0', '0', '$qty', '1', '$waitron_id', '1', '$name', '$print_destination', '$till_id', '$thesplit', '$checkthis', '$loyalty_program', '$binid');") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $results->finish(); $results = $dbh->prepare("update menu set stockonhand = stockonhand - ? where id = ?") or die $dbh->errstr(); $results->execute($qty,$plu) or die $results->errstr(); } foreach my $item ( keys %{$paying->{redeemselect}} ) { my ($loyalty_program, $qty, $points) = split(",",$paying->{redeemselect}->{$item}); $results = $dbh->prepare(" select * from loyalty_programs where id = ? ;") or die $dbh->errstr(); $results->execute($loyalty_program) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $subresults = $dbh->prepare("select max(id), substring_index(group_concat(running_points order by id desc), ',', 1) totalpoints from tillclients_loyalty_redeemed where customer_id = ? and loyalty_program = ? group by loyalty_program, customer_id ") or die $dbh->errstr(); $subresults->execute($current_client, $loyalty_program) or die $subresults->errstr(); my $subref = $subresults->fetchrow_hashref(); my $redeemedpoints = $points; if ($ref->{currentbill} == 1) { $redeemedpoints = $paying->{lpoints}->{$loyalty_program}; } my $newrunning = $subref->{totalpoints} + $redeemedpoints; $subresults = $dbh->prepare("insert into tillclients_loyalty_redeemed (customer_id, loyalty_program, points, stamp, description, itemdescription, cost, running_points) values (?, ?, ?, current_timestamp, ?, ?, ?, ?) ") or die $dbh->errstr(); $subresults->execute($current_client, $loyalty_program, $redeemedpoints, 'automatic', '', '', $newrunning ) or die $subresults->errstr(); } } #query if we need to credit redeemplu database with items from refund if($params{'ret'}) { $results = $dbh->prepare(" select tod.qty * lrp.points_requested reversepoints, lrp.loyalty_program from tillordersdetails tod, loyalty_redeemplus lrp where tod.invoice = ? and tod.plu = lrp.menu_id;;") or die $dbh->errstr(); $results->execute($checkthis) or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { #current top points my $subresults = $dbh->prepare("select max(id), substring_index(group_concat(running_points order by id desc), ',', 1) totalpoints from tillclients_loyalty_redeemed where customer_id = ? and loyalty_program = ? group by loyalty_program, customer_id") or die $dbh->errstr(); $subresults->execute($current_client, $ref->{loyalty_program}) or die $subresults->errstr(); my $subref = $subresults->fetchrow_hashref(); my $newrunning = $subref->{totalpoints} + $ref->{reversepoints}; $subresults = $dbh->prepare(" insert into tillclients_loyalty_redeemed (customer_id, loyalty_program, points, stamp, description, itemdescription, cost, running_points) values (?, ?, ?, current_timestamp, ?, ?, ?, ?) ") or die $dbh->errstr(); $subresults->execute($current_client, $ref->{loyalty_program}, $ref->{reversepoints}, 'reversal', '', '', $newrunning ) or die $subresults->errstr(); } } } # LOYALTY $emptyline = " "x$pmax; $emptyline = &align($emptyline,"=========",3,2); $tempbill .= $emptyline."\n"; if ($billexcl == 1) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"SUB-TOTAL: $currency ".pr($subtotalnet),3,2); $tempbill .= $emptyline."\n"; } $tempbill .= "$ps{dh}"; # GRAND $emptyline = " "x$pmax; $emptyline = &align($emptyline,"TOTAL: $currency ".pr($total),3,2); $tempbill .= $emptyline."\n"; if ($discount > 0) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"DISCOUNT: $currency ".pr($discount),3,2); $tempbill .= $emptyline."\n"; } $emptyline = " "x$pmax; $emptyline = &align($emptyline,"=========",3,2); $tempbill .= $emptyline."\n"; #calculate service charge my $schargetotal = $servicecharge; if ($schargetotal > 0) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"SERVICE CHARGE: $currency ".pr($schargetotal),3,2); $tempbill .= $emptyline."\n"; } if ($tenpercent > 0) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"Sugg. Fee Incl.: $currency ".pr($tenpercent),3,2); $tempbill .= $emptyline."\n"; } if ($demomode) { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"DEMO! DEMO! DEMO! DEMO!",3,2); $tempbill .= $emptyline."\n"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"DEMO!!!DUE: $currency ".pr($total-($discount)+$schargetotal),3,2); $tempbill .= $emptyline."\n"; } else { $emptyline = " "x$pmax; $emptyline = &align($emptyline,"DUE: $currency ".pr($total-($discount)+$schargetotal+$tenpercent),3,2); $tempbill .= $emptyline."\n"; } $tempbill .= "$ps{n}"; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"=========",3,2); $tempbill .= $emptyline."\n"; # iterate over cost centers and displaying them along with total price my @ccs = sort {$a <=> $b} keys %pluCcTotals; foreach(@ccs){ $results = $dbh->prepare("SELECT name ccName FROM stocktypes WHERE id = ?;"); $results->execute($_) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $ccName = $ref->{ccName}; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$ccName : $currency ".pr($pluCcTotals{$_}),3,2); $tempbill .= $emptyline."\n"; } $tempbill .= "\n"; if ($params{deptype} and $params{depamount} and ! $supervisor_flag) { #30, 100, Cash, "DEPOSIT", "POS DOC# 12981", 12981 $dbh->do("insert into accounts SET account=1, entityid=?, credit=?, transaction_type=?, description=?, document=?, stamp=CURRENT_TIMESTAMP,date=CURRENT_DATE, tillinvoice_id=?",undef,$current_client, $params{depamount}, $params{deptype}, "DEPOSIT", 'POS DOC# '.$checkthis, $checkthis )||die $results->errstr(); =pre $results = $dbh->prepare("insert into accounts SET account=1, entityid=?, credit=?, transaction_type=?, description=?, document=?, stamp=CURRENT_TIMESTAMP,date=CURRENT_DATE, tillinvoice_id=?") or die $dbh->errstr(); $results->execute( $current_client, $params{depamount}, $params{deptype}, "DEPOSIT", "POS DOC# $checkthis", $checkthis ) or die $results->errstr(); =cut } $tempbill .= $loyalfooter."\n"; if (! $proforma) { $tempbill .= "PAYMENT METHOD:"."\n"; $tempbill .= "\n"; if ($thiscash != 0) { my $due = $total-($discount)+$schargetotal; my $change = ($thiscash + $thisaccount + $thisccard + $thischeque) - $due; $tempbill .= "CASH: $currency ".pr($thiscash < 0 ? $thiscash * -1 : $thiscash)."\n"; if ($change > 0) { $tempbill .= "\nCHANGE: $currency ".pr($change)."\n"; $tempbill .= "* CHANGE WAS DEPOSITED IN YOUR ACCOUNT.\n" if ($params{deptype}); } $tempbill .= "\n"; } $tempbill .= "MOBILE Payment: $currency ".pr($thischeque < 0 ? $thischeque * -1 : $thischeque)."\n\n" if ($thischeque != 0); $tempbill .= "CREDIT CARD: $currency ".pr($thisccard < 0 ? $thisccard * -1 : $thisccard)."\n\n" if ($thisccard != 0); $tempbill .= "ACCOUNT: $currency ".pr($thisaccount < 0 ? $thisaccount * -1 : $thisaccount)."\n\n" if ($thisaccount != 0); if ($thiscash == 0) { my $due = $total-($discount)+$schargetotal; my $change = ($thiscash + $thisaccount + $thisccard + $thischeque) - $due; if ($change > 0) { $tempbill .= "TIP: $currency ".pr($change); $tempbill .= "\n\n"; } } } if ($billexcl == 1) { #TAX BREAKDOWNS my $tax_divider = 0; if ($discount > 0) { $tax_divider = $discount / $total; } foreach my $key (sort {$a <=> $b} keys %taxsum){ my $usetax = $taxsum{$key}; $usetax = $usetax - $usetax * $tax_divider; $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$tax{$database}{$key}{name} $tax{$database}{$key}{tax}%: $currency ".pr( $usetax),2,0); $tempbill .= $emptyline."\n"; } } if ($billexcl != 1) { #TAX BREAKDOWNS foreach my $key (sort {$a <=> $b} keys %taxsum){ $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$tax{$database}{$key}{name} $tax{$database}{$key}{tax}%(INCL): $currency ".pr($taxsum{$key}),2,0); $tempbill .= $emptyline."\n"; } } my $client_limit; my $client_group; if ($current_client) { $results = $dbh->prepare("select * from $sharedclients.tillclients where id = '$current_client';"); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); $client_limit = $ref->{limited}; $client_group = $ref->{clientgroup}; #~ my $clientprint = $ps{minuses}."\n"; #~ $clientprint .= "CUSTOMER: $ref->{name}\n"; #~ $clientprint .= "ADDRESS: [1] $ref->{ph_address} [2] $ref->{ph_address1} [3] $ref->{ph_address2} [4] $ref->{ph_address3} \n" if ($ref->{address}); #~ $clientprint .= "T: $ref->{telephone} " if ($ref->{telephone}); #~ $clientprint .= "M: $ref->{cellphone}" if ($ref->{cellphone}); #~ $clientprint .= "\n"; #~ $subresults = $dbh->prepare(" #~ SELECT tillclients.*, bal.entity_debit, bal.entity_credit, #~ bal.entity_credit - bal.entity_debit credit_balance, #~ tillclients.creditlimit + #~ IF(bal.entity_credit IS NULL OR bal.entity_debit IS NULL,0, bal.entity_credit - bal.entity_debit) available_credit #~ FROM $sharedclients.tillclients tillclients #~ left join account_balance_entity bal on bal.account = 1 and entityid = tillclients.id #~ where tillclients.id = ?;") or die $dbh->errstr(); #~ $subresults->execute($current_client) or die $subresults->errstr(); #~ $subref = $subresults->fetchrow_hashref(); #~ my $account_available = pr($subref->{available_credit}*-1); #~ $clientprint .= $ps{minuses}."\n"; #~ $clientprint .= "YOUR BALANCE: $account_available\n"; #~ $tempbill .= $clientprint; } #~ $tempbill .= "CLIENT: $current_client_name\n\n" if ($current_client_name); $emptyline = " "x$pmax; $emptyline = &align($emptyline,$date,2,0); $tempbill .= $emptyline."\n"; $emptyline = "\nInvoice Created : " .$invoce_date; $tempbill .= $emptyline."\n"; if($supervisor_flag && $inital_printed_date){ $emptyline = "Last Printed : " .$inital_printed_date; $tempbill .= $emptyline."\n"; } $tempbill .= "\n"; $emptyline = "-"x$pmax;$tempbill .= $emptyline."\n"; #~ $emptyline = " "x$pmax; #~ $emptyline = &align($emptyline,"$nvat Inclusive @ $cvat%",2,0); #~ $tempbill .= $emptyline."\n"; #~ foreach my $key (keys %taxsum){ #~ $emptyline = " "x$pmax; #~ $emptyline = &align($emptyline,"$tax{$database}{name}{$key} $currency ".pr($taxsum{$key})." @ $tax{$database}{tax}{$key}% Included",2,0); #~ $tempbill .= $emptyline."\n"; #~ } #PROPERTY LIMITS if ($params{enable_proplim} and $client_limit > 0 and ! $supervisor_flag and ! $params{voidflag}) { my $invoice = $checkthis; #verify whether we must put our count in existing count or create a new one. $subresults = $dbh->prepare(" select concat(current_date, ' 00:00:00') dont_use_here_date, max(countstart) validate, date_add(max(countstart), interval ? day) > current_timestamp valid from tillclients_limitusage where customer_id = ?; ;") or die $dbh->errstr(); $subresults->execute($client_limit, $current_client) or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); my $container_date; if ($subref->{valid}) { $container_date = $subref->{validate}; } else { $container_date = $subref->{dont_use_here_date}; } #~ open (DDD, ">/ddd.ddd"); #~ print DDD $container_date; #~ close (DDD); #calculate limiteds per invoice $subresults = $dbh->prepare("select tods.invoice, sum(mpp.value * tods.qty) qty, mpp.property_id, menu.limiter_id from tillordersdetails tods, menu_properties_properties mpp, menu, menu_properties_allowance mpa where tods.invoice = ? and mpp.menu_id = menu.id and menu.limiter_id = mpa.id and mpa.property_id = mpp.property_id and menu.id = tods.plu group by menu.limiter_id; ;") or die $dbh->errstr(); $subresults->execute($invoice) or die $subresults->errstr(); while ($subref = $subresults->fetchrow_hashref() ) { $results = $dbh->prepare(" insert into tillclients_limitusage (stamp, customer_id, limiter_id, countstart, transaction_qty,invoice) values (current_timestamp, ?, ?, ?, ?, ?) ;") or die $dbh->errstr(); $results->execute( $current_client, $subref->{limiter_id}, $container_date, $subref->{qty}, $invoice ) or die $results->errstr(); } } #//PROPERTY LIMITS if (! $proforma) { open DATA, "$billfooteri"; } else { open DATA, "$billfooter" } while () { chomp($_); my $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$_",1,0); $tempbill .= $emptyline."\n"; } close DATA; ### PRINTING END #$tillprinter $tmprn = $tempbill; $tmprn = client_regex($current_client, $tmprn, $dbh, $sharedclients); #surf all printers and prepare tmprns for the session foreach my $lpdprn (@{$psubst{$tillprinter}}) { $tmprns{$lpdprn} .= $tmprn; #slip body if ($prntype{$lpdprn} == 1) { $tmprns{$lpdprn} .= $ps{cp}; #~ $tmprns{$lpdprn} .= $ps{od}; $tmprns{$lpdprn} .= "\f"; } else { $tmprns{$lpdprn} .= $ps{feed}; } if ($copies <= 1) { $tmprns{$lpdprn} = ($tmprns{$lpdprn})x$copies; $tmprns{$lpdprn} =~ s/\@COPY\@//gsi; } else { my $orig = $tmprns{$lpdprn}; my $copy = $orig; $orig =~ s/\@COPY\@//gsi; my $c = $ps{dh}.$ps{b}; $c .= " ***COPY***COPY***COPY***\n"; $c .= chr(27)."@"; $copy =~ s/\@COPY\@/$c/gsi; $tmprns{$lpdprn} = $orig; $tmprns{$lpdprn} .= ($copy)x($copies-1); } if (! $supervisor_flag and $printqnayes > 0) { #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ my $q_waitron_name = $waitron; my $q_invoice_id = "$ps{dw}$checkthis$ps{n}"; $q_invoice_id = "PROFORMA" if ($qnaproforma == 1); my $qnadata = slurpfile($qnafile); my $qnaprint = $qnadata; $qnaprint = "DATE: ".$date.$qnaprint; #~ $emptyline = " "x$pmax; #~ $emptyline = &align($emptyline,$date,2,0); #~ $tempbill .= $emptyline."\n"; my $qna_id; my %questionz; #qna init $qnaprint =~ /\[formid:(\d+)\]/sgi; $qna_id = $1; $qnaprint =~ s/\[formid:($qna_id)\]//gsi; $qnaprint =~ s/\[waitron\]/$q_waitron_name/gsi; $qnaprint =~ s/\[invoice\]/$q_invoice_id/gsi; $qnaprint =~ s/\[guests\]/$guests/gsi; $qnaprint =~ s/\[table\]/$table_nr/gsi; #styles $qnaprint =~ s/\[dwidth\]/$ps{dw}/gsi; $qnaprint =~ s/\[dheight\]/$ps{dh}/gsi; $qnaprint =~ s/\[normal\]/$ps{n}/gsi; $qnaprint =~ s/\[underline\]/$ps{u}/gsi; #qna question fetch # my @breaked = split (/\n|\r/, $qnaprint); # $_ =~ s/\n|\r// foreach @breaked; # my $cnt1 = 1; # my $cnt2 = 1; # # foreach my $line (@breaked) { # # if ($line =~ /(\[qp\])/) { # $questionz{questions}{$cnt1} = $'; # $cnt1++; # $cnt2 = 1; # } elsif ($line =~ /(\[q\])/) { # $questionz{answers}{$cnt1-1}{$cnt2} = $'; # $cnt2++; # } # # } #debug print # foreach my $question ( sort keys %{$questionz{questions}}) { # #print "\n$question. $questionz{questions}{$question}\n\n"; # foreach my $answer ( sort keys %{ $questionz{answers}{$question} } ) { # #print " $answer. $questionz{answers}{$question}{$answer} \n"; # } # } #--end fetching--- #qna print prepare $qnaprint =~ s/\[qp\]//gsi; $qnaprint =~ s/\[q\]//gsi; $qnaprint = $ps{n}.$qnaprint; if ($prntype{$lpdprn} == 1) { $qnaprint = $qnaprint.$ps{cp}."\n"; } #check whether this table should print this my $table_type; $subresults = $dbh->prepare(" select type from tilltables where shop_id=$shop{id} and f_status<100 and number='$table_nr'; ;"); $subresults->execute() or die $subresults->errstr(); $subref = $subresults->fetchrow_hashref(); $table_type = $subref->{type}; #printqnayes if ($proforma == 1 and $qnaproforma == 1) { $tmprns{$lpdprn} .= $qnaprint if ($table_type != 2 and $table_type != 3 and $table_type != 4); } elsif ($proforma != 1 and $qnaproforma != 1 ) { $tmprns{$lpdprn} .= $qnaprint if ($table_type != 2 and $table_type != 3 and $table_type != 4); } #END QNA STUFF #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } #qna section if(!$printmode){##A4 Printit::printit ("127.0.0.1","127.0.0.1","$lpdprn",$tmprns{$lpdprn}) if ($tmprns{$lpdprn}); } } #close (P); if ($params{voidflag}>0) { $results = $dbh->prepare("UPDATE tillinvoices set stamp=CURRENT_TIMESTAMP, f_status=1, voided = $params{voidflag}, void_reason = ?, supervised_by = $params{voidsupervisedby} where id = $checkthis;") or die $dbh->errstr(); $results->execute($params{voidreason}) or die $results->errstr(); broadcast_void($checkthis, $params{station_id}, {dbh => $dbh}, $screenmode); } $status=1;$message = "INVOICE PRINTED SUCCESSFULY"; } else { #no data to print $status=0;$message="INVALID INVOICE OR SPLIT NUMBER"; } } else { $status=0;$message="SPLIT ALREADY PRINTED"; } #if printflag my $count; if ($tableopsid) { $results = $dbh->prepare(" SELECT ttod.invoice from tillordersdetails ttod, tillorders tto where tto.f_status<100 and ttod.f_status<100 and tto.tableops_id = '$tableopsid' and ttod.orders_id = tto.id and tto.confirm_status = 3 and ttod.plutype = 1 ;"); $results->execute() or die $results->errstr(); while($ref = $results->fetchrow_hashref()) { if ($ref->{invoice} <= 0) {$count++} #not printed yet } }# my $billcount = 0; #EVERYTHING IS PRINTED - TABLE READY TO CLOSE if (! $count) {$billcount = 1}; #closetableflag = 1 means close the table; #$oxml = " \n"; return ($status, $billcount, $message, $checkthis); } ###Group PLUS### # groups plus from pluDetails into groupedPluDetails # expects hash argument of ungrouped plus in following format : # hash consists of key value pairs # key is number that starts at 0, value is array # index 0 = plu name # index 1 = plu qty # index 2 = plu price # index 3 = plu instruction count, -1 if plu is an instruction # returns a hash of grouped plus with same format sub groupPlus { my %ungroupedPluDetails = @_; my %groupedPluDetails; my $pluInd = 0; my $existInd = 0; foreach(keys %ungroupedPluDetails){ # if current plu not an instruction if($ungroupedPluDetails{$_}[3] > -1){ my $match = 0; # iterate over all plus already in new list for (my $i = 0; $i < scalar(keys %groupedPluDetails); $i = $i + 1){ # if the current plu from old list is in the new list and their instruction count is equal if($groupedPluDetails{$i}[0] eq $ungroupedPluDetails{$_}[0] && $groupedPluDetails{$i}[3] == $ungroupedPluDetails{$_}[3]){ if($ungroupedPluDetails{$_}[3] > 0){ # if all associated instructions are the same between old and new list the match for(my $j = 1; $j <= $ungroupedPluDetails{$_}[3]; $j = $j + 1){ if($ungroupedPluDetails{$_ + $j}[0] eq $groupedPluDetails{$i + $j}[0]){ $match = 1; }else{ $match = 0; last; } } }else{ $match = 1; } if($match == 1){ $existInd = $i; last; } } } # if match update plu qty in new list if($match == 1){ $groupedPluDetails{$existInd}[1] += $ungroupedPluDetails{$_}[1]; }else{ # else add new plu to list $groupedPluDetails{$pluInd} = $ungroupedPluDetails{$_}; $pluInd += 1; # as well as associated instructions for(my $i = 1; $i <= $ungroupedPluDetails{$_}[3]; $i = $i + 1){ $groupedPluDetails{$pluInd} = $ungroupedPluDetails{$_ + $i}; $pluInd += 1; } } } } return %groupedPluDetails; } sub retreive_tax { my $database = $_[0]; my %shop = (id => $_[1]); my $dbh = DBI->connect("DBI:mysql:$database;host=127.0.0.1",'root','fbg4ips') or die $DBI::errstr; my ($results, $subresults, $subresults1, $ref,$ref1,$ref2,$subref,$subref1); #/ database $cacheflag{$database} = 1; $tax{$database}=(); $results = $dbh->prepare("SELECT * from tax;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $tax{$database}{$ref->{id}}{name} = $ref->{name}; $tax{$database}{$ref->{id}}{tax} = $ref->{percent}; $tax{$database}{$ref->{id}}{std} = $ref->{std}; $tax{$database}{cvat} += $ref->{percent}; $tax{$database}{nvat} .= $ref->{name}; } #~ #TODO #~ $tax{$database}{cvat} = $tax{$database}{cvat} || 14; } sub close_table_onhold { my %params = %{ $_[0] }; my $dbh = $_[1]->{dbh}; my %shop = (id => $_[2]); my ($results, $ref, $subref,$subresults); my $flag = 1; my $mesg = "SUCCESS"; my $waitron_id = $params{'waitron_id'}; my $table_id = $params{'table_id'}; my $till_id = $params{'till_id'}; #verify whether the table is open $results = $dbh->prepare("select action,id,visitors from tilltableops where table_id='$table_id' order by id desc limit 1;") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $tableops_id = $ref->{id}; my $visitors = $ref->{visitors}; #action will not be "1" even if there is no table operation if ($ref->{action} != 1) {$flag = 0; $mesg="TABLE CLOSED ALREADY!"} #verify whether there is invoices for all the splits my $emptytableflag; #lets close the poor table if ($flag) { $results = $dbh->do("INSERT into tilltableops (stamp,shop_id, waitron_id, till_id, action, table_id) values (CURRENT_TIMESTAMP,$shop{id}, $waitron_id, '$till_id', 2, $table_id);") or die $dbh->errstr(); $results = $dbh->prepare(" UPDATE tilltables SET description = '' WHERE id = ? AND description LIKE '*%'; ") or die $dbh->errstr(); $results->execute($table_id) or die $results->errstr(); # create onhold entry $results = $dbh->prepare(" INSERT into tillonholds (user_id,tableops_id,client_id) values (?,?,?); ") or die $dbh->errstr(); $results->execute( $waitron_id,$tableops_id,$params{'client_id'} ) or die $results->errstr(); #REOPEN THE TABLE if ($params{qm} == 1) { $results = $dbh->do("INSERT into tilltableops (stamp,shop_id, waitron_id, till_id, action, table_id, visitors) values (CURRENT_TIMESTAMP, $shop{id}, $waitron_id, $till_id, 1, $table_id, '$visitors');") or die $dbh->errstr(); } } return($flag, $mesg); } sub close_table { my %params = %{ $_[0] }; my $dbh = $_[1]->{dbh}; my %shop = (id => $_[2]); my ($results, $ref, $subref,$subresults); my $flag = 1; my $mesg = "SUCCESS"; my $waitron_id = $params{'waitron_id'}; my $table_id = $params{'table_id'}; my $till_id = $params{'till_id'}; #verify whether the table is open $results = $dbh->prepare("select action,id,visitors from tilltableops where table_id='$table_id' order by id desc limit 1") or die $dbh->errstr(); $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $tableops_id = $ref->{id}; my $visitors = $ref->{visitors}; #action will not be "1" even if there is no table operation if ($ref->{action} != 1) {$flag = 0; $mesg="TABLE CLOSED ALREADY!"} #verify whether there is invoices for all the splits my $emptytableflag; if ($flag) { $results = $dbh->prepare(" select count(tods.id) noinvoices from tillordersdetails tods,tillorders tod where tod.confirm_status=3 and tods.orders_id = tod.id and tods.plutype=1 and (tods.invoice=0 or tods.invoice is null or tods.invoice < 0) and tod.tableops_id = '$tableops_id'; ;") or die $dbh->errstr(); #~ open (DEBUGER, ">/DEBUGER"); #~ print DEBUGER " #~ select count(tods.id) noinvoices #~ from tillordersdetails tods,tillorders tod #~ where #~ tod.confirm_status=3 #~ and tods.orders_id = tod.id #~ and tods.plutype=1 #~ and (tods.invoice=0 or tods.invoice is null or tods.invoice < 0) #~ and tod.tableops_id = '$tableops_id'; #~ ;"; #~ close DEBUGER; $results->execute() or die $results->errstr(); $ref = $results->fetchrow_hashref(); if ($ref->{noinvoices}) {$flag = 0; $mesg="OUTSTANDING PAYMENT!"} #~ else { #~ $emptytableflag = 1; #~ $results = $dbh->prepare(" #~ delete tods.*, tod.* #~ from tillordersdetails tods,tillorders tod #~ where #~ tod.confirm_status <> 3 #~ and tods.orders_id = tod.id #~ and (tods.invoice=0 or tods.invoice is null or tods.invoice < 0) #~ and tod.tableops_id = '$tableops_id'; #~ ;") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ $results = $dbh->prepare(" #~ delete from tilltableops where id = '$tableops_id' #~ ;") or die $dbh->errstr(); #~ $results->execute() or die $results->errstr(); #~ } } #lets close the poor table if ($flag) { #~ if (! $emptytableflag) { $results = $dbh->do("INSERT into tilltableops (stamp,shop_id, waitron_id, till_id, action, table_id) values (CURRENT_TIMESTAMP,$shop{id}, $waitron_id, '$till_id', 2, $table_id);") or die $dbh->errstr(); #~ } #remove star comments $results = $dbh->prepare(" UPDATE tilltables SET description = '' WHERE id = ? AND description LIKE '*%'; ") or die $dbh->errstr(); $results->execute($table_id) or die $results->errstr(); #$results = $dbh->do("update tilltables set quick_mode = 1 where id='$table_id';") or die $dbh->errstr(); #REOPEN THE TABLE ##WHY REOPEN ? if ($params{qm} == 1) { $results = $dbh->do("INSERT into tilltableops (stamp,shop_id, waitron_id, till_id, action, table_id, visitors) values (CURRENT_TIMESTAMP, $shop{id}, $waitron_id, $till_id, 1, $table_id, '$visitors')") or die $dbh->errstr(); } } #$oxml = " \n"; return($flag, $mesg); } sub client_regex { my $client_id = $_[0]; my $text = $_[1]; my $dbh = $_[2]; my $sharedclients = $_[3]; my $repolacer; $repolacer->{clientid} = $client_id; if ($client_id > 0) { my $results = $dbh->prepare("select * from $sharedclients.tillclients where id = ? ") or die $dbh->errstr(); $results->execute($client_id) or die $results->errstr(); my $ref = $results->fetchrow_hashref(); my $client_limit_days = $ref->{limited}; $repolacer->{name} = $ref->{name}; $repolacer->{company} = $ref->{clientgroup}; $repolacer->{idnumber} = $ref->{idnumber}; $repolacer->{posaddress1} = $ref->{address}; $repolacer->{posaddress2} = $ref->{address1}; $repolacer->{posaddress3} = $ref->{address2}; $repolacer->{posaddress4} = $ref->{address3}; $repolacer->{phaddress1} = $ref->{ph_address}; $repolacer->{phaddress2} = $ref->{ph_address1}; $repolacer->{phaddress3} = $ref->{ph_address2}; $repolacer->{phaddress4} = $ref->{ph_address3}; $repolacer->{cardnumber} = $ref->{loyalnumber}; $repolacer->{accountcode} = $ref->{code}; $repolacer->{fixeddiscount} = $ref->{discountpercent}; $repolacer->{telephone} = $ref->{telephone}; $repolacer->{cellphone} = $ref->{cellphone}; #~ $repolacer->{propertylimits} = $ref->{}; $repolacer->{notes} = $ref->{note}; $repolacer->{clientvatnr} = $ref->{tax_number}; #~ my $results = $dbh->prepare("SELECT lp.description, SUBSTRING_INDEX(GROUP_CONCAT(p.running_points ORDER BY p.stamp DESC), ',', 1) AS running_points FROM tillclients_loyalty_points p, loyalty_programs lp WHERE p.loyalty_program = lp.id AND customer_id = ?; ") or die $dbh->errstr(); $results->execute($client_id) or die $results->errstr(); while (my $ref1 = $results->fetchrow_hashref()) { $repolacer->{loyaltypoints} .= $ref1->{description} . ": ". $ref1->{running_points} . "\n" ; } my $pricelist = $ref->{pricelist}; if ($pricelist > 0) { $results = $dbh->prepare(" select * from menu_pricelists where id = ?;") or die $dbh->errstr(); $results->execute($pricelist) or die $results->errstr(); $ref = $results->fetchrow_hashref(); $repolacer->{pricelist} = $ref->{description}; } else { $repolacer->{pricelist} = 'Default'; } #~ #loyalty points #~ $results = $dbh->prepare(" #~ select #~ lp.id, #~ lp.autoredeem, #~ lp.currentbill, #~ lp.item_description, #~ lp.item_cost, #~ lp.description, #~ lp.points_requested, #~ lp.notification, #~ max(tlp.running_points) totalpoints #~ from #~ loyalty_programs lp, tillclients_loyalty_points tlp #~ where tlp.customer_id = ? and lp.currentbill != 1 #~ and lp.id = tlp.loyalty_program and #~ lp.active = 1 and ((lp.activeafter <= CURRENT_DATE or lp.activeafter = '') #~ and (lp.activebefore >= CURRENT_DATE or lp.activebefore = '')) #~ group by lp.id; #~ ") or die $dbh->errstr(); #~ $results->execute($client_id) or die $results->errstr(); #~ while ($ref = $results->fetchrow_hashref()) { #~ my $subresults = $dbh->prepare("select max(running_points) totalredeemed from tillclients_loyalty_redeemed #~ where customer_id = ? and loyalty_program = ?") or die $dbh->errstr(); #~ $subresults->execute($client_id, $ref->{id}) or die $subresults->errstr(); #~ my $subref = $subresults->fetchrow_hashref(); #~ my $lbalance = $ref->{totalpoints} - $subref->{totalredeemed}; #~ if ($lbalance > 0) { #~ if ($lbalance >= $ref->{points_requested}) { #~ $repolacer->{loyaltypoints} .= "-"x$pmax."\n"; #~ $repolacer->{loyaltypoints} .= "LOYALTY PROGRAM: $ref->{description}\n"; #~ $repolacer->{loyaltypoints} .= "$ref->{notification}\n"; #~ if ($ref->{autoredeem} > 1 && $ref->{currentbill} != 1) { #~ my $subresults = $dbh->prepare(" #~ select max(running_points) totalpoints #~ from tillclients_loyalty_redeemed where customer_id = ? and loyalty_program = ? #~ ") or die $dbh->errstr(); #~ $subresults->execute($client_id, $ref->{id}) or die $subresults->errstr(); #~ my $subref = $subresults->fetchrow_hashref(); #~ my $redeemedpoints = $lbalance; #~ if ($ref->{autoredeem} == 3) { #~ $redeemedpoints = $ref->{points_requested}; #~ } #~ my $newrunning = $subref->{totalpoints} + $redeemedpoints; #~ $repolacer->{loyaltypoints} .= "$redeemedpoints Points was redeemed.\n"; #~ $subresults = $dbh->prepare(" #~ insert into tillclients_loyalty_redeemed #~ (customer_id, loyalty_program, points, stamp, description, itemdescription, cost, running_points) #~ values #~ (?, ?, ?, stamp, ?, ?, ?, ?) #~ ") or die $dbh->errstr(); #~ $subresults->execute($client_id, $ref->{id}, $redeemedpoints, 'automatic', $ref->{item_description}, $ref->{item_cost}, $newrunning #~ ) or die $subresults->errstr(); #~ } #~ } else { #~ my $pointstogo = $ref->{points_requested} - $lbalance; #~ $repolacer->{loyaltypoints} .= "-"x$pmax."\n"; #~ $repolacer->{loyaltypoints} .= "LOYALTY PROGRAM: $ref->{description}\n"; #~ $repolacer->{loyaltypoints} .= "$lbalance of $ref->{points_requested} points collected.\n"; #~ $repolacer->{loyaltypoints} .= "You need ".($pointstogo)." more point".($pointstogo > 1 ? 's' : '').".\n"; #~ } #~ } #~ $repolacer->{loyaltypoints} = $ref->{}; #~ } $results = $dbh->prepare(" SELECT tillclients.*, bal.entity_debit, bal.entity_credit, bal.entity_credit - bal.entity_debit credit_balance, tillclients.creditlimit , tillclients.creditlimit + IF(bal.entity_credit IS NULL OR bal.entity_debit IS NULL,0, bal.entity_credit - bal.entity_debit) available_credit FROM $sharedclients.tillclients tillclients left join account_balance_entity bal on bal.account = 1 and entityid = tillclients.id where tillclients.id = ?;") or die $dbh->errstr(); $results->execute($client_id) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $account_available = pr($ref->{available_credit}*-1); ##20230608 my $available_balance = pr($ref->{creditlimit} - $ref->{credit_balance}); $repolacer->{currentbalance} = $account_available; $repolacer->{available_balance} = $available_balance; #property limits if ($enable_proplim == 1 and $client_limit_days > 0) { my $property_totals; $repolacer->{propertylimits} = '-'x$pmax."\n"; #opening balance #verify for currently open count. $results = $dbh->prepare(" select concat(current_date, ' 00:00:00') dont_use_here_date, max(countstart) validate, date_add(max(countstart), interval ? day) > current_timestamp valid from tillclients_limitusage where customer_id = ?; ") or die $dbh->errstr(); $results->execute($client_limit_days, $client_id) or die $results->errstr(); $ref = $results->fetchrow_hashref(); my $container_date; if ($ref->{valid}) { $container_date = $ref->{validate}; $results = $dbh->prepare(" select tlu.limiter_id, sum(tlu.transaction_qty) qty from tillclients_limitusage tlu, tillinvoices inv where inv.id = tlu.invoice and tlu.countstart = ? and (inv.voided =0 or inv.voided is null) and tlu.customer_id=? group by tlu.limiter_id; ") or die $dbh->errstr(); $results->execute($container_date, $client_id) or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { $property_totals->{$ref->{limiter_id}} = $ref->{qty}; } } $results = $dbh->prepare(" select description, id, allowance from menu_properties_allowance ;"); $results->execute() or die $results->errstr(); while ($ref = $results->fetchrow_hashref()) { my $proptotal; $proptotal = pr($ref->{allowance} - $property_totals->{$ref->{id}}); my $emptyline = " "x$pmax; $emptyline = &align($emptyline,"$ref->{description}",1,0); $emptyline = &align($emptyline,"$proptotal",3,0); $repolacer->{propertylimits} .= $emptyline."\n"; } } } my $regexcnt =0; my $lastblock; while ($text =~ /client{(.*?)}/s) { $regexcnt ++; my $result; my $block = $1; if ($repolacer->{clientid}) { $result = $block; while ( $result =~ /\[(.*?)\]/s) { my $parameter = $1; $result =~ s/\Q[$parameter]\E/$repolacer->{$parameter}/; } } $text =~ s/\Qclient{$block}\E/$result/; if ($regexcnt > 1 && $lastblock eq $block && $block ne '') { $text .= "\nREGEX ERROR.\nCONTACT SPACEBIZ SUPPORT\nBLOCK:\"$block\""; } $lastblock = $block; } return $text; } sub poleformat { my $line1; my $line2; my $emptyline; $emptyline = " "x$polewidth; $emptyline = &align($emptyline,$_[0],1,0); $emptyline = &align($emptyline,$_[1],3,0); $line1 = $emptyline; $emptyline = " "x$polewidth; $emptyline = &align($emptyline,$_[2],1,0); $emptyline = &align($emptyline,$_[3],3,0); $line2 = $emptyline; my $allpole = $line1."".$line2; $allpole =~ s/\'/\\'/gsi; return $allpole; } sub slurpanyfile { open(IN, "< $_[0]");# or die "can't open $_[0]: $!"; binmode (IN); seek(IN, 0, 0); sysread (IN, my $slurp, -s IN); close(IN); return $slurp; } sub stringtimeshort { my $globalseconds = $_[0]; $globalseconds *= -1 if ($globalseconds < 0); my $daysml; my $remain; my $seconds; my $minutes; my $hours; my $days; $seconds = sprintf (" %02d sec", $globalseconds % 60); $minutes = sprintf (" %02d min", int($globalseconds / 60) % 60); $hours = sprintf (" %02d hours ",int($globalseconds / 3600) % 24); $days = int($globalseconds / 86400); $daysml = sprintf (" %d days".",", $days) if ($days>0); my $tresult; $daysml = $daysml if ($_[0] < 0); $tresult .= $daysml if $days*1>0; $tresult .= $hours if $hours*1>0; $tresult .= $minutes if $minutes*1>0; return $tresult || '00 min'; } sub centRound { my ($price,$nearest) = @_; my $round = sprintf("%.2f",($price / $nearest)) * $nearest; if (sprintf("%.2f",$round) > sprintf("%.2f",$price)) { $round -= $nearest / 100; } return $round; } sub supervisorLog{ my($dbh,$suser,$rsn,$what,$case,$trans_id,$terminal_id,$user_id,$plu) = @_; logit("$suser,$rsn,$what,$case,$trans_id,$terminal_id,$user_id,$plu"); my $subresults = $dbh->prepare("insert into supervisorlog (supervisor, reason, stamp, supervisingwhat, transaction_case, transaction_id, terminal_id, user, plu) values(?, ?, current_timestamp, ?, ?, ?, ?, ?,?)") or die $dbh->errstr(); $subresults->execute($suser, $rsn, $what,$case, $trans_id,$terminal_id,$user_id,$plu ) or die $subresults->errstr(); return '1'; } sub logit{ my $content = shift; my @t = getTime(); my ($year,$month,$day,$hour,$minute,$second) = ($t[0],$t[1],$t[2],$t[3],$t[4],$t[5]); return 1; #return unless $content=~/(PRINTER)/i; open FILE,">>$tdir/spacebiz.pm.log"; print FILE "\n==== $year-$month-$day $hour:$minute:$second ===\n";print FILE $content;print "\n"; close FILE; } sub write2log{ return 1; open FILE,">>$tdir/spacebiz.pm.log"; print FILE shift;print FILE "\n"; close FILE; } sub getTime { my ($time) = @_; my @t = localtime(); return ( sprintf("%04d",$t[5]+1900), sprintf("%02d",$t[4]+1), sprintf("%02d",$t[3]), sprintf("%02d",$t[2]), sprintf("%02d",$t[1]), sprintf("%02d",$t[0]) ); } #sub Trigger_tillinvoices{ # return ; #} sub getWeightQty{ my ($dbh,$unit_weight,$orgprice) = @_; my $results = $dbh->prepare("SELECT scale_value FROM spaceusers.scales LIMIT 1") ;##or die $dbh->errstr(); $results->execute();## or die $results->errstr(); my $ref = $results->fetchrow_hashref(); my $w = $ref->{scale_value} ||0; #my $db = DataBase->new(dbh=>$dbh); #my $w = $db->SelectOne("SELECT scale_value FROM spaceusers.scales LIMIT 1")||'0.00'; #WHERE created + INTERVAL 5 MINUTE > NOW() if($w > 0 && $unit_weight > 0){ return int(($w / $unit_weight) *1000) /1000 .":".int(($w / $unit_weight) * $orgprice * 1000)/1000; } return "0".":".$orgprice; } sub Trigger_tillinvoices{ my($dbhs,$tableops_id,$split,$id,$VOIDED,$ACCOUNT,$client_id) = @_; #&logit("FLAGTrigger:$tableops_id,$split,$id,$VOIDED,$ACCOUNT,$client_id\n"); #FLAGTrigger: 24389, 1, 11364,,, my ($flag_isrefund,$voided_condition); my $result = $dbhs->selectrow_arrayref("SELECT isrefund FROM tillinvoices WHERE id=?",undef,$id); my $flag_isrefund_db = $result->[0];#$db->SelectOne("SELECT isrefund FROM tillinvoices WHERE id=?",$id); $flag_isrefund = $flag_isrefund_db if $flag_isrefund_db > 0; $voided_condition = $VOIDED if $VOIDED > 0; if($voided_condition !=3){ my $res = $dbhs->selectall_arrayref("SELECT tods.plu,tods.qty FROM tillordersdetails AS tods, tillorders AS tod where tods.orders_id = tod.id and tod.tableops_id = ? and tods.split = ?", { Slice=>{} }, $tableops_id,$split ); foreach( @$res ) { if($flag_isrefund != 1){ $dbhs->do("update menu set stockonhand = stockonhand - ? where id = ?",undef, $_->{qty},$_->{plu}); }else{ $dbhs->do("update menu set stockonhand = stockonhand + ? where id = ?",undef, $_->{qty},$_->{plu}); } } if($ACCOUNT !=0){ my $account_amount = abs($ACCOUNT); $result = $dbhs->selectrow_arrayref("SELECT date from dcash where f_status < 100 order by date desc limit 1"); my $debtor_date = $result->[0]; if($ACCOUNT > 0){ $dbhs->do("INSERT INTO accounts SET account=?, entityid=?, debit=?, description=?, document=?, stamp=current_timestamp, date=?, tillinvoice_id=?",undef, 1, $client_id, $account_amount, "INVOICE", 'POS DOC# '. $id, $debtor_date, $id); }else{ $dbhs->do("INSERT INTO accounts SET account=?, entityid=?, credit=?, description=?, document=?, stamp=current_timestamp, date=?, tillinvoice_id=?",undef, 1, $client_id, $account_amount, "REFUND", 'POS DOC# '. $id, $debtor_date, $id); } } } } sub Trigger_tillinvoices_BAK{ my($dbhs,$tableops_id,$split,$id,$VOIDED,$ACCOUNT,$client_id) = @_; &logit("FLAGTrigger:$tableops_id,$split,$id,$VOIDED,$ACCOUNT,$client_id\n"); #FLAGTrigger: 24389, 1, 11364,,, my ($flag_isrefund,$voided_condition); my $db = DataBase->new(dbh=>$dbhs); my $flag_isrefund_db = $db->SelectOne("SELECT isrefund FROM tillinvoices WHERE id=?",$id); $flag_isrefund = $flag_isrefund_db if $flag_isrefund_db > 0; $voided_condition = $VOIDED if $VOIDED > 0; if($voided_condition !=3){ my $list = $db->SelectARef("SELECT tods.plu,tods.qty FROM tillordersdetails AS tods, tillorders AS tod where tods.orders_id = tod.id and tod.tableops_id = ? and tods.split = ?",$tableops_id,$split); foreach(@$list){ if($flag_isrefund != 1){ $db->Exec("update menu set stockonhand = stockonhand - ? where id = ?",$_->{qty},$_->{plu}); }else{ $db->Exec("update menu set stockonhand = stockonhand + ? where id = ?",$_->{qty},$_->{plu}); } } if($ACCOUNT !=0){ my $account_amount = abs($ACCOUNT); my $debtor_date = $db->SelectOne("SELECT date from dcash where f_status < 100 order by date desc limit 1"); if($ACCOUNT > 0){ $db->Exec("INSERT INTO accounts SET account=?, entityid=?, debit=?, description=?, document=?, stamp=current_timestamp, date=?, tillinvoice_id=?", 1, $client_id, $account_amount, "INVOICE", 'POS DOC# '. $id, $debtor_date, $id); }else{ $db->Exec("INSERT INTO accounts SET account=?, entityid=?, credit=?, description=?, document=?, stamp=current_timestamp, date=?, tillinvoice_id=?", 1, $client_id, $account_amount, "REFUND", 'POS DOC# '. $id, $debtor_date, $id); } } } } sub posGET{ my $url = "$HotelierBase:$HotelierPORT/posInhouseList?SiteId=$HotelierSite_id"; eval{ my $req = HTTP::Request::Common::GET $url; $req->header('Authorization', $HotelierToken); my $ua = LWP::UserAgent->new; my $res = $ua->request($req); my $ret = JSON::decode_json($res->decoded_content); #print Dumper($ret); my $resNo = $ret->{inHouse}->[0]->{resNo}; return $resNo; }; } sub posAccountPost{ my (%opts) = @_; # return '' unless $HotelierBase=~/hotelierapi/i; #return ($status, $billcount, $message, $checkthis); my $resNo = posGET(); my $db = DataBase->new(dbh=>$opts{dbh}); my $tm = localtime(time); my $date = sprintf("%02d/%02d/%04d",($tm->mon+1),$tm->mday,($tm->year + 1900)); my $time = sprintf("%02d:%02d",$tm->hour, $tm->min); my @items; my $list = $db->SelectARef("select (ttod.price*ttod.qty) price, (ttod.discount*ttod.qty) plu_discount, ttod.price uprice, ttod.qty qty, ttod.yield yield, ttod.name name, ttod.orders_id, ttod.plu, m.menu_category, s.name type from tillordersdetails ttod LEFT JOIN menu m ON m.id = ttod.plu LEFT JOIN stocktypes s ON s.id=ttod.plutype where ttod.invoice = ? and ttod.f_status < 101 and ttod.plu > 0",$opts{invoice}); foreach (@$list){ my $item; $item->{item} = $_->{name}; $item->{category} = $db->SelectOne("SELECT name FROM menu_categories WHERE id=?",$_->{menu_category}); $item->{type} = $_->{type}; $item->{unitCost} = $_->{uprice}; $item->{qty} = $_->{qty}; push @items,$item if $item->{unitCost} > 0; } my $js; $js->{PostGroup}->{siteId} = $HotelierSite_id; $js->{PostGroup}->{resNo} = $resNo; $js->{PostGroup}->{split} = 'A'; $js->{PostGroup}->{docket} = $opts{invoice}; $js->{PostGroup}->{terminal} = ""; $js->{PostGroup}->{waiter} = $db->SelectOne("SELECT name FROM `waitron` WHERE id=?", $opts{waitron_id}); $js->{PostGroup}->{date} = $date; $js->{PostGroup}->{time} = $time; $js->{PostGroup}->{tip} = ''; $js->{PostGroup}->{lineItems} = \@items; my $req = HTTP::Request::Common::POST "$HotelierBase:$HotelierPORT/posAccountPost", Content_Type => 'application/json', Content => JSON::encode_json($js); $req->header('Authorization', $HotelierToken); my $ua = LWP::UserAgent->new(ssl_opts=>{verify_hostname=>0,ssl_ciper_list=>''}); my $res = $ua->request($req); #logit($res->decoded_content); my $ret = JSON::decode_json($res->decoded_content); return $ret->{id}; =pre { "PostGroup" : { "siteId" : value, "resNo" : value, "split" : value, "docket" : value, "terminal" : value, "waiter" : value, "date" : value, "time" : value, "tip" : value }, "lineItems" : [ { "item" : value, "category" : value, "type" : value, "qty" : value, "unitCost" : value } ] } =cut } sub retreive_printers{ my $dbh = DBI->connect("DBI:mysql:spaceusers;host=127.0.0.1",'root','fbg4ips') or die $DBI::errstr; my @row = $dbh->selectrow_array("SELECT val FROM printers WHERE id=1 LIMIT 1"); if(!$row[0]){ $dbh->do("UPDATE printers SET val=?",undef,qq|{"prntype":{"192.168.5.32/till":1,"192.168.5.31/till":1,"192.168.5.33/kitchen":1,"192.168.5.33/till":1},"psubst":{"T1":["192.168.5.31/till"],"T4":["192.168.5.31/till"],"K1":["192.168.5.33/kitchen","192.168.5.33/till"],"T3":["192.168.5.32/till"],"T2":["192.168.5.33/till"]},"altord":{"1":{},"2":{}}}|); @row = $dbh->selectrow_array("SELECT val FROM printers WHERE id=1 LIMIT 1"); } my $p_setup = JSON::decode_json($row[0]); %psubst = %{$p_setup->{psubst} }; %prntype = %{$p_setup->{prntype}}; %altord = %{$p_setup->{altord}}; #return (%{$p_setup->{psubst} },%{$p_setup->{altord}},%{$p_setup->{prntype}}); } package settings; sub new { my ($class,$sys_settings) = @_; my $self; #print "Content-type:text/html\n\n"; foreach my $key(keys %{$sys_settings}){ #print qq|("OPTS:" ${$key} $key=> $sys_settings->{$key} )\n
    |; ${$key} = $sys_settings->{$key}; } ${'tablesep'} = 1; return $self; } sub DESTROY { my $self = shift; } package DataBase; use DBI; sub new{ my ($class, %opts) = @_; my $self = { %opts }; bless $self,$class; $self->{'db_name'} = ''; $self->InitDB; return $self; } sub inherit{ my $class = shift; my $dbh = shift; my $self={ dbh=>undef }; bless $self,$class; $self->{dbh} = $dbh; return $self; } sub dbh{shift->{dbh}} sub InitDB{ my $self = shift; $self->{'exec'}=0; $self->{'select'}=0; } sub DESTROY{ #shift->UnInitDB(); } sub UnInitDB{ my $self=shift; if($self->{dbh}) { if($self->{locks}) { $self->Unlock(); } $self->{dbh}->disconnect; } $self->{dbh}=undef; } sub Exec { my $self=shift; $self->{dbh}->do(shift,undef,@_) || die"Can't exec:\n".$self->{dbh}->errstr; $self->{'exec'}++; } sub SelectOne { my $self=shift; my $res = $self->{dbh}->selectrow_arrayref(shift,undef,@_); die"Can't execute select:\n".$self->{dbh}->errstr if $self->{dbh}->err; $self->{'select'}++; return $res->[0]; }; sub SelectRow { my $self=shift; my $s = shift; #print STDERR $s; my $res = $self->{dbh}->selectrow_hashref($s,undef,@_); die"Can't execute select:\n".$self->{dbh}->errstr if $self->{dbh}->err; $self->{'select'}++; return $res; } sub Select { my $self=shift; my $sql = shift; my $res = $self->{dbh}->selectall_arrayref($sql, { Slice=>{} }, @_ ); die"Can't execute select:\n".$self->{dbh}->errstr if $self->{dbh}->err; return undef if $#$res==-1; my $cidxor=0; for(@$res) { $cidxor = $cidxor ^ 1; $_->{row_cid} = $cidxor; } $self->{'select'}++; return $res; } sub SelectARef { my $self = shift; my $data = $self->Select(@_); return [] unless $data; return [$data] unless ref($data) eq 'ARRAY'; return $data; } sub getLastInsertId { return shift->{ dbh }->{'mysql_insertid'}; } 1;