Implemented custom templates by inventory type using PrinterTemplate object.
[htsworkflow.git] / htsworkflow / frontend / inventory / models.py
1 import logging
2
3 from django.db import models
4 from django.db.models.signals import pre_save
5
6 from htsworkflow.frontend.samples.models import Library
7 from htsworkflow.frontend.experiments.models import FlowCell
8 from htsworkflow.frontend.bcmagic.models import Printer
9
10
11 try:
12     import uuid
13 except ImportError, e:
14     # Some systems are using python 2.4, which doesn't have uuid
15     # this is a stub
16     logging.warning('Real uuid is not available, initializing fake uuid module')
17     class uuid:
18         def uuid1(self):
19             self.hex = None
20             return self
21
22 def _assign_uuid(sender, instance, **kwargs):
23     """
24     Assigns a UUID to model on save
25     """
26     print 'Entered _assign_uuid'
27     if instance.uuid is None or len(instance.uuid) != 32:
28         instance.uuid = uuid.uuid1().hex
29
30 def _switch_default(sender, instance, **kwargs):
31     """
32     When new instance has default == True, uncheck all other defaults
33     """
34     if instance.default:
35         other_defaults = PrinterTemplate.objects.filter(default=True)
36         
37         for other in other_defaults:
38             other.default = False
39             other.save()
40     
41
42 class Vendor(models.Model):
43     name = models.CharField(max_length=256)
44     url = models.URLField(blank=True, null=True)
45
46     def __unicode__(self):
47         return u"%s" % (self.name)
48
49
50 class Location(models.Model):
51     
52     name = models.CharField(max_length=256, unique=True)
53     location_description = models.TextField()
54     
55     uuid = models.CharField(max_length=32, blank=True, help_text="Leave blank for automatic UUID generation", editable=False)
56     
57     notes = models.TextField(blank=True, null=True)
58     
59     def __unicode__(self):
60         if len(self.location_description) > 16:
61             return u"%s: %s" % (self.name, self.location_description[0:16]+u"...")
62         else:
63             return u"%s: %s" % (self.name, self.location_description)
64
65 pre_save.connect(_assign_uuid, sender=Location)
66
67
68 class ItemInfo(models.Model):
69     model_id = models.CharField(max_length=256, blank=True, null=True)
70     part_number = models.CharField(max_length=256, blank=True, null=True)
71     lot_number = models.CharField(max_length=256, blank=True, null=True)
72     
73     url = models.URLField(blank=True, null=True)
74     
75     qty_purchased = models.IntegerField(default=1)
76     
77     vendor = models.ForeignKey(Vendor)
78     purchase_date = models.DateField(blank=True, null=True)
79     warranty_months = models.IntegerField(blank=True, null=True)
80     
81     notes = models.TextField(blank=True, null=True)
82     
83     def __unicode__(self):
84         name = u''
85         if self.model_id:
86             name += u"model:%s " % (self.model_id)
87         if self.part_number:
88             name += u"part:%s " % (self.part_number)
89         if self.lot_number:
90             name += u"lot:%s " % (self.lot_number)
91             
92         return u"%s: %s" % (name, self.purchase_date)
93     
94     class Meta:
95         verbose_name_plural = "Item Info"
96
97
98 class ItemType(models.Model):
99     
100     name = models.CharField(max_length=64, unique=True)
101     description = models.TextField(blank=True, null=True)
102     
103     def __unicode__(self):
104         return u"%s" % (self.name)
105
106 class ItemStatus(models.Model):
107     name = models.CharField(max_length=64, unique=True)
108     notes = models.TextField(blank=True, null=True)
109     
110     def __unicode__(self):
111         return self.name
112     
113     class Meta:
114         verbose_name_plural = "Item Status"
115
116
117 class Item(models.Model):
118     
119     item_type = models.ForeignKey(ItemType)
120     
121     #Automatically assigned uuid; used for barcode if one is not provided in
122     # barcode_id
123     uuid = models.CharField(max_length=32, blank=True, help_text="Leave blank for automatic UUID generation", unique=True, editable=False)
124     
125     # field for existing barcodes; used instead of uuid if provided
126     barcode_id = models.CharField(max_length=256, blank=True, null=True)
127     force_use_uuid = models.BooleanField(default=False)
128     
129     item_info = models.ForeignKey(ItemInfo)
130     
131     location = models.ForeignKey(Location)
132     
133     status = models.ForeignKey(ItemStatus, blank=True, null=True)
134     
135     creation_date = models.DateTimeField(auto_now_add=True)
136     modified_date = models.DateTimeField(auto_now=True)
137     
138     notes = models.TextField(blank=True, null=True)
139     
140     def __unicode__(self):
141         if self.barcode_id is None or len(self.barcode_id) == 0:
142             return u"invu|%s" % (self.uuid)
143         else:
144             return u"invb|%s" % (self.barcode_id)
145             
146     def get_absolute_url(self):
147         return '/inventory/%s/' % (self.uuid)
148             
149 pre_save.connect(_assign_uuid, sender=Item)
150
151
152 class PrinterTemplate(models.Model):
153     """
154     Maps templates to printer to use
155     """
156     item_type = models.ForeignKey(ItemType)
157     printer = models.ForeignKey(Printer)
158     
159     default = models.BooleanField()
160     
161     template = models.TextField()
162     
163     def __unicode__(self):
164         if self.default:
165             return u'%s %s' % (self.item_type.name, self.printer.name)
166         else:
167             return u'%s %s (default)' % (self.item_type.name, self.printer.name)
168
169 pre_save.connect(_switch_default, sender=PrinterTemplate)
170
171
172 class LongTermStorage(models.Model):
173     
174     flowcell = models.ForeignKey(FlowCell)
175     libraries = models.ManyToManyField(Library)
176
177     storage_devices = models.ManyToManyField(Item)
178     
179     creation_date = models.DateTimeField(auto_now_add=True)
180     modified_date = models.DateTimeField(auto_now=True)
181     
182     def __unicode__(self):
183         return u"%s: %s" % (str(self.flowcell), ', '.join([ str(s) for s in self.storage_devices.iterator() ]))
184         
185     class Meta:
186         verbose_name_plural = "Long Term Storage"
187         
188
189
190 class ReagentBase(models.Model):
191     
192     reagent = models.ManyToManyField(Item)
193     
194     creation_date = models.DateTimeField(auto_now_add=True)
195     modified_date = models.DateTimeField(auto_now=True)
196     
197     class Meta:
198         abstract = True
199
200
201 class ReagentFlowcell(ReagentBase):
202     """
203     Links reagents and flowcells
204     """
205     flowcell = models.ForeignKey(FlowCell)
206     
207     def __unicode__(self):
208         return u"%s: %s" % (str(self.flowcell), ', '.join([ str(s) for s in self.reagent.iterator() ]))
209    
210
211 class ReagentLibrary(ReagentBase):
212     """
213     Links libraries and flowcells
214     """
215     library = models.ForeignKey(Library)
216     
217     def __unicode__(self):
218         return u"%s: %s" % (str(self.library), ', '.join([ str(s) for s in self.reagent.iterator() ]))