67 lines
1.9 KiB
Python
67 lines
1.9 KiB
Python
from celery import shared_task
|
|
from django.db.models import Q
|
|
from django.utils import timezone
|
|
|
|
from external_api.cdek import client as cdek_client, CDEKStatus
|
|
from external_api.currency import client as CurrencyAPIClient
|
|
from .models import Checklist, GlobalSettings
|
|
|
|
|
|
@shared_task
|
|
def check_cdek_status(order_id):
|
|
obj = Checklist.objects.filter(id=order_id).first()
|
|
if obj is None or obj.cdek_tracking is None or obj.status == Checklist.Status.COMPLETED:
|
|
return
|
|
|
|
# Get CDEK statuses
|
|
statuses = cdek_client.get_order_statuses(obj.cdek_tracking)
|
|
if not statuses:
|
|
return
|
|
|
|
new_status = obj.status
|
|
if CDEKStatus.DELIVERED in statuses:
|
|
new_status = Checklist.Status.COMPLETED
|
|
elif CDEKStatus.READY_FOR_SHIPMENT_IN_SENDER_CITY in statuses:
|
|
new_status = Checklist.Status.CDEK
|
|
|
|
# Update status
|
|
if obj.status != new_status:
|
|
print(f'Order [{obj.id}] status: {obj.status} -> {new_status}')
|
|
obj.status = new_status
|
|
obj.save()
|
|
return new_status
|
|
|
|
|
|
@shared_task
|
|
def schedule_cdek_status_update():
|
|
qs = Checklist.objects.filter(
|
|
Q(cdek_tracking__isnull=False) & Q(status__in=Checklist.Status.CDEK_READY_STATUSES)
|
|
)
|
|
|
|
order_count = len(qs)
|
|
print(f'Scheduled to update {order_count} orders')
|
|
|
|
# Spawn a sub-task for every order
|
|
for obj in qs:
|
|
check_cdek_status.delay(order_id=obj.id)
|
|
|
|
return order_count
|
|
|
|
|
|
@shared_task(autoretry_for=(Exception,), retry_backoff=True, retry_kwargs={'max_retries': 5})
|
|
def update_yuan_rate():
|
|
# Get fresh rate from API
|
|
rate = CurrencyAPIClient.get_cny_rate()
|
|
if not rate:
|
|
raise Exception("Failed to get yuan rate")
|
|
|
|
print(f"Fetched new yuan rate: {rate}")
|
|
|
|
# Save rate in DB for future usage
|
|
settings = GlobalSettings.load()
|
|
settings.yuan_rate = rate
|
|
settings.yuan_rate_last_updated = timezone.now()
|
|
settings.save()
|
|
|
|
return rate
|