def buildkit(request, kit_id=None): """ Helper view for building up kits. If no kit ID is passed, we ask for a kit. If a kit ID is passed (via URL), we ask for items to add. Workflow: Create (empty) kits in admin; come to this view and add items """ if "kit_id" in request.GET: return HttpResponseRedirect("/equipment/buildkit/%s/" % request.GET['kit_id']) title = "Enter/scan kit ID number" if kit_id: try: kit = Item.find_by_number(kit_id) assert(kit.itemtype.kit==True) title = "Adding equipment to %s" % kit except (Item.DoesNotExist, AssertionError): raise Http404 if request.method == "POST": number = request.POST['number'] item = Item.find_by_number(number) try: assert(item.itemtype.kit==False) # Don't add a kit to a kit assert(item.part_of_kit==None) # Item must not already be in a kit kit.contents.add(item) message = "Added %s" % item except ItemError, error_message: pass
def report(request, report_kind=None, number=None): """ General-purpose reporting view. To add a new report type, add an appropriate `if` clause here, and a corresponding `{% if ... %}` clause in the template for display. """ if report_kind: now = datetime.datetime.now() title = "%s Report" % report_kind.title() try: if report_kind == "kits": kits = Item.objects.filter(itemtype__kit=True) if report_kind == "item": item = Item.find_by_number(number) title = item if report_kind == "instock": itemtypes = [i for i in ItemType.objects.all() if i.how_many_in_stock()] if report_kind == "latepenalties": try: report_rows = _penalty_report_data(cohort=1, phase=number) csv_link = "/equipment/report/latepenalties-csv/" filename = "late_equipment.csv" except ValueError: report_rows = None error_message = "Can't generate report (incorrect phase?)" if report_kind.startswith("out-"): items = Item.objects.filter(status=Item.OUT, part_of_kit__isnull=True).order_by("due") if report_kind.startswith("overdue-"): items = Item.objects.filter(status=Item.OUT, due__lt=now, part_of_kit__isnull=True).order_by("due","checked_out_by") if report_kind.endswith("-student"): items = items.filter(checked_out_by__kind=STUDENT_KIND) if report_kind.endswith("-staff"): items = items.exclude(checked_out_by__kind=STUDENT_KIND) except ItemError, error_message: pass # Letting error_message get picked up by the template
def check_out(request, person_id=None, due_timestamp=None): """ This view handles all stages of the checkout operation. In order for checkout to begin, a person_id must be in the URL. Optional due_timestamp is also in the URL. Those are designed to persist; i.e. if you change the person the custom due date (if any) is kept, and if you change the due date the person (if any) is kept. """ # Set default due date values for use in "Change due date" form dummy_item = Item() dummy_item.set_due_datetime() example_due_date = dummy_item.due.date() example_due_time = dummy_item.due.time() # If a specific due-date was requested, set it if due_timestamp: custom_due_datetime = datetime.datetime.strptime(due_timestamp, "%Y-%m-%d-%H-%M") else: custom_due_datetime = None title = "Scan ID" try: # If a change is requested for person or due date, update the URL if set(["due_date", "due_time", "person_id"]).intersection(request.GET): url = checkout_url(request, due_timestamp, person_id) return HttpResponseRedirect(url) if person_id: person = Person.objects.get(id_number=person_id) if not person.is_active(): raise Person.DoesNotExist("ID EXPIRED") title = "Checking out equipment to %s" % person recent_checkouts = recent_transactions(person, kind=Transaction.CHECKOUT) if request.method == "POST" and request.POST['number']: try: item = Item.find_by_number(request.POST['number']) item.check_out(person, custom_due_datetime) message = "Checked out %s" % item soundfile = "Glass.aiff" except (ItemError, TransactionError), error_message: soundfile = "error.mp3" except Person.DoesNotExist, reason: title = "Bad ID" id_number = person_id or request.GET['person_id'] error_message = "%s: %s" % (id_number, reason) person = None soundfile = "error.mp3"
def item(request): """Display information on the specified item, with some editing options.""" title = "Find an item" if 'number' in request.GET: number = request.GET['number'] try: item = Item.find_by_number(number) title = unicode(item) history = item.transaction_set.all() except ItemError, error_message: pass
def process_data(number_list, options): """ Take a list of numbers and create a new equipment item for each. ItemType is specified in options.itemtype. """ check_data(number_list, options) added_count = 0 for number in number_list: number = number.upper() # Normalize to upper case if options.hipnumber: new_item = Item(itemtype=options.itemtype, hip_number=number) else: new_item = Item(itemtype=options.itemtype, serialnumber=number) if options.add: new_item.log_this("Added from %s" % options.datafile) new_item.save() added_count += 1 print "Added %s new items (%s)" % (added_count, options.itemtype)
def check_data(number_list, options): """Perform basic checks on provided numbers, and halt if problems are found.""" trouble = False std_num_len = len(number_list[0]) for number in number_list: dupes = Item.objects.filter( Q(hip_number=number) | Q(serialnumber=number)).count() if dupes: print "Number %s already present: %s" % ( number, Item.find_by_number(number)) trouble = True if len(number) != std_num_len: print "Number %s is different length (%s instead of %s)" % ( number, len(number), std_num_len) trouble = True if trouble: sys.exit()
def check_in(request): """ GET: Show check-in form. POST: Check in the scanned item. """ title = "Check in" if request.method == "POST": number = request.POST['number'] try: item = Item.find_by_number(number) person = item.checked_out_by title = "Checked in %s" % item if item.days_overdue(): title += " (OVERDUE)" item.check_in() message = item.transaction_set.latest() recent_checkins = recent_transactions(person, kind=Transaction.CHECKIN) except (ItemError, TransactionError), error_message: pass