From e0fe9bd1566f11eda01f2bb2d153c8cf43a33820 Mon Sep 17 00:00:00 2001 From: husanjon Date: Thu, 2 Apr 2026 12:57:59 +0500 Subject: [PATCH] category va elonlanri olish optimalashtrildi --- .../commands/sync_firebase_categories.py | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 core/apps/vendors/management/commands/sync_firebase_categories.py diff --git a/core/apps/vendors/management/commands/sync_firebase_categories.py b/core/apps/vendors/management/commands/sync_firebase_categories.py new file mode 100644 index 0000000..bd97530 --- /dev/null +++ b/core/apps/vendors/management/commands/sync_firebase_categories.py @@ -0,0 +1,132 @@ +""" +Firebase sections + vendor_categories → Django DB sync. + +Ishlatish: + python manage.py sync_firebase_categories + python manage.py sync_firebase_categories --update + +Docker: + docker compose exec web python manage.py sync_firebase_categories +""" + +import os +from datetime import datetime, timezone + +import firebase_admin +from firebase_admin import credentials, firestore +from django.core.management.base import BaseCommand + +from core.apps.vendors.models import SectionModel, CategoryModel + +CERT_PATH = os.path.normpath(os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "../../../../..", + "fondexuzb-firebase-adminsdk-fbsvc-7b0e2d6200.json", +)) + + +def _init_firebase(): + if firebase_admin._apps: + return firestore.client() + if not os.path.exists(CERT_PATH): + raise FileNotFoundError(f"Firebase credentials topilmadi: {CERT_PATH}") + cred = credentials.Certificate(CERT_PATH) + firebase_admin.initialize_app(cred) + return firestore.client() + + +class Command(BaseCommand): + help = "Firebase sections + vendor_categories → Django DB sync" + + def add_arguments(self, parser): + parser.add_argument("--update", action="store_true", + help="Mavjudlarni ham yangilaydi") + + def handle(self, *args, **options): + update = options["update"] + + try: + db = _init_firebase() + except FileNotFoundError as e: + self.stderr.write(self.style.ERROR(str(e))) + return + + # ── 1. SECTIONS ────────────────────────────────────────────────────── + self.stdout.write("\n[1/2] Sections sinxronlanmoqda…") + section_docs = list(db.collection("sections").stream()) + s_created = s_updated = s_skipped = 0 + + for doc in section_docs: + data = doc.to_dict() or {} + fid = data.get("id") or doc.id + + existing = SectionModel.objects.filter(firestore_id=fid).first() + fields = dict( + name=data.get("name") or "—", + is_active=bool(data.get("isActive", True)), + image_url=data.get("sectionImage") or None, + color=data.get("color") or None, + service_type=data.get("serviceTypeFlag") or None, + ) + + if existing and not update: + s_skipped += 1 + continue + if existing: + for k, v in fields.items(): + setattr(existing, k, v) + existing.save() + s_updated += 1 + else: + SectionModel.objects.create(firestore_id=fid, **fields) + s_created += 1 + + self.stdout.write( + self.style.SUCCESS( + f" Sections → yaratildi: {s_created}, yangilandi: {s_updated}, o'tkazildi: {s_skipped}" + ) + ) + + # ── 2. VENDOR_CATEGORIES ───────────────────────────────────────────── + self.stdout.write("\n[2/2] Kategoriyalar sinxronlanmoqda…") + cat_docs = list(db.collection("vendor_categories").stream()) + c_created = c_updated = c_skipped = 0 + + for doc in cat_docs: + data = doc.to_dict() or {} + fid = data.get("id") or doc.id + + section = SectionModel.objects.filter( + firestore_id=data.get("section_id", "") + ).first() + + existing = CategoryModel.objects.filter(firestore_id=fid).first() + fields = dict( + title=data.get("title") or "—", + description=data.get("description") or "", + photo_url=data.get("photo") or None, + is_publish=bool(data.get("publish", True)), + order=int(data.get("order", 0) or 0), + section=section, + ) + + if existing and not update: + c_skipped += 1 + continue + if existing: + for k, v in fields.items(): + setattr(existing, k, v) + existing.save() + c_updated += 1 + else: + CategoryModel.objects.create(firestore_id=fid, **fields) + c_created += 1 + + self.stdout.write( + self.style.SUCCESS( + f" Kategoriyalar → yaratildi: {c_created}, yangilandi: {c_updated}, o'tkazildi: {c_skipped}" + ) + ) + + self.stdout.write(self.style.SUCCESS("\nTayyor! Endi mahsulotlarni yangilash uchun:")) + self.stdout.write(" python manage.py sync_firebase_products --update")