Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions robosystems_client/clients/ledger_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2306,6 +2306,7 @@ def resolve_reconciling_item(
status: str | None = None,
note: str | None = None,
reference_event_id: str | None = None,
expected_drift_detected_at: str | datetime.datetime | None = None,
) -> ResolveReconcilingItemResponse:
"""Decide one reconciling item.

Expand All @@ -2315,11 +2316,22 @@ def resolve_reconciling_item(
preview reports. ``posting_date`` and ``status`` (``draft`` or
``posted``) apply to ``catch_up`` only; ``reference_event_id`` to
``acknowledge`` only.

Pass ``expected_drift_detected_at`` as the ``drift_detected_at`` of the
preview the decision was made on: the resolution is refused if the item
was flagged again since, and must be previewed again.
"""
if isinstance(posting_date, str):
posting_date = datetime.date.fromisoformat(posting_date)
if isinstance(expected_drift_detected_at, str):
expected_drift_detected_at = datetime.datetime.fromisoformat(
expected_drift_detected_at
)
body = ResolveReconcilingItemRequest(
event_id=event_id,
expected_drift_detected_at=(
expected_drift_detected_at if expected_drift_detected_at is not None else UNSET
),
disposition=(
ResolveReconcilingItemRequestDispositionType0(disposition)
if disposition is not None
Expand Down
36 changes: 36 additions & 0 deletions robosystems_client/models/resolve_reconciling_item_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class ResolveReconcilingItemRequest:

Attributes:
event_id (str): Event id (evt_ prefixed) to resolve
expected_drift_detected_at (datetime.datetime | None | Unset): The `drift_detected_at` of the preview this
resolution was decided on. Pass it: the resolution is refused when the item has been flagged again since, with a
newer payload nobody has seen, and must be previewed again.
disposition (None | ResolveReconcilingItemRequestDispositionType0 | Unset): How to dispose of the difference.
Omit to take the default the preview reports: restate when every period the event touches is open, catch_up when
any is closed.
Expand All @@ -39,6 +42,7 @@ class ResolveReconcilingItemRequest:
"""

event_id: str
expected_drift_detected_at: datetime.datetime | None | Unset = UNSET
disposition: None | ResolveReconcilingItemRequestDispositionType0 | Unset = UNSET
posting_date: datetime.date | None | Unset = UNSET
status: ResolveReconcilingItemRequestStatus | Unset = (
Expand All @@ -51,6 +55,14 @@ class ResolveReconcilingItemRequest:
def to_dict(self) -> dict[str, Any]:
event_id = self.event_id

expected_drift_detected_at: None | str | Unset
if isinstance(self.expected_drift_detected_at, Unset):
expected_drift_detected_at = UNSET
elif isinstance(self.expected_drift_detected_at, datetime.datetime):
expected_drift_detected_at = self.expected_drift_detected_at.isoformat()
else:
expected_drift_detected_at = self.expected_drift_detected_at

disposition: None | str | Unset
if isinstance(self.disposition, Unset):
disposition = UNSET
Expand Down Expand Up @@ -90,6 +102,8 @@ def to_dict(self) -> dict[str, Any]:
"event_id": event_id,
}
)
if expected_drift_detected_at is not UNSET:
field_dict["expected_drift_detected_at"] = expected_drift_detected_at
if disposition is not UNSET:
field_dict["disposition"] = disposition
if posting_date is not UNSET:
Expand All @@ -108,6 +122,27 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
d = dict(src_dict)
event_id = d.pop("event_id")

def _parse_expected_drift_detected_at(
data: object,
) -> datetime.datetime | None | Unset:
if data is None:
return data
if isinstance(data, Unset):
return data
try:
if not isinstance(data, str):
raise TypeError()
expected_drift_detected_at_type_0 = datetime.datetime.fromisoformat(data)

return expected_drift_detected_at_type_0
except (TypeError, ValueError, AttributeError, KeyError):
pass
return cast(datetime.datetime | None | Unset, data)

expected_drift_detected_at = _parse_expected_drift_detected_at(
d.pop("expected_drift_detected_at", UNSET)
)

def _parse_disposition(
data: object,
) -> None | ResolveReconcilingItemRequestDispositionType0 | Unset:
Expand Down Expand Up @@ -171,6 +206,7 @@ def _parse_reference_event_id(data: object) -> None | str | Unset:

resolve_reconciling_item_request = cls(
event_id=event_id,
expected_drift_detected_at=expected_drift_detected_at,
disposition=disposition,
posting_date=posting_date,
status=status,
Expand Down
15 changes: 15 additions & 0 deletions tests/test_ledger_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,21 @@ def test_resolve_reconciling_item_sends_the_chosen_treatment(
"note": "Vendor credit arrived late",
}

@patch("robosystems_client.clients.ledger_client.op_resolve_reconciling_item")
def test_resolve_reconciling_item_sends_the_previewed_stamp(
self, mock_op, mock_config, graph_id
):
envelope = _envelope("resolve-reconciling-item", {"event_id": "evt_1"})
mock_op.return_value = _mock_response(envelope)
client = LedgerClient(mock_config)
client.resolve_reconciling_item(
graph_id, "evt_1", expected_drift_detected_at="2026-08-21T04:00:00+00:00"
)
assert mock_op.call_args.kwargs["body"].to_dict() == {
"event_id": "evt_1",
"expected_drift_detected_at": "2026-08-21T04:00:00+00:00",
}

def test_resolve_reconciling_item_refuses_an_unknown_treatment(
self, mock_config, graph_id
):
Expand Down
Loading