Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common.DataModel/Classes/TestMetaData.md

246 lines
14 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
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 customers 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`.