From 07aa41358fed3a98c11362a4e9f3ef4f83191d58 Mon Sep 17 00:00:00 2001
From: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Date: Mon, 9 May 2022 18:35:10 +0200
Subject: [PATCH] Bug 30650: Notify the patron when a new curbside pickup is
 created

Sponsored-by: Association KohaLa - https://koha-fr.org/

Signed-off-by: Koha Team University Lyon 3 <koha@univ-lyon3.fr>

Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
---
 Koha/CurbsidePickup.pm                        | 33 ++++++++++
 circ/curbside_pickups.pl                      |  6 +-
 .../data/mysql/atomicupdate/bug_30650.pl      |  5 ++
 .../mysql/en/mandatory/sample_notices.yml     | 11 ++++
 opac/opac-curbside-pickups.pl                 |  6 +-
 t/db_dependent/Koha/CurbsidePickups.t         | 64 ++++++++++++++++++-
 6 files changed, 117 insertions(+), 8 deletions(-)

diff --git a/Koha/CurbsidePickup.pm b/Koha/CurbsidePickup.pm
index 1e47f0413e..7fd0cac65b 100644
--- a/Koha/CurbsidePickup.pm
+++ b/Koha/CurbsidePickup.pm
@@ -24,6 +24,8 @@ use Koha::Database;
 use base qw(Koha::Object);
 
 use C4::Circulation qw( CanBookBeIssued AddIssue );
+use C4::Members::Messaging qw( GetMessagingPreferences );
+use C4::Letters qw( GetPreparedLetter EnqueueLetter );
 use Koha::DateUtils qw( dt_from_string );
 use Koha::Patron;
 use Koha::Library;
@@ -77,6 +79,37 @@ sub new {
     return $self->SUPER::new($params);
 }
 
+=head3 notify_new_pickup
+
+$pickup->notify_new_pickup
+
+Will notify the patron that the pickup has been created.
+Letter 'NEW_CURBSIDE_PICKUP will be used', and depending on 'Hold_Filled' configuration.
+
+=cut
+
+sub notify_new_pickup {
+    my ( $self ) = @_;
+
+    my $patron = $self->patron;
+
+    my $library = $self->library;
+
+    $patron->queue_notice({ letter_params => {
+        module     => 'reserves',
+        letter_code => 'NEW_CURBSIDE_PICKUP',
+        borrowernumber => $patron->borrowernumber,
+        branchcode => $self->branchcode,
+        tables     => {
+            'branches'  => $library->unblessed,
+            'borrowers' => $patron->unblessed,
+        },
+        substitute => {
+            curbside_pickup => $self,
+        }
+    }, message_name => 'Hold_Filled' });
+}
+
 =head3 checkouts
 
 Return the checkouts linked to this pickup
diff --git a/circ/curbside_pickups.pl b/circ/curbside_pickups.pl
index d50352f262..5d2b247b40 100755
--- a/circ/curbside_pickups.pl
+++ b/circ/curbside_pickups.pl
@@ -84,14 +84,15 @@ elsif ( $op eq 'create-pickup' ) {
     my $notes                     = $input->param('notes');
 
     try {
-        Koha::CurbsidePickup->new(
+        my $pickup = Koha::CurbsidePickup->new(
             {
                 branchcode                => $branchcode,
                 borrowernumber            => $borrowernumber,
                 scheduled_pickup_datetime => dt_from_string($scheduled_pickup_datetime),
                 notes                     => $notes,
             }
-        )->store();
+        )->store;
+        $pickup->notify_new_pickup;
     } catch {
         if ( $_->isa('Koha::Exceptions::CurbsidePickup::TooManyPickups') ) {
             push @messages, {
@@ -107,7 +108,6 @@ elsif ( $op eq 'create-pickup' ) {
             };
         }
     }
-        # $self->_notify_new_pickup($curbside_pickup); TODO
 }
 elsif ( $op eq 'cancel' ) {
     my $id              = $input->param('id');
diff --git a/installer/data/mysql/atomicupdate/bug_30650.pl b/installer/data/mysql/atomicupdate/bug_30650.pl
index e729382b87..aef972c408 100755
--- a/installer/data/mysql/atomicupdate/bug_30650.pl
+++ b/installer/data/mysql/atomicupdate/bug_30650.pl
@@ -156,6 +156,11 @@ return {
                 }
             );
         }
+        $dbh->do(
+            q{
+                INSERT IGNORE INTO `letter` (`module`, `code`, `branchcode`, `is_html`, `title`, `content`, `message_transport_type`, `lang`) VALUES ('reserves','NEW_CURBSIDE_PICKUP','',0,"You have schedule a curbside pickup for [% branch.branchname %]","[%- USE KohaDates -%]\n[%- SET cp = curbside_pickup -%]\n\nYou have a curbside pickup scheduled for [% cp.scheduled_pickup_datetime | $KohaDates with_hours => 1 %] at [% cp.library.branchname %].\n\nAny holds waiting for you at the pickup time will be included in this pickup. At this time, that list includes:\n[%- FOREACH h IN cp.patron.holds %]\n    [%- IF h.branchcode == cp.branchcode && h.found == 'W' %]\n* [% h.biblio.title %], [% h.biblio.author %] ([% h.item.barcode %])\n    [%- END %]\n[%- END %]\n\nOnce you have arrived, please call your library or log into your account and click the \"Alert staff of your arrival\" button to let them know you are there.",'email','default');
+            }
+        );
 
         $dbh->do(q{
             INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`, `type` )
diff --git a/installer/data/mysql/en/mandatory/sample_notices.yml b/installer/data/mysql/en/mandatory/sample_notices.yml
index 34ffab80df..2d56c94288 100644
--- a/installer/data/mysql/en/mandatory/sample_notices.yml
+++ b/installer/data/mysql/en/mandatory/sample_notices.yml
@@ -1317,6 +1317,17 @@ tables:
           content:
             - "Dear [% borrower.firstname %] [% borrower.surname %],\n\nThe following holds are waiting at [% branch.branchname %]:\n\n[% FOREACH hold IN holds %]\n    [% hold.biblio.title %] : waiting since [% hold.waitingdate | $KohaDates %]\n[% END %]"
 
+        - module: reserves
+          code: NEW_CURBSIDE_PICKUP
+          branchcode: ""
+          name: "Curbside pickups"
+          is_html: 0
+          title: "You have schedule a curbside pickup for [% branch.branchname %]."
+          message_transport_type: email
+          lang: default
+          content:
+            - "[%- USE KohaDates -%]\n[%- SET cp = curbside_pickup -%]\n\nYou have a curbside pickup scheduled for [% cp.scheduled_pickup_datetime | $KohaDates with_hours => 1 %] at [% cp.library.branchname %].\n\nAny holds waiting for you at the pickup time will be included in this pickup. At this time, that list includes:\n[%- FOREACH h IN cp.patron.holds %]\n    [%- IF h.branchcode == cp.branchcode && h.found == 'W' %]\n* [% h.biblio.title %], [% h.biblio.author %] ([% h.item.barcode %])\n    [%- END %]\n[%- END %]\n\nOnce you have arrived, please call your library or log into your account and click the \"Alert staff of your arrival\" button to let them know you are there."
+
         - module: serial
           code: SERIAL_ALERT
           branchcode: ""
diff --git a/opac/opac-curbside-pickups.pl b/opac/opac-curbside-pickups.pl
index e2801aaf9a..6a286803bc 100755
--- a/opac/opac-curbside-pickups.pl
+++ b/opac/opac-curbside-pickups.pl
@@ -54,14 +54,15 @@ if ( $op eq 'create-pickup' ) {
     my $notes                     = $input->param('notes');
 
     try {
-        Koha::CurbsidePickup->new(
+        my $pickup = Koha::CurbsidePickup->new(
             {
                 branchcode                => $branchcode,
                 borrowernumber            => $borrowernumber,
                 scheduled_pickup_datetime => dt_from_string($scheduled_pickup_datetime),
                 notes                     => $notes,
             }
-        )->store();
+        )->store;
+        $pickup->notify_new_pickup;
     } catch {
         if ( $_->isa('Koha::Exceptions::CurbsidePickup::TooManyPickups') ) {
             push @messages, {
@@ -77,7 +78,6 @@ if ( $op eq 'create-pickup' ) {
             };
         }
     }
-        # $self->_notify_new_pickup($curbside_pickup); TODO
 }
 elsif ( $op eq 'cancel-pickup' ) {
     my $id              = $input->param('pickup_id');
diff --git a/t/db_dependent/Koha/CurbsidePickups.t b/t/db_dependent/Koha/CurbsidePickups.t
index b931b5e7e1..5e3fb36a0a 100755
--- a/t/db_dependent/Koha/CurbsidePickups.t
+++ b/t/db_dependent/Koha/CurbsidePickups.t
@@ -17,7 +17,7 @@
 
 use Modern::Perl;
 
-use Test::More tests => 3;
+use Test::More tests => 4;
 use Test::Exception;
 
 use Koha::City;
@@ -193,6 +193,8 @@ subtest 'workflow' => sub {
     $cp->mark_as_delivered;
     is( $cp->status, 'delivered' );
     is( $pickups->filter_by_delivered->count, 1 );
+
+    $cp->delete;
 };
 
 subtest 'mark_as_delivered' => sub {
@@ -230,7 +232,65 @@ subtest 'mark_as_delivered' => sub {
 
     is( $hold->get_from_storage, undef, 'Hold has been filled' );
     my $checkout = Koha::Checkouts->find({ itemnumber => $item->itemnumber });
-    is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' )
+    is( $checkout->borrowernumber, $patron->borrowernumber, 'Item has correctly been checked out' );
+
+    $cp->delete;
+};
+
+subtest 'notify_new_pickup' => sub {
+    plan tests => 2;
+
+    my $item =
+      $builder->build_sample_item( { library => $library->branchcode } );
+    my $reserve_id = C4::Reserves::AddReserve(
+        {
+            branchcode     => $library->branchcode,
+            borrowernumber => $patron->borrowernumber,
+            biblionumber   => $item->biblionumber,
+            priority       => 1,
+            itemnumber     => $item->itemnumber,
+        }
+    );
+    my $hold = Koha::Holds->find($reserve_id);
+    $hold->set_waiting;
+
+    my $next_monday =
+      $today->clone->add( days => ( 1 - $today->day_of_week ) % 7 );
+    my $schedule_dt =
+      $next_monday->set_hour(15)->set_minute(00)->set_second(00);
+    my $cp = Koha::CurbsidePickup->new(
+        {
+            branchcode                => $library->branchcode,
+            borrowernumber            => $patron->borrowernumber,
+            scheduled_pickup_datetime => $schedule_dt,
+            notes                     => 'just a note'
+        }
+    )->store;
+
+    $patron->set( { email => 'test@example.org' } )->store;
+    my $dbh = C4::Context->dbh;
+    $dbh->do( q|INSERT INTO borrower_message_preferences( borrowernumber, message_attribute_id ) VALUES ( ?, ?)|,
+        undef, $patron->borrowernumber, 4
+    );
+    my $borrower_message_preference_id =
+      $dbh->last_insert_id( undef, undef, "borrower_message_preferences", undef );
+    $dbh->do(
+        q|INSERT INTO borrower_message_transport_preferences( borrower_message_preference_id, message_transport_type) VALUES ( ?, ? )|,
+        undef, $borrower_message_preference_id, 'email'
+    );
+
+    $cp->notify_new_pickup;
+
+    my $messages = C4::Letters::GetQueuedMessages(
+        { borrowernumber => $patron->borrowernumber } );
+    is(
+        $messages->[0]->{subject},
+        sprintf ("You have schedule a curbside pickup for %s.", $library->branchname),
+        "Notice correctly generated"
+    );
+    my $biblio_title = $item->biblio->title;
+    like( $messages->[0]->{content},
+        qr{$biblio_title}, "Content contains the list of waiting holds" );
 };
 
 $schema->storage->txn_rollback;
-- 
2.30.2