| 
      
            Lines 43-71
          sub list {
      
      
        Link Here
      
     | 
  
        
          | 43 | 
              my $c = shift->openapi->valid_input or return;  | 
          43 | 
              my $c = shift->openapi->valid_input or return;  | 
        
        
          | 44 | 
           | 
          44 | 
           | 
        
        
          | 45 | 
              return try { | 
          45 | 
              return try { | 
        
          
            
              | 46 | 
                      my $attributes = {}; | 
              46 | 
               | 
            
            
               | 
               | 
              47 | 
                      my $patrons_rs = Koha::Patrons->new;  | 
            
        
          | 47 | 
                  my $args = $c->validation->output;  | 
          48 | 
                  my $args = $c->validation->output;  | 
        
          
            
              | 48 | 
                      my ( $params, $reserved_params ) = $c->extract_reserved_params( $args );  | 
              49 | 
                      my $attributes = {}; | 
            
            
               | 
               | 
              50 | 
               | 
            
            
              | 51 | 
                      # Extract reserved params  | 
            
            
              | 52 | 
                      my ( $filtered_params, $reserved_params ) = $c->extract_reserved_params($args);  | 
            
            
              | 53 | 
               | 
            
            
              | 54 | 
                      my $restricted = delete $filtered_params->{restricted}; | 
            
        
          | 49 | 
           | 
          55 | 
           | 
        
        
          | 50 | 
                  # Merge sorting into query attributes  | 
          56 | 
                  # Merge sorting into query attributes  | 
        
          
            
              | 51 | 
                      $c->dbic_merge_sorting({ attributes => $attributes, params => $reserved_params }); | 
              57 | 
                      $c->dbic_merge_sorting(  | 
            
            
               | 
               | 
              58 | 
                          { | 
            
            
              | 59 | 
                              attributes => $attributes,  | 
            
            
              | 60 | 
                              params     => $reserved_params,  | 
            
            
              | 61 | 
                              result_set => $patrons_rs  | 
            
            
              | 62 | 
                          }  | 
            
            
              | 63 | 
                      );  | 
            
        
          | 52 | 
           | 
          64 | 
           | 
        
        
          | 53 | 
                  # Merge pagination into query attributes  | 
          65 | 
                  # Merge pagination into query attributes  | 
        
          
            
              | 54 | 
                      $c->dbic_merge_pagination({ filter => $attributes, params => $reserved_params }); | 
              66 | 
                      $c->dbic_merge_pagination(  | 
            
            
               | 
               | 
              67 | 
                          { | 
            
            
              | 68 | 
                              filter => $attributes,  | 
            
            
              | 69 | 
                              params => $reserved_params  | 
            
            
              | 70 | 
                          }  | 
            
            
              | 71 | 
                      );  | 
            
        
          | 55 | 
           | 
          72 | 
           | 
        
          
            
              | 56 | 
                      my $restricted = $args->{restricted}; | 
              73 | 
                      if ( defined $filtered_params ) { | 
            
        
          | 57 | 
           | 
          74 | 
           | 
        
          
            
              | 58 | 
                      $params = _to_model($params)  | 
              75 | 
                          # Apply the mapping function to the passed params  | 
            
            
              | 59 | 
                          if defined $params;  | 
              76 | 
                          $filtered_params = $patrons_rs->attributes_from_api($filtered_params);  | 
            
            
              | 60 | 
                      # deal with string params  | 
              77 | 
                          $filtered_params = $c->build_query_params( $filtered_params, $reserved_params );  | 
            
            
              | 61 | 
                      $params = $c->build_query_params( $params, $reserved_params );  | 
              78 | 
                      }  | 
            
        
          | 62 | 
           | 
          79 | 
           | 
        
        
          | 63 | 
                  # translate 'restricted' => 'debarred'  | 
          80 | 
                  # translate 'restricted' => 'debarred'  | 
        
          
            
              | 64 | 
                      $params->{debarred} = { '!=' => undef } | 
              81 | 
                      $filtered_params->{debarred} = { '!=' => undef } | 
            
        
          | 65 | 
                    if $restricted;  | 
          82 | 
                    if $restricted;  | 
        
        
          | 66 | 
           | 
          83 | 
           | 
        
          
            
              | 67 | 
                      my $patrons = Koha::Patrons->search( $params, $attributes );  | 
              84 | 
                      my $patrons = $patrons_rs->search( $filtered_params, $attributes );  | 
            
            
              | 68 | 
                      if ( $patrons->is_paged ) { | 
              85 | 
                      if ( $patrons_rs->is_paged ) { | 
            
        
          | 69 | 
                      $c->add_pagination_headers(  | 
          86 | 
                      $c->add_pagination_headers(  | 
        
        
          | 70 | 
                          { | 
          87 | 
                          { | 
        
        
          | 71 | 
                              total  => $patrons->pager->total_entries,  | 
          88 | 
                              total  => $patrons->pager->total_entries,  | 
        
  
    | 
      
            Lines 132-137
          sub add {
      
      
        Link Here
      
     | 
  
        
          | 132 | 
                  );  | 
          149 | 
                  );  | 
        
        
          | 133 | 
              }  | 
          150 | 
              }  | 
        
        
          | 134 | 
              catch { | 
          151 | 
              catch { | 
        
            
               | 
               | 
              152 | 
               | 
            
            
              | 153 | 
                      my $to_api_mapping = Koha::Patron->new->to_api_mapping;  | 
            
            
              | 154 | 
               | 
            
        
          | 135 | 
                  unless ( blessed $_ && $_->can('rethrow') ) { | 
          155 | 
                  unless ( blessed $_ && $_->can('rethrow') ) { | 
        
        
          | 136 | 
                      return $c->render(  | 
          156 | 
                      return $c->render(  | 
        
        
          | 137 | 
                          status  => 500,  | 
          157 | 
                          status  => 500,  | 
        
  
    | 
      
            Lines 149-155
          sub add {
      
      
        Link Here
      
     | 
  
        
          | 149 | 
                          status  => 400,  | 
          169 | 
                          status  => 400,  | 
        
        
          | 150 | 
                          openapi => { | 
          170 | 
                          openapi => { | 
        
        
          | 151 | 
                                    error => "Given "  | 
          171 | 
                                    error => "Given "  | 
        
          
            
              | 152 | 
                                      . $Koha::REST::V1::Patrons::to_api_mapping->{ $_->broken_fk } | 
              172 | 
                                      . $to_api_mapping->{ $_->broken_fk } | 
            
        
          | 153 | 
                                  . " does not exist"  | 
          173 | 
                                  . " does not exist"  | 
        
        
          | 154 | 
                          }  | 
          174 | 
                          }  | 
        
        
          | 155 | 
                      );  | 
          175 | 
                      );  | 
        
  
    | 
      
            Lines 159-165
          sub add {
      
      
        Link Here
      
     | 
  
        
          | 159 | 
                          status  => 400,  | 
          179 | 
                          status  => 400,  | 
        
        
          | 160 | 
                          openapi => { | 
          180 | 
                          openapi => { | 
        
        
          | 161 | 
                                    error => "Given "  | 
          181 | 
                                    error => "Given "  | 
        
          
            
              | 162 | 
                                      . $Koha::REST::V1::Patrons::to_api_mapping->{ $_->parameter } | 
              182 | 
                                      . $to_api_mapping->{ $_->parameter } | 
            
        
          | 163 | 
                                  . " does not exist"  | 
          183 | 
                                  . " does not exist"  | 
        
        
          | 164 | 
                          }  | 
          184 | 
                          }  | 
        
        
          | 165 | 
                      );  | 
          185 | 
                      );  | 
        
  
    | 
      
            Lines 218-224
          sub update {
      
      
        Link Here
      
     | 
  
        
          | 218 | 
                      return $c->render(  | 
          238 | 
                      return $c->render(  | 
        
        
          | 219 | 
                          status  => 400,  | 
          239 | 
                          status  => 400,  | 
        
        
          | 220 | 
                          openapi => { error => "Given " . | 
          240 | 
                          openapi => { error => "Given " . | 
        
          
            
              | 221 | 
                                          $Koha::REST::V1::Patrons::to_api_mapping->{$_->broken_fk} | 
              241 | 
                                          $patron->to_api_mapping->{$_->broken_fk} | 
            
        
          | 222 | 
                                      . " does not exist" }  | 
          242 | 
                                      . " does not exist" }  | 
        
        
          | 223 | 
                      );  | 
          243 | 
                      );  | 
        
        
          | 224 | 
                  }  | 
          244 | 
                  }  | 
        
  
    | 
      
            Lines 379-577
          sub guarantors_can_see_checkouts {
      
      
        Link Here
      
     | 
  
        
          | 379 | 
              };  | 
          399 | 
              };  | 
        
        
          | 380 | 
          }  | 
          400 | 
          }  | 
        
        
          | 381 | 
           | 
          401 | 
           | 
        
            
              | 382 | 
              =head2 Internal methods  | 
               | 
               | 
            
            
              | 383 | 
               | 
            
            
              | 384 | 
              =head3 _to_api  | 
            
            
              | 385 | 
               | 
            
            
              | 386 | 
              Helper function that maps unblessed Koha::Patron objects into REST api  | 
            
            
              | 387 | 
              attribute names.  | 
            
            
              | 388 | 
               | 
            
            
              | 389 | 
              =cut  | 
            
            
              | 390 | 
               | 
            
            
              | 391 | 
              sub _to_api { | 
            
            
              | 392 | 
                  my $patron    = shift;  | 
            
            
              | 393 | 
                  my $patron_id = $patron->{ borrowernumber }; | 
            
            
              | 394 | 
               | 
            
            
              | 395 | 
                  # Rename attributes  | 
            
            
              | 396 | 
                  foreach my $column ( keys %{ $Koha::REST::V1::Patrons::to_api_mapping } ) { | 
            
            
              | 397 | 
                      my $mapped_column = $Koha::REST::V1::Patrons::to_api_mapping->{$column}; | 
            
            
              | 398 | 
                      if (    exists $patron->{ $column } | 
            
            
              | 399 | 
                           && defined $mapped_column )  | 
            
            
              | 400 | 
                      { | 
            
            
              | 401 | 
                          # key != undef  | 
            
            
              | 402 | 
                          $patron->{ $mapped_column } = delete $patron->{ $column }; | 
            
            
              | 403 | 
                      }  | 
            
            
              | 404 | 
                      elsif (    exists $patron->{ $column } | 
            
            
              | 405 | 
                              && !defined $mapped_column )  | 
            
            
              | 406 | 
                      { | 
            
            
              | 407 | 
                          # key == undef  | 
            
            
              | 408 | 
                          delete $patron->{ $column }; | 
            
            
              | 409 | 
                      }  | 
            
            
              | 410 | 
                  }  | 
            
            
              | 411 | 
               | 
            
            
              | 412 | 
                  # Calculate the 'restricted' field  | 
            
            
              | 413 | 
                  my $patron_obj = Koha::Patrons->find( $patron_id );  | 
            
            
              | 414 | 
                  $patron->{ restricted } = ($patron_obj->is_debarred) ? Mojo::JSON->true : Mojo::JSON->false; | 
            
            
              | 415 | 
               | 
            
            
              | 416 | 
                  return $patron;  | 
            
            
              | 417 | 
              }  | 
            
            
              | 418 | 
               | 
            
            
              | 419 | 
              =head3 _to_model  | 
            
            
              | 420 | 
               | 
            
            
              | 421 | 
              Helper function that maps REST api objects into Koha::Patron  | 
            
            
              | 422 | 
              attribute names.  | 
            
            
              | 423 | 
               | 
            
            
              | 424 | 
              =cut  | 
            
            
              | 425 | 
               | 
            
            
              | 426 | 
              sub _to_model { | 
            
            
              | 427 | 
                  my $patron = shift;  | 
            
            
              | 428 | 
               | 
            
            
              | 429 | 
                  foreach my $attribute ( keys %{ $Koha::REST::V1::Patrons::to_model_mapping } ) { | 
            
            
              | 430 | 
                      my $mapped_attribute = $Koha::REST::V1::Patrons::to_model_mapping->{$attribute}; | 
            
            
              | 431 | 
                      if (    exists $patron->{ $attribute } | 
            
            
              | 432 | 
                           && defined $mapped_attribute )  | 
            
            
              | 433 | 
                      { | 
            
            
              | 434 | 
                          # key => !undef  | 
            
            
              | 435 | 
                          $patron->{ $mapped_attribute } = delete $patron->{ $attribute }; | 
            
            
              | 436 | 
                      }  | 
            
            
              | 437 | 
                      elsif (    exists $patron->{ $attribute } | 
            
            
              | 438 | 
                              && !defined $mapped_attribute )  | 
            
            
              | 439 | 
                      { | 
            
            
              | 440 | 
                          # key => undef / to be deleted  | 
            
            
              | 441 | 
                          delete $patron->{ $attribute }; | 
            
            
              | 442 | 
                      }  | 
            
            
              | 443 | 
                  }  | 
            
            
              | 444 | 
               | 
            
            
              | 445 | 
                  # TODO: Get rid of this once write operations are based on Koha::Patron  | 
            
            
              | 446 | 
                  if ( exists $patron->{lost} ) { | 
            
            
              | 447 | 
                      $patron->{lost} = ($patron->{lost}) ? 1 : 0; | 
            
            
              | 448 | 
                  }  | 
            
            
              | 449 | 
               | 
            
            
              | 450 | 
                  if ( exists $patron->{ gonenoaddress} ) { | 
            
            
              | 451 | 
                      $patron->{gonenoaddress} = ($patron->{gonenoaddress}) ? 1 : 0; | 
            
            
              | 452 | 
                  }  | 
            
            
              | 453 | 
               | 
            
            
              | 454 | 
                  if ( exists $patron->{lastseen} ) { | 
            
            
              | 455 | 
                      $patron->{lastseen} = output_pref({ str => $patron->{lastseen}, dateformat => 'sql' }); | 
            
            
              | 456 | 
                  }  | 
            
            
              | 457 | 
               | 
            
            
              | 458 | 
                  if ( exists $patron->{updated_on} ) { | 
            
            
              | 459 | 
                      $patron->{updated_on} = output_pref({ str => $patron->{updated_on}, dateformat => 'sql' }); | 
            
            
              | 460 | 
                  }  | 
            
            
              | 461 | 
               | 
            
            
              | 462 | 
                  return $patron;  | 
            
            
              | 463 | 
              }  | 
            
            
              | 464 | 
               | 
            
            
              | 465 | 
              =head2 Global variables  | 
            
            
              | 466 | 
               | 
            
            
              | 467 | 
              =head3 $to_api_mapping  | 
            
            
              | 468 | 
               | 
            
            
              | 469 | 
              =cut  | 
            
            
              | 470 | 
               | 
            
            
              | 471 | 
              our $to_api_mapping = { | 
            
            
              | 472 | 
                  borrowernotes       => 'staff_notes',  | 
            
            
              | 473 | 
                  borrowernumber      => 'patron_id',  | 
            
            
              | 474 | 
                  branchcode          => 'library_id',  | 
            
            
              | 475 | 
                  categorycode        => 'category_id',  | 
            
            
              | 476 | 
                  checkprevcheckout   => 'check_previous_checkout',  | 
            
            
              | 477 | 
                  contactfirstname    => undef, # Unused  | 
            
            
              | 478 | 
                  contactname         => undef, # Unused  | 
            
            
              | 479 | 
                  contactnote         => 'altaddress_notes',  | 
            
            
              | 480 | 
                  contacttitle        => undef, # Unused  | 
            
            
              | 481 | 
                  dateenrolled        => 'date_enrolled',  | 
            
            
              | 482 | 
                  dateexpiry          => 'expiry_date',  | 
            
            
              | 483 | 
                  dateofbirth         => 'date_of_birth',  | 
            
            
              | 484 | 
                  debarred            => undef, # replaced by 'restricted'  | 
            
            
              | 485 | 
                  debarredcomment     => undef, # calculated, API consumers will use /restrictions instead  | 
            
            
              | 486 | 
                  emailpro            => 'secondary_email',  | 
            
            
              | 487 | 
                  flags               => undef, # permissions manipulation handled in /permissions  | 
            
            
              | 488 | 
                  gonenoaddress       => 'incorrect_address',  | 
            
            
              | 489 | 
                  guarantorid         => 'guarantor_id',  | 
            
            
              | 490 | 
                  lastseen            => 'last_seen',  | 
            
            
              | 491 | 
                  lost                => 'patron_card_lost',  | 
            
            
              | 492 | 
                  opacnote            => 'opac_notes',  | 
            
            
              | 493 | 
                  othernames          => 'other_name',  | 
            
            
              | 494 | 
                  password            => undef, # password manipulation handled in /password  | 
            
            
              | 495 | 
                  phonepro            => 'secondary_phone',  | 
            
            
              | 496 | 
                  relationship        => 'relationship_type',  | 
            
            
              | 497 | 
                  sex                 => 'gender',  | 
            
            
              | 498 | 
                  smsalertnumber      => 'sms_number',  | 
            
            
              | 499 | 
                  sort1               => 'statistics_1',  | 
            
            
              | 500 | 
                  sort2               => 'statistics_2',  | 
            
            
              | 501 | 
                  streetnumber        => 'street_number',  | 
            
            
              | 502 | 
                  streettype          => 'street_type',  | 
            
            
              | 503 | 
                  zipcode             => 'postal_code',  | 
            
            
              | 504 | 
                  B_address           => 'altaddress_address',  | 
            
            
              | 505 | 
                  B_address2          => 'altaddress_address2',  | 
            
            
              | 506 | 
                  B_city              => 'altaddress_city',  | 
            
            
              | 507 | 
                  B_country           => 'altaddress_country',  | 
            
            
              | 508 | 
                  B_email             => 'altaddress_email',  | 
            
            
              | 509 | 
                  B_phone             => 'altaddress_phone',  | 
            
            
              | 510 | 
                  B_state             => 'altaddress_state',  | 
            
            
              | 511 | 
                  B_streetnumber      => 'altaddress_street_number',  | 
            
            
              | 512 | 
                  B_streettype        => 'altaddress_street_type',  | 
            
            
              | 513 | 
                  B_zipcode           => 'altaddress_postal_code',  | 
            
            
              | 514 | 
                  altcontactaddress1  => 'altcontact_address',  | 
            
            
              | 515 | 
                  altcontactaddress2  => 'altcontact_address2',  | 
            
            
              | 516 | 
                  altcontactaddress3  => 'altcontact_city',  | 
            
            
              | 517 | 
                  altcontactcountry   => 'altcontact_country',  | 
            
            
              | 518 | 
                  altcontactfirstname => 'altcontact_firstname',  | 
            
            
              | 519 | 
                  altcontactphone     => 'altcontact_phone',  | 
            
            
              | 520 | 
                  altcontactsurname   => 'altcontact_surname',  | 
            
            
              | 521 | 
                  altcontactstate     => 'altcontact_state',  | 
            
            
              | 522 | 
                  altcontactzipcode   => 'altcontact_postal_code'  | 
            
            
              | 523 | 
              };  | 
            
            
              | 524 | 
               | 
            
            
              | 525 | 
              =head3 $to_model_mapping  | 
            
            
              | 526 | 
               | 
            
            
              | 527 | 
              =cut  | 
            
            
              | 528 | 
               | 
            
            
              | 529 | 
              our $to_model_mapping = { | 
            
            
              | 530 | 
                  altaddress_notes         => 'contactnote',  | 
            
            
              | 531 | 
                  category_id              => 'categorycode',  | 
            
            
              | 532 | 
                  check_previous_checkout  => 'checkprevcheckout',  | 
            
            
              | 533 | 
                  date_enrolled            => 'dateenrolled',  | 
            
            
              | 534 | 
                  date_of_birth            => 'dateofbirth',  | 
            
            
              | 535 | 
                  expiry_date              => 'dateexpiry',  | 
            
            
              | 536 | 
                  gender                   => 'sex',  | 
            
            
              | 537 | 
                  guarantor_id             => 'guarantorid',  | 
            
            
              | 538 | 
                  incorrect_address        => 'gonenoaddress',  | 
            
            
              | 539 | 
                  last_seen                => 'lastseen',  | 
            
            
              | 540 | 
                  library_id               => 'branchcode',  | 
            
            
              | 541 | 
                  opac_notes               => 'opacnote',  | 
            
            
              | 542 | 
                  other_name               => 'othernames',  | 
            
            
              | 543 | 
                  patron_card_lost         => 'lost',  | 
            
            
              | 544 | 
                  patron_id                => 'borrowernumber',  | 
            
            
              | 545 | 
                  postal_code              => 'zipcode',  | 
            
            
              | 546 | 
                  relationship_type        => 'relationship',  | 
            
            
              | 547 | 
                  restricted               => undef,  | 
            
            
              | 548 | 
                  secondary_email          => 'emailpro',  | 
            
            
              | 549 | 
                  secondary_phone          => 'phonepro',  | 
            
            
              | 550 | 
                  sms_number               => 'smsalertnumber',  | 
            
            
              | 551 | 
                  staff_notes              => 'borrowernotes',  | 
            
            
              | 552 | 
                  statistics_1             => 'sort1',  | 
            
            
              | 553 | 
                  statistics_2             => 'sort2',  | 
            
            
              | 554 | 
                  street_number            => 'streetnumber',  | 
            
            
              | 555 | 
                  street_type              => 'streettype',  | 
            
            
              | 556 | 
                  altaddress_address       => 'B_address',  | 
            
            
              | 557 | 
                  altaddress_address2      => 'B_address2',  | 
            
            
              | 558 | 
                  altaddress_city          => 'B_city',  | 
            
            
              | 559 | 
                  altaddress_country       => 'B_country',  | 
            
            
              | 560 | 
                  altaddress_email         => 'B_email',  | 
            
            
              | 561 | 
                  altaddress_phone         => 'B_phone',  | 
            
            
              | 562 | 
                  altaddress_state         => 'B_state',  | 
            
            
              | 563 | 
                  altaddress_street_number => 'B_streetnumber',  | 
            
            
              | 564 | 
                  altaddress_street_type   => 'B_streettype',  | 
            
            
              | 565 | 
                  altaddress_postal_code   => 'B_zipcode',  | 
            
            
              | 566 | 
                  altcontact_firstname     => 'altcontactfirstname',  | 
            
            
              | 567 | 
                  altcontact_surname       => 'altcontactsurname',  | 
            
            
              | 568 | 
                  altcontact_address       => 'altcontactaddress1',  | 
            
            
              | 569 | 
                  altcontact_address2      => 'altcontactaddress2',  | 
            
            
              | 570 | 
                  altcontact_city          => 'altcontactaddress3',  | 
            
            
              | 571 | 
                  altcontact_state         => 'altcontactstate',  | 
            
            
              | 572 | 
                  altcontact_postal_code   => 'altcontactzipcode',  | 
            
            
              | 573 | 
                  altcontact_country       => 'altcontactcountry',  | 
            
            
              | 574 | 
                  altcontact_phone         => 'altcontactphone'  | 
            
            
              | 575 | 
              };  | 
            
            
              | 576 | 
               | 
            
        
          | 577 | 
          1;  | 
          402 | 
          1;  | 
        
            
              | 578 | 
              -   | 
               | 
               |