def holds_by_user(request): """ Tests: - GETTest - SecurityTest """ if request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request, {}) return HttpResponseForbidden(t.render(c)) books_on_hold = Book.objects.filter(status='O') user_dict = {} for book in books_on_hold: if not user_dict.has_key(book.holder): user_dict[book.holder] = Book.objects.filter( status='O', holder=book.holder).count() user_list_by_user = user_dict.items() user_list_by_count = [] for item in user_list_by_user: user_list_by_count.append((item[1], item[0])) user_list_by_count.sort(reverse=True) var_dict = {'user_list': user_list_by_count} return rtr('books/reports/holds_by_user.html', var_dict, context_instance=RC(request))
def remove_holds_by_user(request): """ Tests: - GETTest - SecurityTest - NotAllowedTest """ if not request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request) return HttpResponseForbidden(t.render(c)) for key, value in request.POST.items(): if "holder_id" == key: holder = User.objects.get(pk=int(value)) break books = Book.objects.filter(holder=holder, status='O') for book in books: Log(action='R', book=book, who=request.user).save() var_dict = {'removed': books.count()} books.update(status='F', hold_date=None, holder=None) template = 'books/update_book/remove_holds.html' return rtr(template, var_dict, context_instance=RC(request))
def metabook(request, metabook_id): """ Tests: - GETTest - SecurityTest """ if request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request, {}) return HttpResponseForbidden(t.render(c)) try: metabook = MetaBook.objects.get(id=metabook_id) except MetaBook.DoesNotExist: message = "Invalid MetaBook Ref #: %s" % metabook_id return tidy_error(request, message) var_dict = { 'metabook': metabook, 'books': Book.objects.filter(metabook=metabook).order_by('list_date'), } return rtr('books/reports/metabook.html', var_dict, context_instance=RC(request))
def user(request, user_id): """ Tests: - GETTest - SecurityTest """ if request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request, {}) return HttpResponseForbidden(t.render(c)) try: user_obj = User.objects.get(id=user_id) except User.DoesNotExist: user_obj = import_user(user_id) if user_obj == None: message = "Invalid Student ID: %s" % user_id return tidy_error(request, message) logs_of_books_for_sale = Log.objects.filter(book__seller=user_obj).filter( action='A') var_dict = { 'user_obj': user_obj, 'logs': Log.objects.filter(who=user_obj).order_by('when'), 'logs_of_books_for_sale': logs_of_books_for_sale, } return rtr('books/reports/user.html', var_dict, context_instance=RC(request))
def profile(request): """ Allow users to view their profile """ if not request.method == "GET": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['GET']) template = 'users/profile.html' return rtr(template, {}, context_instance=RC(request))
def edit_setting(request, setting_id): """ This view is used to update the values for an Application Setting Tests: - GETTest - SecurityTest """ if request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request, {}) return HttpResponseForbidden(t.render(c)) try: setting_obj = AppSetting.objects.get(id=setting_id) except AppSetting.DoesNotExist: # We need at least 1 thing to edit, otherwise bad things can happen var_dict = { 'message': "Didn't get any settings to process", } t = loader.get_template('400.html') c = RC(request, var_dict) return HttpResponseBadRequest(t.render(c)) initial = { 'name': setting_obj.name, 'value': setting_obj.value, 'description': setting_obj.description, } form = SettingForm(initial) var_dict = { 'form': form, 'name': setting_obj.name, 'value': setting_obj.value, 'description': setting_obj.description, 'id': setting_obj.id, } template = 'appsettings/update/edit.html' return rtr(template, var_dict, context_instance=RC(request))
def books_sold_within_date(request): """ Shows a list of all books sold within a given date range Test: - GETTest - SecurityTest """ if not request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request, {}) return HttpResponseForbidden(t.render(c)) date_range_form = DateRangeForm(request.POST) if not date_range_form.is_valid(): var_dict = { 'date_range_form': date_range_form, } return rtr('books/reports/menu.html', var_dict, context_instance=RC(request)) to_date = date_range_form.cleaned_data['to_date'] from_date = date_range_form.cleaned_data['from_date'] book_sale_logs = Log.objects.filter( action='S', when__gte=from_date).exclude(when__gt=to_date) # Find all the books for the related Logs books_sold = Book.objects.filter(id__in=book_sale_logs.values('book_id')) # Sum up the price of all the books retrieved previously total_money = books_sold.aggregate(total=Sum('price'))['total'] var_dict = { 'book_sale_logs': book_sale_logs.order_by('book__sell_date'), 'total_money': total_money, 'from_date': from_date, 'to_date': to_date, } return rtr('books/reports/books_sold_within_date.html', var_dict, context_instance=RC(request))
def attach_book(request): """ Tests: - GETTest - SecurityTest - NotAllowedTest """ # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request) return HttpResponseForbidden(t.render(c)) if not request.method == 'POST': t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) form = NewBookForm(request.POST) if not form.is_valid(): # The form has bad data. send the user back var_dict = {'form': form} template = 'books/attach_book.html' return rtr(template, var_dict, context_instance=RC(request)) # shorten our code line lengths below goc = Course.objects.get_or_create cd = form.cleaned_data # Get the course if it exists, otherwise create it. tpl = goc(department=cd['department'], number=cd['course_number']) course = tpl[0] metabook = MetaBook() metabook.title = form.cleaned_data['title'] metabook.author = form.cleaned_data['author'] metabook.barcode = form.cleaned_data['barcode'] metabook.edition = form.cleaned_data['edition'] metabook.save() metabook.courses.add(course) metabook.save() book = Book.objects.get(pk=form.cleaned_data['book_id']) book.metabook = metabook book.save() var_dict = {'book': book} template = 'books/attached.html' return rtr(template, var_dict, context_instance=RC(request))
def save_setting(request): """ Applies changes to an AppSetting on the edit page Tests: """ if not request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request) return HttpResponseForbidden(t.render(c)) form = SettingForm(request.POST) if form.is_valid(): id_to_edit = request.POST.get('IdToEdit') try: setting = AppSetting.objects.get(id=id_to_edit) except AppSetting.DoesNotExist: message = 'Application Setting with ref# "%s" does not exist' % id_to_edit return tidy_error(request, message) setting.name = form.cleaned_data['name'] setting.value = form.cleaned_data['value'] setting.description = form.cleaned_data['description'] setting.save() var_dict = {'appsetting': setting} template = 'appsettings/update/edited.html' return rtr(template, var_dict, context_instance=RC(request)) elif request.POST.get('IdToEdit'): # form isn't valid, but we have an id to work with. send user back id_to_edit = request.POST.get('IdToEdit') var_dict = { 'form': form, # 'too_many' : False, 'id': id_to_edit, # 'logs' : Log.objects.filter(setting=id_to_edit), } template = 'appsettings/update/edit.html' return rtr(template, var_dict, context_instance=RC(request))
def update(request): """ This view is used to update metabook data Tests: - GETTest - SecurityTest - NotAllowedTest """ if not request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request) return HttpResponseForbidden(t.render(c)) bunch = MetaBook.objects.none() action = request.POST.get("Action", '') for key, value in request.POST.items(): if "idToEdit" in key: bunch = bunch | MetaBook.objects.filter(pk=int(value)) if action == "Delete": bunch = bunch.exclude(status='D') var_dict = {'num_deleted': bunch.count()} bunch.update(status='D') template = 'books/update_book/deleted.html' return rtr(template, var_dict, context_instance=RC(request)) elif action == "Edit": if bunch.count() > 1: too_many = True else: too_many = False item = bunch[0] metabook_form = MetaBookForm(instance=item) course = item.courses.all()[0] course_form = CourseForm(instance=course) var_dict = { 'metabook_form' : metabook_form, 'course_form' : course_form, 'metabook_id' : item.id, 'course_id' : course.id, } template = 'books/edit_metabook.html' return rtr(template, var_dict, context_instance=RC(request)) elif action == "Save": metabook_id = request.POST.get('metabook_id', '') course_id = request.POST.get('course_id', '') metabook = MetaBook.objects.get(pk=metabook_id) course = Course.objects.get(pk=course_id) metabook_form = MetaBookForm(request.POST, instance=metabook) course_form = CourseForm(request.POST, instance=course) if metabook_form.is_valid() and course_form.is_valid(): dept = course_form.cleaned_data['department'] num = course_form.cleaned_data['number'] tpl = Course.objects.get_or_create(department=dept, number=num) course = tpl[0] metabook = metabook_form.save() metabook.courses.add(course) var_dict={'metabook': metabook} template = 'books/update_metabook/saved.html' return rtr(template, var_dict, context_instance=RC(request)) # the form isn't valid. send the user back var_dict = { 'metabook_form' : metabook_form, 'course_form' : course_form, # TODO need to check for metabook id before hitting here 'metabook_id' : metabook_id, } template = 'books/edit_metabook.html' return rtr(template, var_dict, context_instance=RC(request)) else: var_dict = {'action' : action} template = 'books/update_book/error.html' return rtr(template, var_dict, context_instance=RC(request))
def update_book(request): """ This view is used to update book data Tests: - GETTest - EmailTest - HoldGlitchTest - NotAllowedTest """ if not request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) bunch = Book.objects.none() action = request.POST.get("Action", '') # We need at least 1 thing to edit, otherwise bad things can happen # Since the keys have to be unique, the template appends a number to each idToEdit if not request.POST.has_key('idToEdit'): var_dict = { 'message': "Didn't get any books to process", } t = loader.get_template('400.html') c = RC(request, var_dict) return HttpResponseBadRequest(t.render(c)) # For each form key of idToEdit add its value to our list of items to process for value in request.POST.getlist('idToEdit'): bunch = bunch | Book.objects.filter(pk=int(value)) if action == "Delete": bunch = bunch.exclude(status='D') for book in bunch: Log(action='D', book=book, who=request.user).save() var_dict = {'num_deleted': bunch.count()} bunch.update(status='D') template = 'books/update_book/deleted.html' return rtr(template, var_dict, context_instance=RC(request)) elif action[:1] == "To Be Deleted"[:1]: # apparently some browsers have issues passing spaces # can't do this for Deleted, Seller Paid, and Sold Books bunch = bunch.exclude(status__in='DPS') send_tbd_emails(bunch) for book in bunch: Log(action='T', book=book, who=request.user).save() var_dict = { 'num_doomed': bunch.count(), 'num_owners': len(set(map(lambda x: x.seller, bunch))), } bunch.update(status='T') template = 'books/update_book/to_be_deleted.html' return rtr(template, var_dict, context_instance=RC(request)) elif action == "Sold": # Allow only if For Sale or On Hold bunch = bunch.filter(status__in='FO') for book in bunch: Log(action='S', book=book, who=request.user).save() send_sold_emails(list(bunch)) var_dict = { 'sold': bunch.count(), 'num_owners': len(set(map(lambda x: x.seller, bunch))), } bunch.update(status='S', sell_date=datetime.today()) template = 'books/update_book/sold.html' return rtr(template, var_dict, context_instance=RC(request)) elif action[:5] == "Seller Paid"[:5]: # apparently some browsers have issues passing spaces # only staff can do this if not request.user.is_staff: bunch = Book.objects.none() # A Seller can be paid only after the book was sold else: bunch = bunch.filter(status='S') for book in bunch: Log(action='P', book=book, who=request.user).save() var_dict = {'paid': bunch.count()} bunch.update(status='P') template = 'books/update_book/seller_paid.html' return rtr(template, var_dict, context_instance=RC(request)) elif action == "Missing": # Must be For Sale, On Hold or To Be Deleted for it to go Missing bunch = bunch.filter(status__in='FOT') for book in bunch: Log(action='M', book=book, who=request.user).save() send_missing_emails(bunch) var_dict = { 'num_owners': len(set(map(lambda x: x.seller, bunch))), 'num_missing': bunch.count(), } bunch.update(status='M') template = 'books/update_book/missing.html' return rtr(template, var_dict, context_instance=RC(request)) elif action[:4] == "Place on Hold"[:4]: # apparently some browsers have issues passing spaces extended = bunch.filter(status='O', holder=request.user) new_hold = bunch.filter(status='F') failed = bunch.exclude(status__in='OF', holder=request.user) for book in new_hold: Log(action='O', book=book, who=request.user).save() for book in extended: Log(action='X', book=book, who=request.user).save() held = extended | new_hold var_dict = { 'failed': failed, 'extended': extended, 'new_hold': new_hold, 'num_held': held.count(), 'total_price': sum(map(lambda x: x.price, held)), } extended.update(hold_date=datetime.today()) new_hold.update(status='O', hold_date=datetime.today(), holder=request.user) template = 'books/update_book/place_hold.html' return rtr(template, var_dict, context_instance=RC(request)) elif action[:5] == "Remove Holds"[:5]: bunch = bunch.filter(status='O') if not request.user.is_staff: bunch = bunch.filter(holder=request.user) for book in bunch: Log(action='R', book=book, who=request.user).save() var_dict = {'removed': bunch.count()} bunch.update(status='F', hold_date=None, holder=None) template = 'books/update_book/remove_holds.html' return rtr(template, var_dict, context_instance=RC(request)) elif action == "Edit": if bunch.count() > 1: too_many = True else: too_many = False item = bunch[0] initial = { 'seller': item.seller.id, 'price': item.price, 'barcode': item.metabook.barcode, } form = BookForm(initial=initial) logs = Log.objects.filter(book=item) var_dict = { 'form': form, 'too_many': too_many, 'id': item.id, 'logs': logs, } template = 'books/update_book/edit.html' return rtr(template, var_dict, context_instance=RC(request)) elif action == "Undelete": # only staff can do this if not request.user.is_staff: bunch = Book.objects.none() # Filter out any books that aren't deleted bunch = bunch.filter(status='D') # For each book revert to what its previous status was before being deleted for book in bunch: book.status = book.previous_status() book.save() Log(action='U', book=book, who=request.user).save() var_dict = {'num_undeleted': bunch.count()} template = 'books/update_book/undeleted.html' return rtr(template, var_dict, context_instance=RC(request)) else: var_dict = {'action': action} template = 'books/update_book/error.html' return rtr(template, var_dict, context_instance=RC(request))
def add_new_book(request): """ Tests: - GETTest - AddNewBookTest - SecurityTest - NotAllowedTest """ if not request.method == 'POST': t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request) return HttpResponseForbidden(t.render(c)) if request.POST.get("Action", '') == 'Add': form = NewBookForm(request.POST) if form.is_valid(): # This came from the add_book view, and we need to # create a book and a metabook barcode = form.cleaned_data['barcode'] price = form.cleaned_data['price'] sid = form.cleaned_data['seller'] author = form.cleaned_data['author'] title = form.cleaned_data['title'] ed = form.cleaned_data['edition'] dept = form.cleaned_data['department'] course_num = form.cleaned_data['course_number'] metabook = MetaBook(barcode=barcode, author=author, title=title, edition=ed) metabook.save() goc = Course.objects.get_or_create course, created = goc(department=dept, number=course_num) metabook.courses.add(course) metabook.save() try: seller = User.objects.get(pk=sid) except User.DoesNotExist: seller = import_user(sid) if seller == None: message = "Invalid Student ID: %s" % sid return tidy_error(request, message) book = Book(seller=seller, price=Decimal(price), metabook=metabook) book.status = 'F' book.save() Log(book=book, who=request.user, action='A').save() var_dict = { 'title': metabook.title, 'author': metabook.author, 'seller_name': seller.get_full_name(), 'book_id': book.id, } template = 'books/update_book/added.html' return rtr(template, var_dict, context_instance=RC(request)) var_dict = {'form': form} template = 'books/add_new_book.html' return rtr(template, var_dict, context_instance=RC(request))
def update_book_edit(request): """ Applies changes to a book made on the edit page If the barcode doesn't exist, it makes the user create a MetaBook object as well Tests: - GETTest - SecurityTest - NotAllowedTest """ if not request.method == "POST": t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) # User must be staff or admin to get to this page if not request.user.is_staff: t = loader.get_template('403.html') c = RC(request) return HttpResponseForbidden(t.render(c)) form = BookForm(request.POST) if form.is_valid(): id_to_edit = request.POST.get('idToEdit') try: book = Book.objects.get(id=id_to_edit) except Book.DoesNotExist: message = 'Book with ref# "%s" does not exist' % id_to_edit return tidy_error(request, message) try: barcode = form.cleaned_data['barcode'] book.metabook = MetaBook.objects.get(barcode=barcode) except MetaBook.DoesNotExist: # barcode doesn't exist in db, we have to create a metabook. initial = { 'barcode': barcode, 'seller': form.cleaned_data['seller'], 'price': form.cleaned_data['price'], 'book_id': book.id, 'edition': '1', } form = NewBookForm(initial=initial) var_dict = {'form': form} template = 'books/attach_book.html' return rtr(template, var_dict, context_instance=RC(request)) try: seller_id = form.cleaned_data['seller'] book.seller = User.objects.get(id=seller_id) except User.DoesNotExist: user = import_user(seller_id) if user == None: message = "Invalid Student ID: %s" % id_to_edit return tidy_error(request, message) book.seller = user book.price = form.cleaned_data['price'] book.save() Log(who=request.user, action='E', book=book).save() var_dict = {'book': book} template = 'books/update_book/edited.html' return rtr(template, var_dict, context_instance=RC(request)) elif request.POST.get('idToEdit'): # form isn't valid, but we have an id to work with. send user back id_to_edit = request.POST.get('idToEdit') var_dict = { 'form': form, 'too_many': False, 'id': id_to_edit, 'logs': Log.objects.filter(book=id_to_edit), } template = 'books/update_book/edit.html' return rtr(template, var_dict, context_instance=RC(request))
def update_staff(request): """ Tests: GETTest """ if not request.method == 'POST': t = loader.get_template('405.html') c = RC(request) return HttpResponseNotAllowed(t.render(c), ['POST']) student_id = request.POST.get("student_id", '') action = request.POST.get('Action') # Delete User if action == "Delete" and student_id: # Delete single try: user = User.objects.get(id=student_id) user.is_superuser = False user.is_staff = False user.save() var_dict = {'num_deleted': 1} template = 'books/update_staff/deleted.html' return rtr(template, var_dict, context_instance=RC(request)) except User.DoesNotExist: return tidy_error(request, "Invalid Student ID: %s" % student_id) elif action == "Delete": # Delete multiple try: num_deleted = 0 for key, value in request.POST.items(): if "idToEdit" in key: user = User.objects.get(id=value) user.is_superuser = False user.is_staff = False user.save() num_deleted += 1 var_dict = {'num_deleted': num_deleted} template = 'books/update_staff/deleted.html' return rtr(template, var_dict, context_instance=RC(request)) except User.DoesNotExist: if num_deleted == 1: p = ' was' else: p = 's were' message = "Only %d user%s" % (num_deleted, p) + \ "deleted because %s is an invalid student ID" % value return tidy_error(request, message) elif action == "Save": try: user = User.objects.get(id=student_id) except User.DoesNotExist: twupass_backend = TWUPassBackend() user = twupass_backend.import_user(student_id) if user == None: return tidy_error(request, "Invalid Student ID: %s" % student_id) user.email = request.POST.get("email", '') if request.POST.get("role", '') == 'admin': user.is_superuser = True user.is_staff = True elif request.POST.get("role", '') == 'staff': user.is_staff = True user.save() var_dict = { 'user_name': user.get_full_name(), 'administrator': user.is_superuser } template = 'books/update_staff/saved.html' return rtr(template, var_dict, context_instance=RC(request))