from django.conf import settings from django.db import models from django.utils.translation import gettext_lazy as _ # ریزاپ‌های ساده‌ی کسب‌وکار کوچک — مشتریان، دفتر درآمد/هزینه، انبار، # نوبت‌دهی. دقیقا هم‌الگو با apps.banker: id همان UUID تولیدشده در خودِ اپ # فلاتر است (نه auto-increment)، هر رکورد به user صاحبش محدود می‌شود. class Customer(models.Model): id = models.CharField(max_length=36, primary_key=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="customers") name = models.CharField(max_length=150, verbose_name=_("نام")) phone = models.CharField(max_length=20, blank=True, verbose_name=_("شماره تماس")) email = models.CharField(max_length=150, blank=True, verbose_name=_("ایمیل")) address = models.CharField(max_length=255, blank=True, verbose_name=_("آدرس")) notes = models.TextField(blank=True, verbose_name=_("یادداشت")) updated_at = models.DateTimeField(auto_now=True) class Meta: verbose_name = _("مشتری") verbose_name_plural = _("مشتریان") ordering = ["name"] def __str__(self): return self.name class LedgerEntry(models.Model): class EntryType(models.TextChoices): INCOME = "income", _("درآمد") EXPENSE = "expense", _("هزینه") id = models.CharField(max_length=36, primary_key=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="ledger_entries") entry_type = models.CharField(max_length=10, choices=EntryType.choices, verbose_name=_("نوع")) title = models.CharField(max_length=150, verbose_name=_("عنوان")) amount = models.FloatField(verbose_name=_("مبلغ")) category = models.CharField(max_length=100, blank=True, verbose_name=_("دسته")) entry_date = models.DateField(verbose_name=_("تاریخ")) note = models.TextField(blank=True, verbose_name=_("یادداشت")) updated_at = models.DateTimeField(auto_now=True) class Meta: verbose_name = _("ردیف دفتر درآمد/هزینه") verbose_name_plural = _("دفتر درآمد و هزینه") ordering = ["-entry_date"] def __str__(self): return f"{self.title} ({self.get_entry_type_display()})" class Product(models.Model): id = models.CharField(max_length=36, primary_key=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="products") name = models.CharField(max_length=150, verbose_name=_("نام کالا")) sku = models.CharField(max_length=100, blank=True, verbose_name=_("کد کالا")) category = models.CharField(max_length=100, blank=True, verbose_name=_("دسته")) quantity = models.FloatField(default=0, verbose_name=_("موجودی")) unit_price = models.FloatField(default=0, verbose_name=_("قیمت واحد")) low_stock_threshold = models.FloatField(default=0, verbose_name=_("آستانه‌ی هشدار موجودی کم")) notes = models.TextField(blank=True, verbose_name=_("یادداشت")) updated_at = models.DateTimeField(auto_now=True) class Meta: verbose_name = _("کالا") verbose_name_plural = _("انبار") ordering = ["name"] def __str__(self): return self.name class StockMovement(models.Model): """تاریخچه‌ی تغییرات موجودی — هر تعدیل (دستیِ +/- یا ویرایش مستقیم فرم) یک ردیف اینجا ثبت می‌کند تا معلوم باشد موجودی کِی و چقدر تغییر کرده.""" id = models.AutoField(primary_key=True) product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name="movements") delta = models.FloatField(verbose_name=_("تغییر")) quantity_after = models.FloatField(verbose_name=_("موجودی بعد از تغییر")) note = models.CharField(max_length=255, blank=True, verbose_name=_("یادداشت")) created_at = models.DateTimeField(auto_now_add=True) class Meta: verbose_name = _("تغییر موجودی") verbose_name_plural = _("تاریخچه‌ی موجودی") ordering = ["-created_at"] def __str__(self): return f"{self.product.name} — {self.delta:+g} — {self.created_at:%Y-%m-%d %H:%M}" class Appointment(models.Model): class Status(models.TextChoices): SCHEDULED = "scheduled", _("زمان‌بندی‌شده") DONE = "done", _("انجام‌شده") CANCELLED = "cancelled", _("لغوشده") id = models.CharField(max_length=36, primary_key=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="appointments") customer_name = models.CharField(max_length=150, verbose_name=_("نام مشتری")) customer_phone = models.CharField(max_length=20, blank=True, verbose_name=_("شماره مشتری")) title = models.CharField(max_length=150, verbose_name=_("عنوان/خدمت")) start_at = models.DateTimeField(verbose_name=_("زمان نوبت")) status = models.CharField(max_length=10, choices=Status.choices, default=Status.SCHEDULED) notes = models.TextField(blank=True, verbose_name=_("یادداشت")) updated_at = models.DateTimeField(auto_now=True) class Meta: verbose_name = _("نوبت") verbose_name_plural = _("نوبت‌دهی") ordering = ["start_at"] def __str__(self): return f"{self.customer_name} — {self.title}"