summaryrefslogtreecommitdiff
path: root/ishtar_common/models.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@proxience.com>2014-11-28 11:30:02 +0100
committerÉtienne Loks <etienne.loks@proxience.com>2014-11-28 11:30:02 +0100
commita62abdcb0c6daa71bc8bef293c20d911a63ccc60 (patch)
treefc3cb300358ed90b4d08dac9a274bcc124dcec01 /ishtar_common/models.py
parent9dd0ba91bdd9c76b42f4d6b4791633d7eac95b4a (diff)
downloadIshtar-a62abdcb0c6daa71bc8bef293c20d911a63ccc60.tar.bz2
Ishtar-a62abdcb0c6daa71bc8bef293c20d911a63ccc60.zip
Merge action implementation (person and organization)
Diffstat (limited to 'ishtar_common/models.py')
-rw-r--r--ishtar_common/models.py74
1 files changed, 70 insertions, 4 deletions
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index a96b24840..1031df71e 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -47,6 +47,7 @@ from django.contrib import admin
from simple_history.models import HistoricalRecords as BaseHistoricalRecords
from ishtar_common.ooo_replace import ooo_replace
+from ishtar_common.model_merging import merge_model_objects
from ishtar_common.utils import get_cache
def post_save_user(sender, **kwargs):
@@ -214,7 +215,7 @@ class GeneralType(models.Model):
txt_idx = models.CharField(_(u"Textual ID"),
validators=[validate_slug], max_length=30, unique=True)
comment = models.TextField(_(u"Comment"), blank=True, null=True)
- available = models.BooleanField(_(u"Available"))
+ available = models.BooleanField(_(u"Available"), default=True)
HELP_TEXT = u""
class Meta:
@@ -224,6 +225,10 @@ class GeneralType(models.Model):
def __unicode__(self):
return self.label
+ @classmethod
+ def create_default_for_test(cls):
+ return [cls.objects.create(label='Test %d' % i) for i in range(5)]
+
@property
def short_label(self):
return self.label
@@ -334,6 +339,8 @@ class GeneralType(models.Model):
if not self.id and not self.label:
self.label = u" ".join(u" ".join(self.txt_idx.split('-')
).split('_')).title()
+ if not self.txt_idx:
+ self.txt_idx = slugify(self.label)
return super(GeneralType, self).save(*args, **kwargs)
class ImageModel(models.Model):
@@ -820,13 +827,62 @@ class Address(BaseHistorizedItem):
class Meta:
abstract = True
+class Merge(models.Model):
+ merge_key = models.CharField(_("Merge key"), max_length=300,
+ blank=True, null=True)
+ merge_candidate = models.ManyToManyField("self",
+ blank=True, null=True)
+ merge_exclusion = models.ManyToManyField("self",
+ blank=True, null=True)
+ # 1 for one word similarity, 2 for two word similarity, etc.
+ MERGE_CLEMENCY = None
+ EMPTY_MERGE_KEY = '--'
+
+ class Meta:
+ abstract = True
+
+ def generate_merge_key(self):
+ self.merge_key = slugify(self.name if self.name else '')
+ if not self.merge_key:
+ self.merge_key = self.EMPTY_MERGE_KEY
+
+ def generate_merge_candidate(self):
+ if not self.merge_key:
+ self.generate_merge_key()
+ self.save()
+ if not self.pk or self.merge_key == self.EMPTY_MERGE_KEY:
+ return
+ q = self.__class__.objects.exclude(pk=self.pk
+ ).exclude(merge_exclusion=self
+ ).exclude(merge_candidate=self)
+ if not self.MERGE_CLEMENCY:
+ q = q.filter(merge_key=self.merge_key)
+ else:
+ subkeys_front = u"-".join(
+ self.merge_key.split('-')[:self.MERGE_CLEMENCY])
+ subkeys_back = u"-".join(
+ self.merge_key.split('-')[-self.MERGE_CLEMENCY:])
+ q = q.filter(Q(merge_key__istartswith=subkeys_front) |
+ Q(merge_key__iendswith=subkeys_back))
+ for item in q.all():
+ self.merge_candidate.add(item)
+
+ def save(self, *args, **kwargs):
+ self.generate_merge_key()
+ item = super(Merge, self).save(*args, **kwargs)
+ self.generate_merge_candidate()
+
+ def merge(self, item):
+ merge_model_objects(self, item)
+ self.generate_merge_candidate()
+
class OrganizationType(GeneralType):
class Meta:
verbose_name = _(u"Organization type")
verbose_name_plural = _(u"Organization types")
ordering = ('label',)
-class Organization(Address, OwnPerms, ValueGetter):
+class Organization(Address, Merge, OwnPerms, ValueGetter):
TABLE_COLS = ('name', 'organization_type',)
name = models.CharField(_(u"Name"), max_length=300)
organization_type = models.ForeignKey(OrganizationType,
@@ -862,7 +918,7 @@ class PersonType(GeneralType):
verbose_name_plural = _(u"Person types")
ordering = ('label',)
-class Person(Address, OwnPerms, ValueGetter) :
+class Person(Address, Merge, OwnPerms, ValueGetter) :
_prefix = 'person_'
TYPE = (('Mr', _(u'Mr')),
('Ms', _(u'Miss')),
@@ -900,7 +956,7 @@ class Person(Address, OwnPerms, ValueGetter) :
for attr in ('surname', 'name')
if getattr(self, attr)]
if not values:
- values = [self.raw_name]
+ values = [self.raw_name or ""]
if self.attached_to:
values.append(u"- " + unicode(self.attached_to))
return u" ".join(values)
@@ -921,6 +977,16 @@ class Person(Address, OwnPerms, ValueGetter) :
def person_types_list(self):
return u", ".join([unicode(pt) for pt in self.person_types.all()])
+ def generate_merge_key(self):
+ if self.name and self.name.strip():
+ self.merge_key = slugify(self.name.strip()) + (
+ (u'-' + slugify(self.surname.strip()))
+ if self.surname else u'')
+ elif self.raw_name and self.raw_name.strip():
+ self.merge_key = slugify(self.raw_name.strip())
+ else:
+ self.merge_key = self.EMPTY_MERGE_KEY
+
def has_right(self, right_name):
if '.' in right_name:
right_name = right_name.split('.')[-1]