From 1ae09a1c645ff6664761e7c9cc268f3c0938caac Mon Sep 17 00:00:00 2001
From: Tomas Cohen Arazi <tomascohen@theke.io>
Date: Fri, 30 Dec 2016 11:12:32 -0300
Subject: [PATCH] Bug 17828: Overload Koha::Patron::Attribute->store to check
 for unique_id and repeatable

This patch introduces a Koha::Patron::Attribute->store method that does
the required check for the corresponding Koha::Patron::Attribute::Type
and raises an exception if trying to store more than one unique
attribute code/value combination, and another exception for
non-repeatable attribute types being stored while already existing on
the DB.

This patch introduces exception definitions for that purpose.

To test:
- Apply the unit tests patches
- Run:
  $ prove t/db_dependent/Koha/Patron/Attributes.t
=> FAIL: Tests fail
- Apply this patch
- Run:
  $ prove t/db_dependent/Koha/Patron/Attributes.t
=> SUCCESS: Tests pass!
- Sign off :-D

Signed-off-by: Josef Moravec <josef.moravec@gmail.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
---
 Koha/Exceptions/Patron/Attribute.pm | 20 +++++++++++
 Koha/Patron/Attribute.pm            | 70 +++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+)
 create mode 100644 Koha/Exceptions/Patron/Attribute.pm

diff --git a/Koha/Exceptions/Patron/Attribute.pm b/Koha/Exceptions/Patron/Attribute.pm
new file mode 100644
index 0000000..80d7370
--- /dev/null
+++ b/Koha/Exceptions/Patron/Attribute.pm
@@ -0,0 +1,20 @@
+package Koha::Exceptions::Patron::Attribute;
+
+use Modern::Perl;
+
+use Exception::Class (
+
+    'Koha::Exceptions::Patron::Attribute' => {
+        description => 'Something went wrong'
+    },
+    'Koha::Exceptions::Patron::Attribute::NonRepeatable' => {
+        isa => 'Koha::Exceptions::Patron::Attribute',
+        description => "repeatable not set for attribute type and tried to add a new attribute for the same code"
+    },
+    'Koha::Exceptions::Patron::Attribute::UniqueIDConstraint' => {
+        isa => 'Koha::Exceptions::Patron::Attribute',
+        description => "unique_id set for attribute type and tried to add a new with the same code and value"
+    }
+);
+
+1;
diff --git a/Koha/Patron/Attribute.pm b/Koha/Patron/Attribute.pm
index 7643536..fe62dfa 100644
--- a/Koha/Patron/Attribute.pm
+++ b/Koha/Patron/Attribute.pm
@@ -17,6 +17,8 @@ package Koha::Patron::Attribute;
 
 use Modern::Perl;
 
+use Koha::Database;
+use Koha::Exceptions::Patron::Attribute;
 use Koha::Patron::Attribute::Types;
 
 use base qw(Koha::Object);
@@ -31,6 +33,24 @@ Koha::Patron::Attribute - Koha Patron Attribute Object class
 
 =cut
 
+=head3 store
+
+    my $attribute = Koha::Patron::Attribute->new({ code => 'a_code', ... });
+    try { $attribute->store }
+    catch { handle_exception };
+
+=cut
+
+sub store {
+
+    my $self = shift;
+
+    $self->_check_repeatable;
+    $self->_check_unique_id;
+
+    return $self->SUPER::store();
+}
+
 =head3 opac_display
 
     my $attribute = Koha::Patron::Attribute->new({ code => 'a_code', ... });
@@ -59,6 +79,56 @@ sub opac_editable {
     return Koha::Patron::Attribute::Types->find( $self->code )->opac_editable;
 }
 
+=head2 Internal methods
+
+=head3 _check_repeatable
+
+_check_repeatable checks if the attribute type is repeatable and throws and exception
+if the attribute type isn't repeatable and there's already an attribute with the same
+code for the given patron.
+
+=cut
+
+sub _check_repeatable {
+
+    my $self = shift;
+
+    if ( !Koha::Patron::Attribute::Types->find( $self->code )->repeatable ) {
+        my $attr_count
+            = Koha::Database->new->schema->resultset( $self->_type )->search(
+            {   borrowernumber => $self->borrowernumber,
+                code           => $self->code
+            }
+            )->count;
+        Koha::Exceptions::Patron::Attribute::NonRepeatable->throw()
+            if $attr_count > 0;
+    }
+
+    return $self;
+}
+
+=head3 _check_unique_id
+
+_check_unique_id checks if the attribute type is marked as unique id and throws and exception
+if the attribute type is a unique id and there's already an attribute with the same
+code and value on the database.
+
+=cut
+
+sub _check_unique_id {
+
+    my $self = shift;
+
+    if ( Koha::Patron::Attribute::Types->find( $self->code )->unique_id ) {
+        my $unique_count
+            = Koha::Database->new->schema->resultset( $self->_type )
+            ->search( { code => $self->code, attribute => $self->attribute } )
+            ->count;
+        Koha::Exceptions::Patron::Attribute::UniqueIDConstraint->throw()
+            if $unique_count > 0;
+    }
+}
+
 =head3 _type
 
 =cut
-- 
2.9.3