示例#1
0
 def __init__(self, *args, **kwargs):
     super(LocationCodeCategory, self).__init__(*args, **kwargs)
     self._formats = [
         fmt.char_definition for fmt in LocationCodeDefault.objects.all()
     ]
     self._separator = LocationCodeDefault.getSegmentSeparator()
     self._parser = FormatParser(self._formats, self._separator)
示例#2
0
 def __init__(self, *args, **kwargs):
     super(LocationCodeCategory, self).__init__(*args, **kwargs)
     self._formats = [fmt.char_definition
                      for fmt in LocationCodeDefault.objects.all()]
     self._separator = LocationCodeDefault.getSegmentSeparator()
     self._parser = FormatParser(self._formats, self._separator)
示例#3
0
class LocationCodeCategory(Base):
    parent = models.ForeignKey("self", blank=True, null=True,
                               default=0, related_name='children')
    segment = models.CharField(
        max_length=248, db_index=True,
        help_text=_("See the LocationCodeDefault.description for the " +
                    "format used."))
    path = models.CharField(max_length=248, editable=False)
    char_definition = models.ForeignKey(LocationCodeDefault, editable=False)

    def __init__(self, *args, **kwargs):
        super(LocationCodeCategory, self).__init__(*args, **kwargs)
        self._formats = [fmt.char_definition
                         for fmt in LocationCodeDefault.objects.all()]
        self._separator = LocationCodeDefault.getSegmentSeparator()
        self._parser = FormatParser(self._formats, self._separator)

    def _getCategoryPath(self, current=True):
        parents = LocationCodeCategory.getParents(self)
        if current: parents.append(self)
        return self._separator.join([parent.segment for parent in parents])

    @classmethod
    def getParents(self, category):
        parents = LocationCodeCategory._recurseParents(category)
        parents.reverse()
        return parents

    @classmethod
    def _recurseParents(self, category):
        parents = []

        if category.parent_id:
            parents.append(category.parent)
            more = LocationCodeCategory._recurseParents(category.parent)
            parents.extend(more)

        return parents

    def _levelProducer(self):
        path = self._getCategoryPath()
        return path.count(self._separator)
    _levelProducer.short_description = _("Level")

    def _parentsProducer(self):
        return self._getCategoryPath(current=False)
    _parentsProducer.short_description = _("Segment Parents")

    def _charDefProducer(self):
        return self.char_definition.char_definition
    _charDefProducer.short_description = _("Character Definition")

    def clean(self):
        parents = LocationCodeCategory.getParents(self)

        if self.segment in [parent.segment for parent in parents]:
            raise ValidationError(_("You cannot save a category in itself."))

        if self._separator and self._separator in self.segment:
            msg = "A segment cannot contain the segment delimiter '%s'."
            raise ValidationError(_(msg % self._separator))

        maxNumSegments = LocationCodeDefault.getMaxNumSegments()
        length = len(parents) + 1

        if length > maxNumSegments:
            msg = "There are too many segments in this location code, " + \
                  "found: %s, allowed: %s"
            raise ValidationError(_(msg % (length, maxNumSegments)))

        try:
            self.char_definition = \
                                 LocationCodeDefault.getCharDefinitionBySegment(
                self._parser.getFormat(self.segment))
        except ValueError, e:
            msg = "Segment does not match a Location Code Default, %s"
            raise ValidationError(msg % e)

        if not self.char_definition:
            msg = "Invalid segment must conform to one of the following " + \
                  "character definitions: %s"
            raise ValidationError(_(msg % ', '.join(self._formats)))
示例#4
0
class LocationCodeCategory(Base):
    parent = models.ForeignKey("self",
                               blank=True,
                               null=True,
                               default=0,
                               related_name='children')
    segment = models.CharField(
        max_length=248,
        db_index=True,
        help_text=_("See the LocationCodeDefault.description for the " +
                    "format used."))
    path = models.CharField(max_length=248, editable=False)
    char_definition = models.ForeignKey(LocationCodeDefault, editable=False)

    def __init__(self, *args, **kwargs):
        super(LocationCodeCategory, self).__init__(*args, **kwargs)
        self._formats = [
            fmt.char_definition for fmt in LocationCodeDefault.objects.all()
        ]
        self._separator = LocationCodeDefault.getSegmentSeparator()
        self._parser = FormatParser(self._formats, self._separator)

    def _getCategoryPath(self, current=True):
        parents = LocationCodeCategory.getParents(self)
        if current: parents.append(self)
        return self._separator.join([parent.segment for parent in parents])

    @classmethod
    def getParents(self, category):
        parents = LocationCodeCategory._recurseParents(category)
        parents.reverse()
        return parents

    @classmethod
    def _recurseParents(self, category):
        parents = []

        if category.parent_id:
            parents.append(category.parent)
            more = LocationCodeCategory._recurseParents(category.parent)
            parents.extend(more)

        return parents

    def _levelProducer(self):
        path = self._getCategoryPath()
        return path.count(self._separator)

    _levelProducer.short_description = _("Level")

    def _parentsProducer(self):
        return self._getCategoryPath(current=False)

    _parentsProducer.short_description = _("Segment Parents")

    def _charDefProducer(self):
        return self.char_definition.char_definition

    _charDefProducer.short_description = _("Character Definition")

    def clean(self):
        parents = LocationCodeCategory.getParents(self)

        if self.segment in [parent.segment for parent in parents]:
            raise ValidationError(_("You cannot save a category in itself."))

        if self._separator and self._separator in self.segment:
            msg = "A segment cannot contain the segment delimiter '%s'."
            raise ValidationError(_(msg % self._separator))

        maxNumSegments = LocationCodeDefault.getMaxNumSegments()
        length = len(parents) + 1

        if length > maxNumSegments:
            msg = "There are too many segments in this location code, " + \
                  "found: %s, allowed: %s"
            raise ValidationError(_(msg % (length, maxNumSegments)))

        try:
            self.char_definition = \
                                 LocationCodeDefault.getCharDefinitionBySegment(
                self._parser.getFormat(self.segment))
        except ValueError as e:
            msg = "Segment does not match a Location Code Default, %s"
            raise ValidationError(msg % e)

        if not self.char_definition:
            msg = "Invalid segment must conform to one of the following " + \
                  "character definitions: %s"
            raise ValidationError(_(msg % ', '.join(self._formats)))

    def save(self, *args, **kwargs):
        # Run all the validators.
        self.full_clean()

        # Fix our self.
        self.path = self._getCategoryPath()
        super(LocationCodeCategory, self).save(*args, **kwargs)

        # Fix all the children if any.
        iterator = self.children.iterator()

        try:
            while True:
                child = iterator.next()
                child.save()
        except StopIteration:
            pass

    @classmethod
    def getAllRootTrees(self, segment):
        result = []
        records = LocationCodeCategory.objects.filter(segment=segment)

        if len(records) > 0:
            result[:] = [
                LocationCodeCategory.getParents(record) for record in records
            ]

        return result

    ## @classmethod
    ## def getSegmentLength(self, segment=None):
    ##     result = 0
    ##     record = LocationCodeCategory.objects.get(segment=segment)

    ##     if record:

    ##     #return self.segment_length

    def __str__(self):
        return self.path

    class Meta:
        verbose_name = _("Location Code")
        verbose_name_plural = _("Location Codes")
        ordering = ('path', )