2d3825c0e4afa493fb52f59d14483fdc430ab482
[htsworkflow.git] / samplebc / samples / views.py
1 from django.http import HttpResponse, HttpResponseRedirect
2 from samplebc.samples import models
3 from django.core.exceptions import ObjectDoesNotExist
4 from django.template import Context, Template, RequestContext
5 from django.template.loader import get_template
6 from django.shortcuts import render_to_response
7 from django.contrib.auth.decorators import login_required
8
9 from django.utils.safestring import mark_safe
10
11 from samplebc.samples.forms import FreezerForm, ContainerForm, SampleForm, CmdMoveSampleForm
12 from samplebc.samples.models import Freezer, Container, Sample
13 from samplebc.samples.util import get_uuid, get_sampleid, assign_to_container
14 from samplebc.samples.errors import NoSpaceAvaliable
15 from samplebc import settings
16
17 # Barcode Magic!
18 from samplebc.bcmagic.forms import BarcodeMagicForm
19
20 # Reversion
21 from reversion import revision
22
23 import random
24 import ftplib
25 import StringIO
26
27
28 ################################################
29 # Util functions
30 ################################################
31
32 def print_zpl(zpl_text):
33     """
34     Sends zpl_text to printer
35     """
36     ftp = ftplib.FTP(host='131.215.54.194', user='blank', passwd='')
37     ftp.login()
38     ftp.storlines("STOR printme.txt", StringIO.StringIO(zpl_text))
39     ftp.quit()
40
41
42 def __center_line(line, width):
43     spaces_to_add = width - len(line)
44     
45     front_half = spaces_to_add / 2
46     back_half = spaces_to_add - front_half
47     
48     return (' ' * front_half) + line + (' ' * back_half)    
49
50
51   
52   
53 ################################################
54 # Container
55 ################################################
56 @login_required
57 def container_index(request):
58     """
59     Returns an index of available to containers
60     """
61     container_list = Container.objects.all()
62     c = Context({'title': 'Container Index',
63                  'container_list': container_list})
64     t = get_template('container_index.html')
65     
66     return render_to_response('app.html', {
67                                 'app_name': "HTSW-SampleTracker",
68                                 'page_name': 'Container Index',
69                                 'bcmagic': BarcodeMagicForm(),
70                                 'select': 'container',
71                                 'body': t.render(c)
72                             },
73                               context_instance=RequestContext(request))
74     
75
76
77 @login_required
78 def container_summary(request, container_id, msg=None):
79     """
80     Returns details of a container
81     """
82     # Retrieve container by UUID
83     try:
84         container = models.Container.objects.get(uuid=container_id)
85     except ObjectDoesNotExist, e:
86         msg = "Container (%s) does not exist." % (container_id)
87         return render_to_response('app.html', {
88                                     'app_name': settings.HTSW_ST_APPNAME,
89                                     'page_name': 'Container Summary',
90                                     'media': '',
91                                     'bcmagic': BarcodeMagicForm(),
92                                     'select': 'container',
93                                     'body': msg
94                                 },
95                                   context_instance=RequestContext(request))
96     
97     # Retrieve samples from container
98     sample_list = container.sample_set.all()
99     
100     # Prepare a Sample Index of Contained Samples
101     cs = Context({'title': 'Contained Samples',
102                  'sample_list': sample_list})
103     ts = get_template('sample_index.html')
104     
105     # Render prepared samples into container summary
106     cc = Context({'container': container,
107                   'msg': msg,
108                  'rendered_samples': ts.render(cs) })
109     tc = get_template('container_summary.html')
110     
111     # Render container summary to app html
112     return render_to_response('app.html', {
113                                 'app_name': settings.HTSW_ST_APPNAME,
114                                 'page_name': 'Container Summary',
115                                 'media': '',
116                                 'bcmagic': BarcodeMagicForm(),
117                                 'select': 'container',
118                                 'body': tc.render(cc)
119                             },
120                               context_instance=RequestContext(request))
121
122 @login_required
123 @revision.create_on_success
124 def container_add(request):
125     """
126     Form for adding a container.
127     """
128     #Reversion stuff
129     #revision.user = me
130     revision.comment = "New container created by user."
131     
132     # If user submitted the Container form.
133     if request.method == 'POST':
134         # Fill in ContainerForm with POSTed data.
135         form = ContainerForm(request.POST)
136         
137         # If the form is valid, process it.
138         if form.is_valid():
139             # Create new Container object from form data
140             c_obj = form.save(commit=False)
141             # Added UUID
142             c_obj.uuid = get_uuid()
143             # Save to DB.
144             c_obj.save()
145             # Save the many to many link data.
146             form.save_m2m()
147             return container_summary(request, c_obj.uuid)
148     else:
149         # If users first visit, create empty form.
150         form = ContainerForm()
151         
152     # Load form template
153     c = Context({'form': form,
154                  'action_url': '/samples/container/add/'})
155     t = get_template('generic_form.html')
156
157     return render_to_response('app.html', {
158                                 'app_name': settings.HTSW_ST_APPNAME,
159                                 'page_name': 'Container Add',
160                                 'media': form.media,
161                                 'bcmagic': BarcodeMagicForm(),
162                                 'select': 'container',
163                                 'body': t.render(c)
164                             },
165                               context_instance=RequestContext(request))
166
167 @login_required
168 @revision.create_on_success
169 def container_edit(request, container_id):
170     """
171     Allow editing of a container
172     """
173     #Reversion stuff
174     revision.comment = "Manual container edit by user."
175     
176     try:
177         container = models.Container.objects.get(uuid=container_id)
178     except ObjectDoesNotExist, e:
179         msg = "Container (%s) cannot be edited as it does not exist." % (container_id)
180         return render_to_response('app.html', {
181                                     'app_name': settings.HTSW_ST_APPNAME,
182                                     'page_name': 'Container Edit',
183                                     'media': '',
184                                     'bcmagic': BarcodeMagicForm(),
185                                     'select': 'container',
186                                     'body': msg
187                                 },
188                                   context_instance=RequestContext(request))
189     
190     # If user submitted the container form.
191     if request.method == 'POST':
192         # Fill in ContainerForm with POSTed data.
193         form = ContainerForm(request.POST, instance=container)
194         
195         # If the form is valid, process it.
196         if form.is_valid():
197             # Save Container object from form data
198             c_obj = form.save(commit=True)
199             # Save many2many changes as well
200             #form.save_m2m() #Not needed when form.save(commit=True)
201             
202             return container_summary(request, c_obj.uuid)
203     else:
204         # If users first visit, create form from Container instance.
205         form = ContainerForm(instance=container)
206
207     # Load form template
208     c = Context({'form': form,
209                  'action_url': '%sedit/' % (container.get_absolute_url())})
210     t = get_template('generic_form.html')
211
212     return render_to_response('app.html', {
213                                 'app_name': settings.HTSW_ST_APPNAME,
214                                 'page_name': 'Container Edit',
215                                 'media': form.media,
216                                 'bcmagic': BarcodeMagicForm(),
217                                 'select': 'container',
218                                 'body': t.render(c)
219                             },
220                               context_instance=RequestContext(request))
221
222 @login_required
223 def container_print(request, container_id):
224     """
225     prints a container label
226     """
227     
228     try:
229         container = models.Container.objects.get(uuid=container_id)
230     except ObjectDoesNotExist:
231         return HttpResponse('Container (%s) does not exist!' % (container_id))
232     
233     params = {}
234     params['container_name'] = __center_line(container.name[0:17], 17)
235     params['line1'] = __center_line('%s' % (container.name[17:34]), 17)
236     params['line2'] = __center_line('%s' % (container.name[34:51]), 17)
237     params['line3'] = __center_line('%s' % (container.name[51:68]), 17)
238     params['line4'] = __center_line('%s' % (container.name[68:85]), 17)
239     params['barcode'] = 'cntr|%s' % (container.uuid)
240     params['symbol'] = ''
241     
242     c = RequestContext(request, params)
243     t = get_template('zpl_container_label.txt')
244     print_zpl(t.render(c))
245     
246     return container_summary(request, container_id, msg='print command for container %s sent.' % (container.uuid))
247
248
249 ################################################
250 # Freezer
251 ################################################
252 @login_required
253 def freezer_index(request):
254     """
255     Returns an index of available freezers
256     """
257     freezer_list = Freezer.objects.all()
258     c = Context({'freezer_list': freezer_list})
259     t = get_template('freezer_index.html')
260     
261     return render_to_response('app.html', {
262                                 'app_name': "HTSW-SampleTracker",
263                                 'page_name': 'Freezer Index',
264                                 'media': '',
265                                 'bcmagic': BarcodeMagicForm(),
266                                 'select': 'freezer',
267                                 'body': t.render(c)
268                             },
269                               context_instance=RequestContext(request))
270     
271 @login_required    
272 def freezer_summary(request, freezer_id, msg=None):
273     """
274     Returns summary of freezer_id
275     """
276     # Retrieve freezer by UUID
277     try:
278         freezer = models.Freezer.objects.get(uuid=freezer_id)
279     except ObjectDoesNotExist, e:
280         msg = "Freezer (%s) does not exist." % (freezer_id)
281         return render_to_response('app.html', {
282                                     'app_name': settings.HTSW_ST_APPNAME,
283                                     'page_name': 'Freezer Summary',
284                                     'media': '',
285                                     'bcmagic': BarcodeMagicForm(),
286                                     'select': 'freezer',
287                                     'body': msg
288                                     },
289                                   context_instance=RequestContext(request))
290     
291     # List of contained containers
292     container_list = freezer.container_set.all()
293     
294     
295     # Render prepared container index into freezer summary
296     cf = Context({'freezer': freezer,
297                   'msg': msg})
298     tf = get_template('freezer_summary.html')
299     
300     # Render Freezer summary to app html
301     return render_to_response('app.html', {
302                                 'app_name': settings.HTSW_ST_APPNAME,
303                                 'page_name': 'Freezer Summary',
304                                 'media': '',
305                                 'bcmagic': BarcodeMagicForm(),
306                                 'select': 'freezer',
307                                 'body': tf.render(cf)
308                             },
309                               context_instance=RequestContext(request))
310
311 @login_required
312 @revision.create_on_success
313 def freezer_add(request):
314     """
315     Allows you to add a new freezer.
316     """
317     #Reversion stuff
318     revision.comment = "New freezer created by user."
319     
320     # If user submitted the freezer form.
321     if request.method == 'POST':
322         # Fill in FreezerForm with POSTed data.
323         form = FreezerForm(request.POST)
324         
325         # If the form is valid, process it.
326         if form.is_valid():
327             # Create new Freezer object from form data
328             f_obj = form.save(commit=False)
329             # Added UUID
330             f_obj.uuid = get_uuid()
331             # Save to DB.
332             f_obj.save()
333             return freezer_summary(request, f_obj.uuid)
334     else:
335         # If users first visit, create empty form.
336         form = FreezerForm()
337
338     # Load form template
339     c = Context({'form': form,
340                  'action_url': '/samples/freezer/add/'})
341     t = get_template('generic_form.html')
342
343     return render_to_response('app.html', {
344                                 'app_name': settings.HTSW_ST_APPNAME,
345                                 'page_name': 'Freezer Add',
346                                 'media': form.media,
347                                 'bcmagic': BarcodeMagicForm(),
348                                 'select': 'freezer',
349                                 'body': t.render(c)
350                             },
351                               context_instance=RequestContext(request))
352
353 @login_required
354 @revision.create_on_success
355 def freezer_edit(request, freezer_id):
356     """
357     Allow editing of a freezer
358     """
359     #Reversion stuff
360     revision.comment = "Manual freezer edit by user."
361     
362     try:
363         freezer = models.Freezer.objects.get(uuid=freezer_id)
364     except ObjectDoesNotExist, e:
365         msg = "Freezer (%s) cannot be edited as it does not exist." % (freezer_id)
366         return render_to_response('app.html', {
367                                     'app_name': settings.HTSW_ST_APPNAME,
368                                     'page_name': 'Freezer Summary',
369                                     'media': '',
370                                     'bcmagic': BarcodeMagicForm(),
371                                     'select': 'freezer',
372                                     'body': msg
373                                     },
374                                   context_instance=RequestContext(request))
375     
376     # If user submitted the freezer form.
377     if request.method == 'POST':
378         # Fill in FreezerForm with POSTed data.
379         form = FreezerForm(request.POST, instance=freezer)
380         
381         # If the form is valid, process it.
382         if form.is_valid():
383             # Save Freezer object from form data
384             f_obj = form.save(commit=True)
385             
386             return freezer_summary(request, f_obj.uuid)
387     else:
388         # If users first visit, create form from freezer instance.
389         form = FreezerForm(instance=freezer)
390
391     # Load form template
392     c = Context({'form': form,
393                  'action_url': '%sedit/' % (freezer.get_absolute_url())})
394     t = get_template('generic_form.html')
395
396     return render_to_response('app.html', {
397                                 'app_name': settings.HTSW_ST_APPNAME,
398                                 'page_name': 'Freezer Edit',
399                                 'media': form.media,
400                                 'bcmagic': BarcodeMagicForm(),
401                                 'select': 'freezer',
402                                 'body': t.render(c)
403                             },
404                               context_instance=RequestContext(request))
405
406 @login_required
407 def freezer_print(request, freezer_id):
408     """
409     prints a freezer label
410     """
411     
412     try:
413         freezer = models.Freezer.objects.get(uuid=freezer_id)
414     except ObjectDoesNotExist:
415         return HttpResponse('Freezer (%s) does not exist!' % (freezer_id))
416     
417     params = {}
418     params['freezer_name'] = __center_line(freezer.name, 17)
419     params['line1'] = __center_line('%s' % (freezer.name[17:34]), 17)
420     params['line2'] = __center_line('%s' % (freezer.name[34:51]), 17)
421     params['line3'] = __center_line('%s' % (freezer.name[51:68]), 17)
422     params['line4'] = __center_line('Temp: %s C' % (freezer.temperature), 17)
423     params['barcode'] = 'frzr|%s' % (freezer.uuid)
424     params['symbol'] = ''
425     
426     c = RequestContext(request, params)
427     t = get_template('zpl_freezer_label.txt')
428     print_zpl(t.render(c))
429     
430     return freezer_summary(request, freezer_id, msg='print command for freezer %s sent.' % (freezer.uuid))
431
432
433 ################################################
434 # Samples
435 ################################################
436 @login_required
437 def sample_index(request):
438     """
439     return a list of samples and what we can do with them.
440     """
441     sample_list = models.Sample.objects.all()
442     
443     # Load form template
444     c = Context({'title': 'Sample Index',
445                  'sample_list': sample_list})
446     t = get_template('sample_index.html')
447     #html.append('%s <a href="/samples/sample/%s/print">(print)</a>' \
448     #            % (sample, sample.sampleid))
449         
450     return render_to_response('app.html', {
451                                 'app_name': settings.HTSW_ST_APPNAME,
452                                 'page_name': 'Samples Index',
453                                 'media': '',
454                                 'bcmagic': BarcodeMagicForm(),
455                                 'select': 'samples',
456                                 'body': t.render(c)
457                             },
458                               context_instance=RequestContext(request))
459
460 @login_required
461 def sample_homeless(request):
462     """
463     Returns an index of homeless samples
464     """
465     sample_list = Sample.objects.filter(container=None)
466     c = Context({'title': 'Homeless Samples',
467                  'sample_list': sample_list})
468     t = get_template('sample_homeless.html')
469     
470     return render_to_response('app.html', {
471                                 'app_name': "HTSW-SampleTracker",
472                                 'page_name': 'Homeless Samples',
473                                 'bcmagic': BarcodeMagicForm(),
474                                 'select': 'samples',
475                                 'body': t.render(c)
476                             },
477                               context_instance=RequestContext(request))
478     
479 @login_required
480 @revision.create_on_success
481 def sample_add(request):
482     """
483     Allow adding of a new sample
484     """
485     #Reversion stuff
486     revision.comment = "New sample created by user."
487     
488     ASSIGNED_CONTAINER = False
489     
490     # If user submitted the sample form.
491     if request.method == 'POST':
492         # Fill in SampleForm with POSTed data.
493         form = SampleForm(request.POST)
494         
495         # If the form is valid, process it.
496         if form.is_valid():
497             # Create new Sample object from form data
498             s_obj = form.save(commit=False)
499             
500             # Add sample ID
501             s_obj.sampleid = get_sampleid()
502             
503             # If the user wants us to assign a container.
504             if form.cleaned_data['assign_container']:
505                 # Choose container
506                 try:
507                     assign_to_container(s_obj)
508                     ASSIGNED_CONTAINER = True
509                 except NoSpaceAvaliable, e:
510                     #return HttpResponse("<b>Error:</b> %s<br /><i>You will need to prepare a new container before continuing.</i>" \
511                     #                    % (e))
512                     ASSIGNED_CONTAINER = False
513                                     
514             # Save to DB.
515             s_obj.save()
516             
517             if not ASSIGNED_CONTAINER:
518                 msg = "NOTE: Sample is homeless"
519                 return sample_summary(request, s_obj.sampleid, msg=msg)
520
521             
522             msg = "Sample created."
523             return sample_summary(request, s_obj.sampleid, msg=msg)
524     else:
525         # If users first visit, create empty form.
526         form = SampleForm()
527
528     # Load form template
529     c = Context({'form': form,
530                  'action_url': '/samples/sample/add/'})
531     t = get_template('generic_form.html')
532
533     return render_to_response('app.html', {
534                                 'app_name': settings.HTSW_ST_APPNAME,
535                                 'page_name': 'Sample Add',
536                                 'media': form.media,
537                                 'bcmagic': BarcodeMagicForm(),
538                                 'select': 'samples',
539                                 'body': t.render(c)
540                             },
541                               context_instance=RequestContext(request))
542     
543 @login_required
544 @revision.create_on_success
545 def sample_edit(request, sampleid):
546     """
547     Allow editing of a sample
548     """
549     #Reversion stuff
550     revision.comment = "Manual sample edit by user."
551     
552     try:
553         sample = models.Sample.objects.get(sampleid=sampleid)
554     except ObjectDoesNotExist, e:
555         msg = "Sample (%s) cannot be edited as it does not exist." % (sampleid)
556         return render_to_response('app.html', {
557                     'app_name': settings.HTSW_ST_APPNAME,
558                     'page_name': 'Sample Edit',
559                     'media': '',
560                     'bcmagic': BarcodeMagicForm(),
561                     'select': 'samples',
562                     'body': msg
563                 })
564     
565     # If user submitted the sample form.
566     if request.method == 'POST':
567         # Fill in SampleForm with POSTed data.
568         form = SampleForm(request.POST, instance=sample)
569         
570         # If the form is valid, process it.
571         if form.is_valid():
572             # Save Sample object from form data
573             s_obj = form.save(commit=True)
574             
575             msg = "Sample Update Saved"
576             return sample_summary(request, s_obj.sampleid, msg)
577     else:
578         # If users first visit, create form from sample instance.
579         form = SampleForm(instance=sample)
580
581     # Load form template
582     c = Context({'form': form,
583                  'action_url': '%sedit/' % (sample.get_absolute_url())})
584     t = get_template('generic_form.html')
585
586     return render_to_response('app.html', {
587                                 'app_name': settings.HTSW_ST_APPNAME,
588                                 'page_name': 'Sample Edit',
589                                 'media': form.media,
590                                 'bcmagic': BarcodeMagicForm(),
591                                 'select': 'samples',
592                                 'body': t.render(c)
593                             },
594                               context_instance=RequestContext(request))
595
596 @login_required
597 @revision.create_on_success
598 def sample_assign_container(request, sampleid):
599     """
600     Assigns sample to container using the assign to container algorithm
601     """
602     
603     sample = Sample.objects.get(sampleid=sampleid)
604     
605     try:
606         assign_to_container(sample)
607     except NoSpaceAvaliable, e:
608         return render_to_response('app.html', {
609                                     'app_name': settings.HTSW_ST_APPNAME,
610                                     'page_name': 'Sample Assign',
611                                     'media': '',
612                                     'bcmagic': BarcodeMagicForm(),
613                                     'select': 'samples',
614                                     'body': mark_safe("<b>Error:</b> %s<br /><i>You will need to prepare a new container before continuing.</i>" \
615                                                         % (e))
616                                     },
617                                   context_instance=RequestContext(request))
618         
619     sample.save()
620     
621     body = 'Sample (<a href="%s">%s</a>) assigned to container (<a href="%s">%s</a>)' \
622            % (sample.get_absolute_url(), str(sample), sample.container.get_absolute_url(), str(sample.container))
623     
624     #Reversion stuff
625     revision.comment = "Sample auto-assigned to container (%s: %s)" % (str(sample.container), sample.container.uuid)
626     
627     return render_to_response('app.html', {
628                                 'app_name': settings.HTSW_ST_APPNAME,
629                                 'page_name': 'Sample Assign',
630                                 'media': '',
631                                 'bcmagic': BarcodeMagicForm(),
632                                 'select': 'samples',
633                                 'body': mark_safe(body),
634                             },
635                             context_instance=RequestContext(request))
636
637 @login_required
638 def sample_summary(request, sampleid, msg=None):
639     """
640     Display a summary of a given sample
641     """
642     try:
643         sample = models.Sample.objects.get(sampleid=sampleid)
644     except ObjectDoesNotExist, e:
645         msg = "Sample (%s) does not exist." % (sampleid)
646         return render_to_response('app.html', {
647                                     'app_name': settings.HTSW_ST_APPNAME,
648                                     'page_name': 'Sample Summary',
649                                     'media': '',
650                                     'bcmagic': BarcodeMagicForm(),
651                                     'select': 'samples',
652                                     'body': msg
653                                 },
654                                   context_instance=RequestContext(request))
655     
656     c = Context({'sample': sample,
657                  'msg': msg,})
658     t = get_template('sample_summary.html')
659     
660     return render_to_response('app.html', {
661                                 'app_name': settings.HTSW_ST_APPNAME,
662                                 'page_name': 'Sample Summary',
663                                 'media': '',
664                                 'bcmagic': BarcodeMagicForm(),
665                                 'select': 'samples',
666                                 'body': t.render(c)
667                             },
668                               context_instance=RequestContext(request))
669
670 @login_required  
671 def sample_print(request, sampleid):
672     """
673     prints a sample!
674     """
675     
676     try:
677         sample = models.Sample.objects.get(sampleid=sampleid)
678     except ObjectDoesNotExist:
679         return HttpResponse('Sample (%s) does not exist!' % (sampleid))
680     
681     params = {}
682     params['fullid'] = str(sample)
683     params['sampleid'] = __center_line("s|%s" % (sample.sampleid), 16)
684     params['line1'] = __center_line(sample.name[0:10], 10)
685     params['line2'] = __center_line(sample.name[10:25], 14)
686     params['line3'] = __center_line('ExpType %s' % (sample.sample_type.name[0:8]), 15)
687     params['slot_num'] = random.randint(1,81)
688     
689     c = RequestContext(request, params)
690     t = get_template('half_inch_samples.txt')
691     print_zpl(t.render(c))
692     
693     return sample_summary(request, sampleid, msg='print command for sample %s sent.' % (sample.sampleid))
694
695 @login_required
696 def user_profile(request):
697     """
698     Information about the user
699     """
700     return render_to_response('registration/profile.html', {
701                                 'app_name': settings.HTSW_ST_APPNAME,
702                                 'page_name': 'User Profile',
703                                 'media': '',
704                                 'bcmagic': BarcodeMagicForm(),
705                                 'select': 'settings',
706                             },
707                               context_instance=RequestContext(request))
708
709 ################################################
710 # Barcode Magic Commands
711 ################################################
712
713 def __cmd_move_sample_return(form, request, msg=''):
714     """
715     A small helper function since this code is reused multiple times
716     """
717     # Load form template
718     c = Context({'form': form,
719                  'action_url': '.'})
720     t = get_template('generic_form.html')
721     
722     return render_to_response('app.html', {
723                                 'app_name': settings.HTSW_ST_APPNAME,
724                                 'page_name': 'CMD: Move Sample',
725                                 'media': '',
726                                 'bcmagic': BarcodeMagicForm({'bcm_mode': 'cmd_move_sample'}),
727                                 'select': 'samples',
728                                 'msg': msg,
729                                 'body': t.render(c)
730                             },
731                               context_instance=RequestContext(request))
732
733 @login_required
734 @revision.create_on_success
735 def cmd_move_sample(request):
736     """
737     Moves a sample to a target container
738     """
739     form = CmdMoveSampleForm()
740     # Process form:
741     if request.method == 'POST':
742         form = CmdMoveSampleForm(request.POST)
743         
744         #If for some reason the form is not valid, return
745         if not form.is_valid():
746             msg = "Form is not valid."
747             return __cmd_move_sample_return(form, request, msg)
748         
749         try:
750             sample = models.Sample.objects.get(sampleid=form.cleaned_data['sampleid'])
751         except ObjectDoesNotExist, e:
752             msg = "Sample %s does not exist." % (form.cleaned_data['sampleid'])
753             return __cmd_move_sample_return(form, request, msg)
754             
755         try:
756             container = models.Container.objects.get(uuid=form.cleaned_data['container_id'])
757         except ObjectDoesNotExist, e:
758             msg = "Container %s does not exist." % (form.cleaned_data['container_id'])
759             return __cmd_move_sample_return(form, request, msg)
760         
761         # Move the sample to the new container
762         old_container = sample.container
763         sample.container = container
764         if old_container is None:
765             revision.comment = "Sample (%s) moved from Homeless to Container(%s; uuid: %s)" \
766                                % (str(sample), str(container), container.uuid)
767         else:
768             revision.comment = "Sample (%s) moved from Container(%s; uuid: %s) to Container(%s; uuid: %s)" \
769                                % (str(sample), str(old_container), old_container.uuid, str(container), container.uuid)
770         sample.save()
771         
772         return __cmd_move_sample_return(CmdMoveSampleForm(), request, revision.comment)
773         
774     return __cmd_move_sample_return(form, request)
775         
776         
777     
778