Skip to content

Activatable entities

julia-fms edited this page Feb 7, 2020 · 12 revisions

Activatable entities provide a way to model those domain aspects that have temporal or lifecycle-like nature (i.e going through various stages) that lead to activation (switch-on) and deactivation (switch-off) of entities.

For example, WorkActivity, PmRoutine and Person are activatable entities.

There are following rules related to such entities:

1. Activatable entitiy should extend ActivatableAbstractEntity.

public class PmRoutine extends ActivatableAbstractEntity<...>

Also it is a good idea to override its parent's method setActive() in the following manner:

   @Observable
   public PmRoutine setActive(final boolean active) {
       super.setActive(active);
       return this;
   }

Sometimes user is in control and decides when entity becomes active/inactive (in case of PmRoutine and Person), but sometimes it is totally controlled by system and entity changes it's state automatically (in case of WorkActivity).

For example, existing PM Routine is replaced be newer version, as result it may become inactive at some point of time and system's manager is in charge of making this decision.

When in case of Work Activity it becomes inactive when it's status progresses to the status F (finished) or C (Closed), and deactivation is happening automatically in the WorkActivityStatusDefiner:

    @Override
    public void handle(final MetaProperty<WorkActivityStatus> property, final WorkActivityStatus newStatus) {
        final WorkActivity workActivity = property.getEntity();

        if (!workActivity.isInitialising()) {
            // A user or some business logic has changed the status - set "active" flag accordingly.
            workActivity.setActive(newStatus.isActiveStatus());
        }
    }

Therefore if activation/deactivation should be automatically controlled the business rule have to be provided.

2. Properties refCount and active have to be included in the model.

If you are creating activatable entity in the new system you have to include two properties in the entity's retriever: refCount and active.

    @Override
    public SortedMap<String, String> resultFields() {
        return map(
                field("key", "LTRIM(RTRIM(CRAFT))"),
                field("desc", "CRAFT_DESC"),
                field("active", "COALESCE(CASE UPPER(LTRIM(RTRIM(CONTRACTOR))) WHEN 'Y' THEN 'Y' WHEN 'N' THEN 'Y' WHEN 
                'EY' THEN 'N' WHEN 'EN' THEN 'N' ELSE NULL END, 'N')"),
                field("refCount", "0"),
                .....................
                );
    }

If you are modifying an existing entity you have to provide SQL script that changes database structure by adding REFCOUNT_ and ACTIVE_ columns.

  ALTER TABLE MODIFICATION_ ADD REFCOUNT_ [int] NOT NULL
  GO 
  ALTER TABLE MODIFICATION_ ADD ACTIVE_ [char](1) NOT NULL
  GO 

3. Activatable dependencies have to be considered.

Very often activatable entity could be a property of another entity. For example, activatable entity Timesheet has property person that is activatable entity. We therefore refer to Timesheet as an activatable dependency of Person.

Activatable entities cannot be deactivated if active dependencies exist. Property refCount is used to keep track of active activatable dependencies. Therefore it is critical to provide an SQL script to calculate the number of active activatable dependencies.

UPDATE Modification_ SET REFCOUNT_ = 0;
GO

UPDATE Modification_ SET REFCOUNT_ = 
 (SELECT COUNT(*) FROM WORKORDER_ AS DEPENDENT_ 
     WHERE DEPENDENT_.ACTIVE_ = 'Y' AND 
           DEPENDENT_.Modification_ = Modification_._ID
    ) 
 WHERE ACTIVE_ = 'Y'
GO

Please note that method main in ApplicationDomain can be used to locate all activatable dependencies in the model domain for a given entity.

4. Deactivatable dependencies.

Sometimes when activatable entity is made inactive it should also automatically deactivate dependent active entities. For example, activatable entity PmRoutine has an activatable dependency PmTimeXref. When PmRoutine is made inactive, there is a requirement for all associated PmTimeXrefs to also be made inactive.

@DeactivatableDependencies(...) annotation is used to achieve this.

@DeactivatableDependencies(PmTimeXref.class)
public class PmRoutine extends ActivatableAbstractEntity<String>
Clone this wiki locally