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