Sequence Configuration Model

Developer guide for the Enezaframework sequence generation. Part of the Sequence Generation series.

Table of Contents

  1. Overview
  2. Model Definition
  3. Field Reference
  4. Unique Constraint
  5. get_sequence_format()
  6. Related Guides

Overview

SequenceConfig (enezaframework/models/enezasequence.py:10) is the per-document record that drives numbering. SequenceMixin.generate_sequence() looks up the single active config for the model's document_name, reads nextnumber, formats it, and increments the counter.


Model Definition

python
class SequenceConfig(EnezaModel):
    documents = models.CharField(
        max_length=50,
        null=False,
        choices=get_number_sequences_choices().choices,
        help_text="Choose the model for this sequence configuration.",
    )
    prefix = models.CharField(
        max_length=10,
        null=False,
        help_text="Prefix like 'IV', 'CR', etc.",
    )
    delimiter = models.CharField(
        max_length=1,
        default='-',
        help_text="Delimiter like '-', '_', etc.",
    )
    number_length = models.PositiveIntegerField(
        default=4,
        null=False,
        help_text="Length of the number sequence (e.g., 4 for '0001').",
    )
    active = models.BooleanField(
        default=False,
    )
    nextnumber = models.PositiveIntegerField(
        default=1,
        help_text="Next number for the sequence.",
    )
    modules = models.CharField(
        max_length=50,
        null=False,
        choices=get_modules_choices().choices,
        help_text="Choose the module for this sequence configuration.",
    )
    entity = models.ForeignKey(
        Entity,
        on_delete=models.PROTECT,
        blank=True,
        null=True,
        help_text="Entity to which this sequence configuration belongs.",
    )

SequenceConfig extends EnezaModel, so it carries the standard UUID PK, audit fields, and history.


Field Reference

Field Type Purpose Example
documents CharField(50) Document type identifier; matched against the model's document_name. CUST, INVC, PO
prefix CharField(10) Alpha prefix. CUST, INV, PO
delimiter CharField(1) Character between prefix and number. -, _, /
number_length PositiveIntegerField Width of the numeric portion. 4 → 0001, 6 → 000001
active BooleanField Whether generate_sequence() will use it. True
nextnumber PositiveIntegerField The next number to assign; incremented after each use. 1, 1001
modules CharField(50) Module category for organization. GL, AP, IM
entity ForeignKey(Entity) Multi-tenant scoping. per company

The final value is prefix + delimiter + zero-padded(nextnumber). The modules field only categorizes the config; it does not affect the generated string.


Unique Constraint

python
class Meta:
    constraints = [
        models.UniqueConstraint(
            fields=['documents', 'active'],
            name='unique_model_name_active',
        )
    ]

This constraint makes the (documents, active) pair unique. In practice:

  • At most one active config per document type — which is what generate_sequence() relies on (filter(documents=..., active=True).first()).
  • At most one inactive config per document type as well, because (documents, False) is also unique.

The source guide suggests keeping multiple inactive configs "as historical records". The constraint above prevents that: for any document type you can have only one active=True row and one active=False row. To change a format, deactivate or delete the current row before creating another, or adjust the constraint.


get_sequence_format()

python
def get_sequence_format(self):
    formatted_number = '#' * self.number_length
    return f"{self.prefix}{self.delimiter}{formatted_number}"

Returns a display-only preview using # for each digit — for example CUST-#### or INV-#####. It is useful in admin and templates; it is not used during generation. See Sequence Template Integration.