App-Dochazka-REST

 view release on metacpan or  search on metacpan

lib/App/Dochazka/REST/Model/Employee.pm  view on Meta::CPAN

        eid => $context->{'current'}->{'eid'},
        object => $self,
        sql => $site->SQL_EMPLOYEE_DELETE,
        attrs => [ 'eid' ],
    );
    #$self->reset( eid => $self->eid ) if $status->ok;
    return $status;
}


=head2 ldap_sync

Sync the mapping fields to the values found in the LDAP database.

=cut

sub ldap_sync {
    my $self = shift;
    $log->debug( "Entering " . __PACKAGE__ . "::sync()" );
    die "Employee nick property not populated!" unless $self->nick =~ /\S+/;
    my $nick = $self->nick;

    return $CELL->status_err( 'DOCHAZKA_LDAP_NOT_ENABLED' ) unless $site->DOCHAZKA_LDAP;
    return $CELL->status_err(
        'DOCHAZKA_LDAP_SYNC_PROP_FALSE',
        args => [ $nick ],
    ) unless $self->sync;
    return $CELL->status_err(
        'DOCHAZKA_LDAP_SYSTEM_USER_NOSYNC',
        args => [ $nick ],
    ) if grep { $nick eq $_; } @{ $site->DOCHAZKA_SYSTEM_USERS };

    $log->debug( "About to populate $nick from LDAP" );

    require Net::LDAP;

    # initiate connection to LDAP server (anonymous bind)
    my $server = $site->DOCHAZKA_LDAP_SERVER;
    my $ldap = Net::LDAP->new( $server );
    $log->error("$@") unless $ldap;
    return $CELL->status_err( 'Could not connect to LDAP server' ) unless $ldap;

    # get LDAP properties and stuff them into the employee object
    my $count = 0;
    foreach my $key ( keys( %{ $site->DOCHAZKA_LDAP_MAPPING } ) ) {
        my $prop = $site->DOCHAZKA_LDAP_MAPPING->{ $key };
        my $value = ldap_search( $ldap, $nick, $prop );
        last unless $value;
        $log->debug( "Setting $key to $value" );
        $self->set( $key, $value );
        $count += 1;
    }

    $ldap->unbind;

    return $CELL->status_ok( 
        'DOCHAZKA_LDAP_SYNC_SUCCESS',
        args => [ $count ],
    ) unless $count < 1;

    return $CELL->status_not_ok( 'DOCHAZKA_LDAP_SYNC_FAILURE' );
}


=head2 load_by_eid

Analogous method to L<App::Dochazka::REST::Model::Activity/"load_by_aid">.

=cut

sub load_by_eid {
    my $self = shift;
    my ( $conn, $eid ) = validate_pos( @_, 
        { isa => 'DBIx::Connector' },
        { type => SCALAR },
#        { type => SCALAR, regex => qr/^-?\d+$/ }, <-- causes a regression
    );
    $log->debug( "Entering " . __PACKAGE__ . "::load_by_eid with argument $eid" );

    return load( 
        conn => $conn,
        class => __PACKAGE__, 
        sql => $site->SQL_EMPLOYEE_SELECT_BY_EID,
        keys => [ $eid ],
    );
}


=head2 load_by_nick

Analogous method to L<App::Dochazka::REST::Model::Activity/"load_by_aid">.

=cut

sub load_by_nick {
    my $self = shift;
    my ( $conn, $nick ) = validate_pos( @_, 
        { isa => 'DBIx::Connector' },
        { type => SCALAR },
    );
    $log->debug( "Entering " . __PACKAGE__ . "::load_by_nick with argument $nick" );

    return load( 
        conn => $conn,
        class => __PACKAGE__, 
        sql => $site->SQL_EMPLOYEE_SELECT_BY_NICK,
        keys => [ $nick ], 
    );
}


=head2 load_by_sec_id

Analogous method to L<App::Dochazka::REST::Model::Activity/"load_by_aid">.

FIXME: add unit tests

=cut

sub load_by_sec_id {
    my $self = shift;

lib/App/Dochazka/REST/Model/Employee.pm  view on Meta::CPAN

=head2 has_reports

Given a L<DBIx::Connector> object, return a status object that, if successful,
will contain in the payload an integer indicating how many "reports" the
employee has - i.e. how many employees, if any, there are whose supervisor is
the employee corresponding to C<$self>.

=cut

sub has_reports {
    my $self = shift;
    my ( $conn ) = validate_pos( @_,
        { isa => 'DBIx::Connector' },
    );
    $log->debug( "Entering " . __PACKAGE__ . "::has_reports for employee " . ( $self->nick || 'undefined' ) );
    my $reports;

    # no EID, no team
    return $CELL->status_ok( 'TEAM', payload => [] ) unless $self->eid;

    my $status = select_single(
        'conn' => $conn,
        'sql' => $site->SQL_EMPLOYEE_HAS_REPORTS,
        'keys' => [ $self->eid ],
    );
    return $status unless $status->ok;
    ( $reports ) = @{ $status->payload };
    return $CELL->status_ok(
        'DISPATCH_EMPLOYEE_HAS_REPORTS_EID',
        args => [ $self->eid ],
        payload => $reports,
    );
}


=head1 FUNCTIONS

The following functions are not object methods.



=head1 EXPORTED FUNCTIONS

The following functions are exported and are not called as methods.


=head2 autocreate_employee

Takes a DBIx::Connector object and a nick - the nick is assumed not to exist in
the Dochazka employees table. If DOCHAZKA_LDAP_AUTOCREATE is true, attempts to 
create the employee. Returns a status object.

=cut

sub autocreate_employee {
    my ( $dbix_conn, $nick ) = @_;
    $log->debug( "Entering " . __PACKAGE__ . "::autocreate_employee()" );
    my $status;

    return $CELL->status_ok() if nick_exists( $dbix_conn, $nick );
    return $CELL->status_not_ok( 'DOCHAZKA_NO_AUTOCREATE' ) unless $site->DOCHAZKA_LDAP_AUTOCREATE;

    my $emp = App::Dochazka::REST::Model::Employee->spawn(
        nick => $nick,
        sync => 1,
        remark => 'LDAP autocreate',
    );
    $status = $emp->ldap_sync();
    return $status unless $status->ok;

    my $faux_context = { 'dbix_conn' => $dbix_conn, 'current' => { 'eid' => 1 } };
    $status = $emp->insert( $faux_context );
    if ( $status->not_ok ) {
        my $reason = $status->text;
        return $CELL->status_err(
            'DOCHAZKA_EMPLOYEE_CREATE_FAIL',
            args => [ $nick, $reason ],
        );
    }
    $log->notice( "Auto-created employee $nick, who was authenticated via LDAP" );

    my $priv = $site->DOCHAZKA_LDAP_AUTOCREATE_AS;
    if ( $priv !~ m/^(inactive)|(active)$/ ) {
        return $CELL->status_err(
            'DOCHAZKA_INVALID_PARAM',
            args => [ 'DOCHAZKA_LDAP_AUTOCREATE_AS', $priv ],
        );
    }

    # create a privhistory record (inactive/active only)
    init_timepiece();
    my $ph_obj = App::Dochazka::REST::Model::Privhistory->spawn(
        eid => $emp->eid,
        priv => $priv,
        effective => ( $today . ' 00:00' ),
        remark => 'LDAP autocreate',
    );
    $status = $ph_obj->insert( $faux_context );
    if ( $status->not_ok ) {
        my $reason = $status->text;
        $status = $CELL->status_err(
            'DOCHAZKA_AUTOCREATE_PRIV_PROBLEM',
            args => [ $nick, $reason ],
        );
    }

    return $status;
}


=head2 nick_exists

See C<exists> routine in L<App::Dochazka::REST::Model::Shared>


=head2 eid_exists

See C<exists> routine in L<App::Dochazka::REST::Model::Shared>

=cut

BEGIN {
    no strict 'refs';
    *{"eid_exists"} = App::Dochazka::REST::Model::Shared::make_test_exists( 'eid' );
    *{"nick_exists"} = App::Dochazka::REST::Model::Shared::make_test_exists( 'nick' );
}


=head2 list_employees_by_priv

Get employee nicks. Argument can be one of the following:

    all admin active inactive passerby

=cut

sub list_employees_by_priv {
    my ( $conn, $priv ) = validate_pos( @_,
        { isa => 'DBIx::Connector' },
        { type => SCALAR, regex => qr/^(all)|(admin)|(active)|(inactive)|(passerby)$/ },
    );
    $log->debug( "Entering " . __PACKAGE__ . "::list_employees_by_priv with priv $priv" );

    my $nicks = [];  # reference to array of nicks
    my $sql = '';    # SQL statement
    my $keys_arrayref = [];   # reference to array of keys (may be empty)
    if ( $priv eq 'all' ) {
        $sql = $site->SQL_EMPLOYEE_SELECT_NICKS_ALL
    } else {
        $sql = $site->SQL_EMPLOYEE_SELECT_NICKS_BY_PRIV_LEVEL;
        $keys_arrayref = [ $priv ];
    }
    my $status = select_set_of_single_scalar_rows( 
        'conn' => $conn, 
        'sql' => $sql, 
        'keys' => $keys_arrayref,
    );
    return $status unless $status->ok;
    



( run in 0.550 second using v1.01-cache-2.11-cpan-d7f47b0818f )