Event handlers — FillCheckProcessing
Scope: managed applications, mobile applications, and ordinary applications.
1.1. This object module's handler is intended to validate the values of object attributes, such as dimensions and resources.
See also Properties — Tooltip and Required field
1.2. It is recommended that you use this event handler when the default required field validation is not sufficient. For example, when an attribute value depends on another value or when the entry is required conditionally.
If an attribute value validation is conditional—depends on the value of an attribute or functional option—provide the event handler with the code that will remove the name of the attribute from the CheckedAttributes array. A common filling check has the following procedure:
- Create the AttributesNotToCheck array that contains the attributes the check will ignore.
- Add to the array the names of the attributes that don't meet the conditions.
- Call the DeleteNotCheckedAttributesFromArray procedure that will delete the ignored attributes.
It is not recommended that you employ other approaches to verify values. Since some checking conditions will be implemented beyond the "Required field" property, it will be troublesome for other developers to understand the configuration behavior.
Incorrect:
Procedure FillCheckProcessing(Cancel, CheckedAttributes)
...
// Check if the value meets the conditions.
If NOT TINMeetsRequirements(TIN) Then
Message = New UserMessage();
Message.Text = NStr("en = 'TIN is invalid.'");
Message.Field = "TIN";
Message.SetData(ThisObject);
Message.Message();
Cancel = True;
EndIf;
...
// The attribute value is conditionally required depending on another attribute value.
If EntityType = Enums.EntityType.Individual Then
// An entrepreneur must be mapped with an individual.
CheckedAttributes.Add("IndividualEntrepreneur");
EndIf;
...
EndProcedure
Correct:
Procedure FillCheckProcessing(Cancel, CheckedAttributes)
AttributesNotToCheck = New Array();
...
// Check if the value meets the conditions.
If NOT TINMeetsRequirements(TIN) Then
Message = New UserMessage();
Message.Text = NStr("en = 'TIN is invalid.'");
Message.Field = "TIN";
Message.SetData(ThisObject);
Message.Message();
Cancel = True;
AttributesNotToCheck.Add("TIN");
EndIf;
...
// The attribute value is conditionally required depending on another attribute value.
If EntityType <> Enums.EntityType.Individual Then
AttributesNotToCheck.Add("IndividualEntrepreneur");
EndIf;
...
DeleteNotCheckedAttributesFromArray(CheckedAttributes, AttributesNotToCheck);
EndProcedure;
Procedure DeleteNotCheckedAttributesFromArray(AttributesArray, NotCheckedAttributeArray) Export
For Each ArrayElement In NotCheckedAttributeArray Do
// Before deleting, ensure the array contains the attribute.
// It might have been already deleted.
SequenceNumber = AttributesArray.Find(ArrayElement);
If SequenceNumber <> Undefined Then
AttributesArray.Delete(SequenceNumber);
EndIf;
EndDo;
EndProcedure
1.3. Not every write operation calls FillCheckProcessing. For example, when writing is initiated programmatically.
Best practices 1.4. If a configuration contains the "Data exchange" SSL subsystem, FillCheckProcessing is called when a document is posted and imported from the exchange message. To disable some of the checks, adjust the AdditionalProperties.DeferredPosting property. |
Checks before and during transactions
2.1. Checks in FillCheckProcessing always run before the write transaction starts. This is considered the best practice since if some attribute values are invalid, the operation is terminated before an attempt to write to the database.
Note that before all checks in FillCheckProcessing are completed, the new state of the object is not committed. If you need to access some data—for example, get the ProductKind for the products in a tabular section—create a temporary table, save the data to the table, and send it as the request parameter.
2.2. FillCheckProcessing is not intended to contain checks that validate the integrity of the object or linked data, such as document records. To validate attributes whose invalid values might result in the data inconsistency, place the checks in the event handlers that process transaction events: BeforeWrite, OnWrite, and Posting.
There are two types of transaction checks:
- Checking register records generated by real-time accounting documents. Such checks are typical for real-time accounting applications and run quite often.
- Checking the state of the objects that are referenced by the current object. Make sure that in your application such checks don't run often. Try to keep the number of transaction checks as low as possible. During write transactions, check only the resources and the object map rules that cannot be changed unless they are checked by all transaction participants.
In the first case, in a write transaction, check the balance only if all transaction documents run this check. If even one of the participants modifies the resource without the prior check, it will nullify other participants' check effect. It is acceptable to ignore the recommendation only if the document rarely modifies the resource. For example, although the "Inventory count" document changes stock balance without prior checks, it is acceptable since the users rarely create it. Use your best judgment when you develop a document that does not check the resources.
In the second case, for example, if a user saves a Department, the write transaction checks whether the employee that is assigned as the department manager has the "Manager" position. There must be a cross-check of the same rule when the Employee is being written: if the Employee's position is not Manager, the transaction fails. Since the rule—the Employee assigned as the department manager must have the Manager position—can be violated when the employee or department is being written, both checks must be run either during the transaction or before the transactions.