Base classes

Base classes for business rules and violations.

class common.business_rules.BusinessRule(transaction=None)[source]

Represents a TARIC business rule.

classmethod get_linked_models(model: common.models.trackedmodel.TrackedModel, transaction) Iterator[common.models.trackedmodel.TrackedModel][source]

Returns latest approved model instances that have relations to the passed model and have this business rule listed in their business_rules attribute.

Parameters
  • TrackedModel (model) – Get models linked to this model instance

  • Transaction (transaction) – Get latest approved versions of linked models as of this transaction

Returns

The linked models

Return type

Iterator[TrackedModel]

validate(*args)[source]

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

violation(model: Optional[common.models.trackedmodel.TrackedModel] = None, message: Optional[str] = None) common.business_rules.BusinessRuleViolation[source]

Create a violation exception object.

Parameters
  • model (Optional[TrackedModel]) – The model that violates this business rule

  • message (Optional[str]) – A message explaining the violation

Rtype BusinessRuleViolation

An exception indicating a business rule violation

class common.business_rules.BusinessRuleBase(name, bases, attrs, **kwargs)[source]

Metaclass for all BusinessRules.

Adds a :exception:BusinessRuleViolation nested class, which can be accessed as BusinessRuleSubclass.Violation, and sets the docstring (and hence the default error message) to the docstring of the new class.

exception common.business_rules.BusinessRuleViolation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)[source]

Base class for business rule violations.

default_message() Optional[str][source]

Get the first paragraph of the class docstring (if it exists) to use as the error message.

Return Optional[str]

The error message

class common.business_rules.DescriptionsRules(transaction=None)[source]

Repeated rule pattern for descriptions.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Repeated rule pattern for descriptions.

validate(model)

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

class common.business_rules.ExclusionMembership(transaction=None)[source]

The excluded geographical area must be a member of the geographical area group.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

The excluded geographical area must be a member of the geographical area group.

excluded_from: str

The object that the geographical area is excluded from.

validate(exclusion)[source]

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

class common.business_rules.FootnoteApplicability(transaction=None)[source]

Check that a footnote type can be applied to a certain model, based on the set of ApplicationCode that the model reports is valid for itself.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Check that a footnote type can be applied to a certain model, based on the set of ApplicationCode that the model reports is valid for itself.

applicable_field: str

The field containing a model to check applicability for.

It must have a property or attribute called footnote_application_codes.

footnote_type_field: str = 'associated_footnote__footnote_type'

The field containing a footnote type to check for applicability.

validate(model)[source]

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

class common.business_rules.MustExist(transaction=None)[source]

Rule enforcing a referenced record exists.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Rule enforcing a referenced record exists.

validate(model)[source]

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

class common.business_rules.MustExistNotNull(transaction=None)[source]

Rule enforcing a referenced record exists, Null values raise violation.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Rule enforcing a referenced record exists, Null values raise violation.

validate(model)[source]

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

class common.business_rules.NoBlankDescription(transaction=None)[source]

Descriptions should not be blank.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Descriptions should not be blank.

validate(model)[source]

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

class common.business_rules.NoOverlapping(transaction=None)[source]

Rule enforcing no overlapping validity periods of instances of a model.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Rule enforcing no overlapping validity periods of instances of a model.

validate(model)[source]

Check other models with the same identifying fields do not have overlapping validity periods, except other versions of the same model.

Parameters

TrackedModel (model) – The model to compare with

Raises

self.violation – Rule violation

class common.business_rules.PreventDeleteIfInUse(transaction=None)[source]

Rule preventing deleting an in-use model.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Rule preventing deleting an in-use model.

has_violation(model) bool[source]

Return True if the given model instance is “in use” - determined by calling the method on the model instance named in self.in_use_check.

Parameters

TrackedModel (model) – The model to check

Rtype bool

True if the specified model’s “in use” method returns True

validate(model)[source]

Check whether the specified model violates this business rule.

Parameters

TrackedModel (model) – The model to check

Raises

BusinessRuleViolation – Raised if the passed model violates this business rule.

class common.business_rules.UniqueIdentifyingFields(transaction=None)[source]

Rule enforcing identifying fields are unique.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Rule enforcing identifying fields are unique.

validate(model)[source]

Check no other model has the same identifying fields, except other versions of the same model.

Parameters

TrackedModel (model) – The model to compare with

Raises

self.violation – Rule violation

class common.business_rules.UpdateValidity(transaction=None)[source]

The update type of this object must be valid.

The first update must be of type Create. Subsequent updates must not be of type Create. After an update of type Delete, there must be no further updates. Only one version of the object may be updated in a single transaction.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

The update type of this object must be valid.

The first update must be of type Create. Subsequent updates must not be of type Create. After an update of type Delete, there must be no further updates. Only one version of the object may be updated in a single transaction.

validate(model)[source]

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

class common.business_rules.ValidityPeriodContained(transaction=None)[source]

Rule enforcing validity period of a container object completely contains the validity period of one more contained objects.

Checks that the following is true:

for contained_object in contained_objects:

container_object.valid_between contains contained_object.valid_between

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Rule enforcing validity period of a container object completely contains the validity period of one more contained objects.

Checks that the following is true:

for contained_object in contained_objects:

container_object.valid_between contains contained_object.valid_between

contained_field_name: Optional[str] = None

The name of a field (or double-underscore-seperated path to a field) on the passed model that gives the object(s) who’s validity range should be smaller or equal at both ends.

This value can be unspecified, in which case the default is that the passed model is the contained model.

The contained object may be null because subrecords are not routinely deleted when the parent record is deleted. For example, if a footnote is attached to a measure but the measure is deleted, the footnote association may not be routinely cleared up.

Note that this one reason is why it is important to make sure we are checking against the latest versions because the object will still be linking via FK to the contained object version it was first attached to. The other good reason is that if the dates on the container or contained objects are modified, this business rule needs to be considering them.

container_field_name: Optional[str] = None

The name of the field on the passed model that gives the object who’s validity range should be bigger or equal at both ends.

This value can be unspecified, in which case the default is that the passed model is the container model.

The container may be null because some business rules refer to optional links. E.g. between additional codes and measures: in many cases the measure just may not be using an addiitonal code, but this rule is run against every measure. The case where the container has been deleted but the contained object has not been deleted yet should be prevented by other business rules but is of course possible to represent in the data, so we ignore that case too.

extra_filters: Dict[str, Any] = {}

Any extra filters that should be applied to filter the contained objects.

validate(model)[source]

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

class common.business_rules.ValidityStartDateRules(transaction=None)[source]

Repeated rule pattern for descriptions.

exception Violation(model: common.models.trackedmodel.TrackedModel, message: Optional[str] = None)

Repeated rule pattern for descriptions.

validate(model)[source]

Perform business rule validation.

Raises

NotImplementedError – Must be overridden by subclasses

common.business_rules.only_applicable_after(cutoff: Union[datetime.date, datetime.datetime, str])[source]

Decorate BusinessRules to make them only applicable after a given date.

Parameters

str] (cutoff Union[date, datetime,) – The date, datetime or isoformat

date string of the time before which the rule should not apply

common.business_rules.skip_when_deleted(cls: Type[common.business_rules.BusinessRule])[source]

Skip business rule when the model is being deleted.

Parameters

Type[BusinessRule] (cls) – BusinessRule to decorate

common.business_rules.skip_when_not_deleted(cls: Type[common.business_rules.BusinessRule])[source]

Skip business rule when the model is not being deleted.

Parameters

Type[BusinessRule] (cls) – The BusinessRule to decorate

common.business_rules.skip_when_update_type(cls: Type[common.business_rules.BusinessRule], update_types: Iterable[common.validators.UpdateType])[source]

Skip business rule validation for given update types.

Parameters
  • cls (Type[BusinessRule]) – The BusinessRule to decorate

  • update_types (Iterable[int]) – The UpdateTypes to skip