| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package App::JobLog::Log::Day; | 
| 2 |  |  |  |  |  |  | $App::JobLog::Log::Day::VERSION = '1.041'; | 
| 3 |  |  |  |  |  |  | # ABSTRACT: collects events and vacation in a complete day | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 2 |  |  | 2 |  | 1545 | use Modern::Perl; | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 17 |  | 
| 7 | 2 |  |  |  |  | 132 | use App::JobLog::Config qw( | 
| 8 |  |  |  |  |  |  | day_length | 
| 9 |  |  |  |  |  |  | is_workday | 
| 10 |  |  |  |  |  |  | precision | 
| 11 | 2 |  |  | 2 |  | 379 | ); | 
|  | 2 |  |  |  |  | 4 |  | 
| 12 | 2 |  |  | 2 |  | 12 | use Carp qw(carp); | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 78 |  | 
| 13 | 2 |  |  | 2 |  | 9508 | use Text::Wrap; | 
|  | 2 |  |  |  |  | 6032 |  | 
|  | 2 |  |  |  |  | 117 |  | 
| 14 | 2 |  |  |  |  | 201 | use App::JobLog::Log::Format qw( | 
| 15 |  |  |  |  |  |  | duration | 
| 16 |  |  |  |  |  |  | wrap | 
| 17 | 2 |  |  | 2 |  | 13 | ); | 
|  | 2 |  |  |  |  | 4 |  | 
| 18 |  |  |  |  |  |  |  | 
| 19 | 2 |  |  | 2 |  | 11 | use constant WORK_SECONDS => 60 * 60 * day_length; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 2 |  |  |  |  | 10 |  | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | sub new { | 
| 23 | 11169 |  |  | 11169 | 1 | 39836 | my ( $class, %opts ) = @_; | 
| 24 | 11169 |  | 33 |  |  | 45755 | $class = ref $class || $class; | 
| 25 | 11169 |  |  |  |  | 85327 | bless { events => [], vacation => [], synopses => [], %opts }, $class; | 
| 26 |  |  |  |  |  |  | } | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  |  | 
| 29 | 8000 |  |  | 8000 | 0 | 19744 | sub concerns_notes { $_[0]->{notes} } | 
| 30 |  |  |  |  |  |  |  | 
| 31 | 19246 |  |  | 19246 | 0 | 59968 | sub start { $_[0]->{start} } | 
| 32 |  |  |  |  |  |  |  | 
| 33 | 345 |  |  | 345 | 0 | 7071 | sub end { $_[0]->{end} } | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 0 |  |  | 0 | 1 | 0 | sub skip_flex { $_[0]->{skip_flex} } | 
| 37 |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | sub time_remaining { | 
| 40 | 0 |  |  | 0 | 1 | 0 | my ($self) = @_; | 
| 41 | 0 |  |  |  |  | 0 | my $t = 0; | 
| 42 | 0 |  |  |  |  | 0 | $t -= $_->duration for @{ $self->events }, @{ $self->vacation }; | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 43 | 0 | 0 |  |  |  | 0 | $t += WORK_SECONDS if is_workday $self->start; | 
| 44 | 0 |  |  |  |  | 0 | return $t; | 
| 45 |  |  |  |  |  |  | } | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  |  | 
| 48 | 43337 |  |  | 43337 | 1 | 136430 | sub events { $_[0]->{events} } | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  |  | 
| 51 | 0 |  | 0 | 0 | 1 | 0 | sub last_event { ( $_[0]->events || [] )->[-1] } | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  |  | 
| 54 | 34985 |  |  | 34985 | 1 | 176060 | sub vacation { $_[0]->{vacation} } | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  |  | 
| 57 | 8076 |  |  | 8076 | 1 | 22546 | sub synopses { $_[0]->{synopses} } | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  | sub is_empty { | 
| 61 | 19169 |  |  | 19169 | 1 | 26128 | my ($self) = @_; | 
| 62 | 19169 |  | 66 |  |  | 24137 | return !( @{ $self->events } || @{ $self->vacation } ); | 
| 63 |  |  |  |  |  |  | } | 
| 64 |  |  |  |  |  |  |  | 
| 65 | 0 |  |  | 0 | 0 | 0 | sub show_date { !$_[0]->no_date } | 
| 66 |  |  |  |  |  |  |  | 
| 67 | 0 |  |  | 0 | 0 | 0 | sub no_date { $_[0]->{no_date} } | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | sub times { | 
| 71 | 8000 |  |  | 8000 | 1 | 10620 | my ( $self, $times ) = @_; | 
| 72 | 8000 | 100 |  |  |  | 14493 | return if $self->concerns_notes; | 
| 73 |  |  |  |  |  |  |  | 
| 74 | 7968 |  |  |  |  | 9671 | for my $e ( @{ $self->events }, @{ $self->vacation } ) { | 
|  | 7968 |  |  |  |  | 15937 |  | 
|  | 7968 |  |  |  |  | 14654 |  | 
| 75 | 137 |  |  |  |  | 1097 | my @tags = @{ $e->tags }; | 
|  | 137 |  |  |  |  | 381 |  | 
| 76 | 137 |  |  |  |  | 512 | my $d    = $e->duration; | 
| 77 | 137 |  |  |  |  | 871 | $times->{tags}{$_} += $d for @tags; | 
| 78 | 137 | 100 |  |  |  | 374 | $times->{untagged} += $d unless @tags; | 
| 79 | 137 |  |  |  |  | 207 | $times->{total} += $d; | 
| 80 | 137 | 50 |  |  |  | 431 | $times->{vacation} += $d if $e->isa('App::JobLog::Vacation::Period'); | 
| 81 |  |  |  |  |  |  | } | 
| 82 | 7968 | 100 |  |  |  | 18033 | $times->{expected} += WORK_SECONDS | 
| 83 |  |  |  |  |  |  | if is_workday $self->start; | 
| 84 |  |  |  |  |  |  | } | 
| 85 |  |  |  |  |  |  |  | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | sub display { | 
| 88 | 8000 |  |  | 8000 | 1 | 13235 | my ( $self, $format, $columns, $screen_width, $show_year ) = @_; | 
| 89 | 8000 | 100 |  |  |  | 14398 | return if $self->is_empty; | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | # cache some bits from the $columns hash | 
| 92 |  |  |  |  |  |  | my ( $show_times, $show_durations, $show_tags, $show_descriptions ) = | 
| 93 | 76 |  |  |  |  | 132 | @{ $columns->{formats} }{qw(time duration tags description)}; | 
|  | 76 |  |  |  |  | 248 |  | 
| 94 | 76 |  |  |  |  | 143 | my $show_date = $columns->{date}; | 
| 95 |  |  |  |  |  |  | my ( $tag_width, $description_width ) = | 
| 96 | 76 |  |  |  |  | 101 | @{ $columns->{widths} }{qw(tags description)}; | 
|  | 76 |  |  |  |  | 164 |  | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | # date | 
| 99 | 76 | 50 |  |  |  | 194 | if ($show_date) { | 
| 100 | 76 | 100 |  |  |  | 202 | my $f = $show_year ? '%A, %e %B, %Y' : '%A, %e %B'; | 
| 101 | 76 |  |  |  |  | 167 | print $self->start->strftime($f), "\n"; | 
| 102 |  |  |  |  |  |  | } | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | # activities | 
| 105 | 76 |  |  |  |  | 5921 | for my $s ( @{ $self->synopses } ) { | 
|  | 76 |  |  |  |  | 182 |  | 
| 106 | 76 |  |  |  |  | 113 | my @lines; | 
| 107 | 76 | 50 |  |  |  | 392 | push @lines, [ $s->time_fmt ] if $show_times; | 
| 108 | 76 | 100 |  |  |  | 361 | push @lines, [ duration( $s->duration ) ] if $show_durations; | 
| 109 | 76 | 100 |  |  |  | 250 | push @lines, wrap( $s->tag_string, $tag_width ) if $show_tags; | 
| 110 | 76 | 100 |  |  |  | 458 | push @lines, $screen_width == -1 | 
|  |  | 50 |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | ? [ $s->description ] | 
| 112 |  |  |  |  |  |  | : wrap( $s->description, $description_width ) | 
| 113 |  |  |  |  |  |  | if $show_descriptions; | 
| 114 | 76 |  |  |  |  | 281 | my $count = _pad_lines( \@lines ); | 
| 115 |  |  |  |  |  |  |  | 
| 116 | 76 |  |  |  |  | 186 | for my $i ( 0 .. $count ) { | 
| 117 | 76 |  |  |  |  | 209 | say sprintf $format, _gather( \@lines, $i ); | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  | } | 
| 120 | 76 | 50 | 33 |  |  | 1738 | print "\n" | 
|  |  |  | 33 |  |  |  |  | 
|  |  |  | 0 |  |  |  |  | 
|  |  |  | 0 |  |  |  |  | 
| 121 |  |  |  |  |  |  | if $show_times | 
| 122 |  |  |  |  |  |  | || $show_durations | 
| 123 |  |  |  |  |  |  | || $show_tags | 
| 124 |  |  |  |  |  |  | || $show_descriptions | 
| 125 |  |  |  |  |  |  | || $show_date; | 
| 126 |  |  |  |  |  |  | } | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | # add blank lines to short columns | 
| 129 |  |  |  |  |  |  | # returns the number of lines to print | 
| 130 |  |  |  |  |  |  | sub _pad_lines { | 
| 131 | 76 |  |  | 76 |  | 117 | my ($lines) = @_; | 
| 132 | 76 |  |  |  |  | 129 | my $max = 0; | 
| 133 | 76 |  |  |  |  | 174 | for my $column (@$lines) { | 
| 134 | 207 | 100 |  |  |  | 559 | $max = @$column if @$column > $max; | 
| 135 |  |  |  |  |  |  | } | 
| 136 | 76 |  |  |  |  | 149 | for my $column (@$lines) { | 
| 137 | 207 |  |  |  |  | 525 | push @$column, '' while @$column < $max; | 
| 138 |  |  |  |  |  |  | } | 
| 139 | 76 |  |  |  |  | 168 | return $max - 1; | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | # collect the pieces of columns corresponding to a particular line to print | 
| 143 |  |  |  |  |  |  | sub _gather { | 
| 144 | 76 |  |  | 76 |  | 116 | my ( $lines, $i ) = @_; | 
| 145 | 76 |  |  |  |  | 86 | my @line; | 
| 146 | 76 |  |  |  |  | 147 | for my $column (@$lines) { | 
| 147 | 207 |  |  |  |  | 424 | push @line, $column->[$i]; | 
| 148 |  |  |  |  |  |  | } | 
| 149 | 76 |  |  |  |  | 616 | return @line; | 
| 150 |  |  |  |  |  |  | } | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | sub pseudo_event { | 
| 154 | 233 |  |  | 233 | 1 | 367 | my ($self) = @_; | 
| 155 | 233 | 100 |  |  |  | 694 | unless ( $self->{pseudo_event} ) { | 
| 156 | 76 |  |  |  |  | 188 | my $e = | 
| 157 |  |  |  |  |  |  | App::JobLog::Log::Event->new( | 
| 158 |  |  |  |  |  |  | App::JobLog::Log::Line->new( time => $self->start ) ); | 
| 159 | 76 |  |  |  |  | 182 | $e->end = $self->end; | 
| 160 | 76 |  |  |  |  | 211 | $self->{pseudo_event} = $e; | 
| 161 |  |  |  |  |  |  | } | 
| 162 | 233 |  |  |  |  | 807 | return $self->{pseudo_event}; | 
| 163 |  |  |  |  |  |  | } | 
| 164 |  |  |  |  |  |  |  | 
| 165 |  |  |  |  |  |  | 1; | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | __END__ |