2using System.Collections.Generic;
3using System.Globalization;
5using System.Xml.Serialization;
6using LotSizingDataModel.Core;
7using LotSizingDataModel.Core.Common;
28[XmlRoot(
"lotSizingInstance")]
29[XmlType(TypeName =
"lotSizingInstance")]
32 private string _instanceId =
35 private string _name =
38 private string _description =
41 private string _sourceInformation =
44 private string _createdBy =
47 private string _formatVersion =
50 private DateTime? _createdAtUtc =
53 private DateTime? _modifiedAtUtc =
59 private ProductStructureDescriptor
63 private LotSizingProblemClassification
64 _problemClassification =
67 private string _bestKnownResultId =
70 private string _comment =
97 ArgumentNullException.ThrowIfNull(
151 if (
string.IsNullOrWhiteSpace(instanceId))
153 throw new ArgumentException(
154 "A lot-sizing instance identifier is required.",
158 ArgumentNullException.ThrowIfNull(
168 name?.Trim() ??
string.Empty;
170 DateTime currentDateUtc =
187 [XmlAttribute(
"instanceId")]
196 value?.Trim() ??
string.Empty))
207 [XmlAttribute(
"name")]
216 value?.Trim() ??
string.Empty))
228 [XmlElement(
"description")]
237 value?.Trim() ??
string.Empty))
253 [XmlElement(
"sourceInformation")]
256 get => _sourceInformation;
261 ref _sourceInformation,
262 value?.Trim() ??
string.Empty))
274 [XmlAttribute(
"createdBy")]
283 value?.Trim() ??
string.Empty))
295 [XmlAttribute(
"formatVersion")]
298 get => _formatVersion;
304 value?.Trim() ??
string.Empty))
316 [XmlElement(
"createdAtUtc", IsNullable =
true)]
319 get => _createdAtUtc;
325 ConvertToUtc(value)))
337 [XmlElement(
"modifiedAtUtc", IsNullable =
true)]
340 get => _modifiedAtUtc;
346 ConvertToUtc(value)))
376 [XmlElement(
"supplyChain")]
401 [XmlElement(
"productStructure")]
404 get => _productStructure;
413 ref _productStructure,
422 [XmlElement(
"problemClassification")]
427 _problemClassification;
436 ref _problemClassification,
448 [XmlArray(
"knownResults")]
449 [XmlArrayItem(
"knownResult")]
461 [XmlAttribute(
"bestKnownResultId")]
464 get => _bestKnownResultId;
469 ref _bestKnownResultId,
470 value?.Trim() ??
string.Empty))
472 NotifyBestKnownResultProperties();
482 [XmlArrayItem(
"tag")]
483 public List<string>
Tags {
get; } =
489 [XmlElement(
"comment")]
498 value?.Trim() ??
string.Empty))
512 !
string.IsNullOrWhiteSpace(
521 !
string.IsNullOrWhiteSpace(
530 !
string.IsNullOrWhiteSpace(
539 !
string.IsNullOrWhiteSpace(
548 !
string.IsNullOrWhiteSpace(
557 !
string.IsNullOrWhiteSpace(
589 KnownResults.Count > 0;
605 !
string.IsNullOrWhiteSpace(
652 !
string.IsNullOrWhiteSpace(
672 ArgumentNullException.ThrowIfNull(
675 if (
string.IsNullOrWhiteSpace(
678 throw new ArgumentException(
679 "The known result must have a result " +
681 nameof(knownResult));
687 throw new ArgumentException(
688 $
"Known-result identifier " +
689 $
"'{knownResult.ResultId}' is already used.",
690 nameof(knownResult));
696 NotifyKnownResultProperties();
717 IEnumerable<KnownResult> knownResults)
719 ArgumentNullException.ThrowIfNull(
723 knownResults.ToArray();
725 if (materializedResults.Any(
729 throw new ArgumentException(
730 "The known-result collection cannot contain " +
732 nameof(knownResults));
736 materializedResults.FirstOrDefault(
738 string.IsNullOrWhiteSpace(
741 if (resultWithoutIdentifier is not
null)
743 throw new ArgumentException(
744 "Every known result must have a result " +
746 nameof(knownResults));
749 string[] duplicateIdentifiers =
754 StringComparer.OrdinalIgnoreCase)
764 StringComparer.OrdinalIgnoreCase)
767 if (duplicateIdentifiers.Length > 0)
769 throw new ArgumentException(
770 "Duplicate known-result identifiers: " +
773 duplicateIdentifiers) +
775 nameof(knownResults));
781 materializedResults);
791 NotifyKnownResultProperties();
812 if (
string.IsNullOrWhiteSpace(
818 string normalizedResultId =
825 result is not
null &&
829 StringComparison.OrdinalIgnoreCase))
833 return matches.Length
switch
842 throw new InvalidOperationException(
843 $
"Known-result identifier '{resultId}' " +
844 "is ambiguous in the current instance.")
863 resultId) is not
null;
883 if (knownResult is
null)
900 StringComparison.OrdinalIgnoreCase))
906 NotifyKnownResultProperties();
929 NotifyKnownResultProperties();
950 if (
string.IsNullOrWhiteSpace(
953 throw new ArgumentException(
954 "A best-known-result identifier is required.",
962 if (knownResult is
null)
964 throw new KeyNotFoundException(
965 $
"Known result '{resultId}' does not exist.");
987 ArgumentNullException.ThrowIfNull(
1024 ArgumentNullException.ThrowIfNull(
1051 .ClearDetectedAnalysis();
1054 .ClearClassificationResult();
1090 if (
string.IsNullOrWhiteSpace(
1093 throw new ArgumentException(
1094 "A non-empty tag is required.",
1098 string normalizedTag =
1103 StringComparer.OrdinalIgnoreCase))
1113 NotifyTagProperties();
1133 if (
string.IsNullOrWhiteSpace(
1139 string? existingTag =
1140 Tags.FirstOrDefault(
1145 StringComparison.OrdinalIgnoreCase));
1147 if (existingTag is
null)
1158 NotifyTagProperties();
1178 IEnumerable<string> tags)
1180 ArgumentNullException.ThrowIfNull(
1183 string[] normalizedTags =
1187 !
string.IsNullOrWhiteSpace(
1193 StringComparer.OrdinalIgnoreCase)
1197 StringComparer.OrdinalIgnoreCase)
1205 NotifyTagProperties();
1215 if (
Tags.Count == 0)
1222 NotifyTagProperties();
1303 string instanceDescription =
1308 :
"Unnamed lot-sizing instance";
1311 $
"{instanceDescription}; " +
1312 $
"horizon {PlanningHorizon.ToString(
1313 CultureInfo.InvariantCulture)}; " +
1314 $
"{KnownResultCount.ToString(
1315 CultureInfo.InvariantCulture)} known result(s)";
1318 private static DateTime? ConvertToUtc(
1321 if (!value.HasValue)
1326 DateTime dateTimeValue =
1329 return dateTimeValue.Kind
switch
1334 DateTimeKind.Local =>
1335 dateTimeValue.ToUniversalTime(),
1338 DateTime.SpecifyKind(
1344 private void SortTags()
1346 string[] orderedTags =
1351 StringComparer.OrdinalIgnoreCase)
1360 private void NotifyKnownResultProperties()
1371 NotifyBestKnownResultProperties();
1374 private void NotifyBestKnownResultProperties()
1392 private void NotifyTagProperties()
Stores the persistent result of the automatic classification of a lot-sizing problem instance.
Adds explicit closed-loop return streams to a lot-sizing instance without changing the historical Sup...
void ClearBestKnownResult()
Clears the best-known-result selection.
void SetBestKnownResult(string resultId)
Selects the best known result from its identifier.
bool HasTags
Gets a value indicating whether at least one tag has been recorded.
bool HasDescription
Gets a value indicating whether a description has been recorded.
bool ShouldSerializeKnownResults()
Determines whether the known-result collection must be serialized.
string InstanceId
Gets or sets the stable identifier of the instance.
string Comment
Gets or sets an optional explanatory comment.
string FormatVersion
Gets or sets the format version of the serialized instance.
bool ShouldSerializeCreatedAtUtc()
Determines whether the creation date must be serialized.
void AddKnownResult(KnownResult knownResult)
Adds a known result to the instance.
string Description
Gets or sets the human-readable description of the problem instance.
bool RemoveTag(string tag)
Removes a descriptive tag from the instance.
LotSizingProblemClassification ProblemClassification
Gets or sets the automatic lot-sizing problem classification.
override string ToString()
List< string > Tags
Gets the descriptive tags associated with the instance.
bool HasBestKnownResult
Gets a value indicating whether the selected best known result exists in KnownResults.
void ReplaceSupplyChain(SupplyChain supplyChain)
Replaces the supply-chain model and invalidates all derived analysis and recommendation information.
List< KnownResult > KnownResults
Gets the known results associated with the instance.
void ClearSolutionMethodRecommendationReport()
Clears the complete solution-method recommendation report.
void Touch()
Updates the last-modification date of the instance.
KnownResult? FindKnownResult(string resultId)
Finds a known result from its identifier.
bool ShouldSerializeTags()
Determines whether the tag collection must be serialized.
bool HasEligibleBestKnownResult
Gets a value indicating whether the selected best-known result is eligible for that role.
bool HasModificationDate
Gets a value indicating whether a modification date has been recorded.
void ReplaceKnownResults(IEnumerable< KnownResult > knownResults)
Replaces all known results associated with the instance.
void ClearTags()
Removes every descriptive tag from the instance.
bool AddTag(string tag)
Adds a descriptive tag to the instance.
bool HasCreationDate
Gets a value indicating whether a creation date has been recorded.
void ClearAnalysis()
Clears derived product-structure, classification and recommendation information.
bool HasKnownResults
Gets a value indicating whether at least one known result has been recorded.
bool ShouldSerializeModifiedAtUtc()
Determines whether the modification date must be serialized.
KnownResult? BestKnownResult
Gets the result selected as the best known result.
bool HasInstanceId
Gets a value indicating whether the instance has a stable identifier.
void SetBestKnownResult(KnownResult knownResult)
Selects a known result as the best known result.
DateTime? ModifiedAtUtc
Gets or sets the UTC date and time at which the instance was last modified.
void ClearKnownResults()
Removes every known result from the instance.
LotSizingInstance(SupplyChain supplyChain, string name)
Initializes a named lot-sizing problem instance.
bool RemoveKnownResult(string resultId)
Removes a known result from the instance.
DateTime? CreatedAtUtc
Gets or sets the UTC date and time at which the instance was created.
bool ShouldSerializeBestKnownResultId()
Determines whether the best-known-result identifier must be serialized.
bool ContainsKnownResultId(string resultId)
Determines whether a known result uses the supplied identifier.
string SourceInformation
Gets or sets information identifying the source of the instance.
LotSizingInstance(SupplyChain supplyChain)
Initializes a lot-sizing problem instance from a supply-chain model.
void ClearDerivedAnalysis()
Clears derived product-structure, classification and solution-method recommendation information.
SupplyChain SupplyChain
Gets or sets the supply-chain model represented by the instance.
bool HasBestKnownResultId
Gets a value indicating whether a best known result identifier has been selected.
string BestKnownResultId
Gets or sets the identifier of the result currently considered to be the best known result.
void ReplaceTags(IEnumerable< string > tags)
Replaces every descriptive tag associated with the instance.
LotSizingInstance(string instanceId, SupplyChain supplyChain, string name="")
Initializes an identified lot-sizing problem instance.
int PlanningHorizon
Gets the planning horizon of the supply-chain model.
LotSizingInstance()
Initializes an empty lot-sizing problem instance.
bool HasCreatedBy
Gets a value indicating whether creator information has been recorded.
bool HasComment
Gets a value indicating whether an explanatory comment has been recorded.
ProductStructureDescriptor ProductStructure
Gets or sets the product-structure descriptor associated with the supply-chain model.
string CreatedBy
Gets or sets the person, organization or software component that created the instance.
DateTime? LastModifiedAtUtc
Gets the last-modification date of the instance.
string Name
Gets or sets the human-readable name of the instance.
int KnownResultCount
Gets the number of known results associated with the instance.
bool HasName
Gets a value indicating whether the instance has a human-readable name.
bool HasFormatVersion
Gets a value indicating whether a format version has been recorded.
bool HasSourceInformation
Gets a value indicating whether source information has been recorded.
Represents a known result associated with a lot-sizing problem instance.
string ResultId
Gets or sets the stable identifier of this result.