summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archaeological_context_records/ishtar_menu.py1
-rw-r--r--archaeological_files/ishtar_menu.py2
-rw-r--r--archaeological_finds/ishtar_menu.py1
-rw-r--r--archaeological_finds/models.py28
-rw-r--r--archaeological_operations/admin.py20
-rw-r--r--archaeological_operations/forms.py47
-rw-r--r--archaeological_operations/ishtar_menu.py6
-rw-r--r--archaeological_operations/models.py437
-rw-r--r--archaeological_operations/views.py3
-rw-r--r--archaeological_operations/wizards.py8
-rw-r--r--archaeological_warehouse/ishtar_menu.py1
-rw-r--r--example_project/urls.py8
-rw-r--r--ishtar_common/context_processors.py14
-rw-r--r--ishtar_common/management/commands/update_specific_importers.py7
-rw-r--r--ishtar_common/menu_base.py31
-rw-r--r--ishtar_common/models.py57
-rw-r--r--ishtar_common/tests.py6
-rw-r--r--ishtar_common/views.py36
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))