1 # This file has been auto-generated only because it didn't exist.
 
   2 # Feel free to modify it at will; it will not be overwritten automatically.
 
   4 package SL::DB::TimeRecording;
 
   8 use SL::Locale::String qw(t8);
 
  10 use SL::DB::Helper::AttrDuration;
 
  11 use SL::DB::Helper::AttrHTML;
 
  13 use SL::DB::MetaSetup::TimeRecording;
 
  14 use SL::DB::Manager::TimeRecording;
 
  16 __PACKAGE__->meta->initialize;
 
  18 __PACKAGE__->attr_duration_minutes(qw(duration));
 
  20 __PACKAGE__->attr_html('description');
 
  22 __PACKAGE__->before_save('_before_save_check_valid');
 
  24 sub _before_save_check_valid {
 
  27   my @errors = $self->validate;
 
  28   return (scalar @errors == 0);
 
  36   push @errors, t8('Start time must not be empty.')                            if !$self->start_time;
 
  37   push @errors, t8('Customer must not be empty.')                              if !$self->customer_id;
 
  38   push @errors, t8('Staff member must not be empty.')                          if !$self->staff_member_id;
 
  39   push @errors, t8('Employee must not be empty.')                              if !$self->employee_id;
 
  40   push @errors, t8('Description must not be empty.')                           if !$self->description;
 
  41   push @errors, t8('Start time must be earlier than end time.')                if $self->is_time_in_wrong_order;
 
  43   my $conflict = $self->is_time_overlapping;
 
  44   push @errors, t8('Entry overlaps with "#1".', $conflict->displayable_times)  if $conflict;
 
  49 sub is_time_overlapping {
 
  52   # Do not allow overlapping time periods.
 
  53   # Start time can be equal to another end time
 
  54   # (an end time can be equal to another start time)
 
  56   # We cannot check if no staff member is given.
 
  57   return if !$self->staff_member_id;
 
  59   # If no start time and no end time are given, there is no overlapping.
 
  60   return if !($self->start_time || $self->end_time);
 
  64   # Start time or end time can be undefined.
 
  65   if (!$self->start_time) {
 
  66     $conflicting = SL::DB::Manager::TimeRecording->get_all(where  => [ and => [ '!id'           => $self->id,
 
  67                                                                                 staff_member_id => $self->staff_member_id,
 
  68                                                                                 start_time      => {lt => $self->end_time},
 
  69                                                                                 end_time        => {ge => $self->end_time} ] ],
 
  70                                                            sort_by => 'start_time DESC',
 
  72   } elsif (!$self->end_time) {
 
  73     $conflicting = SL::DB::Manager::TimeRecording->get_all(where  => [ and => [ '!id'           => $self->id,
 
  74                                                                                 staff_member_id => $self->staff_member_id,
 
  75                                                                                 or              => [ and => [start_time => {le => $self->start_time},
 
  76                                                                                                              end_time   => {gt => $self->start_time} ],
 
  77                                                                                                      start_time => $self->start_time,
 
  81                                                            sort_by => 'start_time DESC',
 
  84     $conflicting = SL::DB::Manager::TimeRecording->get_all(where  => [ and => [ '!id'           => $self->id,
 
  85                                                                                 staff_member_id => $self->staff_member_id,
 
  86                                                                                 or              => [ and => [ start_time => {lt => $self->end_time},
 
  87                                                                                                               end_time   => {gt => $self->start_time} ] ,
 
  88                                                                                                      or  => [ start_time => $self->start_time,
 
  89                                                                                                               end_time   => $self->end_time, ],
 
  93                                                            sort_by => 'start_time DESC',
 
  97   return $conflicting->[0] if @$conflicting;
 
 101 sub is_time_in_wrong_order {
 
 104   if ($self->start_time && $self->end_time
 
 105       && $self->start_time >= $self->end_time) {
 
 112 sub displayable_times {
 
 116   my $ph = $::locale->format_date_object(DateTime->new(year => 1111, month => 11, day => 11, hour => 11, minute => 11), precision => 'minute');
 
 119   return ($self->start_time_as_timestamp||$ph) . ' - ' . ($self->end_time_as_timestamp||$ph);
 
 125   if ($self->start_time && $self->end_time) {
 
 126     return ($self->end_time->subtract_datetime_absolute($self->start_time))->seconds/60.0;