RSS Git Download  Clone
Raw Blame History
use v5.34;
package Model::SQL;

use Moo;
use SQL::Abstract::More;
use Data::Printer alias => 'p';
use Types::Standard qw(InstanceOf ArrayRef Str);

has sql_abs => ( is => 'lazy', builder => sub {  SQL::Abstract::More->new() } );
# has dbix    => ( is => 'ro', isa => InstanceOf['Local::DB'] ); # for get_cols()
has patient_cols => ( is => 'ro', isa => ArrayRef[Str] ); # avoids needing a dbix here

sub user_details {
    my ($self, $ref) = @_; # p $ref; # used directly in query 'where' clause:
    # $ref = key => userId, where key = nhs_number, email or patient_id
    if ( $ref->{patient_id} ) { # patient_id is ambiguous, replace with p.id:
        $ref->{'p.id'} = delete $ref->{patient_id};
    }
    # ensure patient isn't dead (ie disable login by relative):
    # TODO - needs 'status' col on pd table, not just request_followup.option_id:
    # $ref->{'pd.status'} = { '!=' => 'dead' };
    # p $ref;

    my @cols = qw(
        p.dob
        p.nhs_number
        pa.email
        pa.patient_id
        pa.last_login
        pa.password
        pd.address
        pd.post_code
        pd.contact_number
        ref.name|GP
        rs.display_name|practice
    ); # p \@cols;
    # names cols depend on db in use (patient_access_demo or outreach_patient_access):
    unshift @cols, ( grep $_ eq 'last_name', @{ $self->patient_cols } )
         ? qw( p.last_name p.first_name ) : qw(p.initials); # p \@cols;

    my @rels = (                   'patient_access|pa'          ,
        'pa.patient_id=p.id'    => 'patients|p'                 ,
        'pd.patient_id=p.id'    => 'patient_demographics|pd'    ,
        'pd.practice_id=rs.id'  => 'referral_sources|rs'        ,
        'pd.gp_id=ref.id'       => 'referrers|ref'              ,
    );
    my @params = (
        -columns  => \@cols,
        -from     => [ -join => @rels ],
        -where    => $ref,
        # -order_by => $sort_by,
    );
    return $self->sql_abs->select(@params);
}

sub get_pack_dispatches {
    my ($self, $patient_id) = @_; # p $patient_id;
    # last 10 requests & pack dispatches, reverse chronological order:
    my @cols = (
        'r.id',
        'r.request_number',
        'r.year',
        'r.registered',
        'IFNULL(d.count, 0)|section_data_count',
        'so.description|request_status',
        'fo.option',
        'fo.label|outcome',
        'rpd.pack_due',
        'rpd.pack_sent',
        'rpd.return_due',
    );
    my @rels = (                               'requests|r'                 ,
        'r.status_option_id=so.id'          => 'status_options|so'          ,
        'r.patient_case_id=pc.id'           => 'patient_case|pc'            ,
        'pc.patient_id=p.id'                => 'patients|p'                 ,
        # left joins:
        '=>rpd.request_id=r.id'             => 'request_pack_dispatch|rpd'  ,
        '=>rfu.request_id=r.id'             => 'request_followup|rfu'       ,
        '=>rfu.followup_option_id=fo.id'    => 'followup_options|fo'        ,
        '=>d.request_id=r.id'               => 'lab_sections_data|d'        ,
    );
    my %where = ( 'p.id' => $patient_id );
    my @params = (
        -columns  => \@cols,
        -from     => [ -join => @rels ],
        -where    => \%where,
        -order_by => { -desc => 'r.id' }, # or just '-r.id' will work
        -limit    => 10,
    );
    return $self->sql_abs->select(@params);
}

=begin - same queries configured for hilis4 & outreach db's only:
sub user_details {
    my ($self, $ref) = @_; # p $ref;

    # $ref = key => userId, where key = nhs_number, email or patient_id
    if ( $ref->{patient_id} ) { # patient_id is ambiguous, replace with p.id:
        $ref->{'p.id'} = delete $ref->{patient_id};
    } # p $where;

    my @cols = qw(
        p.last_name
        p.first_name
        p.dob
        p.nhs_number
        pa.email
        pa.patient_id
        pa.last_login
        pa.password
        pd.address
        pd.post_code
        pd.contact_number
        ref.name|GP
        rs.display_name|practice
    ); # p \@cols;
    my @rels = (                   'patient_access|pa'                 ,
        'pa.patient_id=p.id'    => 'hilis4.patients|p'                 ,
        'pd.patient_id=p.id'    => 'hilis4.patient_demographics|pd'    ,
        'pd.practice_id=rs.id'  => 'hilis4.referral_sources|rs'        ,
        'pd.gp_id=ref.id'       => 'hilis4.referrers|ref'              ,
    );
    my @params = (
        -columns  => \@cols,
        -from     => [ -join => @rels ],
        -where    => $ref,
        # -order_by => $sort_by,
    );
    return $self->sql_abs->select(@params);
}

sub get_pack_dispatches {
    my ($self, $patient_id) = @_; # p $patient_id;
    # last 10 requests & pack dispatches, reverse chronological order:
    my @cols = (
        'r.id',
        'r.request_number',
        'r.year',
        'r.created_at|registered',
        'DATE(rsv.time)|reported',
        'COUNT(DISTINCT(rt.description))|section_data_count',
        'so.description|request_status',
        'fo.option',
        'fo.label|outcome',
        'rpd.pack_due',
        'rpd.pack_sent',
        'rpd.return_due',
    );
    my @rels = (                               'hilis4.requests|r'             ,
        'r.status_option_id=so.id'          => 'hilis4.status_options|so'      ,
        'r.patient_case_id=pc.id'           => 'hilis4.patient_case|pc'        ,
        'pc.patient_id=p.id'                => 'hilis4.patients|p'             ,
        'pd.patient_id=p.id'                => 'hilis4.patient_demographics|pd',
        'rs.request_id=r.id'                => 'hilis4.request_specimen|rs'    ,
        q!rs.specimen_id=s.id,s.sample_code='CMP'!
                                            => 'hilis4.specimens|s'            ,
        # left joins:
        '=>rpd.request_id=r.id'          => 'request_pack_dispatch|rpd'        ,
        '=>rfu.request_id=r.id'          => 'request_followup|rfu'             ,
        '=>rfu.followup_option_id=fo.id' => 'followup_options|fo'              ,
        '=>rr.request_id=r.id'           => 'request_results|rr'               ,
        '=>rr.param_id=lp.id'            => 'lab_params|lp'                    ,
        '=>lp.department_id=rt.id'       => 'result_types|rt'                  ,
        q!=>rsv.request_id=r.id,rsv.action='reported'!,
                                         => 'hilis4.request_status_view|rsv'   ,
    );
    my %where = (
        'p.id' => $patient_id,
        'rt.description' => { -in => ['haematology', 'flow_cytometry'] },
    );
    my @params = (
        -columns  => \@cols,
        -from     => [ -join => @rels ],
        -where    => \%where,
        -group_by => 'r.id',
        -order_by => { -desc => 'r.id' }, # or just '-r.id' will work
        -limit    => 10,
    );
    return $self->sql_abs->select(@params);
}
=cut

1;