Skip to content

Task record lifecycle — create, retrieve, insert, update, soft-delete

clsTask is an abstract BOF business object; every concrete task type in the SAIF task ecosystem inherits it and shares one CRUD lifecycle against the TASK table through the pk82036_task Oracle package. The lifecycle covers five phases that a caller may trigger independently: in-memory initialization of a new task, single-row retrieval by task sequence number, insert of a new row, update of an existing row, and soft-delete of a row. All five phases are implemented as overrides of the BOF data-portal template methods (Create, BeforeRetrieve/AfterRetrieve, BeforeInsert/AfterInsert, BeforeUpdate/AfterUpdate, BeforeDelete/AfterDelete) on the same class, and insert/update share the same field-level validation rule set, so they are documented together as one operation.

Field Value
Operation ID OP-TASK-01
Trigger A concrete task subclass calls Create() (new task), triggers a BOF retrieve with a TaskID criterion, or calls Save() on a new/dirty/deleted task instance
Inputs Task field values (CategoryCode, SourceCode, PriorityCode, MailID, Text, TaskDate, ActionCode, ClaimID, PolicyNum, ImageSeqNum, TaskSecurity, TaskContext values), TaskSeqNum, UpdateSeqNum, acting user from IDataPortalInfo
Outputs Populated task object (retrieve); inserted/updated/soft-deleted TASK row and a rows-affected result (insert/update/delete); broken-rule collection when validation fails
Primary components clsTask.Create, clsTask.BeforeRetrieve, clsTask.AfterRetrieve, clsTask.BeforeInsert, clsTask.AfterInsert, clsTask.BeforeUpdate, clsTask.AfterUpdate, clsTask.BeforeDelete, clsTask.AfterDelete, clsTask.AddBusinessRules, clsTask.AssignTaskDate
Entry point Business\SAIF.Business.Tasks\clsTask.vb

Steps

  1. Initialize a new task. A concrete subclass constructs a task; Create() resets Text, SourceCode, CategoryCode, ActionCode to empty strings, sets NotepadFlag and DeleteFlag to N, and seeds CreateUser from the criteria's explicit create-user value or, if that is blank, from MyCriteria.DataPortalInfo.UserID.
  2. UpdateUser, CreateDate, and UpdateDate are stamped with the create user and the current time, and the smart-value fields (ClaimID, PolicyNumber, TaskDate, ImageSeqNum, UpdateUser, Mailid) are marked as their own originals so change tracking starts clean.
  3. Populate task fields. The caller (or concrete subclass) sets the task's properties before validation or persistence. Setting TaskDate runs AssignTaskDate, which leaves the date unchanged for CurrentDay mode but, for NextWorkDay or PriorWorkDay mode, rolls the date forward or backward off weekends/non-working days and flags TaskDateModified = True (BR-003).
  4. Retrieve a single task. BeforeRetrieve issues a stored-procedure call to pk82036_task.task_select, binding only the TaskID (task sequence number) and a REF CURSOR output (SQL-002, TASK) (BR-012).
  5. AfterRetrieve reads the cursor; if a row is returned, Fill() populates all task fields including the embedded TaskContext values, then PostFill() (implemented by the concrete subclass) runs, and the instance is marked old (clean, not new).
  6. If no row is returned, the object is left unfilled and is still marked old.
  7. Validate before save. AddBusinessRules() registers text-required checks for CategoryCode, SourceCode, PriorityCode, and MailID (BR-004, BR-005, BR-006, BR-007), delegating to the TextRequired helper on CommonBusinessRules (SAIF.Business).
  8. clsTaskBusinessRules.ValidSourceCategory runs a scalar count of TASK_CATEGORY_CODE for the task's source/category pair (SQL-005, TASK_CATEGORY_CODE) (BR-001).
    • If the count is zero, the concrete subclass gets a final say through OverrideRules("TASK1", ...); if the subclass does not override, the mismatch is added as a broken rule.
  9. clsTaskBusinessRules.CheckDate runs only when the task is dirty and not deleted, and only if the date was adjusted by AssignTaskDate or is still Date.MinValue; it then delegates to CommonBusinessRules.IsTodayOrFutureDate (SAIF.Business) (BR-002).
    • Batch-rule tasks (BatchRules = True) skip this check entirely.
    • If the date is in the past, the subclass may override through OverrideRules("TASK2", ...); otherwise the past-date error is recorded.
  10. clsTaskBusinessRules.CheckDateModified reports the workday-adjustment warning recorded in step 2, selecting the next-workday or prior-workday wording and again allowing subclass override through OverrideRules("TASK4", ...) (BR-003).
  11. Insert a new task. BeforeInsert calls pk82036_task.task_insert, binding the full set of task and context fields plus a rows-affected return parameter (SQL-001, TASK).
  12. The Oracle function normalizes a zero ClaimID to NULL (BR-013) and a zero PolicyNum to NULL (BR-014), and seeds DELETE_FLAG = 'N', UPDATE_SEQ_NUM = 0, CREATE_DATE/UPDATE_DATE = SYSDATE, and a new TASK_SEQ_NUM from TASK_SEQ.NEXTVAL (BR-015).
  13. AfterInsert checks the rows-affected value (BR-008):
    • If not exactly 1: add InsertError with the message Task Insert Failed.
    • If 1: remove any prior InsertError and mark the object old.
  14. Update an existing task. BeforeUpdate re-stamps UpdateDate to now and UpdateUser from the data-portal info, then calls pk82036_task.task_update, binding the mutable task/context fields plus TaskSeqNum, UpdateSeqNum, and a rows-affected return parameter (SQL-013, TASK).
  15. The Oracle function matches on TASK_SEQ_NUM AND UPDATE_SEQ_NUM (BR-016), normalizes zero ClaimID/PolicyNum to NULL (BR-017), and on a match advances UPDATE_DATE, UPDATE_SEQ_NUM + 1, and UPDATE_USER (BR-018).
  16. AfterUpdate checks the rows-affected value (BR-009):
    • If not exactly 1: add UpdateError with the shared database-contention message.
    • If 1: remove any prior UpdateError, increment the in-memory UpdateSeqNum, and mark the object old.
  17. Soft-delete a task. A concrete subclass marks the task completed and satisfies whatever delete-eligibility semantics it defines, then BeforeDelete sets UpdateUser from the data-portal info and calls pk82036_task.task_delete, binding TaskSeqNum, UpdateSeqNum, UpdateUser, and a rows-affected return parameter (SQL-014, TASK).
  18. The Oracle function matches on TASK_SEQ_NUM AND UPDATE_SEQ_NUM (BR-020) and sets DELETE_FLAG = 'Y' instead of physically removing the row (BR-019).
  19. AfterDelete checks the rows-affected value (BR-010):
    • If not exactly 1: add DeleteError with the shared database-contention message.
    • If 1: remove any prior DeleteError.

Process flow

The following diagram visualizes the five phases of the task record lifecycle and their shared validation and concurrency handling.

flowchart TD
    Start([Concrete task subclass<br>drives the lifecycle]) --> Which{Which phase?}
    Which -->|New| Create[Create: seed defaults,<br>audit stamps]
    Which -->|Retrieve| RetSel[Call task_select<br>by TaskID]
    RetSel --> RetFill{Row returned?}
    RetFill -->|Yes| Fill[Fill fields and<br>TaskContext, PostFill]
    RetFill -->|No| Empty([Object left unfilled,<br>marked old])
    Which -->|Save new/dirty| Validate{AddBusinessRules<br>pass?}
    Validate -->|No| Broken([Broken rules returned;<br>no DB call])
    Validate -->|Yes, new| Insert[Call task_insert]
    Validate -->|Yes, existing| Update[Call task_update]
    Which -->|Save deleted| Delete[Call task_delete]
    Insert --> InsRows{RowsAffected = 1?}
    InsRows -->|No| InsErr([InsertError added])
    InsRows -->|Yes| InsOk([Marked old])
    Update --> UpdRows{RowsAffected = 1?}
    UpdRows -->|No| UpdErr([UpdateError: contention])
    UpdRows -->|Yes| UpdOk([UpdateSeqNum incremented,<br>marked old])
    Delete --> DelRows{RowsAffected = 1?}
    DelRows -->|No| DelErr([DeleteError: contention])
    DelRows -->|Yes| DelOk([DeleteError cleared])

Failure and edge-case behavior

  • A rows-affected value other than 1 is treated as a hard failure on insert, update, and delete alike — the message differs (Task Insert Failed for insert; the shared database-contention message for update and delete) but the effect is the same: the in-memory object is not marked clean and the caller sees a broken rule.
  • The ValidSourceCategory, CheckDate, and CheckDateModified rules all route their failing result through clsTask.OverrideRules, a no-op hook in the base class; a concrete subclass can silently suppress any of the three by overriding it, so the documented outcomes assume no override is applied.*
  • CheckDate is bypassed entirely when BatchRules is True, when the task is not dirty, when the task is deleted, or when the date was not modified and is not Date.MinValue — so an already-valid date is never re-validated on a routine save.
  • AssignTaskDate only adjusts the date when it is neither Date.MinValue nor Date.MaxValue; sentinel dates pass through unmodified and unflagged.
  • Retrieval silently returns an empty, "old" object when pk82036_task.task_select finds no matching row — there is no explicit not-found error surfaced by this class.*

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.

Sources

  • Business\SAIF.Business.Tasks\clsTask.vb
  • Business\SAIF.Business.Tasks\clsTaskBusinessRules.vb