Updated inventory to support display of inventory items based on uuid/barcode_id...
[htsworkflow.git] / htsworkflow / frontend / inventory / views.py
1 from htsworkflow.frontend.inventory.models import Item, LongTermStorage
2 from htsworkflow.frontend.experiments.models import FlowCell
3 from htsworkflow.frontend.bcmagic.forms import BarcodeMagicForm
4 from htsworkflow.frontend.bcprinter.util import print_zpl_socket
5 from htsworkflow.frontend import settings
6 #from htsworkflow.util.jsonutil import encode_json
7
8 from django.core.exceptions import ObjectDoesNotExist
9 from django.http import HttpResponse, HttpResponseRedirect
10 from django.shortcuts import render_to_response
11 from django.template import RequestContext
12 from django.template.loader import get_template
13 from django.contrib.auth.decorators import login_required
14
15 try:
16     import json
17 except ImportError, e:
18     import simplejson as json
19
20 INVENTORY_CONTEXT_DEFAULTS = {
21     'app_name': 'Inventory Tracker',
22     'bcmagic': BarcodeMagicForm()
23 }
24
25 INVENTORY_ITEM_PRINT_DEFAULTS = {
26     'default': 'inventory/default.zpl',
27     'host': settings.BCPRINTER_PRINTER1_HOST
28 }
29
30 def getTemplateByType(item_type):
31     """
32     returns template to use given item_type
33     """
34     if item_type in INVENTORY_ITEM_PRINT_DEFAULTS:
35         return INVENTORY_ITEM_PRINT_DEFAULTS[item_type]
36     else:
37         return INVENTORY_ITEM_PRINT_DEFAULTS['default']
38
39 @login_required
40 def data_items(request):
41     """
42     Returns items in json format
43     """
44     item_list = Item.objects.all()
45     d = { 'results': len(item_list) }
46     rows = []
47     
48     for item in item_list:
49         item_d = {}
50         item_d['uuid'] = item.uuid
51         item_d['barcode_id'] = item.barcode_id
52         item_d['model_id'] = item.item_info.model_id
53         item_d['part_number'] = item.item_info.part_number
54         item_d['lot_number'] = item.item_info.lot_number
55         item_d['vendor'] = item.item_info.vendor.name
56         item_d['creation_date'] = item.creation_date.strftime('%Y-%m-%d %H:%M:%S')
57         item_d['modified_date'] = item.modified_date.strftime('%Y-%m-%d %H:%M:%S')
58         item_d['location'] = item.location.name
59         
60         # Item status if exists
61         if item.status is None:
62             item_d['status'] = ''
63         else:
64             item_d['status'] = item.status.name
65             
66         # Stored flowcells on device
67         if item.longtermstorage_set.count() > 0:
68             item_d['flowcells'] = ','.join([ lts.flowcell.flowcell_id for lts in item.longtermstorage_set.all() ])
69         else:
70             item_d['flowcells'] = ''
71         
72         item_d['type'] = item.item_type.name
73         rows.append(item_d)
74     
75     d['rows'] = rows
76     
77     return HttpResponse(json.dumps(d), content_type="application/javascript")
78
79 @login_required
80 def index(request):
81     """
82     Inventory Index View
83     """
84     context_dict = {
85         'page_name': 'Inventory Index'
86     }
87     context_dict.update(INVENTORY_CONTEXT_DEFAULTS)
88     
89     return render_to_response('inventory/inventory_index.html',
90                               context_dict,
91                               context_instance=RequestContext(request))
92     
93
94 @login_required
95 def item_summary_by_barcode(request, barcode_id, msg=''):
96     """
97     Display a summary for an item by barcode
98     """
99     try:
100         item = Item.objects.get(barcode_id=barcode_id)
101     except ObjectDoesNotExist, e:
102         item = None
103         
104     return item_summary_by_uuid(request, None, msg, item)
105     
106
107 @login_required
108 def item_summary_by_uuid(request, uuid, msg='', item=None):
109     """
110     Display a summary for an item
111     """
112     # Use item instead of looking it up if it is passed.
113     if item is None:
114         try:
115             item = Item.objects.get(uuid=uuid)
116         except ObjectDoesNotExist, e:
117             item = None
118     
119     context_dict = {
120         'page_name': 'Item Summary',
121         'item': item,
122         'uuid': uuid,
123         'msg': msg
124     }
125     context_dict.update(INVENTORY_CONTEXT_DEFAULTS)
126     
127     return render_to_response('inventory/inventory_summary.html',
128                               context_dict,
129                               context_instance=RequestContext(request))
130
131
132 def _item_print(item, request):
133     """
134     Prints an item given a type of item label to print
135     """
136     #FIXME: Hard coding this for now... need to abstract later.
137     context = {'item': item}
138     
139     # Print using barcode_id
140     if not item.force_use_uuid and (item.barcode_id is None or len(item.barcode_id.strip())):
141         context['use_uuid'] = False
142         msg = 'Printing item with barcode id: %s' % (item.barcode_id)
143     # Print using uuid
144     else:
145         context['use_uuid'] = True
146         msg = 'Printing item with UUID: %s' % (item.uuid)
147     
148     c = RequestContext(request, context)
149     t = get_template(getTemplateByType(item.item_type.name))
150     print_zpl_socket(t.render(c))
151     
152     return msg
153
154 @login_required
155 def item_print(request, uuid):
156     """
157     Print a label for a given item
158     """
159     try:
160         item = Item.objects.get(uuid=uuid)
161     except ObjectDoesNotExist, e:
162         item = None
163         msg = "Item with UUID %s does not exist" % (uuid)
164     
165     if item is not None:
166         msg = _item_print(item, request)
167     
168     return item_summary_by_uuid(request, uuid, msg)
169
170
171 def link_flowcell_and_device(request, flowcell, serial):
172     """
173     Updates database records of a flowcell being archived on a device with a particular serial #
174     """
175     assert flowcell is not None
176     assert serial is not None
177     
178     LTS_UPDATED = False
179     SD_UPDATED = False
180     LIBRARY_UPDATED = False
181         
182     ###########################################
183     # Retrieve Storage Device
184     try:
185         sd = Item.objects.get(barcode_id=serial)
186     except ObjectDoesNotExist, e:
187         msg = "Item with barcode_id of %s not found." % (serial)
188         raise ObjectDoesNotExist(msg)
189     
190     ###########################################
191     # Retrieve FlowCell
192     try:    
193         fc = FlowCell.objects.get(flowcell_id=flowcell)
194     except ObjectDoesNotExist, e:
195         msg = "FlowCell with flowcell_id of %s not found." % (flowcell)
196         raise ObjectDoesNotExist(msg)
197     
198     ###########################################
199     # Retrieve or create LongTermStorage Object
200     count = fc.longtermstorage_set.count()
201     lts = None
202     if count > 1:
203         msg = "There really should only be one longtermstorage object per flowcell"
204         raise ValueError, msg
205     elif count == 1:
206         # lts already attached to flowcell
207         lts = fc.longtermstorage_set.all()[0]
208     else:
209         lts = LongTermStorage()
210         # Attach flowcell
211         lts.flowcell = fc
212         # Need a primary keey before linking to storage devices
213         lts.save()
214         LTS_UPDATED = True
215         
216         
217     ############################################
218     # Link Storage to Flowcell
219     
220     # Add a link to this storage device if it is not already linked.
221     if sd not in lts.storage_devices.all():
222         lts.storage_devices.add(sd)
223         SD_UPDATED = True
224     
225     ###########################################
226     # Add Library Links to LTS
227     
228     if fc.lane_1_library not in lts.libraries.all():
229         lts.libraries.add(fc.lane_1_library)
230         LIBRARY_UPDATED = True
231         print 1
232     
233     if fc.lane_2_library not in lts.libraries.all():
234         lts.libraries.add(fc.lane_2_library)
235         LIBRARY_UPDATED = True
236         print 2
237     
238     if fc.lane_3_library not in lts.libraries.all():
239         lts.libraries.add(fc.lane_3_library)
240         LIBRARY_UPDATED = True
241         print 3
242     
243     if fc.lane_4_library not in lts.libraries.all():
244         lts.libraries.add(fc.lane_4_library)
245         LIBRARY_UPDATED = True
246         print 4
247     
248     
249     if fc.lane_5_library not in lts.libraries.all():
250         lts.libraries.add(fc.lane_5_library)
251         LIBRARY_UPDATED = True
252         print 5
253     
254     if fc.lane_6_library not in lts.libraries.all():
255         lts.libraries.add(fc.lane_6_library)
256         LIBRARY_UPDATED = True
257         print 6
258     
259     if fc.lane_7_library not in lts.libraries.all():
260         lts.libraries.add(fc.lane_7_library)
261         LIBRARY_UPDATED = True
262         print 7
263     
264     if fc.lane_8_library not in lts.libraries.all():
265         lts.libraries.add(fc.lane_8_library)
266         LIBRARY_UPDATED = True
267         print 8
268         
269     # Save Changes
270     lts.save()
271     
272     msg = ['Success:']
273     if LTS_UPDATED or SD_UPDATED or LIBRARY_UPDATED:
274         msg.append('  LongTermStorage (LTS) Created: %s' % (LTS_UPDATED))
275         msg.append('   Storage Device Linked to LTS: %s' % (SD_UPDATED))
276         msg.append('       Libraries updated in LTS: %s' % (LIBRARY_UPDATED))
277     else:
278         msg.append('  No Updates Needed.')
279     
280     return HttpResponse('\n'.join(msg))