Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common.DataModel/Classes/TestMetaData.md
2026-04-17 14:55:32 -04:00

246 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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`.