+ get_barcode CDEK API

* Upload payment_proof & cheque_photo to docs
This commit is contained in:
Phil Zhitnikov 2023-07-06 15:49:34 +04:00
parent bc91845074
commit 7a04f15aab
4 changed files with 60 additions and 2 deletions

View File

@ -1,9 +1,12 @@
import http
import os
from time import sleep
from typing import Optional
from urllib.parse import urljoin
import requests
from django.conf import settings
from django.core.files.base import ContentFile
from requests import Request
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'poizonstore.settings')
@ -13,6 +16,7 @@ class CDEKClient:
AUTH_ENDPOINT = 'oauth/token'
ORDER_INFO_ENDPOINT = 'orders'
CALCULATOR_TARIFF_ENDPOINT = 'calculator/tariff'
BARCODE_ENDPOINT = 'print/barcodes'
MAX_RETRIES = 2
@ -63,6 +67,49 @@ class CDEKClient:
def calculate_tariff(self, data):
return self.request('POST', self.CALCULATOR_TARIFF_ENDPOINT, json=data)
def generate_barcode(self, cdek_number, format="A6") -> Optional[str]:
request_data = {
"orders": [{"cdek_number": cdek_number}],
"copy_count": 1,
"format": format
}
r = self.request('POST', self.BARCODE_ENDPOINT, json=request_data)
if not r:
return None
resp_data = r.json()
if 'entity' not in resp_data:
return None
barcode_uuid = resp_data['entity']['uuid']
return barcode_uuid
def get_barcode_url(self, uuid) -> Optional[str]:
if not uuid:
return None
r = self.request('GET', f'{self.BARCODE_ENDPOINT}/{uuid}')
if not r:
return None
resp_data = r.json()
if 'entity' not in resp_data:
return None
url = resp_data['entity'].get('url')
return url
def get_barcode_file(self, cdek_number):
uuid = self.generate_barcode(cdek_number)
sleep(2) # Sometimes url are not yet created, so be prepared for this
url = self.get_barcode_url(uuid)
if not url:
return None
r = self.request('GET', url)
return ContentFile(r.content) if r and r.content else None
client = CDEKClient(settings.CDEK_CLIENT_ID, settings.CDEK_CLIENT_SECRET)
client.authorize()

View File

@ -2,6 +2,7 @@
Django==4.2.2
django-filter==23.2
djangorestframework==3.14.0
drf-extra-fields==3.5.0
Pillow==9.5.0
# Misc

View File

@ -220,6 +220,8 @@ class Checklist(models.Model):
CDEK = "cdek"
COMPLETED = "completed"
PDF_AVAILABLE_STATUSES = (RUSSIA, CDEK, COMPLETED)
CHOICES = (
(DRAFT, 'Черновик'),
(NEW, 'Новый заказ'),
@ -291,6 +293,7 @@ class Checklist(models.Model):
# trackid
poizon_tracking = models.CharField('Трек-номер Poizon', max_length=100, null=True, blank=True)
cdek_tracking = models.CharField('Трек-номер СДЭК', max_length=100, null=True, blank=True)
cdek_barcode_pdf = models.FileField('Штрих-код СДЭК в PDF', upload_to='docs', null=True, blank=True)
objects = ChecklistQuerySet.as_manager()
@ -358,6 +361,13 @@ class Checklist(models.Model):
if old_obj and self.status != old_obj.status:
self.status_updated_at = timezone.now()
# Try to get CDEK barcode PDF
if not self.cdek_barcode_pdf and self.cdek_tracking and self.status in Checklist.Status.PDF_AVAILABLE_STATUSES:
from store.views import CDEKAPI
pdf_file = CDEKAPI.client.get_barcode_file(self.cdek_tracking)
if pdf_file:
self.cdek_barcode_pdf.save(f'{self.id}_barcode.pdf', pdf_file)
# Create preview image
if self.images.exists() and not self.preview_image:
# Render preview image

View File

@ -135,7 +135,7 @@ class ChecklistSerializer(serializers.ModelSerializer):
'buyername', 'buyerphone', 'tg',
'receivername', 'reveiverphone',
'paymenttype', 'paymentproovement', 'checkphoto',
'trackid', 'cdek_tracking', 'delivery',
'trackid', 'cdek_tracking', 'cdek_barcode_pdf', 'delivery',
'startDate', 'currentDate',
)
@ -188,4 +188,4 @@ class PromocodeSerializer(serializers.ModelSerializer):
class Meta:
model = Promocode
fields = ('name', 'discount', 'freedelivery', 'nocomission')
fields = ('id', 'name', 'discount', 'freedelivery', 'nocomission')