use strict; use warnings; use CGI qw(:standard); use Date::Simple; sub NiceDateFormat { Date::Simple->new($_[0])->format("%d %b %Y"); } my ($fday,$fmonth,$fyear) = (param('fday'),param('fmonth'),param('fyear')); my ($tday,$tmonth,$tyear) = (param('tday'),param('tmonth'),param('tyear')); die &Template("DevMgr/GenericError",{message => 'missing some or all of the FROM date'}) unless ($fday and $fmonth and $fyear); die &Template("DevMgr/GenericError",{message => 'missing some or all of the TO date'}) unless ($tday and $tmonth and $tyear); my $start = "$fyear-$fmonth-$fday"; my $end = "$tyear-$tmonth-$tday"; my $s = &db_Staff_On_Site_Between_Two_Dates($start,$end); my (%days, $hc, @previnits, $thisline, $from, @people, @prevpeople, $prevdate); push @{$days{$$_[1]}}, $$_[2] for @$s; # loop through each date (up to the end of range) # looking for changes in head count for my $date (sort keys %days) { @people = sort @{$days{$date}}; # initialise values for the 'previous' day @prevpeople = @people unless @prevpeople; $from ||= $date; $prevdate ||= $date; if ("@prevpeople" ne "@people") { # work out who has arrived, who has departed my (@arriving,@departing); my %prevpeople = map {$_ => undef} @prevpeople; my %people = map {$_ => undef} @people; for (@people) { push @arriving, $_ unless exists $prevpeople{$_}; } for (@prevpeople) { push @departing, $_ unless exists $people{$_}; } # then deal with arrivals and departures my $arriving = @arriving ? &Template("DevMgr/SingleHeadCountArrivalLine",{ date => NiceDateFormat($date), change => join(", ", sort @arriving)}) : ' '; my $departing = @departing ? &Template("DevMgr/SingleHeadCountDepartureLine",{ date => NiceDateFormat($prevdate), change => join(", ", sort @departing)}) : ' '; # output the headcount as at the previous day $hc .= &Template("DevMgr/SingleHeadCountLine", { datefrom => NiceDateFormat($from), dateto => NiceDateFormat($prevdate), headcount => scalar(@prevpeople), staffonsite => join (', ', sort values %{UniqInits(@prevpeople)}), arriving => $arriving, departing => $departing } ); $from = $date; @prevpeople = @people; } $prevdate = $date; } # we drop out of the loop when we hit the end of the range, # so it is now necessary to output a final line of head count $hc .= &Template("DevMgr/SingleHeadCountLine", { datefrom => NiceDateFormat($from), dateto => NiceDateFormat((reverse sort keys %days)[0]), headcount => scalar(@people), staffonsite => join(', ', sort values %{UniqInits(@people)}), arriving => ' ', departing => ' ' } ); print &Template("DevMgr/ShowHeadCount",{ headcount_html => $hc });