Skip to content

AI translation

This page was translated from German with AI. If in doubt, the German original applies.

Movement with the SDK

Setup and, for each stage, the call via the MovementDocumentHandler.

The background in business terms is described in the guide Movement (company role).

Setup

// Authenticated client with an active session — see Getting started
var client = ZedalClientFactory.Default.CreateClient(
    TargetSystem.Test, "MyIntegrationApp", "1.0.0");

await client.CreateSession(
    userId:   "mysubscriber-myaccount@1:mypassword",
    appToken: new AppToken("<APP_TOKEN_JWT>"));

// NotificationId from the preceding notification phase
string notificationId = "DE0126005589i"; // example

One handler per movement. Each subsequent stage reloads the current state with LoadFromZedalByMovementId(movementId) so that changes made in the meantime (e.g. additional attachments from other parties) are taken into account.

Stage 1 — CreateMovementTemplate

MovementDocumentHandler handler = client.DocumentHandler.CreateMovementHandler();

// Determine the next free SequenceNumber for this notification
// (returns 1 if no movement exists yet). Determines the number
// from the transport papers already created — there is no
// server-side reservation path as there is for the NotificationId.
int sequenceNumber = await handler.GetNextSequenceNumber(notificationId);

var template = new MovementTemplateType
{
    // Template.NotificationId = notificationId
    // Template.SequenceNumber = sequenceNumber
    // planned departure date, planned quantity, packaging,
    // further required fields under Regulation (EU) 2024/1157 …
};

await handler.CreateMovementTemplate(template);
await handler.SaveToZedal();
await handler.SendToDiwass();

string movementId = handler.DiwassNotificationId;
// MovementDocumentHandler exposes the movement ID via the inherited property
// DiwassNotificationId (format: <NotificationId>.<SequenceNumber>MOV,
// e.g. DE0126005589i.000001MOV).

Stage 2 — SetCarrierTransport

As soon as the physical transport begins, the carrier records the transport data:

var handler = client.DocumentHandler.CreateMovementHandler();
await handler.LoadFromZedalByMovementId(movementId);

await handler.SetCarrierTransport(new CarrierTransportDocumentType
{
    // vehicle identification, actual departure date,
    // confirmation of takeover …
});
await handler.SaveToZedal();
await handler.SendToDiwass();

Stage 3 — SetConsigneeReception

The consignee confirms receipt of the goods:

var handler = client.DocumentHandler.CreateMovementHandler();
await handler.LoadFromZedalByMovementId(movementId);

await handler.SetConsigneeReception(new ConsigneeReceptionDocumentType
{
    // date of receipt, quantity actually accepted,
    // quantity difference with justification (if necessary) …
});
await handler.SaveToZedal();
await handler.SendToDiwass();

Stage 4 — SetFacilityReception

var handler = client.DocumentHandler.CreateMovementHandler();
await handler.LoadFromZedalByMovementId(movementId);

await handler.SetFacilityReception(new FacilityReceptionDocumentType
{
    // date of acceptance at the facility, accepted quantity,
    // planned R/D code according to the annex of the regulation …
});
await handler.SaveToZedal();
await handler.SendToDiwass();

Stage 5 — SetFacilityCompletion

The facility completes the treatment. Stage 5 marks the end of the regular lifecycle:

var handler = client.DocumentHandler.CreateMovementHandler();
await handler.LoadFromZedalByMovementId(movementId);

await handler.SetFacilityCompletion(new FacilityCompletionDocumentType
{
    // completion date of the treatment, R/D code actually applied,
    // quantity actually treated …
});
await handler.SaveToZedal();
await handler.SendToDiwass();

Validation and error handling

As with the notification, the movement handler validates before the push:

await handler.SendToDiwass();
// Throws an exception on server-side rejection.
// Validation details (e.g. invalid R/D codes, missing required fields)
// are in handler.ValidationErrors (HasValidationErrors as a convenience flag).
//
// Optionally wait for the transfer acknowledgment:
// Size the time budget to the payload — the client default of 30 s is not enough here.
// A push with an attachment takes more than 90 s; for a multi-stage movement chain,
// 2:39 to 4:53 per stage were measured. See Lifecycle -> Sending procedure.
await handler.WaitForDiwassTransfer(
    timeout:      TimeSpan.FromMinutes(6),
    pollInterval: TimeSpan.FromSeconds(5));
// Throws DiwassTransferFailedException on rejection by DIWASS,
// TimeoutException on timeout.

Common sources of errors:

  • Stage out of order: SetFacilityReception without a preceding SetConsigneeReception is rejected — unless consignee and facility are the same operator in the notification; then stage 3 is omitted and stage 4 follows directly after stage 2.
  • Unknown R/D code: the treatment code you specify must be on the list approved in the notification.
  • Inconsistent quantity balance: differences between the planned and the actual quantity require a QuantityBalance justification in stages 3 and 5.