Skip to content

Address info CRUD and linking

clsAddressInfo is a standalone ADDRESS row that either a customer or a contact can reference through an intersection table (COMPANY_ADDRESS or PERSON_ADDRESS). The owning clsCustomerAddressCollection / clsContactAddressCollection tracks which items were added or removed since retrieval and, on save, persists the address rows themselves before reconciling the link rows.

Field Value
Operation ID OP-CC-05
Trigger Caller adds/removes a clsAddressInfo in clsCustomer.Addresses or clsContact.Addresses, then the parent's Save() cascades into the collection
Inputs AddressID, AddressCode (address type), address lines, city/state/zip, country, foreign-address flag
Outputs Persisted ADDRESS row; persisted or removed COMPANY_ADDRESS / PERSON_ADDRESS link row
Primary components clsAddressInfo.Create, clsAddressInfo.AddBusinessRules, clsCustomerAddressCollection.GetAddresses, clsContactAddressCollection.GetAddresses, clsInfoCollection.OnInsert/OnRemove/Save
Entry point Business\SAIF.Business.CustomerContact\InfoItems\clsAddressInfo.vb

Steps

  1. Create a new address row. clsAddressInfo.Create() assigns AddressID from GetNextSeqNum("Address_SEQ"), sets CreateDate/CreateUser, and marks the object new.
  2. Validate (BR-005). AddBusinessRules registers CommonBusinessRules.NonZeroDecimalRequired for AddressID and CommonBusinessRules.TrimTextRequired for AddressCode.
  3. Retrieve linked addresses.
  4. Customer side: clsCustomerAddressCollection.GetAddresses(dpi, customerID) joins COMPANY_ADDRESS to ADDRESS, plus correlated subqueries against COMPANY_ADDRESS_PHONE to populate ConnectedPhoneID/ConnectedFaxID on each row (SQL-036, COMPANY_ADDRESS, COMPANY_ADDRESS_PHONE, ADDRESS).
  5. Contact side: clsContactAddressCollection.GetAddresses(dpi, contactID) performs the equivalent join against PERSON_ADDRESS and PERSON_ADDRESS_PHONE (SQL-030, PERSON_ADDRESS, PERSON_ADDRESS_PHONE, ADDRESS).
  6. Retrieving = True is set during this load so the collection's add-tracking (step 4) does not treat freshly loaded rows as newly added items.
  7. Track adds and removes. clsInfoCollection.OnInsert adds a newly inserted item to AddedItems unless it is being removed from RemovedItems (a net no-op); OnRemove adds a removed item to RemovedItems unless it was only in AddedItems (in which case it is simply discarded, since it was never persisted).
  8. Persist the root ADDRESS row. Each current clsAddressInfo saves itself through the standard insert/update/delete SQL (SQL-001/SQL-002 insert, SQL-064/SQL-065 update, SQL-075/SQL-076 delete, ADDRESS).
  9. Reconcile link rows. clsInfoCollection.Save() then, in order: deletes link rows for every item in RemovedItems (customer: SQL-083 against COMPANY_ADDRESS; contact: SQL-078 against PERSON_ADDRESS), then inserts link rows for every item in AddedItems (customer: SQL-009; contact: SQL-004); both lists are cleared afterward.

Process flow

The following diagram visualizes the address collection's retrieve/track/save cycle.

flowchart TD
    Start([Parent retrieves address collection]) --> Retrieving[Retrieving = True;<br>load ADDRESS joined to link table]
    Retrieving --> Loaded[Populate ConnectedPhoneID/ConnectedFaxID;<br>Retrieving = False]
    Loaded --> Edit[Caller adds/removes clsAddressInfo items]
    Edit --> Track[OnInsert -> AddedItems<br>OnRemove -> RemovedItems]
    Track --> ParentSave([Parent Save cascades to collection])
    ParentSave --> SaveRows[Save each current ADDRESS row<br>insert/update per item]
    SaveRows --> DeleteLinks[Delete link rows for RemovedItems]
    DeleteLinks --> InsertLinks[Insert link rows for AddedItems]
    InsertLinks --> Done([Collection persisted; lists cleared])

Failure and edge-case behavior

  • Missing or zero AddressID, or a blank AddressCode, blocks the address save with a broken rule before the ADDRESS insert/update executes (BR-005).
  • Removing an address from a customer's or contact's collection deletes only the COMPANY_ADDRESS / PERSON_ADDRESS link row; it does not call Delete() on the standalone ADDRESS row itself, so the row can remain orphaned if no other link references it.*
  • No write path for COMPANY_ADDRESS_PHONE / PERSON_ADDRESS_PHONE was found in the examined source; those phone-connection associations appear to be read-only from this library's perspective.**

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.

Sources

  • Business\SAIF.Business.CustomerContact\InfoItems\clsAddressInfo.vb
  • Business\SAIF.Business.CustomerContact\InfoItems\clsInfoCollection.vb
  • Business\SAIF.Business.CustomerContact\Customer\clsCustomerAddressCollection.vb
  • Business\SAIF.Business.CustomerContact\Contact\clsContactAddressCollection.vb