From f362c9bdabae2106d1ac3c83d65b1567220cc1ac Mon Sep 17 00:00:00 2001
From: Lari Taskula <lari.taskula@jns.fi>
Date: Wed, 26 Oct 2016 18:06:57 +0300
Subject: [PATCH] Bug 17499: Add a method for setting default messaging
 preferences

This patch adds a method Koha::Patron::Message::Preference->new_from_default that
can be used to add category's default messaging preferences to patron for a given
message type.

Example call:

Koha::Patron::Message::Preference->new_from_default({
    borrowernumber => 123,
    categorycode => "ABC",
    message_attribute_id => 1,
});

Also adds a simple method for Koha::Patron, set_default_messaging_preferences.
Usage: $patron->set_default_messaging_preferences()

To test:
1. Run t/db_dependent/Koha/Patron/Message/Preferences.t
---
 Koha/Exceptions.pm                               |  4 ++
 Koha/Patron.pm                                   | 28 +++++++++++
 Koha/Patron/Message/Preference.pm                | 63 ++++++++++++++++++++++++
 t/db_dependent/Koha/Patron/Message/Preferences.t | 36 +++++++++++++-
 4 files changed, 130 insertions(+), 1 deletion(-)

diff --git a/Koha/Exceptions.pm b/Koha/Exceptions.pm
index ff04b9e..793aafa 100644
--- a/Koha/Exceptions.pm
+++ b/Koha/Exceptions.pm
@@ -44,6 +44,10 @@ use Exception::Class (
         isa => 'Koha::Exceptions::Exception',
         description => 'General problem adding a library limit'
     },
+    'Koha::Exceptions::UnknownObject' => {
+        isa => 'Koha::Exceptions::Exception',
+        description => 'Object cannot be found or is not known',
+    },
     # Virtualshelves exceptions
     'Koha::Exceptions::Virtualshelves::DuplicateObject' => {
         isa => 'Koha::Exceptions::DuplicateObject',
diff --git a/Koha/Patron.pm b/Koha/Patron.pm
index b97bceb..d2cc7c7 100644
--- a/Koha/Patron.pm
+++ b/Koha/Patron.pm
@@ -33,6 +33,7 @@ use Koha::Patron::Categories;
 use Koha::Patron::HouseboundProfile;
 use Koha::Patron::HouseboundRole;
 use Koha::Patron::Images;
+use Koha::Patron::Message::Preferences;
 use Koha::Patrons;
 use Koha::Virtualshelves;
 use Koha::Club::Enrollments;
@@ -630,6 +631,33 @@ sub get_enrollable_clubs {
     return wantarray ? $e->as_list : $e;
 }
 
+=head3 set_default_messaging_preferences
+
+    $patron->set_default_messaging_preferences
+
+Sets default messaging preferences on patron.
+
+See Koha::Patron::Message::Preference(s) for more documentation, especially on
+thrown exceptions.
+
+=cut
+
+sub set_default_messaging_preferences {
+    my ($self, $categorycode) = @_;
+
+    my $options = Koha::Patron::Message::Preferences->get_options;
+
+    foreach my $option (@$options) {
+        Koha::Patron::Message::Preference->new_from_default({
+            borrowernumber => $self->borrowernumber,
+            categorycode   => $categorycode || $self->categorycode,
+            message_attribute_id => $option->{message_attribute_id},
+        })->store;
+    }
+
+    return $self;
+}
+
 =head3 type
 
 =cut
diff --git a/Koha/Patron/Message/Preference.pm b/Koha/Patron/Message/Preference.pm
index df0d0ec..8fa1910 100644
--- a/Koha/Patron/Message/Preference.pm
+++ b/Koha/Patron/Message/Preference.pm
@@ -23,6 +23,7 @@ use Koha::Database;
 use Koha::Exceptions;
 use Koha::Patron::Categories;
 use Koha::Patron::Message::Preferences;
+use Koha::Patron::Message::Transport::Preferences;
 use Koha::Patrons;
 
 use base qw(Koha::Object);
@@ -77,6 +78,68 @@ sub new {
     return $self;
 }
 
+=head3 new_from_default
+
+my $preference = Koha::Patron::Message::Preference->new_from_default({
+    borrowernumber => 123,
+    categorycode   => 'ABC',
+    message_attribute_id => 1,
+})->store;
+
+Sets default messaging preference for C<categorycode> to patron for given
+C<message_attribute_id>.
+
+Throws Koha::Exceptions::MissingParameter if any of following is missing:
+- categorycode
+- borrowernumber
+- message_attribute_id
+
+Throws Koha::Exceptions::UnknownObject if default preferences are not found.
+
+=cut
+
+sub new_from_default {
+    my ($class, $params) = @_;
+
+    my @required = qw(borrowernumber categorycode message_attribute_id);
+    foreach my $p (@required) {
+        Koha::Exceptions::MissingParameter->throw(
+            error => "Missing required parameter.",
+            parameter => $p,
+        ) unless exists $params->{$p};
+    }
+
+    my $default = Koha::Patron::Message::Preferences->find({
+        categorycode => $params->{'categorycode'},
+        message_attribute_id => $params->{'message_attribute_id'},
+    });
+    Koha::Exceptions::UnknownObject->throw(
+        error => "Default messaging preference for given categorycode and"
+        ." message_attribute_id cannot be found.",
+    ) unless $default;
+    $default = $default->unblessed;
+
+    # Add a new messaging preference for patron
+    my $self = $class->SUPER::new({
+        borrowernumber => $params->{'borrowernumber'},
+        message_attribute_id => $default->{'message_attribute_id'},
+        days_in_advance => $default->{'days_in_advance'},
+        wants_digest => $default->{'wants_digest'},
+    })->store;
+
+    # Set default messaging transport types
+    my $default_transport_types = Koha::Patron::Message::Transport::Preferences->
+    search({ borrower_message_preference_id => $default->{'borrower_message_preference_id'} });
+    while (my $transport = $default_transport_types->next) {
+        Koha::Patron::Message::Transport::Preference->new({
+            borrower_message_preference_id => $self->borrower_message_preference_id,
+            message_transport_type => $transport->message_transport_type,
+        })->store;
+    }
+
+    return $self;
+}
+
 =head3 store
 
 Makes a validation before actual Koha::Object->store so that proper exceptions
diff --git a/t/db_dependent/Koha/Patron/Message/Preferences.t b/t/db_dependent/Koha/Patron/Message/Preferences.t
index 91d77e3..07a6e04 100644
--- a/t/db_dependent/Koha/Patron/Message/Preferences.t
+++ b/t/db_dependent/Koha/Patron/Message/Preferences.t
@@ -126,7 +126,7 @@ subtest 'Add a test messaging transport' => sub {
 };
 
 subtest 'Add a messaging preference to patron' => sub {
-    plan tests => 4;
+    plan tests => 5;
 
     ok($preference = Koha::Patron::Message::Preference->new({
         borrowernumber => $patron->{'borrowernumber'},
@@ -147,6 +147,40 @@ subtest 'Add a messaging preference to patron' => sub {
             "Adding a duplicate preference"
             ." => Koha::Exceptions::DuplicateObject");
 
+    subtest 'Add preferences from defaults' => sub {
+        plan tests => 4;
+
+        my $attr = Koha::Patron::Message::Attribute->new({
+            message_name => "default",
+        })->store;
+        ok(my $default = Koha::Patron::Message::Preference->new({
+            categorycode   => $patron->{'categorycode'},
+            message_attribute_id => $attr->message_attribute_id,
+            wants_digest   => 1,
+            days_in_advance => 1337,
+        })->store, "Created a new default preference for category.");
+        Koha::Patron::Message::Transport::Preference->new({
+            borrower_message_preference_id => $default->borrower_message_preference_id,
+            message_transport_type => "sms",
+        })->store;
+        Koha::Patron::Message::Transport::Preference->new({
+            borrower_message_preference_id => $default->borrower_message_preference_id,
+            message_transport_type => "email",
+        })->store;
+        ok(Koha::Patron::Message::Preference->new_from_default({
+            borrowernumber => $patron->{'borrowernumber'},
+            categorycode   => $patron->{'categorycode'},
+            message_attribute_id => $attr->message_attribute_id,
+        })->store, "Added a default preference to patron.");
+        ok(my $pref = Koha::Patron::Message::Preferences->find({
+            borrowernumber => $patron->{'borrowernumber'},
+            message_attribute_id => $attr->message_attribute_id,
+        }), "Found the default preference from patron.");
+        is(Koha::Patron::Message::Transport::Preferences->search({
+            borrower_message_preference_id => $pref->borrower_message_preference_id
+        })->count, 2, "Found the two transport types that we set earlier");
+    };
+
     subtest 'Attempt to add a messaging preference with invalid parameters' => sub {
         plan tests => 6;
 
-- 
2.7.4