Skip to content

Maintain provider service and service contract

Three closely related classes are documented together because they govern the same provider-location service catalog: clsProviderService records which services a location offers and which one is primary, clsProviderServiceContract records the pricing/contract terms for a service, and clsProviderServiceType records the service-type-to-service-code reference link. All three follow the standard BOF insert/update/delete pipeline with UPDATE_NUM concurrency on update.

Field Value
Operation ID OP-PRV-10
Trigger Caller calls NewProviderService/NewProviderServiceContract/NewProviderServiceType or the matching Get* factory, edits properties, and calls Save() or Delete()
Inputs ProviderLocationSeqNum, ProviderServiceCode, PrimaryServiceFlag; contract fields EffDate/ExpDate, PurchaseCode, DiscountRate, AdditionalFeeDiscountRate, MaxChargeAmt, CBPServiceCode, ServiceModifierCode, ServiceCode, ServiceTypeCode, MCOPlanID, ContactName; ProviderTypeCode for the service-type link
Outputs Persisted PROVIDER_SERVICE, PROVIDER_SERVICE_CONTRACT, and PROVIDER_SERVICE_TYPE rows
Primary components clsProviderService.AddBusinessRules, clsProviderServiceContract.AddBusinessRules, clsProviderServiceType
Entry point Business\SAIF.Business.Provider\clsProviderService.vb

Steps

  1. Create. clsProviderService.Create() copies ProviderLocationSeqNum and stores the original service code for update targeting. clsProviderServiceContract.Create() copies ProviderLocationSeqNum and assigns a new PROV_SERVICE_CONTRACT_SEQ via GetNextSeqNum(...). clsProviderServiceType.Create() performs no setup.
  2. Validate provider service before save.
  3. CommonBusinessRules.TextRequired on ProviderServiceCode: hard error requiring a service type.
  4. BR-019: HasPrimaryService requires exactly one row in the sibling clsProviderServiceCollection (RelatedServices) flagged primary; HasDuplicatePrimaryService blocks more than one; HasDuplicateService blocks the same ProviderServiceCode appearing twice.
  5. Validate service contract before save.
  6. EffectiveMCOPlanID: hard error — if dirty with MCOPlanID and a valid EffDate — running IsMCOPlanEffective, a count query against MCO_PROVIDER for the location/plan/effective-date combination.
  7. ValidCBPServiceCode: hard error — if dirty with CBPServiceCode and EffDate — calling clsCBPService.GetCBPService(...) and requiring a nonblank ServiceDescrText.
  8. ValidServiceModifier: hard error requiring ServiceModifierCode to be blank or "SG".
  9. BR-020: AmtOrRateRequired (the three pricing fields must total more than zero) and AmtAndRateNotZero (no more than one of the three may be nonzero).
  10. ValidDiscountRate: hard error — when present/nonzero — requiring a value >= 0.45 and < 1. ValidAdditionalFeeDiscountRate: hard error rejecting values >= 0.5 (the associated message describes a "greater than zero and less than .5" range, but the code only enforces the upper bound).*
  11. ValidEffDate, ValidEffExpDate, UnreasonableEffDate: hard errors requiring a real effective date, no later than the expiration date, and no earlier than 01/01/1850.
  12. BR-021: MCOPlanRequired (package-price rows, ServiceCode = Z, require an MCO plan), ServiceTypeCodeAndServiceCode (mutually exclusive), ServiceTypeCodeOrServiceCodeRequired (one required), PurchaseCodeRequired/PurchaseCodeInvalid (equipment rows, ServiceCode/ServiceTypeCode = E, require a purchase code; other rows must leave it blank), DiscountRateNotAllowed/AdditionalFeeDiscountRateNotAllowed (package-price rows must not populate discount fields).
  13. Warning-only: MaxChargeAmtTooMuch (amount over 1000), EarlyEffDate (effective date before 01/01/2002 but not before 1850).
  14. Service type has no business rules. clsProviderServiceType.AddBusinessRules() is empty; only ProviderTypeCode and ProviderServiceCode are persisted.
  15. Insert provider service. Writes PROVIDER_LOCATION_SEQ_NUM, PROVIDER_SERVICE_CODE, PRIMARY_SERVICE_FLAG, and audit fields to PROVIDER_SERVICE (SQL-032).
  16. Insert service contract. Writes all contract fields — including CONTACT_NAME and SERVICE_MODIFIER_CODE — to PROVIDER_SERVICE_CONTRACT (SQL-034).
  17. Insert service type. Writes PROVIDER_TYPE_CODE, PROVIDER_SERVICE_CODE, and audit fields to PROVIDER_SERVICE_TYPE (SQL-035); this table's implemented retrieve/update/delete key is PROVIDER_TYPE_CODE only.*
  18. Update.
  19. Provider service updates WHERE PROVIDER_LOCATION_SEQ_NUM = :ProviderLocationSeqNum AND PROVIDER_SERVICE_CODE = :OriginalProviderServiceCode AND UPDATE_NUM = :UpdateNum (SQL-080); AfterUpdate() resets the tracked original service code.
  20. Service contract updates WHERE PROV_SERVICE_CONTRACT_SEQ_NUM = :ProvServiceContractSeqNum AND UPDATE_NUM = :UpdateNum (SQL-082); AfterUpdate() unusually increments m_ProvServiceContractSeqNum locally in addition to the standard success handling.*
  21. Error handling. All three classes follow the standard pattern: insert failure adds "Insert Failed"; update/delete failure adds the DB contention error.
  22. Retrieval gaps. clsProviderService.GetProviderService() and clsProviderServiceType.GetProviderServiceType() retrieve by their respective code column only (not by location), so retrieval is effectively a code lookup rather than a location-scoped fetch.* clsProviderServiceContract.GetProviderServiceContract() exists as a factory but this class does not implement a working retrieve path — Criteria.RetrieveSQL throws InvalidSQLProperty — so contract rows must be accessed through their parent collection rather than retrieved individually.*

Process flow

flowchart TD
    Start([Caller edits service or contract]) --> Which{Editing service, contract, or type?}
    Which -->|Service| PrimaryCheck{Exactly one primary,<br>no duplicate codes?}
    PrimaryCheck -->|No| Fail([Multiple primaries or<br>duplicate codes block save])
    PrimaryCheck -->|Yes| SaveService[Insert/update PROVIDER_SERVICE]
    Which -->|Contract| PricingCheck{Pricing fields mutually<br>exclusive and populated?}
    PricingCheck -->|No| Fail2([Conflicting pricing<br>fields block save])
    PricingCheck -->|Yes| CrossField{Package/equipment<br>cross-field rules pass?}
    CrossField -->|No| Fail3([Missing cross-field<br>data blocks save])
    CrossField -->|Yes| SaveContract[Insert/update PROVIDER_SERVICE_CONTRACT]
    Which -->|Type| SaveType[Insert/update PROVIDER_SERVICE_TYPE;<br>no business rules]
    SaveService --> Rows{RowsAffected = 1?}
    SaveContract --> Rows
    SaveType --> Rows
    Rows -->|No| Contention([Insert Failed / DB contention error])
    Rows -->|Yes| Done([Save complete])

Failure and edge-case behavior

  • clsProviderServiceContract.GetProviderServiceContract() is not functionally implemented — its RetrieveSQL throws InvalidSQLProperty — so individual contract rows can only be reached through the collection that loaded them.*
  • ValidAdditionalFeeDiscountRate's error message describes a different valid range than the code actually enforces (message implies "greater than zero and less than .5"; code only rejects >= 0.5).*
  • clsProviderServiceType's retrieve/update/delete key is PROVIDER_TYPE_CODE only, so a location can have at most one meaningfully addressable service-type row per provider type code regardless of ProviderServiceCode.*
  • clsProviderServiceContract.AfterUpdate() increments the sequence number locally after a successful save, an unusual pattern not seen on the other classes in this operation.*

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.Provider\clsProviderService.vb
  • Business\SAIF.Business.Provider\clsProviderServiceContract.vb
  • Business\SAIF.Business.Provider\clsProviderServiceType.vb
  • Business\SAIF.Business.Provider\clsCBPService.vb
  • Business\SAIF.Business.Provider\clsMCOPlan.vb