adding
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
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}"
|
||||
Reference in New Issue
Block a user