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