eventespresso / event-espresso-core

Event Espresso 4 Core for WordPress: Build an Event Ticketing Website Today!
https://eventespresso.com
GNU General Public License v3.0
121 stars 87 forks source link

Feature Request: Check-All-In Tickets #183

Closed thebeline closed 6 years ago

thebeline commented 7 years ago

At our venue, registrants will be checking-in and staying for the duration of the multi-day event (they will be given wristbands/tags).

I was able to implement this by adding a method to EE_Registration:

public function checkin_full() {
    $ticket = $this->ticket();

    if(!($ticket instanceof EE_Ticket))
        return FALSE;

    $date_times = $ticket->datetimes();

    foreach($date_times as $date_time) {
        $ID = $date_time->ID();
        if ($cur_status = $this->check_in_status_for_datetime( $ID, NULL ) != EE_Registration::checkin_status_never) {
            EE_Error::add_error(
                    sprintf(
                        __( 'The given registration (ID:%1$d) can not be checked in because it has already been checked in.', 'event_espresso'),
                        $this->ID()
                    ),
                    __FILE__, __FUNCTION__, __LINE__
            );
            return false;
        } elseif (!$this->can_checkin($ID)) {
            EE_Error::add_error(
                    sprintf(
                        __( 'The given registration (ID:%1$d) can not be checked in because it just can\'t, I guess....', 'event_espresso'),
                        $this->ID()
                    ),
                    __FILE__, __FUNCTION__, __LINE__
            );
            return false;
        }
    }

    foreach($date_times as $date_time) {
        $ID = $date_time->ID();
        $this->toggle_checkin_status($ID, true);
    }

    return true;

}

And having the Barcode scanner (in my case) call this method. Now, that said, this is SUPER hacky, and was just a quick test, and is likely a Very Bad Idea.

I think it would be better to have either the ticket have an option, or have the Barcode Scanner Module have an option (either additional select, or a toggle in settings) to do something like this.

I am inclined to have it be a ticket option, where toggle_checkin_status will just iterate over all DateTimes if the option is true, or something. Not sure, exactly, but thoughts? Shouldn't be too complicated to implement. It's just one more gd meta option on tickets. lol

Actually, best-case may be to add a filter for can_checkin and hook or a filter somewhere in toggle_checkin_status. And I can just mod it myself...

thebeline commented 7 years ago

Also, wrt the Barcode Scanner, I would love an option to have the message wiggle and maybe ding if there is an error...

Maybe left-to-right on error, and up-and-down on success. Have the audio be something you can configure in options, and play it a-la this SO answer.

thebeline commented 7 years ago

FYI, I would be happy to fork and do the work for you.

thebeline commented 7 years ago

One more thing on why I think it should be based on the ticket:

It may be possible that a ticket includes a stay of some kind (like in my case) and another does not, as part of the cost.

The Barcode Scanner may have to detect if the ticket is "Check In In Full" type of ticket, and display a slightly different icon and/or tone (optional) if so, so an operator knows if they should give out a wrist-band/id/whatnot. It displays a check and X now, perhaps if it is a "Check In In Full" Ticket, that symbol is circled as well.

Also, it would be helpful if the Barcode scanner logged failed redemption attempts. Both the logged-in user, and the ticket ID.

nerrad commented 7 years ago

Hey just letting you know I've seen this, I can't get to writing a response at the moment but will when I get a chance. Very quickly though:

thebeline commented 7 years ago

I saw that you can add meta to a Ticket, which is great. I will get on this.

Also, where would I do PRs for Barcode Scanner?

nerrad commented 7 years ago

I'll address you doing PR's for barcode scanner sometime today.

thebeline commented 7 years ago

Cheers.

thebeline commented 7 years ago

Could you elaborate on how to set a custom field on the Ticket? I saw it last night at 2am, turns out my long-term memory isn't so grate that time of night... :-/

nerrad commented 7 years ago

You've been granted access to the private barcode scanner repository where you can make pull requests and post issues specific to the barcode scanner there. We can continue to use this ticket for dealing with things specific to EventEspresso core.

thebeline commented 7 years ago

Awesome, so, again, just a general point in the right direction for custom Ticket fields in the Ticket list on Edit Event.

Also, how to get either the EE_Registration, or EE_Ticket object from an EE_Checkin object.

Using existing hooks I was able to get 99% of the way there. I was about to add a number of hooks and hook-wrappers to break out all of the EE_Base_Class and EEM_Base apply_filters and do_action calls so that they called against (example) AHEE__EE_Base_Class__save__end as well as 'AHEE__'.get_class($this).'__save__end', but after a few moments I realized that this would add overhead to each and every call, and running a simple test of if ($object instanceof EE_Checkin) { } was likely much more performant.

So, now I have a saved EE_Checkin object, and would like to get it's EE_Registration object so I can get it's EE_Datetime objects and create a Checkin for each with the same Checkin Status of the currently saved Checkin (there is recursion protection).

thebeline commented 7 years ago

Ok, so I am able to get the current Registration from a save. Looks a little like this:

add_action('AHEE__EE_Base_Class__save__end', 'ee_ticket_full_checkin__ticket__save__end', 1, 4);

function ee_ticket_full_checkin__ticket__save__end($object, $fields_n_values, $query_params = null, $rows_affected = null) {
    if ( $object instanceof EE_Checkin) {
        $running = TRUE;

        $REG_ID = $object->get('REG_ID');

        $registration = EE_Registry::instance()->load_model('Registration')->get_one_by_ID($REG_ID);

        // ...

    }
}

So that works dandy...

Still on about the custom ticket fields (not Registration Options, but an actual Ticket Option, like:

Will dig some more...

thebeline commented 7 years ago

I can do it by modding the table and the Model... Which I may just do... If that is what you are suggesting.

nerrad commented 6 years ago

Going to close this because it's possible its been addressed in other tickets/issues and regardless its an old issue (over a year old).