+ get_barcode CDEK API
* Upload payment_proof & cheque_photo to docs
This commit is contained in:
parent
bc91845074
commit
7a04f15aab
47
cdek/api.py
47
cdek/api.py
|
|
@ -1,9 +1,12 @@
|
||||||
import http
|
import http
|
||||||
import os
|
import os
|
||||||
|
from time import sleep
|
||||||
|
from typing import Optional
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.files.base import ContentFile
|
||||||
from requests import Request
|
from requests import Request
|
||||||
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'poizonstore.settings')
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'poizonstore.settings')
|
||||||
|
|
@ -13,6 +16,7 @@ class CDEKClient:
|
||||||
AUTH_ENDPOINT = 'oauth/token'
|
AUTH_ENDPOINT = 'oauth/token'
|
||||||
ORDER_INFO_ENDPOINT = 'orders'
|
ORDER_INFO_ENDPOINT = 'orders'
|
||||||
CALCULATOR_TARIFF_ENDPOINT = 'calculator/tariff'
|
CALCULATOR_TARIFF_ENDPOINT = 'calculator/tariff'
|
||||||
|
BARCODE_ENDPOINT = 'print/barcodes'
|
||||||
|
|
||||||
MAX_RETRIES = 2
|
MAX_RETRIES = 2
|
||||||
|
|
||||||
|
|
@ -63,6 +67,49 @@ class CDEKClient:
|
||||||
def calculate_tariff(self, data):
|
def calculate_tariff(self, data):
|
||||||
return self.request('POST', self.CALCULATOR_TARIFF_ENDPOINT, json=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 = CDEKClient(settings.CDEK_CLIENT_ID, settings.CDEK_CLIENT_SECRET)
|
||||||
client.authorize()
|
client.authorize()
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
Django==4.2.2
|
Django==4.2.2
|
||||||
django-filter==23.2
|
django-filter==23.2
|
||||||
djangorestframework==3.14.0
|
djangorestframework==3.14.0
|
||||||
|
drf-extra-fields==3.5.0
|
||||||
Pillow==9.5.0
|
Pillow==9.5.0
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,8 @@ class Checklist(models.Model):
|
||||||
CDEK = "cdek"
|
CDEK = "cdek"
|
||||||
COMPLETED = "completed"
|
COMPLETED = "completed"
|
||||||
|
|
||||||
|
PDF_AVAILABLE_STATUSES = (RUSSIA, CDEK, COMPLETED)
|
||||||
|
|
||||||
CHOICES = (
|
CHOICES = (
|
||||||
(DRAFT, 'Черновик'),
|
(DRAFT, 'Черновик'),
|
||||||
(NEW, 'Новый заказ'),
|
(NEW, 'Новый заказ'),
|
||||||
|
|
@ -291,6 +293,7 @@ class Checklist(models.Model):
|
||||||
# trackid
|
# trackid
|
||||||
poizon_tracking = models.CharField('Трек-номер Poizon', max_length=100, null=True, blank=True)
|
poizon_tracking = models.CharField('Трек-номер Poizon', max_length=100, null=True, blank=True)
|
||||||
cdek_tracking = models.CharField('Трек-номер СДЭК', 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()
|
objects = ChecklistQuerySet.as_manager()
|
||||||
|
|
||||||
|
|
@ -358,6 +361,13 @@ class Checklist(models.Model):
|
||||||
if old_obj and self.status != old_obj.status:
|
if old_obj and self.status != old_obj.status:
|
||||||
self.status_updated_at = timezone.now()
|
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
|
# Create preview image
|
||||||
if self.images.exists() and not self.preview_image:
|
if self.images.exists() and not self.preview_image:
|
||||||
# Render preview image
|
# Render preview image
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ class ChecklistSerializer(serializers.ModelSerializer):
|
||||||
'buyername', 'buyerphone', 'tg',
|
'buyername', 'buyerphone', 'tg',
|
||||||
'receivername', 'reveiverphone',
|
'receivername', 'reveiverphone',
|
||||||
'paymenttype', 'paymentproovement', 'checkphoto',
|
'paymenttype', 'paymentproovement', 'checkphoto',
|
||||||
'trackid', 'cdek_tracking', 'delivery',
|
'trackid', 'cdek_tracking', 'cdek_barcode_pdf', 'delivery',
|
||||||
'startDate', 'currentDate',
|
'startDate', 'currentDate',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -188,4 +188,4 @@ class PromocodeSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Promocode
|
model = Promocode
|
||||||
fields = ('name', 'discount', 'freedelivery', 'nocomission')
|
fields = ('id', 'name', 'discount', 'freedelivery', 'nocomission')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user