summaryrefslogtreecommitdiff
path: root/ishtar_common/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/models.py')
-rw-r--r--ishtar_common/models.py184
1 files changed, 158 insertions, 26 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 9509b36a6..3c46573dd 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -243,10 +243,15 @@ class OwnPerms:
user = IshtarUser.objects.get(user_ptr=user)
if user.is_anonymous():
return cls.objects.filter(pk__isnull=True)
+ items = []
+ if hasattr(cls, 'BASKET_MODEL'):
+ items = list(cls.BASKET_MODEL.objects.filter(user=user).all())
query = cls.get_query_owns(user)
if not query:
return cls.objects.filter(pk__isnull=True)
- return cls.objects.filter(query).order_by(*cls._meta.ordering)
+ items += list(
+ cls.objects.filter(query).order_by(*cls._meta.ordering).all())
+ return items
class Cached(object):
@@ -321,13 +326,34 @@ class GeneralType(models.Model, Cached):
@classmethod
def get_types(cls, dct={}, instances=False, exclude=[], empty_first=True,
default=None):
+ # cache
+ cache_key = None
+ if not instances:
+ keys = [u"{}".format(ex) for ex in exclude] + [
+ empty_first and 'empty_first' or ''] + [u"{}".format(default)]
+ cache_key, value = get_cache(cls, keys)
+ if value:
+ return value
base_dct = dct.copy()
if hasattr(cls, 'parent'):
- return cls._get_parent_types(
- base_dct, instances, exclude=exclude, empty_first=empty_first,
- default=default)
- return cls._get_types(base_dct, instances, exclude=exclude,
- empty_first=empty_first, default=default)
+ if not cache_key:
+ return cls._get_parent_types(
+ base_dct, instances, exclude=exclude,
+ empty_first=empty_first, default=default)
+ vals = [v for v in cls._get_parent_types(
+ base_dct, instances, exclude=exclude,
+ empty_first=empty_first, default=default)]
+ cache.set(cache_key, vals, settings.CACHE_TIMEOUT)
+ return vals
+
+ if not cache_key:
+ return cls._get_types(base_dct, instances, exclude=exclude,
+ empty_first=empty_first, default=default)
+ vals = [v for v in cls._get_types(
+ base_dct, instances, exclude=exclude, empty_first=empty_first,
+ default=default)]
+ cache.set(cache_key, vals, settings.CACHE_TIMEOUT)
+ return vals
@classmethod
def _get_types(cls, dct={}, instances=False, exclude=[], empty_first=True,
@@ -475,6 +501,33 @@ class GeneralType(models.Model, Cached):
item.generate_key()
+class Basket(models.Model):
+ """
+ Abstract class for a basket
+ Subclass must be defined with an "items" ManyToManyField
+ """
+ IS_BASKET = True
+ label = models.CharField(_(u"Label"), max_length=1000)
+ comment = models.TextField(_(u"Comment"), blank=True, null=True)
+ user = models.ForeignKey('IshtarUser', blank=True, null=True)
+ available = models.BooleanField(_(u"Available"), default=True)
+
+ class Meta:
+ abstract = True
+ unique_together = (('label', 'user'),)
+
+ def __unicode__(self):
+ return self.label
+
+ def get_short_menu_class(self):
+ return 'basket'
+
+ @property
+ def associated_filename(self):
+ return "{}-{}".format(datetime.date.today().strftime(
+ "%Y-%m-%d"), slugify(self.label))
+
+
class ItemKey(models.Model):
key = models.CharField(_(u"Key"), max_length=100)
content_type = models.ForeignKey(ContentType)
@@ -520,25 +573,27 @@ class ImageModel(models.Model):
filename = os.path.splitext(os.path.split(self.image.name)[-1])[0]
old_path = self.image.path
filename = "%s.jpg" % filename
- image = Image.open(self.image.file)
-
- # convert to RGB
- if image.mode not in ('L', 'RGB'):
- image = image.convert('RGB')
-
- # resize if necessary
- self.image.save(filename,
- self.create_thumb(image, self.IMAGE_MAX_SIZE),
- save=False)
-
- if old_path != self.image.path:
- os.remove(old_path)
-
- # save the thumbnail
- self.thumbnail.save(
- '_%s' % filename,
- self.create_thumb(image, self.THUMB_MAX_SIZE),
- save=False)
+ try:
+ image = Image.open(self.image.file)
+ # convert to RGB
+ if image.mode not in ('L', 'RGB'):
+ image = image.convert('RGB')
+
+ # resize if necessary
+ self.image.save(filename,
+ self.create_thumb(image, self.IMAGE_MAX_SIZE),
+ save=False)
+
+ if old_path != self.image.path:
+ os.remove(old_path)
+
+ # save the thumbnail
+ self.thumbnail.save(
+ '_%s' % filename,
+ self.create_thumb(image, self.THUMB_MAX_SIZE),
+ save=False)
+ except IOError:
+ pass
super(ImageModel, self).save(*args, **kwargs)
@@ -549,8 +604,11 @@ class HistoryError(Exception):
def __str__(self):
return repr(self.value)
+PRIVATE_FIELDS = ('id', 'history_modifier', 'order')
+
class BaseHistorizedItem(Imported):
+ IS_BASKET = False
history_modifier = models.ForeignKey(
User, related_name='+', on_delete=models.SET_NULL,
verbose_name=_(u"Last editor"), blank=True, null=True)
@@ -691,6 +749,8 @@ class BaseHistorizedItem(Imported):
class GeneralRelationType(GeneralType):
order = models.IntegerField(_(u"Order"), default=1)
symmetrical = models.BooleanField(_(u"Symmetrical"))
+ tiny_label = models.CharField(_(u"Tiny label"), max_length=50,
+ blank=True, null=True)
# # an inverse must be set
# inverse_relation = models.ForeignKey(
# 'RelationType', verbose_name=_(u"Inverse relation"), blank=True,
@@ -705,6 +765,9 @@ class GeneralRelationType(GeneralType):
raise ValidationError(
_(u"Cannot have symmetrical and an inverse_relation"))
+ def get_tiny_label(self):
+ return self.tiny_label or self.label or u""
+
def save(self, *args, **kwargs):
obj = super(GeneralRelationType, self).save(*args, **kwargs)
# after saving check that the inverse_relation of the inverse_relation
@@ -769,6 +832,35 @@ class LightHistorizedItem(BaseHistorizedItem):
super(LightHistorizedItem, self).save(*args, **kwargs)
return True
+PARSE_FORMULA = re.compile("{([^}]*)}")
+
+
+def get_external_id(key, item):
+ profile = get_current_profile()
+ if not hasattr(profile, key):
+ return
+ formula = getattr(profile, key)
+ dct = {}
+ for fkey in PARSE_FORMULA.findall(formula):
+ if fkey.startswith('settings__'):
+ dct[fkey] = getattr(settings, fkey[len('settings__'):]) or ''
+ continue
+ obj = item
+ for k in fkey.split('__'):
+ try:
+ obj = getattr(obj, k)
+ except ObjectDoesNotExist:
+ obj = None
+ if callable(obj):
+ obj = obj()
+ if obj is None:
+ break
+ if obj is None:
+ dct[fkey] = ''
+ else:
+ dct[fkey] = obj
+ return formula.format(**dct)
+
class IshtarSiteProfile(models.Model, Cached):
slug_field = 'slug'
@@ -783,6 +875,46 @@ class IshtarSiteProfile(models.Model, Cached):
warehouse = models.BooleanField(
_(u"Warehouses module"), default=False,
help_text=_(u"Need finds module"))
+ homepage = models.TextField(
+ _(u"Home page"), null=True, blank=True,
+ help_text=_(u"Homepage of Ishtar - if not defined a default homepage "
+ u"will appear. Use the markdown syntax."))
+ file_external_id = models.TextField(
+ _(u"File external id"),
+ default="{settings__ISHTAR_LOCAL_PREFIX}{year}-{numeric_reference}",
+ help_text=_(u"Formula to manage file external ID. "
+ u"Change this with care. With incorrect formula, the "
+ u"application might be unusable and import of external "
+ u"data can be destructive."))
+ parcel_external_id = models.TextField(
+ _(u"Parcel external id"),
+ default="{associated_file__external_id}{operation__code_patriarche}-"
+ "{town__numero_insee}-{section}{parcel_number}",
+ help_text=_(u"Formula to manage parcel external ID. "
+ u"Change this with care. With incorrect formula, the "
+ u"application might be unusable and import of external "
+ u"data can be destructive."))
+ context_record_external_id = models.TextField(
+ _(u"Context record external id"),
+ default="{parcel__external_id}-{label}",
+ help_text=_(u"Formula to manage context record external ID. "
+ u"Change this with care. With incorrect formula, the "
+ u"application might be unusable and import of external "
+ u"data can be destructive."))
+ base_find_external_id = models.TextField(
+ _(u"Base find external id"),
+ default="{context_record__external_id}-{label}",
+ help_text=_(u"Formula to manage base find external ID. "
+ u"Change this with care. With incorrect formula, the "
+ u"application might be unusable and import of external "
+ u"data can be destructive."))
+ find_external_id = models.TextField(
+ _(u"Find external id"),
+ default="{get_first_base_find__context_record__external_id}-{label}",
+ help_text=_(u"Formula to manage find external ID. "
+ u"Change this with care. With incorrect formula, the "
+ u"application might be unusable and import of external "
+ u"data can be destructive."))
active = models.BooleanField(_(u"Current active"), default=False)
class Meta:
@@ -974,7 +1106,7 @@ class Dashboard:
if len(str(p[1])) == 1 else p[1]) for p in periods]
self.values = [('month', "", self.periods)]
if show_detail:
- for dpt in settings.ISHTAR_DPTS:
+ for dpt, lbl in settings.ISHTAR_DPTS:
self.serie_labels.append(unicode(dpt))
idx = 'number_' + unicode(dpt)
kwargs_num['fltr']["towns__numero_insee__startswith"] = \