Example #1
0
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
Example #2
0
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
Example #3
0
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"
Example #4
0
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
Example #5
0
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)
Example #6
0
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()
Example #7
0
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