Skip to content

Phone info CRUD and linking

clsPhoneInfo is a standalone PHONE row that concatenates its country code, area code, prefix, number, and extension into a single stored value (unless the number is foreign). As with addresses and emails, the owning collection tracks adds/removes and reconciles the COMPANY_PHONE / PERSON_PHONE link rows on save.

Field Value
Operation ID OP-CC-07
Trigger Caller adds/removes a clsPhoneInfo in clsCustomer.Phones or clsContact.Phones, then the parent's Save() cascades into the collection; or mdlCustomerContact.CreatePhone is called directly
Inputs PhoneID, Value/FormattedValue, PhoneCode (phone type), IsPrimary, IsForeign
Outputs Persisted PHONE row; persisted or removed COMPANY_PHONE / PERSON_PHONE link row
Primary components clsPhoneInfo.Create, clsPhoneInfo.SetStoredVersion, clsPhoneInfo.AddBusinessRules, mdlCustomerContact.CreatePhone, clsInfoCollection.Save
Entry point Business\SAIF.Business.CustomerContact\InfoItems\clsPhoneInfo.vb

Steps

  1. Create a new phone row. Create() assigns PhoneID from GetNextSeqNum("PHONE_SEQ").
  2. Normalize the stored value. SetStoredVersion() concatenates CountryCode, AreaCode, Prefix, Number, and Extension into the persisted phone value; this normalization is skipped when IsForeign = True, leaving the foreign value as entered.
  3. Validate (BR-007). AddBusinessRules registers CommonBusinessRules.NonZeroDecimalRequired for PhoneID and CommonBusinessRules.TrimTextRequired for FormattedValue (with the Business_External_Users.ErrMsgPhoneRequired message).
  4. Persist the root PHONE row. Insert (SQL-016/SQL-017), update (SQL-073/SQL-074), and delete (SQL-090/SQL-091) against PHONE.
  5. Reconcile link rows through clsInfoCollection.Save(), using the same add/remove-tracking pattern used for addresses and emails (see Address info CRUD and linking): save current phone rows, delete removed link rows (customer: SQL-087 against COMPANY_PHONE; contact: SQL-081 against PERSON_PHONE), then insert added link rows (customer: SQL-013; contact: SQL-007).
  6. Helper factory flow. mdlCustomerContact.CreatePhone(dpi, contact, phoneNumber, isForeignPhone, isPrimary, phoneType):
  7. Creates clsPhoneInfo.NewPhone(dpi).
  8. Sets Value, IsPrimary, and IsForeign.
  9. Resolves PhoneCode from mdlCodeMaps.GetPhoneTypes(dpi)(phoneType).Code.
  10. Adds the new phone to contact.Phones only if phone.IsValid — invalid phones are constructed but not attached to the contact.
  11. Resolve the phone-type description. PhoneTypeDescription calls GetPhoneCode(dpi)(PhoneCode).Description from the shared SAIF.Business code-map module for display purposes only.

Process flow

The following diagram visualizes phone normalization and the save/link cycle, including the helper factory's validity gate.

flowchart TD
    Start([Caller sets phone fields]) --> Foreign{IsForeign?}
    Foreign -->|No| Normalize[SetStoredVersion:<br>concatenate country/area/prefix/number/ext]
    Foreign -->|Yes| KeepForeign[Keep foreign value as entered]
    Normalize --> Validate{PhoneID and<br>FormattedValue valid?}
    KeepForeign --> Validate
    Validate -->|No| Blocked([Broken rule added])
    Validate -->|Yes| ParentSave([Parent Save cascades to collection])
    ParentSave --> SaveRows[Save each current PHONE row]
    SaveRows --> DeleteLinks[Delete link rows for RemovedItems]
    DeleteLinks --> InsertLinks[Insert link rows for AddedItems]
    InsertLinks --> Done([Collection persisted])
    Helper([mdlCustomerContact.CreatePhone]) --> Build[Build clsPhoneInfo;<br>resolve PhoneCode from mdlCodeMaps]
    Build --> ValidGate{phone.IsValid?}
    ValidGate -->|Yes| Attach[Add to contact.Phones]
    ValidGate -->|No| Discard([Phone object returned<br>but not attached])

Failure and edge-case behavior

  • Missing/zero PhoneID or a blank FormattedValue blocks the save with a broken rule before the PHONE insert/update executes (BR-007).
  • mdlCustomerContact.CreatePhone only attaches the phone to the contact when it is already valid, so a caller relying on this helper never sees an invalid phone silently added to the collection — unlike the equivalent email helper, CreateEmail, which adds unconditionally.
  • Removing a phone from a collection deletes only the COMPANY_PHONE / PERSON_PHONE link row, not the standalone PHONE row.*
  • Foreign phone numbers bypass the country/area/prefix/extension concatenation entirely, so their stored format depends solely on what the caller supplied in Value.*

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.CustomerContact\InfoItems\clsPhoneInfo.vb
  • Business\SAIF.Business.CustomerContact\InfoItems\clsInfoCollection.vb
  • Business\SAIF.Business.CustomerContact\Customer\clsCustomerPhoneCollection.vb
  • Business\SAIF.Business.CustomerContact\Contact\clsContactPhoneCollection.vb
  • Business\SAIF.Business.CustomerContact\mdlCustomerContact.vb