| 
      
            Line 0
          
      
      
        Link Here
      
     | 
  
            
               | 
               | 
              1 | 
              package Koha::REST::V1::Suggestions;  | 
            
            
              | 2 | 
               | 
            
            
              | 3 | 
              # This file is part of Koha.  | 
            
            
              | 4 | 
              #  | 
            
            
              | 5 | 
              # Koha is free software; you can redistribute it and/or modify it under the  | 
            
            
              | 6 | 
              # terms of the GNU General Public License as published by the Free Software  | 
            
            
              | 7 | 
              # Foundation; either version 3 of the License, or (at your option) any later  | 
            
            
              | 8 | 
              # version.  | 
            
            
              | 9 | 
              #  | 
            
            
              | 10 | 
              # Koha is distributed in the hope that it will be useful, but WITHOUT ANY  | 
            
            
              | 11 | 
              # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR  | 
            
            
              | 12 | 
              # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.  | 
            
            
              | 13 | 
              #  | 
            
            
              | 14 | 
              # You should have received a copy of the GNU General Public License along  | 
            
            
              | 15 | 
              # with Koha; if not, write to the Free Software Foundation, Inc.,  | 
            
            
              | 16 | 
              # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.  | 
            
            
              | 17 | 
               | 
            
            
              | 18 | 
              use Modern::Perl;  | 
            
            
              | 19 | 
               | 
            
            
              | 20 | 
              use Mojo::Base 'Mojolicious::Controller';  | 
            
            
              | 21 | 
               | 
            
            
              | 22 | 
              use C4::Auth qw( haspermission );  | 
            
            
              | 23 | 
              use C4::Context;  | 
            
            
              | 24 | 
              use C4::Koha;  | 
            
            
              | 25 | 
               | 
            
            
              | 26 | 
              use Koha::Suggestion;  | 
            
            
              | 27 | 
              use Koha::Suggestions;  | 
            
            
              | 28 | 
               | 
            
            
              | 29 | 
              use Koha::ItemTypes;  | 
            
            
              | 30 | 
              use Koha::Libraries;  | 
            
            
              | 31 | 
               | 
            
            
              | 32 | 
              use Try::Tiny;  | 
            
            
              | 33 | 
               | 
            
            
              | 34 | 
              sub list { | 
            
            
              | 35 | 
                  my ($c, $args, $cb) = @_;  | 
            
            
              | 36 | 
               | 
            
            
              | 37 | 
                  my $suggestions;  | 
            
            
              | 38 | 
                  my $filter;  | 
            
            
              | 39 | 
                  $args //= {}; | 
            
            
              | 40 | 
               | 
            
            
              | 41 | 
                  for my $filter_param ( keys %$args ) { | 
            
            
              | 42 | 
                      $filter->{$filter_param} = { LIKE => $args->{$filter_param} . '%' }; | 
            
            
              | 43 | 
                  }  | 
            
            
              | 44 | 
               | 
            
            
              | 45 | 
                  return try { | 
            
            
              | 46 | 
                      $suggestions = Koha::Suggestions->search($filter)->unblessed;  | 
            
            
              | 47 | 
                      return $c->$cb( $suggestions, 200 );  | 
            
            
              | 48 | 
                  }  | 
            
            
              | 49 | 
                  catch { | 
            
            
              | 50 | 
                      if ( $_->isa('DBIx::Class::Exception') ) { | 
            
            
              | 51 | 
                          return $c->$cb( { error => $_->{msg} }, 500 ); | 
            
            
              | 52 | 
                      }  | 
            
            
              | 53 | 
                      else { | 
            
            
              | 54 | 
                          return $c->$cb(  | 
            
            
              | 55 | 
                              { error => 'Something went wrong, check the logs.' }, 500 ); | 
            
            
              | 56 | 
                      }  | 
            
            
              | 57 | 
                  };  | 
            
            
              | 58 | 
              }  | 
            
            
              | 59 | 
               | 
            
            
              | 60 | 
              sub get { | 
            
            
              | 61 | 
                  my ($c, $args, $cb) = @_;  | 
            
            
              | 62 | 
               | 
            
            
              | 63 | 
                  my $suggestion = Koha::Suggestions->find($args->{suggestionid}); | 
            
            
              | 64 | 
                  unless ($suggestion) { | 
            
            
              | 65 | 
                      return $c->$cb({error => 'Suggestion not found'}, 404); | 
            
            
              | 66 | 
                  }  | 
            
            
              | 67 | 
               | 
            
            
              | 68 | 
                  return $c->$cb($suggestion->unblessed, 200);  | 
            
            
              | 69 | 
              }  | 
            
            
              | 70 | 
               | 
            
            
              | 71 | 
              sub add { | 
            
            
              | 72 | 
                  my ( $c, $args, $cb ) = @_;  | 
            
            
              | 73 | 
               | 
            
            
              | 74 | 
                  my $error = _validate_body($c, $args, $cb, 0);  | 
            
            
              | 75 | 
                  return $error if $error;  | 
            
            
              | 76 | 
               | 
            
            
              | 77 | 
                  my $suggestion = Koha::Suggestion->new( $args->{body} ); | 
            
            
              | 78 | 
               | 
            
            
              | 79 | 
                  return try { | 
            
            
              | 80 | 
                      $suggestion->store;  | 
            
            
              | 81 | 
                      return $c->$cb( $suggestion->unblessed, 200 );  | 
            
            
              | 82 | 
                  }  | 
            
            
              | 83 | 
                  catch { | 
            
            
              | 84 | 
                      if ( $_->isa('DBIx::Class::Exception') ) { | 
            
            
              | 85 | 
                          return $c->$cb( { error => $_->msg }, 500 ); | 
            
            
              | 86 | 
                      }  | 
            
            
              | 87 | 
                      else { | 
            
            
              | 88 | 
                          return $c->$cb(  | 
            
            
              | 89 | 
                              { error => 'Something went wrong, check the logs.' }, 500 ); | 
            
            
              | 90 | 
                      }  | 
            
            
              | 91 | 
                  };  | 
            
            
              | 92 | 
              }  | 
            
            
              | 93 | 
               | 
            
            
              | 94 | 
              sub update { | 
            
            
              | 95 | 
                  my ( $c, $args, $cb ) = @_;  | 
            
            
              | 96 | 
               | 
            
            
              | 97 | 
                  my $suggestion;  | 
            
            
              | 98 | 
               | 
            
            
              | 99 | 
                  return try { | 
            
            
              | 100 | 
               | 
            
            
              | 101 | 
                      $suggestion = Koha::Suggestions->find( $args->{suggestionid} ); | 
            
            
              | 102 | 
               | 
            
            
              | 103 | 
                      my $body = $args->{body}; | 
            
            
              | 104 | 
               | 
            
            
              | 105 | 
                      # Remove unchaned fields so that we can use our body validation from the add subroutine  | 
            
            
              | 106 | 
                      foreach my $param ( keys %{ $body } ) { | 
            
            
              | 107 | 
                          if (exists $body->{$param}) { | 
            
            
              | 108 | 
                              delete $body->{$param} if $body->{$param} eq $suggestion->unblessed->{$param}; | 
            
            
              | 109 | 
                          }  | 
            
            
              | 110 | 
                      }  | 
            
            
              | 111 | 
               | 
            
            
              | 112 | 
                      my $error = _validate_body($c, $args, $cb, 1);  | 
            
            
              | 113 | 
                      return $error if $error;  | 
            
            
              | 114 | 
               | 
            
            
              | 115 | 
                      $suggestion->set( $body );  | 
            
            
              | 116 | 
                      $suggestion->store();  | 
            
            
              | 117 | 
                      return $c->$cb( $suggestion->unblessed, 200 );  | 
            
            
              | 118 | 
                  }  | 
            
            
              | 119 | 
                  catch { | 
            
            
              | 120 | 
                      if ( not defined $suggestion ) { | 
            
            
              | 121 | 
                          return $c->$cb( { error => 'Object not found' }, 404 ); | 
            
            
              | 122 | 
                      }  | 
            
            
              | 123 | 
                      elsif ( $_->isa('Koha::Exceptions::Object') ) { | 
            
            
              | 124 | 
                          return $c->$cb( { error => $_->message }, 500 ); | 
            
            
              | 125 | 
                      }  | 
            
            
              | 126 | 
                      else { | 
            
            
              | 127 | 
                          return $c->$cb(  | 
            
            
              | 128 | 
                              { error => 'Something went wrong, check the logs.' }, 500 ); | 
            
            
              | 129 | 
                      }  | 
            
            
              | 130 | 
                  };  | 
            
            
              | 131 | 
               | 
            
            
              | 132 | 
              }  | 
            
            
              | 133 | 
               | 
            
            
              | 134 | 
              sub delete { | 
            
            
              | 135 | 
                  my ( $c, $args, $cb ) = @_;  | 
            
            
              | 136 | 
               | 
            
            
              | 137 | 
                  my $suggestion;  | 
            
            
              | 138 | 
               | 
            
            
              | 139 | 
                  return try { | 
            
            
              | 140 | 
                      $suggestion = Koha::Suggestions->find( $args->{suggestionid} ); | 
            
            
              | 141 | 
                      $suggestion->delete;  | 
            
            
              | 142 | 
                      return $c->$cb( '', 200 );  | 
            
            
              | 143 | 
                  }  | 
            
            
              | 144 | 
                  catch { | 
            
            
              | 145 | 
                      if ( not defined $suggestion ) { | 
            
            
              | 146 | 
                          return $c->$cb( { error => 'Object not found' }, 404 ); | 
            
            
              | 147 | 
                      }  | 
            
            
              | 148 | 
                      elsif ( $_->isa('DBIx::Class::Exception') ) { | 
            
            
              | 149 | 
                          return $c->$cb( { error => $_->msg }, 500 ); | 
            
            
              | 150 | 
                      }  | 
            
            
              | 151 | 
                      else { | 
            
            
              | 152 | 
                          return $c->$cb(  | 
            
            
              | 153 | 
                              { error => 'Something went wrong, check the logs.' }, 500 ); | 
            
            
              | 154 | 
                      }  | 
            
            
              | 155 | 
                  };  | 
            
            
              | 156 | 
               | 
            
            
              | 157 | 
              }  | 
            
            
              | 158 | 
               | 
            
            
              | 159 | 
              sub _validate_body { | 
            
            
              | 160 | 
                  my ( $c, $args, $cb, $updating ) = @_;  | 
            
            
              | 161 | 
               | 
            
            
              | 162 | 
                  my $body = $args->{body}; | 
            
            
              | 163 | 
                  my $user = $c->stash('koha.user'); | 
            
            
              | 164 | 
               | 
            
            
              | 165 | 
                  my $has_acquisition = C4::Auth::haspermission($user->userid, {acquisition => 1}); | 
            
            
              | 166 | 
               | 
            
            
              | 167 | 
                  if (not $has_acquisition) { | 
            
            
              | 168 | 
                      # Regular user cannot change anything ...  | 
            
            
              | 169 | 
                      my @allowed_fields = ('suggestedby', 'title', 'author', 'copyrightdate', 'isbn', | 
            
            
              | 170 | 
                          'publishercode', 'collectiontitle', 'place', 'itemtype', 'patronreason', 'note');  | 
            
            
              | 171 | 
               | 
            
            
              | 172 | 
                      # Hmm, how about branches?  | 
            
            
              | 173 | 
                      if ( C4::Context->preference('AllowPurchaseSuggestionBranchChoice') ) { | 
            
            
              | 174 | 
                          push(@allowed_fields, 'branchcode');  | 
            
            
              | 175 | 
                      }  | 
            
            
              | 176 | 
               | 
            
            
              | 177 | 
                      foreach my $param ( keys %{ $body } ) { | 
            
            
              | 178 | 
                          unless (/^$param$/ ~~ @allowed_fields) { | 
            
            
              | 179 | 
                              # Ouch ! Some mandatory field is missing!  | 
            
            
              | 180 | 
                              my $verb = $updating ? 'updated ' : 'specified ';  | 
            
            
              | 181 | 
                              return $c->$cb({error => 'You ' . $verb . $param . ', but allowed fields are only ' . | 
            
            
              | 182 | 
                                      join(', ', @allowed_fields)}, 403); | 
            
            
              | 183 | 
                          }  | 
            
            
              | 184 | 
                      }  | 
            
            
              | 185 | 
                  }  | 
            
            
              | 186 | 
               | 
            
            
              | 187 | 
                  if (not $updating) { | 
            
            
              | 188 | 
                      # Check for missing fields  | 
            
            
              | 189 | 
                      my @mandatory_fields = split /,/, C4::Context->preference('OPACSuggestionMandatoryFields'); | 
            
            
              | 190 | 
                      my @missing_fields = ();  | 
            
            
              | 191 | 
                      for my $mandatory_field (@mandatory_fields) { | 
            
            
              | 192 | 
                          push(@missing_fields, $mandatory_field) if (not exists $body->{$mandatory_field}); | 
            
            
              | 193 | 
                      }  | 
            
            
              | 194 | 
               | 
            
            
              | 195 | 
                      if ( @missing_fields ) { | 
            
            
              | 196 | 
                          return $c->$cb({error => 'Missing mandatory fields: ' . join(', ', @missing_fields)}, 400); | 
            
            
              | 197 | 
                      }  | 
            
            
              | 198 | 
                  }  | 
            
            
              | 199 | 
               | 
            
            
              | 200 | 
                  # Is suggester anonymous?  | 
            
            
              | 201 | 
                  my $is_anonymous = not (defined $body->{suggestedby} and | 
            
            
              | 202 | 
                      $body->{suggestedby} ne '' and | 
            
            
              | 203 | 
                      $body->{suggestedby} ne C4::Context->preference('AnonymousPatron')); | 
            
            
              | 204 | 
               | 
            
            
              | 205 | 
                  # Refuse if are anonymous suggestions disabled  | 
            
            
              | 206 | 
                  if ( $is_anonymous ) { | 
            
            
              | 207 | 
                      return $c->$cb({error => 'Anonymous suggestions are disabled'}, 403) | 
            
            
              | 208 | 
                      unless C4::Context->preference('AnonSuggestions'); | 
            
            
              | 209 | 
                  }  | 
            
            
              | 210 | 
               | 
            
            
              | 211 | 
                  # Refuse adding another suggestion if max reached for a user  | 
            
            
              | 212 | 
                  my $max_open_suggestions = C4::Context->preference('MaxOpenSuggestions'); | 
            
            
              | 213 | 
                  if ( $max_open_suggestions gt 0 and not $is_anonymous ) { | 
            
            
              | 214 | 
                      my $count = Koha::Suggestions->search({suggestedby => $body->{suggestedby}})->count(); | 
            
            
              | 215 | 
               | 
            
            
              | 216 | 
                      return $c->$cb({error =>  | 
            
            
              | 217 | 
                              'You have ' . $count . ' opened suggestions out of ' . $max_open_suggestions}, 403)  | 
            
            
              | 218 | 
                      if ( $count >= $max_open_suggestions );  | 
            
            
              | 219 | 
                  }  | 
            
            
              | 220 | 
               | 
            
            
              | 221 | 
                  # Check STATUS is valid  | 
            
            
              | 222 | 
                  if ( exists $body->{STATUS} ) { | 
            
            
              | 223 | 
                      return $c->$cb({error => 'STATUS must be one of ASKED, CHECKED, ACCEPTED, or REJECTED'}, 400) | 
            
            
              | 224 | 
                      unless ($body->{STATUS} =~ m/^(ASKED|CHECKED|ACCEPTED|REJECTED)$/); | 
            
            
              | 225 | 
                  }  | 
            
            
              | 226 | 
               | 
            
            
              | 227 | 
                  # Check itemtype is valid  | 
            
            
              | 228 | 
                  if ( exists $body->{itemtype} ) { | 
            
            
              | 229 | 
                      my @item_types = map {$_->unblessed->{itemtype}} Koha::ItemTypes->search; | 
            
            
              | 230 | 
                      return $c->$cb({error => 'itemtype must be one of ' . join(', ', @item_types)}, 400) | 
            
            
              | 231 | 
                      unless /^$body->{itemtype}$/ ~~ @item_types; | 
            
            
              | 232 | 
                  }  | 
            
            
              | 233 | 
               | 
            
            
              | 234 | 
                  # Check branchcode is valid  | 
            
            
              | 235 | 
                  if ( exists $body->{branchcode} ) { | 
            
            
              | 236 | 
                      my @branch_codes = map {$_->unblessed->{branchcode}} Koha::Libraries->search; | 
            
            
              | 237 | 
                      return $c->$cb({error => 'branchcode must be one of ' . join(', ', @branch_codes)}, 400) | 
            
            
              | 238 | 
                      unless /^$body->{branchcode}$/ ~~ @branch_codes; | 
            
            
              | 239 | 
                  }  | 
            
            
              | 240 | 
               | 
            
            
              | 241 | 
                  # Check patron reason is valid  | 
            
            
              | 242 | 
                  if ( exists $body->{patronreason} ) { | 
            
            
              | 243 | 
                      my @authorized_values = map { $_->{authorised_value} } @{ C4::Koha::GetAuthorisedValues('OPAC_SUG') }; | 
            
            
              | 244 | 
                      return $c->$cb({error => 'patronreason must be one of ' . join(', ', @authorized_values)}, 400) | 
            
            
              | 245 | 
                      unless /^$body->{patronreason}$/ ~~ @authorized_values; | 
            
            
              | 246 | 
                  }  | 
            
            
              | 247 | 
               | 
            
            
              | 248 | 
                  # Check suggestedby patron exists  | 
            
            
              | 249 | 
                  if ( exists $body->{suggestedby} ) { | 
            
            
              | 250 | 
                      return $c->$cb({error => 'suggestedby patron not found'}, 400) | 
            
            
              | 251 | 
                      unless Koha::Patrons->find($body->{suggestedby}); | 
            
            
              | 252 | 
                  }  | 
            
            
              | 253 | 
               | 
            
            
              | 254 | 
                  # Check managedby patron exists  | 
            
            
              | 255 | 
                  if ( exists $body->{managedby} ) { | 
            
            
              | 256 | 
                      return $c->$cb({error => 'managedby patron not found'}, 400) | 
            
            
              | 257 | 
                      unless Koha::Patrons->find($body->{managedby}); | 
            
            
              | 258 | 
                  }  | 
            
            
              | 259 | 
               | 
            
            
              | 260 | 
                  # Everything's fine ..  | 
            
            
              | 261 | 
                  return 0;  | 
            
            
              | 262 | 
              }  | 
            
            
              | 263 | 
               | 
            
            
              | 264 | 
              1;  |