--- source_files: - Common/DTS.Common.DataModel/Classes/TestMetaData/CustomerDetails.cs - Common/DTS.Common.DataModel/Classes/TestMetaData/LabratoryDetails.cs - Common/DTS.Common.DataModel/Classes/TestMetaData/TestEngineerDetails.cs generated_at: "2026-04-16T03:33:20.750893+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "9acc3ac2395ce04b" --- # TestMetaData ## Documentation: Test Metadata Domain Models --- ### 1. Purpose This module provides domain models for managing test-related metadata entities—specifically `CustomerDetails`, `LabratoryDetails`, and `TestEngineerDetails`—within the DataPROWin7 system. Each class wraps a corresponding low-level ISO-compliant data object (`DTS.Common.ISO.*`) and exposes a property-change-aware interface for UI binding and data entry. The module also provides static/list management classes (`*DetailsList`) for CRUD operations (create, read, delete, list) against persisted metadata, with special handling for caching in run-test scenarios (only for `TestEngineerDetails`). Its role is to abstract persistence and change tracking while enabling data binding in WPF UIs. --- ### 2. Public Interface #### `CustomerDetails` (inherits `BasePropertyChanged`) - **`bool IsBlank()`** Returns `true` if no property has been set since construction (initial state only). - **`string Name { get; set; }`** Gets/sets the display name of the customer. Setting triggers `_blank = false` and `OnPropertyChanged("Name")`. - **`string CustomerName { get; set; }`** Gets/sets the full customer name. - **`string CustomerTestRefNumber { get; set; }`** Gets/sets the customer’s test reference number. - **`string ProjectRefNumber { get; set; }`** Gets/sets the associated project reference number. - **`string CustomerOrderNumber { get; set; }`** Gets/sets the customer order number. - **`string CustomerCostUnit { get; set; }`** Gets/sets the cost center or unit. - **`bool LocalOnly { get; }`** Gets the `LocalOnly` flag from the underlying ISO object. - **`DateTime LastModified { get; }`** Gets the last modification timestamp. - **`string LastModifiedBy { get; }`** Gets the user who last modified the record. - **`int Version { get; }`** Gets the version number of the record. - **`bool HasBlankName()`** Returns `true` if `Name` equals `StringResources.TestTemplate_EmptyListName`. - **`CustomerDetails()`** Default constructor: initializes `_customerDetails` with a new `DTS.Common.ISO.CustomerDetails`, sets `Name` to `TestTemplate_EmptyListName`, and `_blank = true`. - **`CustomerDetails(DTS.Common.ISO.CustomerDetails customerDetails)`** Wraps an existing ISO object; sets `_blank = false`. - **`DTS.Common.ISO.CustomerDetails GetISOCustomer()`** Returns the underlying ISO object. - **`override string ToString()`** Returns `Name`. #### `CustomerDetailsList` - **`static void Delete(CustomerDetails customer)`** Calls `customer.GetISOCustomer().Delete(currentUser)`. - **`static void Delete(CustomerDetails[] customers)`** Deletes each customer in the array. - **`static CustomerDetails[] GetAllCustomers()`** Fetches all ISO customers via `DTS.Common.ISO.CustomerDetails.GetAllCustomerDetails()`, wraps each in `CustomerDetails`, sorts by `Name` (ordinal), and returns as array. - **`static void DeleteAll()`** Calls `DTS.Common.ISO.CustomerDetails.DeleteCustomerDetails()`. - **`static CustomerDetails GetCustomerDetail(string name)`** Returns a wrapped `CustomerDetails` for the given `name`, or `null` if not found or `name` is null/empty. #### `LabratoryDetails` (inherits `BasePropertyChanged`) - **`bool IsBlank()`** Returns `_isBlank`, initialized `true`, set to `false` on first property mutation. - **`string Name { get; set; }`** Display name; triggers `_isBlank = false` and `OnPropertyChanged("Name")`. - **`string LabratoryName { get; set; }`** Laboratory name. - **`string LabratoryContactName { get; set; }`** Contact person name. - **`string LabratoryContactPhone { get; set; }`** Contact phone number. - **`string LabratoryContactFax { get; set; }`** Contact fax number. - **`string LabratoryContactEmail { get; set; }`** Contact email address. - **`string LabratoryTestRefNumber { get; set; }`** Laboratory test reference number. - **`string LabratoryProjectRefNumber { get; set; }`** Laboratory project reference number. - **`bool LocalOnly { get; }`** Gets `LocalOnly` from underlying ISO object. - **`DateTime LastModified { get; }`** Gets last modification timestamp. - **`string LastModifiedBy { get; }`** Gets last modifier username. - **`int Version { get; }`** Gets record version. - **`bool HasBlankName()`** Returns `true` if `Name == StringResources.TestTemplate_EmptyListName`. - **`LabratoryDetails()`** Default constructor: initializes `_lab` with new `DTS.Common.ISO.LabratoryDetails`, sets `Name` to `TestTemplate_EmptyListName`, `_isBlank = true`. - **`LabratoryDetails(DTS.Common.ISO.LabratoryDetails lab)`** Wraps an existing ISO object; sets `_isBlank = false`. - **`DTS.Common.ISO.LabratoryDetails GetIsoLab()`** Returns the underlying ISO object. - **`override string ToString()`** Returns `Name`. #### `LabratoryDetailsList` - **`static LabratoryDetails[] GetAllLabs()`** Fetches all ISO labs via `DTS.Common.ISO.LabratoryDetails.GetAllLabratoryDetails()`, wraps each, sorts by `Name`, returns array. - **`static void DeleteAll()`** Calls `DTS.Common.ISO.LabratoryDetails.DeleteLabratoryDetails()`. - **`static void Delete(LabratoryDetails lab)`** Calls `lab?.GetIsoLab().Delete(currentUser)`. - **`static void Delete(LabratoryDetails[] labs)`** Deletes each lab in the array. - **`static LabratoryDetails GetLab(string name)`** Returns a wrapped `LabratoryDetails` for the given `name`, or `null` if not found or `name` is null/empty. #### `TestEngineerDetails` (inherits `BasePropertyChanged`) - **`bool IsBlank()`** Returns `_blank`, initialized `true`, set to `false` on first mutation. - **`string Name { get; set; }`** Display name; triggers `_blank = false` and `OnPropertyChanged("Name")`. - **`string TestEngineerName { get; set; }`** Full test engineer name. - **`string TestEngineerPhone { get; set; }`** Phone number. - **`string TestEngineerFax { get; set; }`** Fax number. - **`string TestEngineerEmail { get; set; }`** Email address. - **`bool LocalOnly { get; }`** Gets `LocalOnly` from underlying ISO object. - **`DateTime LastModified { get; }`** Gets last modification timestamp. - **`string LastModifiedBy { get; }`** Gets last modifier username. - **`int Version { get; }`** Gets record version. - **`bool HasBlankName()`** Returns `true` if `Name == StringResources.TestTemplate_EmptyListName`. - **`TestEngineerDetails()`** Default constructor: initializes `_testEngineerDetails` with new `DTS.Common.ISO.TestEngineerDetails`, sets `Name` to `TestTemplate_EmptyListName`, `_blank = true`. - **`TestEngineerDetails(DTS.Common.ISO.TestEngineerDetails testEngineerDetails)`** Wraps an existing ISO object; sets `_blank = false`. - **`DTS.Common.ISO.TestEngineerDetails GetISOTestEngineer()`** Returns the underlying ISO object. - **`override string ToString()`** Returns `Name`. #### `TestEngineerDetailsList` (inherits `BasePropertyChanged`) - **`static TestEngineerDetailsList TestEngineerList { get; }`** Singleton instance of `TestEngineerDetailsList`. - **`void Delete(TestEngineerDetails testEngineer)`** Deletes from ISO store, removes from internal `_testEngineers` dictionary, and raises `OnPropertyChanged("TestEngineers")`. - **`void Delete(TestEngineerDetails[] testEngineers)`** Deletes each engineer in the array. - **`TestEngineerDetails[] TestEngineers { get; }`** Returns all engineers sorted by `Name`. Lazily populates from `GetAllTestEngineers()` if `_testEngineers` is null/empty (thread-safe via lock). - **`void ReloadAll()`** Clears `_testEngineers` and repopulates from `GetAllTestEngineers()`. - **`void DeleteAll()`** Clears `_testEngineers`, calls `DTS.Common.ISO.TestEngineerDetails.DeleteAllTestEngineerDetails()`. - **`TestEngineerDetails GetTestEngineerDetail(string name)`** Returns engineer by `Name` from in-memory cache (`TestEngineers`), or `null` if not found or `name` is null/whitespace. - **`void AddTestEngineer(TestEngineerDetails testEngineer)`** Commits to ISO store, adds/updates in `_testEngineers` dictionary, and raises `OnPropertyChanged("TestEngineers")`. - **`static TestEngineerDetails[] GetAllTestEngineers()`** Returns all engineers. **Special behavior**: if `RunTestVariables.InRunTest` is `true` and `TestTemplateList.TestTemplatesList.CachedTestEngineerDetails` is populated, returns cached data (converted to ISO objects and wrapped); otherwise fetches from `DTS.Common.ISO.TestEngineerDetails.GetAllTestEngineerDetails()`. --- ### 3. Invariants - **`_blank` / `_isBlank` state**: - For `CustomerDetails` and `TestEngineerDetails`, `_blank` starts `true` and is set to `false` on first property setter invocation. - For `LabratoryDetails`, `_isBlank` behaves identically. - `IsBlank()` returns this state, but it is *not* reset by any operation (e.g., `DeleteAll()` does not reset it). - **`Name` field semantics**: - Default constructor sets `Name` to `StringResources.TestTemplate_EmptyListName`. - `HasBlankName()` checks for this exact string. - `Name` is used as the primary key for lookup (`GetCustomerDetail`, `GetLab`, `GetTestEngineerDetail`, `CompareCustomers`, etc.). - **Sorting**: - `GetAllCustomers()`, `GetAllLabs()`, and `TestEngineers` getter sort by `Name` using `string.Compare(..., StringComparison.Ordinal)`. - **Persistence layer**: - All mutations (`set` on properties, `Add*`, `Delete*`) ultimately call methods on `DTS.Common.ISO.*` types (e.g., `Commit`, `Delete`). - `Commit` and `Delete` are called with `ApplicationProperties.CurrentUser.UserName`. - **Caching for run-test mode**: - `TestEngineerDetailsList.GetAllTestEngineers()` uses cached data *only* when `RunTestVariables.InRunTest` is `true` *and* `CachedTestEngineerDetails` is non-null/non-empty. - This cache is *not* used by `CustomerDetailsList` or `LabratoryDetailsList`. --- ### 4. Dependencies #### Internal Dependencies (from source) - **`DTS.Common.ISO.*`** Core data models: `CustomerDetails`, `LabratoryDetails`, `TestEngineerDetails` (ISO layer). - **`DTS.Common.Base.BasePropertyChanged`** Base class for `INotifyPropertyChanged` implementation. - **`DTS.Common.SharedResource.Strings.StringResources`** Used for `TestTemplate_EmptyListName`. - **`DTS.Common.Storage.ApplicationProperties`** Used to get `CurrentUser.UserName`. - **`DTS.Common.Enums.RunTestVariables`** Used in `TestEngineerDetailsList.GetAllTestEngineers()` to check `InRunTest`. - **`DTS.Common.DataModel.TestTemplateList.TestTemplatesList`** Used in `TestEngineerDetailsList.GetAllTestEngineers()` to access `CachedTestEngineerDetails`. #### External Dependencies (inferred) - **WPF (`System.Windows`)** Used for `ApplicationProperties.CurrentUser` (likely tied to WPF app context). - **.NET Core/Standard runtime** Standard libraries (`System`, `System.Collections.Generic`, `System.Linq`). #### What depends on this module? - UI layers (WPF) binding to `CustomerDetails`, `LabratoryDetails`, `TestEngineerDetails` properties. - Any code managing test metadata (e.g., test setup, reporting) via `*DetailsList` static methods. - `TestTemplateList.TestTemplatesList` (indirectly via caching dependency). --- ### 5. Gotchas - **Inconsistent naming**: - Class is named `LabratoryDetails` (misspelled "Laboratory") in all files. This is preserved in ISO layer and must be used as-is. - **`IsBlank()` behavior is one-way**: - Once set to `false`, `_blank`/`_isBlank` is never reset (e.g., by `Delete`, `Clear`, or `ReloadAll`). A deleted record may still report `IsBlank() == false`. - **`TestEngineerDetailsList` is a singleton with mutable state**: - `_testEngineerList` is static; `TestEngineerList` returns the same instance. - `TestEngineers` property caches data in `_testEngineers` dictionary, which is lazily populated and cleared only by `DeleteAll()` or `ReloadAll()`. - Concurrent access is partially protected by `lock (_testEngineerLock)` in `TestEngineers` getter and `AddTestEngineer`, but `GetTestEngineerDetail` uses `AsParallel()` on `TestEngineers` without locking—potential race condition if `TestEngineers` is being repopulated. - **`GetAllTestEngineers()` has conditional caching logic**: - Behavior changes based on `RunTestVariables.InRunTest` and `CachedTestEngineerDetails`. This is not obvious from the class alone and may cause inconsistent data if caching is stale or misconfigured. - **`CustomerDetailsList` and `LabratoryDetailsList` lack instance methods**: - All operations are `static`. Only `TestEngineerDetailsList` provides instance methods (e.g., `AddTestEngineer`, `Delete(TestEngineerDetails)`), suggesting inconsistent design or incomplete refactoring. - **No validation on property setters**: - Setting `Name` to `null` or empty is allowed (though `HasBlankName()` checks only for `TestTemplate_EmptyListName`). - `GetCustomerDetail`, `GetLab`, `GetTestEngineerDetail` return `null` for `null`/empty/whitespace input, but no validation prevents setting such values on `Name`. - **`ToString()` returns `Name`**: - If `Name` is `null`, this may cause `NullReferenceException` in UI bindings or `string.Format` calls. None identified beyond the above for `CustomerDetails` and `LabratoryDetails`.