Curbside Pickup

Bug #1879983 reported by Andrea Neiman
68
This bug affects 8 people
Affects Status Importance Assigned to Milestone
Evergreen
Fix Released
Wishlist
Unassigned

Bug Description

Equinox is working on a curbside pickup interface for Evergreen. This will sit alongside the existing holds interfaces and its main function will be to give staff a process checklist to follow for curbside pickup. Patrons will be able to schedule pickup times online or via a staff member. Existing notice structures via Action/Trigger will be leveraged to broker communication about curbside pickup.

A basic outline and wireframes can be seen in this document:

https://yeti.esilibrary.com/dev/public/techspecs/curbside.pdf

This is very much a "v.1" feature, and our primary goal is to get something broadly functional together as quickly as possible. Details of the above plan are subject to change as we work through the code.

Watch this space!

Edited to add: This work is being sponsored by PaILS.

Changed in evergreen:
status: New → Confirmed
importance: Undecided → Wishlist
Revision history for this message
Mike Rylander (mrylander) wrote :

For those not on the dev mailing list but paying attention to LP, I provided a bit more technical background and narrative exposition at https://markmail.org/message/pw6czjez2zj2f2c6 for this.

Revision history for this message
Ken Cox (kenstir) wrote :

Great proposal and I totally understand your focus on a v.1 experience that can be fielded quickly.

I don't see any mention of OpenSRF methods. Would adding them represent extra work, or are they part of the development plan? The Hemlock mobile apps interact almost exclusively through the OSRF gateway, and having a few basic APIs would I think enable a better mobile experience.

MOBILE USE CASES

These are listed in order of decreasing utility, and increasing effort.

0. Notify me that I need to schedule pickup for available holds. Some UX in the app links to the OPAC pickup scheduler URL.

1. Notify the staff that I have arrived for pickup. This would be a button in the app instead of the form login via the mobile browser. The arrival UX could present an interstitial with per-location arrival instructions.

2. List my pickup appointment(s), and possibly add them to my calendar. Of course the email action trigger could include enough information to allow the mail app to do it.

3. Request a new pickup appointment. This UX could be globally visible based on the org setting, and enabled if the patron has any available holds. The UX could be triggered from the Holds interface, or by deep linking from a push notification or the email sent by the action trigger.

OSRF INTERFACE OUTLINE

Rough sketch of the interfaces I think might be required to support the above use cases.

0. Notify me I need to schedule pickup. No OSRF interface is required, but the OPAC URL would need to be predictable.

1. Arrival

    API: actor.curbside.arrive
    Parameters: auth_token, user_id, vehicle_description

2. List Appointments

    API: actor.curbside.appointments.retrieve
    Parameters: auth_token, user_id

3. Request Appointments

    This seems like a lot of work for diminishing returns so this outline is rough.

    APIs: actor.curbside.appointments.list_available
                actor.curbside.appointments.reserve

Revision history for this message
Mike Rylander (mrylander) wrote :

Hi Ken,

We're glad you're interested in trying to get this into the app! I didn't mention any specific opensrf methods in the email because, well, the API will likely continue to change as we work outward toward the UI, but we do have a public branch where we're working in the open.

https://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/collab/gmcharlt/curbside-wip

There are already methods to cover pretty much everything you'll need for the patron side, including the ability to ask for a list of available times on a given date and to create an appointment for yourself. We're building the API in a new opensrf app (open-ils.curbside) to keep things entirely separate.

Part of the process is to configure an A/T event definition that uses the hold.available hook to create an empty placeholder appointment for the patron (with no date selected) when an item hits a hold shelf of a library that has curbside enabled and for which there is not already such a placeholder. I just added the "fetch my appointments" method which returns the appointment slots for the authenticated user that have not yet been delivered. You could just call that, check for objects that do not have the "slot" timestamp field set, and offer to walk them through requesting an appointment.

The basic workflow for that would be something like:

 * for each placeholder appointment
   - ask the patron for the date they want to pick up their items (today is fine)
   - call the open-ils.curbside.times_for_date API with that date and the org from the placeholder
   - for times that have an available > 0, let the patron choose
   - call the open-ils.curbside.create_appointment with the (separate) date and time selected
   - if necessary, there is an update API and a notes field we intend for patron use, for vehicle description or other library-specific needs, that can be called after creation if that data isn't available at create time.
   - profit!

 * when the patron arrives let them push a button in my-opac (or click a link from an earlier email) that marks them as arrived on the appointment at the relevant library.

We'll be putting our patron UI into a page that knows about the holds (and thus each pickup lib) that are ready, sot that's a natural grouping mechanism. It may be separate from the main my-account holds page, but that's undecided yet (and really just a minor detail).

For the staff side, the UI is underway now. I'm not sure if the app needs that, since our intent is to make sure this is usable for staff on portable devices. But let a thousand flowers bloom!

Thanks!

Revision history for this message
Shula Link (slink-g) wrote :

A small suggestion, based on feedback from staff:

Giving patrons the option to select curbside pickup when placing the hold, along with a receipt template variable to indicate that request when the hold slip is printed, would be an excellent addition. Our workflow for curbside involves calling the patrons to schedule their pickup, so simply knowing which patrons require that contact once we reopen would be excellent since curbside service is going to continue.

Thanks!

Revision history for this message
Galen Charlton (gmc) wrote :

A clean, feature-complete branch is now available:

working/collab/gmcharlt/lp1879983_curbside_pickup
https://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/collab/gmcharlt/lp1879983_curbside_pickup

I am not applying the pullrequest tag just yet pending testing by the sponsoring library, but the branch is suitable for detailed code review and independent testing of the functionality.

Andrea Neiman (aneiman)
description: updated
Revision history for this message
Galen Charlton (gmc) wrote :

Thanks for the suggestion, Sam. Out of curiosity, do you have any guesstimate of what proportion of your patrons would continue to use curbside pickup?

Revision history for this message
Galen Charlton (gmc) wrote :

Noting some enhancements that were pushed to the working branch:

- staff can now claim / unclaim responsibility for staging an appointment on the To Be Staged tab.
- The Staged and Ready, Patron is Outside, and Delivered Today tabs now include Items for Pickup / Items Checked Out columns. Those columns now also highlight holds whose shelf time falls _after_ the time that the appointment was staged.
- The last appointment slot for the day now falls _before_ the closing time, not on it.
- There is a new library setting, Disable patron modification of curbside appointments in public catalog, that prevents the ability of patrons to change appointments in the public catalog. This is meant to support workflows where the library wants to require that patrons call them to manage curbside appointments.
- The act of marking an appointment delivered can now trigger sending email receipts.

Revision history for this message
Jason Boyer (jboyer) wrote :

I've also pushed a minor correction to the A/T event defs to correct the time display.

Revision history for this message
Evergreen Bug Maintenance (bugmaster) wrote :

I did some basic testing of the Equinox demo server, and I found a small bug. When you are on the My OPAC "Holds History" tab, the "Curbside Pickup" tab is missing. However, switching to the "Items on Hold" tab makes the curbside tab appear.

Revision history for this message
Remington Steed (rjs7) wrote :

Sorry, the above comment from "bug master" was actually me.

Revision history for this message
Mike Rylander (mrylander) wrote :

Thanks for testing, Bugmaster Steed!

I've pushed a fix for that subtab display issue, and for a patron appointment request problem when using All The A/T Definitions to drive the process.

Revision history for this message
Galen Charlton (gmc) wrote :

A new squashed branch is available:

collab/gmcharlt/lp1879983_curbside_pickup_pr /
https://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/collab/gmcharlt/lp1879983_curbside_pickup_pr

This branch has completed testing by the sponsoring customer, PaILS, so I'm now slapping on the pullrequest. To get a sense of the changes that were made after testing by PaILS and others began, consult the previous active branch, collab/gmcharlt/lp1879983_curbside_pickup.

tags: added: curbside holds pullrequest
Revision history for this message
Andrea Neiman (aneiman) wrote :

Updated documentation including the updates reflected in the above branch:

https://docs.google.com/document/d/1FV-qiMArSDfTFUQNhfGeNuofbx4j0mE0j_-ReTmJ12Q/edit?usp=sharing

Thanks to Angela Kilsdonk for the docs.

Revision history for this message
Mike Rylander (mrylander) wrote :

We've heard that some folks were hesitant to test curbside on non-master branches, so I've backported and resolved conflicts as far back as 3.1. These branches are based on the origin/rel_3_X branches we split release off of, as of yesterday afternoon. I've pushed them to working as collab branches, which means anyone with a working-repo key can push fixes to them as well, if anything ends up being ... off ... but the conflict resolution ended up being very benign.

3.1: https://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/collab/miker/lp1879983_curbside_pickup_pr_3_1

3.2: https://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/collab/miker/lp1879983_curbside_pickup_pr_3_2

3.3: https://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/collab/miker/lp1879983_curbside_pickup_pr_3_3

3.4: https://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/collab/miker/lp1879983_curbside_pickup_pr_3_4

I did not push a version for 3.5 because, unsurprisingly, the commits pick completely clean. The 3.1 backport does not contain the (new) Angular bits, as that wasn't really a "thing" back then, and the 3.2 backport's Angular code needed a little cleanup to avoid trying to get a YAOUS that did not exist in 3.2.

If anyone has time and eyes, they'd be much appreciated.

Revision history for this message
Ruth Frasur Davis (redavis) wrote :

I've tested this purely from a staff and patron interface standpoint (without doing any of the administrative setup) on the curbside.evergreencatalog.com server in multiple ways. It all worked as I expected.

Revision history for this message
John Amundson (jamundson) wrote :

I am still in the process of testing this feature on curbside.evergreencatalog.com this morning. For the most part, the feature is working quite well! Good job, everyone!

I am running into one potentially medium-sized bug, though.

On the test server, I have set BR3 interval's to 30 minutes apart and to two slots. I left CONS at 15 minutes, 10 slots.

In the OPAC, if a patron has a scheduled appointment for a certain day at one branch and tries to request another appointment at a different branch for the same day, the intervals used by the first branch are presented for the second branch.

If you're quick, you can see this in the OPAC as 99999378730/robertw1234.

This patron has two appointments scheduled for 6/29/20. One at BR1, one at BR3. Both give options for 15 minute intervals. BR3 should only be giving options for 30 minute intervals.

The further I write about this bug, the less I think it will happen often, but it's still worth mentioning.

Revision history for this message
Ruth Frasur Davis (redavis) wrote :

John,

This scenario strikes me as a particularly valid one when considering libraries and library users in Indiana. There are a few "library hopping" patrons who do set up hold pick-ups at different libraries who might, when using curb-side and based on differences in staffing, have different pick-up intervals. Thanks for testing it.

Revision history for this message
John Amundson (jamundson) wrote :

I've run into a few more bugs/oddities/discrepancies...

The draft documentation states there is a setting called "Circulation: Enable curbside pickup functionality at library". On curbside.evergreencatalog.com, this seems to be called "Circulation:  Allow patrons to select a curbside pickup time" Updating/editing this setting does not seem to impact the "Curbside Pickup" option in the Circulation menu. I can access the option regardless of what is set.

The draft documentation states that if a patron is blocked, then the option to check items out is disabled. I find this true in my testing. In the test document I am using, though, it asks to "Check against patrons with blocks - force override should be in effect.". Is the desired behavior that the checkout option remains disabled or that staff should have the ability to force an override? I tested both as a circulator and as admin.

I find that on the test server, I am not receiving emails as a patron. Action triggers for these events seem to be disabled. I did receive an emailed checkout receipt.

Finally, one (very) small bug. When a staff member clicks to "claim" an appointment, the toast message states they are releasing the claim, not claiming it.

I'm also linking to my Google Doc of testing. It includes a section of Potential Development/Would-be-nice's that are probably outside the scope of the project: https://docs.google.com/document/d/1K7VKbwGRGwmByIfoXouY7ER2iH8K93WlcTquf4Vmhc0/edit?usp=sharing

Again, though, I am impressed with how smoothly most of testing went for this. I think the feature is very user-friendly.

Revision history for this message
Andrea Neiman (aneiman) wrote :

Hi John - thanks for testing!

The statement on the testing doc "Check against patrons with blocks - force override should be in effect" indicates that, where permissions and settings allow, checkouts will be forced.

However, if a patron is inactive, barred, expired, or has a circ-blocking standing-penalty, curbside will show a warning; and will disable the buttons to advance the patron's appointment through the workflow until the blocks are resolved. This change came after I wrote the test notes, and I have updated the test notes to reflect this.

The OU setting you noted was a labelling error - it's correct in the branch but had not been updated on the public test server. It is now updated. Note that you may need to log out and log back in to see the menu change reflected.

Stand by for patches for your bugs...

Revision history for this message
Galen Charlton (gmc) wrote :

> This patron has two appointments scheduled for 6/29/20.
> One at BR1, one at BR3. Both give options for 15 minute
> intervals. BR3 should only be giving options for 30 minute
> intervals.

We've updated both branch and test system to fix this.

> The draft documentation states there is a setting called
> "Circulation: Enable curbside pickup functionality at
> library". On curbside.evergreencatalog.com, this seems
> to be called "Circulation: Allow patrons to select a
> curbside pickup time" Updating/editing this setting does
> not seem to impact the "Curbside Pickup" option in the
> Circulation menu. I can access the option regardless of
> what is set.

The test system had not reflected all of the churn in the labels of the org unit settings; that's now been rectified. As far as turning circ.curbside on/off is concerned, logging out and back into the staff interface may be necessary to see an update to the circ menu.

> Finally, one (very) small bug. When a staff member clicks
> to "claim" an appointment, the toast message states they
> are releasing the claim, not claiming it.

Now fixed in both branch and test system.

> The draft documentation states that if a patron is
> blocked, then the option to check items out is disabled.
> I find this true in my testing. In the test document
> I am using, though, it asks to "Check against patrons
> with blocks - force override should be in effect.".
> Is the desired behavior that the checkout option remains
> disabled or that staff should have the ability to
> force an override? I tested both as a circulator
> and as admin.

The underlying circ method that's being called is open-ils.circ.checkout.full.override, and that's meant to handle automatically overriding conditions like checking out lost items. The reasoning is that by the time the circulation staff member hits the button to mark the appointment delivered, the items are in the patron's hands and the checkouts perforce must go through. The various checks that disable the delivery button (and warn the circ staff before the items are event staged) are meant to forestall blocks and events that the patron or library staff can directly control prior to the patron showing up.

Revision history for this message
Galen Charlton (gmc) wrote :

> I find that on the test server, I am not
> receiving emails as a patron. Action triggers
> for these events seem to be disabled. I did
> receive an emailed checkout receipt.

The event definitions ship disabled by default. If you haven't put up your own testing system yet, you're welcome to turn the events on for testing, but please turn them off when you're done to avoid inadvertently spamming anybody. Pending events (without a granularity) are set to be processed every three minutes.

Revision history for this message
John Amundson (jamundson) wrote :

Thanks, Galen. Looks good so for.

I confirmed the Library Setting now reads appropriately and works. A logout and login is needed.

Intervals for multiple pickup locations on the same day seem to be working correctly now in the OPAC.

Claiming a hold set no longer reads that the claim is being released.

The description of the override makes sense. My patron was blocked due to being over the fine limit.

I am currently testing the action trigger notices and will update again shortly.

Revision history for this message
John Amundson (jamundson) wrote :

I enabled the following three action triggers...

- Curbside confirmation Email notification
- Curbside offer Email notification, triggered by CurbsideSlot reactor on a definition attached to the hold.available hook
- Hold Ready for Pickup Email Notification

...assuming this is how they would be set up in our network.

I received a ready for pickup email. I also received a confirmed email after making an appointment. This occurred whether staff or the patron made the appointment, which is nice.

I never received the Curbside offer email. I assumed this one would be sent around the same time as the ready for pickup email. Is the idea that the Curbside offer email replaces the ready for pickup notice or am I doing something wrong?

All I did was enable the notices. I don't spent much time with action triggers, so I do not know if there is a step I'm missing.

I have to clock out for the day, so I am going to disable the action triggers.

Revision history for this message
Jason Boyer (jboyer) wrote :

Hi John, Offer notices have a little bit more going on behind the scenes. They're only triggered by capturing a hold and part of processing an offer is inserting a row into action.curbside for that patron, but with no timeslot. If there's an entry in that table for that user already that hasn't been picked up the validator fails and the offer isn't sent. (That way you don't get one for every hold that's captured.)

So as long as a user shows up in the To Be Staged tab they won't get any more offers.

Revision history for this message
John Amundson (jamundson) wrote :

Thanks, Jason, but I still can't seem to get the Offer notice to trigger, (or at least I am not receiving the email).

I re-enabled the aforementioned notices again. I placed a hold from BR4 for 99999319193. This patron had no holds and no items out. No patrons even appeared for BR4 in the "To Be Staged" tab.

I placed holds on three titles for the patron. I checked the three corresponding items in. After that I left everything alone. I didn't want to mix in any unnecessary variables in.

About 30 minutes later, I received an email stating my three items were available for pickup. That was at 10:12 EST. It's now 13:00 EST, and I have still not received an offer email. (Not even in my Spam folder)

I then disabled the hold pickup email notice, leaving the offer trigger intact. I placed two holds for 99999398998 at 11:56 EST. I have not received any offer notice, yet.

Revision history for this message
John Amundson (jamundson) wrote :

I also want to reiterate that this could be because of something I'm doing.

If others have already tested the offer notice (in some form or another) and it's working, then it probably is.

Revision history for this message
Galen Charlton (gmc) wrote :

To clarify, there are at least two events that would need to be made active:

[1] Trigger curbside offer events and create a placeholder for the patron, where applicable (event def ID 111, hook hold.available) = create the placeholder appointments. This is on a 30-minute delay
[2] Curbside offer Email notification, triggered by CurbsideSlot reactor on a definition attached to the hold.available hook (event def 112, hook holds.offer_curbside) = send the actual offer notification

The first generates the events that trigger the second.

Revision history for this message
Jason Boyer (jboyer) wrote :

Oh, I should have noticed this the other day; if you didn't also enable the "Trigger curbside offer events and create a placeholder for the patron, where applicable" event then the offers can't happen. That is the event that's triggered on hold capture, it then triggers the offer messages to happen. That way the offer emails don't need to have the "Is there already a curbside entry?" smarts in their reactor.

Revision history for this message
John Amundson (jamundson) wrote :

Success! Thanks, Jason and Galen.

A trigger to trigger a trigger. That's fun, but it works!

In the documentation I'm using, (dated 6/22/20), it is not obvious to me that this trigger has to be enabled. It's mentioned in small paragraph at the end of the Action Trigger section. I think it should be moved up and discussed with "Curbside offer Email notification, triggered by CurbsideSlot reactor on a definition attached to the hold.available hook" since it has to be enabled for the offer notice to work.

Revision history for this message
Mike Rylander (mrylander) wrote :

We've discovered a "fun" way to cause the curbside code to spin by setting a granularity of bare numbers, rather than supplying a unit-qualified interval. I've pushed a commit to the above-linked branch that does two things:

 1) assumes a "minute" unit for bare number appointment intervals
 2) forces a floor of "10 minutes" on the appointment interval

Revision history for this message
Mike Rylander (mrylander) wrote :

I've added a commit to the collab branch above to have curbside check for library closings when offering times to patrons or staff. This should be helpful come Labor Day.

I also applied this to the curbside test server linked above. But note: BR1 is set to US Pacific time, so you may want to pick a different branch for testing this -- timezone matters for library closings!

Revision history for this message
Jason Stephenson (jstephenson) wrote :

For those still using/following the 3.2 branch, I pushed a collab branch with all of the up to date commits from the main pr branch:

https://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/collab/dyrcona/lp1879983_curbside_pickup_pr_3_2

I added my signoff to 1 commit that had conflicts. The signoff means that I made the conflict resolution and does not imply that I've tested any of the code, yet.

We plan to start looking at this with 3.2.10 at CW MARS very soon.

Revision history for this message
Michele Morgan (mmorgan) wrote :

I'm adding my signoff to this based on the following:

- My testing on the Equinox test server which confirmed a good workable foundation
- Libraries are running this in their production systems
- Library settings exist to entirely disable the feature

My signoff branch is here:

https://git.evergreen-ils.org/?p=working/Evergreen.git;a=shortlog;h=refs/heads/user/mmorgan/lp1879983_signoff

tags: added: signedoff
Changed in evergreen:
milestone: none → 3.6-beta
Revision history for this message
Galen Charlton (gmc) wrote :

Thanks for testing, Michele.

As my big exercise of RM privilege for this cycle, and given that this is in production at several sites, I've merged this for inclusion in 3.6.

Changed in evergreen:
status: Confirmed → Fix Committed
Changed in evergreen:
status: Fix Committed → Fix Released
Revision history for this message
Josh Stompro (u-launchpad-stompro-org) wrote :

I've trying to test this out in 3.3, and kept running into an apache 500 server error when trying to access the opac curbside pages.

I just increased my apache log level to debug, which showed me the following error.

[Thu Oct 15 16:56:25.061322 2020] [perl:warn] [pid 25735] [client 10.0.100.6:55453] egweb: template error: file error - opac/parts/hold_notify.tt2: not found

It looks like Open-ILS/src/templates/opac/myopac/holds_curbside.tt2
tries to process that file, but it doesn't exist.

Looks like it is a newer file, in 3.5
https://git.evergreen-ils.org/?p=Evergreen.git;a=commitdiff;h=7e9229353092302402c1ca0cbc2efcd5f8a54d90

So if anyone else is trying to apply this to their pre 3.5 system, you may need to comment out that process statement. I don't know if that breaks anything else yet.

Jason, you may run into this with your 3.2 testing.

Josh

Revision history for this message
Jason Stephenson (jstephenson) wrote :

Josh, we already encountered it and resolved it. Here's some relevant discussion in IRC:

http://irc.evergreen-ils.org/evergreen/2020-09-28#i_460450

Revision history for this message
Josh Stompro (u-launchpad-stompro-org) wrote :

Another issue I saw was with trailing/ending commas in schedule_pickup.js causing phantomjs errors when running npm run test.

16 10 2020 10:59:18.141:INFO [karma]: Karma v1.7.1 server started at http://0.0.0.0:9876/
16 10 2020 10:59:18.144:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency
16 10 2020 10:59:18.153:INFO [launcher]: Starting browser PhantomJS
16 10 2020 10:59:18.467:INFO [PhantomJS 2.1.1 (Linux 0.0.0)]: Connected on socket L9Xz1N27s9NhJpNbAAAA with id 54833370
PhantomJS 2.1.1 (Linux 0.0.0) ERROR
  SyntaxError: Unexpected token ')'
  at circ/curbside/directives/schedule_pickup.js:273

PhantomJS 2.1.1 (Linux 0.0.0): Executed 0 of 0 ERROR (0.271 secs / 0 secs)

Removing those commas doesn't seem to be an issue in my brief testing. It looks like those ending commas are still in Master, so they may only cause testing problems in 3.3 and my test environment.

Josh

Revision history for this message
Jason Stephenson (jstephenson) wrote :

PhantomJS is a defunct project. Versions of Evergreen from 3.4 on up no longer use it. https://bugs.launchpad.net/evergreen/+bug/1845693

I don't bother with npm run test on anything less than 3.4.1.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.