Added a 'Print Labels' action to the Library Admin Page.
[htsworkflow.git] / htsworkflow / frontend / samples / models.py
index 9cc0b926f8af1d0cd617735e6e2d0686ef0f7f7b..cce961918138a1e7f57a1f300be3f3078d594159 100644 (file)
@@ -1,5 +1,8 @@
+import urlparse
 from django.db import models
-from django.contrib.auth.models import User
+from django.contrib.auth.models import User, UserManager
+from django.db.models.signals import pre_save, post_save
+from django.db import connection
 from htsworkflow.frontend import settings
 from htsworkflow.frontend.reports.libinfopar import *
 
@@ -58,6 +61,12 @@ class Condition(models.Model):
     class Meta:
         ordering = ["condition_name"]
 
+class ExperimentType(models.Model):
+  name = models.CharField(max_length=50, unique=True)
+
+  def __unicode__(self):
+    return unicode(self.name)
+
 class Tag(models.Model): 
   tag_name = models.CharField(max_length=100, db_index=True,blank=False,null=False) 
   TAG_CONTEXT = ( 
@@ -92,27 +101,43 @@ class Species(models.Model):
     ordering = ["scientific_name"]
   
 class Affiliation(models.Model):
-  name = models.CharField(max_length=256, db_index=True, verbose_name='Group Name')
-  contact = models.CharField(max_length=256, null=True, blank=True,verbose_name='Contact Name')  
+  name = models.CharField(max_length=256, db_index=True, verbose_name='Name')
+  contact = models.CharField(max_length=256, null=True, blank=True,verbose_name='Lab Name')  
   email = models.EmailField(null=True,blank=True)
+  users = models.ManyToManyField('HTSUser', null=True, blank=True)
+  users.admin_order_field = "username"
   
   def __unicode__(self):
     str = unicode(self.name)
-    if len(self.contact) != 0:
+    if self.contact is not None and len(self.contact) > 0:
       str += u' ('+self.contact+u')' 
     return str
 
+  def Users(self):
+      users = self.users.all().order_by('username')
+      return ", ".join([unicode(a) for a in users ])
+
   class Meta:
     ordering = ["name","contact"]
     unique_together = (("name", "contact"),)
 
+class LibraryType(models.Model):
+  name = models.CharField(max_length=255, unique=True)
+
+  def __unicode__(self):
+    return unicode(self.name)
+
+
 class Library(models.Model):
-  
-  library_id = models.CharField(max_length=30, primary_key=True, db_index=True)
+  id = models.CharField(max_length=10, primary_key=True)
   library_name = models.CharField(max_length=100, unique=True)
   library_species = models.ForeignKey(Species)
-  cell_line = models.ForeignKey(Cellline)
-  condition = models.ForeignKey(Condition)
+  # new field 2008 Mar 5, alter table samples_library add column "hidden" NOT NULL default 0;
+  hidden = models.BooleanField()
+  # new field 2009 Oct 6, alter table samples_library add column "account_number" varchar(100) NULL
+  account_number = models.CharField(max_length=100, null=True, blank=True)
+  cell_line = models.ForeignKey(Cellline, blank=True, null=True, verbose_name="Background")
+  condition = models.ForeignKey(Condition, blank=True, null=True)
   antibody = models.ForeignKey(Antibody,blank=True,null=True)
   # New field Aug/25/08. SQL: alter table fctracker_library add column "lib_affiliation" varchar(256)  NULL;
   affiliations = models.ManyToManyField(Affiliation,related_name='library_affiliations',null=True)
@@ -122,20 +147,11 @@ class Library(models.Model):
   # SQL to add column: alter table fctracker_library add column "replicate" smallint unsigned NULL;
   REPLICATE_NUM = ((1,1),(2,2),(3,3),(4,4))
   replicate =  models.PositiveSmallIntegerField(choices=REPLICATE_NUM,default=1) 
-
-  EXPERIMENT_TYPES = (
-      ('INPUT_RXLCh','INPUT_RXLCh'),
-      ('ChIP-seq', 'ChIP-seq'),
-      ('Sheared', 'Sheared'),
-      ('RNA-seq', 'RNA-seq'),
-      ('Methyl-seq', 'Methyl-seq'),
-      ('DIP-seq', 'DIP-seq'),
-    ) 
-  experiment_type = models.CharField(max_length=50, choices=EXPERIMENT_TYPES,
-                                     default='RNA-seq')
-  
+  experiment_type = models.ForeignKey(ExperimentType)
+  library_type = models.ForeignKey(LibraryType, blank=True, null=True)
   creation_date = models.DateField(blank=True, null=True)
-  made_for = models.ForeignKey(User)
+  made_for = models.CharField(max_length=50, blank=True, 
+      verbose_name='ChIP/DNA/RNA Made By')
   made_by = models.CharField(max_length=50, blank=True, default="Lorian")
   
   PROTOCOL_END_POINTS = (
@@ -150,20 +166,24 @@ class Library(models.Model):
       ('Done', 'Completed'),
     )
   stopping_point = models.CharField(max_length=25, choices=PROTOCOL_END_POINTS, default='Done')
-  amplified_from_sample = models.ForeignKey('self', blank=True, null=True)  
+  amplified_from_sample = models.ForeignKey('self', blank=True, null=True, related_name='amplified_into_sample')  
   
-  undiluted_concentration = models.DecimalField("Undiluted concentration (ng/ul)", max_digits=5, decimal_places=2, default=0, blank=True, null=True)
-  successful_pM = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
+  undiluted_concentration = models.DecimalField("Concentration", 
+      max_digits=5, decimal_places=2, blank=True, null=True,
+      help_text=u"Undiluted concentration (ng/\u00b5l)") 
+      # note \u00b5 is the micro symbol in unicode
+  successful_pM = models.DecimalField(max_digits=9, decimal_places=1, blank=True, null=True)
   ten_nM_dilution = models.BooleanField()
   avg_lib_size = models.IntegerField(default=225, blank=True, null=True)
   notes = models.TextField(blank=True)
   
   def __unicode__(self):
-    return u'#%s: %s' % (self.library_id, self.library_name)
+    return u'#%s: %s' % (self.id, self.library_name)
   
   class Meta:
     verbose_name_plural = "libraries"
-    ordering = ["-creation_date"] #["-library_id"]
+    #ordering = ["-creation_date"] 
+    ordering = ["-id"]
   
   def antibody_name(self):
     str ='<a target=_self href="/admin/samples/antibody/'+self.antibody.id.__str__()+'/" title="'+self.antibody.__str__()+'">'+self.antibody.nickname+'</a>' 
@@ -180,6 +200,15 @@ class Library(models.Model):
     for t in affs:
         ar.append(t.__unicode__())
     return '%s' % (", ".join(ar))
+    
+  def is_archived(self):
+    """
+    returns True if archived else False
+    """
+    if self.longtermstorage_set.count() > 0:
+        return True
+    else:
+        return False
 
   def libtags(self):
     affs = self.tags.all().order_by('tag_name')
@@ -189,15 +218,15 @@ class Library(models.Model):
     return u'%s' % ( ", ".join(ar))
 
   def DataRun(self):
-    str ='<a target=_self href="/admin/experiments/datarun/?q='+self.library_id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>' 
+    str ='<a target=_self href="/admin/experiments/datarun/?q='+self.id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>' 
     return str
   DataRun.allow_tags = True
 
   def aligned_m_reads(self):
-    return getLibReads(self.library_id)
+    return getLibReads(self.id)
 
   def aligned_reads(self):
-    res = getLibReads(self.library_id)
+    res = getLibReads(self.id)
 
     # Check data sanity
     if res[2] != "OK":
@@ -225,4 +254,45 @@ class Library(models.Model):
     else: tstr = 'not processed yet' 
     return tstr
   aligned_reads.allow_tags = True
+  
+  def public(self):
+    SITE_ROOT = '/'
+    summary_url = self.get_absolute_url()
+    return '<a href="%s">S</a>' % (summary_url,)
+  public.allow_tags = True
+    
+  @models.permalink
+  def get_absolute_url(self):
+    return ('htsworkflow.frontend.samples.views.library_to_flowcells', [str(self.id)])
+    
+  
+    
+
+
+class HTSUser(User):
+    """
+    Provide some site-specific customization for the django user class
+    """
+    #objects = UserManager()
 
+    class Meta:
+        ordering = ['first_name', 'last_name', 'username']
+
+    def admin_url(self):
+        return '/admin/%s/%s/%d' % (self._meta.app_label, self._meta.module_name, self.id)
+
+    def __unicode__(self):
+        #return unicode(self.username) + u" (" + unicode(self.get_full_name()) + u")"
+        return unicode(self.get_full_name()) + u' (' + unicode(self.username) + ')'
+    
+def HTSUserInsertID(sender, instance, **kwargs):
+    """
+    Force addition of HTSUsers when someone just modifies the auth_user object
+    """
+    u = HTSUser.objects.filter(pk=instance.id)
+    if len(u) == 0:
+        cursor = connection.cursor()
+        cursor.execute('INSERT INTO samples_htsuser (user_ptr_id) VALUES (%s);' % (instance.id,))
+        cursor.close()
+    
+post_save.connect(HTSUserInsertID, sender=User)