TODO-6 (add books to loan) is now complete, so loans are now fully functional... the whole pybook is now at least functional, more features/validation to come :)

This commit is contained in:
2021-01-04 22:28:35 +11:00
parent 6ff3d13713
commit 336ae4b67f
6 changed files with 60 additions and 10 deletions

3
BUGs
View File

@@ -1,4 +1,4 @@
#### BUGS
#### BUGS (next-13)
BUG-2: series does not deal with calcd_rating...
- (on edit could, recalc as a catch-all, and obviously if we change a single book's rating, we should re-calc)
@@ -8,3 +8,4 @@ BUG-6: author,series, etc. do not have explicit ordering like sub-books... sort
- add/remove authors, and after save they are ordered by author.id, not order of addition (prob. needs book_author_link to have an auth_num)
BUG-7: if you remove a series from a book, it won't appear in the series drop-down if it is the first 'missing' book in that series -- either reset the list, or show all series always?
BUG-12: remove loaned out books from results of search for books to add to a loan

2
README
View File

@@ -37,7 +37,6 @@ TODO-4: removing a subbook from a series
- dont allow it & say remove sub book form parent book before we can act on this. OR:
- popup with: this is a subbook, you want to remove the parent & all its sub books from the series?
TODO-5: should deleting really just ask if want to mark it as SOLD?
TODO-6: need to add books to loan (on loan page, and via a book search?)
TODO-8: show books on shelf list
TODO-9: show books to buy view / printable
TODO-11: show unrated books (with toggle to exclude those with missing in a series)
@@ -56,3 +55,4 @@ TODO-19: icons on wish list, etc.? (not sure I really want them, but if so)
TODO-20: ORM all books load is slow
- should I lazy load all books (ajax the 2nd->last pages in, or not use ORM, and do a quick db.execute()....)
TODO-21: allow a way to add a book as a child of another existing book (opposite of rem_sub_book)

23
main.py
View File

@@ -561,18 +561,31 @@ def stats():
@app.route("/rem_books_from_loan/<id>", methods=["POST"])
def rem_books_from_loan(id):
print( "rem_books_from_loan for loan: {}".format( id ) )
for field in request.form:
rem_id=int(re.findall( '\d+', field )[0])
print( "field: {} -- so removing book id: {}".format( field, rem_id ) )
try:
db.engine.execute("delete from book_loan_link where book_id = {} and loan_id = {}".format( rem_id, id ))
db.session.commit()
except:
except SQLAlchemyError as e:
st.SetAlert("danger")
st.SetMessage("Failed to remove books from loan!")
st.SetMessage("Failed to remove books from loan! -- {}".format( e.orig ))
print( "now redirect to /loan/{}".format(id) )
print ("NOT SURE WHAT TO DO if we dont want output" )
return redirect("/loan/{}".format(id))
@app.route("/add_books_to_loan/<id>", methods=["POST"])
def add_books_to_loan(id):
for field in request.form:
add_id=int(re.findall( '\d+', field )[0])
try:
db.engine.execute("insert into book_loan_link (book_id, loan_id) values ( {}, {} )".format( add_id, id ))
print("insert into book_loan_link (book_id, loan_id) values ( {}, {} )".format( add_id, id ))
db.session.commit()
except SQLAlchemyError as e:
st.SetAlert("danger")
st.SetMessage("Failed to add books to loan! -- {}".format( e.orig ))
print ("NOT SURE WHAT TO DO if we dont want output" )
return redirect("/loan/{}".format(id))
@app.route("/", methods=["GET"])

View File

@@ -43,7 +43,7 @@
<div id="bfl-new" class="col-lg-10 px-0 py-4">
</div>
<div class="col py-4">
<button id="bfl-addsel-btn" class="btn btn-success disabled" disabled style="display:none" onClick="">Add Selected</button>
<button id="bfl-addsel-btn" class="btn btn-success disabled" disabled style="display:none" onClick="AddSelToLoan()">Add Selected</button>
</div>
</div>
</div>

View File

@@ -3,8 +3,11 @@
{% if not InDBox %}
<h3>All Books</h1>
{% set tab_id = 'book_table' %}
{% else %}
{% set tab_id = 'addsel_table' %}
{% endif %}
<table id="book_table" class="table table-striped table-sm" data-toolbar="#toolbar" data-search="true">
<table id="{{tab_id}}" class="table table-striped table-sm" data-toolbar="#toolbar" data-search="true">
<thead>
<tr class="thead-light"><th>Title</th><th>Author(s)</th>
{% if not InDBox %}
@@ -42,7 +45,7 @@
{% endif %}
<td>{{ GetCovertypeById(book.covertype) }}</td>
{% if InDBox %}
<td> <input type="checkbox"></td>
<td><input name="addsel-{{book.id}}" type="checkbox" onClick="ActivateBFLAddSelButton()"></td>
{% endif %}
</tr>
{% endfor %}

View File

@@ -5,10 +5,17 @@
$('#bfl-remsel-btn').attr('disabled',false)
}
function DeactivateBFLRemSelButton()
{
$('#bfl-remsel-btn').addClass('disabled')
$('#bfl-remsel-btn').attr('disabled',true)
}
function RemoveSelFromLoan()
{
var params=$("#book_table :input").serializeArray()
$.post( "/rem_books_from_loan/" + {{loan_id}}, params, function(data) {
DeactivateBFLRemSelButton()
$('#bfl-existing').load('/books_for_loan/' + {{loan_id}}, { 'InDBox' : 1 } )
} )
}
@@ -18,10 +25,36 @@
$('#dbox').modal('show')
$.post( "/books_for_loan/" + {{loan_id}}, function(data) {$('#bfl-existing').html(data) } );
}
function FindNewBFL()
{
$.post( "/search",{ 'term': $('#bfl-search-term').val(), 'InDBox': 1 }, function(data) { $('#bfl-new').html(data) ; $('#bfl-addsel-btn').show() } );
}
function ActivateBFLAddSelButton()
{
$('#bfl-addsel-btn').removeClass('disabled')
$('#bfl-addsel-btn').attr('disabled',false)
}
function DeactivateBFLAddSelButton()
{
$('#bfl-addsel-btn').addClass('disabled')
$('#bfl-addsel-btn').attr('disabled',true)
$('#bfl-addsel-btn').attr('style','display:none')
}
function AddSelToLoan()
{
var params=$("#addsel_table :input").serializeArray()
$.post( "/add_books_to_loan/" + {{loan_id}}, params, function(data) {
DeactivateBFLAddSelButton()
DeactivateBFLRemSelButton()
$('#bfl-search-term').val('')
$('#bfl-new').html('')
$('#bfl-existing').load('/books_for_loan/' + {{loan_id}}, { 'InDBox' : 1 } )
} )
}
</script>
{% if not InDBox %}