1 from htsworkflow.frontend.samples.changelist import ChangeList
2 from htsworkflow.frontend.inventory.models import Item, LongTermStorage, ItemType
3 from htsworkflow.frontend.inventory.bcmagic import item_search
4 from htsworkflow.frontend.bcmagic.plugin import register_search_plugin
5 from htsworkflow.frontend.experiments.models import FlowCell
6 from htsworkflow.frontend.bcmagic.forms import BarcodeMagicForm
7 from htsworkflow.frontend.bcmagic.utils import print_zpl_socket
8 from htsworkflow.frontend import settings
9 #from htsworkflow.util.jsonutil import encode_json
11 from django.core.exceptions import ObjectDoesNotExist
12 from django.http import HttpResponse, HttpResponseRedirect
13 from django.shortcuts import render_to_response
14 from django.template import RequestContext, Template
15 from django.template.loader import get_template
16 from django.contrib.auth.decorators import login_required
18 register_search_plugin('Inventory Item', item_search)
22 except ImportError, e:
23 import simplejson as json
25 INVENTORY_CONTEXT_DEFAULTS = {
26 'app_name': 'Inventory Tracker',
27 'bcmagic': BarcodeMagicForm()
30 def __flowcell_rundate_sort(x, y):
34 if x.run_date > y.run_date:
36 elif x.run_date == y.run_date:
41 def __expand_longtermstorage_context(context, item):
43 Expand information for LongTermStorage
49 for lts in item.longtermstorage_set.all():
50 flowcell_list.append(lts.flowcell)
51 flowcell_id_list.append(lts.flowcell.flowcell_id)
52 library_id_list.extend([ lib.id for lib in lts.libraries.all() ])
54 flowcell_list.sort(__flowcell_rundate_sort)
55 context['oldest_rundate'] = flowcell_list[0].run_date
56 context['latest_rundate'] = flowcell_list[-1].run_date
58 context['flowcell_id_list'] = flowcell_id_list
59 context['library_id_list_1_to_20'] = library_id_list[0:20]
60 context['library_id_list_21_to_40'] = library_id_list[20:40]
61 context['library_id_list_41_to_60'] = library_id_list[40:60]
62 context['library_id_list_61_to_80'] = library_id_list[60:80]
66 'Hard Drive': __expand_longtermstorage_context
69 #INVENTORY_ITEM_PRINT_DEFAULTS = {
70 # 'Hard Drive': 'inventory/hard_drive_shell.zpl',
71 # 'default': 'inventory/default.zpl',
72 # 'host': settings.BCPRINTER_PRINTER1_HOST
75 def getPrinterTemplateByType(item_type):
77 returns template to use given item_type
79 assert item_type.printertemplate_set.count() < 2
81 # Get the template for item_type
82 if item_type.printertemplate_set.count() > 0:
83 printer_template = item_type.printertemplate_set.all()[0]
84 return printer_template
88 printer_template = PrinterTemplate.objects.get(default=True)
89 except ObjectDoesNotExist:
90 msg = "No template for item type (%s) and no default template found" % (item_type.name)
93 return printer_template
97 def data_items(request):
99 Returns items in json format
101 item_list = Item.objects.all()
102 d = { 'results': len(item_list) }
105 for item in item_list:
107 item_d['uuid'] = item.uuid
108 item_d['barcode_id'] = item.barcode_id
109 item_d['model_id'] = item.item_info.model_id
110 item_d['part_number'] = item.item_info.part_number
111 item_d['lot_number'] = item.item_info.lot_number
112 item_d['vendor'] = item.item_info.vendor.name
113 item_d['creation_date'] = item.creation_date.strftime('%Y-%m-%d %H:%M:%S')
114 item_d['modified_date'] = item.modified_date.strftime('%Y-%m-%d %H:%M:%S')
115 item_d['location'] = item.location.name
117 # Item status if exists
118 if item.status is None:
119 item_d['status'] = ''
121 item_d['status'] = item.status.name
123 # Stored flowcells on device
124 if item.longtermstorage_set.count() > 0:
125 item_d['flowcells'] = ','.join([ lts.flowcell.flowcell_id for lts in item.longtermstorage_set.all() ])
127 item_d['flowcells'] = ''
129 item_d['type'] = item.item_type.name
134 return HttpResponse(json.dumps(d), content_type="application/javascript")
142 item_changelist = ChangeList(request, Item,
146 queryset=Item.objects.all()
150 'item_changelist': item_changelist,
151 'page_name': 'Inventory Index'
153 context_dict.update(INVENTORY_CONTEXT_DEFAULTS)
155 return render_to_response('inventory/inventory_index.html',
157 context_instance=RequestContext(request))
161 def item_summary_by_barcode(request, barcode_id, msg=''):
163 Display a summary for an item by barcode
166 item = Item.objects.get(barcode_id=barcode_id)
167 except ObjectDoesNotExist, e:
170 return item_summary_by_uuid(request, None, msg, item)
174 def item_summary_by_uuid(request, uuid, msg='', item=None):
176 Display a summary for an item
178 # Use item instead of looking it up if it is passed.
181 item = Item.objects.get(uuid=uuid)
182 except ObjectDoesNotExist, e:
186 'page_name': 'Item Summary',
191 context_dict.update(INVENTORY_CONTEXT_DEFAULTS)
193 return render_to_response('inventory/inventory_summary.html',
195 context_instance=RequestContext(request))
202 def __expand_context(context, item):
204 If EXPAND_CONTEXT dictionary has item.item_type.name function registered, use it to expand context
206 if item.item_type.name in EXPAND_CONTEXT:
207 expand_func = EXPAND_CONTEXT[item.item_type.name]
208 expand_func(context, item)
210 def _item_print(item, request):
212 Prints an item given a type of item label to print
214 #FIXME: Hard coding this for now... need to abstract later.
215 context = {'item': item}
216 __expand_context(context, item)
218 # Print using barcode_id
219 if not item.force_use_uuid and (item.barcode_id is None or len(item.barcode_id.strip())):
220 context['use_uuid'] = False
221 msg = 'Printing item with barcode id: %s' % (item.barcode_id)
224 context['use_uuid'] = True
225 msg = 'Printing item with UUID: %s' % (item.uuid)
227 printer_template = getPrinterTemplateByType(item.item_type)
229 c = RequestContext(request, context)
230 t = Template(printer_template.template)
231 print_zpl_socket(t.render(c), host=printer_template.printer.ip_address)
236 def item_print(request, uuid):
238 Print a label for a given item
241 item = Item.objects.get(uuid=uuid)
242 except ObjectDoesNotExist, e:
244 msg = "Item with UUID %s does not exist" % (uuid)
247 msg = _item_print(item, request)
249 return item_summary_by_uuid(request, uuid, msg)
252 def link_flowcell_and_device(request, flowcell, serial):
254 Updates database records of a flowcell being archived on a device with a particular serial #
256 assert flowcell is not None
257 assert serial is not None
261 LIBRARY_UPDATED = False
263 ###########################################
264 # Retrieve Storage Device
266 sd = Item.objects.get(barcode_id=serial)
267 except ObjectDoesNotExist, e:
268 msg = "Item with barcode_id of %s not found." % (serial)
269 raise ObjectDoesNotExist(msg)
271 ###########################################
274 fc = FlowCell.objects.get(flowcell_id=flowcell)
275 except ObjectDoesNotExist, e:
276 msg = "FlowCell with flowcell_id of %s not found." % (flowcell)
277 raise ObjectDoesNotExist(msg)
279 ###########################################
280 # Retrieve or create LongTermStorage Object
281 count = fc.longtermstorage_set.count()
284 msg = "There really should only be one longtermstorage object per flowcell"
285 raise ValueError, msg
287 # lts already attached to flowcell
288 lts = fc.longtermstorage_set.all()[0]
290 lts = LongTermStorage()
293 # Need a primary keey before linking to storage devices
298 ############################################
299 # Link Storage to Flowcell
301 # Add a link to this storage device if it is not already linked.
302 if sd not in lts.storage_devices.all():
303 lts.storage_devices.add(sd)
306 ###########################################
307 # Add Library Links to LTS
309 for lane in fc.lane_set.all():
310 if lane.library not in lts.libraries.all():
311 lts.libraries.add(lane.library)
312 LIBRARY_UPDATED = True
318 if LTS_UPDATED or SD_UPDATED or LIBRARY_UPDATED:
319 msg.append(' LongTermStorage (LTS) Created: %s' % (LTS_UPDATED))
320 msg.append(' Storage Device Linked to LTS: %s' % (SD_UPDATED))
321 msg.append(' Libraries updated in LTS: %s' % (LIBRARY_UPDATED))
323 msg.append(' No Updates Needed.')
325 return HttpResponse('\n'.join(msg))