package LIMS::Model::Roles::Outreach; use Moose::Role; use Data::Dumper; has $_ => ( is => 'ro', isa => 'HashRef', lazy_build => 1 ) for qw(pain_options_map nodal_options_map followup_options_map); has overdue_notification => ( is => 'ro', isa => 'HashRef[LIMS::DB::Outreach::RequestNotification]', default => sub { {} }, lazy => 1, traits => ['Hash'], handles => { set_notifications => 'set', get_notification_event => 'get', has_notification_event => 'exists', }, ); has notification_events => ( is => 'ro', isa => 'ArrayRef[Str]', lazy_build => 1, traits => ['Array'], handles => { all_events => 'elements', get_event => 'get', # final_event => 'pop', # can't do this in a loop !! }, ); use Lingua::EN::Words2Nums; #------------------------------------------------------------------------------- sub do_outreach_request_pack_dispatch { my ($self, $data) = @_; my $followup_option_id = $data->{followup_option_id}; my $request_id = $data->{_request_id}; { # request_followup table: my @args = ( followup_option_id => $followup_option_id, request_id => $request_id, ); # warn Dumper \@args; LIMS::DB::Outreach::RequestFollowup->new(@args)->save; } # returns { period => duration } if option_id is a chronological one (eg six_week): my $pack_dispatch_args = $self->get_pack_dispatch_args($followup_option_id); # href if ( $pack_dispatch_args ) { # warn Dumper $pack_dispatch_args; my $request = LIMS::DB::Request->new(id => $request_id)->load; # warn $request->created_at->ymd; # add ref_date: $pack_dispatch_args->{ref_date} = $request->created_at; my $pack_dispatch_date = $self->calculate_pack_dispatch_date($pack_dispatch_args); # warn $pack_dispatch_date->ymd; do { my %h = ( request_id => $request_id, pack_due => $pack_dispatch_date, ); LIMS::DB::Outreach::RequestPackDispatch->new(%h)->save; }; } } #------------------------------------------------------------------------------- # returns { duration_type => number } if option_id is a chronological one (eg six_week) sub get_pack_dispatch_args { my ($self, $option_id) = @_; my $options_map = $self->followup_options_map; # warn Dumper $options_map; my $followup_option_name = $options_map->{$option_id}->{option}; # warn $followup_option_name; # eg six_month my ($numerical_word, $duration_type) = $followup_option_name =~ /^(\w+)_(week|month)$/; # warn Dumper [$numerical_word, $duration_type]; # eg six, month return 0 unless $numerical_word && $duration_type && grep $duration_type =~ /$_\Z/, qw(week month); $duration_type .= 's'; # week => weeks, month => months my $number = words2nums($numerical_word); # warn $number; die qq!cannot extract a number from "$numerical_word"! unless defined $number; # could be 0 (zero_month) return { duration_type => $duration_type, number => $number }; } # shared with do_outreach_request_pack_dispatch() & M::Outreach::update_followup sub calculate_pack_dispatch_date { my $self = shift; my $args = shift; # href of ref_date, period & integer # duration_type = weeks / months, ref_date = datetime, num = 0, 1, 2, 3, etc my ($duration_type, $ref_date, $number) = map $args->{$_}, qw(duration_type ref_date number); my $dispatch_due_date = $ref_date->clone # clone to avoid changing it ->add($duration_type => $number) # + no. of weeks / months (could be 0) ->subtract(days => 14); # - 14 days return $dispatch_due_date; } #------------------------------------------------------------------------------- sub calculate_pack_return_date { # returns datetime object my ($self, $ref_date) = @_; # datetime object # return date = pack dispatch date + 40 days: my $return_date = $ref_date->clone->add(days => 40); # clone otherwise updates orig!! return $return_date; } =begin #------------------------------------------------------------------------ sub get_followup_option_duration { # no longer in use my ($self, $option_id) = @_; my $options_map = $self->followup_options_map; my $followup_durations = $self->followup_durations_map; my $followup_option_name = $options_map->{$option_id}->{option}; # eg six_month my $int = $followup_durations->{$followup_option_name}; # eg 0, 3, 6, etc return $int; } #------------------------------------------------------------------------ sub followup_durations_map { # no longer in use my $self = shift; my $opts = $self->followup_options_map; # get list of 'option' col: my @follow_up_opts = map $opts->{$_}->{option}, keys %$opts; # warn Dumper \@follow_up_opts; my %map; for my $option (@follow_up_opts) { if ( $option =~ /(\w+)_month/ ) { my $num = words2nums($1); # warn Dumper $num; $map{$option} = $num if defined $num; # could be zero } } # warn Dumper \%map; return \%map; } =cut #------------------------------------------------------------------------------- sub get_overdue_pack_notifications { my $self = shift; my $o = LIMS::DB::Outreach::RequestNotification::Manager ->get_request_notifications( require_objects => 'event' ); return $o; } #------------------------------------------------------------------------------- # skip notification if final notification already sent, or less overdue than next event date: sub skip_notification { my ($self, $data) = @_; my $today = LIMS::Local::Utils::time_now(); my $dfm = DateTime::Format::MySQL->new(); my $notification_event = $self->get_notification_event($data->{request_id}); my $pack_sent_date = $dfm->parse_date($data->{pack_sent}); my $event_id = $notification_event->event_id; my $prev_event = $notification_event->event->days; # most recent notification my $next_event = $self->get_event($event_id) || 0; # works due to array pos my $final_event = $self->get_event(-1); # last entry in events list my $delta_days = $pack_sent_date->delta_days($today)->delta_days; # warn Dumper [$delta_days, $prev_event, $next_event, $final_event]; return ( $prev_event == $final_event || $delta_days < $next_event ); } #------------------------------------------------------------------------------- sub questionnaire_options { my $self = shift; my %h = ( followup_options => $self->followup_options_map, nodal_options => $self->nodal_options_map, pain_options => $self->pain_options_map, ); return \%h; } #------------------------------------------------------------------------------- # method shared by C::Outreach::edit_followup & M::Outreach (get_menu_options & update_followup) sub _build_followup_options_map { my $self = shift; my $db_name = $self->lims_db->database eq 'lims_test' ? 'outreach_test' : 'outreach'; return $self->lims_dbix->select("${db_name}.followup_options", # backtick keywords: [ qw(id label `option` `position`) ] )->map_hashes('id'); } #------------------------------------------------------------------------------- sub _build_pain_options_map { my $self = shift; my $dbix = $self->lims_dbix; my $sql = q!select id, `option` from outreach.pain_options!; my $map = $dbix->query($sql)->map; return $map; } #------------------------------------------------------------------------------- sub _build_nodal_options_map { my $self = shift; my $dbix = $self->lims_dbix; my $sql = q!select id, `option` from outreach.nodal_options!; my $map = $dbix->query($sql)->map; return $map; } #------------------------------------------------------------------------------- sub _build_notification_events { my $self = shift; my $dbix = $self->lims_dbix; my $sql = 'select `days` from outreach.notification_events order by id'; my $o = $dbix->query($sql)->flat; # warn Dumper $o; return $o; } 1;