[WTF CVS] wtf/lib/WTF/Pages Admin.pm, 1.5, 1.6 Input.pm, 1.5, 1.6 Reports.pm, 1.8, 1.9
Brought to you by:
gryphonshafer
|
From: Gryphon S. <gry...@us...> - 2006-12-02 00:09:14
|
Update of /cvsroot/wtf-tracker/wtf/lib/WTF/Pages In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv6361/lib/WTF/Pages Modified Files: Admin.pm Input.pm Reports.pm Log Message: Random bits of changes here and there, mostly code clean-up but a few bits of refactoring (globally) based on a code review in prep for v1.02 build and release Index: Reports.pm =================================================================== RCS file: /cvsroot/wtf-tracker/wtf/lib/WTF/Pages/Reports.pm,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Reports.pm 28 Nov 2006 21:58:37 -0000 1.8 --- Reports.pm 2 Dec 2006 00:09:09 -0000 1.9 *************** *** 1,8 **** package WTF::Pages::Reports; ! our $VERSION = 1.01; use strict; use warnings; use base 'WTF::Pages'; ! use Apache2::Const; use Spreadsheet::WriteExcel; use Time::Local 'timelocal'; --- 1,8 ---- package WTF::Pages::Reports; ! our $VERSION = 1.02; use strict; use warnings; use base 'WTF::Pages'; ! use Apache2::Const -compile => 'REDIRECT'; use Spreadsheet::WriteExcel; use Time::Local 'timelocal'; *************** *** 22,26 **** my $sth = WTF::SQL->sth(); ! sub screen_reports_myweekly { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 22,26 ---- my $sth = WTF::SQL->sth(); ! sub screen_myweekly { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 43,47 **** } ! sub screen_reports_team_view { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 43,47 ---- } ! sub screen_team_view { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 76,79 **** --- 76,85 ---- ); } + + # explicitly return nothing here because xls_team_view_build() + # calls WTF::Utils::make_excel_workbook() which in turn writes + # the Excel binary output directly to where it needs to go; given + # that we don't need to re-render the current web page, we should + # stop immediately after this line return; } *************** *** 142,146 **** } ( $date_start, $date_end ); ! # for each day inclusively between the start and end stamps... my @dates; for ( my $time = $date_start_stamp; $time < $date_end_stamp + 86_400; $time += 86_400 ) { --- 148,152 ---- } ( $date_start, $date_end ); ! # for each day inclusively between the start and end stamps... (86_400 = 1 day) my @dates; for ( my $time = $date_start_stamp; $time < $date_end_stamp + 86_400; $time += 86_400 ) { *************** *** 160,165 **** $_->{'days'} = [ map { ! my $work_b = ( $work =~ /$_->{'date'}/ ) ? 1 : 0; ! my $notes_b = ( $notes =~ /$_->{'date'}/ ) ? 1 : 0; { 'work' => $work_b, --- 166,171 ---- $_->{'days'} = [ map { ! my $work_b = ( index( $work, $_->{'date'} ) > -1 ) ? 1 : 0; ! my $notes_b = ( index( $notes, $_->{'date'} ) > -1 ) ? 1 : 0; { 'work' => $work_b, *************** *** 177,183 **** my $team_summary_dates = [ map { $_->{'date'} =~ s/^\d{4}-//; $_ } @dates ]; ! # trim summary data if the range is too big for nice display my $summary_truncated = 0; ! if ( @{ $team_summary_dates } > 14 ) { splice( @{$team_summary_dates}, 0, @{$team_summary_dates} - 14 ); splice( @{ $_->{'days'} }, 0, @{ $_->{'days'} } - 14 ) for ( @{$team_summary} ); --- 183,189 ---- my $team_summary_dates = [ map { $_->{'date'} =~ s/^\d{4}-//; $_ } @dates ]; ! # trim summary data if the range is too big (longer than 2 weeks) for nice display my $summary_truncated = 0; ! if ( @{ $team_summary_dates } > 14 ) { # 14 days = 2 weeks splice( @{$team_summary_dates}, 0, @{$team_summary_dates} - 14 ); splice( @{ $_->{'days'} }, 0, @{ $_->{'days'} } - 14 ) for ( @{$team_summary} ); *************** *** 210,214 **** } ! sub screen_reports_projects_list { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 216,220 ---- } ! sub screen_projects_list { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 240,244 **** } ! sub screen_reports_project_view { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 246,250 ---- } ! sub screen_project_view { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 298,350 **** $sth->{'activities'}->execute() or die $dbh->errstr(); - my ( $indent, $last_activity_id, $total_alloc, @activities ) = ( 0, 0, 0 ); - while ( $_ = $sth->{'activities'}->fetchrow_hashref() ) { - - # if the parent_id doesn't exist or if it does but it's not the same - # as the last saved parent_id, then the item is a "root" activity and should - # have no indent - if ( not $_->{'parent_id'} or $_->{'parent_id'} != $last_activity_id ) { - $indent = 0; - $last_activity_id = $_->{'id'}; - } - - # if the parent_id exists and isn't the same as the previous parent_id, - # then it's a sub-activity and should get indented - elsif ( - @activities and - $_->{'parent_id'} != ( $activities[-1]->{'parent_id'} || -1 ) - ) { - $indent++; - } - $_->{'indent'} = $indent; - - # "group" denotes that the item is unselectable by the user, that the - # item is a group name, not an activity name - $activities[-1]->{'group'} = 1 if ( - @activities and defined $_->{'parent_id'} and - $_->{'parent_id'} == ( $activities[-1]->{'id'} || -1 ) - ); - - # add activity summary report data - $sth->{'activity_summary'}->execute( - $month . '-01', - $month . '-01', - $_->{'id'}, - ) or die $dbh->errstr(); - ( - $_->{'employees'}, - $_->{'days'}, - $_->{'average'}, - ) = $sth->{'activity_summary'}->fetchrow_array(); - - $_->{'employees'} ||= 0; - $_->{'days'} ||= 0; - $_->{'average'} ||= 0; - - $_->{'average'} = int( $_->{'average'} * 100 ) / 100; - $_->{'alloc'} = int( $_->{'employees'} * $_->{'days'} * $_->{'average'} ) / 100; - - push @activities, $_; - } my $tmpl_obj = $self->setup_tmpl('reports/activity.tmpl'); --- 304,307 ---- *************** *** 353,357 **** 'nav_bar' => WTF::Utils::nav_bar_data( $r, 'activity' ), 'activity_months' => $activity_months, ! 'activities' => \@activities, ); --- 310,339 ---- 'nav_bar' => WTF::Utils::nav_bar_data( $r, 'activity' ), 'activity_months' => $activity_months, ! 'activities' => WTF::Utils::indent( ! $sth->{'activities'}->fetchall_arrayref({}), ! 'parent_id', ! sub { ! my ($row) = @_; ! ! # add activity summary report data ! $sth->{'activity_summary'}->execute( ! $month . '-01', ! $month . '-01', ! $row->{'id'}, ! ) or die $dbh->errstr(); ! ( ! $row->{'employees'}, ! $row->{'days'}, ! $row->{'average'}, ! ) = $sth->{'activity_summary'}->fetchrow_array(); ! ! $row->{'employees'} ||= 0; ! $row->{'days'} ||= 0; ! $row->{'average'} ||= 0; ! ! $row->{'average'} = int( $row->{'average'} * 100 ) / 100; ! $row->{'alloc'} = int( $row->{'employees'} * $row->{'days'} * $row->{'average'} ) / 100; ! }, ! ), ); *************** *** 438,445 **** # loop, incrementing $range[0] by a week until it passes the end range point while ( $range[0] < $range[1] ) { ! my @date_start = (localtime( $range[0] - (localtime( $range[0] ))[6] * 86_400 ))[ 3 .. 6 ]; # 86_400 == 1 day ! my @date_end = (localtime( $range[0] - (localtime( $range[0] ))[6] * 86_400 + 518_400 ))[ 3 .. 6 ]; # 518_400 == 6 days ! my $date_start = sprintf( "%4d-%02d-%02d", $date_start[2] + 1900, $date_start[1] + 1, $date_start[0] ); ! my $date_end = sprintf( "%4d-%02d-%02d", $date_end[2] + 1900, $date_end[1] + 1, $date_end[0] ); $worksheet = $workbook->add_worksheet("Week of $date_start"); --- 420,433 ---- # loop, incrementing $range[0] by a week until it passes the end range point while ( $range[0] < $range[1] ) { ! my @date_start = ! (localtime( $range[0] - (localtime( $range[0] ))[6] * 86_400 ))[ 3 .. 6 ]; ! # 86_400 = 1 day ! my @date_end = ! (localtime( $range[0] - (localtime( $range[0] ))[6] * 86_400 + 518_400 ))[ 3 .. 6 ]; ! # 518_400 = 6 days ! my $date_start = ! sprintf( "%4d-%02d-%02d", $date_start[2] + 1900, $date_start[1] + 1, $date_start[0] ); ! my $date_end = ! sprintf( "%4d-%02d-%02d", $date_end[2] + 1900, $date_end[1] + 1, $date_end[0] ); $worksheet = $workbook->add_worksheet("Week of $date_start"); *************** *** 463,467 **** $sth->{'project_xls_data_subselect'}->execute( $id, $date_start, $date_end ) or die $dbh->errstr(); ! my $eids = join(', ', map { $_->[0] } @{ $sth->{'project_xls_data_subselect'}->fetchall_arrayref() } ) || ''; if ( length $eids > 0 ) { --- 451,457 ---- $sth->{'project_xls_data_subselect'}->execute( $id, $date_start, $date_end ) or die $dbh->errstr(); ! my $eids = join( ', ', ! map { $_->[0] } @{ $sth->{'project_xls_data_subselect'}->fetchall_arrayref() } ! ) || ''; if ( length $eids > 0 ) { *************** *** 492,500 **** $row = 5; ! my $last_area = ''; # take the XLS date from the query above, tree it based on employee, # then map through it to convert it into an array reference with ! # and array reference suitable for direct insert into the XLS # via a write_row() and a scalar with area name so that we can # add company functional area title headers into the worksheet --- 482,490 ---- $row = 5; ! my $last_area = q(); # take the XLS date from the query above, tree it based on employee, # then map through it to convert it into an array reference with ! # an array reference suitable for direct insert into the XLS # via a write_row() and a scalar with area name so that we can # add company functional area title headers into the worksheet *************** *** 542,546 **** =head1 VERSION ! This document describes WTF::Pages::Reports version 1.01 =head1 SYNOPSIS --- 532,536 ---- =head1 VERSION ! This document describes WTF::Pages::Reports version 1.02 =head1 SYNOPSIS *************** *** 570,574 **** return; ! =head2 screen_reports_myweekly() This is a page generation method that generates the --- 560,564 ---- return; ! =head2 screen_myweekly() This is a page generation method that generates the *************** *** 577,581 **** This page allows users to view entered time and notes data for a given week. ! =head2 screen_reports_team_view() This is a page generation method that generates the --- 567,571 ---- This page allows users to view entered time and notes data for a given week. ! =head2 screen_team_view() This is a page generation method that generates the *************** *** 586,591 **** From this page, users can also download detailed team data in a Microsoft Excel (XLS) file handled by "xls_team_view_build()". ! =head2 screen_reports_projects_list() This is a page generation method that generates the --- 576,585 ---- From this page, users can also download detailed team data in a Microsoft Excel (XLS) file handled by "xls_team_view_build()". + There's also a summary table at the top of the page that spans the date + range, limited to 14 days (2 weeks) anchored at the end of the range if the + range is greater than 14 days. The summary table shows who has put what data + into the application over the date range. ! =head2 screen_projects_list() This is a page generation method that generates the *************** *** 598,602 **** "screen_reports_project_view()". ! =head2 screen_reports_project_view() This is a page generation method that generates the --- 592,596 ---- "screen_reports_project_view()". ! =head2 screen_project_view() This is a page generation method that generates the *************** *** 608,611 **** --- 602,613 ---- file handled by "xls_project_view_build()". + =head2 screen_activity_summary() + + This is a page generation method that generates the "Activity Summary" page + using the "reports/activity_summary.tmpl" HTML::Template template. + This page displays summary data about general employee activities as defined + in the activity database table. This page displays monthly summary + statistics. + =head2 xls_team_view_build() *************** *** 651,661 **** WTF::Pages::Reports is a subclass of WTF::Pages. - =head1 KNOWN ISSUES - - The method names in this module date to before the dispatch table in WTF::Pages - could handle multiple subroutines with the same name across two or more - subclasses. Consequently, the method names herein have "reports" in them when - in some cases that's redudant and annoying. - =head1 COPYRIGHT, LICENSE, AND DISCLAIMER OF WARRANTY --- 653,656 ---- Index: Admin.pm =================================================================== RCS file: /cvsroot/wtf-tracker/wtf/lib/WTF/Pages/Admin.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Admin.pm 28 Nov 2006 18:47:50 -0000 1.5 --- Admin.pm 2 Dec 2006 00:09:09 -0000 1.6 *************** *** 4,8 **** use warnings; use base 'WTF::Pages'; ! use Apache2::Const; use Apache2::Cookie; use WTF::DBH; --- 4,8 ---- use warnings; use base 'WTF::Pages'; ! use Apache2::Const -compile => 'REDIRECT'; use Apache2::Cookie; use WTF::DBH; *************** *** 13,16 **** --- 13,20 ---- ROOT_URL => WTF::Config->get( 'links', 'root_url' ), UPDATE => WTF::Config->get( 'update' ), + + # the DATA_TABLES constant is used in the screen_table_data() and + # action_save_table_data() methods and describes how these lookup tables + # are designed and how administrators should interact with them DATA_TABLES => [ { *************** *** 61,65 **** my $sth = WTF::SQL->sth(); ! sub screen_admin_authz { my ( $self, $r ) = @_; my $tmpl_obj = $self->setup_tmpl('admin/authz.tmpl'); --- 65,69 ---- my $sth = WTF::SQL->sth(); ! sub screen_authz { my ( $self, $r ) = @_; my $tmpl_obj = $self->setup_tmpl('admin/authz.tmpl'); *************** *** 104,108 **** } ! sub action_admin_save_new_authzs { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 108,112 ---- } ! sub action_save_new_authzs { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 136,140 **** } ! sub action_admin_update { my ( $self, $r ) = @_; system(UPDATE); --- 140,144 ---- } ! sub action_update { my ( $self, $r ) = @_; system(UPDATE); *************** *** 143,147 **** } ! sub screen_admin_users { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 147,151 ---- } ! sub screen_users { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 199,203 **** } ! sub action_admin_save_users { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 203,207 ---- } ! sub action_save_users { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 219,223 **** } ! sub screen_admin_task_area { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 223,227 ---- } ! sub screen_task_area { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 227,264 **** $sth->{'ta_areas' }->execute() or die $dbh->errstr(); ! my ( $indent, @tasks ) = ( 0 ); ! while ( $_ = $sth->{'all_tasks'}->fetchrow_hashref() ) { ! ! # if there's no task_id, then the item should have no intent ! unless ( $_->{'task_id'} ) { ! $indent = 0; ! } ! ! # increment the items indent if the task_id is not the same as the ! # previous task_id ! elsif ( ! @tasks and ! $_->{'task_id'} != ( $tasks[-1]->{'task_id'} || -1 ) ! ) { ! $indent++; ! } ! $_->{'indent'} = $indent; ! ! # "group" denotes that the item is unselectable by the user, that the ! # item is a group name, not a task name ! $tasks[-1]->{'group'} = 1 if ( ! @tasks and defined $_->{'task_id'} and ! $_->{'task_id'} == ( $tasks[-1]->{'id'} || -1 ) ! ); ! ! $sth->{'ta_area_ids'}->execute( $_->{'id'}, $_->{'id'} ) or die $dbh->errstr(); ! $_->{'t_areas'} = $sth->{'ta_area_ids'}->fetchall_arrayref({}); ! ! push @tasks, $_; ! } - # setup $task_lists and append into each element therein all the areas - # from the "ta_areas" query - my $task_lists = WTF::Utils::tree_data( \@tasks, 'project_type', 'tasks' ); my $areas = $sth->{'ta_areas'}->fetchall_arrayref({}); $_->{'areas'} = $areas for ( @{$task_lists}); --- 231,248 ---- $sth->{'ta_areas' }->execute() or die $dbh->errstr(); ! my $task_lists = WTF::Utils::tree_data( ! WTF::Utils::indent( ! $sth->{'all_tasks'}->fetchall_arrayref({}), ! 'task_id', ! sub { ! my ($row) = @_; ! $sth->{'ta_area_ids'}->execute( $row->{'id'}, $row->{'id'} ) or die $dbh->errstr(); ! $row->{'t_areas'} = $sth->{'ta_area_ids'}->fetchall_arrayref({}); ! }, ! ), ! 'project_type', ! 'tasks', ! ); my $areas = $sth->{'ta_areas'}->fetchall_arrayref({}); $_->{'areas'} = $areas for ( @{$task_lists}); *************** *** 273,277 **** } ! sub action_admin_save_task_area { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 257,261 ---- } ! sub action_save_task_area { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 334,338 **** --- 318,327 ---- my $tmpl_obj = $self->setup_tmpl('admin/table_data.tmpl'); + # declaring an empty scalar that will eventually contain a reference to + # an element (which is itself a hash reference) of the DATA_TABLES array my $table; + + # the @tables array will be sent to the XHTML template to populate the + # select drop-down list of tables that an administrator can edit my @tables = map { # set selected to true for the appropriate table requested by the user *************** *** 356,412 **** } $table ||= DATA_TABLES->[0]; my $sql_sth = 'table_data_' . $table->{'table'}; $sth->{$sql_sth}->execute() or die $dbh->errstr(); my $table_data = $sth->{$sql_sth}->fetchall_arrayref({}); ! ! if ( $table->{'has_parent_id'} ) { ! my ( $indent, @rows, @last_ids ) = ( 0 ); ! for ( @{$table_data} ) { ! ! # if there's no parent_id, then the item should have no intent ! unless ( $_->{'parent_id'} ) { ! $indent = 0; ! @last_ids = (); ! } ! ! # increment the items indent if the parent_id is not the same as the ! # previous parent_id ! elsif ( ! @rows and ! $_->{'parent_id'} != ( $last_ids[-1] || -1 ) ! ) { ! my $id = $_->{'parent_id'}; ! ! # this id seen before and in id stack, so decrement indent and ! # pop ids off the stack until a match or at empty ! if ( grep { $_ == $id } @last_ids ) { ! do { ! $indent--; ! pop @last_ids; ! } while ( $last_ids[-1] ne $id and @last_ids ); ! } ! ! # this is an id that's not in the stack, so increment indent ! # and push the id onto the stack ! else { ! $indent++; ! push @last_ids, $_->{'parent_id'}; ! } ! } ! $_->{'indent'} = $indent; ! ! # "group" denotes that the item is unselectable by the user, that the ! # item is a group name, not a task name ! $rows[-1]->{'group'} = 1 if ( ! $table->{'has_groups'} and ! @rows and defined $_->{'parent_id'} and ! $_->{'parent_id'} == ( $rows[-1]->{'id'} || -1 ) ! ); ! ! push @rows, $_; ! } ! $table_data = \@rows; ! } $tmpl_obj->param( --- 345,358 ---- } + # if there isn't a specified table the user wants to edit, then default to + # the first table in the DATA_TABLES array constant $table ||= DATA_TABLES->[0]; + + # for the table name, execute the prepare_cached query for table data and + # return all its data into $table_data my $sql_sth = 'table_data_' . $table->{'table'}; $sth->{$sql_sth}->execute() or die $dbh->errstr(); my $table_data = $sth->{$sql_sth}->fetchall_arrayref({}); ! $table_data = WTF::Utils::indent( $table_data, 'parent_id' ) if ( $table->{'has_parent_id'} ); $tmpl_obj->param( *************** *** 421,424 **** --- 367,371 ---- 'has_project' => $table->{'has_project'}, 'has_ordering' => $table->{'has_ordering'}, + 'has_groups' => $table->{'has_groups'}, 'show_save' => ( $table->{'has_active'} or $table->{'has_project'} ) ? 1 : 0, ); *************** *** 464,489 **** $dbh->do( 'UPDATE ' . $table->{'table'} . ' SET ' . join( ', ', grep { defined } ( ! ( $table->{'has_active'} ) ? 'active = 0' : undef, ( $table->{'has_project'} ) ? 'project = 0' : undef, ) ) ) or die $dbh->errstr(); - if ( $table->{'has_active'} ) { - $dbh->do( - 'UPDATE ' . $table->{'table'} . ' SET active = 1 WHERE id IN ( ' . join( ', ', - map { substr( $_, 7 ) } grep { substr( $_, 0, 7 ) eq 'active_' } $req->param() ) . ')' - ) or die $dbh->errstr(); - } ! if ( $table->{'has_project'} ) { ! $dbh->do( ! 'UPDATE ' . $table->{'table'} . ' SET project = 1 WHERE id IN ( ' . join( ', ', ! map { substr( $_, 8 ) } grep { substr( $_, 0, 8 ) eq 'project_' } $req->param() ) . ')' ! ) or die $dbh->errstr(); ! } } ! # inserting a new record into the table ! elsif ( $req->param('id') < 1 ) { # setup an array of column names we're going to use in our query; --- 411,438 ---- $dbh->do( 'UPDATE ' . $table->{'table'} . ' SET ' . join( ', ', grep { defined } ( ! ( $table->{'has_active' } ) ? 'active = 0' : undef, ( $table->{'has_project'} ) ? 'project = 0' : undef, ) ) ) or die $dbh->errstr(); ! my $update = sub { ! my ($name) = @_; ! my $length = length($name) + 1; ! ! if ( $table->{ 'has_' . $name } ) { ! $dbh->do( ! 'UPDATE ' . $table->{'table'} . ' SET ' . $name . ' = 1 WHERE id IN ( ' . join( ', ', ! map { substr( $_, $length ) } grep { substr( $_, 0, $length ) eq $name . '_' } $req->param() ) . ')' ! ) or die $dbh->errstr(); ! } ! }; ! ! $update->('active'); ! $update->('project'); } ! # inserting or updating a record in the table ! else { # setup an array of column names we're going to use in our query; *************** *** 491,561 **** # table definition structure my @columns = ( 'name', grep { defined } ( ! ( $table->{'has_parent_id'} ) ? $table->{'table'} . '_id' : undef, ! ( $table->{'has_ordering'} ) ? 'ordering' : undef, ( $table->{'has_description'} ) ? 'description' : undef, ) ); - - my $sth = $dbh->prepare( - 'INSERT INTO ' . $table->{'table'} . ' ( ' . - join( ', ', @columns ) . ' ) VALUES ( ' . join( ', ', ('?') x @columns ) . ' )' - ) or die $dbh->errstr(); - - # set parent_id and description for SQL insert based on what the - # Javascript sends into this method - my $pid = ( - not defined $req->param('pid') or - lc( $req->param('pid') ) eq 'null' - ) ? undef : $req->param('pid'); - my $description = ( - not defined $req->param('description') or - length( $req->param('description') ) == 0 - ) ? undef : $req->param('description'); ! # execute the query, grepping-out input values for columns that ! # don't exist ! $sth->execute( grep { $_ ne '-1' } ( $req->param('name'), - ( $table->{'has_parent_id'} ) ? $pid : -1, - ( $table->{'has_ordering'} ) ? $req->param('ordering') : -1, - ( $table->{'has_description'} ) ? $description : -1, - ) ) or die $dbh->errstr(); - } - - # updating an existing record in the table - elsif ( $req->param('id') > 0 ) { - - # setup an array of column names we're going to use in our query; - # "name" is always going to exist, the rest come from the - # table definition structure - my @columns = ( 'name = ?', grep { defined } ( - ( $table->{'has_parent_id'} ) ? $table->{'table'} . '_id = ?' : undef, - ( $table->{'has_ordering'} ) ? 'ordering = ?' : undef, - ( $table->{'has_description'} ) ? 'description = ?' : undef, - ) ); ! my $sth = $dbh->prepare( ! 'UPDATE ' . $table->{'table'} . ' SET ' . join( ', ', @columns ) . ' WHERE id = ?' ! ) or die $dbh->errstr(); ! # set parent_id and description for SQL insert based on what the ! # Javascript sends into this method ! my $pid = ( ! not defined $req->param('pid') or ! lc( $req->param('pid') ) eq 'null' ! ) ? undef : $req->param('pid'); ! my $description = ( ! not defined $req->param('description') or ! length( $req->param('description') ) == 0 ! ) ? undef : $req->param('description'); ! # execute the query, grepping-out input values for columns that ! # don't exist ! $sth->execute( grep { $_ ne '-1' } ( ! $req->param('name'), ! ( $table->{'has_parent_id'} ) ? $pid : -1, ! ( $table->{'has_ordering'} ) ? $req->param('ordering') : -1, ! ( $table->{'has_description'} ) ? $description : -1, ! $req->param('id'), ! ) ) or die $dbh->errstr(); } --- 440,483 ---- # table definition structure my @columns = ( 'name', grep { defined } ( ! ( $table->{'has_parent_id' } ) ? $table->{'table'} . '_id' : undef, ! ( $table->{'has_ordering' } ) ? 'ordering' : undef, ( $table->{'has_description'} ) ? 'description' : undef, ) ); ! # set name, parent_id, ordering, and description parameters for SQL ! # insert based on what the Javascript sends into this method, ! # grepping-out input values for columns that don't exist ! my @sql_params = grep { not defined $_ or $_ ne '-1' } ( $req->param('name'), ! ( not $table->{'has_parent_id'} ) ? -1 : ( ! not defined $req->param('pid') or ! lc( $req->param('pid') ) eq 'null' ! ) ? undef : $req->param('pid'), ! ! ( $table->{'has_ordering'} ) ? $req->param('ordering') : -1, ! ( not $table->{'has_description'} ) ? -1 : ( ! not defined $req->param('description') ! or length( $req->param('description') ) == 0 ! ) ? undef : $req->param('description'), ! ); ! # inserting a new record into the table ! if ( $req->param('id') < 1 ) { ! my $sth = $dbh->prepare( ! 'INSERT INTO ' . $table->{'table'} . ' ( ' . ! join( ', ', @columns ) . ' ) VALUES ( ' . join( ', ', ('?') x @columns ) . ' )' ! ) or die $dbh->errstr(); ! $sth->execute(@sql_params) or die $dbh->errstr(); ! } ! ! # updating an existing record in the table ! elsif ( $req->param('id') > 0 ) { ! my $sth = $dbh->prepare( ! 'UPDATE ' . $table->{'table'} . ' SET ' . join( ' = ?, ', @columns ) . ' = ? WHERE id = ?' ! ) or die $dbh->errstr(); ! $sth->execute( @sql_params, $req->param('id') ) or die $dbh->errstr(); ! } } *************** *** 599,603 **** my $req = WTF::Utils::get_req($r); ! =head2 screen_admin_authz() This is a page generation method that generates the --- 521,525 ---- my $req = WTF::Utils::get_req($r); ! =head2 screen_authz() This is a page generation method that generates the *************** *** 607,621 **** privileges to specific features. ! =head2 action_admin_save_new_authz() This action method saves changes to the administrate authorization privileges made by authorized users under "screen_admin_authz()". ! =head2 action_admin_update() This action method makes a system call to execute the database synchronization script to synchronize the local WTF database with the Bugzilla database. ! =head2 screen_admin_users() This is a page generation method that generates the --- 529,543 ---- privileges to specific features. ! =head2 action_save_new_authz() This action method saves changes to the administrate authorization privileges made by authorized users under "screen_admin_authz()". ! =head2 action_update() This action method makes a system call to execute the database synchronization script to synchronize the local WTF database with the Bugzilla database. ! =head2 screen_users() This is a page generation method that generates the *************** *** 625,634 **** accounts regarding active states, functional areas, and team assignments. ! =head2 action_admin_save_users() This action method saves changes to the employee user accounts made by authorized users under "screen_admin_users()". ! =head2 screen_admin_task_area() This is a page generation method that generates the --- 547,556 ---- accounts regarding active states, functional areas, and team assignments. ! =head2 action_save_users() This action method saves changes to the employee user accounts made by authorized users under "screen_admin_users()". ! =head2 screen_task_area() This is a page generation method that generates the *************** *** 639,643 **** functional areas. ! =head2 action_admin_save_task_area() This action method saves changes to the selection of project and non-project --- 561,565 ---- functional areas. ! =head2 action_save_task_area() This action method saves changes to the selection of project and non-project *************** *** 663,666 **** --- 585,603 ---- logged in as him or herself. + =head2 screen_table_data() + + This is a page generation method that generates the "Administrate Table" + page using the "admin/table_data.tmpl" HTML::Template template. + This page allows authorized users to view and edit the data in the + application's various look-up tables. This method is somewhat generic, + allowing for control of data across a small series of lookup tables with + different designs. + + =head2 action_save_table_data() + + This action method is called from a form submitted from a page generated by + the "screen_table_data()" method. It supports UPDATEs and INSERTs against + look-up tables within the application's database. + =head1 DEPENDENCIES *************** *** 683,693 **** WTF::Pages::Admin is a subclass of WTF::Pages. - =head1 KNOWN ISSUES - - The method names in this module date to before the dispatch table in WTF::Pages - could handle multiple subroutines with the same name across two or more - subclasses. Consequently, the method names herein all have "_admin_" in them, - and that's somewhat redudant and annoying. - =head1 COPYRIGHT, LICENSE, AND DISCLAIMER OF WARRANTY --- 620,623 ---- Index: Input.pm =================================================================== RCS file: /cvsroot/wtf-tracker/wtf/lib/WTF/Pages/Input.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Input.pm 18 Nov 2006 21:15:23 -0000 1.5 --- Input.pm 2 Dec 2006 00:09:09 -0000 1.6 *************** *** 1,8 **** package WTF::Pages::Input; ! our $VERSION = 1.01; use strict; use warnings; use base 'WTF::Pages'; ! use Apache2::Const; use WTF::DBH; use WTF::SQL; --- 1,8 ---- package WTF::Pages::Input; ! our $VERSION = 1.02; use strict; use warnings; use base 'WTF::Pages'; ! use Apache2::Const -compile => 'REDIRECT'; use WTF::DBH; use WTF::SQL; *************** *** 30,34 **** } ! sub screen_input_projects { my ( $self, $r ) = @_; my $tmpl_obj = $self->setup_tmpl('input/projects.tmpl'); --- 30,34 ---- } ! sub screen_projects { my ( $self, $r ) = @_; my $tmpl_obj = $self->setup_tmpl('input/projects.tmpl'); *************** *** 63,67 **** } ! sub screen_input_tasks { my ( $self, $r ) = @_; my $tmpl_obj = $self->setup_tmpl('input/tasks.tmpl'); --- 63,67 ---- } ! sub screen_tasks { my ( $self, $r ) = @_; my $tmpl_obj = $self->setup_tmpl('input/tasks.tmpl'); *************** *** 74,111 **** } - my ( $indent, $last_task_id, @tasks ) = ( 0, 0 ); - for ( @{$tasks_from_db} ) { - - # if the task_id doesn't exist or if it does but it's not the same - # as the last saved task_id, then the item is a "root" task and should - # have no indent - if ( not $_->{'task_id'} or $_->{'task_id'} != $last_task_id ) { - $indent = 0; - $last_task_id = $_->{'id'}; - } - - # if the task_id exists and isn't the same as the previous task_id, - # then it's a sub-task and should get indented - elsif ( - @tasks and - $_->{'task_id'} != ( $tasks[-1]->{'task_id'} || -1 ) - ) { - $indent++; - } - $_->{'indent'} = $indent; - - # "group" denotes that the item is unselectable by the user, that the - # item is a group name, not a task name - $tasks[-1]->{'group'} = 1 if ( - @tasks and defined $_->{'task_id'} and - $_->{'task_id'} == ( $tasks[-1]->{'id'} || -1 ) - ); - push @tasks, $_; - - } - $tmpl_obj->param( 'title' => 'Project Tasks', ! 'task_lists' => WTF::Utils::tree_data( \@tasks, 'project_type', 'tasks' ), ); --- 74,83 ---- } $tmpl_obj->param( 'title' => 'Project Tasks', ! 'task_lists' => WTF::Utils::tree_data( ! WTF::Utils::indent( $tasks_from_db, 'task_id' ), ! 'project_type', 'tasks' ! ), ); *************** *** 113,117 **** } ! sub screen_input_tracking { my ( $self, $r ) = @_; my $tmpl_obj = $self->setup_tmpl('input/tracking.tmpl'); --- 85,89 ---- } ! sub screen_tracking { my ( $self, $r ) = @_; my $tmpl_obj = $self->setup_tmpl('input/tracking.tmpl'); *************** *** 165,200 **** $sth->{'activity_data'}->finish(); - my ( $indent, $last_activity_id, @activities ) = ( 0, 0 ); - while ( $_ = $sth->{'activities'}->fetchrow_hashref() ) { - - # if the parent_id doesn't exist or if it does but it's not the same - # as the last saved parent_id, then the item is a "root" activity and should - # have no indent - if ( not $_->{'parent_id'} or $_->{'parent_id'} != $last_activity_id ) { - $indent = 0; - $last_activity_id = $_->{'id'}; - } - - # if the parent_id exists and isn't the same as the previous parent_id, - # then it's a sub-activity and should get indented - elsif ( - @activities and - $_->{'parent_id'} != ( $activities[-1]->{'parent_id'} || -1 ) - ) { - $indent++; - } - $_->{'indent'} = $indent; - - # "group" denotes that the item is unselectable by the user, that the - # item is a group name, not an activity name - $activities[-1]->{'group'} = 1 if ( - @activities and defined $_->{'parent_id'} and - $_->{'parent_id'} == ( $activities[-1]->{'id'} || -1 ) - ); - - $_->{'percent'} = $activity_data{ $_->{'id'} }; - push @activities, $_; - } - $tmpl_obj->param( 'title' => 'Daily Timesheet', --- 137,140 ---- *************** *** 203,209 **** 'data' => $sth->{'work_sel'}->fetchall_arrayref({}), 'notes' => scalar( $sth->{'notes_sel'}->fetchrow_array() ) || undef, - 'activities' => \@activities, 'vacation' => $vacation, 'sick' => $sick, ); $sth->{'notes_sel'}->finish(); --- 143,156 ---- 'data' => $sth->{'work_sel'}->fetchall_arrayref({}), 'notes' => scalar( $sth->{'notes_sel'}->fetchrow_array() ) || undef, 'vacation' => $vacation, 'sick' => $sick, + 'activities' => WTF::Utils::indent( + $sth->{'activities'}->fetchall_arrayref({}), + 'parent_id', + sub { + my ($row) = @_; + $row->{'percent'} = $activity_data{ $row->{'id'} }; + }, + ), ); $sth->{'notes_sel'}->finish(); *************** *** 212,216 **** } ! sub action_input_save_timesheet { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); --- 159,163 ---- } ! sub action_save_timesheet { my ( $self, $r ) = @_; my $req = WTF::Utils::get_req($r); *************** *** 283,293 **** @activity_input > 0 ) { ! ! my $vacation = ( ! defined $req->param('vacation') and $req->param('vacation') eq 'on' ! ) ? 1 : 0; ! my $sick = ( ! defined $req->param('sick') and $req->param('sick') eq 'on' ! ) ? 1 : 0; $sth->{'summary_ins'}->execute( --- 230,236 ---- @activity_input > 0 ) { ! my ( $vacation, $sick ) = map { ! ( defined $req->param($_) and $req->param($_) eq 'on' ) ? 1 : 0 ! } qw( vacation sick ); $sth->{'summary_ins'}->execute( *************** *** 332,336 **** =head1 VERSION ! This document describes WTF::Pages::Input version 1.01 =head1 SYNOPSIS --- 275,279 ---- =head1 VERSION ! This document describes WTF::Pages::Input version 1.02 =head1 SYNOPSIS *************** *** 362,366 **** tasks, and tracking sub-pages. ! =head2 screen_input_projects() This is a page generation method that generates the --- 305,309 ---- tasks, and tracking sub-pages. ! =head2 screen_projects() This is a page generation method that generates the *************** *** 371,375 **** log time. ! =head2 screen_input_tasks() This is a page generation method that generates the --- 314,318 ---- log time. ! =head2 screen_tasks() This is a page generation method that generates the *************** *** 379,383 **** allowing the user to select a task in which to log time. ! =head2 screen_input_tracking() This is a page generation method that generates the --- 322,326 ---- allowing the user to select a task in which to log time. ! =head2 screen_tracking() This is a page generation method that generates the *************** *** 388,395 **** majority of functionality on this page is handled by Javascript. ! =head2 action_input_save_timesheet() This action method saves changes to daily time and notes data submitted by ! users from the "Daily Timesheet" page under "screen_input_tracking()". =head1 DEPENDENCIES --- 331,338 ---- majority of functionality on this page is handled by Javascript. ! =head2 action_save_timesheet() This action method saves changes to daily time and notes data submitted by ! users from the "Daily Timesheet" page under "screen_tracking()". =head1 DEPENDENCIES *************** *** 413,423 **** WTF::Pages::Input is a subclass of WTF::Pages. - =head1 KNOWN ISSUES - - The method names in this module date to before the dispatch table in WTF::Pages - could handle multiple subroutines with the same name across two or more - subclasses. Consequently, the method names herein have "input" in them when - in some cases that's redudant and annoying. - =head1 COPYRIGHT, LICENSE, AND DISCLAIMER OF WARRANTY --- 356,359 ---- |