add: add country model
This commit is contained in:
@@ -139,4 +139,8 @@ CSRF_TRUSTED_ORIGINS = [
|
|||||||
"https://acargo.felixits.uz",
|
"https://acargo.felixits.uz",
|
||||||
'http://localhost:8002',
|
'http://localhost:8002',
|
||||||
'http://127.0.0.1:8002',
|
'http://127.0.0.1:8002',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
ALLOWED_ATMOS_IPS = []
|
||||||
|
CONSUMER_KEY = ''
|
||||||
|
CONSUMER_SECRET = ''
|
||||||
27
core/apps/common/migrations/0004_country.py
Normal file
27
core/apps/common/migrations/0004_country.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-27 15:43
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('common', '0003_alter_service_options'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Country',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateField(auto_now_add=True)),
|
||||||
|
('updated_at', models.DateField(auto_now=True)),
|
||||||
|
('name', models.CharField(max_length=200)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Davlat',
|
||||||
|
'verbose_name_plural': 'Davlatlar',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -123,3 +123,14 @@ class SiteConfig(BaseModel):
|
|||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = 'sayt sozlamalari'
|
verbose_name = 'sayt sozlamalari'
|
||||||
verbose_name_plural = 'sayt sozlamalari'
|
verbose_name_plural = 'sayt sozlamalari'
|
||||||
|
|
||||||
|
|
||||||
|
class Country(BaseModel):
|
||||||
|
name = models.CharField(max_length=200)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'Davlat'
|
||||||
|
verbose_name_plural = 'Davlatlar'
|
||||||
@@ -43,4 +43,4 @@ class NewsListApiView(generics.ListAPIView):
|
|||||||
class ContactUsApiView(generics.CreateAPIView):
|
class ContactUsApiView(generics.CreateAPIView):
|
||||||
serializer_class = serializers.ContactUsSerializer
|
serializer_class = serializers.ContactUsSerializer
|
||||||
queryset = models.ContactUs.objects.all()
|
queryset = models.ContactUs.objects.all()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-27 15:43
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('common', '0004_country'),
|
||||||
|
('orders', '0003_order_order_number'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='order',
|
||||||
|
name='location_from',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location_from', to='common.country'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='order',
|
||||||
|
name='location_from_en',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location_from', to='common.country'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='order',
|
||||||
|
name='location_from_ru',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location_from', to='common.country'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='order',
|
||||||
|
name='location_from_uz',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location_from', to='common.country'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='order',
|
||||||
|
name='location_to',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location_to', to='common.country'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='order',
|
||||||
|
name='location_to_en',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location_to', to='common.country'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='order',
|
||||||
|
name='location_to_ru',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location_to', to='common.country'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='order',
|
||||||
|
name='location_to_uz',
|
||||||
|
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='location_to', to='common.country'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -2,6 +2,7 @@ from django.db import models
|
|||||||
|
|
||||||
from core.apps.common.models import BaseModel
|
from core.apps.common.models import BaseModel
|
||||||
from core.apps.accounts.models import User
|
from core.apps.accounts.models import User
|
||||||
|
from core.apps.common.models import Country
|
||||||
|
|
||||||
|
|
||||||
class Order(BaseModel):
|
class Order(BaseModel):
|
||||||
@@ -21,21 +22,12 @@ class Order(BaseModel):
|
|||||||
total_price = models.PositiveBigIntegerField()
|
total_price = models.PositiveBigIntegerField()
|
||||||
is_paid = models.BooleanField(default=False)
|
is_paid = models.BooleanField(default=False)
|
||||||
location = models.CharField(max_length=200)
|
location = models.CharField(max_length=200)
|
||||||
location_to = models.CharField(max_length=200, null=True)
|
location_to = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True, related_name='location_to')
|
||||||
location_from = models.CharField(max_length=200, null=True)
|
location_from = models.ForeignKey(Country, on_delete=models.SET_NULL, null=True, related_name='location_from')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'{self.user} user order {self.name}'
|
return f'{self.user} user order {self.name}'
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
if not self.order_number:
|
|
||||||
last_order = Order.objects.all().order_by('-order_number').first()
|
|
||||||
if last_order:
|
|
||||||
self.order_number = last_order.order_number + 1
|
|
||||||
else:
|
|
||||||
self.order_number = 1
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = 'Buyurtma'
|
verbose_name = 'Buyurtma'
|
||||||
verbose_name_plural = 'buyurtmalar'
|
verbose_name_plural = 'buyurtmalar'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import hashlib
|
import hashlib
|
||||||
|
from django.conf import settings
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
@@ -7,7 +7,6 @@ from rest_framework import status
|
|||||||
from core.apps.orders.models import Order
|
from core.apps.orders.models import Order
|
||||||
|
|
||||||
API_KEY = "ATMOS_API_KEY"
|
API_KEY = "ATMOS_API_KEY"
|
||||||
ALLOWED_ATMOS_IPS = ["185.8.212.47"]
|
|
||||||
|
|
||||||
|
|
||||||
def get_client_ip(request):
|
def get_client_ip(request):
|
||||||
@@ -25,7 +24,7 @@ class AtmosCallbackApiView(APIView):
|
|||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
client_ip = get_client_ip(request)
|
client_ip = get_client_ip(request)
|
||||||
if client_ip not in ALLOWED_ATMOS_IPS:
|
if client_ip not in settings.ALLOWED_ATMOS_IPS:
|
||||||
return Response({"status": 0, "message": "IP ruxsat etilmagan"}, status=403)
|
return Response({"status": 0, "message": "IP ruxsat etilmagan"}, status=403)
|
||||||
data = request.data
|
data = request.data
|
||||||
if not data:
|
if not data:
|
||||||
|
|||||||
58
core/services/payment.py
Normal file
58
core/services/payment.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import requests
|
||||||
|
import base64
|
||||||
|
|
||||||
|
|
||||||
|
class Atmos:
|
||||||
|
def __init__(self, consumer_key, consumer_secret, terminal_id, store_id):
|
||||||
|
self.consumer_key = consumer_key
|
||||||
|
self.consumer_secret = consumer_secret
|
||||||
|
self.terminal_id = terminal_id
|
||||||
|
self.store_id = store_id
|
||||||
|
|
||||||
|
def login(self):
|
||||||
|
credentials = f"{self.consumer_key}:{self.consumer_secret}"
|
||||||
|
encoded_credentials = base64.b64encode(credentials.encode()).decode()
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Basic {encoded_credentials}",
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
}
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"grant_type": "client_credentials"
|
||||||
|
}
|
||||||
|
url = 'https://apigw.atmos.uz/token'
|
||||||
|
res = requests.post(url, headers=headers, data=data)
|
||||||
|
if 'access_token' in res.json():
|
||||||
|
return res.json()['access_token']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def create_transaction(self, amount, account):
|
||||||
|
access_token = self.login()
|
||||||
|
|
||||||
|
url = 'https://apigw.atmos.uz/merchant/pay/create'
|
||||||
|
headers = {
|
||||||
|
'Authorization': f'Bearer {access_token}',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
data = {
|
||||||
|
'amount': amount,
|
||||||
|
'account': account,
|
||||||
|
'terminal_id': self.terminal_id,
|
||||||
|
'store_id': self.store_id
|
||||||
|
}
|
||||||
|
|
||||||
|
res = requests.post(url, headers=headers, data=data)
|
||||||
|
if res.json()['result']['code'] == 'OK':
|
||||||
|
return res.json()
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def generate_url(self, transaction_id, redirect_url):
|
||||||
|
url = f'https://test-checkout.pays.uz/invoice/get?storeId={self.store_id}&transactionId={transaction_id}&redirectLink={redirect_url}'
|
||||||
|
|
||||||
|
res = requests.get(url)
|
||||||
|
return res.json()
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user