stackin-python-sdk 0.5.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/PKG-INFO +1 -1
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/pyproject.toml +2 -2
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/stackin/__init__.py +1 -1
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/stackin/core/client.py +25 -4
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/LICENSE +0 -0
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/README.md +0 -0
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/stackin/br/__init__.py +0 -0
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/stackin/br/product.py +0 -0
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/stackin/br/tax.py +0 -0
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/stackin/core/__init__.py +0 -0
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/stackin/core/address.py +0 -0
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/stackin/core/exceptions.py +0 -0
- {stackin_python_sdk-0.5.0 → stackin_python_sdk-0.7.0}/stackin/core/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "stackin-python-sdk"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.7.0"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name = "Fernando Celmer", email = "email@fernandocelmer.com" },
|
|
6
6
|
]
|
|
@@ -45,7 +45,7 @@ Changelog = "https://github.com/stackin-io/stackin-python-sdk/releases"
|
|
|
45
45
|
|
|
46
46
|
[tool.poetry]
|
|
47
47
|
name = "stackin-python-sdk"
|
|
48
|
-
version = "0.
|
|
48
|
+
version = "0.7.0"
|
|
49
49
|
description = "Python SDK for issuing, consulting and cancelling electronic invoices."
|
|
50
50
|
authors = ["Fernando Celmer <email@fernandocelmer.com>"]
|
|
51
51
|
readme = "README.md"
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import os
|
|
6
|
+
from typing import Any
|
|
6
7
|
|
|
7
8
|
import requests
|
|
8
9
|
|
|
@@ -140,15 +141,25 @@ class Invoice:
|
|
|
140
141
|
*,
|
|
141
142
|
document_type: DocumentType,
|
|
142
143
|
reason: str,
|
|
144
|
+
idempotency_key: str | None = None,
|
|
143
145
|
) -> dict:
|
|
144
|
-
"""Cancels a fiscal document by its access key.
|
|
146
|
+
"""Cancels a fiscal document by its access key.
|
|
147
|
+
|
|
148
|
+
Repeating the same idempotency_key with the same body replays
|
|
149
|
+
the first answer instead of cancelling twice. Cancelling is
|
|
150
|
+
irreversible and has a legal window, so a blind retry on a
|
|
151
|
+
dropped connection is the case this exists for.
|
|
152
|
+
"""
|
|
145
153
|
payload = {
|
|
146
154
|
"document_type": document_type.value,
|
|
147
155
|
"reason": reason,
|
|
148
156
|
}
|
|
149
157
|
|
|
150
158
|
return self._request(
|
|
151
|
-
"POST",
|
|
159
|
+
"POST",
|
|
160
|
+
f"/invoices/{access_key}/cancel",
|
|
161
|
+
json=payload,
|
|
162
|
+
idempotency_key=idempotency_key,
|
|
152
163
|
)
|
|
153
164
|
|
|
154
165
|
def invalidate(
|
|
@@ -275,6 +286,14 @@ class Invoice:
|
|
|
275
286
|
|
|
276
287
|
return self._request("GET", "/invoices", params=params)
|
|
277
288
|
|
|
289
|
+
def submissions(self, invoice_id: str) -> list:
|
|
290
|
+
"""Every attempt made for one invoice, and what came back.
|
|
291
|
+
|
|
292
|
+
consult() gives the status; this gives the reason. Takes the
|
|
293
|
+
invoice_id because a rejected document has no access key.
|
|
294
|
+
"""
|
|
295
|
+
return self._request("GET", f"/invoices/{invoice_id}/submissions")
|
|
296
|
+
|
|
278
297
|
def manifest(
|
|
279
298
|
self,
|
|
280
299
|
access_key: str,
|
|
@@ -326,7 +345,7 @@ class Invoice:
|
|
|
326
345
|
json: dict | None = None,
|
|
327
346
|
params: dict | None = None,
|
|
328
347
|
idempotency_key: str | None = None,
|
|
329
|
-
) ->
|
|
348
|
+
) -> Any:
|
|
330
349
|
response = self._send(
|
|
331
350
|
method,
|
|
332
351
|
path,
|
|
@@ -338,7 +357,9 @@ class Invoice:
|
|
|
338
357
|
body = response.json() if response.content else {}
|
|
339
358
|
except ValueError:
|
|
340
359
|
body = {}
|
|
341
|
-
|
|
360
|
+
if isinstance(body, dict):
|
|
361
|
+
return body.get("result", body)
|
|
362
|
+
return body
|
|
342
363
|
|
|
343
364
|
def _send(
|
|
344
365
|
self,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|