From 961f6eac00ad749698a779b68ba4f96d2889c8bd Mon Sep 17 00:00:00 2001 From: behruz-dev Date: Thu, 27 Nov 2025 16:43:36 +0500 Subject: [PATCH] buyurtma qoshishda pdf file generate qilib botga send qiladigan qildim --- core/apps/orders/apps.py | 3 ++ .../apps/orders/migrations/0004_order_file.py | 18 +++++++++++ core/apps/orders/models/order.py | 2 ++ core/apps/orders/serializers/order.py | 22 +++++++++++-- core/services/generate_pdf.py | 30 +++++------------- core/services/send_telegram_msg.py | 31 ++++++++++--------- requirements.txt | 19 ++++++++++++ 7 files changed, 85 insertions(+), 40 deletions(-) create mode 100644 core/apps/orders/migrations/0004_order_file.py diff --git a/core/apps/orders/apps.py b/core/apps/orders/apps.py index 2d18476..4a40637 100644 --- a/core/apps/orders/apps.py +++ b/core/apps/orders/apps.py @@ -4,3 +4,6 @@ from django.apps import AppConfig class OrdersConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'core.apps.orders' + + def ready(self): + import core.apps.orders.admin diff --git a/core/apps/orders/migrations/0004_order_file.py b/core/apps/orders/migrations/0004_order_file.py new file mode 100644 index 0000000..03840cc --- /dev/null +++ b/core/apps/orders/migrations/0004_order_file.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2 on 2025-11-27 10:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('orders', '0003_order_overdue_price'), + ] + + operations = [ + migrations.AddField( + model_name='order', + name='file', + field=models.FileField(blank=True, null=True, upload_to='orders/files/'), + ), + ] diff --git a/core/apps/orders/models/order.py b/core/apps/orders/models/order.py index 959f7ee..42fdac9 100644 --- a/core/apps/orders/models/order.py +++ b/core/apps/orders/models/order.py @@ -17,6 +17,8 @@ class Order(BaseModel): advance = models.FloatField() employee_name = models.CharField(max_length=200) + file = models.FileField(null=True, blank=True, upload_to='orders/files/') + def __str__(self): return f'#{self.id} from {self.user.first_name}, total_price - {self.total_price}, paid - {self.paid_price}' diff --git a/core/apps/orders/serializers/order.py b/core/apps/orders/serializers/order.py index 6bcedfe..119d42d 100644 --- a/core/apps/orders/serializers/order.py +++ b/core/apps/orders/serializers/order.py @@ -1,5 +1,6 @@ # django from django.db import transaction +from django.core.files.base import ContentFile # rest framework from rest_framework import serializers @@ -9,6 +10,9 @@ from core.apps.orders.models import Order, OrderItem from core.apps.orders.serializers.order_item import OrderItemSerializer # shared from core.apps.shared.models import Factory +# services +from core.services.generate_pdf import generate_order_pdf +from core.services.send_telegram_msg import send_to_telegram class OrderCreateSerializer(serializers.Serializer): @@ -28,22 +32,36 @@ class OrderCreateSerializer(serializers.Serializer): def create(self, validated_data): with transaction.atomic(): + user = self.context.get('user') order = Order.objects.create( factory=validated_data.get('factory'), paid_price=validated_data.get('paid_price'), advance=validated_data.get('advance'), employee_name=validated_data.get('employee_name'), total_price=validated_data.get('total_price'), + user=user ) order_items = [] for order_item in validated_data.get('items'): - order_items(OrderItem( + order_items.append(OrderItem( product=order_item.get('product'), order=order, quantity=order_item.get('quantity'), total_price=order_item.get('total_price'), )) OrderItem.objects.bulk_create(order_items) + + # generate pdf file + pdf_buffer = generate_order_pdf(order.id) + + file_name = f"order_{order.id}.pdf" + order.file.save(file_name, ContentFile(pdf_buffer.getvalue()), save=False) + + order.save(update_fields=["file"]) + + # send to telegram + + send_to_telegram(user.telegram_id, order.id) return order @@ -55,7 +73,7 @@ class OrderListSerializer(serializers.ModelSerializer): model = Order fields = [ 'id', 'factory', 'total_price', 'paid_price', 'advance', 'employee_name', - 'overdue_price', 'order_items' + 'overdue_price', 'order_items', 'file' ] def get_factory(self, obj): diff --git a/core/services/generate_pdf.py b/core/services/generate_pdf.py index a3a7856..12d6f65 100644 --- a/core/services/generate_pdf.py +++ b/core/services/generate_pdf.py @@ -13,7 +13,8 @@ from reportlab.lib.units import cm from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer from reportlab.lib.enums import TA_CENTER -from core.apps.orders.models import Order +# orders +from core.apps.orders.models import Order, OrderItem def generate_order_pdf(order_id): @@ -53,7 +54,7 @@ def generate_order_pdf(order_id): spaceAfter=6 ) - title = Paragraph(f"BUYURTMA CHIPTASI", title_style) + title = Paragraph(f"Spesifikatsiya", title_style) elements.append(title) elements.append(Spacer(1, 0.3*cm)) @@ -61,6 +62,7 @@ def generate_order_pdf(order_id): ['Buyurtma ID:', f"#{order.id}"], ['Sana:', order.created_at.strftime('%d.%m.%Y %H:%M') if order.created_at else 'N/A'], ['Fabrika:', order.factory.name if order.factory else 'Belgilanmagan'], + ['Xodim:', order.employee_name or 'Belgilanmagan'], ] info_table = Table(info_data, colWidths=[3*cm, 12*cm]) @@ -74,29 +76,11 @@ def generate_order_pdf(order_id): elements.append(info_table) elements.append(Spacer(1, 0.5*cm)) - elements.append(Paragraph("XARIDOR MA'LUMOTLARI", heading_style)) - customer_data = [ - ['Ismi:', order.user.first_name + ' ' + order.user.last_name if order.user else 'N/A'], - ['Email:', order.user.email if order.user else 'N/A'], - ['Telefon:', order.user.phone if hasattr(order.user, 'phone') else 'N/A'], - ['Xodim:', order.employee_name or 'Belgilanmagan'], - ] - - customer_table = Table(customer_data, colWidths=[3*cm, 12*cm]) - customer_table.setStyle(TableStyle([ - ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'), - ('FONTSIZE', (0, 0), (-1, -1), 9), - ('TEXTCOLOR', (0, 0), (0, -1), colors.HexColor('#333333')), - ('VALIGN', (0, 0), (-1, -1), 'TOP'), - ('BOTTOMPADDING', (0, 0), (-1, -1), 6), - ])) - elements.append(customer_table) elements.append(Spacer(1, 0.5*cm)) - elements.append(Paragraph("MAHSULOTLAR", heading_style)) - - order_items = order.order_items.all() + elements.append(Paragraph("MAHSULOTLAR", title_style)) + order_items = OrderItem.objects.filter(order=order) if order_items.exists(): items_data = [ ['#', 'Mahsulot', 'Miqdor', 'Narxi', 'Jami Narx'], @@ -139,7 +123,7 @@ def generate_order_pdf(order_id): summary_data = [ ['Umumiy summa:', f"{order.total_price:,.2f} so'm"], ['To\'langan:', f"{order.paid_price:,.2f} so'm"], - ['Avans:', f"{order.advance:,.2f} so'm"], + ['Avans:', f"{order.advance} %"], ['Qolgan to\'lov:', f"{order.overdue_price:,.2f} so'm"], ] diff --git a/core/services/send_telegram_msg.py b/core/services/send_telegram_msg.py index 672a216..b58acb4 100644 --- a/core/services/send_telegram_msg.py +++ b/core/services/send_telegram_msg.py @@ -5,28 +5,29 @@ import requests # django from django.conf import settings +from django.shortcuts import get_object_or_404 + +# orders +from core.apps.orders.models import Order -def send_to_telegram(chat_id, file_path=None): +def send_to_telegram(chat_id, order_id): bot_token = settings.BOT_TOKEN try: - url = f"https://api.telegram.org/bot{bot_token}/sendMessage" - data = { - "chat_id": chat_id, - "text": "Buyurtma uchun yuklangan PDF file", - "parse_mode": "HTML" - } + order = get_object_or_404(Order, id=order_id) - if file_path and os.path.exists(file_path): + if order.file: url = f"https://api.telegram.org/bot{bot_token}/sendDocument" - with open(file_path, 'rb') as f: - files = {'document': f} + + with open(order.file.path, "rb") as pdf: + files = {'document': pdf} data = {'chat_id': chat_id} - requests.post(url, files=files, data=data) - - return True + + response = requests.post(url, data=data, files=files) + + return True + except Exception as e: print(f"Telegram xatolik: {e}") - return False - + return False \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 035abc9..2b5ce1b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,38 @@ asgiref==3.11.0 +brotli==1.2.0 +certifi==2025.11.12 +cffi==2.0.0 +charset-normalizer==3.4.4 click==8.3.1 +cssselect2==0.8.0 Django==5.2 django-cors-headers==4.9.0 django-environ==0.12.0 djangorestframework==3.16.1 djangorestframework_simplejwt==5.5.1 drf-yasg==1.21.11 +fonttools==4.60.1 gunicorn==23.0.0 h11==0.16.0 +idna==3.11 inflection==0.5.1 packaging==25.0 +pillow==12.0.0 psycopg2-binary==2.9.11 +pycparser==2.23 +pydyf==0.11.0 PyJWT==2.10.1 +pyphen==0.17.2 pytz==2025.2 PyYAML==6.0.3 +reportlab==4.4.5 +requests==2.32.5 sqlparse==0.5.3 +tinycss2==1.5.1 +tinyhtml5==2.0.0 uritemplate==4.2.0 +urllib3==2.5.0 uvicorn==0.38.0 +weasyprint==66.0 +webencodings==0.5.1 +zopfli==0.4.0