@@ -, +, @@ cookie). You must have permission updatecharges. without body where YYY is the accountlines_id you created in step 2. http://yourlibrary/api/v1/patrons/ZZZ/payment with body {"amount": 10} Replace ZZZ with the borrowernumber for which you have created two fines http://yourlibrary/api/v1/accountlines/YYY/payment with body {"amount": XXX} Replace YYY with the accountlines_id you created in step 8. Set amount (XXX) to the half of the amount of the fine you created in step 8. amount. t/db_dependent/api/v1/patrons.t --- Koha/REST/V1/Accountline.pm | 42 +++++++++++++++++++++++ Koha/REST/V1/Patron.pm | 38 +++++++++++++++++++++ api/v1/swagger/paths.json | 6 ++++ api/v1/swagger/paths/accountlines.json | 50 ++++++++++++++++++++++++++++ api/v1/swagger/paths/patrons.json | 50 ++++++++++++++++++++++++++++ api/v1/swagger/swagger.min.json | 2 +- t/db_dependent/api/v1/accountlines.t | 61 +++++++++++++++++++++++++++++++--- t/db_dependent/api/v1/patrons.t | 58 ++++++++++++++++++++++++++++++-- 8 files changed, 299 insertions(+), 8 deletions(-) --- a/Koha/REST/V1/Accountline.pm +++ a/Koha/REST/V1/Accountline.pm @@ -19,8 +19,11 @@ use Modern::Perl; use Mojo::Base 'Mojolicious::Controller'; +use Scalar::Util qw( looks_like_number ); + use C4::Auth qw( haspermission ); use Koha::Account::Lines; +use Koha::Account; sub list { my ($c, $args, $cb) = @_; @@ -58,4 +61,43 @@ sub edit { return $c->$cb($accountline->unblessed(), 200); } + +sub pay { + my ($c, $args, $cb) = @_; + + my $user = $c->stash('koha.user'); + unless ($user && haspermission($user->userid, {updatecharges => 1})) { + return $c->$cb({error => "You don't have the required permission"}, 403); + } + + my $accountline = Koha::Account::Lines->find($args->{accountlines_id}); + unless ($accountline) { + return $c->$cb({error => "Accountline not found"}, 404); + } + + my $body = $c->req->json; + my $amount = $body->{amount}; + my $note = $body->{note} || ''; + + if ($amount && !looks_like_number($amount)) { + return $c->$cb({error => "Invalid amount"}, 400); + } + + Koha::Account->new( + { + patron_id => $accountline->borrowernumber, + } + )->pay( + { + lines => [$accountline], + amount => $amount, + note => $note, + } + ); + + $accountline = Koha::Account::Lines->find($args->{accountlines_id}); + return $c->$cb($accountline->unblessed(), 200); +} + + 1; --- a/Koha/REST/V1/Patron.pm +++ a/Koha/REST/V1/Patron.pm @@ -19,8 +19,11 @@ use Modern::Perl; use Mojo::Base 'Mojolicious::Controller'; +use Scalar::Util qw( looks_like_number ); + use C4::Auth qw( haspermission ); use Koha::Patrons; +use Koha::Account; sub list { my ($c, $args, $cb) = @_; @@ -55,4 +58,39 @@ sub get { return $c->$cb($patron->unblessed, 200); } +sub pay { + my ($c, $args, $cb) = @_; + + my $user = $c->stash('koha.user'); + unless ($user && haspermission($user->userid, {updatecharges => 1})) { + return $c->$cb({error => "You don't have the required permission"}, 403); + } + + my $patron = Koha::Patrons->find($args->{borrowernumber}); + unless ($patron) { + return $c->$cb({error => "Patron not found"}, 404); + } + + my $body = $c->req->json; + my $amount = $body->{amount}; + my $note = $body->{note} || ''; + + unless ($amount && looks_like_number($amount)) { + return $c->$cb({error => "Invalid amount"}, 400); + } + + Koha::Account->new( + { + patron_id => $args->{borrowernumber}, + } + )->pay( + { + amount => $amount, + note => $note, + } + ); + + return $c->$cb('', 204); +} + 1; --- a/api/v1/swagger/paths.json +++ a/api/v1/swagger/paths.json @@ -5,6 +5,9 @@ "/accountlines/{accountlines_id}": { "$ref": "paths/accountlines.json#/~1accountlines~1{accountlines_id}" }, + "/accountlines/{accountlines_id}/payment": { + "$ref": "paths/accountlines.json#/~1accountlines~1{accountlines_id}~1payment" + }, "/holds": { "$ref": "paths/holds.json#/~1holds" }, @@ -16,5 +19,8 @@ }, "/patrons/{borrowernumber}": { "$ref": "paths/patrons.json#/~1patrons~1{borrowernumber}" + }, + "/patrons/{borrowernumber}/payment": { + "$ref": "paths/patrons.json#/~1patrons~1{borrowernumber}~1payment" } } --- a/api/v1/swagger/paths/accountlines.json +++ a/api/v1/swagger/paths/accountlines.json @@ -81,5 +81,55 @@ } } } + }, + "/accountlines/{accountlines_id}/payment": { + "post": { + "operationId": "payAccountlines", + "tags": ["accountlines"], + "produces": [ + "application/json" + ], + "parameters": [ + { "$ref": "../parameters.json#/accountlinesIdPathParam" }, + { + "name": "body", + "in": "body", + "description": "A JSON object containing fields to modify", + "schema": { + "type": "object", + "properties": { + "amount": { + "description": "Amount to pay" + }, + "note": { + "description": "Payment note" + } + } + } + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "responses": { + "200": { + "description": "Paid accountline", + "schema": { "$ref": "../definitions.json#/accountline" } + }, + "400": { + "description": "Missing or wrong parameters", + "schema": { "$ref": "../definitions.json#/error" } + }, + "403": { + "description": "Access forbidden", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Accountline not found", + "schema": { "$ref": "../definitions.json#/error" } + } + } + } } } --- a/api/v1/swagger/paths/patrons.json +++ a/api/v1/swagger/paths/patrons.json @@ -57,5 +57,55 @@ } } } + }, + "/patrons/{borrowernumber}/payment": { + "post": { + "operationId": "payForPatron", + "tags": ["accountlines"], + "produces": [ + "application/json" + ], + "parameters": [ + { "$ref": "../parameters.json#/borrowernumberPathParam" }, + { + "name": "body", + "in": "body", + "description": "A JSON object containing fields to modify", + "required": true, + "schema": { + "type": "object", + "properties": { + "amount": { + "description": "Amount to pay" + }, + "note": { + "description": "Payment note" + } + } + } + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "responses": { + "204": { + "description": "Success" + }, + "400": { + "description": "Missing or wrong parameters", + "schema": { "$ref": "../definitions.json#/error" } + }, + "403": { + "description": "Access forbidden", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Borrower not found", + "schema": { "$ref": "../definitions.json#/error" } + } + } + } } } --- a/api/v1/swagger/swagger.min.json +++ a/api/v1/swagger/swagger.min.json @@ -1, +1, @@ -{"swagger":"2.0","x-primitives":{"phone":{"type":["string","null"],"description":"primary phone number for patron's primary address"},"reserve_id":{"description":"Internal hold identifier"},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"email":{"description":"primary email address for patron's primary address","type":["string","null"]},"firstname":{"description":"patron's first name","type":["string","null"]},"cardnumber":{"description":"library assigned user identifier","type":["string","null"]},"surname":{"type":"string","description":"patron's last name"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"itemnumber":{"description":"internally assigned item identifier","type":["string","null"]}},"info":{"title":"Koha REST API","license":{"url":"http:\/\/www.gnu.org\/licenses\/gpl.txt","name":"GPL v3"},"contact":{"url":"http:\/\/koha-community.org\/","name":"Koha Team"},"version":"1"},"paths":{"\/patrons\/{borrowernumber}":{"get":{"responses":{"403":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}}},"description":"Access forbidden"},"200":{"schema":{"type":"object","properties":{"B_phone":{"type":["string","null"],"description":"phone number for patron's alternate address"},"dateexpiry":{"type":["string","null"],"description":"date the patron's card is set to expire"},"categorycode":{"type":"string","description":"code of patron's category"},"B_city":{"description":"city or town of patron's alternate address","type":["string","null"]},"initials":{"type":["string","null"],"description":"initials of the patron"},"address2":{"type":["string","null"],"description":"second address line of patron's primary address"},"guarantorid":{"description":"borrowernumber used for children or professionals to link them to guarantor or organizations","type":["string","null"]},"checkprevcheckout":{"type":"string","description":"produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'"},"altcontactstate":{"type":["string","null"],"description":"the state for the alternate contact for the patron"},"emailpro":{"type":["string","null"],"description":"secondary email address for patron's primary address"},"contactname":{"type":["string","null"],"description":"used for children and professionals to include surname or last name of guarantor or organization name"},"sort1":{"description":"a field that can be used for any information unique to the library","type":["string","null"]},"B_address2":{"type":["string","null"],"description":"second address line of patron's alternate address"},"gonenoaddress":{"description":"set to 1 if library marked this patron as having an unconfirmed address","type":["string","null"]},"cardnumber":{"type":["string","null"],"description":"library assigned user identifier"},"altcontactphone":{"description":"the phone number for the alternate contact for the patron","type":["string","null"]},"altcontactaddress3":{"type":["string","null"],"description":"the city for the alternate contact for the patron"},"B_email":{"description":"email address for patron's alternate address","type":["string","null"]},"altcontactzipcode":{"type":["string","null"],"description":"the zipcode for the alternate contact for the patron"},"zipcode":{"type":["string","null"],"description":"zip or postal code of patron's primary address"},"dateofbirth":{"description":"patron's date of birth","type":["string","null"]},"state":{"description":"state or province of patron's primary address","type":["string","null"]},"privacy_guarantor_checkouts":{"description":"controls if relatives can see this patron's checkouts","type":"string"},"fax":{"description":"fax number for patron's primary address","type":["string","null"]},"updated_on":{"description":"time of last change could be useful for synchronization with external systems (among others)","type":"string"},"contactfirstname":{"type":["string","null"],"description":"used for children to include first name of guarantor"},"contacttitle":{"description":"used for children to include title of guarantor","type":["string","null"]},"sex":{"type":["string","null"],"description":"patron's gender"},"B_streetnumber":{"description":"street number of patron's alternate address","type":["string","null"]},"contactnote":{"description":"a note related to patron's alternate address","type":["string","null"]},"mobile":{"description":"the other phone number for patron's primary address","type":["string","null"]},"othernames":{"type":["string","null"],"description":"any other names associated with the patron"},"lost":{"type":["string","null"],"description":"set to 1 if library marked this patron as having lost his card"},"B_state":{"description":"state or province of patron's alternate address","type":["string","null"]},"streetnumber":{"type":["string","null"],"description":"street number of patron's primary address"},"borrowernotes":{"type":["string","null"],"description":"a note on the patron's account"},"phonepro":{"type":["string","null"],"description":"secondary phone number for patron's primary address"},"country":{"description":"country of patron's primary address","type":["string","null"]},"altcontactaddress2":{"type":["string","null"],"description":"the second address line for the alternate contact for the patron"},"streettype":{"type":["string","null"],"description":"street type of patron's primary address"},"title":{"type":["string","null"],"description":"patron's title"},"password":{"type":["string","null"],"description":"patron's encrypted password"},"city":{"description":"city or town of patron's primary address","type":"string"},"relationship":{"type":["string","null"],"description":"used for children to include the relationship to their guarantor"},"firstname":{"description":"patron's first name","type":["string","null"]},"altcontactcountry":{"description":"the country for the alternate contact for the patron","type":["string","null"]},"email":{"description":"primary email address for patron's primary address","type":["string","null"]},"phone":{"description":"primary phone number for patron's primary address","type":["string","null"]},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"debarred":{"description":"until this date the patron can only check-in","type":["string","null"]},"privacy":{"type":"string","description":"patron's privacy settings related to their reading history"},"altcontactsurname":{"type":["string","null"],"description":"surname or last name of the alternate contact for the patron"},"sort2":{"description":"a field that can be used for any information unique to the library","type":["string","null"]},"userid":{"type":["string","null"],"description":"patron's login"},"surname":{"type":"string","description":"patron's last name"},"B_zipcode":{"description":"zip or postal code of patron's alternate address","type":["string","null"]},"altcontactaddress1":{"description":"the first address line for the alternate contact for the patron","type":["string","null"]},"sms_provider_id":{"description":"the provider of the mobile phone number defined in smsalertnumber","type":["string","null"]},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"address":{"description":"first address line of patron's primary address","type":"string"},"altcontactfirstname":{"type":["string","null"],"description":"first name of alternate contact for the patron"},"opacnote":{"description":"a note on the patron's account visible in OPAC and staff client","type":["string","null"]},"flags":{"type":["string","null"],"description":"a number associated with the patron's permissions"},"dateenrolled":{"type":["string","null"],"description":"date the patron was added to Koha"},"B_country":{"description":"country of patron's alternate address","type":["string","null"]},"B_streettype":{"description":"street type of patron's alternate address","type":["string","null"]},"debarredcomment":{"type":["string","null"],"description":"comment on the stop of the patron"},"B_address":{"description":"first address line of patron's alternate address","type":["string","null"]},"smsalertnumber":{"type":["string","null"],"description":"the mobile phone number where the patron would like to receive notices (if SMS turned on)"}}},"description":"A patron"},"404":{"description":"Patron not found","schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}}}}},"operationId":"getPatron","parameters":[{"name":"borrowernumber","in":"path","required":true,"description":"Internal patron identifier","type":"integer"}],"produces":["application\/json"],"tags":["patrons"]}},"\/holds":{"post":{"produces":["application\/json"],"consumes":["application\/json"],"operationId":"addHold","parameters":[{"name":"body","schema":{"type":"object","properties":{"expirationdate":{"format":"date","description":"Hold end date","type":"string"},"branchcode":{"type":"string","description":"Pickup location"},"biblionumber":{"description":"Biblio internal identifier","type":"integer"},"borrowernumber":{"type":"integer","description":"Borrower internal identifier"},"itemnumber":{"description":"Item internal identifier","type":"integer"}}},"required":true,"in":"body","description":"A JSON object containing informations about the new hold"}],"responses":{"403":{"schema":{"properties":{"error":{"type":"string","description":"Error message"}},"type":"object"},"description":"Hold not allowed"},"400":{"description":"Missing or wrong parameters","schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}}}},"500":{"description":"Internal error","schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}}}},"404":{"schema":{"properties":{"error":{"type":"string","description":"Error message"}},"type":"object"},"description":"Borrower not found"},"201":{"description":"Created hold","schema":{"properties":{"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"reserve_id":{"description":"Internal hold identifier"},"reservedate":{"description":"the date the hold was placed"},"suspend_until":{"description":""},"notificationdate":{"description":"currently unused"},"cancellationdate":{"description":"the date the hold was cancelled"},"itemnumber":{"description":"internally assigned item identifier","type":["string","null"]},"suspend":{"description":""},"reservenotes":{"description":"notes related to this hold"},"itemtype":{"type":["string","null"],"description":"If record level hold, the optional itemtype of the item the patron is requesting"},"timestamp":{"description":"date and time the hold was last updated"},"branchcode":{"type":["string","null"],"description":"code of patron's home branch"},"expirationdate":{"description":"the date the hold expires"},"priority":{"description":"where in the queue the patron sits"},"reminderdate":{"description":"currently unused"},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"lowestPriority":{"description":""}},"type":"object"}}},"tags":["borrowers","holds"]},"get":{"responses":{"404":{"schema":{"properties":{"error":{"type":"string","description":"Error message"}},"type":"object"},"description":"Borrower not found"},"200":{"description":"A list of holds","schema":{"type":"array","items":{"properties":{"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"reserve_id":{"description":"Internal hold identifier"},"reservedate":{"description":"the date the hold was placed"},"suspend_until":{"description":""},"notificationdate":{"description":"currently unused"},"cancellationdate":{"description":"the date the hold was cancelled"},"itemnumber":{"description":"internally assigned item identifier","type":["string","null"]},"suspend":{"description":""},"reservenotes":{"description":"notes related to this hold"},"itemtype":{"type":["string","null"],"description":"If record level hold, the optional itemtype of the item the patron is requesting"},"timestamp":{"description":"date and time the hold was last updated"},"branchcode":{"type":["string","null"],"description":"code of patron's home branch"},"expirationdate":{"description":"the date the hold expires"},"priority":{"description":"where in the queue the patron sits"},"reminderdate":{"description":"currently unused"},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"lowestPriority":{"description":""}},"type":"object"}}}},"operationId":"listHolds","parameters":[{"name":"reserve_id","in":"query","type":"integer","description":"Internal reserve identifier"},{"name":"borrowernumber","in":"query","description":"Internal borrower identifier","type":"integer"},{"name":"reservedate","in":"query","description":"Reserve date","type":"string"},{"name":"biblionumber","in":"query","description":"Internal biblio identifier","type":"integer"},{"name":"branchcode","in":"query","description":"Branch code","type":"string"},{"description":"Notification date","type":"string","in":"query","name":"notificationdate"},{"name":"reminderdate","description":"Reminder date","type":"string","in":"query"},{"name":"cancellationdate","in":"query","description":"Cancellation date","type":"string"},{"in":"query","type":"string","description":"Reserve notes","name":"reservenotes"},{"type":"integer","description":"Priority","in":"query","name":"priority"},{"name":"found","type":"string","description":"Found status","in":"query"},{"in":"query","type":"string","description":"Time of latest update","name":"timestamp"},{"type":"integer","description":"Internal item identifier","in":"query","name":"itemnumber"},{"description":"Date the item was marked as waiting for the patron","type":"string","in":"query","name":"waitingdate"},{"in":"query","type":"string","description":"Date the hold expires","name":"expirationdate"},{"name":"lowestPriority","description":"Lowest priority","type":"integer","in":"query"},{"type":"integer","description":"Suspended","in":"query","name":"suspend"},{"name":"suspend_until","in":"query","description":"Suspended until","type":"string"}],"produces":["application\/json"],"tags":["borrowers","holds"]}},"\/accountlines":{"get":{"responses":{"200":{"description":"A list of accountlines","schema":{"items":{"type":"object","properties":{"note":{"description":"Accountline note"},"accountno":{"description":"?"},"accountlines_id":{"description":"Internal account line identifier"},"date":{"description":"Date when the account line was created"},"itemnumber":{"description":"Internal item identifier"},"accounttype":{"description":"Type of accountline"},"notify_level":{"description":"?"},"timestamp":{"description":"When the account line was last updated"},"amount":{"description":"Amount"},"borrowernumber":{"description":"Internal borrower identifier"},"time":{"description":"Time when the account line was created"},"meansofpayment":{"description":"Means of payment"},"description":{"description":"Description of account line"},"amountoutstanding":{"description":"Amount outstanding"},"notify_id":{"description":"?"},"manager_id":{"description":"Borrowernumber of user that created the account line"},"lastincrement":{"description":"?"}}},"type":"array"}},"403":{"schema":{"properties":{"error":{"type":"string","description":"Error message"}},"type":"object"},"description":"Access forbidden"}},"produces":["application\/json"],"operationId":"listAccountlines","tags":["accountlines"]}},"\/patrons":{"get":{"responses":{"200":{"schema":{"type":"array","items":{"type":"object","properties":{"B_phone":{"type":["string","null"],"description":"phone number for patron's alternate address"},"dateexpiry":{"type":["string","null"],"description":"date the patron's card is set to expire"},"categorycode":{"type":"string","description":"code of patron's category"},"B_city":{"description":"city or town of patron's alternate address","type":["string","null"]},"initials":{"type":["string","null"],"description":"initials of the patron"},"address2":{"type":["string","null"],"description":"second address line of patron's primary address"},"guarantorid":{"description":"borrowernumber used for children or professionals to link them to guarantor or organizations","type":["string","null"]},"checkprevcheckout":{"type":"string","description":"produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'"},"altcontactstate":{"type":["string","null"],"description":"the state for the alternate contact for the patron"},"emailpro":{"type":["string","null"],"description":"secondary email address for patron's primary address"},"contactname":{"type":["string","null"],"description":"used for children and professionals to include surname or last name of guarantor or organization name"},"sort1":{"description":"a field that can be used for any information unique to the library","type":["string","null"]},"B_address2":{"type":["string","null"],"description":"second address line of patron's alternate address"},"gonenoaddress":{"description":"set to 1 if library marked this patron as having an unconfirmed address","type":["string","null"]},"cardnumber":{"type":["string","null"],"description":"library assigned user identifier"},"altcontactphone":{"description":"the phone number for the alternate contact for the patron","type":["string","null"]},"altcontactaddress3":{"type":["string","null"],"description":"the city for the alternate contact for the patron"},"B_email":{"description":"email address for patron's alternate address","type":["string","null"]},"altcontactzipcode":{"type":["string","null"],"description":"the zipcode for the alternate contact for the patron"},"zipcode":{"type":["string","null"],"description":"zip or postal code of patron's primary address"},"dateofbirth":{"description":"patron's date of birth","type":["string","null"]},"state":{"description":"state or province of patron's primary address","type":["string","null"]},"privacy_guarantor_checkouts":{"description":"controls if relatives can see this patron's checkouts","type":"string"},"fax":{"description":"fax number for patron's primary address","type":["string","null"]},"updated_on":{"description":"time of last change could be useful for synchronization with external systems (among others)","type":"string"},"contactfirstname":{"type":["string","null"],"description":"used for children to include first name of guarantor"},"contacttitle":{"description":"used for children to include title of guarantor","type":["string","null"]},"sex":{"type":["string","null"],"description":"patron's gender"},"B_streetnumber":{"description":"street number of patron's alternate address","type":["string","null"]},"contactnote":{"description":"a note related to patron's alternate address","type":["string","null"]},"mobile":{"description":"the other phone number for patron's primary address","type":["string","null"]},"othernames":{"type":["string","null"],"description":"any other names associated with the patron"},"lost":{"type":["string","null"],"description":"set to 1 if library marked this patron as having lost his card"},"B_state":{"description":"state or province of patron's alternate address","type":["string","null"]},"streetnumber":{"type":["string","null"],"description":"street number of patron's primary address"},"borrowernotes":{"type":["string","null"],"description":"a note on the patron's account"},"phonepro":{"type":["string","null"],"description":"secondary phone number for patron's primary address"},"country":{"description":"country of patron's primary address","type":["string","null"]},"altcontactaddress2":{"type":["string","null"],"description":"the second address line for the alternate contact for the patron"},"streettype":{"type":["string","null"],"description":"street type of patron's primary address"},"title":{"type":["string","null"],"description":"patron's title"},"password":{"type":["string","null"],"description":"patron's encrypted password"},"city":{"description":"city or town of patron's primary address","type":"string"},"relationship":{"type":["string","null"],"description":"used for children to include the relationship to their guarantor"},"firstname":{"description":"patron's first name","type":["string","null"]},"altcontactcountry":{"description":"the country for the alternate contact for the patron","type":["string","null"]},"email":{"description":"primary email address for patron's primary address","type":["string","null"]},"phone":{"description":"primary phone number for patron's primary address","type":["string","null"]},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"debarred":{"description":"until this date the patron can only check-in","type":["string","null"]},"privacy":{"type":"string","description":"patron's privacy settings related to their reading history"},"altcontactsurname":{"type":["string","null"],"description":"surname or last name of the alternate contact for the patron"},"sort2":{"description":"a field that can be used for any information unique to the library","type":["string","null"]},"userid":{"type":["string","null"],"description":"patron's login"},"surname":{"type":"string","description":"patron's last name"},"B_zipcode":{"description":"zip or postal code of patron's alternate address","type":["string","null"]},"altcontactaddress1":{"description":"the first address line for the alternate contact for the patron","type":["string","null"]},"sms_provider_id":{"description":"the provider of the mobile phone number defined in smsalertnumber","type":["string","null"]},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"address":{"description":"first address line of patron's primary address","type":"string"},"altcontactfirstname":{"type":["string","null"],"description":"first name of alternate contact for the patron"},"opacnote":{"description":"a note on the patron's account visible in OPAC and staff client","type":["string","null"]},"flags":{"type":["string","null"],"description":"a number associated with the patron's permissions"},"dateenrolled":{"type":["string","null"],"description":"date the patron was added to Koha"},"B_country":{"description":"country of patron's alternate address","type":["string","null"]},"B_streettype":{"description":"street type of patron's alternate address","type":["string","null"]},"debarredcomment":{"type":["string","null"],"description":"comment on the stop of the patron"},"B_address":{"description":"first address line of patron's alternate address","type":["string","null"]},"smsalertnumber":{"type":["string","null"],"description":"the mobile phone number where the patron would like to receive notices (if SMS turned on)"}}}},"description":"A list of patrons"},"403":{"description":"Access forbidden","schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}}}}},"produces":["application\/json"],"operationId":"listPatrons","tags":["patrons"]}},"\/accountlines\/{accountlines_id}":{"put":{"responses":{"404":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}}},"description":"Accountline not found"},"400":{"schema":{"properties":{"error":{"type":"string","description":"Error message"}},"type":"object"},"description":"Missing or wrong parameters"},"403":{"description":"Access forbidden","schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}}}},"200":{"schema":{"properties":{"note":{"description":"Accountline note"},"accountno":{"description":"?"},"accountlines_id":{"description":"Internal account line identifier"},"date":{"description":"Date when the account line was created"},"itemnumber":{"description":"Internal item identifier"},"accounttype":{"description":"Type of accountline"},"notify_level":{"description":"?"},"timestamp":{"description":"When the account line was last updated"},"amount":{"description":"Amount"},"borrowernumber":{"description":"Internal borrower identifier"},"time":{"description":"Time when the account line was created"},"meansofpayment":{"description":"Means of payment"},"description":{"description":"Description of account line"},"amountoutstanding":{"description":"Amount outstanding"},"notify_id":{"description":"?"},"manager_id":{"description":"Borrowernumber of user that created the account line"},"lastincrement":{"description":"?"}},"type":"object"},"description":"Updated accountline"}},"parameters":[{"name":"accountlines_id","in":"path","required":true,"description":"Internal accountline identifier","type":"integer"},{"schema":{"type":"object","properties":{"amount":{"description":"Amount"},"amountoutstanding":{"description":"Amount outstanding"},"meansofpayment":{"description":"Means of payment"},"note":{"description":"Accountline note"}}},"name":"body","in":"body","required":true,"description":"A JSON object containing fields to modify"}],"operationId":"editAccountlines","produces":["application\/json"],"consumes":["application\/json"],"tags":["accountlines"]}},"\/holds\/{reserve_id}":{"delete":{"parameters":[{"required":true,"in":"path","type":"integer","description":"Internal hold identifier","name":"reserve_id"}],"operationId":"deleteHold","produces":["application\/json"],"responses":{"404":{"description":"Hold not found","schema":{"properties":{"error":{"type":"string","description":"Error message"}},"type":"object"}},"200":{"schema":{"type":"object"},"description":"Successful deletion"}},"tags":["holds"]},"put":{"tags":["holds"],"responses":{"400":{"schema":{"properties":{"error":{"type":"string","description":"Error message"}},"type":"object"},"description":"Missing or wrong parameters"},"200":{"description":"Updated hold","schema":{"properties":{"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"reserve_id":{"description":"Internal hold identifier"},"reservedate":{"description":"the date the hold was placed"},"suspend_until":{"description":""},"notificationdate":{"description":"currently unused"},"cancellationdate":{"description":"the date the hold was cancelled"},"itemnumber":{"description":"internally assigned item identifier","type":["string","null"]},"suspend":{"description":""},"reservenotes":{"description":"notes related to this hold"},"itemtype":{"type":["string","null"],"description":"If record level hold, the optional itemtype of the item the patron is requesting"},"timestamp":{"description":"date and time the hold was last updated"},"branchcode":{"type":["string","null"],"description":"code of patron's home branch"},"expirationdate":{"description":"the date the hold expires"},"priority":{"description":"where in the queue the patron sits"},"reminderdate":{"description":"currently unused"},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"lowestPriority":{"description":""}},"type":"object"}},"404":{"description":"Hold not found","schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}}}}},"parameters":[{"name":"reserve_id","required":true,"in":"path","type":"integer","description":"Internal hold identifier"},{"description":"A JSON object containing fields to modify","required":true,"in":"body","name":"body","schema":{"type":"object","properties":{"priority":{"description":"Position in waiting queue","type":"integer","minimum":1},"branchcode":{"description":"Pickup location","type":"string"},"suspend_until":{"format":"date","type":"string","description":"Suspend until"}}}}],"operationId":"editHold","consumes":["application\/json"],"produces":["application\/json"]}}},"basePath":"\/api\/v1","definitions":{"accountline":{"properties":{"note":{"description":"Accountline note"},"accountno":{"description":"?"},"accountlines_id":{"description":"Internal account line identifier"},"date":{"description":"Date when the account line was created"},"itemnumber":{"description":"Internal item identifier"},"accounttype":{"description":"Type of accountline"},"notify_level":{"description":"?"},"timestamp":{"description":"When the account line was last updated"},"amount":{"description":"Amount"},"borrowernumber":{"description":"Internal borrower identifier"},"time":{"description":"Time when the account line was created"},"meansofpayment":{"description":"Means of payment"},"description":{"description":"Description of account line"},"amountoutstanding":{"description":"Amount outstanding"},"notify_id":{"description":"?"},"manager_id":{"description":"Borrowernumber of user that created the account line"},"lastincrement":{"description":"?"}},"type":"object"},"patron":{"type":"object","properties":{"B_phone":{"type":["string","null"],"description":"phone number for patron's alternate address"},"dateexpiry":{"type":["string","null"],"description":"date the patron's card is set to expire"},"categorycode":{"type":"string","description":"code of patron's category"},"B_city":{"description":"city or town of patron's alternate address","type":["string","null"]},"initials":{"type":["string","null"],"description":"initials of the patron"},"address2":{"type":["string","null"],"description":"second address line of patron's primary address"},"guarantorid":{"description":"borrowernumber used for children or professionals to link them to guarantor or organizations","type":["string","null"]},"checkprevcheckout":{"type":"string","description":"produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'"},"altcontactstate":{"type":["string","null"],"description":"the state for the alternate contact for the patron"},"emailpro":{"type":["string","null"],"description":"secondary email address for patron's primary address"},"contactname":{"type":["string","null"],"description":"used for children and professionals to include surname or last name of guarantor or organization name"},"sort1":{"description":"a field that can be used for any information unique to the library","type":["string","null"]},"B_address2":{"type":["string","null"],"description":"second address line of patron's alternate address"},"gonenoaddress":{"description":"set to 1 if library marked this patron as having an unconfirmed address","type":["string","null"]},"cardnumber":{"type":["string","null"],"description":"library assigned user identifier"},"altcontactphone":{"description":"the phone number for the alternate contact for the patron","type":["string","null"]},"altcontactaddress3":{"type":["string","null"],"description":"the city for the alternate contact for the patron"},"B_email":{"description":"email address for patron's alternate address","type":["string","null"]},"altcontactzipcode":{"type":["string","null"],"description":"the zipcode for the alternate contact for the patron"},"zipcode":{"type":["string","null"],"description":"zip or postal code of patron's primary address"},"dateofbirth":{"description":"patron's date of birth","type":["string","null"]},"state":{"description":"state or province of patron's primary address","type":["string","null"]},"privacy_guarantor_checkouts":{"description":"controls if relatives can see this patron's checkouts","type":"string"},"fax":{"description":"fax number for patron's primary address","type":["string","null"]},"updated_on":{"description":"time of last change could be useful for synchronization with external systems (among others)","type":"string"},"contactfirstname":{"type":["string","null"],"description":"used for children to include first name of guarantor"},"contacttitle":{"description":"used for children to include title of guarantor","type":["string","null"]},"sex":{"type":["string","null"],"description":"patron's gender"},"B_streetnumber":{"description":"street number of patron's alternate address","type":["string","null"]},"contactnote":{"description":"a note related to patron's alternate address","type":["string","null"]},"mobile":{"description":"the other phone number for patron's primary address","type":["string","null"]},"othernames":{"type":["string","null"],"description":"any other names associated with the patron"},"lost":{"type":["string","null"],"description":"set to 1 if library marked this patron as having lost his card"},"B_state":{"description":"state or province of patron's alternate address","type":["string","null"]},"streetnumber":{"type":["string","null"],"description":"street number of patron's primary address"},"borrowernotes":{"type":["string","null"],"description":"a note on the patron's account"},"phonepro":{"type":["string","null"],"description":"secondary phone number for patron's primary address"},"country":{"description":"country of patron's primary address","type":["string","null"]},"altcontactaddress2":{"type":["string","null"],"description":"the second address line for the alternate contact for the patron"},"streettype":{"type":["string","null"],"description":"street type of patron's primary address"},"title":{"type":["string","null"],"description":"patron's title"},"password":{"type":["string","null"],"description":"patron's encrypted password"},"city":{"description":"city or town of patron's primary address","type":"string"},"relationship":{"type":["string","null"],"description":"used for children to include the relationship to their guarantor"},"firstname":{"description":"patron's first name","type":["string","null"]},"altcontactcountry":{"description":"the country for the alternate contact for the patron","type":["string","null"]},"email":{"description":"primary email address for patron's primary address","type":["string","null"]},"phone":{"description":"primary phone number for patron's primary address","type":["string","null"]},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"debarred":{"description":"until this date the patron can only check-in","type":["string","null"]},"privacy":{"type":"string","description":"patron's privacy settings related to their reading history"},"altcontactsurname":{"type":["string","null"],"description":"surname or last name of the alternate contact for the patron"},"sort2":{"description":"a field that can be used for any information unique to the library","type":["string","null"]},"userid":{"type":["string","null"],"description":"patron's login"},"surname":{"type":"string","description":"patron's last name"},"B_zipcode":{"description":"zip or postal code of patron's alternate address","type":["string","null"]},"altcontactaddress1":{"description":"the first address line for the alternate contact for the patron","type":["string","null"]},"sms_provider_id":{"description":"the provider of the mobile phone number defined in smsalertnumber","type":["string","null"]},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"address":{"description":"first address line of patron's primary address","type":"string"},"altcontactfirstname":{"type":["string","null"],"description":"first name of alternate contact for the patron"},"opacnote":{"description":"a note on the patron's account visible in OPAC and staff client","type":["string","null"]},"flags":{"type":["string","null"],"description":"a number associated with the patron's permissions"},"dateenrolled":{"type":["string","null"],"description":"date the patron was added to Koha"},"B_country":{"description":"country of patron's alternate address","type":["string","null"]},"B_streettype":{"description":"street type of patron's alternate address","type":["string","null"]},"debarredcomment":{"type":["string","null"],"description":"comment on the stop of the patron"},"B_address":{"description":"first address line of patron's alternate address","type":["string","null"]},"smsalertnumber":{"type":["string","null"],"description":"the mobile phone number where the patron would like to receive notices (if SMS turned on)"}}},"holds":{"items":{"properties":{"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"reserve_id":{"description":"Internal hold identifier"},"reservedate":{"description":"the date the hold was placed"},"suspend_until":{"description":""},"notificationdate":{"description":"currently unused"},"cancellationdate":{"description":"the date the hold was cancelled"},"itemnumber":{"description":"internally assigned item identifier","type":["string","null"]},"suspend":{"description":""},"reservenotes":{"description":"notes related to this hold"},"itemtype":{"type":["string","null"],"description":"If record level hold, the optional itemtype of the item the patron is requesting"},"timestamp":{"description":"date and time the hold was last updated"},"branchcode":{"type":["string","null"],"description":"code of patron's home branch"},"expirationdate":{"description":"the date the hold expires"},"priority":{"description":"where in the queue the patron sits"},"reminderdate":{"description":"currently unused"},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"lowestPriority":{"description":""}},"type":"object"},"type":"array"},"error":{"properties":{"error":{"type":"string","description":"Error message"}},"type":"object"},"hold":{"properties":{"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"reserve_id":{"description":"Internal hold identifier"},"reservedate":{"description":"the date the hold was placed"},"suspend_until":{"description":""},"notificationdate":{"description":"currently unused"},"cancellationdate":{"description":"the date the hold was cancelled"},"itemnumber":{"description":"internally assigned item identifier","type":["string","null"]},"suspend":{"description":""},"reservenotes":{"description":"notes related to this hold"},"itemtype":{"type":["string","null"],"description":"If record level hold, the optional itemtype of the item the patron is requesting"},"timestamp":{"description":"date and time the hold was last updated"},"branchcode":{"type":["string","null"],"description":"code of patron's home branch"},"expirationdate":{"description":"the date the hold expires"},"priority":{"description":"where in the queue the patron sits"},"reminderdate":{"description":"currently unused"},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"lowestPriority":{"description":""}},"type":"object"}},"parameters":{"accountlinesIdPathParam":{"in":"path","required":true,"description":"Internal accountline identifier","type":"integer","name":"accountlines_id"},"borrowernumberPathParam":{"required":true,"in":"path","type":"integer","description":"Internal patron identifier","name":"borrowernumber"},"holdIdPathParam":{"in":"path","required":true,"description":"Internal hold identifier","type":"integer","name":"reserve_id"},"borrowernumberQueryParam":{"in":"query","description":"Internal borrower identifier","type":"integer","name":"borrowernumber"}}} +{"swagger":"2.0","parameters":{"borrowernumberPathParam":{"required":true,"in":"path","description":"Internal patron identifier","type":"integer","name":"borrowernumber"},"holdIdPathParam":{"description":"Internal hold identifier","name":"reserve_id","type":"integer","in":"path","required":true},"borrowernumberQueryParam":{"in":"query","type":"integer","name":"borrowernumber","description":"Internal borrower identifier"},"accountlinesIdPathParam":{"in":"path","required":true,"description":"Internal accountline identifier","type":"integer","name":"accountlines_id"}},"info":{"version":"1","title":"Koha REST API","license":{"name":"GPL v3","url":"http:\/\/www.gnu.org\/licenses\/gpl.txt"},"contact":{"url":"http:\/\/koha-community.org\/","name":"Koha Team"}},"definitions":{"holds":{"items":{"properties":{"suspend_until":{"description":""},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"reservedate":{"description":"the date the hold was placed"},"reservenotes":{"description":"notes related to this hold"},"itemnumber":{"type":["string","null"],"description":"internally assigned item identifier"},"lowestPriority":{"description":""},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"notificationdate":{"description":"currently unused"},"expirationdate":{"description":"the date the hold expires"},"reminderdate":{"description":"currently unused"},"priority":{"description":"where in the queue the patron sits"},"reserve_id":{"description":"Internal hold identifier"},"cancellationdate":{"description":"the date the hold was cancelled"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"timestamp":{"description":"date and time the hold was last updated"},"itemtype":{"description":"If record level hold, the optional itemtype of the item the patron is requesting","type":["string","null"]},"suspend":{"description":""}},"type":"object"},"type":"array"},"accountline":{"properties":{"meansofpayment":{"description":"Means of payment"},"date":{"description":"Date when the account line was created"},"note":{"description":"Accountline note"},"amount":{"description":"Amount"},"manager_id":{"description":"Borrowernumber of user that created the account line"},"accountlines_id":{"description":"Internal account line identifier"},"time":{"description":"Time when the account line was created"},"lastincrement":{"description":"?"},"accountno":{"description":"?"},"itemnumber":{"description":"Internal item identifier"},"amountoutstanding":{"description":"Amount outstanding"},"notify_level":{"description":"?"},"notify_id":{"description":"?"},"borrowernumber":{"description":"Internal borrower identifier"},"timestamp":{"description":"When the account line was last updated"},"description":{"description":"Description of account line"},"accounttype":{"description":"Type of accountline"}},"type":"object"},"patron":{"type":"object","properties":{"altcontactaddress1":{"description":"the first address line for the alternate contact for the patron","type":["string","null"]},"B_phone":{"description":"phone number for patron's alternate address","type":["string","null"]},"altcontactfirstname":{"description":"first name of alternate contact for the patron","type":["string","null"]},"relationship":{"type":["string","null"],"description":"used for children to include the relationship to their guarantor"},"address":{"type":"string","description":"first address line of patron's primary address"},"othernames":{"type":["string","null"],"description":"any other names associated with the patron"},"smsalertnumber":{"description":"the mobile phone number where the patron would like to receive notices (if SMS turned on)","type":["string","null"]},"password":{"type":["string","null"],"description":"patron's encrypted password"},"borrowernumber":{"description":"internally assigned user identifier","type":"string"},"altcontactzipcode":{"type":["string","null"],"description":"the zipcode for the alternate contact for the patron"},"initials":{"type":["string","null"],"description":"initials of the patron"},"borrowernotes":{"type":["string","null"],"description":"a note on the patron's account"},"B_country":{"type":["string","null"],"description":"country of patron's alternate address"},"updated_on":{"type":"string","description":"time of last change could be useful for synchronization with external systems (among others)"},"city":{"type":"string","description":"city or town of patron's primary address"},"userid":{"description":"patron's login","type":["string","null"]},"debarred":{"type":["string","null"],"description":"until this date the patron can only check-in"},"lost":{"description":"set to 1 if library marked this patron as having lost his card","type":["string","null"]},"guarantorid":{"description":"borrowernumber used for children or professionals to link them to guarantor or organizations","type":["string","null"]},"phone":{"description":"primary phone number for patron's primary address","type":["string","null"]},"debarredcomment":{"description":"comment on the stop of the patron","type":["string","null"]},"country":{"type":["string","null"],"description":"country of patron's primary address"},"sex":{"type":["string","null"],"description":"patron's gender"},"opacnote":{"description":"a note on the patron's account visible in OPAC and staff client","type":["string","null"]},"altcontactphone":{"description":"the phone number for the alternate contact for the patron","type":["string","null"]},"emailpro":{"type":["string","null"],"description":"secondary email address for patron's primary address"},"B_address2":{"type":["string","null"],"description":"second address line of patron's alternate address"},"branchcode":{"type":["string","null"],"description":"code of patron's home branch"},"altcontactsurname":{"type":["string","null"],"description":"surname or last name of the alternate contact for the patron"},"B_email":{"description":"email address for patron's alternate address","type":["string","null"]},"categorycode":{"description":"code of patron's category","type":"string"},"contacttitle":{"type":["string","null"],"description":"used for children to include title of guarantor"},"surname":{"type":"string","description":"patron's last name"},"altcontactcountry":{"type":["string","null"],"description":"the country for the alternate contact for the patron"},"title":{"type":["string","null"],"description":"patron's title"},"contactnote":{"type":["string","null"],"description":"a note related to patron's alternate address"},"sms_provider_id":{"type":["string","null"],"description":"the provider of the mobile phone number defined in smsalertnumber"},"B_city":{"description":"city or town of patron's alternate address","type":["string","null"]},"fax":{"description":"fax number for patron's primary address","type":["string","null"]},"B_state":{"description":"state or province of patron's alternate address","type":["string","null"]},"altcontactaddress3":{"description":"the city for the alternate contact for the patron","type":["string","null"]},"firstname":{"description":"patron's first name","type":["string","null"]},"altcontactaddress2":{"type":["string","null"],"description":"the second address line for the alternate contact for the patron"},"mobile":{"type":["string","null"],"description":"the other phone number for patron's primary address"},"B_address":{"type":["string","null"],"description":"first address line of patron's alternate address"},"email":{"type":["string","null"],"description":"primary email address for patron's primary address"},"altcontactstate":{"type":["string","null"],"description":"the state for the alternate contact for the patron"},"privacy_guarantor_checkouts":{"description":"controls if relatives can see this patron's checkouts","type":"string"},"dateexpiry":{"type":["string","null"],"description":"date the patron's card is set to expire"},"B_zipcode":{"type":["string","null"],"description":"zip or postal code of patron's alternate address"},"dateofbirth":{"type":["string","null"],"description":"patron's date of birth"},"gonenoaddress":{"description":"set to 1 if library marked this patron as having an unconfirmed address","type":["string","null"]},"phonepro":{"description":"secondary phone number for patron's primary address","type":["string","null"]},"dateenrolled":{"description":"date the patron was added to Koha","type":["string","null"]},"contactfirstname":{"type":["string","null"],"description":"used for children to include first name of guarantor"},"privacy":{"type":"string","description":"patron's privacy settings related to their reading history"},"address2":{"type":["string","null"],"description":"second address line of patron's primary address"},"state":{"type":["string","null"],"description":"state or province of patron's primary address"},"flags":{"type":["string","null"],"description":"a number associated with the patron's permissions"},"streetnumber":{"type":["string","null"],"description":"street number of patron's primary address"},"zipcode":{"type":["string","null"],"description":"zip or postal code of patron's primary address"},"checkprevcheckout":{"description":"produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'","type":"string"},"sort2":{"type":["string","null"],"description":"a field that can be used for any information unique to the library"},"cardnumber":{"type":["string","null"],"description":"library assigned user identifier"},"streettype":{"type":["string","null"],"description":"street type of patron's primary address"},"B_streetnumber":{"type":["string","null"],"description":"street number of patron's alternate address"},"contactname":{"type":["string","null"],"description":"used for children and professionals to include surname or last name of guarantor or organization name"},"B_streettype":{"description":"street type of patron's alternate address","type":["string","null"]},"sort1":{"type":["string","null"],"description":"a field that can be used for any information unique to the library"}}},"error":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"hold":{"properties":{"suspend_until":{"description":""},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"reservedate":{"description":"the date the hold was placed"},"reservenotes":{"description":"notes related to this hold"},"itemnumber":{"type":["string","null"],"description":"internally assigned item identifier"},"lowestPriority":{"description":""},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"notificationdate":{"description":"currently unused"},"expirationdate":{"description":"the date the hold expires"},"reminderdate":{"description":"currently unused"},"priority":{"description":"where in the queue the patron sits"},"reserve_id":{"description":"Internal hold identifier"},"cancellationdate":{"description":"the date the hold was cancelled"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"timestamp":{"description":"date and time the hold was last updated"},"itemtype":{"description":"If record level hold, the optional itemtype of the item the patron is requesting","type":["string","null"]},"suspend":{"description":""}},"type":"object"}},"paths":{"\/holds":{"post":{"tags":["borrowers","holds"],"operationId":"addHold","parameters":[{"description":"A JSON object containing informations about the new hold","schema":{"properties":{"itemnumber":{"type":"integer","description":"Item internal identifier"},"expirationdate":{"format":"date","type":"string","description":"Hold end date"},"borrowernumber":{"type":"integer","description":"Borrower internal identifier"},"biblionumber":{"type":"integer","description":"Biblio internal identifier"},"branchcode":{"type":"string","description":"Pickup location"}},"type":"object"},"name":"body","required":true,"in":"body"}],"consumes":["application\/json"],"responses":{"201":{"description":"Created hold","schema":{"type":"object","properties":{"suspend_until":{"description":""},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"reservedate":{"description":"the date the hold was placed"},"reservenotes":{"description":"notes related to this hold"},"itemnumber":{"type":["string","null"],"description":"internally assigned item identifier"},"lowestPriority":{"description":""},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"notificationdate":{"description":"currently unused"},"expirationdate":{"description":"the date the hold expires"},"reminderdate":{"description":"currently unused"},"priority":{"description":"where in the queue the patron sits"},"reserve_id":{"description":"Internal hold identifier"},"cancellationdate":{"description":"the date the hold was cancelled"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"timestamp":{"description":"date and time the hold was last updated"},"itemtype":{"description":"If record level hold, the optional itemtype of the item the patron is requesting","type":["string","null"]},"suspend":{"description":""}}}},"403":{"schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}},"description":"Hold not allowed"},"500":{"schema":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"description":"Internal error"},"400":{"description":"Missing or wrong parameters","schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}}},"404":{"schema":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"description":"Borrower not found"}},"produces":["application\/json"]},"get":{"responses":{"200":{"description":"A list of holds","schema":{"type":"array","items":{"properties":{"suspend_until":{"description":""},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"reservedate":{"description":"the date the hold was placed"},"reservenotes":{"description":"notes related to this hold"},"itemnumber":{"type":["string","null"],"description":"internally assigned item identifier"},"lowestPriority":{"description":""},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"notificationdate":{"description":"currently unused"},"expirationdate":{"description":"the date the hold expires"},"reminderdate":{"description":"currently unused"},"priority":{"description":"where in the queue the patron sits"},"reserve_id":{"description":"Internal hold identifier"},"cancellationdate":{"description":"the date the hold was cancelled"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"timestamp":{"description":"date and time the hold was last updated"},"itemtype":{"description":"If record level hold, the optional itemtype of the item the patron is requesting","type":["string","null"]},"suspend":{"description":""}},"type":"object"}}},"404":{"schema":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"description":"Borrower not found"}},"produces":["application\/json"],"parameters":[{"in":"query","name":"reserve_id","type":"integer","description":"Internal reserve identifier"},{"in":"query","description":"Internal borrower identifier","type":"integer","name":"borrowernumber"},{"type":"string","name":"reservedate","description":"Reserve date","in":"query"},{"in":"query","name":"biblionumber","type":"integer","description":"Internal biblio identifier"},{"description":"Branch code","name":"branchcode","type":"string","in":"query"},{"type":"string","name":"notificationdate","description":"Notification date","in":"query"},{"in":"query","name":"reminderdate","type":"string","description":"Reminder date"},{"in":"query","description":"Cancellation date","name":"cancellationdate","type":"string"},{"description":"Reserve notes","type":"string","name":"reservenotes","in":"query"},{"type":"integer","name":"priority","description":"Priority","in":"query"},{"description":"Found status","type":"string","name":"found","in":"query"},{"in":"query","description":"Time of latest update","name":"timestamp","type":"string"},{"in":"query","name":"itemnumber","type":"integer","description":"Internal item identifier"},{"in":"query","type":"string","name":"waitingdate","description":"Date the item was marked as waiting for the patron"},{"description":"Date the hold expires","name":"expirationdate","type":"string","in":"query"},{"description":"Lowest priority","name":"lowestPriority","type":"integer","in":"query"},{"in":"query","type":"integer","name":"suspend","description":"Suspended"},{"in":"query","description":"Suspended until","name":"suspend_until","type":"string"}],"operationId":"listHolds","tags":["borrowers","holds"]}},"\/patrons\/{borrowernumber}":{"get":{"parameters":[{"description":"Internal patron identifier","type":"integer","name":"borrowernumber","in":"path","required":true}],"produces":["application\/json"],"responses":{"404":{"description":"Patron not found","schema":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"}},"200":{"description":"A patron","schema":{"type":"object","properties":{"altcontactaddress1":{"description":"the first address line for the alternate contact for the patron","type":["string","null"]},"B_phone":{"description":"phone number for patron's alternate address","type":["string","null"]},"altcontactfirstname":{"description":"first name of alternate contact for the patron","type":["string","null"]},"relationship":{"type":["string","null"],"description":"used for children to include the relationship to their guarantor"},"address":{"type":"string","description":"first address line of patron's primary address"},"othernames":{"type":["string","null"],"description":"any other names associated with the patron"},"smsalertnumber":{"description":"the mobile phone number where the patron would like to receive notices (if SMS turned on)","type":["string","null"]},"password":{"type":["string","null"],"description":"patron's encrypted password"},"borrowernumber":{"description":"internally assigned user identifier","type":"string"},"altcontactzipcode":{"type":["string","null"],"description":"the zipcode for the alternate contact for the patron"},"initials":{"type":["string","null"],"description":"initials of the patron"},"borrowernotes":{"type":["string","null"],"description":"a note on the patron's account"},"B_country":{"type":["string","null"],"description":"country of patron's alternate address"},"updated_on":{"type":"string","description":"time of last change could be useful for synchronization with external systems (among others)"},"city":{"type":"string","description":"city or town of patron's primary address"},"userid":{"description":"patron's login","type":["string","null"]},"debarred":{"type":["string","null"],"description":"until this date the patron can only check-in"},"lost":{"description":"set to 1 if library marked this patron as having lost his card","type":["string","null"]},"guarantorid":{"description":"borrowernumber used for children or professionals to link them to guarantor or organizations","type":["string","null"]},"phone":{"description":"primary phone number for patron's primary address","type":["string","null"]},"debarredcomment":{"description":"comment on the stop of the patron","type":["string","null"]},"country":{"type":["string","null"],"description":"country of patron's primary address"},"sex":{"type":["string","null"],"description":"patron's gender"},"opacnote":{"description":"a note on the patron's account visible in OPAC and staff client","type":["string","null"]},"altcontactphone":{"description":"the phone number for the alternate contact for the patron","type":["string","null"]},"emailpro":{"type":["string","null"],"description":"secondary email address for patron's primary address"},"B_address2":{"type":["string","null"],"description":"second address line of patron's alternate address"},"branchcode":{"type":["string","null"],"description":"code of patron's home branch"},"altcontactsurname":{"type":["string","null"],"description":"surname or last name of the alternate contact for the patron"},"B_email":{"description":"email address for patron's alternate address","type":["string","null"]},"categorycode":{"description":"code of patron's category","type":"string"},"contacttitle":{"type":["string","null"],"description":"used for children to include title of guarantor"},"surname":{"type":"string","description":"patron's last name"},"altcontactcountry":{"type":["string","null"],"description":"the country for the alternate contact for the patron"},"title":{"type":["string","null"],"description":"patron's title"},"contactnote":{"type":["string","null"],"description":"a note related to patron's alternate address"},"sms_provider_id":{"type":["string","null"],"description":"the provider of the mobile phone number defined in smsalertnumber"},"B_city":{"description":"city or town of patron's alternate address","type":["string","null"]},"fax":{"description":"fax number for patron's primary address","type":["string","null"]},"B_state":{"description":"state or province of patron's alternate address","type":["string","null"]},"altcontactaddress3":{"description":"the city for the alternate contact for the patron","type":["string","null"]},"firstname":{"description":"patron's first name","type":["string","null"]},"altcontactaddress2":{"type":["string","null"],"description":"the second address line for the alternate contact for the patron"},"mobile":{"type":["string","null"],"description":"the other phone number for patron's primary address"},"B_address":{"type":["string","null"],"description":"first address line of patron's alternate address"},"email":{"type":["string","null"],"description":"primary email address for patron's primary address"},"altcontactstate":{"type":["string","null"],"description":"the state for the alternate contact for the patron"},"privacy_guarantor_checkouts":{"description":"controls if relatives can see this patron's checkouts","type":"string"},"dateexpiry":{"type":["string","null"],"description":"date the patron's card is set to expire"},"B_zipcode":{"type":["string","null"],"description":"zip or postal code of patron's alternate address"},"dateofbirth":{"type":["string","null"],"description":"patron's date of birth"},"gonenoaddress":{"description":"set to 1 if library marked this patron as having an unconfirmed address","type":["string","null"]},"phonepro":{"description":"secondary phone number for patron's primary address","type":["string","null"]},"dateenrolled":{"description":"date the patron was added to Koha","type":["string","null"]},"contactfirstname":{"type":["string","null"],"description":"used for children to include first name of guarantor"},"privacy":{"type":"string","description":"patron's privacy settings related to their reading history"},"address2":{"type":["string","null"],"description":"second address line of patron's primary address"},"state":{"type":["string","null"],"description":"state or province of patron's primary address"},"flags":{"type":["string","null"],"description":"a number associated with the patron's permissions"},"streetnumber":{"type":["string","null"],"description":"street number of patron's primary address"},"zipcode":{"type":["string","null"],"description":"zip or postal code of patron's primary address"},"checkprevcheckout":{"description":"produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'","type":"string"},"sort2":{"type":["string","null"],"description":"a field that can be used for any information unique to the library"},"cardnumber":{"type":["string","null"],"description":"library assigned user identifier"},"streettype":{"type":["string","null"],"description":"street type of patron's primary address"},"B_streetnumber":{"type":["string","null"],"description":"street number of patron's alternate address"},"contactname":{"type":["string","null"],"description":"used for children and professionals to include surname or last name of guarantor or organization name"},"B_streettype":{"description":"street type of patron's alternate address","type":["string","null"]},"sort1":{"type":["string","null"],"description":"a field that can be used for any information unique to the library"}}}},"403":{"description":"Access forbidden","schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}}}},"operationId":"getPatron","tags":["patrons"]}},"\/accountlines":{"get":{"tags":["accountlines"],"operationId":"listAccountlines","responses":{"403":{"schema":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"description":"Access forbidden"},"200":{"schema":{"items":{"type":"object","properties":{"meansofpayment":{"description":"Means of payment"},"date":{"description":"Date when the account line was created"},"note":{"description":"Accountline note"},"amount":{"description":"Amount"},"manager_id":{"description":"Borrowernumber of user that created the account line"},"accountlines_id":{"description":"Internal account line identifier"},"time":{"description":"Time when the account line was created"},"lastincrement":{"description":"?"},"accountno":{"description":"?"},"itemnumber":{"description":"Internal item identifier"},"amountoutstanding":{"description":"Amount outstanding"},"notify_level":{"description":"?"},"notify_id":{"description":"?"},"borrowernumber":{"description":"Internal borrower identifier"},"timestamp":{"description":"When the account line was last updated"},"description":{"description":"Description of account line"},"accounttype":{"description":"Type of accountline"}}},"type":"array"},"description":"A list of accountlines"}},"produces":["application\/json"]}},"\/accountlines\/{accountlines_id}\/payment":{"post":{"operationId":"payAccountlines","tags":["accountlines"],"consumes":["application\/json"],"parameters":[{"type":"integer","name":"accountlines_id","description":"Internal accountline identifier","in":"path","required":true},{"description":"A JSON object containing fields to modify","schema":{"properties":{"note":{"description":"Payment note"},"amount":{"description":"Amount to pay"}},"type":"object"},"name":"body","in":"body"}],"produces":["application\/json"],"responses":{"400":{"description":"Missing or wrong parameters","schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}}},"404":{"description":"Accountline not found","schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}}},"200":{"description":"Paid accountline","schema":{"type":"object","properties":{"meansofpayment":{"description":"Means of payment"},"date":{"description":"Date when the account line was created"},"note":{"description":"Accountline note"},"amount":{"description":"Amount"},"manager_id":{"description":"Borrowernumber of user that created the account line"},"accountlines_id":{"description":"Internal account line identifier"},"time":{"description":"Time when the account line was created"},"lastincrement":{"description":"?"},"accountno":{"description":"?"},"itemnumber":{"description":"Internal item identifier"},"amountoutstanding":{"description":"Amount outstanding"},"notify_level":{"description":"?"},"notify_id":{"description":"?"},"borrowernumber":{"description":"Internal borrower identifier"},"timestamp":{"description":"When the account line was last updated"},"description":{"description":"Description of account line"},"accounttype":{"description":"Type of accountline"}}}},"403":{"schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}},"description":"Access forbidden"}}}},"\/holds\/{reserve_id}":{"put":{"operationId":"editHold","tags":["holds"],"produces":["application\/json"],"responses":{"200":{"schema":{"type":"object","properties":{"suspend_until":{"description":""},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"reservedate":{"description":"the date the hold was placed"},"reservenotes":{"description":"notes related to this hold"},"itemnumber":{"type":["string","null"],"description":"internally assigned item identifier"},"lowestPriority":{"description":""},"waitingdate":{"description":"the date the item was marked as waiting for the patron at the library"},"found":{"description":"a one letter code defining what the status of the hold is after it has been confirmed"},"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"notificationdate":{"description":"currently unused"},"expirationdate":{"description":"the date the hold expires"},"reminderdate":{"description":"currently unused"},"priority":{"description":"where in the queue the patron sits"},"reserve_id":{"description":"Internal hold identifier"},"cancellationdate":{"description":"the date the hold was cancelled"},"borrowernumber":{"type":"string","description":"internally assigned user identifier"},"timestamp":{"description":"date and time the hold was last updated"},"itemtype":{"description":"If record level hold, the optional itemtype of the item the patron is requesting","type":["string","null"]},"suspend":{"description":""}}},"description":"Updated hold"},"404":{"schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}},"description":"Hold not found"},"400":{"schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}},"description":"Missing or wrong parameters"}},"parameters":[{"required":true,"in":"path","description":"Internal hold identifier","type":"integer","name":"reserve_id"},{"schema":{"type":"object","properties":{"branchcode":{"type":"string","description":"Pickup location"},"priority":{"description":"Position in waiting queue","type":"integer","minimum":1},"suspend_until":{"format":"date","description":"Suspend until","type":"string"}}},"description":"A JSON object containing fields to modify","name":"body","in":"body","required":true}],"consumes":["application\/json"]},"delete":{"responses":{"200":{"description":"Successful deletion","schema":{"type":"object"}},"404":{"description":"Hold not found","schema":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"}}},"produces":["application\/json"],"parameters":[{"description":"Internal hold identifier","type":"integer","name":"reserve_id","required":true,"in":"path"}],"tags":["holds"],"operationId":"deleteHold"}},"\/patrons":{"get":{"operationId":"listPatrons","tags":["patrons"],"produces":["application\/json"],"responses":{"200":{"description":"A list of patrons","schema":{"type":"array","items":{"properties":{"altcontactaddress1":{"description":"the first address line for the alternate contact for the patron","type":["string","null"]},"B_phone":{"description":"phone number for patron's alternate address","type":["string","null"]},"altcontactfirstname":{"description":"first name of alternate contact for the patron","type":["string","null"]},"relationship":{"type":["string","null"],"description":"used for children to include the relationship to their guarantor"},"address":{"type":"string","description":"first address line of patron's primary address"},"othernames":{"type":["string","null"],"description":"any other names associated with the patron"},"smsalertnumber":{"description":"the mobile phone number where the patron would like to receive notices (if SMS turned on)","type":["string","null"]},"password":{"type":["string","null"],"description":"patron's encrypted password"},"borrowernumber":{"description":"internally assigned user identifier","type":"string"},"altcontactzipcode":{"type":["string","null"],"description":"the zipcode for the alternate contact for the patron"},"initials":{"type":["string","null"],"description":"initials of the patron"},"borrowernotes":{"type":["string","null"],"description":"a note on the patron's account"},"B_country":{"type":["string","null"],"description":"country of patron's alternate address"},"updated_on":{"type":"string","description":"time of last change could be useful for synchronization with external systems (among others)"},"city":{"type":"string","description":"city or town of patron's primary address"},"userid":{"description":"patron's login","type":["string","null"]},"debarred":{"type":["string","null"],"description":"until this date the patron can only check-in"},"lost":{"description":"set to 1 if library marked this patron as having lost his card","type":["string","null"]},"guarantorid":{"description":"borrowernumber used for children or professionals to link them to guarantor or organizations","type":["string","null"]},"phone":{"description":"primary phone number for patron's primary address","type":["string","null"]},"debarredcomment":{"description":"comment on the stop of the patron","type":["string","null"]},"country":{"type":["string","null"],"description":"country of patron's primary address"},"sex":{"type":["string","null"],"description":"patron's gender"},"opacnote":{"description":"a note on the patron's account visible in OPAC and staff client","type":["string","null"]},"altcontactphone":{"description":"the phone number for the alternate contact for the patron","type":["string","null"]},"emailpro":{"type":["string","null"],"description":"secondary email address for patron's primary address"},"B_address2":{"type":["string","null"],"description":"second address line of patron's alternate address"},"branchcode":{"type":["string","null"],"description":"code of patron's home branch"},"altcontactsurname":{"type":["string","null"],"description":"surname or last name of the alternate contact for the patron"},"B_email":{"description":"email address for patron's alternate address","type":["string","null"]},"categorycode":{"description":"code of patron's category","type":"string"},"contacttitle":{"type":["string","null"],"description":"used for children to include title of guarantor"},"surname":{"type":"string","description":"patron's last name"},"altcontactcountry":{"type":["string","null"],"description":"the country for the alternate contact for the patron"},"title":{"type":["string","null"],"description":"patron's title"},"contactnote":{"type":["string","null"],"description":"a note related to patron's alternate address"},"sms_provider_id":{"type":["string","null"],"description":"the provider of the mobile phone number defined in smsalertnumber"},"B_city":{"description":"city or town of patron's alternate address","type":["string","null"]},"fax":{"description":"fax number for patron's primary address","type":["string","null"]},"B_state":{"description":"state or province of patron's alternate address","type":["string","null"]},"altcontactaddress3":{"description":"the city for the alternate contact for the patron","type":["string","null"]},"firstname":{"description":"patron's first name","type":["string","null"]},"altcontactaddress2":{"type":["string","null"],"description":"the second address line for the alternate contact for the patron"},"mobile":{"type":["string","null"],"description":"the other phone number for patron's primary address"},"B_address":{"type":["string","null"],"description":"first address line of patron's alternate address"},"email":{"type":["string","null"],"description":"primary email address for patron's primary address"},"altcontactstate":{"type":["string","null"],"description":"the state for the alternate contact for the patron"},"privacy_guarantor_checkouts":{"description":"controls if relatives can see this patron's checkouts","type":"string"},"dateexpiry":{"type":["string","null"],"description":"date the patron's card is set to expire"},"B_zipcode":{"type":["string","null"],"description":"zip or postal code of patron's alternate address"},"dateofbirth":{"type":["string","null"],"description":"patron's date of birth"},"gonenoaddress":{"description":"set to 1 if library marked this patron as having an unconfirmed address","type":["string","null"]},"phonepro":{"description":"secondary phone number for patron's primary address","type":["string","null"]},"dateenrolled":{"description":"date the patron was added to Koha","type":["string","null"]},"contactfirstname":{"type":["string","null"],"description":"used for children to include first name of guarantor"},"privacy":{"type":"string","description":"patron's privacy settings related to their reading history"},"address2":{"type":["string","null"],"description":"second address line of patron's primary address"},"state":{"type":["string","null"],"description":"state or province of patron's primary address"},"flags":{"type":["string","null"],"description":"a number associated with the patron's permissions"},"streetnumber":{"type":["string","null"],"description":"street number of patron's primary address"},"zipcode":{"type":["string","null"],"description":"zip or postal code of patron's primary address"},"checkprevcheckout":{"description":"produce a warning for this patron if this item has previously been checked out to this patron if 'yes', not if 'no', defer to category setting if 'inherit'","type":"string"},"sort2":{"type":["string","null"],"description":"a field that can be used for any information unique to the library"},"cardnumber":{"type":["string","null"],"description":"library assigned user identifier"},"streettype":{"type":["string","null"],"description":"street type of patron's primary address"},"B_streetnumber":{"type":["string","null"],"description":"street number of patron's alternate address"},"contactname":{"type":["string","null"],"description":"used for children and professionals to include surname or last name of guarantor or organization name"},"B_streettype":{"description":"street type of patron's alternate address","type":["string","null"]},"sort1":{"type":["string","null"],"description":"a field that can be used for any information unique to the library"}},"type":"object"}}},"403":{"schema":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"description":"Access forbidden"}}}},"\/accountlines\/{accountlines_id}":{"put":{"parameters":[{"type":"integer","name":"accountlines_id","description":"Internal accountline identifier","in":"path","required":true},{"in":"body","required":true,"name":"body","schema":{"properties":{"amountoutstanding":{"description":"Amount outstanding"},"amount":{"description":"Amount"},"meansofpayment":{"description":"Means of payment"},"note":{"description":"Accountline note"}},"type":"object"},"description":"A JSON object containing fields to modify"}],"consumes":["application\/json"],"produces":["application\/json"],"responses":{"403":{"description":"Access forbidden","schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}}},"400":{"description":"Missing or wrong parameters","schema":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"}},"404":{"schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}},"description":"Accountline not found"},"200":{"schema":{"properties":{"meansofpayment":{"description":"Means of payment"},"date":{"description":"Date when the account line was created"},"note":{"description":"Accountline note"},"amount":{"description":"Amount"},"manager_id":{"description":"Borrowernumber of user that created the account line"},"accountlines_id":{"description":"Internal account line identifier"},"time":{"description":"Time when the account line was created"},"lastincrement":{"description":"?"},"accountno":{"description":"?"},"itemnumber":{"description":"Internal item identifier"},"amountoutstanding":{"description":"Amount outstanding"},"notify_level":{"description":"?"},"notify_id":{"description":"?"},"borrowernumber":{"description":"Internal borrower identifier"},"timestamp":{"description":"When the account line was last updated"},"description":{"description":"Description of account line"},"accounttype":{"description":"Type of accountline"}},"type":"object"},"description":"Updated accountline"}},"tags":["accountlines"],"operationId":"editAccountlines"}},"\/patrons\/{borrowernumber}\/payment":{"post":{"parameters":[{"in":"path","required":true,"description":"Internal patron identifier","type":"integer","name":"borrowernumber"},{"schema":{"properties":{"note":{"description":"Payment note"},"amount":{"description":"Amount to pay"}},"type":"object"},"description":"A JSON object containing fields to modify","name":"body","in":"body","required":true}],"consumes":["application\/json"],"responses":{"400":{"schema":{"properties":{"error":{"description":"Error message","type":"string"}},"type":"object"},"description":"Missing or wrong parameters"},"404":{"schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}},"description":"Borrower not found"},"204":{"description":"Success"},"403":{"description":"Access forbidden","schema":{"type":"object","properties":{"error":{"description":"Error message","type":"string"}}}}},"produces":["application\/json"],"operationId":"payForPatron","tags":["accountlines"]}}},"x-primitives":{"phone":{"description":"primary phone number for patron's primary address","type":["string","null"]},"itemnumber":{"type":["string","null"],"description":"internally assigned item identifier"},"email":{"type":["string","null"],"description":"primary email address for patron's primary address"},"surname":{"type":"string","description":"patron's last name"},"biblionumber":{"description":"internally assigned biblio identifier","type":"string"},"borrowernumber":{"description":"internally assigned user identifier","type":"string"},"cardnumber":{"description":"library assigned user identifier","type":["string","null"]},"firstname":{"description":"patron's first name","type":["string","null"]},"branchcode":{"description":"code of patron's home branch","type":["string","null"]},"reserve_id":{"description":"Internal hold identifier"}},"basePath":"\/api\/v1"} --- a/t/db_dependent/api/v1/accountlines.t +++ a/t/db_dependent/api/v1/accountlines.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 18; +use Test::More tests => 33; use Test::Mojo; use t::lib::TestBuilder; @@ -45,6 +45,9 @@ $t->get_ok('/api/v1/accountlines') $t->put_ok("/api/v1/accountlines/11224409" => json => {'amount' => -5}) ->status_is(403); +$t->post_ok("/api/v1/accountlines/11224408/payment") + ->status_is(403); + my $loggedinuser = $builder->build({ source => 'Borrower', value => { @@ -74,8 +77,8 @@ my $borrowernumber2 = $borrower2->{borrowernumber}; $dbh->do(q| DELETE FROM accountlines |); $dbh->do(q| - INSERT INTO accountlines (borrowernumber, amount, accounttype) - VALUES (?, 20, 'A'), (?, 40, 'F'), (?, 80, 'F'), (?, 10, 'F') + INSERT INTO accountlines (borrowernumber, amount, accounttype, amountoutstanding) + VALUES (?, 20, 'A', 20), (?, 40, 'F', 40), (?, 80, 'F', 80), (?, 10, 'F', 10) |, undef, $borrowernumber, $borrowernumber, $borrowernumber, $borrowernumber2); my $session = C4::Auth::get_session(''); @@ -114,7 +117,6 @@ my $put_data = { $tx = $t->ua->build_tx( PUT => "/api/v1/accountlines/11224409" - => {Accept => '*/*'} => json => $put_data); $tx->req->cookies({name => 'CGISESSID', value => $session->id}); $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); @@ -125,7 +127,6 @@ my $accountline_to_edit = Koha::Account::Lines->search({'borrowernumber' => $bor $tx = $t->ua->build_tx( PUT => "/api/v1/accountlines/$accountline_to_edit->{accountlines_id}" - => {Accept => '*/*'} => json => $put_data); $tx->req->cookies({name => 'CGISESSID', value => $session->id}); $tx->req->env({REMOTE_ADDR => '127.0.0.1'}); @@ -139,5 +140,55 @@ is($accountline_edited->{amountoutstanding}, '-19.000000'); # Payment tests +$tx = $t->ua->build_tx(POST => "/api/v1/accountlines/4562765765/payment"); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); +$t->request_ok($tx) + ->status_is(404); + +my $accountline_to_pay = Koha::Account::Lines->search({'borrowernumber' => $borrowernumber, 'amount' => 20})->unblessed()->[0]; +$tx = $t->ua->build_tx(POST => "/api/v1/accountlines/$accountline_to_pay->{accountlines_id}/payment"); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); +$t->request_ok($tx) + ->status_is(200); +#$t->content_is('toto'); + +my $accountline_paid = Koha::Account::Lines->search({'borrowernumber' => $borrowernumber, 'amount' => -20})->unblessed()->[0]; +ok($accountline_paid); + +# Partial payment tests +my $post_data = { + 'amount' => 17, + 'note' => 'Partial payment' +}; + +$tx = $t->ua->build_tx( + POST => "/api/v1/accountlines/11224419/payment" + => json => $post_data); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); +$t->request_ok($tx) + ->status_is(404); + +my $accountline_to_partiallypay = Koha::Account::Lines->search({'borrowernumber' => $borrowernumber, 'amount' => 80})->unblessed()->[0]; + +$tx = $t->ua->build_tx(POST => "/api/v1/accountlines/$accountline_to_partiallypay->{accountlines_id}/payment" => json => {amount => 'foo'}); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); +$t->request_ok($tx) + ->status_is(400); + +$tx = $t->ua->build_tx(POST => "/api/v1/accountlines/$accountline_to_partiallypay->{accountlines_id}/payment" => json => $post_data); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); +$t->request_ok($tx) + ->status_is(200); + +$accountline_to_partiallypay = Koha::Account::Lines->search({'borrowernumber' => $borrowernumber, 'amount' => 80})->unblessed()->[0]; +is($accountline_to_partiallypay->{amountoutstanding}, '63.000000'); + +my $accountline_partiallypaid = Koha::Account::Lines->search({'borrowernumber' => $borrowernumber, 'amount' => -17})->unblessed()->[0]; +ok($accountline_partiallypaid); $dbh->rollback; --- a/t/db_dependent/api/v1/patrons.t +++ a/t/db_dependent/api/v1/patrons.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 10; +use Test::More tests => 21; use Test::Mojo; use t::lib::TestBuilder; @@ -26,6 +26,7 @@ use C4::Context; use Koha::Database; use Koha::Patron; +use Koha::Account::Lines; my $builder = t::lib::TestBuilder->new(); @@ -50,6 +51,7 @@ $t->get_ok('/api/v1/patrons') ->status_is(403); $t->get_ok("/api/v1/patrons/" . $borrower->{ borrowernumber }) + ->status_is(403); my $loggedinuser = $builder->build({ @@ -57,7 +59,7 @@ my $loggedinuser = $builder->build({ value => { branchcode => $branchcode, categorycode => $categorycode, - flags => 16 # borrowers flag + flags => 1040 # borrowers and updatecharges (2^4 | 2^10) } }); @@ -81,4 +83,56 @@ $t->request_ok($tx) ->json_is('/borrowernumber' => $borrower->{ borrowernumber }) ->json_is('/surname' => $borrower->{ surname }); + +# Payment tests +my $borrower2 = $builder->build({ + source => 'Borrower', + value => { + branchcode => $branchcode, + categorycode => $categorycode, + } +}); +my $borrowernumber2 = $borrower2->{borrowernumber}; + +$dbh->do(q| + INSERT INTO accountlines (borrowernumber, amount, accounttype, amountoutstanding) + VALUES (?, 26, 'A', 26) + |, undef, $borrowernumber2); + +$t->post_ok("/api/v1/patrons/$borrowernumber2/payment" => json => {'amount' => 8}) + ->status_is(403); + +my $post_data2 = { + 'amount' => 24, + 'note' => 'Partial payment' +}; + +$tx = $t->ua->build_tx(POST => "/api/v1/patrons/8789798797/payment" => json => $post_data2); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); +$t->request_ok($tx) + ->status_is(404); + +$tx = $t->ua->build_tx(POST => "/api/v1/patrons/$borrowernumber2/payment" => json => {amount => 0}); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); +$t->request_ok($tx) + ->status_is(400); + +$tx = $t->ua->build_tx(POST => "/api/v1/patrons/$borrowernumber2/payment" => json => {amount => 'foo'}); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); +$t->request_ok($tx) + ->status_is(400); + +$tx = $t->ua->build_tx(POST => "/api/v1/patrons/$borrowernumber2/payment" => json => $post_data2); +$tx->req->cookies({name => 'CGISESSID', value => $session->id}); +$tx->req->env({REMOTE_ADDR => '127.0.0.1'}); +$t->request_ok($tx) + ->status_is(204); + +my $accountline_partiallypaid = Koha::Account::Lines->search({'borrowernumber' => $borrowernumber2, 'amount' => 26})->unblessed()->[0]; + +is($accountline_partiallypaid->{amountoutstanding}, '2.000000'); + $dbh->rollback; --