Bugzilla – Attachment 91864 Details for
Bug 17499
Koha objects for messaging preferences
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 17499: Add Koha-objects for messaging preferences
0001-Bug-17499-Add-Koha-objects-for-messaging-preferences.patch (text/plain), 194.30 KB, created by
Emmi Takkinen
on 2019-07-30 11:35:13 UTC
(
hide
)
Description:
Bug 17499: Add Koha-objects for messaging preferences
Filename:
MIME Type:
Creator:
Emmi Takkinen
Created:
2019-07-30 11:35:13 UTC
Size:
194.30 KB
patch
obsolete
>From 70190be778bf8c1489d38f58725d8cfaf52ecf98 Mon Sep 17 00:00:00 2001 >From: Lari Taskula <lari.taskula@jns.fi> >Date: Fri, 21 Oct 2016 17:26:24 +0300 >Subject: [PATCH] Bug 17499: Add Koha-objects for messaging preferences > >This patch adds Koha-objects for messaging preferences. > >Adds simple validation for messaging preferences. > >The validation includes >- throw exception if both borrowernumber or categorycode is given for a new pref >- throw exception if patron for the given borrowernumber is not found >- throw exception if category for the given categorycode is not found >- throw exception if days in advance cannot be configured but is given >- throw exception if days in advance configuration is invalid (value between 0-30) >- throw exception if digest is not available but attempted to set on >- throw exception if digest must be enabled but attempted to set off >- throw exception on duplicate messaging preference > >Adds a method for getting available messaging options. > >Adds a method for setting default messaging preferenes. > $patron->set_default_messaging_preferences (where $patron is a Koha::Patron) > ...or... > Koha::Patron::Message::Preference->new_from_default({ > borrowernumber => 123, > categorycode => "ABC", > message_attribute_id => 1, > }); > >Since messaging preference is a feature that has multiple related database tables, >usage via Koha-objects is sometimes frustrating. This patch adds easy access to >message transport types via > $preference->message_transport_types (for getting) > $preference->set({ message_transport_types => ['email', 'sms'] }) (for setting) > (also supports other calling conventions, see documentation for more) > >Adds optional parameter message_name for Koha::Patron::Message::Preferences->find >and ->search. Simplifies the Koha-object usage by allowing developer to skip joins >and / or querying the message name via attribute_id from message_attributes table. > >Includes test coverage for basic usage. > >To test: >1. prove t/db_dependent/Koha/Patron/Message/* > >Following Bug 17499, check also Bug 18595 that replaces C4::Members::Messaging >with these new Koha-objects. > >Signed-off-by: Dominic Pichette <dominic@inlibro.com> >--- > ...4620-Contact-information-validations.patch | 648 +++++ > ...ow-up-Link-URL-in-system-preference-.patch | 23 + > ...Koha-objects-for-messaging-preferenc.patch | 2422 +++++++++++++++++ > Koha/Exceptions.pm | 8 +- > Koha/Patron.pm | 42 + > Koha/Patron/Message/Attribute.pm | 50 + > Koha/Patron/Message/Attributes.pm | 55 + > Koha/Patron/Message/Preference.pm | 451 +++ > Koha/Patron/Message/Preferences.pm | 146 + > Koha/Patron/Message/Transport.pm | 50 + > Koha/Patron/Message/Transport/Preference.pm | 51 + > Koha/Patron/Message/Transport/Preferences.pm | 56 + > Koha/Patron/Message/Transport/Type.pm | 51 + > Koha/Patron/Message/Transport/Types.pm | 56 + > Koha/Patron/Message/Transports.pm | 55 + > ..._14620-Contact-information-validation.perl | 7 + > .../Koha/Patron/Message/Attributes.t | 74 + > .../Koha/Patron/Message/Preferences.t | 719 +++++ > .../Patron/Message/Transport/Preferences.t | 179 ++ > .../Koha/Patron/Message/Transport/Types.t | 54 + > .../Koha/Patron/Message/Transports.t | 119 + > 21 files changed, 5315 insertions(+), 1 deletion(-) > create mode 100644 Bug-14620-Contact-information-validations.patch > create mode 100644 Bug-14620-follow-up-Link-URL-in-system-preference-.patch > create mode 100644 Bug-17499-Add-Koha-objects-for-messaging-preferenc.patch > create mode 100644 Koha/Patron/Message/Attribute.pm > create mode 100644 Koha/Patron/Message/Attributes.pm > create mode 100644 Koha/Patron/Message/Preference.pm > create mode 100644 Koha/Patron/Message/Preferences.pm > create mode 100644 Koha/Patron/Message/Transport.pm > create mode 100644 Koha/Patron/Message/Transport/Preference.pm > create mode 100644 Koha/Patron/Message/Transport/Preferences.pm > create mode 100644 Koha/Patron/Message/Transport/Type.pm > create mode 100644 Koha/Patron/Message/Transport/Types.pm > create mode 100644 Koha/Patron/Message/Transports.pm > create mode 100644 installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl > create mode 100644 t/db_dependent/Koha/Patron/Message/Attributes.t > create mode 100644 t/db_dependent/Koha/Patron/Message/Preferences.t > create mode 100644 t/db_dependent/Koha/Patron/Message/Transport/Preferences.t > create mode 100644 t/db_dependent/Koha/Patron/Message/Transport/Types.t > create mode 100644 t/db_dependent/Koha/Patron/Message/Transports.t > >diff --git a/Bug-14620-Contact-information-validations.patch b/Bug-14620-Contact-information-validations.patch >new file mode 100644 >index 0000000000..85bf1d4a59 >--- /dev/null >+++ b/Bug-14620-Contact-information-validations.patch >@@ -0,0 +1,648 @@ >+From 42e664f126d763a63db655df9a6807113d0f3dde Mon Sep 17 00:00:00 2001 >+From: Lari Taskula <lari.taskula@jns.fi> >+Date: Tue, 4 Apr 2017 14:00:31 +0000 >+Subject: [PATCH] Bug 14620: Contact information validations >+ >+This patch adds a phone number validation by regex and centralizes >+different validation methods into Koha::Validation class. >+ >+Introduces a new system preference, ValidatePhoneNumber, that takes a >+regular expression and uses it to validate phone numbers both client >+and server side. >+ >+Unit tests to test: >+1. prove t/db_dependent/Koha/Validation.t >+ >+To test: >+1. Apply the patches and run updatedatabase.pl to install the new >+ system preference >+2. Set system preference ValidatePhoneNumber to any regex you like >+ (there is an example in the description of the preference) >+3. Navigate to edit user contact informations in Staff client and OPAC. >+4. Insert invalid email (e.g. "invalid") and invalid phone number ("+123invalid") >+ and send the form. >+5. Confirm that form will not be submitted and errors will be given. >+6. Disable JavaScript and test that these errors will also be provided by the >+ server. >+--- >+ Koha/Validation.pm | 80 ++++++++++++++++++++++ >+ .../Bug_14620-Contact-information-validation.perl | 7 ++ >+ installer/data/mysql/sysprefs.sql | 1 + >+ .../prog/en/modules/admin/preferences/patrons.pref | 9 +++ >+ .../prog/en/modules/members/memberentrygen.tt | 25 +++++++ >+ koha-tmpl/intranet-tmpl/prog/js/members.js | 28 ++++++++ >+ .../bootstrap/en/modules/opac-memberentry.tt | 37 ++++++++++ >+ .../bootstrap/en/modules/opac-messaging.tt | 44 ++++++++++++ >+ members/memberentry.pl | 32 +++++---- >+ opac/opac-memberentry.pl | 21 ++++-- >+ opac/opac-messaging.pl | 13 +++- >+ t/db_dependent/Koha/Validation.t | 76 ++++++++++++++++++++ >+ 12 files changed, 353 insertions(+), 20 deletions(-) >+ create mode 100644 Koha/Validation.pm >+ create mode 100644 installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl >+ create mode 100644 t/db_dependent/Koha/Validation.t >+ >+diff --git a/Koha/Validation.pm b/Koha/Validation.pm >+new file mode 100644 >+index 0000000000..94006d88bd >+--- /dev/null >++++ b/Koha/Validation.pm >+@@ -0,0 +1,80 @@ >++package Koha::Validation; >++ >++# Copyright 2017 Koha-Suomi Oy >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 2 of the License, or (at your option) any later >++# version. >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use C4::Context; >++use Email::Valid; >++ >++=head1 NAME >++ >++Koha::Validation - validates inputs >++ >++=head1 SYNOPSIS >++ >++ use Koha::Validation >++ >++=head1 DESCRIPTION >++ >++This module lets you validate given inputs. >++ >++=head2 METHODS >++ >++=head3 email >++ >++Koha::Validation::email("email@address.com"); >++ >++Validates given email. >++ >++returns: 1 if the given email is valid (or empty), 0 otherwise. >++ >++=cut >++ >++sub email { >++ my $address = shift; >++ >++ return 1 unless $address; >++ return 0 if $address =~ /(^(\s))|((\s)$)/; >++ >++ return (not defined Email::Valid->address($address)) ? 0:1; >++} >++ >++=head3 phone >++ >++Koha::Validation::validate_phonenumber(123456789); >++ >++Validates given phone number. >++ >++returns: 1 if the given phone number is valid (or empty), 0 otherwise. >++ >++=cut >++ >++sub phone { >++ my $phonenumber = shift; >++ >++ return 1 unless $phonenumber; >++ return 0 if $phonenumber =~ /(^(\s))|((\s)$)/; >++ >++ my $regex = C4::Context->preference("ValidatePhoneNumber"); >++ $regex = qr/$regex/; >++ >++ return ($phonenumber !~ /$regex/) ? 0:1; >++} >++ >++1; >+diff --git a/installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl b/installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl >+new file mode 100644 >+index 0000000000..d816b0ca80 >+--- /dev/null >++++ b/installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl >+@@ -0,0 +1,7 @@ >++$DBversion = 'XXX'; # will be replaced by the RM >++if( CheckVersion( $DBversion ) ) { >++ $dbh->do("INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES ('ValidatePhoneNumber','','','Regex for validation of patron phone numbers.','Textarea')"); >++ >++ SetVersion( $DBversion ); >++ print "Upgrade to $DBversion done (Bug 14620 - description)\n"; >++} >+diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >+index bc08b5a5d3..04bd7fd810 100644 >+--- a/installer/data/mysql/sysprefs.sql >++++ b/installer/data/mysql/sysprefs.sql >+@@ -576,6 +576,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` >+ ('UseQueryParser','0',NULL,'If enabled, try to use QueryParser for queries.','YesNo'), >+ ('UseTransportCostMatrix','0','','Use Transport Cost Matrix when filling holds','YesNo'), >+ ('UseWYSIWYGinSystemPreferences','0','','Show WYSIWYG editor when editing certain HTML system preferences.','YesNo'), >++('ValidatePhoneNumber','','','Regex for validation of patron phone numbers.','Textarea'), >+ ('viewISBD','1','','Allow display of ISBD view of bibiographic records','YesNo'), >+ ('viewLabeledMARC','0','','Allow display of labeled MARC view of bibiographic records','YesNo'), >+ ('viewMARC','1','','Allow display of MARC view of bibiographic records','YesNo'), >+diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >+index 3a95ba71aa..867bfe45e7 100644 >+--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >++++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >+@@ -219,3 +219,12 @@ Patrons: >+ - pref: FailedLoginAttempts >+ class: integer >+ - failed login attempts. >++ - >++ - Use the following regex / >++ - pref: ValidatePhoneNumber >++ type: textarea >++ class: code >++ - / to validate patrons' phone numbers. >++ - Example ^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]{1,12}){1,2}$ >++ - (Source of example http://regexlib.com/REDetails.aspx?regexp_id=3009) >++ - Leave blank to accept any phone number. >+diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt >+index 091486efca..874da57ace 100644 >+--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt >++++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/memberentrygen.tt >+@@ -62,6 +62,19 @@ $(document).ready(function() { >+ $(".toggler").toggle(); >+ }); >+ >++ >++ var MSG_INCORRECT_PHONE = _("Please enter a valid phone number."); >++ $.validator.addMethod('phone', function(value) { >++ value = value.trim(); >++ if (!value.trim()) { >++ return 1; >++ } >++ else { >++ return (value.match(/[% ValidatePhoneNumber %]/)); >++ } >++ }, >++ MSG_INCORRECT_PHONE); >++ >+ $("#save_quick_add").click(function(){ >+ $("#quick_add_form").validate(); >+ if( $("#quick_add_form").valid()){ >+@@ -201,6 +214,18 @@ $(document).ready(function() { >+ [% IF ERROR_bad_email_alternative %] >+ <li id="ERROR_bad_email_alternative">The alternative email is invalid.</li> >+ [% END %] >++ [% IF ERROR_bad_phone %] >++ <li id="ERROR_bad_phone">The primary phone is invalid.</li> >++ [% END %] >++ [% IF ERROR_bad_phone_secondary %] >++ <li id="ERROR_bad_phone_secondary">The secondary phone is invalid.</li> >++ [% END %] >++ [% IF ERROR_bad_phone_alternative %] >++ <li id="ERROR_bad_phone_alternative">The alternative phone is invalid.</li> >++ [% END %] >++ [% IF ERROR_bad_smsnumber %] >++ <li id="ERROR_bad_smsnumber">The SMS number is invalid.</li> >++ [% END %] >+ </ul> >+ </div> >+ [% END %] >+diff --git a/koha-tmpl/intranet-tmpl/prog/js/members.js b/koha-tmpl/intranet-tmpl/prog/js/members.js >+index 2ced2eca8b..bfb8376820 100644 >+--- a/koha-tmpl/intranet-tmpl/prog/js/members.js >++++ b/koha-tmpl/intranet-tmpl/prog/js/members.js >+@@ -333,6 +333,21 @@ $(document).ready(function(){ >+ }, >+ B_email: { >+ email: true >++ }, >++ phone: { >++ phone: true >++ }, >++ phonepro: { >++ phone: true >++ }, >++ mobile: { >++ phone: true >++ }, >++ SMSnumber: { >++ phone: true >++ }, >++ B_phone: { >++ phone: true >+ } >+ }, >+ submitHandler: function(form) { >+@@ -341,10 +356,23 @@ $(document).ready(function(){ >+ return false; >+ else >+ form.beenSubmitted = true; >++ $("#email, #emailpro, #B_email").each(function(){ >++ $(this).val($.trim($(this).val())); >++ }); >++ $("#phone, #phonepro, #B_phone, #SMSnumber").each(function(){ >++ $(this).val($.trim($(this).val())); >++ }); >+ form.submit(); >+ } >+ }); >+ >++ $("#email, #emailpro, #B_email").each(function(){ >++ $(this).val($.trim($(this).val())); >++ }); >++ $("#phone, #phonepro, #B_phone, #SMSnumber").each(function(){ >++ $(this).val($.trim($(this).val())); >++ }); >++ >+ var mrform = $("#manual_restriction_form"); >+ var mrlink = $("#add_manual_restriction"); >+ mrform.hide(); >+diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt >+index d3b89bfdbb..efa392235d 100644 >+--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt >++++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-memberentry.tt >+@@ -64,6 +64,10 @@ >+ [% IF field == "email" %]<li>Contact information: <a href="#borrower_email">primary email address</a></li>[% END %] >+ [% IF field == "emailpro" %]<li>Contact information: <a href="#borrower_emailpro">secondary email address</a></li>[% END %] >+ [% IF field == "B_email" %]<li>Alternate address information: <a href="#borrower_B_email">email address</a></li>[% END %] >++ [% IF field == "phone" %]<li>Contact information: <a href="#borrower_phone">primary phone</a></li>[% END %] >++ [% IF field == "phonepro" %]<li>Contact information: <a href="#borrower_phonepro">secondary phone</a></li>[% END %] >++ [% IF field == "mobile" %]<li>Contact information: <a href="#borrower_mobile">other phone</a></li>[% END %] >++ [% IF field == "B_phone" %]<li>Alternate address information: <a href="#borrower_B_phone">phone</a></li>[% END %] >+ [% IF field == "password_match" %]<li>Passwords do not match! <a href="#password">password</a></li>[% END %] >+ [% IF field == "password_invalid" %]<li>Password does not meet minimum requirements! <a href="#password">password</a></li>[% END %] >+ [% IF field == "password_spaces" %]<li>Password contains leading and/or trailing spaces! <a href="#password">password</a></li>[% END %] >+@@ -943,6 +947,17 @@ >+ $('label.required').removeClass('required'); >+ [% END %] >+ >++ var MSG_INCORRECT_PHONE = _("Please enter a valid phone number."); >++ $.validator.addMethod('phone', function(value) { >++ if (!value.trim()) { >++ return 1; >++ } >++ else { >++ return (value.match(/[% ValidatePhoneNumber %]/)); >++ } >++ }, >++ MSG_INCORRECT_PHONE); >++ >+ $("#memberentry-form").validate({ >+ rules: { >+ borrower_email: { >+@@ -953,6 +968,18 @@ >+ }, >+ borrower_B_email: { >+ email: true >++ }, >++ borrower_phone: { >++ phone: true >++ }, >++ borrower_phonepro: { >++ phone: true >++ }, >++ borrower_mobile: { >++ phone: true >++ }, >++ borrower_B_phone: { >++ phone: true >+ } >+ }, >+ submitHandler: function(form) { >+@@ -961,6 +988,12 @@ >+ } >+ else { >+ form.beenSubmitted = true; >++ $("#borrower_email, #borrower_emailpro, #borrower_B_email").each(function(){ >++ $(this).val($.trim($(this).val())); >++ }); >++ $("#borrower_phone, #borrower_phonepro, #borrower_B_phone").each(function(){ >++ $(this).val($.trim($(this).val())); >++ }); >+ form.submit(); >+ } >+ }, >+@@ -975,6 +1008,10 @@ >+ } >+ }); >+ >++ $("#borrower_email, #borrower_emailpro, #borrower_B_email, #borrower_phone, #borrower_phonepro, #borrower_B_phone").on("change", function(){ >++ $(this).val($.trim($(this).val())); >++ }); >++ >+ [% IF borrower.guarantorid && !Koha.Preference('OPACPrivacy') && Koha.Preference('AllowPatronToSetCheckoutsVisibilityForGuarantor') %] >+ $('#update_privacy_guarantor_checkouts').click( function() { >+ $.post( "/cgi-bin/koha/svc/patron/show_checkouts_to_relatives", { privacy_guarantor_checkouts: $('#privacy_guarantor_checkouts').val() }, null, 'json') >+diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt >+index 801389c97c..a28918f6ba 100644 >+--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt >++++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-messaging.tt >+@@ -28,6 +28,9 @@ >+ [% IF ( settings_updated ) %] >+ <div class="alert alert-success"><h4>Settings updated</h4></div> >+ [% END %] >++ [% IF ( invalid_smsnumber ) %] >++ <div class="alert alert-error"><h4>Invalid SMS number</h4></div> >++ [% END %] >+ <form action="/cgi-bin/koha/opac-messaging.pl" method="get" name="opacmessaging"> >+ <input type="hidden" name="modify" value="yes" /> >+ >+@@ -184,7 +187,48 @@ >+ } >+ }); >+ $("#info_digests").tooltip(); >++ >++ var MSG_INCORRECT_PHONE = _("Please enter a valid phone number."); >++ $.validator.addMethod('phone', function(value) { >++ if (!value.trim()) { >++ return 1; >++ } >++ else { >++ return (value.match(/[% ValidatePhoneNumber %]/)); >++ } >++ }, >++ MSG_INCORRECT_PHONE); >++ >++ $("form[name='opacmessaging']").validate({ >++ rules: { >++ SMSnumber: { >++ phone: true >++ } >++ }, >++ submitHandler: function(form) { >++ $("body, form input[type='submit'], form button[type='submit'], form a").addClass('waiting'); >++ if (form.beenSubmitted) { >++ return false; >++ } >++ else { >++ form.beenSubmitted = true; >++ $("#SMSnumber").each(function(){ >++ $(this).val($.trim($(this).val())); >++ }); >++ form.submit(); >++ } >++ }, >++ errorPlacement: function(error, element) { >++ error.insertAfter(element.closest("li")).wrap('<li></li>'); >++ error.addClass('alert-error'); >++ error.width("auto"); >++ } >++ }); >++ $("#SMSnumber").on("change", function(){ >++ $(this).val($.trim($(this).val())); >++ }); >+ }); >+ //]]> >+ </script> >++<script type="text/javascript" src="/opac-tmpl/bootstrap/lib/jquery/plugins/jquery.validate.min.js"></script> >+ [% END %] >+diff --git a/members/memberentry.pl b/members/memberentry.pl >+index c58b2a9bff..24857089fa 100755 >+--- a/members/memberentry.pl >++++ b/members/memberentry.pl >+@@ -47,7 +47,7 @@ use Koha::Patron::Categories; >+ use Koha::Patron::HouseboundRole; >+ use Koha::Patron::HouseboundRoles; >+ use Koha::Token; >+-use Email::Valid; >++use Koha::Validation; >+ use Module::Load; >+ if ( C4::Context->preference('NorwegianPatronDBEnable') && C4::Context->preference('NorwegianPatronDBEnable') == 1 ) { >+ load Koha::NorwegianPatronDB, qw( NLGetSyncDataFromBorrowernumber ); >+@@ -363,19 +363,13 @@ if ($op eq 'save' || $op eq 'insert'){ >+ push @errors, "ERROR_short_password" if( $password && $minpw && $password ne '****' && (length($password) < $minpw) ); >+ >+ # Validate emails >+- my $emailprimary = $input->param('email'); >+- my $emailsecondary = $input->param('emailpro'); >+- my $emailalt = $input->param('B_email'); >+- >+- if ($emailprimary) { >+- push (@errors, "ERROR_bad_email") if (!Email::Valid->address($emailprimary)); >+- } >+- if ($emailsecondary) { >+- push (@errors, "ERROR_bad_email_secondary") if (!Email::Valid->address($emailsecondary)); >+- } >+- if ($emailalt) { >+- push (@errors, "ERROR_bad_email_alternative") if (!Email::Valid->address($emailalt)); >+- } >++ push (@errors, "ERROR_bad_email") if ($input->param('email') && !Koha::Validation::email($input->param('email'))); >++ push (@errors, "ERROR_bad_email_secondary") if ($input->param('emailpro') && !Koha::Validation::email($input->param('emailpro'))); >++ push (@errors, "ERROR_bad_email_alternative") if ($input->param('B_email') && !Koha::Validation::email($input->param('B_email'))); >++ # Validate phone numbers >++ push (@errors, "ERROR_bad_phone") if ($input->param('phone') && !Koha::Validation::phone($input->param('phone'))); >++ push (@errors, "ERROR_bad_phone_secondary") if ($input->param('phonepro') && !Koha::Validation::phone($input->param('phonepro'))); >++ push (@errors, "ERROR_bad_phone_alternative") if ($input->param('B_phone') && !Koha::Validation::phone($input->param('B_phone'))); >+ >+ if (C4::Context->preference('ExtendedPatronAttributes')) { >+ $extended_patron_attributes = parse_extended_patron_attributes($input); >+@@ -403,7 +397,11 @@ if ( ($op eq 'modify' || $op eq 'insert' || $op eq 'save'|| $op eq 'duplicate') >+ # BZ 14683: Do not mixup mobile [read: other phone] with smsalertnumber >+ my $sms = $input->param('SMSnumber'); >+ if ( defined $sms ) { >+- $newdata{smsalertnumber} = $sms; >++ if (Koha::Validation::phone($sms)){ >++ $newdata{smsalertnumber} = $sms; >++ } else { >++ push (@errors, "ERROR_bad_smsnumber"); >++ } >+ } >+ >+ ### Error checks should happen before this line. >+@@ -720,6 +718,10 @@ if (C4::Context->preference('ExtendedPatronAttributes')) { >+ patron_attributes_form($template, $borrowernumber); >+ } >+ >++$template->param( >++ ValidatePhoneNumber => C4::Context->preference('ValidatePhoneNumber') || '.*', >++); >++ >+ if (C4::Context->preference('EnhancedMessagingPreferences')) { >+ if ($op eq 'add') { >+ C4::Form::MessagingPreferences::set_form_values({ categorycode => $categorycode }, $template); >+diff --git a/opac/opac-memberentry.pl b/opac/opac-memberentry.pl >+index 9784a3deef..7dba2d9575 100755 >+--- a/opac/opac-memberentry.pl >++++ b/opac/opac-memberentry.pl >+@@ -29,7 +29,6 @@ use C4::Members; >+ use C4::Members::Attributes qw( GetBorrowerAttributes ); >+ use C4::Form::MessagingPreferences; >+ use C4::Scrubber; >+-use Email::Valid; >+ use Koha::DateUtils; >+ use Koha::Libraries; >+ use Koha::Patron::Attribute::Types; >+@@ -39,6 +38,7 @@ use Koha::Patron::Modification; >+ use Koha::Patron::Modifications; >+ use Koha::Patrons; >+ use Koha::Token; >++use Koha::Validation; >+ >+ my $cgi = new CGI; >+ my $dbh = C4::Context->dbh; >+@@ -88,6 +88,7 @@ $template->param( >+ mandatory => $mandatory, >+ libraries => \@libraries, >+ OPACPatronDetails => C4::Context->preference('OPACPatronDetails'), >++ ValidatePhoneNumber => C4::Context->preference('ValidatePhoneNumber') || '.*', >+ ); >+ >+ my $attributes = ParsePatronAttributes($borrowernumber,$cgi); >+@@ -390,7 +391,7 @@ sub CheckForInvalidFields { >+ my $borrower = shift; >+ my @invalidFields; >+ if ($borrower->{'email'}) { >+- unless ( Email::Valid->address($borrower->{'email'}) ) { >++ unless ( Koha::Validation::email($borrower->{'email'}) ) { >+ push(@invalidFields, "email"); >+ } elsif ( C4::Context->preference("PatronSelfRegistrationEmailMustBeUnique") ) { >+ my $patrons_with_same_email = Koha::Patrons->search( >+@@ -410,10 +411,22 @@ sub CheckForInvalidFields { >+ } >+ } >+ if ($borrower->{'emailpro'}) { >+- push(@invalidFields, "emailpro") if (!Email::Valid->address($borrower->{'emailpro'})); >++ push(@invalidFields, "emailpro") if (!Koha::Validation::email($borrower->{'emailpro'})); >+ } >+ if ($borrower->{'B_email'}) { >+- push(@invalidFields, "B_email") if (!Email::Valid->address($borrower->{'B_email'})); >++ push(@invalidFields, "B_email") if (!Koha::Validation::email($borrower->{'B_email'})); >++ } >++ if ($borrower->{'mobile'}) { >++ push(@invalidFields, "mobile") if (!Koha::Validation::phone($borrower->{'mobile'})); >++ } >++ if ($borrower->{'phone'}) { >++ push(@invalidFields, "phone") if (!Koha::Validation::phone($borrower->{'phone'})); >++ } >++ if ($borrower->{'phonepro'}) { >++ push(@invalidFields, "phonepro") if (!Koha::Validation::phone($borrower->{'phonepro'})); >++ } >++ if ($borrower->{'B_phone'}) { >++ push(@invalidFields, "B_phone") if (!Koha::Validation::phone($borrower->{'B_phone'})); >+ } >+ if ( defined $borrower->{'password'} >+ and $borrower->{'password'} ne $borrower->{'password2'} ) >+diff --git a/opac/opac-messaging.pl b/opac/opac-messaging.pl >+index 906d56fe4e..f360b4bcd7 100755 >+--- a/opac/opac-messaging.pl >++++ b/opac/opac-messaging.pl >+@@ -31,6 +31,7 @@ use C4::Members; >+ use C4::Members::Messaging; >+ use C4::Form::MessagingPreferences; >+ use Koha::SMS::Providers; >++use Koha::Validation; >+ >+ my $query = CGI->new(); >+ >+@@ -53,10 +54,20 @@ my ( $template, $borrowernumber, $cookie ) = get_template_and_user( >+ my $borrower = Koha::Patrons->find( $borrowernumber )->unblessed; >+ my $messaging_options = C4::Members::Messaging::GetMessagingOptions(); >+ >++my $validate_phone = C4::Context->preference('ValidatePhoneNumber'); >++ >++$template->param( >++ ValidatePhoneNumber => $validate_phone || '.*', >++); >++ >+ if ( defined $query->param('modify') && $query->param('modify') eq 'yes' ) { >+ my $sms = $query->param('SMSnumber'); >+ my $sms_provider_id = $query->param('sms_provider_id'); >+- if ( defined $sms && ( $borrower->{'smsalertnumber'} // '' ) ne $sms >++ >++ my $valid_sms = Koha::Validation::phone($sms); >++ $template->param( invalid_smsnumber => 1 ) unless $valid_sms; >++ >++ if ( defined $sms && $valid_sms && ( $borrower->{'smsalertnumber'} // '' ) ne $sms >+ or ( $borrower->{sms_provider_id} // '' ) ne $sms_provider_id ) { >+ ModMember( >+ borrowernumber => $borrowernumber, >+diff --git a/t/db_dependent/Koha/Validation.t b/t/db_dependent/Koha/Validation.t >+new file mode 100644 >+index 0000000000..481ea8583d >+--- /dev/null >++++ b/t/db_dependent/Koha/Validation.t >+@@ -0,0 +1,76 @@ >++#!/usr/bin/perl >++# >++# Copyright 2017 Koha-Suomi Oy >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version. >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Test::More tests => 3; >++ >++use t::lib::Mocks; >++ >++BEGIN { >++ use_ok('Koha::Validation'); >++} >++ >++subtest 'email() tests' => sub { >++ plan tests => 2; >++ >++ is(Koha::Validation::email('test'), 0, "'test' is invalid e-mail address'"); >++ is(Koha::Validation::email('test@example.com'), 1, '\'test@example.com\' is ' >++ .'valid e-mail address'); >++}; >++ >++subtest 'phone() tests' => sub { >++ plan tests => 3; >++ >++ t::lib::Mocks::mock_preference('ValidatePhoneNumber', ''); >++ >++ is(Koha::Validation::phone('test'), 1, 'Phone number validation is switched ' >++ .'off, so \'test\' is a valid phone number'); >++ >++ # An example: Finnish Phone number validation regex >++ subtest 'Finnish phone number validation regex' => sub { >++ t::lib::Mocks::mock_preference('ValidatePhoneNumber', >++ '^((90[0-9]{3})?0|\+358\s?)(?!(100|20(0|2(0|[2-3])|9[8-9])|300|600|70' >++ .'0|708|75(00[0-3]|(1|2)\d{2}|30[0-2]|32[0-2]|75[0-2]|98[0-2])))(4|50|' >++ .'10[1-9]|20(1|2(1|[4-9])|[3-9])|29|30[1-9]|71|73|75(00[3-9]|30[3-9]|3' >++ .'2[3-9]|53[3-9]|83[3-9])|2|3|5|6|8|9|1[3-9])\s?(\d\s?){4,19}\d$' >++ ); >++ >++ is(Koha::Validation::phone('1234'), 0, '1234 is invalid phone number.'); >++ is(Koha::Validation::phone('+358501234567'), 1, '+358501234567 is valid ' >++ .'phone number.'); >++ is(Koha::Validation::phone('+1-202-555-0198'), 0, '+1-202-555-0198 is ' >++ .'invalid phone number.'); >++ }; >++ >++ subtest 'International phone number validation regex' => sub { >++ t::lib::Mocks::mock_preference('ValidatePhoneNumber', >++ '^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]' >++ .'{1,12}){1,2}$' >++ ); >++ >++ is(Koha::Validation::phone('nope'), 0, 'nope is invalid phone number.'); >++ is(Koha::Validation::phone('1234'), 1, '1234 is valid phone number.'); >++ is(Koha::Validation::phone('+358501234567'), 1, '+358501234567 is valid ' >++ .'phone number.'); >++ is(Koha::Validation::phone('+1-202-555-0198'), 1, '+1-202-555-0198 is ' >++ .'valid phone number.'); >++ }; >++ >++}; >+-- >+2.11.0 >\ No newline at end of file >diff --git a/Bug-14620-follow-up-Link-URL-in-system-preference-.patch b/Bug-14620-follow-up-Link-URL-in-system-preference-.patch >new file mode 100644 >index 0000000000..27daa54007 >--- /dev/null >+++ b/Bug-14620-follow-up-Link-URL-in-system-preference-.patch >@@ -0,0 +1,23 @@ >+From 820a58e04f9ee72a9c1144ad4d5191894c3f57e8 Mon Sep 17 00:00:00 2001 >+From: Katrin Fischer <katrin.fischer.83@web.de> >+Date: Sat, 7 Oct 2017 23:40:24 +0200 >+Subject: [PATCH] Bug 14620: (follow-up) Link URL in system preference >+ description >+ >+--- >+ koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref | 2 +- >+ 1 file changed, 1 insertion(+), 1 deletion(-) >+ >+diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >+index 867bfe45e7..e9efda3cb4 100644 >+--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >++++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref >+@@ -226,5 +226,5 @@ Patrons: >+ class: code >+ - / to validate patrons' phone numbers. >+ - Example ^((\+)?[1-9]{1,2})?([-\s\.])?((\(\d{1,4}\))|\d{1,4})(([-\s\.])?[0-9]{1,12}){1,2}$ >+- - (Source of example http://regexlib.com/REDetails.aspx?regexp_id=3009) >++ - (Source of example <a href="http://regexlib.com/REDetails.aspx?regexp_id=3009">RegExLib.com</a>) >+ - Leave blank to accept any phone number. >+-- >+2.11.0 >\ No newline at end of file >diff --git a/Bug-17499-Add-Koha-objects-for-messaging-preferenc.patch b/Bug-17499-Add-Koha-objects-for-messaging-preferenc.patch >new file mode 100644 >index 0000000000..74f605b0b0 >--- /dev/null >+++ b/Bug-17499-Add-Koha-objects-for-messaging-preferenc.patch >@@ -0,0 +1,2422 @@ >+From 5cb18bd6b778730cd86e44f2920e75b167854b3c Mon Sep 17 00:00:00 2001 >+From: Lari Taskula <lari.taskula@jns.fi> >+Date: Fri, 21 Oct 2016 17:26:24 +0300 >+Subject: [PATCH] Bug 17499: Add Koha-objects for messaging preferences >+ >+This patch adds Koha-objects for messaging preferences. >+ >+Adds simple validation for messaging preferences. >+ >+The validation includes >+- throw exception if both borrowernumber or categorycode is given for a new pref >+- throw exception if patron for the given borrowernumber is not found >+- throw exception if category for the given categorycode is not found >+- throw exception if days in advance cannot be configured but is given >+- throw exception if days in advance configuration is invalid (value between 0-30) >+- throw exception if digest is not available but attempted to set on >+- throw exception if digest must be enabled but attempted to set off >+- throw exception on duplicate messaging preference >+ >+Adds a method for getting available messaging options. >+ >+Adds a method for setting default messaging preferenes. >+ $patron->set_default_messaging_preferences (where $patron is a Koha::Patron) >+ ...or... >+ Koha::Patron::Message::Preference->new_from_default({ >+ borrowernumber => 123, >+ categorycode => "ABC", >+ message_attribute_id => 1, >+ }); >+ >+Since messaging preference is a feature that has multiple related database tables, >+usage via Koha-objects is sometimes frustrating. This patch adds easy access to >+message transport types via >+ $preference->message_transport_types (for getting) >+ $preference->set({ message_transport_types => ['email', 'sms'] }) (for setting) >+ (also supports other calling conventions, see documentation for more) >+ >+Adds optional parameter message_name for Koha::Patron::Message::Preferences->find >+and ->search. Simplifies the Koha-object usage by allowing developer to skip joins >+and / or querying the message name via attribute_id from message_attributes table. >+ >+Includes test coverage for basic usage. >+ >+To test: >+1. prove t/db_dependent/Koha/Patron/Message/* >+ >+Following Bug 17499, check also Bug 18595 that replaces C4::Members::Messaging >+with these new Koha-objects. >+ >+Signed-off-by: Dominic Pichette <dominic@inlibro.com> >+--- >+ Koha/Exceptions.pm | 8 +- >+ Koha/Patron.pm | 42 ++ >+ Koha/Patron/Message/Attribute.pm | 50 ++ >+ Koha/Patron/Message/Attributes.pm | 55 ++ >+ Koha/Patron/Message/Preference.pm | 451 +++++++++++++ >+ Koha/Patron/Message/Preferences.pm | 146 +++++ >+ Koha/Patron/Message/Transport.pm | 50 ++ >+ Koha/Patron/Message/Transport/Preference.pm | 51 ++ >+ Koha/Patron/Message/Transport/Preferences.pm | 56 ++ >+ Koha/Patron/Message/Transport/Type.pm | 51 ++ >+ Koha/Patron/Message/Transport/Types.pm | 56 ++ >+ Koha/Patron/Message/Transports.pm | 55 ++ >+ t/db_dependent/Koha/Patron/Message/Attributes.t | 74 +++ >+ t/db_dependent/Koha/Patron/Message/Preferences.t | 719 +++++++++++++++++++++ >+ .../Koha/Patron/Message/Transport/Preferences.t | 179 +++++ >+ .../Koha/Patron/Message/Transport/Types.t | 54 ++ >+ t/db_dependent/Koha/Patron/Message/Transports.t | 119 ++++ >+ 17 files changed, 2215 insertions(+), 1 deletion(-) >+ create mode 100644 Koha/Patron/Message/Attribute.pm >+ create mode 100644 Koha/Patron/Message/Attributes.pm >+ create mode 100644 Koha/Patron/Message/Preference.pm >+ create mode 100644 Koha/Patron/Message/Preferences.pm >+ create mode 100644 Koha/Patron/Message/Transport.pm >+ create mode 100644 Koha/Patron/Message/Transport/Preference.pm >+ create mode 100644 Koha/Patron/Message/Transport/Preferences.pm >+ create mode 100644 Koha/Patron/Message/Transport/Type.pm >+ create mode 100644 Koha/Patron/Message/Transport/Types.pm >+ create mode 100644 Koha/Patron/Message/Transports.pm >+ create mode 100644 t/db_dependent/Koha/Patron/Message/Attributes.t >+ create mode 100644 t/db_dependent/Koha/Patron/Message/Preferences.t >+ create mode 100644 t/db_dependent/Koha/Patron/Message/Transport/Preferences.t >+ create mode 100644 t/db_dependent/Koha/Patron/Message/Transport/Types.t >+ create mode 100644 t/db_dependent/Koha/Patron/Message/Transports.t >+ >+diff --git a/Koha/Exceptions.pm b/Koha/Exceptions.pm >+index 528a151..c212653 100644 >+--- a/Koha/Exceptions.pm >++++ b/Koha/Exceptions.pm >+@@ -27,7 +27,13 @@ use Exception::Class ( >+ }, >+ 'Koha::Exceptions::MissingParameter' => { >+ isa => 'Koha::Exceptions::Exception', >+- description => 'A required parameter is missing' >++ description => 'A required parameter is missing', >++ fields => ['parameter'], >++ }, >++ 'Koha::Exceptions::TooManyParameters' => { >++ isa => 'Koha::Exceptions::Exception', >++ description => 'Too many parameters given', >++ fields => ['parameter'], >+ }, >+ 'Koha::Exceptions::WrongParameter' => { >+ isa => 'Koha::Exceptions::Exception', >+diff --git a/Koha/Patron.pm b/Koha/Patron.pm >+index daa972c..a00f05c 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; >+@@ -656,6 +657,47 @@ sub account_locked { >+ and $self->login_attempts >= $FailedLoginAttempts )? 1 : 0; >+ } >+ >++=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) { >++ # Check that this option has preference configuration for this category >++ unless (Koha::Patron::Message::Preferences->search({ >++ message_attribute_id => $option->{message_attribute_id}, >++ categorycode => $categorycode || $self->categorycode, >++ })->count) { >++ next; >++ } >++ >++ # Delete current setting >++ Koha::Patron::Message::Preferences->search({ >++ borrowernumber => $self->borrowernumber, >++ message_attribute_id => $option->{message_attribute_id}, >++ })->delete; >++ >++ Koha::Patron::Message::Preference->new_from_default({ >++ borrowernumber => $self->borrowernumber, >++ categorycode => $categorycode || $self->categorycode, >++ message_attribute_id => $option->{message_attribute_id}, >++ }); >++ } >++ >++ return $self; >++} >++ >+ =head3 type >+ >+ =cut >+diff --git a/Koha/Patron/Message/Attribute.pm b/Koha/Patron/Message/Attribute.pm >+new file mode 100644 >+index 0000000..9d9004c >+--- /dev/null >++++ b/Koha/Patron/Message/Attribute.pm >+@@ -0,0 +1,50 @@ >++package Koha::Patron::Message::Attribute; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version.a >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++ >++use base qw(Koha::Object); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Attribute - Koha Patron Message Attribute object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'MessageAttribute'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/Koha/Patron/Message/Attributes.pm b/Koha/Patron/Message/Attributes.pm >+new file mode 100644 >+index 0000000..a2df4e6 >+--- /dev/null >++++ b/Koha/Patron/Message/Attributes.pm >+@@ -0,0 +1,55 @@ >++package Koha::Patron::Message::Attributes; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version. >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++use Koha::Patron::Message::Attribute; >++ >++use base qw(Koha::Objects); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Attributes - Koha Patron Message Attributes object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'MessageAttribute'; >++} >++ >++sub object_class { >++ return 'Koha::Patron::Message::Attribute'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/Koha/Patron/Message/Preference.pm b/Koha/Patron/Message/Preference.pm >+new file mode 100644 >+index 0000000..db96b2a >+--- /dev/null >++++ b/Koha/Patron/Message/Preference.pm >+@@ -0,0 +1,451 @@ >++package Koha::Patron::Message::Preference; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version.a >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++use Koha::Exceptions; >++use Koha::Patron::Categories; >++use Koha::Patron::Message::Attributes; >++use Koha::Patron::Message::Preferences; >++use Koha::Patron::Message::Transport::Preferences; >++use Koha::Patron::Message::Transport::Types; >++use Koha::Patron::Message::Transports; >++use Koha::Patrons; >++ >++use base qw(Koha::Object); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Preference - Koha Patron Message Preference object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 new >++ >++my $preference = Koha::Patron::Message::Preference->new({ >++ borrowernumber => 123, >++ #categorycode => 'ABC', >++ message_attribute_id => 4, >++ message_transport_types => ['email', 'sms'], # see documentation below >++ wants_digest => 1, >++ days_in_advance => 7, >++}); >++ >++Takes either borrowernumber or categorycode, but not both. >++ >++days_in_advance may not be available. See message_attributes table for takes_days >++configuration. >++ >++wants_digest may not be available. See message_transports table for is_digest >++configuration. >++ >++You can instantiate a new object without custom validation errors, but when >++storing, validation may throw exceptions. See C<validate()> for more >++documentation. >++ >++C<message_transport_types> is a parameter that is not actually a column in this >++Koha-object. Given this parameter, the message transport types will be added as >++related transport types for this object. For get and set, you can access them via >++subroutine C<message_transport_types()> in this class. >++ >++=cut >++ >++sub new { >++ my ($class, $params) = @_; >++ >++ my $types = $params->{'message_transport_types'}; >++ delete $params->{'message_transport_types'}; >++ >++ my $self = $class->SUPER::new($params); >++ >++ $self->_set_message_transport_types($types); >++ >++ return $self; >++} >++ >++=head3 new_from_default >++ >++my $preference = Koha::Patron::Message::Preference->new_from_default({ >++ borrowernumber => 123, >++ categorycode => 'ABC', # if not given, patron's categorycode will be used >++ message_attribute_id => 1, >++}); >++ >++NOTE: This subroutine initializes and STORES the object (in order to set >++message transport types for the preference), so no need to call ->store when >++preferences are initialized via this method. >++ >++Stores default messaging preference for C<categorycode> to patron for given >++C<message_attribute_id>. >++ >++Throws Koha::Exceptions::MissingParameter if any of following is missing: >++- borrowernumber >++- message_attribute_id >++ >++Throws Koha::Exceptions::ObjectNotFound if default preferences are not found. >++ >++=cut >++ >++sub new_from_default { >++ my ($class, $params) = @_; >++ >++ my @required = qw(borrowernumber message_attribute_id); >++ foreach my $p (@required) { >++ Koha::Exceptions::MissingParameter->throw( >++ error => 'Missing required parameter.', >++ parameter => $p, >++ ) unless exists $params->{$p}; >++ } >++ unless ($params->{'categorycode'}) { >++ my $patron = Koha::Patrons->find($params->{borrowernumber}); >++ $params->{'categorycode'} = $patron->categorycode; >++ } >++ >++ my $default = Koha::Patron::Message::Preferences->find({ >++ categorycode => $params->{'categorycode'}, >++ message_attribute_id => $params->{'message_attribute_id'}, >++ }); >++ Koha::Exceptions::ObjectNotFound->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 message_name >++ >++$preference->message_name >++ >++Gets message_name for this messaging preference. >++ >++Setter not implemented. >++ >++=cut >++ >++sub message_name { >++ my ($self) = @_; >++ >++ if ($self->{'_message_name'}) { >++ return $self->{'_message_name'}; >++ } >++ $self->{'_message_name'} = Koha::Patron::Message::Attributes->find({ >++ message_attribute_id => $self->message_attribute_id, >++ })->message_name; >++ return $self->{'_message_name'}; >++} >++ >++=head3 message_transport_types >++ >++$preference->message_transport_types >++Returns a HASHREF of message transport types for this messaging preference, e.g. >++if ($preference->message_transport_types->{'email'}) { >++ # email is one of the transport preferences >++} >++ >++$preference->message_transport_types('email', 'sms'); >++Sets the given message transport types for this messaging preference >++ >++=cut >++ >++sub message_transport_types { >++ my $self = shift; >++ >++ unless (@_) { >++ if ($self->{'_message_transport_types'}) { >++ return $self->{'_message_transport_types'}; >++ } >++ map { >++ my $transport = Koha::Patron::Message::Transports->find({ >++ message_attribute_id => $self->message_attribute_id, >++ message_transport_type => $_->message_transport_type, >++ is_digest => $self->wants_digest >++ }); >++ unless ($transport) { >++ my $logger = Koha::Logger->get; >++ $logger->warn( >++ $self->message_name . ' has no transport with '. >++ $_->message_transport_type . ' (digest: '. >++ ($self->wants_digest ? 'yes':'no').').' >++ ); >++ } >++ $self->{'_message_transport_types'}->{$_->message_transport_type} >++ = $transport ? $transport->letter_code : ' '; >++ } >++ Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $self->borrower_message_preference_id, >++ })->as_list; >++ return $self->{'_message_transport_types'} || {}; >++ } >++ else { >++ $self->_set_message_transport_types(@_); >++ return $self; >++ } >++} >++ >++=head3 set >++ >++$preference->set({ >++ message_transport_types => ['sms', 'phone'], >++ wants_digest => 0, >++})->store; >++ >++Sets preference object values and additionally message_transport_types if given. >++ >++=cut >++ >++sub set { >++ my ($self, $params) = @_; >++ >++ my $mtt = $params->{'message_transport_types'}; >++ delete $params->{'message_transport_types'}; >++ >++ $self->SUPER::set($params) if $params; >++ if ($mtt) { >++ $self->message_transport_types($mtt); >++ } >++ >++ return $self; >++} >++ >++=head3 store >++ >++Makes a validation before actual Koha::Object->store so that proper exceptions >++can be thrown. See C<validate()> for documentation about exceptions. >++ >++=cut >++ >++sub store { >++ my $self = shift; >++ >++ $self->validate->SUPER::store(@_); >++ >++ # store message transport types >++ if (exists $self->{'_message_transport_types'}) { >++ Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => >++ $self->borrower_message_preference_id, >++ })->delete; >++ foreach my $type (keys %{$self->{'_message_transport_types'}}) { >++ Koha::Patron::Message::Transport::Preference->new({ >++ borrower_message_preference_id => >++ $self->borrower_message_preference_id, >++ message_transport_type => $type, >++ })->store; >++ } >++ } >++ >++ return $self; >++} >++ >++=head3 validate >++ >++Makes a basic validation for object. >++ >++Throws following exceptions regarding parameters. >++- Koha::Exceptions::MissingParameter >++- Koha::Exceptions::TooManyParameters >++- Koha::Exceptions::BadParameter >++ >++See $_->parameter to identify the parameter causing the exception. >++ >++Throws Koha::Exceptions::DuplicateObject if this preference already exists. >++ >++Returns Koha::Patron::Message::Preference object. >++ >++=cut >++ >++sub validate { >++ my ($self) = @_; >++ >++ if ($self->borrowernumber && $self->categorycode) { >++ Koha::Exceptions::TooManyParameters->throw( >++ error => 'Both borrowernumber and category given, only one accepted', >++ parameter => ['borrowernumber', 'categorycode'], >++ ); >++ } >++ if (!$self->borrowernumber && !$self->categorycode) { >++ Koha::Exceptions::MissingParameter->throw( >++ error => 'borrowernumber or category required, none given', >++ parameter => ['borrowernumber', 'categorycode'], >++ ); >++ } >++ if ($self->borrowernumber) { >++ Koha::Exceptions::BadParameter->throw( >++ error => 'Patron not found.', >++ parameter => 'borrowernumber', >++ ) unless Koha::Patrons->find($self->borrowernumber); >++ } >++ if ($self->categorycode) { >++ Koha::Exceptions::BadParameter->throw( >++ error => 'Category not found.', >++ parameter => 'categorycode', >++ ) unless Koha::Patron::Categories->find($self->categorycode); >++ } >++ >++ if (!$self->in_storage) { >++ my $previous = Koha::Patron::Message::Preferences->search({ >++ borrowernumber => $self->borrowernumber, >++ categorycode => $self->categorycode, >++ message_attribute_id => $self->message_attribute_id, >++ }); >++ if ($previous->count) { >++ Koha::Exceptions::DuplicateObject->throw( >++ error => 'A preference for this borrower/category and' >++ .' message_attribute_id already exists', >++ ); >++ } >++ } >++ >++ my $attr = Koha::Patron::Message::Attributes->find( >++ $self->message_attribute_id >++ ); >++ unless ($attr) { >++ Koha::Exceptions::BadParameter->throw( >++ error => 'Message attribute with id '.$self->message_attribute_id >++ .' not found', >++ parameter => 'message_attribute_id' >++ ); >++ } >++ if (defined $self->days_in_advance) { >++ if ($attr && $attr->takes_days == 0) { >++ Koha::Exceptions::BadParameter->throw( >++ error => 'days_in_advance cannot be defined for '. >++ $attr->message_name . '.', >++ parameter => 'days_in_advance', >++ ); >++ } >++ elsif ($self->days_in_advance < 0 || $self->days_in_advance > 30) { >++ Koha::Exceptions::BadParameter->throw( >++ error => 'days_in_advance has to be a value between 0-30 for '. >++ $attr->message_name . '.', >++ parameter => 'days_in_advance', >++ ); >++ } >++ } >++ if (defined $self->wants_digest) { >++ my $transports = Koha::Patron::Message::Transports->search({ >++ message_attribute_id => $self->message_attribute_id, >++ is_digest => $self->wants_digest ? 1 : 0, >++ }); >++ Koha::Exceptions::BadParameter->throw( >++ error => (!$self->wants_digest ? 'Digest must be selected' >++ : 'Digest cannot be selected') >++ . ' for '.$attr->message_name.'.', >++ parameter => 'wants_digest', >++ ) if $transports->count == 0; >++ } >++ >++ return $self; >++} >++ >++sub _set_message_transport_types { >++ my $self = shift; >++ >++ return unless $_[0]; >++ >++ $self->{'_message_transport_types'} = undef; >++ my $types = ref $_[0] eq "ARRAY" ? $_[0] : [@_]; >++ return unless $types; >++ $self->_validate_message_transport_types({ message_transport_types => $types }); >++ foreach my $type (@$types) { >++ unless (exists $self->{'_message_transport_types'}->{$type}) { >++ my $transport = Koha::Patron::Message::Transports->find({ >++ message_attribute_id => $self->message_attribute_id, >++ message_transport_type => $type >++ }); >++ unless ($transport) { >++ Koha::Exceptions::BadParameter->throw( >++ error => 'No transport configured for '.$self->message_name. >++ " transport type $type.", >++ parameter => 'message_transport_types' >++ ); >++ } >++ $self->{'_message_transport_types'}->{$type} >++ = $transport->letter_code; >++ } >++ } >++ return $self; >++} >++ >++sub _validate_message_transport_types { >++ my ($self, $params) = @_; >++ >++ if (ref($params) eq 'HASH' && $params->{'message_transport_types'}) { >++ if (ref($params->{'message_transport_types'}) ne 'ARRAY') { >++ $params->{'message_transport_types'} = [$params->{'message_transport_types'}]; >++ } >++ my $types = $params->{'message_transport_types'}; >++ >++ foreach my $type (@{$types}) { >++ unless (Koha::Patron::Message::Transport::Types->find({ >++ message_transport_type => $type >++ })) { >++ Koha::Exceptions::BadParameter->throw( >++ error => "Message transport type '$type' does not exist", >++ parameter => 'message_transport_types', >++ ); >++ } >++ } >++ return $types; >++ } >++} >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'BorrowerMessagePreference'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/Koha/Patron/Message/Preferences.pm b/Koha/Patron/Message/Preferences.pm >+new file mode 100644 >+index 0000000..fa8e974 >+--- /dev/null >++++ b/Koha/Patron/Message/Preferences.pm >+@@ -0,0 +1,146 @@ >++package Koha::Patron::Message::Preferences; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version. >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++use Koha::Patron::Message::Attributes; >++use Koha::Patron::Message::Preference; >++use Koha::Patron::Message::Transports; >++ >++use base qw(Koha::Objects); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Preferences - Koha Patron Message Preferences object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 find_with_message_name >++ >++Koha::Patron::Message::Preferences->find_with_message_name({ >++ borrowernumber => 123, >++ message_name => 'Hold_Filled', >++}); >++ >++Converts C<message_name> into C<message_attribute_id> and continues find. >++ >++=cut >++ >++sub find_with_message_name { >++ my ($self, $id) = @_; >++ >++ if (ref($id) eq "HASH" && $id->{'message_name'}) { >++ my $attr = Koha::Patron::Message::Attributes->find({ >++ message_name => $id->{'message_name'}, >++ }); >++ $id->{'message_attribute_id'} = ($attr) ? >++ $attr->message_attribute_id : undef; >++ delete $id->{'message_name'}; >++ } >++ >++ return $self->SUPER::find($id); >++} >++ >++=head3 get_options >++ >++my $messaging_options = Koha::Patron::Message::Preferences->get_options >++ >++Returns an ARRAYref of HASHrefs on available messaging options. >++ >++=cut >++ >++sub get_options { >++ my ($self) = @_; >++ >++ my $transports = Koha::Patron::Message::Transports->search(undef, >++ { >++ join => ['message_attribute'], >++ '+select' => ['message_attribute.message_name', 'message_attribute.takes_days'], >++ '+as' => ['message_name', 'takes_days'], >++ }); >++ >++ my $choices; >++ while (my $transport = $transports->next) { >++ my $name = $transport->get_column('message_name'); >++ $choices->{$name}->{'message_attribute_id'} = $transport->message_attribute_id; >++ $choices->{$name}->{'message_name'} = $name; >++ $choices->{$name}->{'takes_days'} = $transport->get_column('takes_days'); >++ $choices->{$name}->{'has_digest'} ||= 1 if $transport->is_digest; >++ $choices->{$name}->{'has_digest_off'} ||= 1 if !$transport->is_digest; >++ $choices->{$name}->{'transport_'.$transport->get_column('message_transport_type')} = ' '; >++ } >++ >++ my @return = values %$choices; >++ @return = sort { $a->{message_attribute_id} <=> $b->{message_attribute_id} } @return; >++ >++ return \@return; >++} >++ >++=head3 search_with_message_name >++ >++Koha::Patron::Message::Preferences->search_with_message_name({ >++ borrowernumber => 123, >++ message_name => 'Hold_Filled', >++}); >++ >++Converts C<message_name> into C<message_attribute_id> and continues search. Use >++Koha::Patron::Message::Preferences->search with a proper join for more complicated >++searches. >++ >++=cut >++ >++sub search_with_message_name { >++ my ($self, $params, $attributes) = @_; >++ >++ if (ref($params) eq "HASH" && $params->{'message_name'}) { >++ my $attr = Koha::Patron::Message::Attributes->find({ >++ message_name => $params->{'message_name'}, >++ }); >++ $params->{'message_attribute_id'} = ($attr) ? >++ $attr->message_attribute_id : undef; >++ delete $params->{'message_name'}; >++ } >++ >++ return $self->SUPER::search($params, $attributes); >++} >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'BorrowerMessagePreference'; >++} >++ >++sub object_class { >++ return 'Koha::Patron::Message::Preference'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/Koha/Patron/Message/Transport.pm b/Koha/Patron/Message/Transport.pm >+new file mode 100644 >+index 0000000..ca0906e >+--- /dev/null >++++ b/Koha/Patron/Message/Transport.pm >+@@ -0,0 +1,50 @@ >++package Koha::Patron::Message::Transport; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version.a >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++ >++use base qw(Koha::Object); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Transport - Koha Patron Message Transport object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'MessageTransport'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/Koha/Patron/Message/Transport/Preference.pm b/Koha/Patron/Message/Transport/Preference.pm >+new file mode 100644 >+index 0000000..fe0ddeb >+--- /dev/null >++++ b/Koha/Patron/Message/Transport/Preference.pm >+@@ -0,0 +1,51 @@ >++package Koha::Patron::Message::Transport::Preference; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version.a >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++ >++use base qw(Koha::Object); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Transport::Preference - Koha Patron Message Transport >++Preference object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'BorrowerMessageTransportPreference'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/Koha/Patron/Message/Transport/Preferences.pm b/Koha/Patron/Message/Transport/Preferences.pm >+new file mode 100644 >+index 0000000..aabd851 >+--- /dev/null >++++ b/Koha/Patron/Message/Transport/Preferences.pm >+@@ -0,0 +1,56 @@ >++package Koha::Patron::Message::Transport::Preferences; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version. >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++use Koha::Patron::Message::Transport::Preference; >++ >++use base qw(Koha::Objects); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Transport::Preferences - Koha Patron Message Transport >++Preferences object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'BorrowerMessageTransportPreference'; >++} >++ >++sub object_class { >++ return 'Koha::Patron::Message::Transport::Preference'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/Koha/Patron/Message/Transport/Type.pm b/Koha/Patron/Message/Transport/Type.pm >+new file mode 100644 >+index 0000000..4a52a10 >+--- /dev/null >++++ b/Koha/Patron/Message/Transport/Type.pm >+@@ -0,0 +1,51 @@ >++package Koha::Patron::Message::Transport::Type; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version.a >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++ >++use base qw(Koha::Object); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Transport::Type - Koha Patron Message Transport Type >++object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'MessageTransportType'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/Koha/Patron/Message/Transport/Types.pm b/Koha/Patron/Message/Transport/Types.pm >+new file mode 100644 >+index 0000000..2633ea3 >+--- /dev/null >++++ b/Koha/Patron/Message/Transport/Types.pm >+@@ -0,0 +1,56 @@ >++package Koha::Patron::Message::Transport::Types; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version. >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++use Koha::Patron::Message::Transport::Type; >++ >++use base qw(Koha::Objects); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Transport::Types - Koha Patron Message Transport Types >++object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'MessageTransportType'; >++} >++ >++sub object_class { >++ return 'Koha::Patron::Message::Transport::Type'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/Koha/Patron/Message/Transports.pm b/Koha/Patron/Message/Transports.pm >+new file mode 100644 >+index 0000000..b6aee32 >+--- /dev/null >++++ b/Koha/Patron/Message/Transports.pm >+@@ -0,0 +1,55 @@ >++package Koha::Patron::Message::Transports; >++ >++# Copyright Koha-Suomi Oy 2016 >++# >++# This file is part of Koha. >++# >++# Koha is free software; you can redistribute it and/or modify it under the >++# terms of the GNU General Public License as published by the Free Software >++# Foundation; either version 3 of the License, or (at your option) any later >++# version. >++# >++# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >++# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >++# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License along >++# with Koha; if not, write to the Free Software Foundation, Inc., >++# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >++ >++use Modern::Perl; >++ >++use Koha::Database; >++use Koha::Patron::Message::Transport; >++ >++use base qw(Koha::Objects); >++ >++=head1 NAME >++ >++Koha::Patron::Message::Transports - Koha Patron Message Transports object class >++ >++=head1 API >++ >++=head2 Class Methods >++ >++=cut >++ >++=head3 type >++ >++=cut >++ >++sub _type { >++ return 'MessageTransport'; >++} >++ >++sub object_class { >++ return 'Koha::Patron::Message::Transport'; >++} >++ >++=head1 AUTHOR >++ >++Lari Taskula <lari.taskula@jns.fi> >++ >++=cut >++ >++1; >+diff --git a/t/db_dependent/Koha/Patron/Message/Attributes.t b/t/db_dependent/Koha/Patron/Message/Attributes.t >+new file mode 100644 >+index 0000000..836b4f0 >+--- /dev/null >++++ b/t/db_dependent/Koha/Patron/Message/Attributes.t >+@@ -0,0 +1,74 @@ >++#!/usr/bin/perl >++ >++# Copyright 2017 Koha-Suomi Oy >++# >++# This file is part of Koha >++# >++# Koha is free software; you can redistribute it and/or modify it >++# under the terms of the GNU General Public License as published by >++# the Free Software Foundation; either version 3 of the License, or >++# (at your option) any later version. >++# >++# Koha is distributed in the hope that it will be useful, but >++# WITHOUT ANY WARRANTY; without even the implied warranty of >++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >++# GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License >++# along with Koha; if not, see <http://www.gnu.org/licenses>. >++ >++use Modern::Perl; >++ >++use Test::More tests => 2; >++ >++use Koha::Database; >++ >++my $schema = Koha::Database->new->schema; >++ >++subtest 'Test class imports' => sub { >++ plan tests => 2; >++ >++ use_ok('Koha::Patron::Message::Attribute'); >++ use_ok('Koha::Patron::Message::Attributes'); >++}; >++ >++subtest 'Test Koha::Patron::Message::Attributes' => sub { >++ plan tests => 6; >++ >++ $schema->storage->txn_begin; >++ >++ Koha::Patron::Message::Attribute->new({ >++ message_name => 'Test_Attribute' >++ })->store; >++ Koha::Patron::Message::Attribute->new({ >++ message_name => 'Test_Attribute2', >++ takes_days => 1 >++ })->store; >++ >++ my $attribute = Koha::Patron::Message::Attributes->find({ >++ message_name => 'Test_Attribute' }); >++ my $attribute2 = Koha::Patron::Message::Attributes->find({ >++ message_name => 'Test_Attribute2' }); >++ >++ is($attribute->message_name, 'Test_Attribute', >++ 'Added a new messaging attribute.'); >++ is($attribute->takes_days, 0, >++ 'For that messaging attribute, takes_days is disabled by default.'); >++ is($attribute2->message_name, 'Test_Attribute2', >++ 'Added another messaging attribute.'); >++ is($attribute2->takes_days, 1, >++ 'takes_days is enabled for that message attribute (as expected).'); >++ >++ $attribute->delete; >++ $attribute2->delete; >++ is(Koha::Patron::Message::Attributes->find({ >++ message_name => 'Test_Attribute' }), undef, >++ 'Deleted the first message attribute.'); >++ is(Koha::Patron::Message::Attributes->find({ >++ message_name => 'Test_Attribute2' }), undef, >++ 'Deleted the second message attribute.'); >++ >++ $schema->storage->txn_rollback; >++}; >++ >++1; >+diff --git a/t/db_dependent/Koha/Patron/Message/Preferences.t b/t/db_dependent/Koha/Patron/Message/Preferences.t >+new file mode 100644 >+index 0000000..bd88c63 >+--- /dev/null >++++ b/t/db_dependent/Koha/Patron/Message/Preferences.t >+@@ -0,0 +1,719 @@ >++#!/usr/bin/perl >++ >++# Copyright 2017 Koha-Suomi Oy >++# >++# This file is part of Koha >++# >++# Koha is free software; you can redistribute it and/or modify it >++# under the terms of the GNU General Public License as published by >++# the Free Software Foundation; either version 3 of the License, or >++# (at your option) any later version. >++# >++# Koha is distributed in the hope that it will be useful, but >++# WITHOUT ANY WARRANTY; without even the implied warranty of >++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >++# GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License >++# along with Koha; if not, see <http://www.gnu.org/licenses>. >++ >++use Modern::Perl; >++ >++use Test::More tests => 7; >++ >++use t::lib::Mocks; >++use t::lib::TestBuilder; >++ >++use C4::Context; >++ >++use Koha::Notice::Templates; >++use Koha::Patron::Categories; >++use Koha::Patron::Message::Attributes; >++use Koha::Patron::Message::Transport::Types; >++use Koha::Patron::Message::Transports; >++use Koha::Patrons; >++ >++use File::Temp qw/tempfile/; >++use Log::Log4perl; >++ >++my $schema = Koha::Database->new->schema; >++my $builder = t::lib::TestBuilder->new; >++ >++subtest 'Test class imports' => sub { >++ plan tests => 2; >++ >++ use_ok('Koha::Patron::Message::Preference'); >++ use_ok('Koha::Patron::Message::Preferences'); >++}; >++ >++subtest 'Test Koha::Patron::Message::Preferences' => sub { >++ plan tests => 2; >++ >++ $schema->storage->txn_begin; >++ >++ my $attribute = build_a_test_attribute(); >++ my $letter = build_a_test_letter(); >++ my $mtt = build_a_test_transport_type(); >++ Koha::Patron::Message::Transport->new({ >++ message_attribute_id => $attribute->message_attribute_id, >++ message_transport_type => $mtt->message_transport_type, >++ is_digest => 0, >++ letter_module => $letter->module, >++ letter_code => $letter->code, >++ })->store; >++ >++ subtest 'Test for a patron' => sub { >++ plan tests => 3; >++ >++ my $patron = build_a_test_patron(); >++ Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ wants_digest => 0, >++ days_in_advance => undef, >++ })->store; >++ >++ my $preference = Koha::Patron::Message::Preferences->find({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id >++ }); >++ ok($preference->borrower_message_preference_id > 0, >++ 'Added a new messaging preference for patron.'); >++ >++ subtest 'Test set not throwing an exception on duplicate object' => sub { >++ plan tests => 1; >++ >++ Koha::Patron::Message::Attributes->find({ >++ message_attribute_id => $attribute->message_attribute_id >++ })->set({ takes_days => 1 })->store; >++ $preference->set({ days_in_advance => 1 })->store; >++ is(ref($preference), 'Koha::Patron::Message::Preference', >++ 'Updating the preference does not cause duplicate object exception'); >++ }; >++ >++ $preference->delete; >++ is(Koha::Patron::Message::Preferences->search({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id >++ })->count, 0, 'Deleted the messaging preference.'); >++ }; >++ >++ subtest 'Test for a category' => sub { >++ my $category = build_a_test_category(); >++ Koha::Patron::Message::Preference->new({ >++ categorycode => $category->categorycode, >++ message_attribute_id => $attribute->message_attribute_id, >++ wants_digest => 0, >++ days_in_advance => undef, >++ })->store; >++ >++ my $preference = Koha::Patron::Message::Preferences->find({ >++ categorycode => $category->categorycode, >++ message_attribute_id => $attribute->message_attribute_id >++ }); >++ ok($preference->borrower_message_preference_id > 0, >++ 'Added a new messaging preference for category.'); >++ >++ $preference->delete; >++ is(Koha::Patron::Message::Preferences->search({ >++ categorycode => $category->categorycode, >++ message_attribute_id => $attribute->message_attribute_id >++ })->count, 0, 'Deleted the messaging preference.'); >++ }; >++ >++ $schema->storage->txn_rollback; >++}; >++ >++subtest 'Test Koha::Patron::Message::Preferences->get_options' => sub { >++ plan tests => 2; >++ >++ subtest 'Test method availability and return value' => sub { >++ plan tests => 3; >++ >++ ok(Koha::Patron::Message::Preferences->can('get_options'), >++ 'Method get_options is available.'); >++ ok(my $options = Koha::Patron::Message::Preferences->get_options, >++ 'Called get_options successfully.'); >++ is(ref($options), 'ARRAY', 'get_options returns a ARRAYref'); >++ }; >++ >++ subtest 'Make sure options are correct' => sub { >++ $schema->storage->txn_begin; >++ my $options = Koha::Patron::Message::Preferences->get_options; >++ >++ foreach my $option (@$options) { >++ my $n = $option->{'message_name'}; >++ my $attr = Koha::Patron::Message::Attributes->find($option->{'message_attribute_id'}); >++ is($option->{'message_attribute_id'}, $attr->message_attribute_id, >++ '$n: message_attribute_id is set'); >++ is($option->{'message_name'}, $attr->message_name, '$n: message_name is set'); >++ is($option->{'takes_days'}, $attr->takes_days, '$n: takes_days is set'); >++ my $transports = Koha::Patron::Message::Transports->search({ >++ message_attribute_id => $option->{'message_attribute_id'}, >++ is_digest => $option->{'has_digest'} || 0, >++ }); >++ while (my $trnzport = $transports->next) { >++ is($option->{'has_digest'} || 0, $trnzport->is_digest, '$n: has_digest is set for '.$trnzport->message_transport_type); >++ is($option->{'transport_'.$trnzport->message_transport_type}, ' ', '$n: transport_'.$trnzport->message_transport_type.' is set'); >++ } >++ } >++ >++ $schema->storage->txn_rollback; >++ }; >++}; >++ >++subtest 'Add preferences from defaults' => sub { >++ plan tests => 3; >++ >++ $schema->storage->txn_begin; >++ >++ my $patron = build_a_test_patron(); >++ my ($default, $mtt1, $mtt2) = build_a_test_category_preference({ >++ patron => $patron, >++ }); >++ ok(Koha::Patron::Message::Preference->new_from_default({ >++ borrowernumber => $patron->borrowernumber, >++ categorycode => $patron->categorycode, >++ message_attribute_id => $default->message_attribute_id, >++ })->store, 'Added a default preference to patron.'); >++ ok(my $pref = Koha::Patron::Message::Preferences->find({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $default->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'); >++ >++ $schema->storage->txn_rollback; >++}; >++ >++subtest 'Test Koha::Patron::Message::Preference->message_transport_types' => sub { >++ plan tests => 4; >++ >++ ok(Koha::Patron::Message::Preference->can('message_transport_types'), >++ 'Method message_transport_types available'); >++ >++ subtest 'get message_transport_types' => sub { >++ plan tests => 5; >++ >++ $schema->storage->txn_begin; >++ >++ my $patron = build_a_test_patron(); >++ my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({ >++ patron => $patron >++ }); >++ Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ })->delete; >++ Koha::Patron::Message::Transport::Preference->new({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ message_transport_type => $mtt1->message_transport_type, >++ })->store; >++ Koha::Patron::Message::Transport::Preference->new({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ message_transport_type => $mtt2->message_transport_type, >++ })->store; >++ my $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ }); >++ my $transport1 = Koha::Patron::Message::Transports->find({ >++ message_attribute_id => $preference->message_attribute_id, >++ message_transport_type => $mtt1->message_transport_type, >++ }); >++ my $transport2 = Koha::Patron::Message::Transports->find({ >++ message_attribute_id => $preference->message_attribute_id, >++ message_transport_type => $mtt2->message_transport_type, >++ }); >++ my $transports = $preference->message_transport_types; >++ is(keys %{$transports}, $stored_transports->count, >++ '->message_transport_types gets correct amount of transport types.'); >++ is($transports->{$stored_transports->next->message_transport_type}, >++ $transport1->letter_code, 'Found correct message transport type and letter code.'); >++ is($transports->{$stored_transports->next->message_transport_type}, >++ $transport2->letter_code, 'Found correct message transport type and letter code.'); >++ ok(!$preference->message_transport_types->{'nonexistent'}, >++ 'Didn\'t find nonexistent transport type.'); >++ >++ subtest 'test logging of warnings by invalid message transport type' => sub { >++ plan tests => 2; >++ >++ my $log = mytempfile(); >++ my $conf = mytempfile( <<"HERE" >++log4perl.logger.opac = WARN, OPAC >++log4perl.appender.OPAC=Log::Log4perl::Appender::TestBuffer >++log4perl.appender.OPAC.filename=$log >++log4perl.appender.OPAC.mode=append >++log4perl.appender.OPAC.layout=SimpleLayout >++log4perl.logger.intranet = WARN, INTRANET >++log4perl.appender.INTRANET=Log::Log4perl::Appender::TestBuffer >++log4perl.appender.INTRANET.filename=$log >++log4perl.appender.INTRANET.mode=append >++log4perl.appender.INTRANET.layout=SimpleLayout >++HERE >++ ); >++ t::lib::Mocks::mock_config('log4perl_conf', $conf); >++ my $appenders = Log::Log4perl->appenders; >++ my $appender = Log::Log4perl->appenders->{OPAC}; >++ >++ my $pref = Koha::Patron::Message::Preferences->find( >++ $preference->borrower_message_preference_id >++ ); >++ my $transports = $pref->message_transport_types; >++ is($appender, undef, 'Nothing in buffer yet'); >++ >++ my $mtt_new = build_a_test_transport_type(); >++ Koha::Patron::Message::Transport::Preference->new({ >++ borrower_message_preference_id => >++ $pref->borrower_message_preference_id, >++ message_transport_type => $mtt_new->message_transport_type, >++ })->store; >++ $pref = Koha::Patron::Message::Preferences->find( >++ $pref->borrower_message_preference_id >++ ); >++ $transports = $pref->message_transport_types; >++ $appender = Log::Log4perl->appenders->{OPAC}; >++ my $name = $pref->message_name; >++ my $tt = $mtt_new->message_transport_type; >++ like($appender->buffer, qr/WARN - $name has no transport with $tt/, >++ 'Logged invalid message transport type'); >++ }; >++ >++ $schema->storage->txn_rollback; >++ }; >++ >++ subtest 'set message_transport_types' => sub { >++ plan tests => 6; >++ >++ $schema->storage->txn_begin; >++ >++ my $patron = build_a_test_patron(); >++ my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({ >++ patron => $patron >++ }); >++ >++ my $mtt1_str = $mtt1->message_transport_type; >++ my $mtt2_str = $mtt2->message_transport_type; >++ # 1/3, use message_transport_types(list) >++ Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ })->delete; >++ ok($preference->message_transport_types($mtt1_str, $mtt2_str)->store, >++ '1/3 Set returned true.'); >++ my $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ '-or' => [ >++ message_transport_type => $mtt1_str, >++ message_transport_type => $mtt2_str >++ ] >++ }); >++ is($stored_transports->count, 2, 'Two transports selected'); >++ >++ # 2/3, use message_transport_types(ARRAYREF) >++ Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ })->delete; >++ ok($preference->message_transport_types([$mtt1_str, $mtt2_str])->store, >++ '2/3 Set returned true.'); >++ $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ '-or' => [ >++ message_transport_type => $mtt1_str, >++ message_transport_type => $mtt2_str >++ ] >++ }); >++ is($stored_transports->count, 2, 'Two transports selected'); >++ >++ # 3/3, use set({ message_transport_types => ARRAYREF }) >++ Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ })->delete; >++ ok($preference->set({ >++ message_transport_types => [$mtt1_str, $mtt2_str]})->store, >++ '3/3 Set returned true.'); >++ $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ '-or' => [ >++ message_transport_type => $mtt1_str, >++ message_transport_type => $mtt2_str >++ ] >++ }); >++ is($stored_transports->count, 2, 'Two transports selected'); >++ >++ $schema->storage->txn_rollback; >++ }; >++ >++ subtest 'new message_transport_types' => sub { >++ plan tests => 3; >++ >++ $schema->storage->txn_begin; >++ >++ my $patron = build_a_test_patron(); >++ my $letter = build_a_test_letter(); >++ my $attribute = build_a_test_attribute(); >++ my $mtt = build_a_test_transport_type(); >++ Koha::Patron::Message::Transport->new({ >++ message_attribute_id => $attribute->message_attribute_id, >++ message_transport_type => $mtt->message_transport_type, >++ is_digest => 0, >++ letter_module => $letter->module, >++ letter_code => $letter->code, >++ })->store; >++ ok(my $preference = Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ wants_digest => 0, >++ days_in_advance => undef, >++ message_transport_types => $mtt->message_transport_type, >++ })->store, 'Added a new messaging preference and transport types to patron.'); >++ ok($preference->message_transport_types->{$mtt->message_transport_type}, >++ 'The transport type is stored in the object.'); >++ my $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $preference->borrower_message_preference_id, >++ }); >++ is($stored_transports->next->message_transport_type, $mtt->message_transport_type, >++ 'The transport type is stored in the database.'); >++ >++ $schema->storage->txn_rollback; >++ }; >++}; >++ >++subtest 'Test Koha::Patron::Message::Preference->message_name' => sub { >++ plan tests => 1; >++ >++ $schema->storage->txn_begin; >++ >++ my $patron = build_a_test_patron(); >++ my $attribute = build_a_test_attribute(); >++ my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({ >++ patron => $patron, >++ attr => $attribute, >++ }); >++ my $message_name_pref = Koha::Patron::Message::Preferences->search_with_message_name({ >++ borrowernumber => $patron->{'borrowernumber'}, >++ message_name => $attribute->message_name, >++ })->next; >++ is($message_name_pref->message_name, $attribute->message_name, "Found preference with message_name"); >++ >++ $schema->storage->txn_rollback; >++}; >++ >++subtest 'Test adding a new preference with invalid parameters' => sub { >++ plan tests => 4; >++ >++ subtest 'Missing parameters' => sub { >++ plan tests => 1; >++ >++ eval { Koha::Patron::Message::Preference->new->store }; >++ is(ref $@, 'Koha::Exceptions::MissingParameter', >++ 'Adding a message preference without parameters' >++ .' => Koha::Exceptions::MissingParameter'); >++ }; >++ >++ subtest 'Too many parameters' => sub { >++ plan tests => 1; >++ >++ $schema->storage->txn_begin; >++ >++ my $patron = build_a_test_patron(); >++ eval { Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ categorycode => $patron->categorycode, >++ })->store }; >++ is(ref $@, 'Koha::Exceptions::TooManyParameters', >++ 'Adding a message preference for both borrowernumber and categorycode' >++ .' => Koha::Exceptions::TooManyParameters'); >++ >++ $schema->storage->txn_rollback; >++ }; >++ >++ subtest 'Bad parameter' => sub { >++ plan tests => 22; >++ >++ $schema->storage->txn_begin; >++ >++ eval { Koha::Patron::Message::Preference->new({ >++ borrowernumber => -999, >++ })->store }; >++ is(ref $@, 'Koha::Exceptions::BadParameter', >++ 'Adding a message preference with invalid borrowernumber' >++ .' => Koha::Exceptions::BadParameter'); >++ is ($@->parameter, 'borrowernumber', 'The previous exception tells us it' >++ .' was the borrowernumber.'); >++ >++ eval { Koha::Patron::Message::Preference->new({ >++ categorycode => 'nonexistent', >++ })->store }; >++ is(ref $@, 'Koha::Exceptions::BadParameter', >++ 'Adding a message preference with invalid categorycode' >++ .' => Koha::Exceptions::BadParameter'); >++ is($@->parameter, 'categorycode', 'The previous exception tells us it' >++ .' was the categorycode.'); >++ >++ my $attribute = build_a_test_attribute({ takes_days => 0 }); >++ my $patron = build_a_test_patron(); >++ eval { Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ days_in_advance => 10, >++ })->store }; >++ is(ref $@, 'Koha::Exceptions::BadParameter', >++ 'Adding a message preference with days in advance option when not' >++ .' available => Koha::Exceptions::BadParameter'); >++ is($@->parameter, 'days_in_advance', 'The previous exception tells us it' >++ .' was the days_in_advance.'); >++ >++ $attribute->set({ takes_days => 1 })->store; >++ eval { Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ days_in_advance => 31, >++ })->store }; >++ is(ref $@, 'Koha::Exceptions::BadParameter', >++ 'Adding a message preference with days in advance option too large' >++ .' => Koha::Exceptions::BadParameter'); >++ is($@->parameter, 'days_in_advance', 'The previous exception tells us it' >++ .' was the days_in_advance.'); >++ >++ eval { Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_transport_types => ['nonexistent'] >++ })->store }; >++ is (ref $@, 'Koha::Exceptions::BadParameter', >++ 'Adding a message preference with invalid message_transport_type' >++ .' => Koha::Exceptions::BadParameter'); >++ is ($@->parameter, 'message_transport_types', 'The previous exception ' >++ .'tells us it was the message_transport_types.'); >++ >++ my $mtt_new = build_a_test_transport_type(); >++ eval { >++ Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ message_transport_types => [$mtt_new->message_transport_type], >++ wants_digest => 1, >++ })->store }; >++ is (ref $@, 'Koha::Exceptions::BadParameter', >++ 'Adding a message preference with invalid message_transport_type' >++ .' => Koha::Exceptions::BadParameter'); >++ is ($@->parameter, 'message_transport_types', 'The previous exception ' >++ .'tells us it was the message_transport_types.'); >++ like ($@->error, qr/^No transport configured/, 'Exception is because of ' >++ .'given message_transport_type is not a valid option.'); >++ >++ eval { >++ Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ message_transport_types => [], >++ wants_digest => 1, >++ })->store }; >++ is (ref $@, 'Koha::Exceptions::BadParameter', >++ 'Adding a message preference with invalid message_transport_type' >++ .' => Koha::Exceptions::BadParameter'); >++ is ($@->parameter, 'wants_digest', 'The previous exception tells us it' >++ .' was the wants_digest'); >++ like ($@->error, qr/^Digest cannot be selected/, 'Exception s because of' >++ .' given digest is not available for this transport.'); >++ >++ eval { >++ Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ message_transport_types => [], >++ wants_digest => 0, >++ })->store }; >++ is (ref $@, 'Koha::Exceptions::BadParameter', >++ 'Adding a message preference with invalid message_transport_type' >++ .' => Koha::Exceptions::BadParameter'); >++ is ($@->parameter, 'wants_digest', 'The previous exception tells us it' >++ .' was the wants_digest'); >++ like ($@->error, qr/^Digest must be selected/, 'Exception s because of' >++ .' digest has to be on for this transport.'); >++ >++ eval { >++ Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => -1, >++ message_transport_types => [], >++ })->store }; >++ is (ref $@, 'Koha::Exceptions::BadParameter', >++ 'Adding a message preference with invalid message_transport_type' >++ .' => Koha::Exceptions::BadParameter'); >++ is ($@->parameter, 'message_attribute_id', 'The previous exception tells' >++ .' us it was the message_attribute_id'); >++ like ($@->error, qr/^Message attribute with id -1 not found/, 'Exception ' >++ .' is because of given message attribute id is not found.'); >++ >++ $schema->storage->txn_rollback; >++ }; >++ >++ subtest 'Duplicate object' => sub { >++ plan tests => 2; >++ >++ $schema->storage->txn_begin; >++ >++ my $attribute = build_a_test_attribute(); >++ my $letter = build_a_test_letter(); >++ my $mtt = build_a_test_transport_type(); >++ Koha::Patron::Message::Transport->new({ >++ message_attribute_id => $attribute->message_attribute_id, >++ message_transport_type => $mtt->message_transport_type, >++ is_digest => 0, >++ letter_module => $letter->module, >++ letter_code => $letter->code, >++ })->store; >++ my $patron = build_a_test_patron(); >++ my $preference = Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ wants_digest => 0, >++ days_in_advance => undef, >++ })->store; >++ ok($preference->borrower_message_preference_id, >++ 'Added a new messaging preference for patron.'); >++ eval { Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ wants_digest => 0, >++ days_in_advance => undef, >++ })->store }; >++ is(ref $@, 'Koha::Exceptions::DuplicateObject', >++ 'Adding a duplicate preference' >++ .' => Koha::Exceptions::DuplicateObject'); >++ >++ $schema->storage->txn_rollback; >++ }; >++}; >++ >++sub build_a_test_attribute { >++ my ($params) = @_; >++ >++ $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0 >++ ? 1 : 0; >++ >++ my $attribute = $builder->build({ >++ source => 'MessageAttribute', >++ value => $params, >++ }); >++ >++ return Koha::Patron::Message::Attributes->find( >++ $attribute->{message_attribute_id} >++ ); >++} >++ >++sub build_a_test_category { >++ my $categorycode = $builder->build({ >++ source => 'Category' })->{categorycode}; >++ >++ return Koha::Patron::Categories->find($categorycode); >++} >++ >++sub build_a_test_letter { >++ my ($params) = @_; >++ >++ my $mtt = $params->{mtt} ? $params->{mtt} : 'email'; >++ my $branchcode = $builder->build({ >++ source => 'Branch' })->{branchcode}; >++ my $letter = $builder->build({ >++ source => 'Letter', >++ value => { >++ branchcode => '', >++ is_html => 0, >++ message_transport_type => $mtt >++ } >++ }); >++ >++ return Koha::Notice::Templates->find({ >++ module => $letter->{module}, >++ code => $letter->{code}, >++ branchcode => $letter->{branchcode}, >++ }); >++} >++ >++sub build_a_test_patron { >++ my $categorycode = $builder->build({ >++ source => 'Category' })->{categorycode}; >++ my $branchcode = $builder->build({ >++ source => 'Branch' })->{branchcode}; >++ my $borrowernumber = $builder->build({ >++ source => 'Borrower' })->{borrowernumber}; >++ >++ return Koha::Patrons->find($borrowernumber); >++} >++ >++sub build_a_test_transport_type { >++ my $mtt = $builder->build({ >++ source => 'MessageTransportType' }); >++ >++ return Koha::Patron::Message::Transport::Types->find( >++ $mtt->{message_transport_type} >++ ); >++} >++ >++sub build_a_test_category_preference { >++ my ($params) = @_; >++ >++ my $patron = $params->{patron}; >++ my $attr = $params->{attr} >++ ? $params->{attr} >++ : build_a_test_attribute($params->{days_in_advance}); >++ >++ my $letter = $params->{letter} ? $params->{letter} : build_a_test_letter(); >++ my $mtt1 = $params->{mtt1} ? $params->{mtt1} : build_a_test_transport_type(); >++ my $mtt2 = $params->{mtt2} ? $params->{mtt2} : build_a_test_transport_type(); >++ >++ Koha::Patron::Message::Transport->new({ >++ message_attribute_id => $attr->message_attribute_id, >++ message_transport_type => $mtt1->message_transport_type, >++ is_digest => $params->{digest} ? 1 : 0, >++ letter_module => $letter->module, >++ letter_code => $letter->code, >++ })->store; >++ >++ Koha::Patron::Message::Transport->new({ >++ message_attribute_id => $attr->message_attribute_id, >++ message_transport_type => $mtt2->message_transport_type, >++ is_digest => $params->{digest} ? 1 : 0, >++ letter_module => $letter->module, >++ letter_code => $letter->code, >++ })->store; >++ >++ my $default = Koha::Patron::Message::Preference->new({ >++ categorycode => $patron->categorycode, >++ message_attribute_id => $attr->message_attribute_id, >++ wants_digest => $params->{digest} ? 1 : 0, >++ days_in_advance => $params->{days_in_advance} >++ ? $params->{days_in_advance} : undef, >++ })->store; >++ >++ Koha::Patron::Message::Transport::Preference->new({ >++ borrower_message_preference_id => $default->borrower_message_preference_id, >++ message_transport_type => $mtt1->message_transport_type, >++ })->store; >++ Koha::Patron::Message::Transport::Preference->new({ >++ borrower_message_preference_id => $default->borrower_message_preference_id, >++ message_transport_type => $mtt2->message_transport_type, >++ })->store; >++ >++ return ($default, $mtt1, $mtt2); >++} >++ >++sub build_a_test_complete_preference { >++ my ($params) = @_; >++ >++ my ($default, $mtt1, $mtt2) = build_a_test_category_preference($params); >++ my $patron = $params->{patron}; >++ $patron->set_default_messaging_preferences; >++ return (Koha::Patron::Message::Preferences->search({ >++ borrowernumber => $patron->borrowernumber >++ })->next, $mtt1, $mtt2); >++} >++ >++sub mytempfile { >++ my ( $fh, $fn ) = tempfile( SUFFIX => '.logger.test', UNLINK => 1 ); >++ print $fh $_[0]//''; >++ close $fh; >++ return $fn; >++} >++ >++1; >+diff --git a/t/db_dependent/Koha/Patron/Message/Transport/Preferences.t b/t/db_dependent/Koha/Patron/Message/Transport/Preferences.t >+new file mode 100644 >+index 0000000..0cdf809 >+--- /dev/null >++++ b/t/db_dependent/Koha/Patron/Message/Transport/Preferences.t >+@@ -0,0 +1,179 @@ >++#!/usr/bin/perl >++ >++# Copyright 2017 Koha-Suomi Oy >++# >++# This file is part of Koha >++# >++# Koha is free software; you can redistribute it and/or modify it >++# under the terms of the GNU General Public License as published by >++# the Free Software Foundation; either version 3 of the License, or >++# (at your option) any later version. >++# >++# Koha is distributed in the hope that it will be useful, but >++# WITHOUT ANY WARRANTY; without even the implied warranty of >++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >++# GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License >++# along with Koha; if not, see <http://www.gnu.org/licenses>. >++ >++use Modern::Perl; >++ >++use Test::More tests => 2; >++ >++use t::lib::Mocks; >++use t::lib::TestBuilder; >++ >++use Koha::Notice::Templates; >++use Koha::Patron::Categories; >++use Koha::Patron::Message::Attributes; >++use Koha::Patron::Message::Preferences; >++use Koha::Patron::Message::Transport::Types; >++use Koha::Patron::Message::Transports; >++use Koha::Patrons; >++ >++my $schema = Koha::Database->new->schema; >++my $builder = t::lib::TestBuilder->new; >++ >++subtest 'Test class imports' => sub { >++ plan tests => 2; >++ >++ use_ok('Koha::Patron::Message::Transport::Preference'); >++ use_ok('Koha::Patron::Message::Transport::Preferences'); >++}; >++ >++subtest 'Test Koha::Patron::Message::Transport::Preferences' => sub { >++ plan tests => 2; >++ >++ $schema->storage->txn_begin; >++ >++ my $attribute = build_a_test_attribute(); >++ my $mtt = build_a_test_transport_type(); >++ my $letter = build_a_test_letter({ >++ mtt => $mtt->message_transport_type >++ }); >++ Koha::Patron::Message::Transport->new({ >++ message_attribute_id => $attribute->message_attribute_id, >++ message_transport_type => $mtt->message_transport_type, >++ is_digest => 0, >++ letter_module => $letter->module, >++ letter_code => $letter->code, >++ })->store; >++ >++ subtest 'For a patron' => sub { >++ my $patron = build_a_test_patron(); >++ my $preference = Koha::Patron::Message::Preference->new({ >++ borrowernumber => $patron->borrowernumber, >++ message_attribute_id => $attribute->message_attribute_id, >++ wants_digest => 0, >++ days_in_advance => undef, >++ })->store; >++ >++ my $pref_id = $preference->borrower_message_preference_id; >++ my $transport_pref = Koha::Patron::Message::Transport::Preference->new({ >++ borrower_message_preference_id => $pref_id, >++ message_transport_type => $mtt->message_transport_type, >++ })->store; >++ is(ref($transport_pref), 'Koha::Patron::Message::Transport::Preference', >++ 'Added a new messaging transport preference for patron.'); >++ >++ $transport_pref->delete; >++ is(Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $pref_id, >++ message_transport_type => $mtt->message_transport_type, >++ })->count, 0, 'Deleted the messaging transport preference.'); >++ }; >++ >++ subtest 'For a category' => sub { >++ my $category = build_a_test_category(); >++ my $preference = Koha::Patron::Message::Preference->new({ >++ categorycode => $category->categorycode, >++ message_attribute_id => $attribute->message_attribute_id, >++ wants_digest => 0, >++ days_in_advance => undef, >++ })->store; >++ >++ my $pref_id = $preference->borrower_message_preference_id; >++ my $transport_pref = Koha::Patron::Message::Transport::Preference->new({ >++ borrower_message_preference_id => $pref_id, >++ message_transport_type => $mtt->message_transport_type, >++ })->store; >++ is(ref($transport_pref), 'Koha::Patron::Message::Transport::Preference', >++ 'Added a new messaging transport preference for category.'); >++ >++ $transport_pref->delete; >++ is(Koha::Patron::Message::Transport::Preferences->search({ >++ borrower_message_preference_id => $pref_id, >++ message_transport_type => $mtt->message_transport_type, >++ })->count, 0, 'Deleted the messaging transport preference.'); >++ }; >++ >++ $schema->storage->txn_rollback; >++}; >++ >++sub build_a_test_attribute { >++ my ($params) = @_; >++ >++ $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0 >++ ? 1 : 0; >++ >++ my $attribute = $builder->build({ >++ source => 'MessageAttribute', >++ value => $params, >++ }); >++ >++ return Koha::Patron::Message::Attributes->find( >++ $attribute->{message_attribute_id} >++ ); >++} >++ >++sub build_a_test_category { >++ my $categorycode = $builder->build({ >++ source => 'Category' })->{categorycode}; >++ >++ return Koha::Patron::Categories->find($categorycode); >++} >++ >++sub build_a_test_letter { >++ my ($params) = @_; >++ >++ my $mtt = $params->{mtt} ? $params->{mtt} : 'email'; >++ my $branchcode = $builder->build({ >++ source => 'Branch' })->{branchcode}; >++ my $letter = $builder->build({ >++ source => 'Letter', >++ value => { >++ branchcode => '', >++ is_html => 0, >++ message_transport_type => $mtt >++ } >++ }); >++ >++ return Koha::Notice::Templates->find({ >++ module => $letter->{module}, >++ code => $letter->{code}, >++ branchcode => $letter->{branchcode}, >++ }); >++} >++ >++sub build_a_test_patron { >++ my $categorycode = $builder->build({ >++ source => 'Category' })->{categorycode}; >++ my $branchcode = $builder->build({ >++ source => 'Branch' })->{branchcode}; >++ my $borrowernumber = $builder->build({ >++ source => 'Borrower' })->{borrowernumber}; >++ >++ return Koha::Patrons->find($borrowernumber); >++} >++ >++sub build_a_test_transport_type { >++ my $mtt = $builder->build({ >++ source => 'MessageTransportType' }); >++ >++ return Koha::Patron::Message::Transport::Types->find( >++ $mtt->{message_transport_type} >++ ); >++} >++ >++1; >+diff --git a/t/db_dependent/Koha/Patron/Message/Transport/Types.t b/t/db_dependent/Koha/Patron/Message/Transport/Types.t >+new file mode 100644 >+index 0000000..cbba32b >+--- /dev/null >++++ b/t/db_dependent/Koha/Patron/Message/Transport/Types.t >+@@ -0,0 +1,54 @@ >++#!/usr/bin/perl >++ >++# Copyright 2017 Koha-Suomi Oy >++# >++# This file is part of Koha >++# >++# Koha is free software; you can redistribute it and/or modify it >++# under the terms of the GNU General Public License as published by >++# the Free Software Foundation; either version 3 of the License, or >++# (at your option) any later version. >++# >++# Koha is distributed in the hope that it will be useful, but >++# WITHOUT ANY WARRANTY; without even the implied warranty of >++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >++# GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License >++# along with Koha; if not, see <http://www.gnu.org/licenses>. >++ >++use Modern::Perl; >++ >++use Test::More tests => 2; >++ >++use Koha::Database; >++ >++my $schema = Koha::Database->new->schema; >++ >++subtest 'Test class imports' => sub { >++ plan tests => 2; >++ >++ use_ok('Koha::Patron::Message::Transport::Type'); >++ use_ok('Koha::Patron::Message::Transport::Types'); >++}; >++ >++subtest 'Test Koha::Patron::Message::Transport::Types' => sub { >++ plan tests => 2; >++ >++ $schema->storage->txn_begin; >++ >++ my $transport_type = Koha::Patron::Message::Transport::Type->new({ >++ message_transport_type => 'test' >++ })->store; >++ >++ is($transport_type->message_transport_type, 'test', >++ 'Added a new message transport type.'); >++ >++ $transport_type->delete; >++ is(Koha::Patron::Message::Transport::Types->find('test'), undef, >++ 'Deleted the message transport type.'); >++ >++ $schema->storage->txn_rollback; >++}; >++ >++1; >+diff --git a/t/db_dependent/Koha/Patron/Message/Transports.t b/t/db_dependent/Koha/Patron/Message/Transports.t >+new file mode 100644 >+index 0000000..b9296fd >+--- /dev/null >++++ b/t/db_dependent/Koha/Patron/Message/Transports.t >+@@ -0,0 +1,119 @@ >++#!/usr/bin/perl >++ >++# Copyright 2017 Koha-Suomi Oy >++# >++# This file is part of Koha >++# >++# Koha is free software; you can redistribute it and/or modify it >++# under the terms of the GNU General Public License as published by >++# the Free Software Foundation; either version 3 of the License, or >++# (at your option) any later version. >++# >++# Koha is distributed in the hope that it will be useful, but >++# WITHOUT ANY WARRANTY; without even the implied warranty of >++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >++# GNU General Public License for more details. >++# >++# You should have received a copy of the GNU General Public License >++# along with Koha; if not, see <http://www.gnu.org/licenses>. >++ >++use Modern::Perl; >++ >++use Test::More tests => 2; >++ >++use t::lib::TestBuilder; >++ >++use Koha::Notice::Templates; >++use Koha::Patron::Message::Attributes; >++use Koha::Patron::Message::Transport::Types; >++ >++my $schema = Koha::Database->new->schema; >++my $builder = t::lib::TestBuilder->new; >++ >++subtest 'Test class imports' => sub { >++ plan tests => 2; >++ >++ use_ok('Koha::Patron::Message::Transport'); >++ use_ok('Koha::Patron::Message::Transports'); >++}; >++ >++subtest 'Test Koha::Patron::Message::Transports' => sub { >++ plan tests => 2; >++ >++ $schema->storage->txn_begin; >++ >++ my $attribute = build_a_test_attribute(); >++ my $mtt = build_a_test_transport_type(); >++ my $letter = build_a_test_letter({ >++ mtt => $mtt->message_transport_type >++ }); >++ >++ my $transport = Koha::Patron::Message::Transport->new({ >++ message_attribute_id => $attribute->message_attribute_id, >++ message_transport_type => $mtt->message_transport_type, >++ is_digest => 0, >++ letter_module => $letter->module, >++ letter_code => $letter->code, >++ })->store; >++ >++ is($transport->message_attribute_id, $attribute->message_attribute_id, >++ 'Added a new messaging transport.'); >++ >++ $transport->delete; >++ is(Koha::Patron::Message::Transports->search({ >++ message_attribute_id => $attribute->message_attribute_id, >++ message_transport_type => $mtt->message_transport_type, >++ is_digest => 0 >++ })->count, 0, 'Deleted the messaging transport.'); >++ >++ $schema->storage->txn_rollback; >++}; >++ >++sub build_a_test_attribute { >++ my ($params) = @_; >++ >++ $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0 >++ ? 1 : 0; >++ >++ my $attribute = $builder->build({ >++ source => 'MessageAttribute', >++ value => $params, >++ }); >++ >++ return Koha::Patron::Message::Attributes->find( >++ $attribute->{message_attribute_id} >++ ); >++} >++ >++sub build_a_test_letter { >++ my ($params) = @_; >++ >++ my $mtt = $params->{mtt} ? $params->{mtt} : 'email'; >++ my $branchcode = $builder->build({ >++ source => 'Branch' })->{branchcode}; >++ my $letter = $builder->build({ >++ source => 'Letter', >++ value => { >++ branchcode => '', >++ is_html => 0, >++ message_transport_type => $mtt >++ } >++ }); >++ >++ return Koha::Notice::Templates->find({ >++ module => $letter->{module}, >++ code => $letter->{code}, >++ branchcode => $letter->{branchcode}, >++ }); >++} >++ >++sub build_a_test_transport_type { >++ my $mtt = $builder->build({ >++ source => 'MessageTransportType' }); >++ >++ return Koha::Patron::Message::Transport::Types->find( >++ $mtt->{message_transport_type} >++ ); >++} >++ >++1; >+-- >+2.7.4 >\ No newline at end of file >diff --git a/Koha/Exceptions.pm b/Koha/Exceptions.pm >index 72a56cc3af..4b58bd2a36 100644 >--- a/Koha/Exceptions.pm >+++ b/Koha/Exceptions.pm >@@ -24,7 +24,13 @@ use Exception::Class ( > }, > 'Koha::Exceptions::MissingParameter' => { > isa => 'Koha::Exceptions::Exception', >- description => 'A required parameter is missing' >+ description => 'A required parameter is missing', >+ fields => ['parameter'], >+ }, >+ 'Koha::Exceptions::TooManyParameters' => { >+ isa => 'Koha::Exceptions::Exception', >+ description => 'Too many parameters given', >+ fields => ['parameter'], > }, > 'Koha::Exceptions::NoChanges' => { > isa => 'Koha::Exceptions::Exception', >diff --git a/Koha/Patron.pm b/Koha/Patron.pm >index f0ab2d4d3e..367567f2f3 100644 >--- a/Koha/Patron.pm >+++ b/Koha/Patron.pm >@@ -39,6 +39,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; >@@ -1417,6 +1418,47 @@ sub _anonymize_column { > $self->$col($val); > } > >+=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) { >+ # Check that this option has preference configuration for this category >+ unless (Koha::Patron::Message::Preferences->search({ >+ message_attribute_id => $option->{message_attribute_id}, >+ categorycode => $categorycode || $self->categorycode, >+ })->count) { >+ next; >+ } >+ >+ # Delete current setting >+ Koha::Patron::Message::Preferences->search({ >+ borrowernumber => $self->borrowernumber, >+ message_attribute_id => $option->{message_attribute_id}, >+ })->delete; >+ >+ Koha::Patron::Message::Preference->new_from_default({ >+ borrowernumber => $self->borrowernumber, >+ categorycode => $categorycode || $self->categorycode, >+ message_attribute_id => $option->{message_attribute_id}, >+ }); >+ } >+ >+ return $self; >+} >+ > =head2 Internal methods > > =head3 _type >diff --git a/Koha/Patron/Message/Attribute.pm b/Koha/Patron/Message/Attribute.pm >new file mode 100644 >index 0000000000..9d9004c249 >--- /dev/null >+++ b/Koha/Patron/Message/Attribute.pm >@@ -0,0 +1,50 @@ >+package Koha::Patron::Message::Attribute; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version.a >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+ >+use base qw(Koha::Object); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Attribute - Koha Patron Message Attribute object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'MessageAttribute'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/Koha/Patron/Message/Attributes.pm b/Koha/Patron/Message/Attributes.pm >new file mode 100644 >index 0000000000..a2df4e62d9 >--- /dev/null >+++ b/Koha/Patron/Message/Attributes.pm >@@ -0,0 +1,55 @@ >+package Koha::Patron::Message::Attributes; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+use Koha::Patron::Message::Attribute; >+ >+use base qw(Koha::Objects); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Attributes - Koha Patron Message Attributes object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'MessageAttribute'; >+} >+ >+sub object_class { >+ return 'Koha::Patron::Message::Attribute'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/Koha/Patron/Message/Preference.pm b/Koha/Patron/Message/Preference.pm >new file mode 100644 >index 0000000000..db96b2aee3 >--- /dev/null >+++ b/Koha/Patron/Message/Preference.pm >@@ -0,0 +1,451 @@ >+package Koha::Patron::Message::Preference; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version.a >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+use Koha::Exceptions; >+use Koha::Patron::Categories; >+use Koha::Patron::Message::Attributes; >+use Koha::Patron::Message::Preferences; >+use Koha::Patron::Message::Transport::Preferences; >+use Koha::Patron::Message::Transport::Types; >+use Koha::Patron::Message::Transports; >+use Koha::Patrons; >+ >+use base qw(Koha::Object); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Preference - Koha Patron Message Preference object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 new >+ >+my $preference = Koha::Patron::Message::Preference->new({ >+ borrowernumber => 123, >+ #categorycode => 'ABC', >+ message_attribute_id => 4, >+ message_transport_types => ['email', 'sms'], # see documentation below >+ wants_digest => 1, >+ days_in_advance => 7, >+}); >+ >+Takes either borrowernumber or categorycode, but not both. >+ >+days_in_advance may not be available. See message_attributes table for takes_days >+configuration. >+ >+wants_digest may not be available. See message_transports table for is_digest >+configuration. >+ >+You can instantiate a new object without custom validation errors, but when >+storing, validation may throw exceptions. See C<validate()> for more >+documentation. >+ >+C<message_transport_types> is a parameter that is not actually a column in this >+Koha-object. Given this parameter, the message transport types will be added as >+related transport types for this object. For get and set, you can access them via >+subroutine C<message_transport_types()> in this class. >+ >+=cut >+ >+sub new { >+ my ($class, $params) = @_; >+ >+ my $types = $params->{'message_transport_types'}; >+ delete $params->{'message_transport_types'}; >+ >+ my $self = $class->SUPER::new($params); >+ >+ $self->_set_message_transport_types($types); >+ >+ return $self; >+} >+ >+=head3 new_from_default >+ >+my $preference = Koha::Patron::Message::Preference->new_from_default({ >+ borrowernumber => 123, >+ categorycode => 'ABC', # if not given, patron's categorycode will be used >+ message_attribute_id => 1, >+}); >+ >+NOTE: This subroutine initializes and STORES the object (in order to set >+message transport types for the preference), so no need to call ->store when >+preferences are initialized via this method. >+ >+Stores default messaging preference for C<categorycode> to patron for given >+C<message_attribute_id>. >+ >+Throws Koha::Exceptions::MissingParameter if any of following is missing: >+- borrowernumber >+- message_attribute_id >+ >+Throws Koha::Exceptions::ObjectNotFound if default preferences are not found. >+ >+=cut >+ >+sub new_from_default { >+ my ($class, $params) = @_; >+ >+ my @required = qw(borrowernumber message_attribute_id); >+ foreach my $p (@required) { >+ Koha::Exceptions::MissingParameter->throw( >+ error => 'Missing required parameter.', >+ parameter => $p, >+ ) unless exists $params->{$p}; >+ } >+ unless ($params->{'categorycode'}) { >+ my $patron = Koha::Patrons->find($params->{borrowernumber}); >+ $params->{'categorycode'} = $patron->categorycode; >+ } >+ >+ my $default = Koha::Patron::Message::Preferences->find({ >+ categorycode => $params->{'categorycode'}, >+ message_attribute_id => $params->{'message_attribute_id'}, >+ }); >+ Koha::Exceptions::ObjectNotFound->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 message_name >+ >+$preference->message_name >+ >+Gets message_name for this messaging preference. >+ >+Setter not implemented. >+ >+=cut >+ >+sub message_name { >+ my ($self) = @_; >+ >+ if ($self->{'_message_name'}) { >+ return $self->{'_message_name'}; >+ } >+ $self->{'_message_name'} = Koha::Patron::Message::Attributes->find({ >+ message_attribute_id => $self->message_attribute_id, >+ })->message_name; >+ return $self->{'_message_name'}; >+} >+ >+=head3 message_transport_types >+ >+$preference->message_transport_types >+Returns a HASHREF of message transport types for this messaging preference, e.g. >+if ($preference->message_transport_types->{'email'}) { >+ # email is one of the transport preferences >+} >+ >+$preference->message_transport_types('email', 'sms'); >+Sets the given message transport types for this messaging preference >+ >+=cut >+ >+sub message_transport_types { >+ my $self = shift; >+ >+ unless (@_) { >+ if ($self->{'_message_transport_types'}) { >+ return $self->{'_message_transport_types'}; >+ } >+ map { >+ my $transport = Koha::Patron::Message::Transports->find({ >+ message_attribute_id => $self->message_attribute_id, >+ message_transport_type => $_->message_transport_type, >+ is_digest => $self->wants_digest >+ }); >+ unless ($transport) { >+ my $logger = Koha::Logger->get; >+ $logger->warn( >+ $self->message_name . ' has no transport with '. >+ $_->message_transport_type . ' (digest: '. >+ ($self->wants_digest ? 'yes':'no').').' >+ ); >+ } >+ $self->{'_message_transport_types'}->{$_->message_transport_type} >+ = $transport ? $transport->letter_code : ' '; >+ } >+ Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $self->borrower_message_preference_id, >+ })->as_list; >+ return $self->{'_message_transport_types'} || {}; >+ } >+ else { >+ $self->_set_message_transport_types(@_); >+ return $self; >+ } >+} >+ >+=head3 set >+ >+$preference->set({ >+ message_transport_types => ['sms', 'phone'], >+ wants_digest => 0, >+})->store; >+ >+Sets preference object values and additionally message_transport_types if given. >+ >+=cut >+ >+sub set { >+ my ($self, $params) = @_; >+ >+ my $mtt = $params->{'message_transport_types'}; >+ delete $params->{'message_transport_types'}; >+ >+ $self->SUPER::set($params) if $params; >+ if ($mtt) { >+ $self->message_transport_types($mtt); >+ } >+ >+ return $self; >+} >+ >+=head3 store >+ >+Makes a validation before actual Koha::Object->store so that proper exceptions >+can be thrown. See C<validate()> for documentation about exceptions. >+ >+=cut >+ >+sub store { >+ my $self = shift; >+ >+ $self->validate->SUPER::store(@_); >+ >+ # store message transport types >+ if (exists $self->{'_message_transport_types'}) { >+ Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => >+ $self->borrower_message_preference_id, >+ })->delete; >+ foreach my $type (keys %{$self->{'_message_transport_types'}}) { >+ Koha::Patron::Message::Transport::Preference->new({ >+ borrower_message_preference_id => >+ $self->borrower_message_preference_id, >+ message_transport_type => $type, >+ })->store; >+ } >+ } >+ >+ return $self; >+} >+ >+=head3 validate >+ >+Makes a basic validation for object. >+ >+Throws following exceptions regarding parameters. >+- Koha::Exceptions::MissingParameter >+- Koha::Exceptions::TooManyParameters >+- Koha::Exceptions::BadParameter >+ >+See $_->parameter to identify the parameter causing the exception. >+ >+Throws Koha::Exceptions::DuplicateObject if this preference already exists. >+ >+Returns Koha::Patron::Message::Preference object. >+ >+=cut >+ >+sub validate { >+ my ($self) = @_; >+ >+ if ($self->borrowernumber && $self->categorycode) { >+ Koha::Exceptions::TooManyParameters->throw( >+ error => 'Both borrowernumber and category given, only one accepted', >+ parameter => ['borrowernumber', 'categorycode'], >+ ); >+ } >+ if (!$self->borrowernumber && !$self->categorycode) { >+ Koha::Exceptions::MissingParameter->throw( >+ error => 'borrowernumber or category required, none given', >+ parameter => ['borrowernumber', 'categorycode'], >+ ); >+ } >+ if ($self->borrowernumber) { >+ Koha::Exceptions::BadParameter->throw( >+ error => 'Patron not found.', >+ parameter => 'borrowernumber', >+ ) unless Koha::Patrons->find($self->borrowernumber); >+ } >+ if ($self->categorycode) { >+ Koha::Exceptions::BadParameter->throw( >+ error => 'Category not found.', >+ parameter => 'categorycode', >+ ) unless Koha::Patron::Categories->find($self->categorycode); >+ } >+ >+ if (!$self->in_storage) { >+ my $previous = Koha::Patron::Message::Preferences->search({ >+ borrowernumber => $self->borrowernumber, >+ categorycode => $self->categorycode, >+ message_attribute_id => $self->message_attribute_id, >+ }); >+ if ($previous->count) { >+ Koha::Exceptions::DuplicateObject->throw( >+ error => 'A preference for this borrower/category and' >+ .' message_attribute_id already exists', >+ ); >+ } >+ } >+ >+ my $attr = Koha::Patron::Message::Attributes->find( >+ $self->message_attribute_id >+ ); >+ unless ($attr) { >+ Koha::Exceptions::BadParameter->throw( >+ error => 'Message attribute with id '.$self->message_attribute_id >+ .' not found', >+ parameter => 'message_attribute_id' >+ ); >+ } >+ if (defined $self->days_in_advance) { >+ if ($attr && $attr->takes_days == 0) { >+ Koha::Exceptions::BadParameter->throw( >+ error => 'days_in_advance cannot be defined for '. >+ $attr->message_name . '.', >+ parameter => 'days_in_advance', >+ ); >+ } >+ elsif ($self->days_in_advance < 0 || $self->days_in_advance > 30) { >+ Koha::Exceptions::BadParameter->throw( >+ error => 'days_in_advance has to be a value between 0-30 for '. >+ $attr->message_name . '.', >+ parameter => 'days_in_advance', >+ ); >+ } >+ } >+ if (defined $self->wants_digest) { >+ my $transports = Koha::Patron::Message::Transports->search({ >+ message_attribute_id => $self->message_attribute_id, >+ is_digest => $self->wants_digest ? 1 : 0, >+ }); >+ Koha::Exceptions::BadParameter->throw( >+ error => (!$self->wants_digest ? 'Digest must be selected' >+ : 'Digest cannot be selected') >+ . ' for '.$attr->message_name.'.', >+ parameter => 'wants_digest', >+ ) if $transports->count == 0; >+ } >+ >+ return $self; >+} >+ >+sub _set_message_transport_types { >+ my $self = shift; >+ >+ return unless $_[0]; >+ >+ $self->{'_message_transport_types'} = undef; >+ my $types = ref $_[0] eq "ARRAY" ? $_[0] : [@_]; >+ return unless $types; >+ $self->_validate_message_transport_types({ message_transport_types => $types }); >+ foreach my $type (@$types) { >+ unless (exists $self->{'_message_transport_types'}->{$type}) { >+ my $transport = Koha::Patron::Message::Transports->find({ >+ message_attribute_id => $self->message_attribute_id, >+ message_transport_type => $type >+ }); >+ unless ($transport) { >+ Koha::Exceptions::BadParameter->throw( >+ error => 'No transport configured for '.$self->message_name. >+ " transport type $type.", >+ parameter => 'message_transport_types' >+ ); >+ } >+ $self->{'_message_transport_types'}->{$type} >+ = $transport->letter_code; >+ } >+ } >+ return $self; >+} >+ >+sub _validate_message_transport_types { >+ my ($self, $params) = @_; >+ >+ if (ref($params) eq 'HASH' && $params->{'message_transport_types'}) { >+ if (ref($params->{'message_transport_types'}) ne 'ARRAY') { >+ $params->{'message_transport_types'} = [$params->{'message_transport_types'}]; >+ } >+ my $types = $params->{'message_transport_types'}; >+ >+ foreach my $type (@{$types}) { >+ unless (Koha::Patron::Message::Transport::Types->find({ >+ message_transport_type => $type >+ })) { >+ Koha::Exceptions::BadParameter->throw( >+ error => "Message transport type '$type' does not exist", >+ parameter => 'message_transport_types', >+ ); >+ } >+ } >+ return $types; >+ } >+} >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'BorrowerMessagePreference'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/Koha/Patron/Message/Preferences.pm b/Koha/Patron/Message/Preferences.pm >new file mode 100644 >index 0000000000..fa8e974ee0 >--- /dev/null >+++ b/Koha/Patron/Message/Preferences.pm >@@ -0,0 +1,146 @@ >+package Koha::Patron::Message::Preferences; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+use Koha::Patron::Message::Attributes; >+use Koha::Patron::Message::Preference; >+use Koha::Patron::Message::Transports; >+ >+use base qw(Koha::Objects); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Preferences - Koha Patron Message Preferences object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 find_with_message_name >+ >+Koha::Patron::Message::Preferences->find_with_message_name({ >+ borrowernumber => 123, >+ message_name => 'Hold_Filled', >+}); >+ >+Converts C<message_name> into C<message_attribute_id> and continues find. >+ >+=cut >+ >+sub find_with_message_name { >+ my ($self, $id) = @_; >+ >+ if (ref($id) eq "HASH" && $id->{'message_name'}) { >+ my $attr = Koha::Patron::Message::Attributes->find({ >+ message_name => $id->{'message_name'}, >+ }); >+ $id->{'message_attribute_id'} = ($attr) ? >+ $attr->message_attribute_id : undef; >+ delete $id->{'message_name'}; >+ } >+ >+ return $self->SUPER::find($id); >+} >+ >+=head3 get_options >+ >+my $messaging_options = Koha::Patron::Message::Preferences->get_options >+ >+Returns an ARRAYref of HASHrefs on available messaging options. >+ >+=cut >+ >+sub get_options { >+ my ($self) = @_; >+ >+ my $transports = Koha::Patron::Message::Transports->search(undef, >+ { >+ join => ['message_attribute'], >+ '+select' => ['message_attribute.message_name', 'message_attribute.takes_days'], >+ '+as' => ['message_name', 'takes_days'], >+ }); >+ >+ my $choices; >+ while (my $transport = $transports->next) { >+ my $name = $transport->get_column('message_name'); >+ $choices->{$name}->{'message_attribute_id'} = $transport->message_attribute_id; >+ $choices->{$name}->{'message_name'} = $name; >+ $choices->{$name}->{'takes_days'} = $transport->get_column('takes_days'); >+ $choices->{$name}->{'has_digest'} ||= 1 if $transport->is_digest; >+ $choices->{$name}->{'has_digest_off'} ||= 1 if !$transport->is_digest; >+ $choices->{$name}->{'transport_'.$transport->get_column('message_transport_type')} = ' '; >+ } >+ >+ my @return = values %$choices; >+ @return = sort { $a->{message_attribute_id} <=> $b->{message_attribute_id} } @return; >+ >+ return \@return; >+} >+ >+=head3 search_with_message_name >+ >+Koha::Patron::Message::Preferences->search_with_message_name({ >+ borrowernumber => 123, >+ message_name => 'Hold_Filled', >+}); >+ >+Converts C<message_name> into C<message_attribute_id> and continues search. Use >+Koha::Patron::Message::Preferences->search with a proper join for more complicated >+searches. >+ >+=cut >+ >+sub search_with_message_name { >+ my ($self, $params, $attributes) = @_; >+ >+ if (ref($params) eq "HASH" && $params->{'message_name'}) { >+ my $attr = Koha::Patron::Message::Attributes->find({ >+ message_name => $params->{'message_name'}, >+ }); >+ $params->{'message_attribute_id'} = ($attr) ? >+ $attr->message_attribute_id : undef; >+ delete $params->{'message_name'}; >+ } >+ >+ return $self->SUPER::search($params, $attributes); >+} >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'BorrowerMessagePreference'; >+} >+ >+sub object_class { >+ return 'Koha::Patron::Message::Preference'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/Koha/Patron/Message/Transport.pm b/Koha/Patron/Message/Transport.pm >new file mode 100644 >index 0000000000..ca0906e600 >--- /dev/null >+++ b/Koha/Patron/Message/Transport.pm >@@ -0,0 +1,50 @@ >+package Koha::Patron::Message::Transport; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version.a >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+ >+use base qw(Koha::Object); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Transport - Koha Patron Message Transport object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'MessageTransport'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/Koha/Patron/Message/Transport/Preference.pm b/Koha/Patron/Message/Transport/Preference.pm >new file mode 100644 >index 0000000000..fe0ddeb08f >--- /dev/null >+++ b/Koha/Patron/Message/Transport/Preference.pm >@@ -0,0 +1,51 @@ >+package Koha::Patron::Message::Transport::Preference; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version.a >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+ >+use base qw(Koha::Object); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Transport::Preference - Koha Patron Message Transport >+Preference object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'BorrowerMessageTransportPreference'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/Koha/Patron/Message/Transport/Preferences.pm b/Koha/Patron/Message/Transport/Preferences.pm >new file mode 100644 >index 0000000000..aabd8517a9 >--- /dev/null >+++ b/Koha/Patron/Message/Transport/Preferences.pm >@@ -0,0 +1,56 @@ >+package Koha::Patron::Message::Transport::Preferences; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+use Koha::Patron::Message::Transport::Preference; >+ >+use base qw(Koha::Objects); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Transport::Preferences - Koha Patron Message Transport >+Preferences object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'BorrowerMessageTransportPreference'; >+} >+ >+sub object_class { >+ return 'Koha::Patron::Message::Transport::Preference'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/Koha/Patron/Message/Transport/Type.pm b/Koha/Patron/Message/Transport/Type.pm >new file mode 100644 >index 0000000000..4a52a10e3f >--- /dev/null >+++ b/Koha/Patron/Message/Transport/Type.pm >@@ -0,0 +1,51 @@ >+package Koha::Patron::Message::Transport::Type; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version.a >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+ >+use base qw(Koha::Object); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Transport::Type - Koha Patron Message Transport Type >+object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'MessageTransportType'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/Koha/Patron/Message/Transport/Types.pm b/Koha/Patron/Message/Transport/Types.pm >new file mode 100644 >index 0000000000..2633ea3e73 >--- /dev/null >+++ b/Koha/Patron/Message/Transport/Types.pm >@@ -0,0 +1,56 @@ >+package Koha::Patron::Message::Transport::Types; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+use Koha::Patron::Message::Transport::Type; >+ >+use base qw(Koha::Objects); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Transport::Types - Koha Patron Message Transport Types >+object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'MessageTransportType'; >+} >+ >+sub object_class { >+ return 'Koha::Patron::Message::Transport::Type'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/Koha/Patron/Message/Transports.pm b/Koha/Patron/Message/Transports.pm >new file mode 100644 >index 0000000000..b6aee329b5 >--- /dev/null >+++ b/Koha/Patron/Message/Transports.pm >@@ -0,0 +1,55 @@ >+package Koha::Patron::Message::Transports; >+ >+# Copyright Koha-Suomi Oy 2016 >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it under the >+# terms of the GNU General Public License as published by the Free Software >+# Foundation; either version 3 of the License, or (at your option) any later >+# version. >+# >+# Koha is distributed in the hope that it will be useful, but WITHOUT ANY >+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR >+# A PARTICULAR PURPOSE. See the GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License along >+# with Koha; if not, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+ >+use Modern::Perl; >+ >+use Koha::Database; >+use Koha::Patron::Message::Transport; >+ >+use base qw(Koha::Objects); >+ >+=head1 NAME >+ >+Koha::Patron::Message::Transports - Koha Patron Message Transports object class >+ >+=head1 API >+ >+=head2 Class Methods >+ >+=cut >+ >+=head3 type >+ >+=cut >+ >+sub _type { >+ return 'MessageTransport'; >+} >+ >+sub object_class { >+ return 'Koha::Patron::Message::Transport'; >+} >+ >+=head1 AUTHOR >+ >+Lari Taskula <lari.taskula@jns.fi> >+ >+=cut >+ >+1; >diff --git a/installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl b/installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl >new file mode 100644 >index 0000000000..d816b0ca80 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/Bug_14620-Contact-information-validation.perl >@@ -0,0 +1,7 @@ >+$DBversion = 'XXX'; # will be replaced by the RM >+if( CheckVersion( $DBversion ) ) { >+ $dbh->do("INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES ('ValidatePhoneNumber','','','Regex for validation of patron phone numbers.','Textarea')"); >+ >+ SetVersion( $DBversion ); >+ print "Upgrade to $DBversion done (Bug 14620 - description)\n"; >+} >diff --git a/t/db_dependent/Koha/Patron/Message/Attributes.t b/t/db_dependent/Koha/Patron/Message/Attributes.t >new file mode 100644 >index 0000000000..836b4f0cd5 >--- /dev/null >+++ b/t/db_dependent/Koha/Patron/Message/Attributes.t >@@ -0,0 +1,74 @@ >+#!/usr/bin/perl >+ >+# Copyright 2017 Koha-Suomi Oy >+# >+# This file is part of Koha >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Test::More tests => 2; >+ >+use Koha::Database; >+ >+my $schema = Koha::Database->new->schema; >+ >+subtest 'Test class imports' => sub { >+ plan tests => 2; >+ >+ use_ok('Koha::Patron::Message::Attribute'); >+ use_ok('Koha::Patron::Message::Attributes'); >+}; >+ >+subtest 'Test Koha::Patron::Message::Attributes' => sub { >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ Koha::Patron::Message::Attribute->new({ >+ message_name => 'Test_Attribute' >+ })->store; >+ Koha::Patron::Message::Attribute->new({ >+ message_name => 'Test_Attribute2', >+ takes_days => 1 >+ })->store; >+ >+ my $attribute = Koha::Patron::Message::Attributes->find({ >+ message_name => 'Test_Attribute' }); >+ my $attribute2 = Koha::Patron::Message::Attributes->find({ >+ message_name => 'Test_Attribute2' }); >+ >+ is($attribute->message_name, 'Test_Attribute', >+ 'Added a new messaging attribute.'); >+ is($attribute->takes_days, 0, >+ 'For that messaging attribute, takes_days is disabled by default.'); >+ is($attribute2->message_name, 'Test_Attribute2', >+ 'Added another messaging attribute.'); >+ is($attribute2->takes_days, 1, >+ 'takes_days is enabled for that message attribute (as expected).'); >+ >+ $attribute->delete; >+ $attribute2->delete; >+ is(Koha::Patron::Message::Attributes->find({ >+ message_name => 'Test_Attribute' }), undef, >+ 'Deleted the first message attribute.'); >+ is(Koha::Patron::Message::Attributes->find({ >+ message_name => 'Test_Attribute2' }), undef, >+ 'Deleted the second message attribute.'); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+1; >diff --git a/t/db_dependent/Koha/Patron/Message/Preferences.t b/t/db_dependent/Koha/Patron/Message/Preferences.t >new file mode 100644 >index 0000000000..bd88c6308c >--- /dev/null >+++ b/t/db_dependent/Koha/Patron/Message/Preferences.t >@@ -0,0 +1,719 @@ >+#!/usr/bin/perl >+ >+# Copyright 2017 Koha-Suomi Oy >+# >+# This file is part of Koha >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Test::More tests => 7; >+ >+use t::lib::Mocks; >+use t::lib::TestBuilder; >+ >+use C4::Context; >+ >+use Koha::Notice::Templates; >+use Koha::Patron::Categories; >+use Koha::Patron::Message::Attributes; >+use Koha::Patron::Message::Transport::Types; >+use Koha::Patron::Message::Transports; >+use Koha::Patrons; >+ >+use File::Temp qw/tempfile/; >+use Log::Log4perl; >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+subtest 'Test class imports' => sub { >+ plan tests => 2; >+ >+ use_ok('Koha::Patron::Message::Preference'); >+ use_ok('Koha::Patron::Message::Preferences'); >+}; >+ >+subtest 'Test Koha::Patron::Message::Preferences' => sub { >+ plan tests => 2; >+ >+ $schema->storage->txn_begin; >+ >+ my $attribute = build_a_test_attribute(); >+ my $letter = build_a_test_letter(); >+ my $mtt = build_a_test_transport_type(); >+ Koha::Patron::Message::Transport->new({ >+ message_attribute_id => $attribute->message_attribute_id, >+ message_transport_type => $mtt->message_transport_type, >+ is_digest => 0, >+ letter_module => $letter->module, >+ letter_code => $letter->code, >+ })->store; >+ >+ subtest 'Test for a patron' => sub { >+ plan tests => 3; >+ >+ my $patron = build_a_test_patron(); >+ Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ wants_digest => 0, >+ days_in_advance => undef, >+ })->store; >+ >+ my $preference = Koha::Patron::Message::Preferences->find({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id >+ }); >+ ok($preference->borrower_message_preference_id > 0, >+ 'Added a new messaging preference for patron.'); >+ >+ subtest 'Test set not throwing an exception on duplicate object' => sub { >+ plan tests => 1; >+ >+ Koha::Patron::Message::Attributes->find({ >+ message_attribute_id => $attribute->message_attribute_id >+ })->set({ takes_days => 1 })->store; >+ $preference->set({ days_in_advance => 1 })->store; >+ is(ref($preference), 'Koha::Patron::Message::Preference', >+ 'Updating the preference does not cause duplicate object exception'); >+ }; >+ >+ $preference->delete; >+ is(Koha::Patron::Message::Preferences->search({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id >+ })->count, 0, 'Deleted the messaging preference.'); >+ }; >+ >+ subtest 'Test for a category' => sub { >+ my $category = build_a_test_category(); >+ Koha::Patron::Message::Preference->new({ >+ categorycode => $category->categorycode, >+ message_attribute_id => $attribute->message_attribute_id, >+ wants_digest => 0, >+ days_in_advance => undef, >+ })->store; >+ >+ my $preference = Koha::Patron::Message::Preferences->find({ >+ categorycode => $category->categorycode, >+ message_attribute_id => $attribute->message_attribute_id >+ }); >+ ok($preference->borrower_message_preference_id > 0, >+ 'Added a new messaging preference for category.'); >+ >+ $preference->delete; >+ is(Koha::Patron::Message::Preferences->search({ >+ categorycode => $category->categorycode, >+ message_attribute_id => $attribute->message_attribute_id >+ })->count, 0, 'Deleted the messaging preference.'); >+ }; >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'Test Koha::Patron::Message::Preferences->get_options' => sub { >+ plan tests => 2; >+ >+ subtest 'Test method availability and return value' => sub { >+ plan tests => 3; >+ >+ ok(Koha::Patron::Message::Preferences->can('get_options'), >+ 'Method get_options is available.'); >+ ok(my $options = Koha::Patron::Message::Preferences->get_options, >+ 'Called get_options successfully.'); >+ is(ref($options), 'ARRAY', 'get_options returns a ARRAYref'); >+ }; >+ >+ subtest 'Make sure options are correct' => sub { >+ $schema->storage->txn_begin; >+ my $options = Koha::Patron::Message::Preferences->get_options; >+ >+ foreach my $option (@$options) { >+ my $n = $option->{'message_name'}; >+ my $attr = Koha::Patron::Message::Attributes->find($option->{'message_attribute_id'}); >+ is($option->{'message_attribute_id'}, $attr->message_attribute_id, >+ '$n: message_attribute_id is set'); >+ is($option->{'message_name'}, $attr->message_name, '$n: message_name is set'); >+ is($option->{'takes_days'}, $attr->takes_days, '$n: takes_days is set'); >+ my $transports = Koha::Patron::Message::Transports->search({ >+ message_attribute_id => $option->{'message_attribute_id'}, >+ is_digest => $option->{'has_digest'} || 0, >+ }); >+ while (my $trnzport = $transports->next) { >+ is($option->{'has_digest'} || 0, $trnzport->is_digest, '$n: has_digest is set for '.$trnzport->message_transport_type); >+ is($option->{'transport_'.$trnzport->message_transport_type}, ' ', '$n: transport_'.$trnzport->message_transport_type.' is set'); >+ } >+ } >+ >+ $schema->storage->txn_rollback; >+ }; >+}; >+ >+subtest 'Add preferences from defaults' => sub { >+ plan tests => 3; >+ >+ $schema->storage->txn_begin; >+ >+ my $patron = build_a_test_patron(); >+ my ($default, $mtt1, $mtt2) = build_a_test_category_preference({ >+ patron => $patron, >+ }); >+ ok(Koha::Patron::Message::Preference->new_from_default({ >+ borrowernumber => $patron->borrowernumber, >+ categorycode => $patron->categorycode, >+ message_attribute_id => $default->message_attribute_id, >+ })->store, 'Added a default preference to patron.'); >+ ok(my $pref = Koha::Patron::Message::Preferences->find({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $default->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'); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'Test Koha::Patron::Message::Preference->message_transport_types' => sub { >+ plan tests => 4; >+ >+ ok(Koha::Patron::Message::Preference->can('message_transport_types'), >+ 'Method message_transport_types available'); >+ >+ subtest 'get message_transport_types' => sub { >+ plan tests => 5; >+ >+ $schema->storage->txn_begin; >+ >+ my $patron = build_a_test_patron(); >+ my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({ >+ patron => $patron >+ }); >+ Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ })->delete; >+ Koha::Patron::Message::Transport::Preference->new({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ message_transport_type => $mtt1->message_transport_type, >+ })->store; >+ Koha::Patron::Message::Transport::Preference->new({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ message_transport_type => $mtt2->message_transport_type, >+ })->store; >+ my $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ }); >+ my $transport1 = Koha::Patron::Message::Transports->find({ >+ message_attribute_id => $preference->message_attribute_id, >+ message_transport_type => $mtt1->message_transport_type, >+ }); >+ my $transport2 = Koha::Patron::Message::Transports->find({ >+ message_attribute_id => $preference->message_attribute_id, >+ message_transport_type => $mtt2->message_transport_type, >+ }); >+ my $transports = $preference->message_transport_types; >+ is(keys %{$transports}, $stored_transports->count, >+ '->message_transport_types gets correct amount of transport types.'); >+ is($transports->{$stored_transports->next->message_transport_type}, >+ $transport1->letter_code, 'Found correct message transport type and letter code.'); >+ is($transports->{$stored_transports->next->message_transport_type}, >+ $transport2->letter_code, 'Found correct message transport type and letter code.'); >+ ok(!$preference->message_transport_types->{'nonexistent'}, >+ 'Didn\'t find nonexistent transport type.'); >+ >+ subtest 'test logging of warnings by invalid message transport type' => sub { >+ plan tests => 2; >+ >+ my $log = mytempfile(); >+ my $conf = mytempfile( <<"HERE" >+log4perl.logger.opac = WARN, OPAC >+log4perl.appender.OPAC=Log::Log4perl::Appender::TestBuffer >+log4perl.appender.OPAC.filename=$log >+log4perl.appender.OPAC.mode=append >+log4perl.appender.OPAC.layout=SimpleLayout >+log4perl.logger.intranet = WARN, INTRANET >+log4perl.appender.INTRANET=Log::Log4perl::Appender::TestBuffer >+log4perl.appender.INTRANET.filename=$log >+log4perl.appender.INTRANET.mode=append >+log4perl.appender.INTRANET.layout=SimpleLayout >+HERE >+ ); >+ t::lib::Mocks::mock_config('log4perl_conf', $conf); >+ my $appenders = Log::Log4perl->appenders; >+ my $appender = Log::Log4perl->appenders->{OPAC}; >+ >+ my $pref = Koha::Patron::Message::Preferences->find( >+ $preference->borrower_message_preference_id >+ ); >+ my $transports = $pref->message_transport_types; >+ is($appender, undef, 'Nothing in buffer yet'); >+ >+ my $mtt_new = build_a_test_transport_type(); >+ Koha::Patron::Message::Transport::Preference->new({ >+ borrower_message_preference_id => >+ $pref->borrower_message_preference_id, >+ message_transport_type => $mtt_new->message_transport_type, >+ })->store; >+ $pref = Koha::Patron::Message::Preferences->find( >+ $pref->borrower_message_preference_id >+ ); >+ $transports = $pref->message_transport_types; >+ $appender = Log::Log4perl->appenders->{OPAC}; >+ my $name = $pref->message_name; >+ my $tt = $mtt_new->message_transport_type; >+ like($appender->buffer, qr/WARN - $name has no transport with $tt/, >+ 'Logged invalid message transport type'); >+ }; >+ >+ $schema->storage->txn_rollback; >+ }; >+ >+ subtest 'set message_transport_types' => sub { >+ plan tests => 6; >+ >+ $schema->storage->txn_begin; >+ >+ my $patron = build_a_test_patron(); >+ my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({ >+ patron => $patron >+ }); >+ >+ my $mtt1_str = $mtt1->message_transport_type; >+ my $mtt2_str = $mtt2->message_transport_type; >+ # 1/3, use message_transport_types(list) >+ Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ })->delete; >+ ok($preference->message_transport_types($mtt1_str, $mtt2_str)->store, >+ '1/3 Set returned true.'); >+ my $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ '-or' => [ >+ message_transport_type => $mtt1_str, >+ message_transport_type => $mtt2_str >+ ] >+ }); >+ is($stored_transports->count, 2, 'Two transports selected'); >+ >+ # 2/3, use message_transport_types(ARRAYREF) >+ Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ })->delete; >+ ok($preference->message_transport_types([$mtt1_str, $mtt2_str])->store, >+ '2/3 Set returned true.'); >+ $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ '-or' => [ >+ message_transport_type => $mtt1_str, >+ message_transport_type => $mtt2_str >+ ] >+ }); >+ is($stored_transports->count, 2, 'Two transports selected'); >+ >+ # 3/3, use set({ message_transport_types => ARRAYREF }) >+ Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ })->delete; >+ ok($preference->set({ >+ message_transport_types => [$mtt1_str, $mtt2_str]})->store, >+ '3/3 Set returned true.'); >+ $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ '-or' => [ >+ message_transport_type => $mtt1_str, >+ message_transport_type => $mtt2_str >+ ] >+ }); >+ is($stored_transports->count, 2, 'Two transports selected'); >+ >+ $schema->storage->txn_rollback; >+ }; >+ >+ subtest 'new message_transport_types' => sub { >+ plan tests => 3; >+ >+ $schema->storage->txn_begin; >+ >+ my $patron = build_a_test_patron(); >+ my $letter = build_a_test_letter(); >+ my $attribute = build_a_test_attribute(); >+ my $mtt = build_a_test_transport_type(); >+ Koha::Patron::Message::Transport->new({ >+ message_attribute_id => $attribute->message_attribute_id, >+ message_transport_type => $mtt->message_transport_type, >+ is_digest => 0, >+ letter_module => $letter->module, >+ letter_code => $letter->code, >+ })->store; >+ ok(my $preference = Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ wants_digest => 0, >+ days_in_advance => undef, >+ message_transport_types => $mtt->message_transport_type, >+ })->store, 'Added a new messaging preference and transport types to patron.'); >+ ok($preference->message_transport_types->{$mtt->message_transport_type}, >+ 'The transport type is stored in the object.'); >+ my $stored_transports = Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $preference->borrower_message_preference_id, >+ }); >+ is($stored_transports->next->message_transport_type, $mtt->message_transport_type, >+ 'The transport type is stored in the database.'); >+ >+ $schema->storage->txn_rollback; >+ }; >+}; >+ >+subtest 'Test Koha::Patron::Message::Preference->message_name' => sub { >+ plan tests => 1; >+ >+ $schema->storage->txn_begin; >+ >+ my $patron = build_a_test_patron(); >+ my $attribute = build_a_test_attribute(); >+ my ($preference, $mtt1, $mtt2) = build_a_test_complete_preference({ >+ patron => $patron, >+ attr => $attribute, >+ }); >+ my $message_name_pref = Koha::Patron::Message::Preferences->search_with_message_name({ >+ borrowernumber => $patron->{'borrowernumber'}, >+ message_name => $attribute->message_name, >+ })->next; >+ is($message_name_pref->message_name, $attribute->message_name, "Found preference with message_name"); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'Test adding a new preference with invalid parameters' => sub { >+ plan tests => 4; >+ >+ subtest 'Missing parameters' => sub { >+ plan tests => 1; >+ >+ eval { Koha::Patron::Message::Preference->new->store }; >+ is(ref $@, 'Koha::Exceptions::MissingParameter', >+ 'Adding a message preference without parameters' >+ .' => Koha::Exceptions::MissingParameter'); >+ }; >+ >+ subtest 'Too many parameters' => sub { >+ plan tests => 1; >+ >+ $schema->storage->txn_begin; >+ >+ my $patron = build_a_test_patron(); >+ eval { Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ categorycode => $patron->categorycode, >+ })->store }; >+ is(ref $@, 'Koha::Exceptions::TooManyParameters', >+ 'Adding a message preference for both borrowernumber and categorycode' >+ .' => Koha::Exceptions::TooManyParameters'); >+ >+ $schema->storage->txn_rollback; >+ }; >+ >+ subtest 'Bad parameter' => sub { >+ plan tests => 22; >+ >+ $schema->storage->txn_begin; >+ >+ eval { Koha::Patron::Message::Preference->new({ >+ borrowernumber => -999, >+ })->store }; >+ is(ref $@, 'Koha::Exceptions::BadParameter', >+ 'Adding a message preference with invalid borrowernumber' >+ .' => Koha::Exceptions::BadParameter'); >+ is ($@->parameter, 'borrowernumber', 'The previous exception tells us it' >+ .' was the borrowernumber.'); >+ >+ eval { Koha::Patron::Message::Preference->new({ >+ categorycode => 'nonexistent', >+ })->store }; >+ is(ref $@, 'Koha::Exceptions::BadParameter', >+ 'Adding a message preference with invalid categorycode' >+ .' => Koha::Exceptions::BadParameter'); >+ is($@->parameter, 'categorycode', 'The previous exception tells us it' >+ .' was the categorycode.'); >+ >+ my $attribute = build_a_test_attribute({ takes_days => 0 }); >+ my $patron = build_a_test_patron(); >+ eval { Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ days_in_advance => 10, >+ })->store }; >+ is(ref $@, 'Koha::Exceptions::BadParameter', >+ 'Adding a message preference with days in advance option when not' >+ .' available => Koha::Exceptions::BadParameter'); >+ is($@->parameter, 'days_in_advance', 'The previous exception tells us it' >+ .' was the days_in_advance.'); >+ >+ $attribute->set({ takes_days => 1 })->store; >+ eval { Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ days_in_advance => 31, >+ })->store }; >+ is(ref $@, 'Koha::Exceptions::BadParameter', >+ 'Adding a message preference with days in advance option too large' >+ .' => Koha::Exceptions::BadParameter'); >+ is($@->parameter, 'days_in_advance', 'The previous exception tells us it' >+ .' was the days_in_advance.'); >+ >+ eval { Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_transport_types => ['nonexistent'] >+ })->store }; >+ is (ref $@, 'Koha::Exceptions::BadParameter', >+ 'Adding a message preference with invalid message_transport_type' >+ .' => Koha::Exceptions::BadParameter'); >+ is ($@->parameter, 'message_transport_types', 'The previous exception ' >+ .'tells us it was the message_transport_types.'); >+ >+ my $mtt_new = build_a_test_transport_type(); >+ eval { >+ Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ message_transport_types => [$mtt_new->message_transport_type], >+ wants_digest => 1, >+ })->store }; >+ is (ref $@, 'Koha::Exceptions::BadParameter', >+ 'Adding a message preference with invalid message_transport_type' >+ .' => Koha::Exceptions::BadParameter'); >+ is ($@->parameter, 'message_transport_types', 'The previous exception ' >+ .'tells us it was the message_transport_types.'); >+ like ($@->error, qr/^No transport configured/, 'Exception is because of ' >+ .'given message_transport_type is not a valid option.'); >+ >+ eval { >+ Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ message_transport_types => [], >+ wants_digest => 1, >+ })->store }; >+ is (ref $@, 'Koha::Exceptions::BadParameter', >+ 'Adding a message preference with invalid message_transport_type' >+ .' => Koha::Exceptions::BadParameter'); >+ is ($@->parameter, 'wants_digest', 'The previous exception tells us it' >+ .' was the wants_digest'); >+ like ($@->error, qr/^Digest cannot be selected/, 'Exception s because of' >+ .' given digest is not available for this transport.'); >+ >+ eval { >+ Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ message_transport_types => [], >+ wants_digest => 0, >+ })->store }; >+ is (ref $@, 'Koha::Exceptions::BadParameter', >+ 'Adding a message preference with invalid message_transport_type' >+ .' => Koha::Exceptions::BadParameter'); >+ is ($@->parameter, 'wants_digest', 'The previous exception tells us it' >+ .' was the wants_digest'); >+ like ($@->error, qr/^Digest must be selected/, 'Exception s because of' >+ .' digest has to be on for this transport.'); >+ >+ eval { >+ Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => -1, >+ message_transport_types => [], >+ })->store }; >+ is (ref $@, 'Koha::Exceptions::BadParameter', >+ 'Adding a message preference with invalid message_transport_type' >+ .' => Koha::Exceptions::BadParameter'); >+ is ($@->parameter, 'message_attribute_id', 'The previous exception tells' >+ .' us it was the message_attribute_id'); >+ like ($@->error, qr/^Message attribute with id -1 not found/, 'Exception ' >+ .' is because of given message attribute id is not found.'); >+ >+ $schema->storage->txn_rollback; >+ }; >+ >+ subtest 'Duplicate object' => sub { >+ plan tests => 2; >+ >+ $schema->storage->txn_begin; >+ >+ my $attribute = build_a_test_attribute(); >+ my $letter = build_a_test_letter(); >+ my $mtt = build_a_test_transport_type(); >+ Koha::Patron::Message::Transport->new({ >+ message_attribute_id => $attribute->message_attribute_id, >+ message_transport_type => $mtt->message_transport_type, >+ is_digest => 0, >+ letter_module => $letter->module, >+ letter_code => $letter->code, >+ })->store; >+ my $patron = build_a_test_patron(); >+ my $preference = Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ wants_digest => 0, >+ days_in_advance => undef, >+ })->store; >+ ok($preference->borrower_message_preference_id, >+ 'Added a new messaging preference for patron.'); >+ eval { Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ wants_digest => 0, >+ days_in_advance => undef, >+ })->store }; >+ is(ref $@, 'Koha::Exceptions::DuplicateObject', >+ 'Adding a duplicate preference' >+ .' => Koha::Exceptions::DuplicateObject'); >+ >+ $schema->storage->txn_rollback; >+ }; >+}; >+ >+sub build_a_test_attribute { >+ my ($params) = @_; >+ >+ $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0 >+ ? 1 : 0; >+ >+ my $attribute = $builder->build({ >+ source => 'MessageAttribute', >+ value => $params, >+ }); >+ >+ return Koha::Patron::Message::Attributes->find( >+ $attribute->{message_attribute_id} >+ ); >+} >+ >+sub build_a_test_category { >+ my $categorycode = $builder->build({ >+ source => 'Category' })->{categorycode}; >+ >+ return Koha::Patron::Categories->find($categorycode); >+} >+ >+sub build_a_test_letter { >+ my ($params) = @_; >+ >+ my $mtt = $params->{mtt} ? $params->{mtt} : 'email'; >+ my $branchcode = $builder->build({ >+ source => 'Branch' })->{branchcode}; >+ my $letter = $builder->build({ >+ source => 'Letter', >+ value => { >+ branchcode => '', >+ is_html => 0, >+ message_transport_type => $mtt >+ } >+ }); >+ >+ return Koha::Notice::Templates->find({ >+ module => $letter->{module}, >+ code => $letter->{code}, >+ branchcode => $letter->{branchcode}, >+ }); >+} >+ >+sub build_a_test_patron { >+ my $categorycode = $builder->build({ >+ source => 'Category' })->{categorycode}; >+ my $branchcode = $builder->build({ >+ source => 'Branch' })->{branchcode}; >+ my $borrowernumber = $builder->build({ >+ source => 'Borrower' })->{borrowernumber}; >+ >+ return Koha::Patrons->find($borrowernumber); >+} >+ >+sub build_a_test_transport_type { >+ my $mtt = $builder->build({ >+ source => 'MessageTransportType' }); >+ >+ return Koha::Patron::Message::Transport::Types->find( >+ $mtt->{message_transport_type} >+ ); >+} >+ >+sub build_a_test_category_preference { >+ my ($params) = @_; >+ >+ my $patron = $params->{patron}; >+ my $attr = $params->{attr} >+ ? $params->{attr} >+ : build_a_test_attribute($params->{days_in_advance}); >+ >+ my $letter = $params->{letter} ? $params->{letter} : build_a_test_letter(); >+ my $mtt1 = $params->{mtt1} ? $params->{mtt1} : build_a_test_transport_type(); >+ my $mtt2 = $params->{mtt2} ? $params->{mtt2} : build_a_test_transport_type(); >+ >+ Koha::Patron::Message::Transport->new({ >+ message_attribute_id => $attr->message_attribute_id, >+ message_transport_type => $mtt1->message_transport_type, >+ is_digest => $params->{digest} ? 1 : 0, >+ letter_module => $letter->module, >+ letter_code => $letter->code, >+ })->store; >+ >+ Koha::Patron::Message::Transport->new({ >+ message_attribute_id => $attr->message_attribute_id, >+ message_transport_type => $mtt2->message_transport_type, >+ is_digest => $params->{digest} ? 1 : 0, >+ letter_module => $letter->module, >+ letter_code => $letter->code, >+ })->store; >+ >+ my $default = Koha::Patron::Message::Preference->new({ >+ categorycode => $patron->categorycode, >+ message_attribute_id => $attr->message_attribute_id, >+ wants_digest => $params->{digest} ? 1 : 0, >+ days_in_advance => $params->{days_in_advance} >+ ? $params->{days_in_advance} : undef, >+ })->store; >+ >+ Koha::Patron::Message::Transport::Preference->new({ >+ borrower_message_preference_id => $default->borrower_message_preference_id, >+ message_transport_type => $mtt1->message_transport_type, >+ })->store; >+ Koha::Patron::Message::Transport::Preference->new({ >+ borrower_message_preference_id => $default->borrower_message_preference_id, >+ message_transport_type => $mtt2->message_transport_type, >+ })->store; >+ >+ return ($default, $mtt1, $mtt2); >+} >+ >+sub build_a_test_complete_preference { >+ my ($params) = @_; >+ >+ my ($default, $mtt1, $mtt2) = build_a_test_category_preference($params); >+ my $patron = $params->{patron}; >+ $patron->set_default_messaging_preferences; >+ return (Koha::Patron::Message::Preferences->search({ >+ borrowernumber => $patron->borrowernumber >+ })->next, $mtt1, $mtt2); >+} >+ >+sub mytempfile { >+ my ( $fh, $fn ) = tempfile( SUFFIX => '.logger.test', UNLINK => 1 ); >+ print $fh $_[0]//''; >+ close $fh; >+ return $fn; >+} >+ >+1; >diff --git a/t/db_dependent/Koha/Patron/Message/Transport/Preferences.t b/t/db_dependent/Koha/Patron/Message/Transport/Preferences.t >new file mode 100644 >index 0000000000..0cdf8095a4 >--- /dev/null >+++ b/t/db_dependent/Koha/Patron/Message/Transport/Preferences.t >@@ -0,0 +1,179 @@ >+#!/usr/bin/perl >+ >+# Copyright 2017 Koha-Suomi Oy >+# >+# This file is part of Koha >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Test::More tests => 2; >+ >+use t::lib::Mocks; >+use t::lib::TestBuilder; >+ >+use Koha::Notice::Templates; >+use Koha::Patron::Categories; >+use Koha::Patron::Message::Attributes; >+use Koha::Patron::Message::Preferences; >+use Koha::Patron::Message::Transport::Types; >+use Koha::Patron::Message::Transports; >+use Koha::Patrons; >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+subtest 'Test class imports' => sub { >+ plan tests => 2; >+ >+ use_ok('Koha::Patron::Message::Transport::Preference'); >+ use_ok('Koha::Patron::Message::Transport::Preferences'); >+}; >+ >+subtest 'Test Koha::Patron::Message::Transport::Preferences' => sub { >+ plan tests => 2; >+ >+ $schema->storage->txn_begin; >+ >+ my $attribute = build_a_test_attribute(); >+ my $mtt = build_a_test_transport_type(); >+ my $letter = build_a_test_letter({ >+ mtt => $mtt->message_transport_type >+ }); >+ Koha::Patron::Message::Transport->new({ >+ message_attribute_id => $attribute->message_attribute_id, >+ message_transport_type => $mtt->message_transport_type, >+ is_digest => 0, >+ letter_module => $letter->module, >+ letter_code => $letter->code, >+ })->store; >+ >+ subtest 'For a patron' => sub { >+ my $patron = build_a_test_patron(); >+ my $preference = Koha::Patron::Message::Preference->new({ >+ borrowernumber => $patron->borrowernumber, >+ message_attribute_id => $attribute->message_attribute_id, >+ wants_digest => 0, >+ days_in_advance => undef, >+ })->store; >+ >+ my $pref_id = $preference->borrower_message_preference_id; >+ my $transport_pref = Koha::Patron::Message::Transport::Preference->new({ >+ borrower_message_preference_id => $pref_id, >+ message_transport_type => $mtt->message_transport_type, >+ })->store; >+ is(ref($transport_pref), 'Koha::Patron::Message::Transport::Preference', >+ 'Added a new messaging transport preference for patron.'); >+ >+ $transport_pref->delete; >+ is(Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $pref_id, >+ message_transport_type => $mtt->message_transport_type, >+ })->count, 0, 'Deleted the messaging transport preference.'); >+ }; >+ >+ subtest 'For a category' => sub { >+ my $category = build_a_test_category(); >+ my $preference = Koha::Patron::Message::Preference->new({ >+ categorycode => $category->categorycode, >+ message_attribute_id => $attribute->message_attribute_id, >+ wants_digest => 0, >+ days_in_advance => undef, >+ })->store; >+ >+ my $pref_id = $preference->borrower_message_preference_id; >+ my $transport_pref = Koha::Patron::Message::Transport::Preference->new({ >+ borrower_message_preference_id => $pref_id, >+ message_transport_type => $mtt->message_transport_type, >+ })->store; >+ is(ref($transport_pref), 'Koha::Patron::Message::Transport::Preference', >+ 'Added a new messaging transport preference for category.'); >+ >+ $transport_pref->delete; >+ is(Koha::Patron::Message::Transport::Preferences->search({ >+ borrower_message_preference_id => $pref_id, >+ message_transport_type => $mtt->message_transport_type, >+ })->count, 0, 'Deleted the messaging transport preference.'); >+ }; >+ >+ $schema->storage->txn_rollback; >+}; >+ >+sub build_a_test_attribute { >+ my ($params) = @_; >+ >+ $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0 >+ ? 1 : 0; >+ >+ my $attribute = $builder->build({ >+ source => 'MessageAttribute', >+ value => $params, >+ }); >+ >+ return Koha::Patron::Message::Attributes->find( >+ $attribute->{message_attribute_id} >+ ); >+} >+ >+sub build_a_test_category { >+ my $categorycode = $builder->build({ >+ source => 'Category' })->{categorycode}; >+ >+ return Koha::Patron::Categories->find($categorycode); >+} >+ >+sub build_a_test_letter { >+ my ($params) = @_; >+ >+ my $mtt = $params->{mtt} ? $params->{mtt} : 'email'; >+ my $branchcode = $builder->build({ >+ source => 'Branch' })->{branchcode}; >+ my $letter = $builder->build({ >+ source => 'Letter', >+ value => { >+ branchcode => '', >+ is_html => 0, >+ message_transport_type => $mtt >+ } >+ }); >+ >+ return Koha::Notice::Templates->find({ >+ module => $letter->{module}, >+ code => $letter->{code}, >+ branchcode => $letter->{branchcode}, >+ }); >+} >+ >+sub build_a_test_patron { >+ my $categorycode = $builder->build({ >+ source => 'Category' })->{categorycode}; >+ my $branchcode = $builder->build({ >+ source => 'Branch' })->{branchcode}; >+ my $borrowernumber = $builder->build({ >+ source => 'Borrower' })->{borrowernumber}; >+ >+ return Koha::Patrons->find($borrowernumber); >+} >+ >+sub build_a_test_transport_type { >+ my $mtt = $builder->build({ >+ source => 'MessageTransportType' }); >+ >+ return Koha::Patron::Message::Transport::Types->find( >+ $mtt->{message_transport_type} >+ ); >+} >+ >+1; >diff --git a/t/db_dependent/Koha/Patron/Message/Transport/Types.t b/t/db_dependent/Koha/Patron/Message/Transport/Types.t >new file mode 100644 >index 0000000000..cbba32b228 >--- /dev/null >+++ b/t/db_dependent/Koha/Patron/Message/Transport/Types.t >@@ -0,0 +1,54 @@ >+#!/usr/bin/perl >+ >+# Copyright 2017 Koha-Suomi Oy >+# >+# This file is part of Koha >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Test::More tests => 2; >+ >+use Koha::Database; >+ >+my $schema = Koha::Database->new->schema; >+ >+subtest 'Test class imports' => sub { >+ plan tests => 2; >+ >+ use_ok('Koha::Patron::Message::Transport::Type'); >+ use_ok('Koha::Patron::Message::Transport::Types'); >+}; >+ >+subtest 'Test Koha::Patron::Message::Transport::Types' => sub { >+ plan tests => 2; >+ >+ $schema->storage->txn_begin; >+ >+ my $transport_type = Koha::Patron::Message::Transport::Type->new({ >+ message_transport_type => 'test' >+ })->store; >+ >+ is($transport_type->message_transport_type, 'test', >+ 'Added a new message transport type.'); >+ >+ $transport_type->delete; >+ is(Koha::Patron::Message::Transport::Types->find('test'), undef, >+ 'Deleted the message transport type.'); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+1; >diff --git a/t/db_dependent/Koha/Patron/Message/Transports.t b/t/db_dependent/Koha/Patron/Message/Transports.t >new file mode 100644 >index 0000000000..b9296fd3c1 >--- /dev/null >+++ b/t/db_dependent/Koha/Patron/Message/Transports.t >@@ -0,0 +1,119 @@ >+#!/usr/bin/perl >+ >+# Copyright 2017 Koha-Suomi Oy >+# >+# This file is part of Koha >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Test::More tests => 2; >+ >+use t::lib::TestBuilder; >+ >+use Koha::Notice::Templates; >+use Koha::Patron::Message::Attributes; >+use Koha::Patron::Message::Transport::Types; >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+subtest 'Test class imports' => sub { >+ plan tests => 2; >+ >+ use_ok('Koha::Patron::Message::Transport'); >+ use_ok('Koha::Patron::Message::Transports'); >+}; >+ >+subtest 'Test Koha::Patron::Message::Transports' => sub { >+ plan tests => 2; >+ >+ $schema->storage->txn_begin; >+ >+ my $attribute = build_a_test_attribute(); >+ my $mtt = build_a_test_transport_type(); >+ my $letter = build_a_test_letter({ >+ mtt => $mtt->message_transport_type >+ }); >+ >+ my $transport = Koha::Patron::Message::Transport->new({ >+ message_attribute_id => $attribute->message_attribute_id, >+ message_transport_type => $mtt->message_transport_type, >+ is_digest => 0, >+ letter_module => $letter->module, >+ letter_code => $letter->code, >+ })->store; >+ >+ is($transport->message_attribute_id, $attribute->message_attribute_id, >+ 'Added a new messaging transport.'); >+ >+ $transport->delete; >+ is(Koha::Patron::Message::Transports->search({ >+ message_attribute_id => $attribute->message_attribute_id, >+ message_transport_type => $mtt->message_transport_type, >+ is_digest => 0 >+ })->count, 0, 'Deleted the messaging transport.'); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+sub build_a_test_attribute { >+ my ($params) = @_; >+ >+ $params->{takes_days} = $params->{takes_days} && $params->{takes_days} > 0 >+ ? 1 : 0; >+ >+ my $attribute = $builder->build({ >+ source => 'MessageAttribute', >+ value => $params, >+ }); >+ >+ return Koha::Patron::Message::Attributes->find( >+ $attribute->{message_attribute_id} >+ ); >+} >+ >+sub build_a_test_letter { >+ my ($params) = @_; >+ >+ my $mtt = $params->{mtt} ? $params->{mtt} : 'email'; >+ my $branchcode = $builder->build({ >+ source => 'Branch' })->{branchcode}; >+ my $letter = $builder->build({ >+ source => 'Letter', >+ value => { >+ branchcode => '', >+ is_html => 0, >+ message_transport_type => $mtt >+ } >+ }); >+ >+ return Koha::Notice::Templates->find({ >+ module => $letter->{module}, >+ code => $letter->{code}, >+ branchcode => $letter->{branchcode}, >+ }); >+} >+ >+sub build_a_test_transport_type { >+ my $mtt = $builder->build({ >+ source => 'MessageTransportType' }); >+ >+ return Koha::Patron::Message::Transport::Types->find( >+ $mtt->{message_transport_type} >+ ); >+} >+ >+1; >-- >2.17.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 17499
:
63427
|
63428
|
63429
|
63430
|
63431
|
63432
|
63433
|
63434
|
63786
|
63787
|
63788
|
63789
|
63790
|
63791
|
63792
|
63793
|
63801
|
63802
|
63803
|
63804
|
63805
|
63806
|
63807
|
63808
|
63809
|
63810
|
63811
|
63812
|
63878
|
63895
|
64035
|
64036
|
64037
|
64038
|
64039
|
64040
|
64041
|
64042
|
64043
|
64044
|
64795
|
66686
|
69434
|
69435
|
69458
|
91864
|
93863
|
93865
|
93872
|
94748
|
99479
|
99634
|
99668
|
99669
|
99670
|
103441
|
103442
|
103443
|
106653
|
106654
|
106655
|
106656
|
106657
|
107612
|
107613
|
107614
|
107615
|
107616
|
113010
|
113011
|
113127
|
113129
|
113686
|
113687
|
113765
|
113766
|
113767
|
113768
|
118452
|
118453
|
119470
|
119471
|
119472
|
119473
|
119474
|
119475
|
119476
|
119477
|
119478
|
119479
|
119480
|
119481
|
119482
|
119483
|
119484
|
119485
|
119486
|
119487
|
119488
|
119489
|
119490
|
119491
|
141408
|
141409
|
141410
|
141411
|
141412
|
141413
|
141414
|
141415
|
141416
|
141417
|
141418
|
146529
|
146530
|
146531
|
146532
|
146533
|
146534
|
146535
|
146536
|
146537
|
146538
|
146539
|
146540
|
151900
|
151901
|
151902
|
151903
|
151904
|
151905
|
151906
|
151907
|
151908
|
151909
|
151910
|
151911
|
151937
|
151938
|
151939
|
151940
|
151941
|
151942
|
151943
|
151944
|
151945
|
151946
|
151947
|
151948
|
155365
|
155366
|
155367
|
155368
|
155369
|
155370
|
155371
|
155372
|
155373
|
155374
|
155375
|
155376