this change will fix the problems with the userProfileData table being way too big. it also simplifies many basic user search tasks, not needing to join the userProfileData table
585 lines
19 KiB
Perl
585 lines
19 KiB
Perl
package WebGUI::Asset::Wobject::InOutBoard;
|
|
|
|
|
|
use strict;
|
|
use WebGUI::HTMLForm;
|
|
use WebGUI::International;
|
|
use WebGUI::Paginator;
|
|
use WebGUI::SQL;
|
|
use Tie::IxHash;
|
|
|
|
use Moose;
|
|
use WebGUI::Definition::Asset;
|
|
extends 'WebGUI::Asset::Wobject';
|
|
define tableName => 'InOutBoard';
|
|
define assetName => ['assetName', 'Asset_MapPoint'];
|
|
define icon => 'iob.gif';
|
|
property statusList => (
|
|
tab => 'properties',
|
|
fieldType => "textarea",
|
|
builder => '_statusList_builder',
|
|
lazy => 1,
|
|
label => [1, 'Asset_InOutBoard'],
|
|
hoverHelp => ['1 description', 'Asset_InOutBoard'],
|
|
subtext => [2, 'Asset_InOutBoard'],
|
|
);
|
|
sub _statusList_builder {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $i18n = WebGUI::International->new($session, 'Asset_InOutBoard');
|
|
return $i18n->get(10)."\n".$i18n->get(11)."\n";
|
|
}
|
|
property reportViewerGroup => (
|
|
tab => 'security',
|
|
default => 3,
|
|
fieldType => "group",
|
|
label => [3, 'Asset_InOutBoard'],
|
|
hoverHelp => ["3 description", 'Asset_InOutBoard'],
|
|
);
|
|
property inOutGroup => (
|
|
tab => 'security',
|
|
default => 2,
|
|
fieldType => "group",
|
|
label => ['inOutGroup', 'Asset_InOutBoard'],
|
|
hoverHelp => ['inOutGroup description', 'Asset_InOutBoard'],
|
|
);
|
|
property inOutTemplateId => (
|
|
tab => 'display',
|
|
fieldType => "template",
|
|
namespace => "InOutBoard",
|
|
label => ["In Out Template", 'Asset_InOutBoard'],
|
|
hoverHelp => ["In Out Template description", 'Asset_InOutBoard'],
|
|
default => 'IOB0000000000000000001',
|
|
);
|
|
property reportTemplateId => (
|
|
tab => 'display',
|
|
fieldType => "template",
|
|
default => 'IOB0000000000000000002',
|
|
label => [13, 'Asset_InOutBoard'],
|
|
hoverHelp => ["13 description", 'Asset_InOutBoard'],
|
|
namespace => "InOutBoard/Report"
|
|
);
|
|
property paginateAfter => (
|
|
tab => 'display',
|
|
fieldType => "integer",
|
|
default => 50,
|
|
label => [12, 'Asset_InOutBoard'],
|
|
hoverHelp => ['12 description', 'Asset_InOutBoard'],
|
|
);
|
|
|
|
#See line 285 if you wish to change the users visible in the delegate select list
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
sub _defineUsername {
|
|
my $data = shift;
|
|
if ($data->{firstName} ne "" && $data->{lastName} ne "") {
|
|
return join ' ', $data->{firstName}, $data->{lastName};
|
|
}
|
|
else {
|
|
return $data->{username};
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
sub _fetchNames {
|
|
my $self = shift;
|
|
my @userIds = @_;
|
|
my %nameHash;
|
|
my $sql = "SELECT users.username, users.userId, firstName, lastName
|
|
FROM users
|
|
WHERE users.userId=?";
|
|
my $sth = $self->session->db->prepare($sql);
|
|
foreach my $userId (@userIds) {
|
|
$sth->execute([ $userId ]);
|
|
$nameHash{ $userId } = _defineUsername($sth->hashRef);
|
|
}
|
|
$sth->finish;
|
|
return %nameHash;
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
sub _fetchDepartments {
|
|
my $self = shift;
|
|
return $self->session->db->buildArray("SELECT department FROM userProfileData GROUP BY department");
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 getStatusList
|
|
|
|
Returns the statusList property as an array
|
|
|
|
=cut
|
|
|
|
sub getStatusList {
|
|
my $self = shift;
|
|
my $text = $self->get('statusList');
|
|
|
|
return
|
|
grep { $_ } # no empty lines
|
|
map { s/^\s+//; s/\s+$//; $_ } # trim
|
|
split(/\r\n|\r|\n/, $text); # seperated by any kind of newline
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 prepareView ( )
|
|
|
|
See WebGUI::Asset::prepareView() for details.
|
|
|
|
=cut
|
|
|
|
sub prepareView {
|
|
my $self = shift;
|
|
$self->SUPER::prepareView();
|
|
my $template = WebGUI::Asset::Template->newById($self->session, $self->inOutTemplateId);
|
|
if (!$template) {
|
|
WebGUI::Error::ObjectNotFound::Template->throw(
|
|
error => qq{Template not found},
|
|
templateId => $self->inOutTemplateId,
|
|
assetId => $self->getId,
|
|
);
|
|
}
|
|
$template->prepare($self->getMetaDataAsTemplateVariables);
|
|
$self->{_viewTemplate} = $template;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 purge ( )
|
|
|
|
Extend the base method to cleanup the status and statusLog tables.
|
|
|
|
=cut
|
|
|
|
override purge => sub {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
$session->db->write('delete from InOutBoard_status where assetId=?', [$self->getId]);
|
|
$session->db->write('delete from InOutBoard_statusLog where assetId=?', [$self->getId]);
|
|
super();
|
|
};
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 view
|
|
|
|
Render the viewing screen, which displays In/Out status and a form to change
|
|
status.
|
|
|
|
=cut
|
|
|
|
sub view {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my %var;
|
|
my $url = $self->getUrl('func=view');
|
|
|
|
my $i18n = WebGUI::International->new($self->session, "Asset_InOutBoard");
|
|
if ($session->user->isInGroup($self->reportViewerGroup)) {
|
|
$var{'viewReportURL'} = $self->getUrl("func=viewReport");
|
|
$var{'viewReportLabel'} = $i18n->get('view report label');
|
|
$var{canViewReport} = 1;
|
|
}
|
|
else {
|
|
$var{canViewReport} = 0;
|
|
}
|
|
|
|
my $statusUserId = $self->session->scratch->get("userId") || $self->session->user->userId;
|
|
tie my %statusOptions, 'Tie::IxHash', (
|
|
map { $_ => $_ } $self->getStatusList
|
|
);
|
|
|
|
#$self->session->log->warn("VIEW: userId: ".$statusUserId."\n" );
|
|
my ($status) = $session->db->quickArray(
|
|
"select status from InOutBoard_status where userId=? and assetId=?",
|
|
[ $statusUserId, $self->getId]
|
|
);
|
|
|
|
##Find all the users for which I am a delegate
|
|
my @users = $session->db->buildArray(
|
|
"select userId from InOutBoard_delegates where assetId=? and delegateUserId=?",
|
|
[ $self->getId, $session->user->userId ]
|
|
);
|
|
|
|
my $f = WebGUI::HTMLForm->new($session,-action=>$self->getUrl);
|
|
if (@users) {
|
|
my %names = (
|
|
$self->_fetchNames(@users),
|
|
"" => $i18n->get('myself'),
|
|
);
|
|
my @options =
|
|
map { @$_ }
|
|
sort { $a->[1] cmp $b->[1] }
|
|
map { [ $_, $names{$_} ] }
|
|
keys %names
|
|
;
|
|
|
|
$f->selectBox(
|
|
-name=>"delegate",
|
|
-options=>\@options,
|
|
-value=>[ $session->scratch->get("userId") ],
|
|
-label=>$i18n->get('delegate'),
|
|
-hoverHelp=>$i18n->get('delegate description'),
|
|
-extras=>q|onchange="this.form.submit();"|,
|
|
);
|
|
}
|
|
$f->radioList(
|
|
-name=>"status",
|
|
-value=>$status,
|
|
-options=>\%statusOptions,
|
|
-label=>$i18n->get(5),
|
|
-hoverHelp=>$i18n->get('5 description'),
|
|
);
|
|
$f->text(
|
|
-name=>"message",
|
|
-label=>$i18n->get(6),
|
|
-hoverHelp=>$i18n->get('6 description'),
|
|
);
|
|
$f->hidden(
|
|
-name=>"func",
|
|
-value=>"setStatus"
|
|
);
|
|
$f->submit;
|
|
|
|
my ($isInGroup) = $session->db->quickArray(
|
|
"select count(*) from groupings where userId=? and groupId=?",
|
|
[ $session->user->userId, $self->inOutGroup ]
|
|
);
|
|
if ($isInGroup) {
|
|
$var{displayForm} = 1;
|
|
$var{'form'} = $f->print;
|
|
$var{'selectDelegatesURL'} = $self->getUrl("func=selectDelegates");
|
|
$var{'selectDelegatesLabel'} = $i18n->get('select delegates label');
|
|
}
|
|
else {
|
|
$var{displayForm} = 0;
|
|
}
|
|
|
|
my $lastDepartment = "_nothing_";
|
|
|
|
my $p = WebGUI::Paginator->new($session, $url, $self->paginateAfter);
|
|
|
|
my $sql = "select users.username,
|
|
users.userId,
|
|
firstName,
|
|
InOutBoard_status.message,
|
|
lastName,
|
|
InOutBoard_status.status,
|
|
InOutBoard_status.dateStamp,
|
|
department,
|
|
groupings.groupId
|
|
from users
|
|
left join groupings on groupings.userId=users.userId
|
|
left join InOutBoard on groupings.groupId=InOutBoard.inOutGroup
|
|
left join userProfileData on users.userId=userProfileData.userId
|
|
left join InOutBoard_status on users.userId=InOutBoard_status.userId and InOutBoard_status.assetId=?
|
|
where users.userId<>'1' and InOutBoard.inOutGroup=?
|
|
group by userId
|
|
order by department, lastName, firstName";
|
|
|
|
$p->setDataByQuery($sql, undef, 0, [ $self->getId, $self->inOutGroup ], );
|
|
my $rowdata = $p->getPageData();
|
|
my @rows;
|
|
foreach my $data (@$rowdata) {
|
|
my %row;
|
|
if ($lastDepartment ne $data->{department}) {
|
|
$row{deptHasChanged} = 1;
|
|
$row{'department'} = ($data->{department}||$i18n->get(7));
|
|
$lastDepartment = $data->{department};
|
|
}
|
|
else { $row{deptHasChanged} = 0; }
|
|
|
|
if ($data->{firstName} ne "" && $data->{lastName} ne "") {
|
|
$row{'username'} = $data->{firstName}." ".$data->{lastName};
|
|
}
|
|
else {
|
|
$row{'username'} = $data->{username};
|
|
}
|
|
|
|
$row{'status'} = ($data->{status} || $i18n->get(15));
|
|
$row{'dateStamp'} = $data->{status} ? $self->session->datetime->epochToHuman($data->{dateStamp}) : " ";
|
|
$row{'message'} = ($data->{message} || " ");
|
|
|
|
push (@rows, \%row);
|
|
}
|
|
$var{rows_loop} = \@rows;
|
|
$var{'paginateBar'} = $p->getBarTraditional();
|
|
$p->appendTemplateVars(\%var);
|
|
|
|
return $self->processTemplate(\%var,undef,$self->{_viewTemplate});
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_selectDelegates
|
|
|
|
Form where a user can select delegates, other users who are allowed to change
|
|
their status.
|
|
|
|
=cut
|
|
|
|
sub www_selectDelegates {
|
|
my $self = shift;
|
|
my %userNames = ();
|
|
my $sth = $self->session->db->read(
|
|
"select
|
|
users.username,
|
|
users.userId,
|
|
firstName,
|
|
lastName
|
|
from users
|
|
left join groupings on users.userId=groupings.userId
|
|
left join InOutBoard on groupings.groupId=InOutBoard.inOutGroup
|
|
left join InOutBoard_status on users.userId=InOutBoard_status.userId and InOutBoard_status.assetId=?
|
|
where
|
|
users.userId<>'1'
|
|
and users.status='Active'
|
|
and users.userId <> ?
|
|
and InOutBoard.inOutGroup=?
|
|
group by userId
|
|
",[$self->getId, $self->session->user->userId, $self->inOutGroup]);
|
|
while (my $data = $sth->hashRef) {
|
|
$userNames{ $data->{userId} } = _defineUsername($data);
|
|
}
|
|
$sth->finish;
|
|
my $sql = sprintf "select delegateUserId from InOutBoard_delegates where userId=%s and assetId=%s",
|
|
$self->session->db->quote($self->session->user->userId), $self->session->db->quote($self->getId);
|
|
my $delegates = $self->session->db->buildArrayRef($sql);
|
|
my $i18n = WebGUI::International->new($self->session,"Asset_InOutBoard");
|
|
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl);
|
|
$f->hidden(
|
|
-name => "func",
|
|
-value => "selectDelegatesEditSave"
|
|
);
|
|
$f->selectList(
|
|
-name => "delegates",
|
|
-label => $i18n->get('in/out status delegates'),
|
|
-hoverHelp => $i18n->get('in/out status delegates description','Asset_InOutBoard'),
|
|
-options => \%userNames,
|
|
-multiple => 1, ##Multiple select
|
|
-size => 10, ##Multiple select
|
|
-sortByValue => 1,
|
|
-value => $delegates, ##My current delegates, if any
|
|
-subtext => $i18n->get('in/out status delegates subtext'),
|
|
);
|
|
$f->submit;
|
|
my $ac = $self->getAdminConsole;
|
|
return $ac->render($f->print,
|
|
$i18n->get('select delegate'));
|
|
}
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_selectDelegatesEditSave
|
|
|
|
Process the selectDeletages form.
|
|
|
|
=cut
|
|
|
|
sub www_selectDelegatesEditSave {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $db = $session->db;
|
|
my @delegates = $session->form->selectList("delegates");
|
|
$db->write(
|
|
"delete from InOutBoard_delegates where assetId=? and userId=?",
|
|
[ $self->getId, $session->user->userId ]
|
|
);
|
|
|
|
foreach my $delegate (@delegates) {
|
|
$db->write(
|
|
"insert into InOutBoard_delegates (userId,delegateUserId,assetId) values (?,?,?)",
|
|
[$session->user->userId, $delegate, $self->getId ],
|
|
);
|
|
}
|
|
return "";
|
|
}
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_setStatus
|
|
|
|
Process the form from the view method to set status for a user.
|
|
|
|
=cut
|
|
|
|
sub www_setStatus {
|
|
my $self = shift;
|
|
my $session = $self->session;
|
|
my $db = $session->db;
|
|
my $delegate = $session->form->process('delegate');
|
|
if ($delegate eq $self->session->scratch->get("userId")) {
|
|
my $sessionUserId = $session->scratch->get("userId") || $session->user->userId;
|
|
my $status = $session->form->process('status');
|
|
return $self->www_view if $status eq '';
|
|
$session->scratch->delete("userId");
|
|
my $message = $session->form->process('message');
|
|
$db->write("delete from InOutBoard_status where userId=? and assetId=?", [ $sessionUserId, $self->getId ]);
|
|
$db->write(
|
|
"insert into InOutBoard_status (assetId,userId,status,dateStamp,message) values (?,?,?,?,?)",
|
|
[$self->getId, $sessionUserId, $status, time(), $message ],
|
|
);
|
|
$db->write(
|
|
"insert into InOutBoard_statusLog (assetId,userId,createdBy,status,dateStamp,message) values (?,?,?,?,?,?)",
|
|
[$self->getId, $sessionUserId, $session->user->userId, $status, time(), $message ],
|
|
);
|
|
}
|
|
else {
|
|
$session->scratch->set("userId",$delegate);
|
|
}
|
|
return $self->www_view;
|
|
}
|
|
|
|
|
|
#-------------------------------------------------------------------
|
|
|
|
=head2 www_viewReport
|
|
|
|
Builds a templated form for doing drill-down reports, along with displaying results from
|
|
the report.
|
|
|
|
=cut
|
|
|
|
sub www_viewReport {
|
|
my $self = shift;
|
|
return "" unless ($self->session->user->isInGroup($self->reportViewerGroup));
|
|
my %var;
|
|
my $i18n = WebGUI::International->new($self->session,'Asset_InOutBoard');
|
|
my $f = WebGUI::HTMLForm->new($self->session,-action=>$self->getUrl, -method=>"GET");
|
|
my %changedBy = ();
|
|
$f->hidden(
|
|
-name=>"func",
|
|
-value=>"viewReport"
|
|
);
|
|
$f->hidden(
|
|
-name=>"doit",
|
|
-value=>"1"
|
|
);
|
|
my $startDate = $self->session->datetime->addToDate(time(),0,0,-15);
|
|
$startDate = $self->session->form->date("startDate") if ($self->session->form->process("doit"));
|
|
$f->date(
|
|
-name=>"startDate",
|
|
-label=>$i18n->get(16),
|
|
-hoverHelp=>$i18n->get('16 description'),
|
|
-value=>$startDate
|
|
);
|
|
my $endDate = $self->session->form->date("endDate");
|
|
$f->date(
|
|
-name=>"endDate",
|
|
-label=>$i18n->get(17),
|
|
-hoverHelp=>$i18n->get('17 description'),
|
|
-value=>$endDate
|
|
);
|
|
##Make a list of available departments. Map empty departments to the No departments label, and
|
|
##handle the SQL clause for searching.
|
|
my %depHash;
|
|
%depHash = map { $_ => $_ }
|
|
($self->_fetchDepartments(), $i18n->get('all departments'));
|
|
$depHash{''} = $i18n->get('7');
|
|
my $defaultDepartment = $self->session->form->process("selectDepartment");
|
|
my $departmentSQLclause = $defaultDepartment eq $i18n->get('all departments')
|
|
? ''
|
|
: $defaultDepartment eq ''
|
|
? 'and userProfileData.department IS NULL'
|
|
: 'and userProfileData.department='.$self->session->db->quote($defaultDepartment);
|
|
$f->selectBox(
|
|
-name=>"selectDepartment",
|
|
-options=>\%depHash,
|
|
-value=>[ $defaultDepartment ],
|
|
-label=>$i18n->get('filter departments'),
|
|
-label=>$i18n->get('filter departments description'),
|
|
);
|
|
my %paginHash;
|
|
tie %paginHash, "Tie::IxHash"; ##Because default sort order is alpha
|
|
%paginHash = (50 => 50, 100 => 100, 300 => 300, 500 => 500, 1000 => 1000, 10_000 => 10_000,);
|
|
my $pageReportAfter = $self->session->form->process("reportPagination") || 50;
|
|
$f->selectBox(
|
|
-name=>"reportPagination",
|
|
-options=>\%paginHash,
|
|
-value=>[ $pageReportAfter ],
|
|
-label=>$i18n->get(14),
|
|
-hoverHelp=>$i18n->get('14 description'),
|
|
);
|
|
$f->submit(-value=>$i18n->get('search','Asset'));
|
|
$var{'reportTitleLabel'} = $i18n->get('report title');
|
|
$var{'form'} = $f->print;
|
|
my $url = $self->getUrl("func=viewReport;selectDepartment=".$defaultDepartment.";reportPagination=".$pageReportAfter.";startDate=".$self->session->form->process("startDate").";endDate=".$endDate.";doit=1");
|
|
if ($self->session->form->process("doit")) {
|
|
$var{showReport} = 1;
|
|
$endDate = $self->session->datetime->addToTime($endDate,24,0,0);
|
|
my $lastDepartment = "_none_";
|
|
my $p = WebGUI::Paginator->new($self->session,$url, $pageReportAfter);
|
|
|
|
my $sql = "select users.username,
|
|
users.userId,
|
|
firstName,
|
|
InOutBoard_statusLog.message,
|
|
lastName,
|
|
InOutBoard_statusLog.status,
|
|
InOutBoard_statusLog.dateStamp,
|
|
InOutBoard_statusLog.createdBy,
|
|
department,
|
|
groupings.groupId
|
|
from users
|
|
left join groupings on groupings.userId=users.userId
|
|
left join userProfileData on users.userId=userProfileData.userId
|
|
left join InOutBoard_statusLog on users.userId=InOutBoard_statusLog.userId and InOutBoard_statusLog.assetId=".$self->session->db->quote($self->getId())."
|
|
where users.userId<>'1' and
|
|
groupings.groupId=".$self->session->db->quote($self->inOutGroup)." and
|
|
groupings.userId=users.userId and
|
|
InOutBoard_statusLog.dateStamp>=$startDate and
|
|
InOutBoard_statusLog.dateStamp<=$endDate
|
|
$departmentSQLclause
|
|
group by InOutBoard_statusLog.dateStamp
|
|
order by department, lastName, firstName, InOutBoard_statusLog.dateStamp";
|
|
$self->session->log->warn("QUERY: $sql\n");
|
|
$p->setDataByQuery($sql);
|
|
my $rowdata = $p->getPageData();
|
|
my @rows;
|
|
foreach my $data (@$rowdata) {
|
|
my %row;
|
|
|
|
if ($lastDepartment ne $data->{department}) {
|
|
$row{deptHasChanged} = 1;
|
|
$row{'department'} = ($data->{department}||$i18n->get(7));
|
|
$lastDepartment = $data->{department};
|
|
}
|
|
else { $row{deptHasChanged} = 0; }
|
|
|
|
$row{'username'} = _defineUsername($data);
|
|
|
|
$row{'status'} = ($data->{status}||$i18n->get(15));
|
|
$row{'dateStamp'} = $self->session->datetime->epochToHuman($data->{dateStamp});
|
|
$row{'message'} = ($data->{message}||" ");
|
|
if (! exists $changedBy{ $data->{createdBy} }) {
|
|
my %whoChanged = $self->_fetchNames($data->{createdBy});
|
|
$changedBy{ $data->{createdBy} } = $whoChanged{ $data->{createdBy} };
|
|
}
|
|
$row{'createdBy'} = $changedBy{ $data->{createdBy} };
|
|
|
|
push (@rows, \%row);
|
|
}
|
|
$var{rows_loop} = \@rows;
|
|
$var{'paginateBar'} = $p->getBarTraditional();
|
|
$var{'username.label'} = $i18n->get('username label');
|
|
$var{'status.label'} = $i18n->get(5);
|
|
$var{'date.label'} = $i18n->get('date label');
|
|
$var{'message.label'} = $i18n->get('message label');
|
|
$var{'updatedBy.label'} = $i18n->get('updatedBy label');
|
|
$p->appendTemplateVars(\%var);
|
|
}
|
|
else {
|
|
$var{showReport} = 0;
|
|
}
|
|
|
|
return $self->processStyle($self->processTemplate(\%var, $self->reportTemplateId));
|
|
}
|
|
|
|
__PACKAGE__->meta->make_immutable;
|
|
1;
|
|
|