کوئرا بهتازگی میخواهد یک فروشگاه برای خرید و فروش تجهیزات کامپیوتری تأسیس کند و از شما میخواهد که با استفاده از جنگو یک سیستم مدیریت فروشگاه آنلاین برای او پیادهسازی کنید.
# پیادهسازی
پروژهی اولیه را میتوانید از [این لینک](/problemset/assignments/4367/download_problem_initial_project/254217/) دانلود کنید. ساختار پروژه به شرح زیر است و شما باید قسمتهای مشخص شده را پیادهسازی کنید.
```
├── manage.py
├── requirements.txt
├── server
│ ├── __init__.py
│ ├── asgi.py
│ ├── <mark class="yellow" title="این فایل را تغییر دهید"> > settings.py < </mark>
│ ├── urls.py
│ └── wsgi.py
└── store
├── __init__.py
├── admin.py
├── apps.py
├── <mark class="yellow" title="این فایل را تغییر دهید"> > migrations < </mark>
│ └── __init__.py
├── <mark class="yellow" title="این فایل را تغییر دهید"> > models.py < </mark>
├── <mark class="yellow" title="این فایل را تغییر دهید"> > permissions.py < </mark>
├── <mark class="yellow" title="این فایل را تغییر دهید"> > queries.py < </mark>
├── serializers.py
├── <mark class="yellow" title="این فایل را تغییر دهید"> > signals.py < </mark>
├── tests.py
├── <mark class="yellow" title="این فایل را تغییر دهید"> > throttling.py < </mark>
└── <mark class="yellow" title="این فایل را تغییر دهید"> > views.py < </mark>
```
# نیازمندیها
## احراز هویت مبتنی بر توکن
- سیستم احراز هویت مبتنی بر توکن را با استفاده از *TokenAuthentication* جنگو پیادهسازی کنید.
- هر کاربر باید برای دسترسی به هر اندپوینت، با توکن احراز هویت شود.
- سه نوع کاربر وجود دارد:
- **مشتری**: میتواند محصولات را مشاهده کند، سفارش ثبت کند و نظرات ارسال کند.
- **مدیر فروشگاه**: میتواند موجودی را مدیریت کند و سفارشها را پردازش کند.
- **مدیر کل *(Admin)***: میتواند کاربران، تنظیمات فروشگاه و آمار را مدیریت کند.
## مدلها
- **کاربر**: مدل کاربر سفارشی که از `AbstractUser` جنگو به ارث میبرد و نقشهایی (مشتری، مدیر فروشگاه، مدیر کل) دارد. که این مدل برای شما پیادهسازی شده است و نیاز به پیادهسازی آن نیست.
- **محصول**:
- فیلد `name` که نام محصول است.
- فیلد `description` که توضیحات مرتبط به محصول است.
- فیلد `price` که یک عدد تنها با دو رقم اعشار است.
- فیلد `inventory` تعداد محصولات موجود در انبار را نگه میدارد.(مقدار پیش فرض 0 عدد)
- فیلد `rating` میانگین نمرات مشتریان را در یک عدد با دو رقم اعشار نگه میدارد که با تابع `update_rating` همواره پس از save شدن مدل محاسبه میشود.
- پراپرتی `discounted_price` که قیمت محصول پس از اعمال اولین تخفیف را نگه میدارد.
- **سفارش**:
- فیلد `customer` که user خریدار است.
- فیلد `products` که یک ارتباط چند به چند به محصول است.
- فیلد `total_price` که مجموع خرید را در یک عدد با دو رقم اعشار نگه میدارد.(مقدار پیش فرض: 0)
- فیلد `status` که شامل یکی از گزینههایی است که در صورت پروژه آمده است.
- فیلد `quantity` یک عدد که تعداد کل محصولات خریداری شده را نگه میدارد. (مقدار پیشفرض یک عدد خواهد بود)
- فیلد `order_date` که تاریخ ساخت سفارش را نگه میدارد.
- **نقد و بررسی *(Review)***:
- فیلد `user` که کاربر ثبت کننده نقد است.
- فیلد `product` که محصول مورد بررسی است.
- فیلد `rating` که یک عدد صحیح بین ۱ تا ۵ است که امتیاز کاربر به آن محصول است.
- فیلد `comment` که کامنت کاربر راجع به محصول است.
- فیلد `created_at` که تاریخ ساخت این نقد است.
- **تخفیف *(Discount)***:
- فیلد `product` که محصول دارای تخفیف است.
- فیلد `discount_percentage` که درصد تخفیف تا دو رقم اعشار است.
- فیلد `start_date` که زمان شروع تخفیف است.
- فیلد `end_date` که زمان پایان تخفیف است.
- تابع `is_active` که فعال بودن تخفیف را مشخص میکند.
**نکته: بعد از تکمیل پیادهسازی مدلها، حتما باید دستورهای مایگرشن اجرا شود تا فایلهای مایگرشن در پروژه ایجاد شوند.**
## کوئریها
- **محصولات پرفروش**: تابع `get_top_selling` را پیادهسازی و یک اندپوینت `/api/products/top-selling/` بسازید که ۵ محصول پرفروش بر اساس تعداد فروش (`quantity`) را بازگرداند. از کوئریهای *annotation* برای محاسبه تعداد کل فروش هر محصول استفاده کنید.
- **آمار سفارشات**: تابع `get_monthly_income` را پیادهسازی کنید که درآمد کل تولید شده در ۳۰ روز گذشته را محاسبه کرده و سه مشتری برتر را بر اساس کل مبلغ خرجشده بازگرداند.
- **تاریخچه سفارشات مشتری**: تابع `get_customers_orders` را پیادهسازی و یک اندپوینت `/api/orders/customer_orders/` ارائه دهید که سفارشات قبلی مشتری را شامل قیمت کل، محصولات سفارش دادهشده و وضعیت سفارش لیست کند. از سابکوئری برای محاسبه کل مبلغ خرجشده توسط مشتری در پاسخ استفاده کنید.
- **محصولات با بیشترین امتیاز**: تابع `get_top_rated_products` را پیادهسازی کنید و یک اندپوینت `/api/products/top-rated/` برای نمایش ۵ محصول با بیشترین امتیاز ایجاد کنید. از سابکوئریها برای محاسبه امتیاز میانگین و تعداد کل نظرات برای هر محصول استفاده کنید.
- **سفارشات اخیر**: تابع `recent_orders` را پیادهسازی کنید و از آن در یک اندپوینت `/api/orders/recent/` استفاده کنید که جدیدترین سفارش هر مشتری را بازگرداند.
## سیگنالها
- از سیگنالهای جنگو برای موارد زیر استفاده کنید:
- **بهروزرسانی موجودی محصول** هنگامی که یک سفارش ثبت میشود.
- **بهروزرسانی امتیاز محصول** هنگامیکه یک نظر جدید اضافه یا ویرایش میشود و امتیاز میانگین محصول مجدداً محاسبه میشود.
## مجوزها
- یک سیستم مجوز مبتنی بر نقشها پیادهسازی کنید:
- **مشتریان**: میتوانند محصولات را مشاهده کنند، سفارش ثبت کنند و تنها سفارشات خود را ببینند و نظرات ارسال کنند و صرفا نظرات خود را میتوانند ویرایش و پاک کنند.
- **مدیران فروشگاه**: میتوانند محصولات را مدیریت کرده و سفارشات مشتریان را پردازش کنند (تأیید، رد یا ارسال).
- **مدیران کل**: کنترل کامل بر تمام موارد از جمله مدیریت کاربران و تخفیفها دارند.
- فایل `permissions.py` را برای هندل کردن این مجوزها باید پیادهسازی کنید.
- اطمینان حاصل کنید که **مشتریان** نمیتوانند نظرات را بهروز کنند یا حذف کنند مگر اینکه خودشان آنها را ایجاد کرده باشند.
## سیستم محدودسازی درخواستها
- یک سیستم محدودسازی درخواستها با استفاده از سیستم *Throttling DRF* پیادهسازی کنید:
- مشتریان: **۱۰۰ درخواست در روز**
- مدیران فروشگاه: **۵۰۰ درخواست در روز**
- مدیران کل: **۱۰۰۰ درخواست در روز**
## تخفیفها
- مدیران کل باید قادر باشند تخفیفهایی را ایجاد و مدیریت کنند. هنگامی که یک محصول تخفیف فعال دارد، قیمت آن باید بهروزرسانی شود تا تخفیف را منعکس کند.
# اندپوینتهای API
**توجه داشته باشید که جز بخش تحلیلها، فرمت پاسخ هر بخش به شکل serializer آن بخش است.**
%align_right_start%
1. **احراز هویت**:
• `POST /api/token-auth/`: تولید توکن احراز هویت که `username` و `password` از کاربر دریافت میکند و در صورت احراز هویت `token` را در پاسخ برمیگرداند.
2. **محصولات**:
• `GET /api/products/`: لیست همه محصولات.
• `GET /api/products/<id>/`: دریافت جزئیات یک محصول.
• `POST /api/products/`: اضافه کردن یک محصول جدید (فقط مدیر فروشگاه/مدیر کل).
• `PUT /api/products/<id>/`: بهروزرسانی یک محصول (فقط مدیر فروشگاه/مدیر کل).
• `DELETE /api/products/<id>/`: حذف یک محصول (فقط مدیر کل).
• `GET /api/products/top-selling/`: دریافت محصولات پرفروش (فقط مدیر کل).
• `GET /api/products/top-rated/`: دریافت محصولات با بیشترین امتیاز (مشتریان).
3. **سفارشات**:
• `POST /api/orders/`: ثبت سفارش جدید (مشتریان).
• `GET /api/orders/<id>/`: دریافت جزئیات سفارش (مشتری/مدیر فروشگاه).
• `GET /api/orders/recent/`: دریافت سفارشات اخیر هر مشتری (مدیر فروشگاه/مدیر کل).
• `GET /api/orders/customer_orders/`: دریافت تاریخچه سفارشات مشتری (مشتریان).
4. **نقد و بررسیها**:
• `POST /api/products/<id>/reviews/`: ارسال نظر برای محصول (مشتریان).
• `GET /api/products/<id>/reviews/`: دریافت نظرات یک محصول (مشتریان).
• `PUT /api/reviews/<id>/`: بهروزرسانی یک نظر (مشتریان).
• `DELETE /api/reviews/<id>/`: حذف یک نظر (مدیر کل/مشتریای که نظر را ایجاد کرده).
5. **تخفیفها**:
• `POST /api/discounts/`: ایجاد تخفیف (فقط مدیر کل).
• `GET /api/discounts/`: لیست همه تخفیفهای فعال (فقط مدیر کل).
• `DELETE /api/discounts/<id>/`: حذف یک تخفیف فعال (فقط مدیر کل).
6. **تحلیلها**:
• `GET /api/analytics/revenue/`: دریافت کل درآمد و سه مشتری برتر (فقط مدیر کل). مانند زیر:
```
{
"total_income": 130.20
"top_customers": [
{
"username": "ahmad",
"total_spent": 23.01
},
{
"username": "ali",
"total_spent": 20.00
},
{
"username": "javad",
"total_spent": 14.50
}
]
}
```
• `GET /api/analytics/orders/`: این API صرفا یک جواب به مدیر کل برگرداند که در آن تعداد کل رکوردهای order باشد. به شکل زیر:
```
{
"total_orders": 13
}
```
# آنچه باید آپلود کنید
شما باید یک فایل _ZIP_ با ساختار مشابه با پروژه اولیه را آپلود کنید.