Loading...
 

Validity

Validity

Setting validities

All objects that are derived from the type CX_TERMED can be provided with validities. To set the validity of an object there is the access function SpanDateValidity() and exchange objects are linked to the object. The current validity date can be read out via ValidityDate and set via SetValidityDate. A validity date of NULL deactivates the validity check of objects.

Code example:
Var(invalid, valid) CreateTransObject(CX_EXPANDABLE) -> invalid CreateTransObject(CX_EXPANDABLE) -> valid "invalid" invalid Put(str) "valid" valid Put(str) "gestern" invalid Put(SpanDateValidity()) "heute" valid Put(SpanDateValidity()) valid invalid Call(Link) invalid Copy(str) //-> "invalid" direct access, no validity checked invalid Copy(this.str) //-> "valid" access via 'this' checks validity

Validity in access expressions

Access expressions are divided into terms. A dot separates the individual terms. An access expression is always evaluated from left to right, term by term.

Each time you switch to the next term, the validity is taken into account if the previous term is an object:

  • ...reference.term...
    If reference refers to an invalid object, a matching valid object is searched for before term is applied to it.
  • ...reference
    After reference no term follows, the referenced object is returned without regard to its validity.

reference is a reference to an object (e.g. mother) or a collection with subscript (e.g. children(2)).
term is a data field, a function call or this.

If you get an object, you get exactly this object.
If you do something with the object, the currently valid object is used.

Examples:

A and B are CX_PERSON objects, where A is valid until yesterday and B from today. Furthermore, B is defined as an exchange object of A. The system validity is set to today.

A Copy(uniqueID) -> get A.uniqueID (1st rule)
B Copy(uniqueID) -> get B.uniqueID (1st rule)
A Copy(this.uniqueID) -> get B.uniqueID (2nd rule, with "this" something is done)
B Copy(this.uniqueID) -> get B.uniqueID (2nd rule, with "this" something is done)

A A Link(masterObject)
B B Link(masterObject)
A Get(masterObject) -> returns A (1st rule)
B Get(masterObject) -> returns B (1st rule)
A Get(this.masterObject) -> returns B (2nd rule, with "this" something is done)
B Get(this.masterObject) -> returns B (2nd rule, with "this" something is done)
A Copy(masterObject.uniqueID) -> get B.uniqueID (2nd rule, with "masterObject" something is done)
B Copy(masterObject.uniqueID) -> get B.uniqueID (2nd rule, with "masterObject" something is done)

Queries, Conditioned Bags

  • All types of queries do not observe any validity.
  • Search in CX_CONDITIONED_BAG does not take into account validity.
  • No search in CX_DICTIONARY and relatives either.

Council

Council functions respect the validity

  • when you register,
  • in all Convert() functions,
  • with implied conversion by modification of the unit table,
  • for temporary change of unit names

Model functions

These model functions observe the validity, e.g. when iterating over collections or tracking pointers:

  • CX_ATTRIBUTE::GetDataField and PlugDataField
  • CX_ITEM_PATTERN::Item()
  • CX_USER::CheckPassword()

All other model functions do not respect the validity. Here are the functions where it is known:

  • CX_ALLOCATION::Allocators()
  • CX_ATTRIBUTE_SET::AttributeNames(), ViewExport()
  • CX_BUSINESS_OBJECT::Access(), CastedStructureByCondition(), MonitorByUnique(), TotalMonitors(), Allocation(), Allocators(), JobSchedule(), ClearingObject(), EmployeeOfCE(), EmployeeByFirstChoiceOfCE()
  • CX_CASH_DISCOUNT::DueCharge(), NetDueCharge()
  • CX_CHARGE_SET::NthDueCharge()
  • CX_DATA_CUBE::DataCube(), TopDimensions()
  • CX_ITEM::Attribute(), Monitor, SubCube(), AccountOwner(), GetTransTable()
  • CX_LEGAL_PERSON::Access(), Employees()
  • CX_MONITOR::Total()
  • CX_SCHEDULE::Predecessor(), Successor()
  • CX_SET_ALLOCATION::Examine(), Resolve3(), Inspect()
  • CX_STRUCTURE::Object()
  • CX_STRUCTURED::StructureByID(), StructureByEnum(), Monitor(), MonitorByUniqueID()
  • CX_TAX::GeneralLedger()
  • CX_TRANSACTION::Monitor(), Predecessors()

InstantView® Commands

  • FillObox, UpdateObox: The currently valid object is always inserted into the ObjectList(View). With the flags LIST_INVALID or LIST_ORIGIN the display of the valid objects and their exchange objects can be configured.
  • UpdateObox: The Siblings are also replaced.
  • iterate: Cardinality does not respect any validity
  • NODE for tree tracking observes validity
  • FillWindow considers validities if it implicitly triggers a FillObox because a collection is displayed (with and without ENTIRE)

Technical description

An object that can have a validity must be derived from CX_TERMED This applies to CX_EXPANDABLE and the following, i.e. all info and business classes. The validity itself is stored in a CX_VALIDITY object. These object pairs form a ring:

Instead of a CX_VALIDITY object, a CX_TERMED_VALIDITY object that points to a CX_DATE object is usually used. In most cases, it should actually be a CX_SPAN_DATE object.

How is the valid exchange object found for an invalid object? Assume that A and B are invalid, only C is valid. From A the valid exchange object is to be found.
The system jumps to the CX_VALIDITY objectAv via the pointer 'validity'. Via 'termedValidity' it reaches the CX_SPAN_DATE object and determines that today is not within this range. The system then jumps to the next exchange object B viaAv.next. The check is repeated. This algorithm is repeated until a valid object is found or the start object is reached again. In this case there is no valid exchange object.

If you combine effectivity with wrapping, wrappers and wrapped objects can either be part of the same effectivity ring or exist in different effectivity rings. This is explained in more detail here.