package TTXDesk; # # This module is a part of Trouble Ticket Express package # http://www.troubleticketexpress.com # # COPYRIGHT: 2002-2006, United Web Coders # http://www.unitedwebcoders.com # # $Revision: 248 $ # $Date: 2006-08-15 07:22:26 -0400 (Tue, 15 Aug 2006) $ # $TTXDesk::VERSION='2.22'; BEGIN { $TTXDesk::REVISION = '$Revision: 248 $'; if ($TTXDesk::REVISION =~ /(\d+)/) { $TTXDesk::REVISION = $1; } }; use strict; use TTXCommon; use TTXUser; use TTXTickets; require TTXMarkup; my @brcols = ('id', 'name', 'email', 'subject', 'oper', 'status', 'open', 'updated'); my %c2t = ( id => 'id', name => 'name', email => 'email', subject => 'subject', oper => 'operator', status => 'status', updated => 'updated', open => 'created', grp => 'group' ); my %c2T = ( id => 'Ticket #', tid => 'Ticket #', name => 'Name', email => 'Email', fltrsubj => 'Subject', oper => 'Operator', status => 'Status', lname => 'Name', grp => 'Group' ); my @rclr = ('#F0F0E1', '#E8E8CF'); my @rcls = ('orow', 'erow'); # =================================================================== invenabled my $_invenabled = undef; sub invenabled { if ($_invenabled eq undef) { eval 'use TTXInvMod'; if ($@ eq undef) { $_invenabled = 1; } else { $_invenabled = 0; } } return $_invenabled; } # ================================================================== buildfilter sub buildfilter { my ($cfg, $query, $data) = @_; my $width = $cfg->get('HTMLBASEWIDTH') || 700; my $buff = "\n"; if ($cfg->get('fltrcols') eq undef) { $cfg->set('fltrcols', 'text|subject|oper|status|id'); $cfg->save(); } my $cfldcnt = TTXCommon::cfldcnt(); foreach my $var ($cfg->vars()) { next if $var !~ /^x/; my $pos = $cfg->get($var); next if $pos < 0 || $pos >= $cfldcnt; $var =~ s/^x//; $var =~ /^(.{1,15})(.*)/; $var = $1; # $val .= '...' if $2 ne undef; $c2T{"c$pos"} = $var; } my $colcnt = 0; my @fltrcols = split(/\|/, $cfg->get('fltrcols')); if (grep(/^subject$/, @fltrcols)) { @fltrcols = grep(!/^subject$/, @fltrcols); @fltrcols = ('subject', @fltrcols); } if (grep(/^text$/, @fltrcols)) { @fltrcols = grep(!/^text$/, @fltrcols); @fltrcols = ('text', @fltrcols); } if (grep(/^drange$/, @fltrcols)) { @fltrcols = grep(!/^drange$/, @fltrcols); @fltrcols = (@fltrcols, 'drange'); } foreach my $fld (@fltrcols) { $fld = 'fltrsubj' if $fld eq 'subject'; $fld = 'tid' if $fld eq 'id'; if ($colcnt > 2) { $buff .= "\n"; $colcnt = 0; } if (!$colcnt) { $buff .= "\n"; } ++$colcnt; if ($fld eq 'text') { $buff .= ''."\n\n"; ++$colcnt; } $buff .= "\n\n"; } $buff .= ''."\n". "\n"; } else { $buff .= ''."\n".'\n"; ++$colcnt; } $buff .= "\n"; } $buff .= "
[%Text%] "; ++$colcnt; # text is always first element } elsif ($fld eq 'drange') { if ($colcnt > 1) { while ($colcnt <= 2) { $buff .= "  
[%Date Range%]\n \n  ".TTXCommon::pickdate($query, 'drs', 1). " - ".TTXCommon::pickdate($query, 'dre', 0)."[%'.$c2T{$fld}.'%] '; } if ($fld eq 'oper') { $buff .= $data->{OPERSELBOX}; } elsif ($fld eq 'item') { if (invenabled()) { $buff .= TTXInvMod::selbox($cfg, $query, 0); } else { $buff .= ' '; } } elsif ($fld eq 'status') { $buff .= $data->{STATUSSELBOX}; } elsif ($fld eq 'grp') { $buff .= $data->{GRPSELBOX}; } elsif ($fld ne 'drange'){ my $val = $query->param($fld); $fld =~ /^c(\d+)$/; if ($1 ne undef && $cfg->get("dropdown$1") ne undef) { my @options = split(/;/, $cfg->get("dropdown$1")); $buff .= "\n"; } else { $val =~ s/&/&/g; $val =~ s/\n"; } if ($colcnt) { while ($colcnt < 3) { $buff .= " 
"; $data->{TICKETFILTER} = $buff; } # ===================================================================== helpdesk sub helpdesk { my ($cfg, $query, $data) = @_; my $browsetxt = 0; $data->{PAGEHEADING} = '[%Help Desk%]'; TTXCommon::tickedvars($cfg, $data); $c2T{item} = $cfg->get('inventory.label') || 'Item'; $c2t{item} = lc $cfg->get('inventory.label') || 'item'; my $cfldcnt = TTXCommon::cfldcnt(); if ($query->param('tk') ne undef) { $query->param(-name => 'key', -value => $query->param('tk')); return 'ticket'; } my $user = $cfg->get('_USER'); my $session; my $readonly; if ($user ne undef) { $session = $user->get('session'); $readonly = $user->get('ro') ? 1:0; } if (!$query->param('do')) { $session->qexpand($query, 'helpdesk') if $session ne undef; if ($query->param('status') eq undef) { $query->param(-name => 'status', -value => $cfg->get('defaultstatus')); } } elsif ($session ne undef) { my @fldlist = ('text', 'oper', 'tid', 'status', 'lname', 'name', 'email', 'fltrsubj', 'grp', 'qwindow', 'qsort', 'qsortorder', 'drfld', 'drsday', 'drsmon', 'drsyear', 'dreday', 'dremon', 'dreyear', 'item'); for (my $i = 0; $i < $cfldcnt; ++$i) { push @fldlist, "c$i"; } foreach my $id (@fldlist) { if ($query->param($id) ne $session->get("helpdesk.$id")) { $query->param(-name => 'qoffset', -value => ''); last; } } } if ($query->param('reset') ne undef) { foreach my $fld ('text', 'oper', 'tid', 'status', 'lname', 'name', 'email', 'fltrsubj', 'grp', 'qoffset', 'drfld', 'item') { $query->param(-name => $fld, -value => ''); } for (my $i = 0; $i < $cfldcnt; ++$i) { $query->param(-name => "c$i", -value => ''); } foreach my $pref ('drs', 'dre') { foreach my $fld ('day', 'mon', 'year') { $query->param(-name => $pref.$fld, -value => ''); } } } if ($cfg->get('brcols') eq undef) { $cfg->set('brcols', 'id|name|email|subject|oper|status|open|updated'); $cfg->save(); } if ($cfg->get('brcols') ne undef) { @brcols = split(/\|/, $cfg->get('brcols')); my @cfgvars = $cfg->vars(); foreach my $var (@cfgvars) { next if $var !~ /^x/; my $cidx = int ($cfg->get($var)); next if ($cidx < 0 || $cidx >= $cfldcnt); $var =~ s/^x//; $c2t{"c$cidx"} = $var; } } if ($query->param('abstract')) { $browsetxt = 1; $data->{CHECKABSTRACT} = ' checked'; } $data->{GRPSELBOX} = "\n"; my @operlist = TTXUser::list(); $data->{OPERSELBOX} = "\n"; $data->{STATUSSELBOX} = "\n"; buildfilter($cfg, $query, $data); my $tickets = TTXCommon::dbtik(); if ($tickets eq undef || $tickets->error() ne undef) { $data->{ERROR_MESSAGE} = $tickets->errortext(); return undef; } my @filter; if ($query->param('oper') ne undef) { my $f; $f->{col} = 'oper'; if ($query->param('oper') ne '-') { $f->{expr} = "^".$query->param('oper')."\$"; } else { $f->{expr} = "^\$"; } push @filter, $f; } if ($query->param('grp') ne undef) { my $f; $f->{col} = 'grp'; if ($query->param('grp') ne '-') { $f->{expr} = "^".$query->param('grp')."\$"; } else { $f->{expr} = "^\$"; } push @filter, $f; } if ($query->param('item') ne undef) { my $f; $f->{col} = 'item'; if ($query->param('item') ne '-') { $f->{expr} = "^.*;".$query->param('item').";.*\$"; } else { $f->{expr} = "^\$"; } push @filter, $f; } if ($cfg->get('accessctrl') && $cfg->get('routex') ne undef) { my $n = $cfg->get('routex'); if ($n =~ /^\d$/) { eval "use TTXCustomRoute"; if ($@ eq undef) { my @list = TTXCustomRoute::grouplist($cfg); if (@list > 0) { my $f; $f->{col} = "c$n"; $f->{expr} = '^('.join('|', @list).')$'; push @filter, $f; } } } } if ($cfg->get('accessctrl') && $cfg->get('_USER') ne undef) { eval "use TTXGroups"; if (!$@) { my @list = TTXGroups::grouplist($cfg, $cfg->get('_USER')->{login}); my $f; $f->{col} = '-grp-'; $f->{groups} = \@list; $f->{oper} = $cfg->get('_USER')->{login}; push @filter, $f; } } if ($query->param('status') ne undef) { my $f; $f->{col} = 'status'; $f->{expr} = "^".$query->param('status')."\$"; push @filter, $f; } my $hideoldsolved; if ($query->param('text') ne undef) { my $f; $f->{col} = 'text'; $f->{expr} = $query->param('text'); $browsetxt = 2; push @filter, $f; $hideoldsolved = $cfg->set('hideoldsolved', ''); } if ($query->param('cmd') eq 'mytickets') { my $f; $f->{col} = 'email'; my $emailkey = $query->param('emailkey'); $emailkey =~ s/\*//g; $f->{expr} = "^$emailkey\$"; push @filter, $f; } if ($query->param('tid') ne undef) { my $f; $f->{col} = 'id'; $f->{expr} = "^".$query->param('tid')."\$"; $f->{expr} =~ s/\*/.*/g; push @filter, $f; } my @fields = ('name', 'lname', 'fltrsubj', 'email'); for (my $i = 0; $i < $cfldcnt; ++$i) { push @fields, "c$i"; } foreach my $fld (@fields) { if ($query->param($fld) ne undef) { my $f; if ($fld eq 'fltrsubj') { $f->{col} = 'subject'; } else { $f->{col} = $fld; } my ($wc, $wc1); if ($fld =~ /^c\d+$/ && $cfg->get("$fld.type") eq 'list') { $wc = '*;'; $wc1 = ';*'; } $f->{expr} = "^$wc".$query->param($fld)."$wc1\$"; $f->{expr} =~ s/\*/.*/g; push @filter, $f; } } if ($query->param('qoffset') eq undef) { $query->param(-name => 'qoffset', -value => 0); } if ($query->param('qwindow') eq undef) { $query->param(-name => 'qwindow', -value => 20); } if ($query->param('qsort') eq undef) { $query->param(-name => 'qsort', -value => 'updated'); } if ($query->param('qsortorder') eq undef) { $query->param(-name => 'qsortorder', -value => 'D'); } my %drange; if ($query->param('drfld') ne undef) { eval "use Time::Local"; if ($@ eq undef) { $query->param('drfld') =~ /^(created|updated|solved)$/; if ($1 ne undef) { $drange{fld} = $1; $drange{stm} = Time::Local::timegm(0,0,0,$query->param('drsday'),$query->param('drsmon'),$query->param('drsyear')) - $cfg->get('timezone') * 60; $drange{etm} = Time::Local::timegm(59,59,23,$query->param('dreday'),$query->param('dremon'),$query->param('dreyear')) - $cfg->get('timezone') * 60; } } } my $browser = $tickets->list($query->param('qoffset'), $query->param('qwindow'), $query->param('qsort'), $query->param('qsortorder'), \@filter, \%drange); if ($query->param('text') ne undef) { $cfg->set('hideoldsolved', $hideoldsolved); } my $list = $browser->{list}; if (@{$list} < 1) { $data->{TICKETLIST} = '[%There are no tickets matching your query%]'; } else { my $ccnt = scalar @brcols; ++$ccnt if $query->param('cmd') ne 'mytickets' && !$readonly; my $lspan = int($ccnt / 2); my $rspan = $ccnt - $lspan; if ($query->param('cmd') ne 'mytickets') { $data->{TICKETLIST} .= "
\n". "\n". "\n". "\n"; } $data->{TICKETLIST} .= "".'[%Tickets%] '. ($browser->{first} + 1)." - ".$browser->{last}.' [%out of%] '. $browser->{total}."". ""; if ($browser->{first} > 0) { $data->{TICKETLIST} .= "param('qwindow')."')".'">[%first%] '; } else { $data->{TICKETLIST} .= '[%first%] '; } if ($browser->{first} > 0) { my $back = $browser->{first} - $query->param('qwindow'); $back = 0 if $back < 0; $data->{TICKETLIST} .= "param('qwindow')."')\">".'[%prev%] '; } else { $data->{TICKETLIST} .= '[%prev%] '; } if ($browser->{last} < $browser->{total}) { my $frw = $browser->{first} + $query->param('qwindow'); $data->{TICKETLIST} .= "param('qwindow')."')\">".'[%next%] '; } else { $data->{TICKETLIST} .= '[%next%] '; } if ($browser->{last} < $browser->{total}) { my $frw = $browser->{total} - $query->param('qwindow'); $data->{TICKETLIST} .= "param('qwindow')."')\">".'[%last%] '; } else { $data->{TICKETLIST} .= '[%last%] '; } $data->{TICKETLIST} .= "\n"; $data->{TICKETLIST} .= "get('imgurl')."/dot.gif\" height=2>"; $data->{TICKETLIST} .= "\n"; if ($query->param('cmd') ne 'mytickets' && !$readonly) { $data->{TICKETLIST} .= '[%sel%]'."\n"; } foreach my $col (@brcols) { my $order = 'A'; if ($query->param('qsort') eq $col) { if ($query->param('qsortorder') eq 'A') { $order = 'D'; } } else { $order = $query->param('qsortorder'); } $data->{TICKETLIST} .= "".'[%'.$c2t{$col}.'%]'."\n"; } $data->{TICKETLIST} .= "\n"; my $i = 0; my $j = 0; my %colormatrix = (PND => 'green', WFR => 'blue', OPN => 'orange', CLS => 'red', LATE => 'red'); my $now = time(); foreach my $id (@{$list}) { my ($fcopen, $fcclose); my $clr = $rclr[$i]; my $cl = $rcls[$i]; ++$i; ++$j; $i = 0 if $i > 1; my $t = $tickets->ticket($id); if ($cfg->get('colortickets')) { $fcopen = ""; $fcclose = ""; } if ($cfg->get('claimtime') && (($t->{status} eq 'PND' && ($now - $t->{open} > 24*60*60) && !$cfg->get('ignorepending') ) || $t->{status} ne 'PND' && $t->{'c'.$cfg->get('claimtime')} > 23)) { $fcopen = ""; $fcclose = ""; } $data->{TICKETLIST} .= "\n"; if ($query->param('cmd') ne 'mytickets' && !$readonly) { $data->{TICKETLIST} .= "\n"; } foreach my $col (@brcols) { my $val = $t->{$col}; my $align = 'right'; if (grep(/^$col$/, ('open', 'updated', 'closed'))) { $val = "$fcopen".TTXCommon::tmtxt($val)."$fcclose"; } elsif ($col eq 'status') { $val = $fcopen.'[%'.TTXCommon::status($val).'%]'.$fcclose; } elsif ($col eq 'id') { $val = "$fcopen$val$fcclose"; if (!$readonly) { $val = "$val"; } } elsif ($col eq 'grp') { $val = $fcopen.($cfg->get($val) || '-').$fcclose; } elsif ($col eq 'subject') { $align = 'left'; my $dots = '...'; $val =~ s/\b([^\s]{15,15})([^\s])*/$1.$dots/ge; $val =~ /^(.{1,30})(.*)/; $val = $1; $val .= '...' if $2 ne undef; $val =~ s/param('cmd') eq 'mytickets') { $emailkey = "&emailkey=".$query->param('emailkey'); } $val = "param('sid')."&key=".$t->{key}.$emailkey. "&qsort=".$query->param('qsort')."&qsortorder=".$query->param('qsortorder'). "&qoffset=".$query->param('qoffset')."&qwindow=".$query->param('qwindow'). "&oper=".$query->param('oper')."&status=".$query->param('status')."&style=".$query->param('style'). "&lname=".$query->param('lname')."&c0=".$query->param('c0')."&fltrsubj=".$query->param('fltrsubj'). "\">$fcopen$val$fcclose"; } elsif ($col eq 'name') { $align = 'left'; $val = $fcopen.$val.$fcclose; } elsif ($col eq 'item') { if (invenabled()) { my $items = TTXInvMod::getitems($val); $val = undef; foreach my $item (@{$items}) { my $lbl = $item->{title}; my $dots = '...'; $lbl =~ s/\b([^\s]{15,15})([^\s])*/$1.$dots/ge; $lbl =~ s/{id}."')\">$lbl"; } if ($val eq undef) { $val = '-'; } $val = $fcopen.$val.$fcclose; } else { $val = $fcopen."???".$fcclose; } } elsif ($col eq 'email') { my $dots = '...'; my $adr = $val; $val =~ s/\b([^\s]{15,15})([^\s])*/$1.$dots/ge; $val = "$fcopen$val$fcclose"; } else { if ($val ne undef) { if ($col =~ /^c\d+/ && $cfg->get("$col.type") eq 'list') { $val =~ s/^;//; $val =~ s/;$//; } } else { $val = "-"; } $val =~ s//>/g; $val =~ s/(\d\d\d\d-\d\d-\d\d)/''.$1.'<\/nobr>'/eg; $val = $fcopen.$val.$fcclose; } # $val = "-" if $val eq undef; if ($query->param('qsort') eq $col) { $val = "$val"; } $data->{TICKETLIST} .= "$val\n"; } $data->{TICKETLIST} .= "\n"; if ($browsetxt) { my $body; if ($browsetxt < 2) { my $msg = shift (@{$t->{messages}}); my @msgparts = split(/\n\n/, $msg); shift @msgparts; $body = join("\n\n", @msgparts); $body =~ s/{abstract}->{$t->{id}}; } $body =~ s/^\s+//s; if ($body =~ /^(.{1,340})/s) { $body = $1; } $data->{TICKETLIST} .= "\n \n"; $data->{TICKETLIST} .= "$body\n"; $data->{TICKETLIST} .= "\n"; } } $data->{TICKETLIST} .= "get('imgurl')."/dot.gif\" height=2>". "\n". "\n"; if ($query->param('cmd') ne 'mytickets' && !$readonly) { my $operselbox; my $userid = $cfg->get('_USER')->{login}; if ($cfg->get('grant.assign') eq undef || grep(/^$userid$/, split(/,/, $cfg->get('grant.assign')))) { $operselbox = "\n"; $operselbox = "\n$operselbox"; } $data->{TICKETLIST} .= "\n"; } $data->{TICKETLIST} .= "
\n"; if (!($cfg->get('demo') && $userid ne 'admin') && ($cfg->get('grant.delete') eq undef || grep(/^$userid$/, split(/,/, $cfg->get('grant.delete'))))) { $data->{TICKETLIST} .= '\n"; } $data->{TICKETLIST} .= "$operselbox"; if ($browser->{first} > 0) { $data->{TICKETLIST} .= "param('qwindow')."')\">".'[%first%]'." "; } else { $data->{TICKETLIST} .= '[%first%] '; } if ($browser->{first} > 0) { my $back = $browser->{first} - $query->param('qwindow'); $back = 0 if $back < 0; $data->{TICKETLIST} .= "param('qwindow')."')\">".'[%prev%]'." "; } else { $data->{TICKETLIST} .= '[%prev%] '; } if ($browser->{last} < $browser->{total}) { my $frw = $browser->{first} + $query->param('qwindow'); $data->{TICKETLIST} .= "param('qwindow')."')\">".'[%next%]'." "; } else { $data->{TICKETLIST} .= '[%next%] '; } if ($browser->{last} < $browser->{total}) { my $frw = $browser->{total} - $query->param('qwindow'); $data->{TICKETLIST} .= "param('qwindow')."')\">".'[%last%]'." "; } else { $data->{TICKETLIST} .= '[%last%] '; } $data->{TICKETLIST} .= "
\n"; $data->{TICKETLIST} .= "\n"; } if ($session ne undef) { my @savelist = ('text', 'oper', 'tid', 'status', 'lname', 'name', 'email', 'fltrsubj', 'grp', 'qwindow', 'qoffset', 'qsort', 'qsortorder', 'abstract', 'drfld', 'drsday', 'drsmon', 'drsyear', 'dreday', 'dremon', 'dreyear'); for (my $i = 0; $i < $cfldcnt; ++$i) { $query->param(-name => "c$i", -value => ''); } $session->qsave($query, 'helpdesk', \@savelist); } return undef; } 1; #