Sequence Configuration Model
Developer guide for the Enezaframework sequence generation. Part of the Sequence Generation series.
Table of Contents
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
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
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=Truerow and oneactive=Falserow. To change a format, deactivate or delete the current row before creating another, or adjust the constraint.
get_sequence_format()
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.