diff options
Diffstat (limited to 'archaeological_finds/models.py')
-rw-r--r-- | archaeological_finds/models.py | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/archaeological_finds/models.py b/archaeological_finds/models.py new file mode 100644 index 000000000..cea9a35f1 --- /dev/null +++ b/archaeological_finds/models.py @@ -0,0 +1,281 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2012 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + +from django.conf import settings +from django.contrib.gis.db import models +from django.utils.translation import ugettext_lazy as _, ugettext + +from ishtar_common.models import GeneralType, BaseHistorizedItem, \ + LightHistorizedItem, HistoricalRecords, OwnPerms, Source, Person + +from archaeological_operations.models import AdministrativeAct +from archaeological_context_records.models import ContextRecord, Dating +WAREHOUSE_AVAILABLE = 'archaeological_warehouse' in settings.INSTALLED_APPS +if WAREHOUSE_AVAILABLE: + from archaeological_warehouse.models import Warehouse, Container + +class MaterialType(GeneralType): + recommendation = models.TextField(_(u"Recommendation")) + parent = models.ForeignKey("MaterialType", blank=True, null=True, + verbose_name=_(u"Parent material")) + + class Meta: + verbose_name = _(u"Material type") + verbose_name_plural = _(u"Material types") + +class BaseItem(BaseHistorizedItem, OwnPerms): + label = models.CharField(_(u"ID"), max_length=60) + description = models.TextField(_(u"Description")) + context_record = models.ForeignKey(ContextRecord, + related_name='base_items', verbose_name=_(u"Context Record")) + is_isolated = models.NullBooleanField(_(u"Is isolated?"), blank=True, + null=True) + index = models.IntegerField(u"Index", default=0) + material_index = models.IntegerField(u"Material index", default=0) + history = HistoricalRecords() + + class Meta: + verbose_name = _(u"Base item") + verbose_name_plural = _(u"Base items") + permissions = ( + ("view_own_baseitem", ugettext(u"Can view own Base item")), + ("add_own_baseitem", ugettext(u"Can add own Base item")), + ("change_own_baseitem", ugettext(u"Can change own Base item")), + ("delete_own_baseitem", ugettext(u"Can delete own Base item")), + ) + + def __unicode__(self): + return self.label + + def get_last_item(self): + #TODO: manage virtuals - property(last_item) ? + items = self.item.filter().order_by("-order").all() + return items and items[0] + + def full_label(self): + return self._real_label() or self._temp_label() + + def material_type_label(self): + item = self.get_last_item() + items = [item and unicode(item.material_type) or ''] + ope = self.context_record.operation + items += [ope.code_patriarche or \ + (unicode(ope.year) + "-" + unicode(ope.operation_code))] + items += [self.context_record.label, unicode(self.material_index)] + return JOINT.join(items) + + def _real_label(self): + if not self.context_record.parcel.operation.code_patriarche: + return + item = self.get_last_item() + lbl = item.label or self.label + return JOINT.join([unicode(it) for it in ( + self.context_record.parcel.operation.code_patriarche, + self.context_record.label, + lbl) if it]) + + def _temp_label(self): + if self.context_record.parcel.operation.code_patriarche: + return + item = self.get_last_item() + lbl = item.label or self.label + return JOINT.join([unicode(it) for it in ( + self.context_record.parcel.year, + self.index, + self.context_record.label, + lbl) if it]) + +class Item(BaseHistorizedItem, OwnPerms): + TABLE_COLS = ['label', 'material_type', 'dating.period', + 'base_items.context_record.parcel.town', + 'base_items.context_record.parcel.operation.year', + 'base_items.context_record.parcel.operation.operation_code', + 'base_items.is_isolated'] + if settings.COUNTRY == 'fr': + TABLE_COLS.insert(6, + 'base_items.context_record.parcel.operation.code_patriarche') + base_items = models.ManyToManyField(BaseItem, verbose_name=_(u"Base item"), + related_name='item') + order = models.IntegerField(_(u"Order")) + label = models.CharField(_(u"ID"), max_length=60) + description = models.TextField(_(u"Description"), blank=True, null=True) + material_type = models.ForeignKey(MaterialType, + verbose_name = _(u"Material type")) + volume = models.FloatField(_(u"Volume (l)"), blank=True, null=True) + weight = models.FloatField(_(u"Weight (g)"), blank=True, null=True) + item_number = models.IntegerField(_("Item number"), blank=True, null=True) + upstream_treatment = models.ForeignKey("Treatment", blank=True, null=True, + related_name='downstream_treatment', verbose_name=_("Upstream treatment")) + downstream_treatment = models.ForeignKey("Treatment", blank=True, null=True, + related_name='upstream_treatment', verbose_name=_("Downstream treatment")) + dating = models.ForeignKey(Dating, verbose_name=_(u"Dating")) + if WAREHOUSE_AVAILABLE: + container = models.ForeignKey(Container, verbose_name=_(u"Container"), + blank=True, null=True, related_name='items') + history = HistoricalRecords() + + @classmethod + def get_years(cls): + years = set() + items = cls.objects.filter(downstream_treatment__isnull=True) + for item in items: + bi = item.base_items.all() + if not bi: + continue + bi = bi[0] + yr = bi.context_record.operation.start_date.year + years.add(yr) + return list(years) + + @classmethod + def get_by_year(cls, year): + return cls.objects.filter(downstream_treatment__isnull=True, + base_items__context_record__operation__start_date__year=year) + + @classmethod + def get_operations(cls): + operations = set() + items = cls.objects.filter(downstream_treatment__isnull=True) + for item in items: + bi = item.base_items.all() + if not bi: + continue + bi = bi[0] + pk = bi.context_record.operation.pk + operations.add(pk) + return list(operations) + + @classmethod + def get_by_operation(cls, operation_id): + return cls.objects.filter(downstream_treatment__isnull=True, + base_items__context_record__operation__pk=operation_id) + + @classmethod + def get_total_number(cls): + return cls.objects.filter(downstream_treatment__isnull=True).count() + + def duplicate(self, user): + dct = dict([(attr, getattr(self, attr)) for attr in ('order', 'label', + 'description', 'material_type', 'volume', 'weight', + 'item_number', 'dating')]) + dct['order'] += 1 + dct['history_modifier'] = user + new = self.__class__(**dct) + new.save() + for base_item in self.base_items.all(): + new.base_items.add(base_item) + return new + + class Meta: + verbose_name = _(u"Item") + verbose_name_plural = _(u"Items") + permissions = ( + ("view_own_item", ugettext(u"Can view own Item")), + ("add_own_item", ugettext(u"Can add own Item")), + ("change_own_item", ugettext(u"Can change own Item")), + ("delete_own_item", ugettext(u"Can delete own Item")), + ) + + def __unicode__(self): + return self.label + + def save(self, *args, **kwargs): + if not self.pk: + super(Item, self).save(*args, **kwargs) + for base_item in self.base_items.all(): + if not base_item.index: + idx = BaseItem.objects.filter(context_record=\ + base_item.context_record).aggregate(Max('index')) + base_item.index = idx and idx['index__max'] + 1 or 1 + if not base_item.material_index: + idx = BaseItem.objects.filter(context_record=\ + base_item.context_record, + item__material_type=self.material_type).aggregate( + Max('material_index')) + base_item.material_index = idx and \ + idx['material_index__max'] + 1 or 1 + base_item.save() + super(Item, self).save(*args, **kwargs) + +class ItemSource(Source): + class Meta: + verbose_name = _(u"Item documentation") + verbose_name_plural = _(u"Item documentations") + item = models.ForeignKey(Item, verbose_name=_(u"Item"), + related_name="source") + +class TreatmentType(GeneralType): + virtual = models.BooleanField(_(u"Virtual")) + class Meta: + verbose_name = _(u"Treatment type") + verbose_name_plural = _(u"Treatment types") + +class Treatment(BaseHistorizedItem, OwnPerms): + container = models.ForeignKey(Container, verbose_name=_(u"Container"), + blank=True, null=True) + description = models.TextField(_(u"Description"), blank=True, null=True) + treatment_type = models.ForeignKey(TreatmentType, + verbose_name=_(u"Treatment type")) + if WAREHOUSE_AVAILABLE: + location = models.ForeignKey(Warehouse, verbose_name=_(u"Location"), + blank=True, null=True) + person = models.ForeignKey(Person, verbose_name=_(u"Person"), + blank=True, null=True) + start_date = models.DateField(_(u"Start date"), blank=True, null=True) + end_date = models.DateField(_(u"End date"), blank=True, null=True) + history = HistoricalRecords() + + class Meta: + verbose_name = _(u"Treatment") + verbose_name_plural = _(u"Treatments") + permissions = ( + ("view_own_treatment", ugettext(u"Can view own Treatment")), + ("add_own_treatment", ugettext(u"Can add own Treatment")), + ("change_own_treatment", ugettext(u"Can change own Treatment")), + ("delete_own_treatment", ugettext(u"Can delete own Treatment")), + ) + + def __unicode__(self): + lbl = unicode(self.treatment_type) + if self.person: + lbl += u" %s %s" % (_(u"by"), unicode(self.person)) + return lbl + +class TreatmentSource(Source): + class Meta: + verbose_name = _(u"Treatment documentation") + verbose_name_plural = _(u"Treament documentations") + treatment = models.ForeignKey(Treatment, verbose_name=_(u"Treatment"), + related_name="source") + +class Property(LightHistorizedItem): + item = models.ForeignKey(Item, verbose_name=_(u"Item")) + administrative_act = models.ForeignKey(AdministrativeAct, + verbose_name=_(u"Administrative act")) + person = models.ForeignKey(Person, verbose_name=_(u"Person")) + start_date = models.DateField(_(u"Start date")) + end_date = models.DateField(_(u"End date")) + + class Meta: + verbose_name = _(u"Property") + verbose_name_plural = _(u"Properties") + + def __unicode__(self): + return self.person + JOINT + self.item + |