From c6835861d3b3575b25161eb13b8284b0da663ab8 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 30 Mar 2017 12:31:55 +0200 Subject: Sources: fix query owns requests (refs #3196) --- ishtar_common/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ishtar_common/models.py') diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 35608abdf..6a9f86569 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2903,7 +2903,7 @@ post_save.connect(post_save_cache, sender=Format) post_delete.connect(post_save_cache, sender=Format) -class Source(ImageModel, models.Model): +class Source(OwnPerms, ImageModel, models.Model): title = models.CharField(_(u"Title"), max_length=300) external_id = models.CharField(_(u"External ID"), max_length=12, null=True, blank=True) -- cgit v1.2.3 From 90f5243a9d755affed1cca8ab020ea49b7c8ea25 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 30 Mar 2017 12:56:45 +0200 Subject: Permissions: add missing permissions for authors and sources (refs #2068) --- archaeological_context_records/models.py | 12 ++++++++++++ archaeological_finds/models_finds.py | 12 ++++++++++++ ishtar_common/models.py | 13 +++++++++++++ 3 files changed, 37 insertions(+) (limited to 'ishtar_common/models.py') diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 5e6b4622b..490124342 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -617,6 +617,18 @@ class ContextRecordSource(Source): class Meta: verbose_name = _(u"Context record documentation") verbose_name_plural = _(u"Context record documentations") + permissions = ( + ("view_contextrecordsource", + ugettext(u"Can view all Context record sources")), + ("view_own_contextrecordsource", + ugettext(u"Can view own Context record source")), + ("add_own_contextrecordsource", + ugettext(u"Can add own Context record source")), + ("change_own_contextrecordsource", + ugettext(u"Can change own Context record source")), + ("delete_own_contextrecordsource", + ugettext(u"Can delete own Context record source")), + ) context_record = models.ForeignKey( ContextRecord, verbose_name=_(u"Context record"), related_name="source") diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index f6be69f93..19464838b 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -1071,6 +1071,18 @@ class FindSource(Source): class Meta: verbose_name = _(u"Find documentation") verbose_name_plural = _(u"Find documentations") + permissions = ( + ("view_findsource", + ugettext(u"Can view all Find sources")), + ("view_own_findsource", + ugettext(u"Can view own Find source")), + ("add_own_findsource", + ugettext(u"Can add own Find source")), + ("change_own_findsource", + ugettext(u"Can change own Find source")), + ("delete_own_findsource", + ugettext(u"Can delete own Find source")), + ) find = models.ForeignKey(Find, verbose_name=_(u"Find"), related_name="source") diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 6a9f86569..048af1294 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2844,6 +2844,7 @@ IshtarUser._meta.get_field('password').help_text = _( class AuthorType(GeneralType): order = models.IntegerField(_(u"Order"), default=1) + class Meta: verbose_name = _(u"Author type") verbose_name_plural = _(u"Author types") @@ -2861,6 +2862,18 @@ class Author(models.Model): verbose_name = _(u"Author") verbose_name_plural = _(u"Authors") ordering = ('author_type__order', 'person__name') + permissions = ( + ("view_author", + ugettext(u"Can view all Authors")), + ("view_own_author", + ugettext(u"Can view own Author")), + ("add_own_author", + ugettext(u"Can add own Author")), + ("change_own_author", + ugettext(u"Can change own Author")), + ("delete_own_author", + ugettext(u"Can delete own Author")), + ) def __unicode__(self): return unicode(self.person) + settings.JOINT + \ -- cgit v1.2.3 From b1b03d624a8c501bc15a21e90e7abde2fd28698f Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 30 Mar 2017 19:27:00 +0200 Subject: Access control: define get_query_own for persons --- archaeological_operations/models.py | 4 +++- ishtar_common/models.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'ishtar_common/models.py') diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index d18181722..bef149b2c 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -270,7 +270,9 @@ class Operation(ClosedItem, BaseHistorizedItem, ImageModel, OwnPerms, on_delete=models.SET_NULL, related_name='operation_responsability') collaborators = models.ManyToManyField( - Person, blank=True, null=True, verbose_name=_(u"Collaborators")) + Person, blank=True, null=True, verbose_name=_(u"Collaborators"), + related_name='operation_collaborator' + ) year = models.IntegerField(_(u"Year"), null=True, blank=True) operation_code = models.IntegerField(_(u"Numeric reference"), null=True, blank=True) diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 048af1294..66433747c 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2770,6 +2770,18 @@ class Person(Address, Merge, OwnPerms, ValueGetter): for fle in self.general_contractor.all(): fle.save() # force update of raw_general_contractor + @classmethod + def get_query_owns(cls, user): + return \ + Q(operation_scientist_responsability__collaborators__ishtaruser + =user.ishtaruser) | \ + Q(operation_scientist_responsability__scientist__ishtaruser + =user.ishtaruser) | \ + Q(operation_collaborator__collaborators__ishtaruser + =user.ishtaruser) | \ + Q(operation_collaborator__scientist__ishtaruser + =user.ishtaruser) + class IshtarUser(User): TABLE_COLS = ('username', 'person__name', 'person__surname', -- cgit v1.2.3 From 3565d1fee6f675646f60c1690bb1c81549b227a9 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Sun, 2 Apr 2017 21:46:17 +0200 Subject: Finds: do not resize the image and regenerate a thumb on find duplication (refs #3579) --- archaeological_finds/models_finds.py | 24 ++++++++++++++---------- archaeological_finds/tests.py | 22 ++++++++++++++++++++++ ishtar_common/models.py | 4 ++++ 3 files changed, 40 insertions(+), 10 deletions(-) (limited to 'ishtar_common/models.py') diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 19464838b..1b492148a 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -847,16 +847,20 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem): def duplicate(self, user): model = self.__class__ - # base fields - table_cols = [field.name for field in model._meta.fields - if field.name not in PRIVATE_FIELDS or - field.name == 'order'] - dct = dict([(attr, getattr(self, attr)) for attr in - table_cols]) - dct['order'] += 1 - dct['history_modifier'] = user - new = self.__class__(**dct) - new.save() + + new = model.objects.get(pk=self.pk) + + for field in model._meta.fields: + # pk is in PRIVATE_FIELDS so: new.pk = None and a new + # item will be created on save + if field.name in PRIVATE_FIELDS: + setattr(new, field.name, None) + new.order = self.order + 1 + new.history_order = user + new.image.name = self.image.name + # force_copy is necessary to not regenerate a thumb and resize + # again the image + new.save(force_copy=True) # m2m fields m2m = [field.name for field in model._meta.many_to_many diff --git a/archaeological_finds/tests.py b/archaeological_finds/tests.py index e274c757f..1268b4f03 100644 --- a/archaeological_finds/tests.py +++ b/archaeological_finds/tests.py @@ -21,6 +21,7 @@ import json from django.conf import settings from django.contrib.auth.models import User +from django.core.files import File from django.core.files.uploadedfile import SimpleUploadedFile from django.core.urlresolvers import reverse from django.test.client import Client @@ -474,8 +475,14 @@ class PackagingTest(FindInit, TestCase): model = models.Find def setUp(self): + img = settings.ROOT_PATH + \ + '../ishtar_common/static/media/images/ishtar-bg.jpg' + self.create_finds({"label": u"Find 1"}, force=True) self.create_finds({"label": u"Find 2"}, force=True) + self.finds[0].image.save('ishtar-bg.jpg', File(open(img))) + self.finds[0].save() + self.basket = models.FindBasket.objects.create( label="My basket", user=IshtarUser.objects.get( pk=self.get_default_user().pk)) @@ -490,11 +497,26 @@ class PackagingTest(FindInit, TestCase): treatment_type = models.TreatmentType.objects.get(txt_idx='packaging') treatment = models.Treatment() items_nb = models.Find.objects.count() + + first_find = self.finds[0] + treatment.save(user=self.get_default_user(), items=self.basket) self.assertEqual(items_nb + self.basket.items.count(), models.Find.objects.count(), msg="Packaging doesn't generate enough new finds") treatment.treatment_types.add(treatment_type) + + resulting_find = models.Find.objects.get( + upstream_treatment__upstream=first_find, + base_finds__pk=first_find.base_finds.all()[0].pk + ) + + # image names used to be altered on save: check for this bug + self.assertEqual( + resulting_find.image.name, + models.Find.objects.get(pk=first_find.pk).image.name + ) + # new version of the find is in the basket for item in self.basket.items.all(): self.assertNotIn( diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 66433747c..7873b63f8 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -769,6 +769,10 @@ class ImageModel(models.Model): return SimpleUploadedFile('temp', temp.read()) def save(self, *args, **kwargs): + if 'force_copy' in kwargs: + kwargs.pop('force_copy') + super(ImageModel, self).save(*args, **kwargs) + return # manage images if self.has_changed('image') and self.image: # convert to jpg -- cgit v1.2.3 From 3f18460f80c89d5de4420fbe53fb39991cd08105 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Mon, 3 Apr 2017 19:15:13 +0200 Subject: Fix find modify action (refs #3405) --- archaeological_finds/views.py | 2 +- ishtar_common/models.py | 2 ++ ishtar_common/wizards.py | 8 +++++++- 3 files changed, 10 insertions(+), 2 deletions(-) (limited to 'ishtar_common/models.py') diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index 03094cbb0..680faf421 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -169,7 +169,7 @@ find_modification_wizard = FindModificationWizard.as_view([ def find_modify(request, pk): - # view = find_modification_wizard(request) + find_modification_wizard(request) FindModificationWizard.session_set_value( request, 'selec-find_modification', 'pk', pk, reset=True) return redirect( diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 7873b63f8..bf5c6056a 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -191,6 +191,8 @@ def valid_ids(cls): def func(value): if "," in value: value = value.split(",") + if type(value) not in (list, tuple): + value = [value] for v in value: try: cls.objects.get(pk=v) diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 61923d920..8d787d733 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -51,10 +51,16 @@ class MultiValueDict(BaseMultiValueDict): v = v() if type(v) in (list, tuple) and len(v) > 1: v = ",".join(v) - else: + elif type(v) not in (int, unicode): v = super(MultiValueDict, self).get(*args, **kwargs) return v + def getlist(self, *args, **kwargs): + lst = super(MultiValueDict, self).getlist(*args, **kwargs) + if type(lst) not in (tuple, list): + lst = [lst] + return lst + def check_rights(rights=[], redirect_url='/'): """ -- cgit v1.2.3 From 2e512bc9dffca5624342aa75ca01b3ff7f390141 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Wed, 5 Apr 2017 11:33:54 +0200 Subject: Warehouse sheet: provide statistics (refs #3398) - Number of finds (total and by places) - Number of container (total and by places) --- archaeological_finds/models_finds.py | 8 +- archaeological_operations/models.py | 8 -- .../templates/ishtar/sheet_operation.html | 1 + archaeological_warehouse/models.py | 103 ++++++++++++++++++++- .../templates/ishtar/sheet_warehouse.html | 44 +++++++++ example_project/settings.py | 2 +- ishtar_common/models.py | 13 +++ ishtar_common/static/media/style.css | 6 ++ 8 files changed, 168 insertions(+), 17 deletions(-) (limited to 'ishtar_common/models.py') diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 3785267b2..52601c896 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -37,7 +37,6 @@ from archaeological_operations.models import AdministrativeAct from archaeological_context_records.models import ContextRecord, Dating from ishtar_common.models import PRIVATE_FIELDS, SpatialReferenceSystem -from archaeological_warehouse.models import Container, Collection class MaterialType(GeneralType): @@ -637,7 +636,8 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem): datings = models.ManyToManyField(Dating, verbose_name=_(u"Dating"), related_name='find') container = models.ForeignKey( - Container, verbose_name=_(u"Container"), blank=True, null=True, + "archaeological_warehouse.Container", verbose_name=_(u"Container"), + blank=True, null=True, related_name='finds', on_delete=models.SET_NULL) is_complete = models.NullBooleanField(_(u"Is complete?"), blank=True, null=True) @@ -671,8 +671,8 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem): estimated_value = models.FloatField(_(u"Estimated value"), blank=True, null=True) collection = models.ForeignKey( - Collection, verbose_name=_(u"Collection"), blank=True, null=True, - related_name='finds', on_delete=models.SET_NULL) + "archaeological_warehouse.Collection", verbose_name=_(u"Collection"), + blank=True, null=True, related_name='finds', on_delete=models.SET_NULL) cached_label = models.TextField(_(u"Cached name"), null=True, blank=True) history = HistoricalRecords() BASKET_MODEL = FindBasket diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index bef149b2c..3826678c3 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -593,14 +593,6 @@ class Operation(ClosedItem, BaseHistorizedItem, ImageModel, OwnPerms, nb = self.parcels.count() return nb - def _get_or_set_stats(self, funcname, update): - key, val = get_cache(self.__class__, [funcname, self.pk]) - if not update and val is not None: - return val - val = getattr(self, funcname)() - cache.set(key, val, settings.CACHE_TIMEOUT) - return val - @property def nb_acts(self, update=False): _(u"Number of administrative acts") diff --git a/archaeological_operations/templates/ishtar/sheet_operation.html b/archaeological_operations/templates/ishtar/sheet_operation.html index 71f41d8c4..5051c4604 100644 --- a/archaeological_operations/templates/ishtar/sheet_operation.html +++ b/archaeological_operations/templates/ishtar/sheet_operation.html @@ -142,6 +142,7 @@ {% endif %}

{% trans "Statistics" %}

+{% trans "Theses number are updated hourly" %}

{% trans "Administrative acts" %}

    diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index fe054a37b..2851e1df0 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -21,7 +21,7 @@ import datetime from django.conf import settings from django.contrib.gis.db import models -from django.db.models import Q +from django.db.models import Q, Count from django.db.models.signals import post_save, post_delete from django.template.defaultfilters import slugify from django.utils.translation import ugettext_lazy as _, ugettext @@ -29,7 +29,9 @@ from django.utils.translation import ugettext_lazy as _, ugettext from ishtar_common.utils import cached_label_changed from ishtar_common.models import GeneralType, get_external_id, \ - LightHistorizedItem, OwnPerms, Address, Person, post_save_cache, ImageModel + LightHistorizedItem, OwnPerms, Address, Person, post_save_cache, \ + ImageModel, DashboardFormItem +from archaeological_finds.models import Find class WarehouseType(GeneralType): @@ -41,7 +43,7 @@ post_save.connect(post_save_cache, sender=WarehouseType) post_delete.connect(post_save_cache, sender=WarehouseType) -class Warehouse(Address, OwnPerms): +class Warehouse(Address, DashboardFormItem, OwnPerms): SHOW_URL = 'show-warehouse' name = models.CharField(_(u"Name"), max_length=200) warehouse_type = models.ForeignKey(WarehouseType, @@ -83,6 +85,98 @@ class Warehouse(Address, OwnPerms): def get_query_owns(cls, user): return Q(person_in_charge__ishtaruser=user.ishtaruser) + @property + def number_of_finds(self): + return Find.objects.filter(container__responsible=self).count() + + @property + def number_of_finds_hosted(self): + return Find.objects.filter(container__location=self).count() + + @property + def number_of_containers(self): + return Container.objects.filter(location=self).count() + + def _get_divisions(self, current_path, remaining_division, depth=0): + if not remaining_division: + return [current_path] + current_division = remaining_division.pop(0) + q = ContainerLocalisation.objects.filter( + division=current_division, + ) + for div, ref in current_path: + q = q.filter( + container__division__division=div, + container__division__reference=ref + ) + res = [] + old_ref = None + for ref in q.values('reference').order_by('reference').all(): + if ref['reference'] == old_ref: + continue + old_ref = ref['reference'] + cpath = current_path[:] + cpath.append((current_division, ref['reference'])) + for r in self._get_divisions(cpath, remaining_division[:], + depth + 1): + res.append(r) + return res + + @property + def available_division_tuples(self): + """ + :return: ordered list of available paths. Each path is a list of + tuple with the WarehouseDivisionLink and the reference. + """ + divisions = list( + WarehouseDivisionLink.objects.filter(warehouse=self + ).order_by('order').all()) + return self._get_divisions([], divisions) + + def _number_of_items_by_place(self, model, division_key='division'): + res = {} + paths = self.available_division_tuples[:] + for path in paths: + q = model.objects + cpath = [] + for division, ref in path: + lbl = u"{} {}".format(division.division, ref) + cpath.append(lbl) + attrs = { + division_key + "__division": division, + division_key + "__reference": ref + } + q = q.filter(**attrs) + if tuple(cpath) not in res: + res[tuple(cpath)] = q.count() + res = [(k, res[k]) for k in res] + final_res, current_res, depth = [], [], 1 + for path, nb in sorted(res, key=lambda x: (len(x[0]), x[0])): + if depth != len(path): + final_res.append(current_res[:]) + current_res = [] + depth = len(path) + current_res.append((u" | ".join(path), nb)) + final_res.append(current_res[:]) + return final_res + + def _number_of_finds_by_place(self): + return self._number_of_items_by_place( + Find, division_key='container__division') + + @property + def number_of_finds_by_place(self, update=False): + return self._get_or_set_stats('_number_of_finds_by_place', update, + settings.CACHE_SMALLTIMEOUT) + + def _number_of_containers_by_place(self): + return self._number_of_items_by_place(Container) + + @property + def number_of_containers_by_place(self, update=False): + return self._get_or_set_stats('_number_of_containers_by_place', update, + settings.CACHE_SMALLTIMEOUT) + def save(self, *args, **kwargs): super(Warehouse, self).save(*args, **kwargs) for container in self.containers.all(): @@ -287,7 +381,8 @@ post_save.connect(cached_label_changed, sender=Container) class ContainerLocalisation(models.Model): - container = models.ForeignKey(Container, verbose_name=_(u"Container")) + container = models.ForeignKey(Container, verbose_name=_(u"Container"), + related_name='division') division = models.ForeignKey(WarehouseDivisionLink, verbose_name=_(u"Division")) reference = models.CharField(_(u"Reference"), max_length=200, default='') diff --git a/archaeological_warehouse/templates/ishtar/sheet_warehouse.html b/archaeological_warehouse/templates/ishtar/sheet_warehouse.html index c31fc93b4..17a2c6c2b 100644 --- a/archaeological_warehouse/templates/ishtar/sheet_warehouse.html +++ b/archaeological_warehouse/templates/ishtar/sheet_warehouse.html @@ -26,4 +26,48 @@ {% dynamic_table_document '' 'containers' 'responsible' item.pk 'TABLE_COLS' output %} {% endif %} +

    {% trans "Statistics" %}

    +{% trans "Theses number are updated hourly" %} + +

    {% trans "Finds" %}

    +
      + {% field_li "Number of attached finds" item.number_of_finds %} + {% field_li "Number of hosted finds" item.number_of_finds_hosted %} +
    + +{% if item.number_of_finds_by_place %} +

    {% trans "Finds by location in the warehouse" %}

    +
      + {% for items in item.number_of_finds_by_place %} +
    • + + {% for item in items %} + + {% endfor %} +
      {{item.0}}{{item.1}}
      +
    • + {% endfor %} +
    +{% endif %} + +

    {% trans "Containers" %}

    +
      + {% field_li "Number of containers" item.number_of_containers %} +
    + +{% if item.number_of_containers_by_place %} +

    {% trans "Containers by location in the warehouse" %}

    +
      + {% for items in item.number_of_containers_by_place %} +
    • + + {% for item in items %} + + {% endfor %} +
      {{item.0}}{{item.1}}
      +
    • + {% endfor %} +
    +{% endif %} + {% endblock %} diff --git a/example_project/settings.py b/example_project/settings.py index efbf0297a..78d97f0ae 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -18,7 +18,7 @@ if "test" in sys.argv: IMAGE_MAX_SIZE = (1024, 768) THUMB_MAX_SIZE = (300, 300) -CACHE_SMALLTIMEOUT = 120 +CACHE_SMALLTIMEOUT = 60 CACHE_TIMEOUT = 3600 CACHE_BACKEND = 'memcached://127.0.0.1:11211/' diff --git a/ishtar_common/models.py b/ishtar_common/models.py index bf5c6056a..1632cbfb2 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -1306,6 +1306,19 @@ class UserDashboard: class DashboardFormItem(object): + """ + Provide methods to manage statistics + """ + + def _get_or_set_stats(self, funcname, update, + timeout=settings.CACHE_TIMEOUT): + key, val = get_cache(self.__class__, [funcname, self.pk]) + if not update and val is not None: + return val + val = getattr(self, funcname)() + cache.set(key, val, timeout) + return val + @classmethod def get_periods(cls, slice='month', fltr={}, date_source='creation'): date_var = date_source + '_date' diff --git a/ishtar_common/static/media/style.css b/ishtar_common/static/media/style.css index fc840526e..011db3652 100644 --- a/ishtar_common/static/media/style.css +++ b/ishtar_common/static/media/style.css @@ -324,6 +324,12 @@ ul.list{ line-height:16px; } +.centered{ + text-align: center; + width: 100%; + display: inline-block; +} + div.nav-button{ cursor:pointer; width:15px; -- cgit v1.2.3 From f18c8d30e9a8d6d04e294d9a7b46ec87c508699e Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 7 Apr 2017 00:53:07 +0200 Subject: Remove public access by default on user creation --- ishtar_common/models.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'ishtar_common/models.py') diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 1632cbfb2..ead703b02 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2834,17 +2834,13 @@ class IshtarUser(User): surname = user.first_name or default name = user.last_name or default email = user.email - if user.is_superuser: - ADMINISTRATOR, created = PersonType.objects.get_or_create( - txt_idx='administrator') - person_type = ADMINISTRATOR - else: - person_type, created = PersonType.objects.get_or_create( - txt_idx='public_access') person = Person.objects.create(surname=surname, name=name, email=email, history_modifier=user) - person.person_types.add(person_type) + if user.is_superuser: + person_type, created = PersonType.objects.get_or_create( + txt_idx='administrator') + person.person_types.add(person_type) password = user.password isht_user = IshtarUser.objects.create( user_ptr=user, username=default, person=person, password=password) -- cgit v1.2.3 From e5ebf3169e52e5a425a56d7c908ba422969443de Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 7 Apr 2017 00:58:11 +0200 Subject: PEP8 --- ishtar_common/models.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'ishtar_common/models.py') diff --git a/ishtar_common/models.py b/ishtar_common/models.py index ead703b02..d8ba637db 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -413,7 +413,7 @@ class GeneralType(Cached, models.Model): if item: return item item, created = cls.objects.get_or_create( - txt_idx=slug, defaults={'label': label}) + txt_idx=slug, defaults={'label': label}) return item @classmethod @@ -1970,7 +1970,8 @@ class ImporterColumn(models.Model): """ Import file column description """ - label = models.CharField(_(u"Label"), blank=True, null=True, max_length=200) + label = models.CharField(_(u"Label"), blank=True, null=True, + max_length=200) importer_type = models.ForeignKey(ImporterType, related_name='columns') col_number = models.IntegerField(_(u"Column number"), default=1) description = models.TextField(_("Description"), blank=True, null=True) @@ -2160,7 +2161,8 @@ TARGET_MODELS = [ ('archaeological_operations.models.ReportState', _(u"Report state")), ('archaeological_operations.models.RemainType', _(u"Remain type")), ('archaeological_context_records.models.Unit', _(u"Unit")), - ('archaeological_context_records.models.ActivityType', _(u"Activity type")), + ('archaeological_context_records.models.ActivityType', + _(u"Activity type")), ('archaeological_finds.models.MaterialType', _(u"Material")), ('archaeological_finds.models.ConservatoryState', _(u"Conservatory state")), @@ -2168,7 +2170,8 @@ TARGET_MODELS = [ ('archaeological_finds.models.PreservationType', _(u"Preservation type")), ('archaeological_finds.models.ObjectType', _(u"Object type")), ('archaeological_finds.models.IntegrityType', _(u"Integrity type")), - ('archaeological_finds.models.RemarkabilityType', _(u"Remarkability type")), + ('archaeological_finds.models.RemarkabilityType', + _(u"Remarkability type")), ('archaeological_finds.models.BatchType', _(u"Batch type")), ('archaeological_context_records.models.IdentificationType', _("Identification type")), -- cgit v1.2.3 From da4af2ab5d105f6d2ce442b517e532b7570616e3 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Fri, 7 Apr 2017 10:47:39 +0200 Subject: Treatment - Treatment files dashboard: first overview (refs #3381) --- archaeological_finds/models_treatments.py | 10 +++++----- ishtar_common/models.py | 10 ++++------ .../templates/ishtar/dashboards/dashboard_main.html | 11 ++++++++++- ishtar_common/views.py | 18 +++++++++++++++--- 4 files changed, 34 insertions(+), 15 deletions(-) (limited to 'ishtar_common/models.py') diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py index 0f7c56678..20e91155a 100644 --- a/archaeological_finds/models_treatments.py +++ b/archaeological_finds/models_treatments.py @@ -30,7 +30,7 @@ from django.utils.translation import ugettext_lazy as _, ugettext from ishtar_common.utils import cached_label_changed from ishtar_common.models import GeneralType, ImageModel, BaseHistorizedItem, \ OwnPerms, HistoricalRecords, Person, Organization, Source, \ - ValueGetter, post_save_cache, ShortMenuItem + ValueGetter, post_save_cache, ShortMenuItem, DashboardFormItem from archaeological_warehouse.models import Warehouse, Container from archaeological_finds.models_finds import Find, FindBasket from archaeological_operations.models import ClosedItem, Operation @@ -69,8 +69,8 @@ post_save.connect(post_save_cache, sender=TreatmentState) post_delete.connect(post_save_cache, sender=TreatmentState) -class Treatment(ValueGetter, BaseHistorizedItem, ImageModel, OwnPerms, - ShortMenuItem): +class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, + ImageModel, OwnPerms, ShortMenuItem): SHOW_URL = 'show-treatment' TABLE_COLS = ('year', 'index', 'treatment_types__label', 'treatment_state__label', @@ -472,8 +472,8 @@ post_save.connect(post_save_cache, sender=TreatmentFileType) post_delete.connect(post_save_cache, sender=TreatmentFileType) -class TreatmentFile(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter, - ShortMenuItem): +class TreatmentFile(DashboardFormItem, ClosedItem, BaseHistorizedItem, + OwnPerms, ValueGetter, ShortMenuItem): SLUG = 'treatmentfile' SHOW_URL = 'show-treatmentfile' TABLE_COLS = ['type', 'year', 'index', 'internal_reference', 'name'] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index d8ba637db..988254359 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -2323,14 +2323,12 @@ class Import(models.Model): conservative_import = models.BooleanField( _(u"Conservative import"), default=False, help_text='If set to true, do not overload existing values') - creation_date = models.DateTimeField(_(u"Creation date"), - auto_now_add=True, blank=True, - null=True) + creation_date = models.DateTimeField( + _(u"Creation date"), auto_now_add=True, blank=True, null=True) end_date = models.DateTimeField(_(u"End date"), blank=True, null=True, editable=False) - seconds_remaining = models.IntegerField(_(u"Remaining seconds"), - blank=True, null=True, - editable=False) + seconds_remaining = models.IntegerField( + _(u"Remaining seconds"), blank=True, null=True, editable=False) class Meta: verbose_name = _(u"Import") diff --git a/ishtar_common/templates/ishtar/dashboards/dashboard_main.html b/ishtar_common/templates/ishtar/dashboards/dashboard_main.html index 93e11d604..6a5a67a63 100644 --- a/ishtar_common/templates/ishtar/dashboards/dashboard_main.html +++ b/ishtar_common/templates/ishtar/dashboards/dashboard_main.html @@ -15,7 +15,16 @@ {% endblock %} {% block content %}
    diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 4732313ea..e8a2c9e12 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -1451,6 +1451,9 @@ def dashboard_main(request, dct, obj_id=None, *args, **kwargs): app_list.append((_(u"Context records"), 'contextrecords')) if profile.find: app_list.append((_(u"Finds"), 'finds')) + if profile.warehouse: + app_list.append((_(u"Treatment requests"), 'treatmentfiles')) + app_list.append((_(u"Treatments"), 'treatments')) dct = {'app_list': app_list} return render_to_response('ishtar/dashboards/dashboard_main.html', dct, context_instance=RequestContext(request)) @@ -1497,18 +1500,27 @@ def dashboard_main_detail(request, item_name): if item_name == 'files' and profile.files: lbl, dashboard = (_(u"Archaeological files"), models.Dashboard(File, **dashboard_kwargs)) - if item_name == 'operations': + elif item_name == 'operations': from archaeological_operations.models import Operation lbl, dashboard = (_(u"Operations"), models.Dashboard(Operation, **dashboard_kwargs)) - if item_name == 'contextrecords' and profile.context_record: + elif item_name == 'contextrecords' and profile.context_record: lbl, dashboard = ( _(u"Context records"), models.Dashboard(ContextRecord, slice=slicing, fltr=fltr)) - if item_name == 'finds' and profile.find: + elif item_name == 'finds' and profile.find: lbl, dashboard = (_(u"Finds"), models.Dashboard(Find, slice=slicing, fltr=fltr)) + elif item_name == 'treatmentfiles' and profile.warehouse: + lbl, dashboard = ( + _(u"Treatment requests"), + models.Dashboard(TreatmentFile, slice=slicing, fltr=fltr)) + elif item_name == 'treatments' and profile.warehouse: + lbl, dashboard = ( + _(u"Treatments"), + models.Dashboard(Treatment, slice=slicing, fltr=fltr, + date_source='start')) if not lbl: raise Http404 dct = {'lbl': lbl, 'dashboard': dashboard, -- cgit v1.2.3