Skip to main content

redispatch_xml/documents/
acknowledgement.rs

1use serde::{Deserialize, Serialize};
2
3use crate::types::{
4    AttrV, AttrVWithScheme, DocumentId, DocumentVersion, MarketParticipantId, MarketRoleType,
5    UtcDateTime,
6};
7
8// ── DocumentType / ReasonCode ─────────────────────────────────────────────────
9
10/// Document types that an `AcknowledgementDocument` may reference in
11/// `ReceivingDocumentType`.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13pub enum AckReceivingDocType {
14    #[serde(rename = "A14")]
15    DayAheadPlan,
16    #[serde(rename = "A41")]
17    ActivationResponse,
18    #[serde(rename = "A42")]
19    TenderReduction,
20    #[serde(rename = "A60")]
21    StatusRequest,
22    #[serde(rename = "A67")]
23    PlannedUnavailability,
24    #[serde(rename = "A76")]
25    ForcedUnavailability,
26    #[serde(rename = "A80")]
27    ProductionUnavailability,
28    #[serde(rename = "A96")]
29    RedispatchActivation,
30    #[serde(rename = "B15")]
31    NetworkConstraint,
32    #[serde(rename = "Z01")]
33    StammdatenCreation,
34    #[serde(rename = "Z02")]
35    StammdatenUpdate,
36    #[serde(rename = "Z03")]
37    StammdatenDeactivation,
38    #[serde(rename = "Z04")]
39    StammdatenNbAggregate,
40    #[serde(rename = "Z05")]
41    Kostenblatt,
42    #[serde(rename = "Z08")]
43    IntradayPlan,
44    #[serde(rename = "Z09")]
45    StammdatenPlan,
46    #[serde(rename = "Z11")]
47    AggregatePlan,
48    #[serde(rename = "Z12")]
49    CorrectedPlan,
50    #[serde(rename = "Z13")]
51    Reserved13,
52    #[serde(rename = "Z14")]
53    Bilanzkreisstammdaten,
54    #[serde(rename = "Z15")]
55    StatusRequestAlt,
56    #[serde(rename = "Z16")]
57    Kaskade,
58    #[serde(rename = "Z17")]
59    TestMessage,
60}
61
62/// Reason codes used at the `AcknowledgementDocument` root level.
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
64pub enum AckReasonCode {
65    /// Message fully accepted.
66    #[serde(rename = "A01")]
67    FullyAccepted,
68    /// Message fully rejected.
69    #[serde(rename = "A02")]
70    FullyRejected,
71    /// Syntax error detected.
72    #[serde(rename = "Z12")]
73    SyntaxError,
74    /// Assignment error.
75    #[serde(rename = "Z13")]
76    AssignmentError,
77    /// Document identification not unique.
78    #[serde(rename = "Z14")]
79    DocumentIdNotUnique,
80    /// Sender not authorised.
81    #[serde(rename = "Z15")]
82    SenderUnauthorised,
83    /// Not permitted per AWT (Anwendungstabelle).
84    #[serde(rename = "Z16")]
85    NotPermitted,
86    /// Format version invalid.
87    #[serde(rename = "Z17")]
88    FormatVersionInvalid,
89    /// Report period invalid.
90    #[serde(rename = "Z18")]
91    ReportPeriodInvalid,
92}
93
94/// Reason element at the `AcknowledgementDocument` root or `TimeSeriesRejection` level.
95#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
96pub struct AckReason {
97    /// Reason code.
98    #[serde(rename = "ReasonCode")]
99    pub code: AttrV<AckReasonCode>,
100    /// Optional free-text description.
101    #[serde(
102        rename = "ReasonText",
103        default,
104        skip_serializing_if = "Option::is_none"
105    )]
106    pub text: Option<String>,
107}
108
109// ── TimeSeriesRejection ───────────────────────────────────────────────────────
110
111/// Rejection detail for a single time series within the received document.
112#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
113pub struct TimeSeriesRejection {
114    /// The `TimeSeriesIdentification` or `AllocationIdentification` of the
115    /// rejected time series.
116    #[serde(
117        rename = "TimeSeriesIdentification",
118        default,
119        skip_serializing_if = "Option::is_none"
120    )]
121    pub time_series_identification: Option<AttrV<DocumentId>>,
122    /// Reasons for the rejection.
123    #[serde(rename = "Reason", default)]
124    pub reasons: Vec<AckReason>,
125}
126
127// ── AcknowledgementDocument ───────────────────────────────────────────────────
128
129/// `AcknowledgementDocument` — application-level acknowledgement for all
130/// Redispatch 2.0 document types.
131///
132/// XSD version: 1.0g (2025-10-01)  
133/// No XML namespace.
134///
135/// An `AcknowledgementDocument` is sent in response to any received Redispatch
136/// 2.0 document. The root-level `Reason` list indicates overall acceptance
137/// (`A01`) or rejection (`A02`). Per-time-series details appear in
138/// `time_series_rejections`.
139#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
140#[serde(rename = "AcknowledgementDocument")]
141pub struct AcknowledgementDocument {
142    /// Unique document identifier (max 35 chars).
143    #[serde(rename = "DocumentIdentification")]
144    pub document_identification: AttrV<DocumentId>,
145    /// Document creation timestamp (UTC, second precision).
146    #[serde(rename = "DocumentDateTime")]
147    pub document_date_time: AttrV<UtcDateTime>,
148    /// Sender's market participant identifier.
149    #[serde(rename = "SenderIdentification")]
150    pub sender_identification: AttrVWithScheme<MarketParticipantId>,
151    /// Sender's market role.
152    #[serde(rename = "SenderRole")]
153    pub sender_role: AttrV<MarketRoleType>,
154    /// Receiver's market participant identifier.
155    #[serde(rename = "ReceiverIdentification")]
156    pub receiver_identification: AttrVWithScheme<MarketParticipantId>,
157    /// Receiver's market role.
158    #[serde(rename = "ReceiverRole")]
159    pub receiver_role: AttrV<MarketRoleType>,
160    /// `DocumentIdentification` of the acknowledged document (optional).
161    #[serde(
162        rename = "ReceivingDocumentIdentification",
163        default,
164        skip_serializing_if = "Option::is_none"
165    )]
166    pub receiving_document_identification: Option<AttrV<DocumentId>>,
167    /// `DocumentVersion` of the acknowledged document (optional).
168    #[serde(
169        rename = "ReceivingDocumentVersion",
170        default,
171        skip_serializing_if = "Option::is_none"
172    )]
173    pub receiving_document_version: Option<AttrV<DocumentVersion>>,
174    /// `DocumentType` of the acknowledged document (optional).
175    #[serde(
176        rename = "ReceivingDocumentType",
177        default,
178        skip_serializing_if = "Option::is_none"
179    )]
180    pub receiving_document_type: Option<AttrV<AckReceivingDocType>>,
181    /// Original filename of the received AS4 payload (optional).
182    #[serde(
183        rename = "ReceivingPayloadName",
184        default,
185        skip_serializing_if = "Option::is_none"
186    )]
187    pub receiving_payload_name: Option<AttrV<String>>,
188    /// `DocumentDateTime` / `CreationDateTime` of the acknowledged document (optional).
189    #[serde(
190        rename = "DateTimeReceivingDocument",
191        default,
192        skip_serializing_if = "Option::is_none"
193    )]
194    pub date_time_receiving_document: Option<AttrV<UtcDateTime>>,
195    /// Per-time-series rejection details (optional).
196    #[serde(
197        rename = "TimeSeriesRejection",
198        default,
199        skip_serializing_if = "Vec::is_empty"
200    )]
201    pub time_series_rejections: Vec<TimeSeriesRejection>,
202    /// Document-level acceptance / rejection reasons (required, at least 1).
203    #[serde(rename = "Reason")]
204    pub reasons: Vec<AckReason>,
205}