RSS Git Download  Clone
Raw Blame History
package RequestForm;

use Dancer2;
use DateTime;

use RequestForm::DB;
use RequestForm::PDF;
use RequestForm::Base;
use RequestForm::BarCode;
use RequestForm::Validate;
use RequestForm::Validate::Ajax;

our $VERSION = '0.1';

hook before => sub {
    my $vars = params; # p('environment:' . dancer_app->environment);
    p $vars if dancer_app->environment eq 'development';
};

hook before_template => sub {
    # does not need session, vars, params, request or settings (automatic)
    my $tokens = shift; # $tokens->{env} = p %ENV;

    { # referral source autosuggest:
        my $uri = uri_for('/ajax/autosuggest_location'); # shouldn't need ajax prefix
        $tokens->{uri_for_autosuggest_location} = $uri;
    }
    { # nhs number ajax validation:
        my $uri = uri_for('/ajax/validate_nhs_number'); # shouldn't need ajax prefix
        $tokens->{uri_for_nhs_number_validation} = $uri;
    }
};

# default Dancer2 app index page:
get '/index' => sub { template 'index', {}, { layout => 'index' } };

# default route to load initial search form:
get '/' => sub { template 'search_form' };

# re-submitted search form - redirect to search form page:
get '/search' => sub { forward '/' };

# submitted an nhs number to search for:
post '/search' => sub {
    my $params = params;

    # $validation = hashref of keys: pass (success) or errs (failed):
    my $dfv = RequestForm::Validate->new(session => session, settings => config);
    my $validation = $dfv->validate_nhs_number($params); # p $validation; # href
    if ( my $errs = $validation->{errs} ) { # return errs to input form: 
        return template 'search_form', { errs => $errs };
    }

    my $db = RequestForm::DB->new();
    my $data = $db->search_patient($params->{nhs_number}) || {}; # p $data;

    if ( my $dob = $data->{dob} ) { # add year, month (as int) & day elements:
        @{$data}{qw/year month day/} = map { int($_) } split '-', $dob; # eg 1966, 5, 2
    }
    
    # put $data into $params to automatically update params() for tt; grep %data
    # keys so we don't clobber $vars->{nhsno} if search_patient() returns empty:
    $params->{$_} = $data->{$_} for grep $data->{$_}, keys %$data;
    
    var found_patient => ( keys %$data ? 'yes' : 'no' ); # will be true if patient found in db
    template 'request_form';
};

# submitted completed request form:
post '/validate' => sub {
    my $params = params; # p $vars;

    my @args = ( settings => config, session => session );
    my $validator = RequestForm::Validate->new(@args);

    # $result = hashref of keys: pass (1 or 0), and data (pass) or errs (fail):
    my $result = $validator->validate_form($params); # p $result; # href

    # if $result 'pass' is true, save params to db & return PDF to print:  
    if ( $result->{pass} ) { # no validation errors
        my $data = $result->{data}; # p $data; # ie $dfv->valid
        my $pds  = $result->{pds_result}; # p $pds;
        
        # generate_pdf param created in tt if PDS returns SMSP-0000 or _skip_pds
        # param submitted:
        unless ( $params->{generate_pdf} ) {
            return template 'request_form', { pds => $pds };
        }
        { # generate unique ref for db:
            my $unique_id = _make_unique_id($data); # p $unique_id;
            $data->{id} = $unique_id;
        }    
        { # save data to db:        
            my $db = RequestForm::DB->new();
            $db->save_params($data);
        }
        { # generate barcode for printed form:
            my $id = $data->{id};
            my $o = RequestForm::BarCode->new(reference => $id);
            $data->{barcode} = $o->create_2d_barcode; # returns html table
            $data->{qrcode}  = $o->create_3d_barcode; # returns html table
        }
        { # set headers & return PDF form for user to print & send:
            my $content = template 'pdf_form', { data => $data },
                { layout => 'pdf' }; # override default 'main' layout
            return $content if dancer_app->environment eq 'development';
            
            my $pdf = RequestForm::PDF->new(content => $content)->render;
            header 'Content-Type' => 'application/pdf';
            return $pdf;
        }
    }
    # validation failed ('pass' is false):    
    elsif ( my $errs = $result->{errs} ) { # return errs to input form: 
        return template 'request_form', { errs => $errs };
    } # should never get here:
    else { send_error( 'validation did not return expected data structure' ) }
};

sub _make_unique_id {
    my $vars = shift;
    my $now = DateTime->now->epoch;
    
    # id = datetime epoch + last_name + first initial:
    my $id = $now . uc( $vars->{last_name} . substr($vars->{first_name}, 0, 1) );
    return $id;    
}

true;