diff --git a/README.md b/README.md
index 9134834df5f52e225585d15da6736246dfa8cd6b..ae38611452e0cb2543250ffa398f5cf09e181de9 100644
--- a/README.md
+++ b/README.md
@@ -3,3 +3,8 @@
 This repo contains all the custom code related to the loan management in LinkAhead.
 It is to be checked out as a custom-directory and needs to be
 specified in your profile.yml.
+
+
+## Integration tests
+Run `pytest .` in the integration tests folder
+
diff --git a/integrationtests/basic_test.py b/integrationtests/basic_test.py
index a4becb2c39664e22364cd122e8f9e877c0a2ff8c..511c1876987a428a660cbb6f3bb79dd300b4d677 100644
--- a/integrationtests/basic_test.py
+++ b/integrationtests/basic_test.py
@@ -26,26 +26,40 @@ import linkahead as db
 import re
 from tempfile import NamedTemporaryFile
 from linkahead.utils.server_side_scripting import run_server_side_script
-from box_loan import (BORROWER, BOX, COMMENT, DESTINATION, EXHAUST_CONTENTS,
-                      EXPECTED_RETURN, F_BOX, F_COMMENT, F_DESTINATION,PERSON,
-                      F_EMAIL, F_EXHAUST_CONTENTS, F_EXPECTED_RETURN_DATE, EMAIL,
-                      F_FIRST_NAME, F_LAST_NAME, FIRST_NAME, LAST_NAME, LOAN, LOCATION,
-                      LOAN_REQUESTED, assert_date_in_future,
-                      assert_key_in_data, get_box, insert_or_update_person, main,
+from box_loan import (BORROWER, BOX, COMMENT, DESTINATION, EXHAUST_CONTENTS, LENT,
+                      F_CURRENT_LOCATION,
+                      EXPECTED_RETURN, F_BOX, F_COMMENT, F_DESTINATION,PERSON, LOAN_ACCEPTED,
+                      F_EMAIL, F_EXHAUST_CONTENTS, F_EXPECTED_RETURN_DATE, EMAIL, F_LOAN,
+                      F_FIRST_NAME, F_LAST_NAME, FIRST_NAME, LAST_NAME, LOAN, LOCATION, RETURNED,
+                      RETURN_ACCEPTED,
+                      LOAN_REQUESTED, assert_date_in_future, CONTENT, RETURNLOCATION,
+                      assert_key_in_data, get_box, insert_or_update_person, main, RETURN_REQUESTED,
                       send_loan_request_mail)
 
 
 TESTLOANCOMMENT = 'This is a test'
+TESTRETURNCOMMENT = 'This is a return test'
 TESTBOXNUMBER = '0123 TEST'
 TESTDESTINATION = 'TEST DEST'
+TESTCURRENTDESTINATION = 'TEST CUR DEST'
 TESTBORROWEREMAIL = 'test@example.com'
+TESTRETURNDATE="2025-03-04"
 TESTFN = "Alice"
 TESTLN = "Wunderland"
 
+
+def save_dict_to_jsonfile(data):
+    tmp = NamedTemporaryFile(delete=False, suffix=".json")
+    tmp.close()
+    with open(tmp.name, "w") as fi:
+        json.dump(data, fi)
+    return tmp.name
+
 def delete_stuff():
     to_be_deleted = db.Container()
     to_be_deleted.extend(db.execute_query(f"FIND loan with {COMMENT.name}='{TESTLOANCOMMENT}'"))
     to_be_deleted.extend(db.execute_query(f"FIND '{TESTDESTINATION}'"))
+    to_be_deleted.extend(db.execute_query(f"FIND '{TESTCURRENTDESTINATION}'"))
     to_be_deleted.extend(db.execute_query(f"FIND '{TESTBOXNUMBER}'"))
     to_be_deleted.extend(db.execute_query(f"FIND person with {EMAIL.name}='{TESTBORROWEREMAIL}'"))
     if len(to_be_deleted)>0:
@@ -56,6 +70,7 @@ def prepare():
     delete_stuff()
     db.Record(name=TESTBOXNUMBER).add_parent(BOX.name).insert()
     db.Record(name=TESTDESTINATION).add_parent(LOCATION.name).insert()
+    db.Record(name=TESTCURRENTDESTINATION).add_parent(LOCATION.name).insert()
     (db.Record().add_parent(PERSON.name).add_property(EMAIL.name, TESTBORROWEREMAIL)
                 .add_property(FIRST_NAME.name, TESTFN)
                 .add_property(LAST_NAME.name, TESTLN).insert())
@@ -64,6 +79,8 @@ def prepare():
 
 
 def test_request_loan():
+
+    ##### request loan #####
     data = {}
     data[F_EXHAUST_CONTENTS] = False
     data[F_EXPECTED_RETURN_DATE]= "2042-02-02"
@@ -74,15 +91,10 @@ def test_request_loan():
     data[F_LAST_NAME]=TESTLN
     data[F_FIRST_NAME]=TESTFN
 
-    fi = NamedTemporaryFile(delete=False, suffix=".json")
-    fi.close()
-    with open(fi.name, "w") as f:
-        json.dump(data, f)
-
     response = run_server_side_script("loan_management/request_loan.py",
                                     #"pos0",
                                     #option1="val1",
-                                    files={"-p0": fi.name},
+                                    files={"-p0": save_dict_to_jsonfile(data)},
                                     **{"auth-token":db.get_connection()._authenticator.auth_token})
     assert response.stderr is None
     assert response.code == 0
@@ -94,3 +106,87 @@ def test_request_loan():
     assert loan.get_property(f"{EXPECTED_RETURN.name}").value == data[F_EXPECTED_RETURN_DATE]
     assert loan.get_property(f"{EXHAUST_CONTENTS.name}").value == data[F_EXHAUST_CONTENTS]
     assert loan.get_property(f"{DESTINATION.name}").value == data[F_DESTINATION]
+    assert loan.get_property(f"{LOAN_ACCEPTED.name}") is None
+    assert loan.get_property(f"{LENT.name}") is None
+
+    ##### accept loan #####
+    data = {}
+    data[F_LOAN] = loan.id
+    response = run_server_side_script("loan_management/accept_loan_request.py",
+                                    #"pos0",
+                                    #option1="val1",
+                                    files={"-p0": save_dict_to_jsonfile(data)},
+                                    **{"auth-token":db.get_connection()._authenticator.auth_token})
+    assert response.stderr is None
+    assert response.code == 0
+    loan = db.execute_query(f"FIND loan with {COMMENT.name}='{TESTLOANCOMMENT}'", unique=True)
+    assert loan.get_property(f"{LOAN_ACCEPTED.name}").value.startswith("20")
+    assert loan.get_property(f"{LENT.name}") is None
+    assert loan.get_property(f"{RETURN_REQUESTED.name}") is None
+
+    ##### confirm loan #####
+    data = {}
+    data[F_LOAN] = loan.id
+    response = run_server_side_script("loan_management/confirm_loan.py",
+                                    #"pos0",
+                                    #option1="val1",
+                                    files={"-p0": save_dict_to_jsonfile(data)},
+                                    **{"auth-token":db.get_connection()._authenticator.auth_token})
+    assert response.stderr is None
+    assert response.code == 0
+    loan = db.execute_query(f"FIND loan with {COMMENT.name}='{TESTLOANCOMMENT}'", unique=True)
+    assert loan.get_property(f"{LENT.name}").value.startswith("20")
+
+    ##### request return #####
+    data = {}
+    data[F_LOAN] = loan.id
+    # TODO: this is writen in the content field. Change name?
+    data[F_COMMENT] = TESTRETURNCOMMENT
+    # TODO: this is written in RETURNLOCATION. Change name?
+    data[F_CURRENT_LOCATION]=db.utils.get_entity.get_entity_by_name(TESTCURRENTDESTINATION).id
+    data[F_EXPECTED_RETURN_DATE] = TESTRETURNDATE
+    data[F_EMAIL]=TESTBORROWEREMAIL
+    data[F_LAST_NAME]=TESTLN
+    data[F_FIRST_NAME]=TESTFN
+    response = run_server_side_script("loan_management/request_return.py",
+                                    #"pos0",
+                                    #option1="val1",
+                                    files={"-p0": save_dict_to_jsonfile(data)},
+                                    **{"auth-token":db.get_connection()._authenticator.auth_token})
+    assert response.stderr is None
+    assert response.code == 0
+    loan = db.execute_query(f"FIND loan with {COMMENT.name}='{TESTLOANCOMMENT}'", unique=True)
+    assert loan.get_property(f"{LOAN_ACCEPTED.name}").value.startswith("20")
+    assert loan.get_property(f"{CONTENT.name}").value == TESTRETURNCOMMENT
+    assert loan.get_property(f"{EXPECTED_RETURN.name}").value == TESTRETURNDATE
+    assert loan.get_property(f"{RETURNLOCATION.name}").value == db.utils.get_entity.get_entity_by_name(TESTCURRENTDESTINATION).id
+    assert loan.get_property(f"{RETURN_REQUESTED.name}").value.startswith("20")
+    assert loan.get_property(f"{RETURN_ACCEPTED.name}") is None
+    # TODO test change of borrower
+
+    # accept return
+    data = {}
+    data[F_LOAN] = loan.id
+    response = run_server_side_script("loan_management/accept_return_request.py",
+                                    #"pos0",
+                                    #option1="val1",
+                                    files={"-p0": save_dict_to_jsonfile(data)},
+                                    **{"auth-token":db.get_connection()._authenticator.auth_token})
+    assert response.stderr is None
+    assert response.code == 0
+    loan = db.execute_query(f"FIND loan with {COMMENT.name}='{TESTLOANCOMMENT}'", unique=True)
+    assert loan.get_property(f"{RETURN_ACCEPTED.name}").value.startswith("20")
+    assert loan.get_property(f"{RETURNED.name}") is None
+
+    # manual return
+    data = {}
+    data[F_LOAN] = loan.id
+    response = run_server_side_script("loan_management/manual_return.py",
+                                    #"pos0",
+                                    #option1="val1",
+                                    files={"-p0": save_dict_to_jsonfile(data)},
+                                    **{"auth-token":db.get_connection()._authenticator.auth_token})
+    assert response.stderr is None
+    assert response.code == 0
+    loan = db.execute_query(f"FIND loan with {COMMENT.name}='{TESTLOANCOMMENT}'", unique=True)
+    assert loan.get_property(f"{RETURNED.name}").value.startswith("20")
diff --git a/loan-custom/caosdb-server/scripting/bin/loan_management/box_loan.py b/loan-custom/caosdb-server/scripting/bin/loan_management/box_loan.py
index 227b0e5c7b59a806fe23110717d7039069862b81..7027e98e969a688bbec139ba5a6f5bbef0ef1f1c 100644
--- a/loan-custom/caosdb-server/scripting/bin/loan_management/box_loan.py
+++ b/loan-custom/caosdb-server/scripting/bin/loan_management/box_loan.py
@@ -206,10 +206,10 @@ def get_box(box):
     return get_record_by_id(BOX.name, box)
 
 
-def get_loan(loan):
+def get_loan(loan_id):
     """ Retrieve a loan record by id. """
 
-    return get_record_by_id(LOAN.name, loan)
+    return get_record_by_id(LOAN.name, loan_id)
 
 
 def get_loan_state(loan):
diff --git a/loan-custom/caosdb-server/scripting/bin/loan_management/manual_return.py b/loan-custom/caosdb-server/scripting/bin/loan_management/manual_return.py
index 9aa7e83c3f3210ad719d41a0b1aa00896e7e5aca..1f6e8e634b6c45198373ea8b1cd08f0613630cf4 100755
--- a/loan-custom/caosdb-server/scripting/bin/loan_management/manual_return.py
+++ b/loan-custom/caosdb-server/scripting/bin/loan_management/manual_return.py
@@ -61,6 +61,7 @@ def _manual_return(data):
     assert_loan_state(loan, S_RETURN_ACCEPTED)
 
     # This changes the state from "return_accepted" to "returned".
+    # TODO why twice????
     set_property(loan, RETURNED, get_timestamp())
     set_property(loan, RETURNED, get_timestamp())
 
diff --git a/loan-custom/caosdb-server/scripting/bin/test/loan_management/test_box_loan.py b/loan-custom/caosdb-server/scripting/bin/test/loan_management/test_box_loan.py
index 6dfb9ab7759bc1b2b44477ee050bd711a957f01d..ff40b78cbe29cec66699b9513bfd48ffda43ce63 100644
--- a/loan-custom/caosdb-server/scripting/bin/test/loan_management/test_box_loan.py
+++ b/loan-custom/caosdb-server/scripting/bin/test/loan_management/test_box_loan.py
@@ -17,7 +17,7 @@ def test_caller():
     args = [get_data_example()]
 
     def test_func(data):
-        assert data["box"] == [2345], "should contain the data from json"
+        assert data["box"] == 2345, "should contain the data from json"
         return 1337
 
     assert _caller(test_func, args) == 1337
diff --git a/notes b/notes
index 313cea340989b90d16db5cc85e5d0dcc604694f3..d59de74242e0e3c7a4f372064a06f3577ae2fc20 100644
--- a/notes
+++ b/notes
@@ -13,3 +13,6 @@ Soll die Email Adress wirklich on the fly mit geändert werden? Alternative
 Introduce a single loan.py file with argparse (`loan.py accept a b c`, etc) 
 
 Person without first or lastname seem to be a problem.
+
+
+Warum wird der Borrower beim Return verändert? Nur anbieten email anzupassen?