diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-02-18 01:05:08 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-02-18 01:05:08 +0100 |
commit | 50b565e74631a684b2b389cac55982db86d8d5ba (patch) | |
tree | a7256183a32a204ac4e90e2503483c5ffc1f33db | |
parent | 5e47cbfcbeb090762547042d809016074bf1c679 (diff) | |
download | Ishtar-50b565e74631a684b2b389cac55982db86d8d5ba.tar.bz2 Ishtar-50b565e74631a684b2b389cac55982db86d8d5ba.zip |
New management of modules
-rw-r--r-- | archaeological_context_records/ishtar_menu.py | 1 | ||||
-rw-r--r-- | archaeological_files/ishtar_menu.py | 2 | ||||
-rw-r--r-- | archaeological_finds/ishtar_menu.py | 1 | ||||
-rw-r--r-- | archaeological_finds/models.py | 28 | ||||
-rw-r--r-- | archaeological_operations/admin.py | 20 | ||||
-rw-r--r-- | archaeological_operations/forms.py | 47 | ||||
-rw-r--r-- | archaeological_operations/ishtar_menu.py | 6 | ||||
-rw-r--r-- | archaeological_operations/models.py | 437 | ||||
-rw-r--r-- | archaeological_operations/views.py | 3 | ||||
-rw-r--r-- | archaeological_operations/wizards.py | 8 | ||||
-rw-r--r-- | archaeological_warehouse/ishtar_menu.py | 1 | ||||
-rw-r--r-- | example_project/urls.py | 8 | ||||
-rw-r--r-- | ishtar_common/context_processors.py | 14 | ||||
-rw-r--r-- | ishtar_common/management/commands/update_specific_importers.py | 7 | ||||
-rw-r--r-- | ishtar_common/menu_base.py | 31 | ||||
-rw-r--r-- | ishtar_common/models.py | 57 | ||||
-rw-r--r-- | ishtar_common/tests.py | 6 | ||||
-rw-r--r-- | ishtar_common/views.py | 36 |
18 files changed, 366 insertions, 347 deletions
diff --git a/archaeological_context_records/ishtar_menu.py b/archaeological_context_records/ishtar_menu.py index 826f99b0f..8e8f32218 100644 --- a/archaeological_context_records/ishtar_menu.py +++ b/archaeological_context_records/ishtar_menu.py @@ -27,6 +27,7 @@ import models MENU_SECTIONS = [ (40, SectionItem('record_management', _(u"Context record"), + profile_restriction='context_record', childs=[MenuItem('record_search', _(u"Search"), model=models.ContextRecord, access_controls=['view_contextrecord', diff --git a/archaeological_files/ishtar_menu.py b/archaeological_files/ishtar_menu.py index b120d18d1..326fec23b 100644 --- a/archaeological_files/ishtar_menu.py +++ b/archaeological_files/ishtar_menu.py @@ -31,6 +31,7 @@ MENU_SECTIONS = [ (20, SectionItem( 'file_management', _(u"Archaeological file"), + profile_restriction='files', childs=[ MenuItem( 'file_search', _(u"Search"), @@ -79,6 +80,7 @@ MENU_SECTIONS = [ (100, SectionItem( 'dashboard', _(u"Dashboard"), + profile_restriction='files', childs=[MenuItem('dashboard_main', _(u"General informations"), model=models.File, access_controls=['change_file', 'change_own_file']), diff --git a/archaeological_finds/ishtar_menu.py b/archaeological_finds/ishtar_menu.py index a688adbb4..ea8cd2c1f 100644 --- a/archaeological_finds/ishtar_menu.py +++ b/archaeological_finds/ishtar_menu.py @@ -29,6 +29,7 @@ MENU_SECTIONS = [ (50, SectionItem( 'find_management', _(u"Find"), + profile_restriction='find', childs=[ MenuItem( 'find_search', _(u"Search"), diff --git a/archaeological_finds/models.py b/archaeological_finds/models.py index f677b1297..8685e8ddd 100644 --- a/archaeological_finds/models.py +++ b/archaeological_finds/models.py @@ -32,11 +32,7 @@ from ishtar_common.models import GeneralType, ImageModel, BaseHistorizedItem, \ 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 - -FILES_AVAILABLE = 'archaeological_files' in settings.INSTALLED_APPS +from archaeological_warehouse.models import Warehouse, Container class MaterialType(GeneralType): @@ -309,10 +305,9 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem): verbose_name=_("Downstream treatment")) datings = models.ManyToManyField(Dating, verbose_name=_(u"Dating"), related_name='find') - if WAREHOUSE_AVAILABLE: - container = models.ForeignKey( - Container, verbose_name=_(u"Container"), blank=True, null=True, - related_name='finds') + container = models.ForeignKey( + Container, verbose_name=_(u"Container"), blank=True, null=True, + related_name='finds') is_complete = models.NullBooleanField(_(u"Is complete?"), blank=True, null=True) object_types = models.ManyToManyField( @@ -559,16 +554,14 @@ class TreatmentType(GeneralType): class Treatment(BaseHistorizedItem, OwnPerms): external_id = models.CharField(_(u"External ID"), blank=True, null=True, max_length=120) - if WAREHOUSE_AVAILABLE: - container = models.ForeignKey(Container, verbose_name=_(u"Container"), - blank=True, null=True) + container = models.ForeignKey(Container, verbose_name=_(u"Container"), + blank=True, null=True) description = models.TextField(_(u"Description"), blank=True, null=True) comment = models.TextField(_(u"Comment"), 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) + location = models.ForeignKey(Warehouse, verbose_name=_(u"Location"), + blank=True, null=True) other_location = models.CharField(_(u"Other location"), max_length=200, blank=True, null=True) person = models.ForeignKey( @@ -610,9 +603,8 @@ class TreatmentSource(Source): class Property(LightHistorizedItem): find = models.ForeignKey(Find, verbose_name=_(u"Find")) - if FILES_AVAILABLE: - administrative_act = models.ForeignKey( - AdministrativeAct, verbose_name=_(u"Administrative act")) + administrative_act = models.ForeignKey( + AdministrativeAct, verbose_name=_(u"Administrative act")) person = models.ForeignKey(Person, verbose_name=_(u"Person"), related_name='properties') start_date = models.DateField(_(u"Start date")) diff --git a/archaeological_operations/admin.py b/archaeological_operations/admin.py index 2a0ec652c..34e6da2ca 100644 --- a/archaeological_operations/admin.py +++ b/archaeological_operations/admin.py @@ -24,17 +24,15 @@ from ishtar_common.admin import HistorizedObjectAdmin, GeneralTypeAdmin import models -FILES_AVAILABLE = 'archaeological_files' in settings.INSTALLED_APPS -if FILES_AVAILABLE: - class AdministrativeActAdmin(HistorizedObjectAdmin): - list_display = ('year', 'index', 'operation', 'associated_file', - 'act_type') - list_filter = ('act_type',) - search_fields = ('year', 'index') - model = models.AdministrativeAct +class AdministrativeActAdmin(HistorizedObjectAdmin): + list_display = ('year', 'index', 'operation', 'associated_file', + 'act_type') + list_filter = ('act_type',) + search_fields = ('year', 'index') + model = models.AdministrativeAct - admin.site.register(models.AdministrativeAct, AdministrativeActAdmin) +admin.site.register(models.AdministrativeAct, AdministrativeActAdmin) class PeriodAdmin(admin.ModelAdmin): @@ -78,9 +76,7 @@ admin.site.register(models.OperationSource, OperationSourceAdmin) class ParcelAdmin(HistorizedObjectAdmin): - list_display = ['section', 'parcel_number', 'operation'] - if FILES_AVAILABLE: - list_display.append('associated_file') + list_display = ['section', 'parcel_number', 'operation', 'associated_file'] search_fields = ('operation__name',) model = models.Parcel diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index d18e7cea7..37ccbf277 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -34,14 +34,11 @@ from django.utils.translation import ugettext_lazy as _, pgettext_lazy from django.utils.safestring import mark_safe from ishtar_common.models import valid_id, PersonType, Person, Town, \ - DocumentTemplate, Organization, OrganizationType + DocumentTemplate, Organization, OrganizationType, get_current_profile from ishtar_common.wizards import MultiValueDict -FILES_AVAILABLE = 'archaeological_files' in settings.INSTALLED_APPS - -if FILES_AVAILABLE: - from archaeological_files.models import File +from archaeological_files.models import File import models from widgets import ParcelWidget, SelectParcelWidget @@ -566,16 +563,16 @@ class OperationCodeInput(forms.TextInput): 'url': reverse_lazy('get_available_operation_code')} return mark_safe(rendered + js) -if FILES_AVAILABLE: - class OperationFormFileChoice(forms.Form): - form_label = _(u"Associated file") - associated_models = {'associated_file': File, } - currents = {'associated_file': File} - associated_file = forms.IntegerField( - label=_(u"Archaelogical file"), - widget=widgets.JQueryAutoComplete( - reverse_lazy('autocomplete-file'), associated_model=File), - validators=[valid_id(File)], required=False) + +class OperationFormFileChoice(forms.Form): + form_label = _(u"Associated file") + associated_models = {'associated_file': File, } + currents = {'associated_file': File} + associated_file = forms.IntegerField( + label=_(u"Archaelogical file"), + widget=widgets.JQueryAutoComplete( + reverse_lazy('autocomplete-file'), associated_model=File), + validators=[valid_id(File)], required=False) class OperationFormAbstract(forms.Form): @@ -814,14 +811,13 @@ class OperationFormGeneral(forms.Form): class OperationFormModifGeneral(OperationFormGeneral): operation_code = forms.IntegerField(label=_(u"Operation code"), required=False) - if FILES_AVAILABLE: - currents = {'associated_file': File} - associated_file = forms.IntegerField( - label=_(u"Archaelogical file"), - widget=widgets.JQueryAutoComplete( - reverse_lazy('autocomplete-file'), - associated_model=File), - validators=[valid_id(File)], required=False) + currents = {'associated_file': File} + associated_file = forms.IntegerField( + label=_(u"Archaelogical file"), + widget=widgets.JQueryAutoComplete( + reverse_lazy('autocomplete-file'), + associated_model=File), + validators=[valid_id(File)], required=False) def __init__(self, *args, **kwargs): super(OperationFormModifGeneral, self).__init__(*args, **kwargs) @@ -829,12 +825,13 @@ class OperationFormModifGeneral(OperationFormGeneral): self.fields.keyOrder.pop(self.fields.keyOrder.index('associated_file')) self.fields.keyOrder.insert(self.fields.keyOrder.index('in_charge'), 'associated_file') + if not get_current_profile().files: + self.fields.pop('associated_file') OperationFormModifGeneral.associated_models = \ OperationFormGeneral.associated_models.copy() -if FILES_AVAILABLE: - OperationFormModifGeneral.associated_models['associated_file'] = File +OperationFormModifGeneral.associated_models['associated_file'] = File class OperationFormPreventive(forms.Form): diff --git a/archaeological_operations/ishtar_menu.py b/archaeological_operations/ishtar_menu.py index 60f764ab7..5a22efd05 100644 --- a/archaeological_operations/ishtar_menu.py +++ b/archaeological_operations/ishtar_menu.py @@ -17,17 +17,15 @@ # See the file COPYING for details. -from django.conf import settings from django.utils.translation import ugettext_lazy as _, pgettext_lazy from ishtar_common.menu_base import SectionItem, MenuItem +from ishtar_common.models import get_current_profile import models # be carreful: each access_controls must be relevant with check_rights in urls -FILES_AVAILABLE = 'archaeological_files' in settings.INSTALLED_APPS - MENU_SECTIONS = [ (30, SectionItem( 'operation_management', _(u"Operation"), @@ -98,7 +96,7 @@ MENU_SECTIONS = [ ), ] -if FILES_AVAILABLE: +if get_current_profile().files: MENU_SECTIONS.insert( 1, ( diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 448adcd68..5bbe357c0 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -35,8 +35,6 @@ from ishtar_common.models import GeneralType, BaseHistorizedItem, \ Person, Organization, Town, Dashboard, IshtarUser, ValueGetter, \ DocumentTemplate, ShortMenuItem, DashboardFormItem, GeneralRelationType,\ GeneralRecordRelations, post_delete_record_relation, OperationType -FILES_AVAILABLE = 'archaeological_files' in settings.INSTALLED_APPS -FINDS_AVAILABLE = 'archaeological_finds' in settings.INSTALLED_APPS class RemainType(GeneralType): @@ -137,8 +135,7 @@ class Operation(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem, SHOW_URL = 'show-operation' TABLE_COLS = ['year_index', 'operation_type', 'remains', 'towns', 'start_date', 'excavation_end_date'] - if FILES_AVAILABLE: - TABLE_COLS.insert(4, 'associated_file_short_label') + TABLE_COLS.insert(4, 'associated_file_short_label') creation_date = models.DateField(_(u"Creation date"), default=datetime.date.today) end_date = models.DateField(_(u"Closing date"), null=True, blank=True) @@ -161,11 +158,10 @@ class Operation(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem, year = models.IntegerField(_(u"Year"), null=True, blank=True) operation_code = models.IntegerField(_(u"Operation code"), null=True, blank=True) - if FILES_AVAILABLE: - associated_file = models.ForeignKey( - 'archaeological_files.File', - related_name='operations', verbose_name=_(u"File"), - blank=True, null=True) + associated_file = models.ForeignKey( + 'archaeological_files.File', + related_name='operations', verbose_name=_(u"File"), + blank=True, null=True) operation_type = models.ForeignKey(OperationType, related_name='+', verbose_name=_(u"Operation type")) surface = models.IntegerField(_(u"Surface (m2)"), blank=True, null=True) @@ -286,15 +282,12 @@ class Operation(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem, return reverse('show-operation', args=[self.pk, '']) def has_finds(self): - if not FINDS_AVAILABLE: - return from archaeological_finds.models import BaseFind return BaseFind.objects.filter(context_record__operation=self).count() def finds(self): - if FINDS_AVAILABLE: - from archaeological_finds.models import BaseFind - return BaseFind.objects.filter(context_record__operation=self) + from archaeological_finds.models import BaseFind + return BaseFind.objects.filter(context_record__operation=self) def get_reference(self, full=False): ref = "" @@ -360,7 +353,7 @@ class Operation(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem, @property def associated_file_short_label(self): - if not FILES_AVAILABLE or not self.associated_file: + if not self.associated_file: return "" return self.associated_file.short_label @@ -453,10 +446,9 @@ def operation_post_save(sender, **kwargs): operation.fnap_financing = fnap_percent operation.save() cached_label_changed(sender, **kwargs) - if FILES_AVAILABLE and operation.associated_file: + if operation.associated_file: operation.associated_file.update_short_menu_class() - # manage parcel association - if FILES_AVAILABLE and operation.associated_file: + # manage parcel association for parcel in operation.parcels.all(): parcel.copy_to_file() post_save.connect(operation_post_save, sender=Operation) @@ -548,216 +540,214 @@ class ActType(GeneralType): verbose_name_plural = _(u"Act types") ordering = ('label',) -AdministrativeAct = None -if FILES_AVAILABLE: - class AdministrativeAct(BaseHistorizedItem, OwnPerms, ValueGetter): - TABLE_COLS = ['full_ref', 'year', 'index', 'act_type', 'act_object', - 'signature_date', 'associated_file', 'operation', - 'towns_label'] - TABLE_COLS_FILE = [ - 'full_ref', 'year', 'index', 'act_type', - 'act_object', 'associated_file', 'towns_label', - ] - TABLE_COLS_OPE = ['full_ref', 'year', 'index', 'act_type', 'operation', - 'act_object', 'towns_label'] - if settings.COUNTRY == 'fr': - TABLE_COLS.append('departments_label') - TABLE_COLS_FILE.append('departments_label') - TABLE_COLS_OPE.append('departments_label') - act_type = models.ForeignKey(ActType, verbose_name=_(u"Act type")) - in_charge = models.ForeignKey( - Person, blank=True, null=True, - related_name='adminact_operation_in_charge', - verbose_name=_(u"Person in charge of the operation"), - on_delete=models.SET_NULL,) - index = models.IntegerField(verbose_name=_(u"Index"), blank=True, - null=True) - operator = models.ForeignKey( - Organization, blank=True, null=True, - verbose_name=_(u"Archaeological preventive operator"), - related_name='adminact_operator', on_delete=models.SET_NULL) - scientist = models.ForeignKey( - Person, blank=True, null=True, - related_name='adminact_scientist', on_delete=models.SET_NULL, - verbose_name=_(u"Scientist in charge")) - signatory = models.ForeignKey( - Person, blank=True, null=True, related_name='signatory', - verbose_name=_(u"Signatory"), on_delete=models.SET_NULL,) - operation = models.ForeignKey( - Operation, blank=True, null=True, - related_name='administrative_act', verbose_name=_(u"Operation")) - if FILES_AVAILABLE: - associated_file = models.ForeignKey( - 'archaeological_files.File', - blank=True, null=True, - related_name='administrative_act', - verbose_name=_(u"Archaelogical file")) - signature_date = models.DateField(_(u"Signature date"), blank=True, - null=True) - year = models.IntegerField(_(u"Year"), blank=True, null=True) - act_object = models.TextField(_(u"Object"), max_length=300, blank=True, + +class AdministrativeAct(BaseHistorizedItem, OwnPerms, ValueGetter): + TABLE_COLS = ['full_ref', 'year', 'index', 'act_type', 'act_object', + 'signature_date', 'associated_file', 'operation', + 'towns_label'] + TABLE_COLS_FILE = [ + 'full_ref', 'year', 'index', 'act_type', + 'act_object', 'associated_file', 'towns_label', + ] + TABLE_COLS_OPE = ['full_ref', 'year', 'index', 'act_type', 'operation', + 'act_object', 'towns_label'] + if settings.COUNTRY == 'fr': + TABLE_COLS.append('departments_label') + TABLE_COLS_FILE.append('departments_label') + TABLE_COLS_OPE.append('departments_label') + act_type = models.ForeignKey(ActType, verbose_name=_(u"Act type")) + in_charge = models.ForeignKey( + Person, blank=True, null=True, + related_name='adminact_operation_in_charge', + verbose_name=_(u"Person in charge of the operation"), + on_delete=models.SET_NULL,) + index = models.IntegerField(verbose_name=_(u"Index"), blank=True, + null=True) + operator = models.ForeignKey( + Organization, blank=True, null=True, + verbose_name=_(u"Archaeological preventive operator"), + related_name='adminact_operator', on_delete=models.SET_NULL) + scientist = models.ForeignKey( + Person, blank=True, null=True, + related_name='adminact_scientist', on_delete=models.SET_NULL, + verbose_name=_(u"Scientist in charge")) + signatory = models.ForeignKey( + Person, blank=True, null=True, related_name='signatory', + verbose_name=_(u"Signatory"), on_delete=models.SET_NULL,) + operation = models.ForeignKey( + Operation, blank=True, null=True, + related_name='administrative_act', verbose_name=_(u"Operation")) + associated_file = models.ForeignKey( + 'archaeological_files.File', + blank=True, null=True, + related_name='administrative_act', + verbose_name=_(u"Archaelogical file")) + signature_date = models.DateField(_(u"Signature date"), blank=True, null=True) - if settings.COUNTRY == 'fr': - ref_sra = models.CharField(u"Référence SRA", max_length=15, - blank=True, null=True) - departments_label = models.TextField( - _(u"Departments"), blank=True, null=True, - help_text=_(u"Cached values get from associated departments")) - towns_label = models.TextField( - _(u"Towns"), blank=True, null=True, - help_text=_(u"Cached values get from associated towns")) - history = HistoricalRecords() - _prefix = 'adminact_' - - class Meta: - ordering = ('year', 'signature_date', 'index', 'act_type') - verbose_name = _(u"Administrative act") - verbose_name_plural = _(u"Administrative acts") - permissions = ( - ("view_administrativeact", - ugettext(u"Can view all Administrative act")), - ("view_own_administrativeact", - ugettext(u"Can view own Administrative act")), - ("add_own_administrativeact", - ugettext(u"Can add own Administrative act")), - ("change_own_administrativeact", - ugettext(u"Can change own Administrative act")), - ("delete_own_administrativeact", - ugettext(u"Can delete own Administrative act")), - ) + year = models.IntegerField(_(u"Year"), blank=True, null=True) + act_object = models.TextField(_(u"Object"), max_length=300, blank=True, + null=True) + if settings.COUNTRY == 'fr': + ref_sra = models.CharField(u"Référence SRA", max_length=15, + blank=True, null=True) + departments_label = models.TextField( + _(u"Departments"), blank=True, null=True, + help_text=_(u"Cached values get from associated departments")) + towns_label = models.TextField( + _(u"Towns"), blank=True, null=True, + help_text=_(u"Cached values get from associated towns")) + history = HistoricalRecords() + _prefix = 'adminact_' + + class Meta: + ordering = ('year', 'signature_date', 'index', 'act_type') + verbose_name = _(u"Administrative act") + verbose_name_plural = _(u"Administrative acts") + permissions = ( + ("view_administrativeact", + ugettext(u"Can view all Administrative act")), + ("view_own_administrativeact", + ugettext(u"Can view own Administrative act")), + ("add_own_administrativeact", + ugettext(u"Can add own Administrative act")), + ("change_own_administrativeact", + ugettext(u"Can change own Administrative act")), + ("delete_own_administrativeact", + ugettext(u"Can delete own Administrative act")), + ) + + def __unicode__(self): + return settings.JOINT.join( + [unicode(item) for item in [ + self.operation, self.associated_file, self.act_object] + if item]) - def __unicode__(self): - return settings.JOINT.join( - [unicode(item) for item in [ - self.operation, self.associated_file, self.act_object] - if item]) - - full_ref_lbl = _(u"Ref.") - - @property - def full_ref(self): - lbl = [] - if self.year: - lbl.append(unicode(self.year)) - if self.index: - lbl.append(u"n°%d" % self.index) - if settings.COUNTRY == 'fr' and self.ref_sra: - lbl.append(u"[%s]" % self.ref_sra) - return u" ".join(lbl) - - @property - def towns(self): - if self.associated_file: - return self.associated_file.towns.all() - elif self.operation: - return self.operation.towns.all() - return [] - - @property - def departments(self): - if settings.COUNTRY != 'fr': - return '' - q = None - if self.associated_file: - q = self.associated_file.towns.all() - elif self.operation: - q = self.operation.towns.all() - if not q: - return '' - dpts = [] - for town in q: - dpt = town.numero_insee[:2] - if dpt not in dpts: - dpts.append(dpt) - return ', '.join(list(sorted(dpts))) - - @property - def related_item(self): - return self.operation if self.operation else self.associated_file - - def get_filename(self): - filename = self.related_item.associated_filename - filename = u"-".join(filename.split('-')[:-1]) # remove date - if self.act_type.code: - filename += u"-" + self.act_type.code - if self.signature_date and self.index: - filename += u"-%d-%d" % (self.signature_date.year, - self.index) - if self.signature_date: - filename += u"-" + self.signature_date.strftime('%Y%m%d') - return filename - - def publish(self, template_pk=None): - if not self.act_type.associated_template.count(): + full_ref_lbl = _(u"Ref.") + + @property + def full_ref(self): + lbl = [] + if self.year: + lbl.append(unicode(self.year)) + if self.index: + lbl.append(u"n°%d" % self.index) + if settings.COUNTRY == 'fr' and self.ref_sra: + lbl.append(u"[%s]" % self.ref_sra) + return u" ".join(lbl) + + @property + def towns(self): + if self.associated_file: + return self.associated_file.towns.all() + elif self.operation: + return self.operation.towns.all() + return [] + + @property + def departments(self): + if settings.COUNTRY != 'fr': + return '' + q = None + if self.associated_file: + q = self.associated_file.towns.all() + elif self.operation: + q = self.operation.towns.all() + if not q: + return '' + dpts = [] + for town in q: + dpt = town.numero_insee[:2] + if dpt not in dpts: + dpts.append(dpt) + return ', '.join(list(sorted(dpts))) + + @property + def related_item(self): + return self.operation if self.operation else self.associated_file + + def get_filename(self): + filename = self.related_item.associated_filename + filename = u"-".join(filename.split('-')[:-1]) # remove date + if self.act_type.code: + filename += u"-" + self.act_type.code + if self.signature_date and self.index: + filename += u"-%d-%d" % (self.signature_date.year, + self.index) + if self.signature_date: + filename += u"-" + self.signature_date.strftime('%Y%m%d') + return filename + + def publish(self, template_pk=None): + if not self.act_type.associated_template.count(): + return + if not template_pk: + template = self.act_type.associated_template.all()[0] + else: + q = self.act_type.associated_template.filter(pk=template_pk) + if not q.count(): return - if not template_pk: - template = self.act_type.associated_template.all()[0] - else: - q = self.act_type.associated_template.filter(pk=template_pk) - if not q.count(): - return - template = q.all()[0] - return template.publish(self) - - def _get_index(self): - if not self.index: - c_index = 1 - q = AdministrativeAct.objects.filter( - act_type__indexed=True, signature_date__year=self.year, - index__isnull=False).order_by("-index") - if q.count(): - c_index = q.all()[0].index + 1 - self.index = c_index - conflict = AdministrativeAct.objects.filter( + template = q.all()[0] + return template.publish(self) + + def _get_index(self): + if not self.index: + c_index = 1 + q = AdministrativeAct.objects.filter( act_type__indexed=True, signature_date__year=self.year, - index=self.index) + index__isnull=False).order_by("-index") + if q.count(): + c_index = q.all()[0].index + 1 + self.index = c_index + conflict = AdministrativeAct.objects.filter( + act_type__indexed=True, signature_date__year=self.year, + index=self.index) + if self.pk: + conflict = conflict.exclude(pk=self.pk) + if conflict.count(): if self.pk: - conflict = conflict.exclude(pk=self.pk) - if conflict.count(): - if self.pk: - raise ValidationError(_(u"This index already exists for " - u"this year")) - else: - self._get_index() - - def clean(self, *args, **kwargs): - if not self.signature_date: - return super(AdministrativeAct, self).clean(*args, **kwargs) - self.year = self.signature_date.year - if not self.act_type.indexed: - return super(AdministrativeAct, self).clean(*args, **kwargs) - self._get_index() - super(AdministrativeAct, self).clean(*args, **kwargs) + raise ValidationError(_(u"This index already exists for " + u"this year")) + else: + self._get_index() + + def clean(self, *args, **kwargs): + if not self.signature_date: + return super(AdministrativeAct, self).clean(*args, **kwargs) + self.year = self.signature_date.year + if not self.act_type.indexed: + return super(AdministrativeAct, self).clean(*args, **kwargs) + self._get_index() + super(AdministrativeAct, self).clean(*args, **kwargs) - def save(self, *args, **kwargs): - if settings.COUNTRY == 'fr': - self.departments_label = self.departments - self.towns_label = u", ".join( - list(sorted([unicode(town) for town in self.towns]))) + def save(self, *args, **kwargs): + if settings.COUNTRY == 'fr': + self.departments_label = self.departments + self.towns_label = u", ".join( + list(sorted([unicode(town) for town in self.towns]))) - force = False - if 'force' in kwargs: - force = kwargs.pop('force') + force = False + if 'force' in kwargs: + force = kwargs.pop('force') - if not self.signature_date: - return super(AdministrativeAct, self).save(*args, **kwargs) - self.year = self.signature_date.year + if not self.signature_date: + return super(AdministrativeAct, self).save(*args, **kwargs) + self.year = self.signature_date.year - if not self.act_type.indexed: - return super(AdministrativeAct, self).save(*args, **kwargs) + if not self.act_type.indexed: + return super(AdministrativeAct, self).save(*args, **kwargs) - if not force: + if not force: + self._get_index() + else: + try: self._get_index() - else: - try: - self._get_index() - except: - pass + except: + pass - super(AdministrativeAct, self).save(*args, **kwargs) - if hasattr(self, 'associated_file') and self.associated_file: - self.associated_file.update_has_admin_act() - self.associated_file.update_short_menu_class() + super(AdministrativeAct, self).save(*args, **kwargs) + if hasattr(self, 'associated_file') and self.associated_file: + self.associated_file.update_has_admin_act() + self.associated_file.update_short_menu_class() def strip_zero(value): @@ -768,11 +758,10 @@ def strip_zero(value): class Parcel(LightHistorizedItem): - if FILES_AVAILABLE: - associated_file = models.ForeignKey( - 'archaeological_files.File', - related_name='parcels', verbose_name=_(u"File"), - blank=True, null=True) + associated_file = models.ForeignKey( + 'archaeological_files.File', + related_name='parcels', verbose_name=_(u"File"), + blank=True, null=True) operation = models.ForeignKey( Operation, related_name='parcels', blank=True, null=True, verbose_name=_(u"Operation")) @@ -867,7 +856,7 @@ class Parcel(LightHistorizedItem): def long_label(self): items = [unicode(self.operation) or - (FILES_AVAILABLE and unicode(self.associated_file)) or ""] + unicode(self.associated_file) or ""] items += [unicode(item) for item in [self.section, self.parcel_number] if item] return settings.JOINT.join(items) @@ -931,12 +920,10 @@ def parcel_post_save(sender, **kwargs): if parcel.operation and parcel.operation.pk and \ parcel.town not in list(parcel.operation.towns.all()): parcel.operation.towns.add(parcel.town) - if FILES_AVAILABLE and parcel.associated_file and \ + if parcel.associated_file and \ parcel.associated_file.pk and \ parcel.town not in list(parcel.associated_file.towns.all()): parcel.associated_file.towns.add(parcel.town) - if not FILES_AVAILABLE: - return if parcel.operation and parcel.associated_file: # parcels are copied between files and operations parcel.copy_to_operation() diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index 5299b7131..22d820b5b 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -30,6 +30,7 @@ from ishtar_common.wizards import SearchWizard, check_rights_condition from ishtar_common.forms import ClosingDateFormSelection from ishtar_common.forms_common import AuthorFormset, TownFormset, \ SourceDeletionForm +from ishtar_common.models import get_current_profile from wizards import * from forms import * import models @@ -243,7 +244,7 @@ wizard_steps = [ ('relations-operation_creation', RecordRelationsFormSet), ('abstract-operation_creation', OperationFormAbstract), ('final-operation_creation', FinalForm)] -if FILES_AVAILABLE: +if get_current_profile().files: wizard_steps.insert(0, ('filechoice-operation_creation', OperationFormFileChoice)) diff --git a/archaeological_operations/wizards.py b/archaeological_operations/wizards.py index 6e512e826..c90b6fa8a 100644 --- a/archaeological_operations/wizards.py +++ b/archaeological_operations/wizards.py @@ -31,9 +31,7 @@ from ishtar_common.wizards import Wizard, ClosingWizard, DeletionWizard, \ import models from forms import GenerateDocForm -FILES_AVAILABLE = 'archaeological_files' in settings.INSTALLED_APPS -if FILES_AVAILABLE: - from archaeological_files.models import File +from archaeological_files.models import File class OperationWizard(Wizard): @@ -59,7 +57,7 @@ class OperationWizard(Wizard): def get_current_file(self): step = self.steps.current - if not FILES_AVAILABLE or not step: + if not step: return file_form_key = 'general-' + self.url_name if self.url_name == 'operation_creation': @@ -104,8 +102,6 @@ class OperationWizard(Wizard): """ Get available towns """ - if not FILES_AVAILABLE: - return -1 towns = [] file = self.get_current_file() if not file: diff --git a/archaeological_warehouse/ishtar_menu.py b/archaeological_warehouse/ishtar_menu.py index 3551fab00..f9f0daf33 100644 --- a/archaeological_warehouse/ishtar_menu.py +++ b/archaeological_warehouse/ishtar_menu.py @@ -28,6 +28,7 @@ from archaeological_finds.models import Treatment MENU_SECTIONS = [ (60, SectionItem('find_management', _(u"Find"), + profile_restriction='warehouse', childs=[ MenuItem('warehouse_packaging', _(u"Packaging"), model=Treatment, diff --git a/example_project/urls.py b/example_project/urls.py index 203c44d4d..62a6b1e04 100644 --- a/example_project/urls.py +++ b/example_project/urls.py @@ -14,10 +14,10 @@ APP_LIST = ['archaeological_files_pdl', 'archaeological_files', 'archaeological_operations', 'archaeological_context_records', 'archaeological_warehouse', 'archaeological_finds'] for app in APP_LIST: - if app in settings.INSTALLED_APPS: - urlpatterns += patterns( - '', ('', include(app + '.urls')), - ) + # filter by activated apps? + urlpatterns += patterns( + '', ('', include(app + '.urls')), + ) urlpatterns += patterns( '', ('', include('ishtar_common.urls')), diff --git a/ishtar_common/context_processors.py b/ishtar_common/context_processors.py index ce303c344..03ba9bc36 100644 --- a/ishtar_common/context_processors.py +++ b/ishtar_common/context_processors.py @@ -25,18 +25,20 @@ from ishtar_common.utils import shortify from menus import Menu +from ishtar_common.models import get_current_profile from archaeological_operations.models import Operation +from archaeological_files.models import File +from archaeological_context_records.models import ContextRecord +from archaeological_finds.models import Find +profile = get_current_profile() CURRENT_ITEMS = [] -if 'archaeological_files' in settings.INSTALLED_APPS: - from archaeological_files.models import File +if profile.files: CURRENT_ITEMS.append((_(u"Archaeological file"), File)) CURRENT_ITEMS.append((_(u"Operation"), Operation)) -if 'archaeological_context_records' in settings.INSTALLED_APPS: - from archaeological_context_records.models import ContextRecord +if profile.context_record: CURRENT_ITEMS.append((_(u"Context record"), ContextRecord)) -if 'archaeological_finds' in settings.INSTALLED_APPS: - from archaeological_finds.models import Find +if profile.find: CURRENT_ITEMS.append((_(u"Find"), Find)) diff --git a/ishtar_common/management/commands/update_specific_importers.py b/ishtar_common/management/commands/update_specific_importers.py index c5445eb0b..9a13e3f3e 100644 --- a/ishtar_common/management/commands/update_specific_importers.py +++ b/ishtar_common/management/commands/update_specific_importers.py @@ -4,14 +4,11 @@ from optparse import make_option from django.core.management.base import BaseCommand -from django.conf import settings IMPORTERS = [] - -if 'archaeological_files' in settings.INSTALLED_APPS: - from archaeological_files.data_importer import FileImporterSraPdL - IMPORTERS.append(FileImporterSraPdL) +from archaeological_files.data_importer import FileImporterSraPdL +IMPORTERS.append(FileImporterSraPdL) class Command(BaseCommand): diff --git a/ishtar_common/menu_base.py b/ishtar_common/menu_base.py index ab0a43d41..eb08d8c78 100644 --- a/ishtar_common/menu_base.py +++ b/ishtar_common/menu_base.py @@ -17,16 +17,28 @@ # See the file COPYING for details. +from ishtar_common.models import get_current_profile + class SectionItem: - def __init__(self, idx, label, childs=[]): + def __init__(self, idx, label, childs=[], profile_restriction=None): self.idx = idx self.label = label self.childs = childs self.available = False self.items = {} + self.profile_restriction = profile_restriction + + def check_profile_restriction(self): + if self.profile_restriction: + profile = get_current_profile() + if not getattr(profile, self.profile_restriction): + return False + return True def can_be_available(self, user, session=None): + if not self.check_profile_restriction(): + return False for child in self.childs: if child.can_be_available(user, session=session): return True @@ -50,14 +62,27 @@ class SectionItem: class MenuItem: - def __init__(self, idx, label, model=None, access_controls=[]): + def __init__(self, idx, label, model=None, access_controls=[], + profile_restriction=None): self.idx = idx self.label = label self.model = model self.access_controls = access_controls self.available = False + self.profile_restriction = profile_restriction + if not self.check_profile_restriction(): + return False + + def check_profile_restriction(self): + if self.profile_restriction: + profile = get_current_profile() + if not getattr(profile, self.profile_restriction): + return False + return True def can_be_available(self, user, session=None): + if not self.check_profile_restriction(): + return False if not self.access_controls: return True prefix = (self.model._meta.app_label + '.') if self.model else '' @@ -75,6 +100,8 @@ class MenuItem: return False def is_available(self, user, obj=None, session=None): + if not self.check_profile_restriction(): + return False if not self.access_controls: return True prefix = (self.model._meta.app_label + '.') if self.model else '' diff --git a/ishtar_common/models.py b/ishtar_common/models.py index bcd1881d6..f5c6ed223 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -250,13 +250,16 @@ class OwnPerms: class Cached(object): + slug_field = 'txt_idx' + @classmethod def get_cache(cls, slug): cache_key, value = get_cache(cls, slug) if value: return value try: - obj = cls.objects.get(txt_idx=slug) + k = {cls.slug_field: slug} + obj = cls.objects.get(**k) cache.set(cache_key, obj, settings.CACHE_TIMEOUT) return obj except cls.DoesNotExist: @@ -768,6 +771,7 @@ class LightHistorizedItem(BaseHistorizedItem): class IshtarSiteProfile(models.Model, Cached): + slug_field = 'slug' label = models.TextField(_(u"Name")) slug = models.SlugField(_(u"Slug"), unique=True) description = models.TextField(_(u"Description"), null=True, blank=True) @@ -817,6 +821,20 @@ class IshtarSiteProfile(models.Model, Cached): return obj +def get_current_profile(): + cache_key, value = get_cache(IshtarSiteProfile, 'is-current-profile') + if value: + return value + q = IshtarSiteProfile.objects.filter(active=True) + if not q.count(): + obj = IshtarSiteProfile.objects.create( + label="Default profile", slug='default', active=True) + else: + obj = q.all()[0] + cache.set(cache_key, obj, settings.CACHE_TIMEOUT) + return obj + + class GlobalVar(models.Model, Cached): slug = models.SlugField(_(u"Variable name"), unique=True) description = models.TextField(_(u"Description of the variable"), @@ -1214,29 +1232,29 @@ class OrganizationType(GeneralType): verbose_name_plural = _(u"Organization types") ordering = ('label',) -MODELS = [ - ('archaeological_operations.models.Operation', _(u"Operation")), - ('archaeological_operations.models.ArchaeologicalSite', - _(u"Archaeological site")), - ('archaeological_operations.models.Parcel', _(u"Parcels")), - ('archaeological_operations.models.OperationSource', - _(u"Operation source")), -] - IMPORTER_CLASSES = {} -if 'archaeological_files' in settings.INSTALLED_APPS: - MODELS = [('archaeological_files.models.File', _(u"Archaeological files"))]\ - + MODELS - IMPORTER_CLASSES.update({ - 'sra-pdl-files': - 'archaeological_files.data_importer.FileImporterSraPdL'}) -if 'archaeological_context_records' in settings.INSTALLED_APPS: +IMPORTER_CLASSES.update({ + 'sra-pdl-files': + 'archaeological_files.data_importer.FileImporterSraPdL'}) + + +def get_importer_models(): + MODELS = [ + ('archaeological_operations.models.Operation', _(u"Operation")), + ('archaeological_operations.models.ArchaeologicalSite', + _(u"Archaeological site")), + ('archaeological_operations.models.Parcel', _(u"Parcels")), + ('archaeological_operations.models.OperationSource', + _(u"Operation source")), + ] + MODELS = [('archaeological_files.models.File', + _(u"Archaeological files"))] + MODELS MODELS = [('archaeological_context_records.models.ContextRecord', _(u"Context records")), ] + MODELS -if 'archaeological_finds' in settings.INSTALLED_APPS: MODELS = [('archaeological_finds.models.BaseFind', _(u"Finds")), ] + MODELS + return MODELS def get_model_fields(model): @@ -1274,7 +1292,8 @@ class ImporterType(models.Model): users = models.ManyToManyField('IshtarUser', verbose_name=_(u"Users"), blank=True, null=True) associated_models = models.CharField(_(u"Associated model"), - max_length=200, choices=MODELS) + max_length=200, + choices=get_importer_models()) is_template = models.BooleanField(_(u"Is template"), default=False) unicity_keys = models.CharField(_(u"Unicity keys (separator \";\")"), blank=True, null=True, max_length=500) diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index 4e800b0d5..e2c9b233f 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -182,3 +182,9 @@ class IshtarSiteProfileTest(TestCase): profile2.warehouse = True profile2 = profile2.save() self.assertTrue(profile2.context_record and profile2.find) + + def testDefaultProfile(self): + self.assertFalse(models.IshtarSiteProfile.objects.count()) + profile = models.get_current_profile() + self.assertTrue(profile) + self.assertTrue(models.IshtarSiteProfile.objects.count()) diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 6f95e070a..1c944441f 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -51,7 +51,12 @@ from xhtml2odt import xhtml2odt from menus import menu +from archaeological_files.models import File +from archaeological_context_records.models import ContextRecord +from archaeological_finds.models import Find + from archaeological_operations.forms import DashboardForm as DashboardFormOpe +from archaeological_files.forms import DashboardForm as DashboardFormFile from ishtar_common.forms import FinalForm, FinalDeleteForm from ishtar_common import forms_common as forms @@ -927,22 +932,20 @@ def dashboard_main(request, dct, obj_id=None, *args, **kwargs): Main dashboard """ app_list = [] - if 'archaeological_files' in settings.INSTALLED_APPS: + profile = models.get_current_profile() + if profile.files: app_list.append((_(u"Archaeological files"), 'files')) app_list.append((_(u"Operations"), 'operations')) - if 'archaeological_context_records' in settings.INSTALLED_APPS: + if profile.context_record: app_list.append((_(u"Context records"), 'contextrecords')) - if 'archaeological_finds' in settings.INSTALLED_APPS: + if profile.find: app_list.append((_(u"Finds"), 'finds')) dct = {'app_list': app_list} return render_to_response('ishtar/dashboards/dashboard_main.html', dct, context_instance=RequestContext(request)) DASHBOARD_FORMS = {} -if 'archaeological_files' in settings.INSTALLED_APPS: - from archaeological_files.forms import DashboardForm as DashboardFormFile - DASHBOARD_FORMS['files'] = DashboardFormFile - +DASHBOARD_FORMS['files'] = DashboardFormFile DASHBOARD_FORMS['operations'] = DashboardFormOpe @@ -957,8 +960,8 @@ def dashboard_main_detail(request, item_name): dct, context_instance=RequestContext(request)) form = None slicing, date_source, fltr, show_detail = 'year', None, {}, False - if (item_name == 'files' and - 'archaeological_files' in settings.INSTALLED_APPS) \ + profile = models.get_current_profile() + if (item_name == 'files' and profile.files) \ or item_name == 'operations': slicing = 'month' if item_name in DASHBOARD_FORMS: @@ -974,32 +977,25 @@ def dashboard_main_detail(request, item_name): else: form = DASHBOARD_FORMS[item_name]() lbl, dashboard = None, None - if (item_name == 'files' and - 'archaeological_files' in settings.INSTALLED_APPS) \ + if (item_name == 'files' and profile.files) \ or item_name == 'operations': dashboard_kwargs = {'slice': slicing, 'fltr': fltr, 'show_detail': show_detail} # date_source is only relevant when the form has set one if date_source: dashboard_kwargs['date_source'] = date_source - if item_name == 'files' and \ - 'archaeological_files' in settings.INSTALLED_APPS: - from archaeological_files.models import File + if item_name == 'files' and profile.files: lbl, dashboard = (_(u"Archaeological files"), models.Dashboard(File, **dashboard_kwargs)) if item_name == 'operations': from archaeological_operations.models import Operation lbl, dashboard = (_(u"Operations"), models.Dashboard(Operation, **dashboard_kwargs)) - if item_name == 'contextrecords' and \ - 'archaeological_context_records' in settings.INSTALLED_APPS: - from archaeological_context_records.models import ContextRecord + if item_name == 'contextrecords' and profile.context_record: lbl, dashboard = ( _(u"Context records"), models.Dashboard(ContextRecord, slice=slicing, fltr=fltr)) - if item_name == 'finds' and \ - 'archaeological_finds' in settings.INSTALLED_APPS: - from archaeological_finds.models import Find + if item_name == 'finds' and profile.find: lbl, dashboard = (_(u"Finds"), models.Dashboard(Find, slice=slicing, fltr=fltr)) |