from conifer.syrup.models import *
for m in [LibraryUnit, ServiceDesk, Member, Department, Course, Term, UserProfile, NewsItem,
- Target]:
+ Target, PhysicalObject]:
admin.site.register(m)
# SIP checkout
class CheckInOut(m.Model):
- """A log of checkout events."""
+ """A log of checkout-to-patron and item-return events."""
is_checkout = m.BooleanField() # in or out?
is_successful = m.BooleanField() # did the transaction work?
staff = m.ForeignKey(User) # who processed the request?
patron = m.CharField(max_length=100) # barcode
patron_descrip = m.CharField(max_length=512) # ILS descrip
- item = m.CharField(max_length=100, null=True)
+ item = m.CharField(max_length=100, null=True) # item barcode
item_descrip = m.CharField(max_length=512, null=True)
outcome = m.CharField(max_length=1024, null=True) # text msg from ILS about transaction
processed = m.DateTimeField(auto_now_add=True)
+class PhysicalObject(m.Model):
+ """A record of a physical object entering and leaving the Reserves area."""
+ barcode = m.CharField(max_length=100) # item barcode
+ receiver = m.ForeignKey(User, related_name='receiver') # who received the item?
+ received = m.DateTimeField(auto_now_add=True)
+ departer = m.ForeignKey(User, blank=True, null=True, related_name='departer') # who sent it away?
+ departed = m.DateTimeField(blank=True, null=True)
+ # an optional small-integer used as a human-shareable barcode by some institutions.
+ smallint = m.IntegerField(blank=True, null=True)
+
+
+ def save(self, force_insert=False, force_update=False):
+ # Must ensure that barcode is unique for non-departed items. Same with smallint
+ try:
+ already = PhysicalObject.objects.exclude(pk=self.id).get(departed=None)
+ if self.smallint:
+ already = PhysicalObject.objects.exclude(pk=self.id).get(smallint=smallint)
+ except PhysicalObject.DoesNotExist:
+ super(PhysicalObject, self).save(force_insert, force_update)
+ else:
+ raise AssertionError, 'barcode is not unique in active PhysicalObject collection.'
+
+ @classmethod
+ def by_barcode(cls, barcode):
+ """Find object by barcode, searching *only* the non-departed items."""
+ res = cls.objects.filter(departed=None, barcode=barcode)
+ return res and res[0] or None
(r'^phys/$', 'phys_index'),
(r'^phys/checkout/$', 'phys_checkout'),
(r'^phys/mark_arrived/$', 'phys_mark_arrived'),
+ (r'^phys/mark_arrived/match/$', 'phys_mark_arrived_match'),
(r'^course/(?P<course_id>\d+)/reseq$', 'course_reseq'),
(ITEM_PREFIX + r'reseq', 'item_heading_reseq'),
return g.render('phys/mark_arrived.xhtml')
else:
barcode = request.POST.get('item', '').strip()
+ already = models.PhysicalObject.by_barcode(barcode)
+ if already:
+ msg = _('This item has already been marked as received. Date received: %s')
+ msg = msg % str(already.received)
+ return simple_message(_('Item already marked as received'), msg)
+
bib_id = lib_integration.barcode_to_bib_id(barcode)
marcxml = lib_integration.bib_id_to_marcxml(bib_id)
dct = marcxml_to_dictionary(marcxml)
bib_id=bib_id,
ranked=ranked,
metadata=dct)
+
+@admin_only
+def phys_mark_arrived_match(request):
+ #[(u'barcode', u'30007000110717'), (u'choose_27', u'on')]
+ choices = [int(k.split('_')[1]) for k in request.POST if k.startswith('choose_')]
+ if not choices:
+ return simple_message(_('No matching items selected!'),
+ _('You must select one or more matching items from the list.'))
+ else:
+ barcode = request.POST.get('barcode', '').strip()
+ assert barcode
+ smallint = request.POST.get('smallint', '').strip() # will be '' for now.
+ phys = models.PhysicalObject(barcode=barcode,
+ receiver = request.user,
+ smallint = smallint or None)
+ phys.save()
+
+ for c in choices:
+ item = models.Item.objects.get(pk=c)
+ if not item.barcode():
+ item.metadata_set.create(name='syrup:barcode', value=barcode)
+ item.save()
+ return simple_message(_('Matches saved.'), '', go_back=False)
+
+
</head>
<body>
<h1>${title}</h1>
- <form action="." method="POST">
<div>
<table class="metadata_table">
<tr><th>Item Barcode</th><td>${barcode}</td></tr>
</tr>
</table>
<h2>Matches</h2>
- <p><button>Associate with matches selected below</button></p>
+ <form action="match/" method="POST">
+ <div style="float: right;">
+ Optional: Small-number ID for this item:
+ <input type="text" name="smallint"/>
+ </div>
+ <p><input type="submit" value="Associate item with matches selected below"/></p>
+ <input type="hidden" name="barcode" value="${barcode}"/>
<table class="metadata_table">
<thead style="font-size: 70%;">
<tr><th py:for="v in 'Select Title Author Course Instructor Score'.split(' ')">${v}</th></tr>
</tr>
</tbody>
</table>
+ </form>
</div>
- </form>
</body>
</html>
<body>
<h1>${title}</h1>
${content}
- <p py:if="defined('go_back')"><a href="javascript:history.go(-1);">Go back</a></p>
+ <p py:if="go_back"><a href="javascript:history.go(-1);">Go back</a></p>
</body>
</html>