karrio-server-events 2026.1.3__py3-none-any.whl → 2026.1.5__py3-none-any.whl
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.
- karrio/server/events/serializers/base.py +3 -0
- karrio/server/events/signals.py +45 -0
- karrio/server/events/task_definitions/base/__init__.py +16 -0
- karrio/server/events/task_definitions/base/pickup.py +66 -0
- {karrio_server_events-2026.1.3.dist-info → karrio_server_events-2026.1.5.dist-info}/METADATA +1 -1
- {karrio_server_events-2026.1.3.dist-info → karrio_server_events-2026.1.5.dist-info}/RECORD +8 -7
- {karrio_server_events-2026.1.3.dist-info → karrio_server_events-2026.1.5.dist-info}/WHEEL +0 -0
- {karrio_server_events-2026.1.3.dist-info → karrio_server_events-2026.1.5.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,9 @@ class EventTypes(lib.StrEnum):
|
|
|
12
12
|
shipment_delivery_failed = "shipment_delivery_failed"
|
|
13
13
|
tracker_created = "tracker_created"
|
|
14
14
|
tracker_updated = "tracker_updated"
|
|
15
|
+
pickup_scheduled = "pickup_scheduled"
|
|
16
|
+
pickup_cancelled = "pickup_cancelled"
|
|
17
|
+
pickup_closed = "pickup_closed"
|
|
15
18
|
order_created = "order_created"
|
|
16
19
|
order_updated = "order_updated"
|
|
17
20
|
order_fulfilled = "order_fulfilled"
|
karrio/server/events/signals.py
CHANGED
|
@@ -13,6 +13,7 @@ def register_signals():
|
|
|
13
13
|
signals.post_save.connect(shipment_updated, sender=models.Shipment)
|
|
14
14
|
signals.post_delete.connect(shipment_cancelled, sender=models.Shipment)
|
|
15
15
|
signals.post_save.connect(tracker_updated, sender=models.Tracking)
|
|
16
|
+
signals.post_save.connect(pickup_updated, sender=models.Pickup)
|
|
16
17
|
|
|
17
18
|
logger.info("Karrio events signals registered")
|
|
18
19
|
|
|
@@ -134,3 +135,47 @@ def tracker_updated(
|
|
|
134
135
|
return
|
|
135
136
|
|
|
136
137
|
tasks.notify_webhooks(event, data, event_at, context, schema=settings.schema)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@utils.disable_for_loaddata
|
|
141
|
+
@utils.error_wrapper
|
|
142
|
+
def pickup_updated(
|
|
143
|
+
sender, instance, created, raw, using, update_fields, *args, **kwargs
|
|
144
|
+
):
|
|
145
|
+
"""Pickup related events:
|
|
146
|
+
- pickup scheduled (created)
|
|
147
|
+
- pickup cancelled (status changed to cancelled)
|
|
148
|
+
- pickup closed (status changed to closed)
|
|
149
|
+
"""
|
|
150
|
+
changes = update_fields or []
|
|
151
|
+
status_updated = "status" in changes
|
|
152
|
+
|
|
153
|
+
if created:
|
|
154
|
+
event = EventTypes.pickup_scheduled.value
|
|
155
|
+
elif (
|
|
156
|
+
status_updated
|
|
157
|
+
and instance.status == serializers.PickupStatus.cancelled.value
|
|
158
|
+
):
|
|
159
|
+
event = EventTypes.pickup_cancelled.value
|
|
160
|
+
elif (
|
|
161
|
+
status_updated
|
|
162
|
+
and instance.status == serializers.PickupStatus.closed.value
|
|
163
|
+
):
|
|
164
|
+
event = EventTypes.pickup_closed.value
|
|
165
|
+
else:
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
data = serializers.Pickup(instance).data
|
|
169
|
+
event_at = instance.updated_at
|
|
170
|
+
context = dict(
|
|
171
|
+
user_id=utils.failsafe(lambda: instance.created_by.id),
|
|
172
|
+
test_mode=instance.test_mode,
|
|
173
|
+
org_id=utils.failsafe(
|
|
174
|
+
lambda: instance.org.first().id if hasattr(instance, "org") else None
|
|
175
|
+
),
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
if settings.MULTI_ORGANIZATIONS and context["org_id"] is None:
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
tasks.notify_webhooks(event, data, event_at, context, schema=settings.schema)
|
|
@@ -49,8 +49,24 @@ def periodic_data_archiving(*args, **kwargs):
|
|
|
49
49
|
_run()
|
|
50
50
|
|
|
51
51
|
|
|
52
|
+
@db_periodic_task(crontab(hour=0, minute=30))
|
|
53
|
+
@with_task_telemetry("daily_pickup_close")
|
|
54
|
+
def daily_pickup_close():
|
|
55
|
+
from karrio.server.events.task_definitions.base import pickup
|
|
56
|
+
|
|
57
|
+
@utils.run_on_all_tenants
|
|
58
|
+
def _run(**kwargs):
|
|
59
|
+
utils.failsafe(
|
|
60
|
+
lambda: pickup.close_past_pickups(),
|
|
61
|
+
"An error occurred during pickup auto-close: $error",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
_run()
|
|
65
|
+
|
|
66
|
+
|
|
52
67
|
TASK_DEFINITIONS = [
|
|
53
68
|
background_trackers_update,
|
|
54
69
|
periodic_data_archiving,
|
|
70
|
+
daily_pickup_close,
|
|
55
71
|
notify_webhooks,
|
|
56
72
|
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
from django.utils import timezone
|
|
3
|
+
|
|
4
|
+
from karrio.server.core.logging import logger
|
|
5
|
+
import karrio.server.manager.models as models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def close_past_pickups():
|
|
9
|
+
"""Auto-close one_time pickups whose pickup_date has passed.
|
|
10
|
+
|
|
11
|
+
Only closes pickups that are:
|
|
12
|
+
- Still in "scheduled" status
|
|
13
|
+
- Have pickup_type == "one_time" (stored in meta)
|
|
14
|
+
- Have a pickup_date strictly before today
|
|
15
|
+
|
|
16
|
+
Recurring and daily pickups without an end_date are excluded to avoid
|
|
17
|
+
prematurely closing open-ended recurring schedules.
|
|
18
|
+
"""
|
|
19
|
+
today = timezone.now().date()
|
|
20
|
+
|
|
21
|
+
# Get all scheduled pickups with pickup_date in the past
|
|
22
|
+
past_pickups = models.Pickup.objects.filter(
|
|
23
|
+
status="scheduled",
|
|
24
|
+
pickup_date__lt=today,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Separate one_time pickups (always close) from recurring/daily pickups
|
|
28
|
+
one_time_ids = []
|
|
29
|
+
recurring_expired_ids = []
|
|
30
|
+
|
|
31
|
+
for pickup in past_pickups.values("id", "meta"):
|
|
32
|
+
meta = pickup.get("meta") or {}
|
|
33
|
+
pickup_type = meta.get("pickup_type", "one_time")
|
|
34
|
+
|
|
35
|
+
if pickup_type == "one_time":
|
|
36
|
+
one_time_ids.append(pickup["id"])
|
|
37
|
+
elif pickup_type in ("daily", "recurring"):
|
|
38
|
+
# Only close recurring/daily pickups that have an explicit end_date
|
|
39
|
+
# that has passed. Leave open-ended recurring pickups alone.
|
|
40
|
+
recurrence = meta.get("recurrence") or {}
|
|
41
|
+
end_date_str = recurrence.get("end_date")
|
|
42
|
+
|
|
43
|
+
if end_date_str:
|
|
44
|
+
try:
|
|
45
|
+
end_date = datetime.date.fromisoformat(end_date_str)
|
|
46
|
+
if end_date < today:
|
|
47
|
+
recurring_expired_ids.append(pickup["id"])
|
|
48
|
+
except (ValueError, TypeError):
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
ids_to_close = one_time_ids + recurring_expired_ids
|
|
52
|
+
|
|
53
|
+
if not ids_to_close:
|
|
54
|
+
logger.info("No past pickups to auto-close")
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
count = models.Pickup.objects.filter(id__in=ids_to_close).update(
|
|
58
|
+
status="closed",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
logger.info(
|
|
62
|
+
"Auto-closed past pickups",
|
|
63
|
+
count=count,
|
|
64
|
+
one_time=len(one_time_ids),
|
|
65
|
+
recurring_expired=len(recurring_expired_ids),
|
|
66
|
+
)
|
|
@@ -4,7 +4,7 @@ karrio/server/events/apps.py,sha256=DIV8JdPB_3hD4DwhcQTevhph3PaceMkFSEGM1lOcdVY,
|
|
|
4
4
|
karrio/server/events/filters.py,sha256=vMeY42IsoFl482-yX1BI17sw-9x9euOnzTl-860W3sg,2230
|
|
5
5
|
karrio/server/events/models.py,sha256=WQQKpDnbUW97beFmCBJDTckSoE-h-HtxeRfjoNWepQY,2582
|
|
6
6
|
karrio/server/events/router.py,sha256=IBUR7rfBkdEHQzWxYOPcVSM8NBp3fte9G6Q5BVTUNNw,95
|
|
7
|
-
karrio/server/events/signals.py,sha256=
|
|
7
|
+
karrio/server/events/signals.py,sha256=PJ-E9-u7PwXEZ6CdmySPCJeUIPlnly1AVFyzF7pGZZo,5917
|
|
8
8
|
karrio/server/events/tasks.py,sha256=kqs-W2VnDHOQNvieN8Ltehk578W5FTXTobj7t_mi9Xk,787
|
|
9
9
|
karrio/server/events/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
|
|
10
10
|
karrio/server/events/urls.py,sha256=oLTTzDWPhEFfK93EvzHTDRxqkw8Fr3iXneDXwFUkvcU,217
|
|
@@ -20,12 +20,13 @@ karrio/server/events/migrations/0009_alter_webhook_enabled_events.py,sha256=0bhn
|
|
|
20
20
|
karrio/server/events/migrations/0010_event_event_created_at_idx.py,sha256=9vLPYVIId5Ni4W_EnmaCfL-F29YzoQ070963D3q6KgA,498
|
|
21
21
|
karrio/server/events/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
karrio/server/events/serializers/__init__.py,sha256=S5KJONM1VFbB_Wyl__F2YbdSV7R_5RPNFos0ERkfDko,52
|
|
23
|
-
karrio/server/events/serializers/base.py,sha256=
|
|
23
|
+
karrio/server/events/serializers/base.py,sha256=7D9qkzluhNVvJJYRQlyF_sjrzpTl_V-Eh9vIzhRz59g,2278
|
|
24
24
|
karrio/server/events/serializers/event.py,sha256=dKYqldfSEjKMY7uB1rBFfEfSZ_dfEp8EPxbkBBSWzcc,289
|
|
25
25
|
karrio/server/events/serializers/webhook.py,sha256=Ri5JS1SXpSsPUvQH989T_7Amu1p46y5TP54MEEhK8j8,889
|
|
26
26
|
karrio/server/events/task_definitions/__init__.py,sha256=bpT73UG7mZL_JjEqMwbYx6q69jA8J5Jcoul1LcDokhA,81
|
|
27
|
-
karrio/server/events/task_definitions/base/__init__.py,sha256=
|
|
27
|
+
karrio/server/events/task_definitions/base/__init__.py,sha256=ZrFjiU_3JdfdIchWDVi-8WC1hCwv4Jvkwb5JfTyKs7M,2045
|
|
28
28
|
karrio/server/events/task_definitions/base/archiving.py,sha256=HVUfgzTSsfa-o2u6N1VuyPopnVLdFRwvv-3ix5LjKHc,7270
|
|
29
|
+
karrio/server/events/task_definitions/base/pickup.py,sha256=6QUcRnfEXGplUw2EW0yFJEtD-iCFPIb6B2_X9eiEAiQ,2164
|
|
29
30
|
karrio/server/events/task_definitions/base/tracking.py,sha256=z5ja6lOjNMBtj5nu2TlKJxgnCelL58vxR5kpyDoUays,7179
|
|
30
31
|
karrio/server/events/task_definitions/base/webhook.py,sha256=QNRq3xhLWQEbrs3zSy6Sa0AXUPhWE7YenKpPzZoFwL0,3616
|
|
31
32
|
karrio/server/events/tests/__init__.py,sha256=5szv9hDvu0R0jtm3XWktY19rCaE8bZ2LdjRm4oJ0pYA,220
|
|
@@ -39,7 +40,7 @@ karrio/server/graph/schemas/events/__init__.py,sha256=Yg1rWew5DgSb_OnLy8n7qqwPLf
|
|
|
39
40
|
karrio/server/graph/schemas/events/inputs.py,sha256=Mgy9qCUrbL-sMI5dNXsnbW8K5_PnGKM13brzZrc5OWk,1526
|
|
40
41
|
karrio/server/graph/schemas/events/mutations.py,sha256=QDng4EXOBCBDVPuO4hxxRteQ_UfUxWUbjtHOk24X4LQ,1752
|
|
41
42
|
karrio/server/graph/schemas/events/types.py,sha256=TPlrDwQV4LZXu-1t4gFl_eYayU39THmgYT3uv7VXnnw,2759
|
|
42
|
-
karrio_server_events-2026.1.
|
|
43
|
-
karrio_server_events-2026.1.
|
|
44
|
-
karrio_server_events-2026.1.
|
|
45
|
-
karrio_server_events-2026.1.
|
|
43
|
+
karrio_server_events-2026.1.5.dist-info/METADATA,sha256=0WXhlnbfFUUiQzme5efWxpbdOv0ZbkDmpNyDWAkbr6I,701
|
|
44
|
+
karrio_server_events-2026.1.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
45
|
+
karrio_server_events-2026.1.5.dist-info/top_level.txt,sha256=D1D7x8R3cTfjF_15mfiO7wCQ5QMtuM4x8GaPr7z5i78,12
|
|
46
|
+
karrio_server_events-2026.1.5.dist-info/RECORD,,
|
|
File without changes
|
{karrio_server_events-2026.1.3.dist-info → karrio_server_events-2026.1.5.dist-info}/top_level.txt
RENAMED
|
File without changes
|